diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-03-06 18:19:35 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-03-06 18:19:45 +0300 |
commit | eb522af4fec58876ac1b0a73ad9bcdae2d82d33f (patch) | |
tree | 485c6a1fb23b5be256757375e2157378d3a5c61b /source/blender/collada | |
parent | ff60dd8b18ed00902e5bdfd36882072db7af8735 (diff) |
Cleanup: move Alembic, AVI, Collada, and USD to `source/blender/io`
This moves the `alembic`, `avi`, `collada`, and `usd` modules into a common
`io` directory.
This also cleans up some `#include "../../{somedir}/{somefile}.h"` by
adding `../../io/{somedir}` to `CMakeLists.txt` and then just using
`#include "{somefile}.h"`.
No functional changes.
Diffstat (limited to 'source/blender/collada')
71 files changed, 0 insertions, 19329 deletions
diff --git a/source/blender/collada/AnimationClipExporter.cpp b/source/blender/collada/AnimationClipExporter.cpp deleted file mode 100644 index 5868c24e6cd..00000000000 --- a/source/blender/collada/AnimationClipExporter.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "GeometryExporter.h" -#include "AnimationClipExporter.h" -#include "MaterialExporter.h" - -void AnimationClipExporter::exportAnimationClips(Scene *sce) -{ - openLibrary(); - std::map<std::string, COLLADASW::ColladaAnimationClip *> clips; - - std::vector<std::vector<std::string>>::iterator anim_meta_entry; - for (anim_meta_entry = anim_meta.begin(); anim_meta_entry != anim_meta.end(); - ++anim_meta_entry) { - std::vector<std::string> entry = *anim_meta_entry; - std::string action_id = entry[0]; - std::string action_name = entry[1]; - - std::map<std::string, COLLADASW::ColladaAnimationClip *>::iterator it = clips.find( - action_name); - if (it == clips.end()) { - COLLADASW::ColladaAnimationClip *clip = new COLLADASW::ColladaAnimationClip(action_name); - clips[action_name] = clip; - } - COLLADASW::ColladaAnimationClip *clip = clips[action_name]; - clip->setInstancedAnimation(action_id); - } - - std::map<std::string, COLLADASW::ColladaAnimationClip *>::iterator clips_it; - for (clips_it = clips.begin(); clips_it != clips.end(); clips_it++) { - COLLADASW::ColladaAnimationClip *clip = (COLLADASW::ColladaAnimationClip *)clips_it->second; - addAnimationClip(*clip); - } - - closeLibrary(); -} diff --git a/source/blender/collada/AnimationClipExporter.h b/source/blender/collada/AnimationClipExporter.h deleted file mode 100644 index 25c69fe6b93..00000000000 --- a/source/blender/collada/AnimationClipExporter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ANIMATIONCLIPEXPORTER_H__ -#define __ANIMATIONCLIPEXPORTER_H__ - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> - -#include "COLLADASWLibraryAnimationClips.h" - -class AnimationClipExporter : COLLADASW::LibraryAnimationClips { - private: - Depsgraph *depsgraph; - Scene *scene; - COLLADASW::StreamWriter *sw; - BCExportSettings &export_settings; - std::vector<std::vector<std::string>> anim_meta; - - public: - AnimationClipExporter(Depsgraph *depsgraph, - COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings, - std::vector<std::vector<std::string>> anim_meta) - : COLLADASW::LibraryAnimationClips(sw), - depsgraph(depsgraph), - scene(nullptr), - sw(sw), - export_settings(export_settings), - anim_meta(anim_meta) - { - } - - void exportAnimationClips(Scene *sce); -}; - -#endif /* __ANIMATIONCLIPEXPORTER_H__ */ diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp deleted file mode 100644 index cd4319e3101..00000000000 --- a/source/blender/collada/AnimationExporter.cpp +++ /dev/null @@ -1,877 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "GeometryExporter.h" -#include "AnimationExporter.h" -#include "AnimationClipExporter.h" -#include "BCAnimationSampler.h" -#include "MaterialExporter.h" -#include "collada_utils.h" - -std::string EMPTY_STRING; - -std::string AnimationExporter::get_axis_name(std::string channel_type, int id) -{ - - static std::map<std::string, std::vector<std::string>> BC_COLLADA_AXIS_FROM_TYPE = { - {"color", {"R", "G", "B"}}, - {"specular_color", {"R", "G", "B"}}, - {"diffuse_color", {"R", "G", "B"}}, - {"alpha", {"R", "G", "B"}}, - {"scale", {"X", "Y", "Z"}}, - {"location", {"X", "Y", "Z"}}, - {"rotation_euler", {"X", "Y", "Z"}}}; - - std::map<std::string, std::vector<std::string>>::const_iterator it; - - it = BC_COLLADA_AXIS_FROM_TYPE.find(channel_type); - if (it == BC_COLLADA_AXIS_FROM_TYPE.end()) { - return ""; - } - - const std::vector<std::string> &subchannel = it->second; - if (id >= subchannel.size()) { - return ""; - } - return subchannel[id]; -} - -bool AnimationExporter::open_animation_container(bool has_container, Object *ob) -{ - if (!has_container) { - char anim_id[200]; - sprintf(anim_id, "action_container-%s", translate_id(id_name(ob)).c_str()); - openAnimation(anim_id, encode_xml(id_name(ob))); - } - return true; -} - -void AnimationExporter::openAnimationWithClip(std::string action_id, std::string action_name) -{ - std::vector<std::string> anim_meta_entry; - anim_meta_entry.push_back(translate_id(action_id)); - anim_meta_entry.push_back(action_name); - anim_meta.push_back(anim_meta_entry); - - openAnimation(translate_id(action_id), action_name); -} - -void AnimationExporter::close_animation_container(bool has_container) -{ - if (has_container) { - closeAnimation(); - } -} - -bool AnimationExporter::exportAnimations() -{ - Scene *sce = export_settings.get_scene(); - - LinkNode *export_set = this->export_settings.get_export_set(); - bool has_anim_data = bc_has_animations(sce, export_set); - int animation_count = 0; - if (has_anim_data) { - - BCObjectSet animated_subset; - BCAnimationSampler::get_animated_from_export_set(animated_subset, *export_set); - animation_count = animated_subset.size(); - BCAnimationSampler animation_sampler(export_settings, animated_subset); - - try { - animation_sampler.sample_scene(export_settings, /*keyframe_at_end = */ true); - - openLibrary(); - - BCObjectSet::iterator it; - for (it = animated_subset.begin(); it != animated_subset.end(); ++it) { - Object *ob = *it; - exportAnimation(ob, animation_sampler); - } - } - catch (std::invalid_argument &iae) { - fprintf(stderr, "Animation export interrupted"); - fprintf(stderr, "Exception was: %s", iae.what()); - } - - closeLibrary(); - -#if 0 - /* TODO: If all actions shall be exported, we need to call the - * AnimationClipExporter which will figure out which actions - * need to be exported for which objects - */ - if (this->export_settings->include_all_actions) { - AnimationClipExporter ace(eval_ctx, sw, export_settings, anim_meta); - ace.exportAnimationClips(sce); - } -#endif - } - return animation_count; -} - -/* called for each exported object */ -void AnimationExporter::exportAnimation(Object *ob, BCAnimationSampler &sampler) -{ - bool container_is_open = false; - - /* Transform animations (trans, rot, scale). */ - container_is_open = open_animation_container(container_is_open, ob); - - /* Now take care of the Object Animations - * Note: For Armatures the skeletal animation has already been exported (see above) - * However Armatures also can have Object animation. - */ - bool export_as_matrix = this->export_settings.get_animation_transformation_type() == - BC_TRANSFORMATION_TYPE_MATRIX; - - if (export_as_matrix) { - /* export all transform_curves as one single matrix animation */ - export_matrix_animation(ob, sampler); - } - - export_curve_animation_set(ob, sampler, export_as_matrix); - - if (ob->type == OB_ARMATURE && export_as_matrix) { - -#ifdef WITH_MORPH_ANIMATION - /* TODO: This needs to be handled by extra profiles, postponed for now */ - export_morph_animation(ob); -#endif - - /* Export skeletal animation (if any) */ - bArmature *arm = (bArmature *)ob->data; - for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next) { - export_bone_animations_recursive(ob, root_bone, sampler); - } - } - - close_animation_container(container_is_open); -} - -/* - * Export all animation FCurves of an Object. - * - * Note: This uses the keyframes as sample points, - * and exports "baked keyframes" while keeping the tangent information - * of the FCurves intact. This works for simple cases, but breaks - * especially when negative scales are involved in the animation. - * And when parent inverse matrices are involved (when exporting - * object hierarchies) - */ -void AnimationExporter::export_curve_animation_set(Object *ob, - BCAnimationSampler &sampler, - bool export_as_matrix) -{ - BCAnimationCurveMap *curves = sampler.get_curves(ob); - bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); - - BCAnimationCurveMap::iterator it; - for (it = curves->begin(); it != curves->end(); ++it) { - BCAnimationCurve &curve = *it->second; - std::string channel_type = curve.get_channel_type(); - if (channel_type == "rotation_quaternion") { - /* Can not export Quaternion animation in Collada as far as i know) - * Maybe automatically convert to euler rotation? - * Discard for now. */ - continue; - } - - if (export_as_matrix && curve.is_transform_curve()) { - /* All Transform curves will be exported within a single matrix animation, - * see export_matrix_animation() - * No need to export the curves here again. - */ - continue; - } - - if (!keep_flat_curves && !curve.is_animated()) { - continue; - } - - BCAnimationCurve *mcurve = get_modified_export_curve(ob, curve, *curves); - if (mcurve) { - export_curve_animation(ob, *mcurve); - delete mcurve; - } - else { - export_curve_animation(ob, curve); - } - } -} - -void AnimationExporter::export_matrix_animation(Object *ob, BCAnimationSampler &sampler) -{ - bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); - - std::vector<float> frames; - sampler.get_object_frames(frames, ob); - if (frames.size() > 0) { - BCMatrixSampleMap samples; - bool is_animated = sampler.get_object_samples(samples, ob); - if (keep_flat_curves || is_animated) { - bAction *action = bc_getSceneObjectAction(ob); - std::string name = encode_xml(id_name(ob)); - std::string action_name = (action == NULL) ? name + "-action" : id_name(action); - std::string channel_type = "transform"; - std::string axis = ""; - std::string id = bc_get_action_id(action_name, name, channel_type, axis); - - std::string target = translate_id(name) + '/' + channel_type; - - BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); - export_collada_matrix_animation( - id, name, target, frames, samples, global_rotation_type, ob->parentinv); - } - } -} - -BC_global_rotation_type AnimationExporter::get_global_rotation_type(Object *ob) -{ - bool is_export_root = this->export_settings.is_export_root(ob); - if (!is_export_root) { - return BC_NO_ROTATION; - } - - bool apply_global_rotation = this->export_settings.get_apply_global_orientation(); - - return (apply_global_rotation) ? BC_DATA_ROTATION : BC_OBJECT_ROTATION; -} - -/* Write bone animations in transform matrix sources. */ -void AnimationExporter::export_bone_animations_recursive(Object *ob, - Bone *bone, - BCAnimationSampler &sampler) -{ - bool keep_flat_curves = this->export_settings.get_keep_flat_curves(); - - std::vector<float> frames; - sampler.get_bone_frames(frames, ob, bone); - - if (frames.size()) { - BCMatrixSampleMap samples; - bool is_animated = sampler.get_bone_samples(samples, ob, bone); - if (keep_flat_curves || is_animated) { - export_bone_animation(ob, bone, frames, samples); - } - } - - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - export_bone_animations_recursive(ob, child, sampler); - } -} - -/** - * In some special cases the exported Curve needs to be replaced - * by a modified curve (for collada purposes) - * This method checks if a conversion is necessary and if applicable - * returns a pointer to the modified BCAnimationCurve. - * IMPORTANT: the modified curve must be deleted by the caller when no longer needed - * if no conversion is needed this method returns a NULL; - */ -BCAnimationCurve *AnimationExporter::get_modified_export_curve(Object *ob, - BCAnimationCurve &curve, - BCAnimationCurveMap &curves) -{ - std::string channel_type = curve.get_channel_type(); - BCAnimationCurve *mcurve = NULL; - if (channel_type == "lens") { - - /* Create an xfov curve */ - - BCCurveKey key(BC_ANIMATION_TYPE_CAMERA, "xfov", 0); - mcurve = new BCAnimationCurve(key, ob); - - /* now tricky part: transform the fcurve */ - BCValueMap lens_values; - curve.get_value_map(lens_values); - - BCAnimationCurve *sensor_curve = NULL; - BCCurveKey sensor_key(BC_ANIMATION_TYPE_CAMERA, "sensor_width", 0); - BCAnimationCurveMap::iterator cit = curves.find(sensor_key); - if (cit != curves.end()) { - sensor_curve = cit->second; - } - - BCValueMap::const_iterator vit; - for (vit = lens_values.begin(); vit != lens_values.end(); ++vit) { - int frame = vit->first; - float lens_value = vit->second; - - float sensor_value; - if (sensor_curve) { - sensor_value = sensor_curve->get_value(frame); - } - else { - sensor_value = ((Camera *)ob->data)->sensor_x; - } - float value = RAD2DEGF(focallength_to_fov(lens_value, sensor_value)); - mcurve->add_value(value, frame); - } - /* to reset the handles */ - mcurve->clean_handles(); - } - return mcurve; -} - -void AnimationExporter::export_curve_animation(Object *ob, BCAnimationCurve &curve) -{ - std::string channel_target = curve.get_channel_target(); - - /* - * Some curves can not be exported as is and need some conversion - * For more information see implementation of get_modified_export_curve() - * note: if mcurve is not NULL then it must be deleted at end of this method; - */ - - int channel_index = curve.get_channel_index(); - /* RGB or XYZ or "" */ - std::string channel_type = curve.get_channel_type(); - std::string axis = get_axis_name(channel_type, channel_index); - - std::string action_name; - bAction *action = bc_getSceneObjectAction(ob); - action_name = (action) ? id_name(action) : "constraint_anim"; - - const std::string curve_name = encode_xml(curve.get_animation_name(ob)); - std::string id = bc_get_action_id(action_name, curve_name, channel_target, axis, "."); - - std::string collada_target = translate_id(curve_name); - - if (curve.is_of_animation_type(BC_ANIMATION_TYPE_MATERIAL)) { - int material_index = curve.get_subindex(); - Material *ma = BKE_object_material_get(ob, material_index + 1); - if (ma) { - collada_target = translate_id(id_name(ma)) + "-effect/common/" + - get_collada_sid(curve, axis); - } - } - else { - collada_target += "/" + get_collada_sid(curve, axis); - } - - BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); - export_collada_curve_animation( - id, curve_name, collada_target, axis, curve, global_rotation_type); -} - -void AnimationExporter::export_bone_animation(Object *ob, - Bone *bone, - BCFrames &frames, - BCMatrixSampleMap &samples) -{ - bAction *action = bc_getSceneObjectAction(ob); - std::string bone_name(bone->name); - std::string name = encode_xml(id_name(ob)); - std::string id = bc_get_action_id(id_name(action), name, bone_name, "pose_matrix"); - std::string target = translate_id(id_name(ob) + "_" + bone_name) + "/transform"; - - BC_global_rotation_type global_rotation_type = get_global_rotation_type(ob); - export_collada_matrix_animation( - id, name, target, frames, samples, global_rotation_type, ob->parentinv); -} - -bool AnimationExporter::is_bone_deform_group(Bone *bone) -{ - bool is_def; - /* Check if current bone is deform */ - if ((bone->flag & BONE_NO_DEFORM) == 0) { - return true; - } - /* Check child bones */ - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - /* loop through all the children until deform bone is found, and then return */ - is_def = is_bone_deform_group(child); - if (is_def) { - return true; - } - } - } - /* no deform bone found in children also */ - return false; -} - -void AnimationExporter::export_collada_curve_animation( - std::string id, - std::string name, - std::string collada_target, - std::string axis, - BCAnimationCurve &curve, - BC_global_rotation_type global_rotation_type) -{ - BCFrames frames; - BCValues values; - curve.get_frames(frames); - curve.get_values(values); - std::string channel_target = curve.get_channel_target(); - - fprintf( - stdout, "Export animation curve %s (%d control points)\n", id.c_str(), int(frames.size())); - openAnimation(id, name); - BC_animation_source_type source_type = (curve.is_rotation_curve()) ? BC_SOURCE_TYPE_ANGLE : - BC_SOURCE_TYPE_VALUE; - - std::string input_id = collada_source_from_values( - BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, axis); - std::string output_id = collada_source_from_values( - source_type, COLLADASW::InputSemantic::OUTPUT, values, id, axis); - - bool has_tangents = false; - std::string interpolation_id; - if (this->export_settings.get_keep_smooth_curves()) { - interpolation_id = collada_interpolation_source(curve, id, axis, &has_tangents); - } - else { - interpolation_id = collada_linear_interpolation_source(frames.size(), id); - } - - std::string intangent_id; - std::string outtangent_id; - if (has_tangents) { - intangent_id = collada_tangent_from_curve( - COLLADASW::InputSemantic::IN_TANGENT, curve, id, axis); - outtangent_id = collada_tangent_from_curve( - COLLADASW::InputSemantic::OUT_TANGENT, curve, id, axis); - } - - std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; - - COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); - - sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); - sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); - sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, - COLLADABU::URI(EMPTY_STRING, interpolation_id)); - - if (has_tangents) { - sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, - COLLADABU::URI(EMPTY_STRING, intangent_id)); - sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, - COLLADABU::URI(EMPTY_STRING, outtangent_id)); - } - - addSampler(sampler); - addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), collada_target); - - closeAnimation(); -} - -void AnimationExporter::export_collada_matrix_animation( - std::string id, - std::string name, - std::string target, - BCFrames &frames, - BCMatrixSampleMap &samples, - BC_global_rotation_type global_rotation_type, - Matrix &parentinv) -{ - fprintf( - stdout, "Export animation matrix %s (%d control points)\n", id.c_str(), int(frames.size())); - - openAnimationWithClip(id, name); - - std::string input_id = collada_source_from_values( - BC_SOURCE_TYPE_TIMEFRAME, COLLADASW::InputSemantic::INPUT, frames, id, ""); - std::string output_id = collada_source_from_values(samples, id, global_rotation_type, parentinv); - std::string interpolation_id = collada_linear_interpolation_source(frames.size(), id); - - std::string sampler_id = std::string(id) + SAMPLER_ID_SUFFIX; - COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id); - - sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(EMPTY_STRING, input_id)); - sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(EMPTY_STRING, output_id)); - sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, - COLLADABU::URI(EMPTY_STRING, interpolation_id)); - - /* Matrix animation has no tangents */ - - addSampler(sampler); - addChannel(COLLADABU::URI(EMPTY_STRING, sampler_id), target); - - closeAnimation(); -} - -std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic) -{ - switch (semantic) { - case COLLADASW::InputSemantic::INPUT: - return INPUT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::OUTPUT: - return OUTPUT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::INTERPOLATION: - return INTERPOLATION_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::IN_TANGENT: - return INTANGENT_SOURCE_ID_SUFFIX; - case COLLADASW::InputSemantic::OUT_TANGENT: - return OUTTANGENT_SOURCE_ID_SUFFIX; - default: - break; - } - return ""; -} - -void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList ¶m, - COLLADASW::InputSemantic::Semantics semantic, - bool is_rot, - const std::string axis, - bool transform) -{ - switch (semantic) { - case COLLADASW::InputSemantic::INPUT: - param.push_back("TIME"); - break; - case COLLADASW::InputSemantic::OUTPUT: - if (is_rot) { - param.push_back("ANGLE"); - } - else { - if (axis != "") { - param.push_back(axis); - } - else if (transform) { - param.push_back("TRANSFORM"); - } - else { - /* assumes if axis isn't specified all axises are added */ - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - } - } - break; - case COLLADASW::InputSemantic::IN_TANGENT: - case COLLADASW::InputSemantic::OUT_TANGENT: - param.push_back("X"); - param.push_back("Y"); - break; - default: - break; - } -} - -std::string AnimationExporter::collada_tangent_from_curve( - COLLADASW::InputSemantic::Semantics semantic, - BCAnimationCurve &curve, - const std::string &anim_id, - std::string axis_name) -{ - Scene *scene = this->export_settings.get_scene(); - - std::string channel = curve.get_channel_target(); - - const std::string source_id = anim_id + get_semantic_suffix(semantic); - - bool is_angle = (bc_startswith(channel, "rotation") || channel == "spot_size"); - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(curve.sample_count()); - source.setAccessorStride(2); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, is_angle, axis_name, false); - - source.prepareToAppendValues(); - - const FCurve *fcu = curve.get_fcurve(); - int tangent = (semantic == COLLADASW::InputSemantic::IN_TANGENT) ? 0 : 2; - - for (int i = 0; i < fcu->totvert; i++) { - BezTriple &bezt = fcu->bezt[i]; - - float sampled_time = bezt.vec[tangent][0]; - float sampled_val = bezt.vec[tangent][1]; - - if (is_angle) { - sampled_val = RAD2DEGF(sampled_val); - } - - source.appendValues(FRA2TIME(sampled_time)); - source.appendValues(sampled_val); - } - source.finish(); - return source_id; -} - -std::string AnimationExporter::collada_source_from_values( - BC_animation_source_type source_type, - COLLADASW::InputSemantic::Semantics semantic, - std::vector<float> &values, - const std::string &anim_id, - const std::string axis_name) -{ - BlenderContext &blender_context = this->export_settings.get_blender_context(); - Scene *scene = blender_context.get_scene(); - /* T can be float, int or double */ - - int stride = 1; - int entry_count = values.size() / stride; - std::string source_id = anim_id + get_semantic_suffix(semantic); - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(entry_count); - source.setAccessorStride(stride); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, source_type == BC_SOURCE_TYPE_ANGLE, axis_name, false); - - source.prepareToAppendValues(); - - for (int i = 0; i < entry_count; i++) { - float val = values[i]; - switch (source_type) { - case BC_SOURCE_TYPE_TIMEFRAME: - val = FRA2TIME(val); - break; - case BC_SOURCE_TYPE_ANGLE: - val = RAD2DEGF(val); - break; - default: - break; - } - source.appendValues(val); - } - - source.finish(); - - return source_id; -} - -/* - * Create a collada matrix source for a set of samples - */ -std::string AnimationExporter::collada_source_from_values( - BCMatrixSampleMap &samples, - const std::string &anim_id, - BC_global_rotation_type global_rotation_type, - Matrix &parentinv) -{ - COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT; - std::string source_id = anim_id + get_semantic_suffix(semantic); - - COLLADASW::Float4x4Source source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(samples.size()); - source.setAccessorStride(16); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - add_source_parameters(param, semantic, false, "", true); - - source.prepareToAppendValues(); - - BCMatrixSampleMap::iterator it; - /* could be made configurable */ - int precision = (this->export_settings.get_limit_precision()) ? 6 : -1; - for (it = samples.begin(); it != samples.end(); it++) { - BCMatrix sample = BCMatrix(*it->second); - BCMatrix global_transform = this->export_settings.get_global_transform(); - DMatrix daemat; - if (this->export_settings.get_apply_global_orientation()) { - sample.apply_transform(global_transform); - } - else { - sample.add_transform(global_transform); - } - sample.get_matrix(daemat, true, precision); - source.appendValues(daemat); - } - - source.finish(); - return source_id; -} - -std::string AnimationExporter::collada_interpolation_source(const BCAnimationCurve &curve, - const std::string &anim_id, - const std::string axis, - bool *has_tangents) -{ - std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); - - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(curve.sample_count()); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("INTERPOLATION"); - - source.prepareToAppendValues(); - - *has_tangents = false; - - std::vector<float> frames; - curve.get_frames(frames); - - for (unsigned int i = 0; i < curve.sample_count(); i++) { - float frame = frames[i]; - int ipo = curve.get_interpolation_type(frame); - if (ipo == BEZT_IPO_BEZ) { - source.appendValues(BEZIER_NAME); - *has_tangents = true; - } - else if (ipo == BEZT_IPO_CONST) { - source.appendValues(STEP_NAME); - } - else { - /* BEZT_IPO_LIN */ - source.appendValues(LINEAR_NAME); - } - } - /* unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS */ - - source.finish(); - - return source_id; -} - -std::string AnimationExporter::collada_linear_interpolation_source(int tot, - const std::string &anim_id) -{ - std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION); - - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(tot); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("INTERPOLATION"); - - source.prepareToAppendValues(); - - for (int i = 0; i < tot; i++) { - source.appendValues(LINEAR_NAME); - } - - source.finish(); - - return source_id; -} - -const std::string AnimationExporter::get_collada_name(std::string channel_type) const -{ - /* - * Translation table to map FCurve animation types to Collada animation. - * Todo: Maybe we can keep the names from the fcurves here instead of - * mapping. However this is what i found in the old code. So keep - * this map for now. - */ - static std::map<std::string, std::string> BC_CHANNEL_BLENDER_TO_COLLADA = { - {"rotation", "rotation"}, - {"rotation_euler", "rotation"}, - {"rotation_quaternion", "rotation"}, - {"scale", "scale"}, - {"location", "location"}, - - /* Materials */ - {"specular_color", "specular"}, - {"diffuse_color", "diffuse"}, - {"ior", "index_of_refraction"}, - {"specular_hardness", "specular_hardness"}, - {"alpha", "alpha"}, - - /* Lights */ - {"color", "color"}, - {"fall_off_angle", "falloff_angle"}, - {"spot_size", "falloff_angle"}, - {"fall_off_exponent", "falloff_exponent"}, - {"spot_blend", "falloff_exponent"}, - /* Special blender profile (todo: make this more elegant). */ - {"blender/blender_dist", "blender/blender_dist"}, - /* Special blender profile (todo: make this more elegant). */ - {"distance", "blender/blender_dist"}, - - /* Cameras */ - {"lens", "xfov"}, - {"xfov", "xfov"}, - {"xmag", "xmag"}, - {"zfar", "zfar"}, - {"znear", "znear"}, - {"ortho_scale", "xmag"}, - {"clip_end", "zfar"}, - {"clip_start", "znear"}}; - - std::map<std::string, std::string>::iterator name_it = BC_CHANNEL_BLENDER_TO_COLLADA.find( - channel_type); - if (name_it == BC_CHANNEL_BLENDER_TO_COLLADA.end()) { - return ""; - } - std::string tm_name = name_it->second; - return tm_name; -} - -/* - * Assign sid of the animated parameter or transform for rotation, - * axis name is always appended and the value of append_axis is ignored - */ -std::string AnimationExporter::get_collada_sid(const BCAnimationCurve &curve, - const std::string axis_name) -{ - std::string channel_target = curve.get_channel_target(); - std::string channel_type = curve.get_channel_type(); - std::string tm_name = get_collada_name(channel_type); - - bool is_angle = curve.is_rotation_curve(); - - if (tm_name.size()) { - if (is_angle) { - return tm_name + std::string(axis_name) + ".ANGLE"; - } - else if (axis_name != "") { - return tm_name + "." + std::string(axis_name); - } - else { - return tm_name; - } - } - - return tm_name; -} - -#ifdef WITH_MORPH_ANIMATION -/* TODO: This function needs to be implemented similar to the material animation export - * So we have to update BCSample for this to work. */ -void AnimationExporter::export_morph_animation(Object *ob, BCAnimationSampler &sampler) -{ - FCurve *fcu; - Key *key = BKE_key_from_object(ob); - if (!key) { - return; - } - - if (key->adt && key->adt->action) { - fcu = (FCurve *)key->adt->action->curves.first; - - while (fcu) { - BC_animation_transform_type tm_type = get_transform_type(fcu->rna_path); - - create_keyframed_animation(ob, fcu, tm_type, true, sampler); - - fcu = fcu->next; - } - } -} -#endif diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h deleted file mode 100644 index 64751ec5327..00000000000 --- a/source/blender/collada/AnimationExporter.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __ANIMATIONEXPORTER_H__ -#define __ANIMATIONEXPORTER_H__ - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> - -#include "BCAnimationCurve.h" - -extern "C" { -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_curve_types.h" -#include "DNA_light_types.h" -#include "DNA_camera_types.h" -#include "DNA_armature_types.h" -#include "DNA_material_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" - -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "BLI_utildefines.h" - -#include "BKE_fcurve.h" -#include "BKE_animsys.h" -#include "BKE_scene.h" -#include "BKE_action.h" // pose functions -#include "BKE_armature.h" -#include "BKE_object.h" -#include "BKE_constraint.h" -#include "BIK_api.h" -#include "ED_object.h" -} - -#include "MEM_guardedalloc.h" - -#include "RNA_access.h" - -#include "COLLADASWSource.h" -#include "COLLADASWInstanceGeometry.h" -#include "COLLADASWInputList.h" -#include "COLLADASWPrimitves.h" -#include "COLLADASWVertices.h" -#include "COLLADASWLibraryAnimations.h" -#include "COLLADASWParamTemplate.h" -#include "COLLADASWParamBase.h" -#include "COLLADASWSampler.h" -#include "COLLADASWConstants.h" -#include "COLLADASWBaseInputElement.h" - -#include "EffectExporter.h" -#include "BCAnimationSampler.h" -#include "collada_internal.h" - -#include "IK_solver.h" - -#include <vector> -#include <map> -#include <algorithm> // std::find - -typedef enum BC_animation_source_type { - BC_SOURCE_TYPE_VALUE, - BC_SOURCE_TYPE_ANGLE, - BC_SOURCE_TYPE_TIMEFRAME, -} BC_animation_source_type; - -typedef enum BC_global_rotation_type { - BC_NO_ROTATION, - BC_OBJECT_ROTATION, - BC_DATA_ROTATION -} BC_global_rotation_type; - -class AnimationExporter : COLLADASW::LibraryAnimations { - private: - COLLADASW::StreamWriter *sw; - BCExportSettings &export_settings; - - BC_global_rotation_type get_global_rotation_type(Object *ob); - - public: - AnimationExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) - : COLLADASW::LibraryAnimations(sw), sw(sw), export_settings(export_settings) - { - } - - bool exportAnimations(); - - // called for each exported object - void operator()(Object *ob); - - protected: - void export_object_constraint_animation(Object *ob); - - void export_morph_animation(Object *ob); - - void write_bone_animation_matrix(Object *ob_arm, Bone *bone); - - void write_bone_animation(Object *ob_arm, Bone *bone); - - void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type); - - void sample_and_write_bone_animation_matrix(Object *ob_arm, Bone *bone); - - void sample_animation(float *v, - std::vector<float> &frames, - int type, - Bone *bone, - Object *ob_arm, - bPoseChannel *pChan); - - void sample_animation(std::vector<float[4][4]> &mats, - std::vector<float> &frames, - Bone *bone, - Object *ob_arm, - bPoseChannel *pChan); - - // dae_bone_animation -> add_bone_animation - // (blend this into dae_bone_animation) - void dae_bone_animation(std::vector<float> &fra, - float *v, - int tm_type, - int axis, - std::string ob_name, - std::string bone_name); - - void dae_baked_animation(std::vector<float> &fra, Object *ob_arm, Bone *bone); - - void dae_baked_object_animation(std::vector<float> &fra, Object *ob); - - float convert_time(float frame); - - float convert_angle(float angle); - - std::vector<std::vector<std::string>> anim_meta; - - /* Main entry point into Animation export (called for each exported object) */ - void exportAnimation(Object *ob, BCAnimationSampler &sampler); - - /* export animation as separate trans/rot/scale curves */ - void export_curve_animation_set(Object *ob, BCAnimationSampler &sampler, bool export_tm_curves); - - /* export one single curve */ - void export_curve_animation(Object *ob, BCAnimationCurve &curve); - - /* export animation as matrix data */ - void export_matrix_animation(Object *ob, BCAnimationSampler &sampler); - - /* step through the bone hierarchy */ - void export_bone_animations_recursive(Object *ob_arm, Bone *bone, BCAnimationSampler &sampler); - - /* Export for one bone */ - void export_bone_animation(Object *ob, Bone *bone, BCFrames &frames, BCMatrixSampleMap &outmats); - - /* call to the low level collada exporter */ - void export_collada_curve_animation(std::string id, - std::string name, - std::string target, - std::string axis, - BCAnimationCurve &curve, - BC_global_rotation_type global_rotation_type); - - /* call to the low level collada exporter */ - void export_collada_matrix_animation(std::string id, - std::string name, - std::string target, - BCFrames &frames, - BCMatrixSampleMap &outmats, - BC_global_rotation_type global_rotation_type, - Matrix &parentinv); - - BCAnimationCurve *get_modified_export_curve(Object *ob, - BCAnimationCurve &curve, - BCAnimationCurveMap &curves); - - /* Helper functions */ - void openAnimationWithClip(std::string id, std::string name); - bool open_animation_container(bool has_container, Object *ob); - void close_animation_container(bool has_container); - - /* Input and Output sources (single valued) */ - std::string collada_source_from_values(BC_animation_source_type tm_channel, - COLLADASW::InputSemantic::Semantics semantic, - std::vector<float> &values, - const std::string &anim_id, - const std::string axis_name); - - /* Output sources (matrix data) */ - std::string collada_source_from_values(BCMatrixSampleMap &samples, - const std::string &anim_id, - BC_global_rotation_type global_rotation_type, - Matrix &parentinv); - - /* Interpolation sources */ - std::string collada_linear_interpolation_source(int tot, const std::string &anim_id); - - /* source ID = animation_name + semantic_suffix */ - - std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic); - - void add_source_parameters(COLLADASW::SourceBase::ParameterNameList ¶m, - COLLADASW::InputSemantic::Semantics semantic, - bool is_rot, - const std::string axis, - bool transform); - - int get_point_in_curve(BCBezTriple &bezt, - COLLADASW::InputSemantic::Semantics semantic, - bool is_angle, - float *values); - int get_point_in_curve(const BCAnimationCurve &curve, - float sample_frame, - COLLADASW::InputSemantic::Semantics semantic, - bool is_angle, - float *values); - - std::string collada_tangent_from_curve(COLLADASW::InputSemantic::Semantics semantic, - BCAnimationCurve &curve, - const std::string &anim_id, - const std::string axis_name); - - std::string collada_interpolation_source(const BCAnimationCurve &curve, - const std::string &anim_id, - std::string axis_name, - bool *has_tangents); - - std::string get_axis_name(std::string channel, int id); - const std::string get_collada_name(std::string channel_target) const; - std::string get_collada_sid(const BCAnimationCurve &curve, const std::string axis_name); - - /* ===================================== */ - /* Currently unused or not (yet?) needed */ - /* ===================================== */ - - bool is_bone_deform_group(Bone *bone); - -#if 0 - BC_animation_transform_type _get_transform_type(const std::string path); - void get_eul_source_for_quat(std::vector<float> &cache, Object *ob); -#endif - -#ifdef WITH_MORPH_ANIMATION - void export_morph_animation(Object *ob, BCAnimationSampler &sampler); -#endif -}; - -#endif /* __ANIMATIONEXPORTER_H__ */ diff --git a/source/blender/collada/AnimationImporter.cpp b/source/blender/collada/AnimationImporter.cpp deleted file mode 100644 index 715cd9e1a12..00000000000 --- a/source/blender/collada/AnimationImporter.cpp +++ /dev/null @@ -1,2232 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <stddef.h> - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "DNA_armature_types.h" - -#include "ED_keyframing.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_string_utils.h" - -#include "BLT_translation.h" - -#include "BKE_action.h" -#include "BKE_armature.h" -#include "BKE_fcurve.h" -#include "BKE_object.h" - -#include "MEM_guardedalloc.h" - -#include "collada_utils.h" -#include "AnimationImporter.h" -#include "ArmatureImporter.h" -#include "MaterialExporter.h" - -#include <algorithm> - -/* first try node name, if not available (since is optional), fall back to original id */ -template<class T> static const char *bc_get_joint_name(T *node) -{ - const std::string &id = node->getName(); - return id.size() ? id.c_str() : node->getOriginalId().c_str(); -} - -FCurve *AnimationImporter::create_fcurve(int array_index, const char *rna_path) -{ - FCurve *fcu = (FCurve *)MEM_callocN(sizeof(FCurve), "FCurve"); - fcu->flag = (FCURVE_VISIBLE | FCURVE_AUTO_HANDLES | FCURVE_SELECTED); - fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); - fcu->array_index = array_index; - return fcu; -} - -void AnimationImporter::add_bezt(FCurve *fcu, - float frame, - float value, - eBezTriple_Interpolation ipo) -{ - // float fps = (float)FPS; - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - bez.vec[1][0] = frame; - bez.vec[1][1] = value; - bez.ipo = ipo; /* use default interpolation mode here... */ - bez.f1 = bez.f2 = bez.f3 = SELECT; - bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); - calchandles_fcurve(fcu); -} - -/* create one or several fcurves depending on the number of parameters being animated */ -void AnimationImporter::animation_to_fcurves(COLLADAFW::AnimationCurve *curve) -{ - COLLADAFW::FloatOrDoubleArray &input = curve->getInputValues(); - COLLADAFW::FloatOrDoubleArray &output = curve->getOutputValues(); - - float fps = (float)FPS; - size_t dim = curve->getOutDimension(); - unsigned int i; - - std::vector<FCurve *> &fcurves = curve_map[curve->getUniqueId()]; - - switch (dim) { - case 1: /* X, Y, Z or angle */ - case 3: /* XYZ */ - case 4: - case 16: /* matrix */ - { - for (i = 0; i < dim; i++) { - FCurve *fcu = (FCurve *)MEM_callocN(sizeof(FCurve), "FCurve"); - - fcu->flag = (FCURVE_VISIBLE | FCURVE_AUTO_HANDLES | FCURVE_SELECTED); - fcu->array_index = 0; - fcu->auto_smoothing = U.auto_smoothing_new; - - for (unsigned int j = 0; j < curve->getKeyCount(); j++) { - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - - /* input, output */ - bez.vec[1][0] = bc_get_float_value(input, j) * fps; - bez.vec[1][1] = bc_get_float_value(output, j * dim + i); - bez.h1 = bez.h2 = HD_AUTO; - - if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER || - curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_STEP) { - COLLADAFW::FloatOrDoubleArray &intan = curve->getInTangentValues(); - COLLADAFW::FloatOrDoubleArray &outtan = curve->getOutTangentValues(); - - /* intangent */ - unsigned int index = 2 * (j * dim + i); - bez.vec[0][0] = bc_get_float_value(intan, index) * fps; - bez.vec[0][1] = bc_get_float_value(intan, index + 1); - - /* outtangent */ - bez.vec[2][0] = bc_get_float_value(outtan, index) * fps; - bez.vec[2][1] = bc_get_float_value(outtan, index + 1); - if (curve->getInterpolationType() == COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER) { - bez.ipo = BEZT_IPO_BEZ; - bez.h1 = bez.h2 = HD_AUTO_ANIM; - } - else { - bez.ipo = BEZT_IPO_CONST; - } - } - else { - bez.ipo = BEZT_IPO_LIN; - } -#if 0 - bez.ipo = U.ipo_new; /* use default interpolation mode here... */ -#endif - bez.f1 = bez.f2 = bez.f3 = SELECT; - - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); - } - - calchandles_fcurve(fcu); - - fcurves.push_back(fcu); - unused_curves.push_back(fcu); - } - } break; - default: - fprintf(stderr, - "Output dimension of %d is not yet supported (animation id = %s)\n", - (int)dim, - curve->getOriginalId().c_str()); - } -} - -void AnimationImporter::fcurve_deg_to_rad(FCurve *cu) -{ - for (unsigned int i = 0; i < cu->totvert; i++) { - /* TODO convert handles too */ - cu->bezt[i].vec[1][1] *= DEG2RADF(1.0f); - cu->bezt[i].vec[0][1] *= DEG2RADF(1.0f); - cu->bezt[i].vec[2][1] *= DEG2RADF(1.0f); - } -} - -void AnimationImporter::fcurve_scale(FCurve *cu, int scale) -{ - for (unsigned int i = 0; i < cu->totvert; i++) { - /* TODO convert handles too */ - cu->bezt[i].vec[1][1] *= scale; - cu->bezt[i].vec[0][1] *= scale; - cu->bezt[i].vec[2][1] *= scale; - } -} - -void AnimationImporter::fcurve_is_used(FCurve *fcu) -{ - unused_curves.erase(std::remove(unused_curves.begin(), unused_curves.end(), fcu), - unused_curves.end()); -} - -void AnimationImporter::add_fcurves_to_object(Main *bmain, - Object *ob, - std::vector<FCurve *> &curves, - char *rna_path, - int array_index, - Animation *animated) -{ - bAction *act; - - if (!ob->adt || !ob->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&ob->id); - } - else { - act = ob->adt->action; - } - - std::vector<FCurve *>::iterator it; - int i; - -#if 0 - char *p = strstr(rna_path, "rotation_euler"); - bool is_rotation = p && *(p + strlen("rotation_euler")) == '\0'; - - /* convert degrees to radians for rotation */ - if (is_rotation) { - fcurve_deg_to_rad(fcu); - } -#endif - - for (it = curves.begin(), i = 0; it != curves.end(); it++, i++) { - FCurve *fcu = *it; - fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); - - if (array_index == -1) { - fcu->array_index = i; - } - else { - fcu->array_index = array_index; - } - - if (ob->type == OB_ARMATURE) { - bActionGroup *grp = NULL; - const char *bone_name = bc_get_joint_name(animated->node); - - if (bone_name) { - /* try to find group */ - grp = BKE_action_group_find_name(act, bone_name); - - /* no matching groups, so add one */ - if (grp == NULL) { - /* Add a new group, and make it active */ - grp = (bActionGroup *)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); - - grp->flag = AGRP_SELECTED; - BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); - - BLI_addtail(&act->groups, grp); - BLI_uniquename(&act->groups, - grp, - CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"), - '.', - offsetof(bActionGroup, name), - 64); - } - - /* add F-Curve to group */ - action_groups_add_channel(act, grp, fcu); - fcurve_is_used(fcu); - } -#if 0 - if (is_rotation) { - fcurves_actionGroup_map[grp].push_back(fcu); - } -#endif - } - else { - BLI_addtail(&act->curves, fcu); - fcurve_is_used(fcu); - } - } -} - -AnimationImporter::~AnimationImporter() -{ - /* free unused FCurves */ - for (std::vector<FCurve *>::iterator it = unused_curves.begin(); it != unused_curves.end(); - it++) { - free_fcurve(*it); - } - - if (unused_curves.size()) { - fprintf(stderr, "removed %d unused curves\n", (int)unused_curves.size()); - } -} - -bool AnimationImporter::write_animation(const COLLADAFW::Animation *anim) -{ - if (anim->getAnimationType() == COLLADAFW::Animation::ANIMATION_CURVE) { - COLLADAFW::AnimationCurve *curve = (COLLADAFW::AnimationCurve *)anim; - - /* XXX Don't know if it's necessary - * Should we check outPhysicalDimension? */ - if (curve->getInPhysicalDimension() != COLLADAFW::PHYSICAL_DIMENSION_TIME) { - fprintf(stderr, "Inputs physical dimension is not time.\n"); - return true; - } - - /* a curve can have mixed interpolation type, - * in this case curve->getInterpolationTypes returns a list of interpolation types per key */ - COLLADAFW::AnimationCurve::InterpolationType interp = curve->getInterpolationType(); - - if (interp != COLLADAFW::AnimationCurve::INTERPOLATION_MIXED) { - switch (interp) { - case COLLADAFW::AnimationCurve::INTERPOLATION_LINEAR: - case COLLADAFW::AnimationCurve::INTERPOLATION_BEZIER: - case COLLADAFW::AnimationCurve::INTERPOLATION_STEP: - animation_to_fcurves(curve); - break; - default: - /* TODO there're also CARDINAL, HERMITE, BSPLINE and STEP types */ - fprintf(stderr, - "CARDINAL, HERMITE and BSPLINE anim interpolation types not supported yet.\n"); - break; - } - } - else { - /* not supported yet */ - fprintf(stderr, "MIXED anim interpolation type is not supported yet.\n"); - } - } - else { - fprintf(stderr, "FORMULA animation type is not supported yet.\n"); - } - - return true; -} - -/* called on post-process stage after writeVisualScenes */ -bool AnimationImporter::write_animation_list(const COLLADAFW::AnimationList *animlist) -{ - const COLLADAFW::UniqueId &animlist_id = animlist->getUniqueId(); - animlist_map[animlist_id] = animlist; - -#if 0 - - /* should not happen */ - if (uid_animated_map.find(animlist_id) == uid_animated_map.end()) { - return true; - } - - /* for bones rna_path is like: pose.bones["bone-name"].rotation */ - -#endif - - return true; -} - -/* \todo refactor read_node_transform to not automatically apply anything, - * but rather return the transform matrix, so caller can do with it what is - * necessary. Same for \ref get_node_mat */ -void AnimationImporter::read_node_transform(COLLADAFW::Node *node, Object *ob) -{ - float mat[4][4]; - TransformReader::get_node_mat(mat, node, &uid_animated_map, ob); - if (ob) { - copy_m4_m4(ob->obmat, mat); - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); - } -} - -#if 0 -virtual void AnimationImporter::change_eul_to_quat(Object *ob, bAction *act) -{ - bActionGroup *grp; - int i; - - for (grp = (bActionGroup *)act->groups.first; grp; grp = grp->next) { - - FCurve *eulcu[3] = {NULL, NULL, NULL}; - - if (fcurves_actionGroup_map.find(grp) == fcurves_actionGroup_map.end()) { - continue; - } - - std::vector<FCurve *> &rot_fcurves = fcurves_actionGroup_map[grp]; - - if (rot_fcurves.size() > 3) { - continue; - } - - for (i = 0; i < rot_fcurves.size(); i++) { - eulcu[rot_fcurves[i]->array_index] = rot_fcurves[i]; - } - - char joint_path[100]; - char rna_path[100]; - - BLI_snprintf(joint_path, sizeof(joint_path), "pose.bones[\"%s\"]", grp->name); - BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_quaternion", joint_path); - - FCurve *quatcu[4] = { - create_fcurve(0, rna_path), - create_fcurve(1, rna_path), - create_fcurve(2, rna_path), - create_fcurve(3, rna_path), - }; - - bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, grp->name); - - float m4[4][4], irest[3][3]; - invert_m4_m4(m4, chan->bone->arm_mat); - copy_m3_m4(irest, m4); - - for (i = 0; i < 3; i++) { - - FCurve *cu = eulcu[i]; - - if (!cu) { - continue; - } - - for (int j = 0; j < cu->totvert; j++) { - float frame = cu->bezt[j].vec[1][0]; - - float eul[3] = { - eulcu[0] ? evaluate_fcurve(eulcu[0], frame) : 0.0f, - eulcu[1] ? evaluate_fcurve(eulcu[1], frame) : 0.0f, - eulcu[2] ? evaluate_fcurve(eulcu[2], frame) : 0.0f, - }; - - /* make eul relative to bone rest pose */ - float rot[3][3], rel[3][3], quat[4]; - -# if 0 - eul_to_mat3(rot, eul); - mul_m3_m3m3(rel, irest, rot); - mat3_to_quat(quat, rel); -# endif - - eul_to_quat(quat, eul); - - for (int k = 0; k < 4; k++) { - create_bezt(quatcu[k], frame, quat[k], U.ipo_new); - } - } - } - - /* now replace old Euler curves */ - - for (i = 0; i < 3; i++) { - if (!eulcu[i]) { - continue; - } - - action_groups_remove_channel(act, eulcu[i]); - free_fcurve(eulcu[i]); - } - - chan->rotmode = ROT_MODE_QUAT; - - for (i = 0; i < 4; i++) { - action_groups_add_channel(act, grp, quatcu[i]); - } - } - - bPoseChannel *pchan; - for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) { - pchan->rotmode = ROT_MODE_QUAT; - } -} -#endif - -/* sets the rna_path and array index to curve */ -void AnimationImporter::modify_fcurve(std::vector<FCurve *> *curves, - const char *rna_path, - int array_index, - int scale) -{ - std::vector<FCurve *>::iterator it; - int i; - for (it = curves->begin(), i = 0; it != curves->end(); it++, i++) { - FCurve *fcu = *it; - fcu->rna_path = BLI_strdup(rna_path); - - if (array_index == -1) { - fcu->array_index = i; - } - else { - fcu->array_index = array_index; - } - - if (scale != 1) { - fcurve_scale(fcu, scale); - } - - fcurve_is_used(fcu); - } -} - -void AnimationImporter::unused_fcurve(std::vector<FCurve *> *curves) -{ - /* when an error happens and we can't actually use curve remove it from unused_curves */ - std::vector<FCurve *>::iterator it; - for (it = curves->begin(); it != curves->end(); it++) { - FCurve *fcu = *it; - fcurve_is_used(fcu); - } -} - -void AnimationImporter::find_frames(std::vector<float> *frames, std::vector<FCurve *> *curves) -{ - std::vector<FCurve *>::iterator iter; - for (iter = curves->begin(); iter != curves->end(); iter++) { - FCurve *fcu = *iter; - - for (unsigned int k = 0; k < fcu->totvert; k++) { - /* get frame value from bezTriple */ - float fra = fcu->bezt[k].vec[1][0]; - /* if frame already not added add frame to frames */ - if (std::find(frames->begin(), frames->end(), fra) == frames->end()) { - frames->push_back(fra); - } - } - } -} - -static int get_animation_axis_index(const COLLADABU::Math::Vector3 &axis) -{ - int index; - if (COLLADABU::Math::Vector3::UNIT_X == axis) { - index = 0; - } - else if (COLLADABU::Math::Vector3::UNIT_Y == axis) { - index = 1; - } - else if (COLLADABU::Math::Vector3::UNIT_Z == axis) { - index = 2; - } - else { - index = -1; - } - return index; -} - -/* creates the rna_paths and array indices of fcurves from animations using transformation and - * bound animation class of each animation. */ -void AnimationImporter::Assign_transform_animations( - COLLADAFW::Transformation *transform, - const COLLADAFW::AnimationList::AnimationBinding *binding, - std::vector<FCurve *> *curves, - bool is_joint, - char *joint_path) -{ - COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); - bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; - - /* to check if the no of curves are valid */ - bool xyz = ((tm_type == COLLADAFW::Transformation::TRANSLATE || - tm_type == COLLADAFW::Transformation::SCALE) && - binding->animationClass == COLLADAFW::AnimationList::POSITION_XYZ); - - if (!((!xyz && curves->size() == 1) || (xyz && curves->size() == 3) || is_matrix)) { - fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves->size()); - return; - } - - char rna_path[100]; - - switch (tm_type) { - case COLLADAFW::Transformation::TRANSLATE: - case COLLADAFW::Transformation::SCALE: { - bool loc = tm_type == COLLADAFW::Transformation::TRANSLATE; - if (is_joint) { - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, loc ? "location" : "scale"); - } - else { - BLI_strncpy(rna_path, loc ? "location" : "scale", sizeof(rna_path)); - } - - switch (binding->animationClass) { - case COLLADAFW::AnimationList::POSITION_X: - modify_fcurve(curves, rna_path, 0); - break; - case COLLADAFW::AnimationList::POSITION_Y: - modify_fcurve(curves, rna_path, 1); - break; - case COLLADAFW::AnimationList::POSITION_Z: - modify_fcurve(curves, rna_path, 2); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - modify_fcurve(curves, rna_path, -1); - break; - default: - unused_fcurve(curves); - fprintf(stderr, - "AnimationClass %d is not supported for %s.\n", - binding->animationClass, - loc ? "TRANSLATE" : "SCALE"); - } - break; - } - - case COLLADAFW::Transformation::ROTATE: { - if (is_joint) { - BLI_snprintf(rna_path, sizeof(rna_path), "%s.rotation_euler", joint_path); - } - else { - BLI_strncpy(rna_path, "rotation_euler", sizeof(rna_path)); - } - std::vector<FCurve *>::iterator iter; - for (iter = curves->begin(); iter != curves->end(); iter++) { - FCurve *fcu = *iter; - - /* if transform is rotation the fcurves values must be turned in to radian. */ - if (is_rotation) { - fcurve_deg_to_rad(fcu); - } - } - COLLADAFW::Rotate *rot = (COLLADAFW::Rotate *)transform; - COLLADABU::Math::Vector3 &axis = rot->getRotationAxis(); - - switch (binding->animationClass) { - case COLLADAFW::AnimationList::ANGLE: { - int axis_index = get_animation_axis_index(axis); - if (axis_index >= 0) { - modify_fcurve(curves, rna_path, axis_index); - } - else { - unused_fcurve(curves); - } - } break; - case COLLADAFW::AnimationList::AXISANGLE: - /* TODO convert axis-angle to quat? or XYZ? */ - default: - unused_fcurve(curves); - fprintf(stderr, - "AnimationClass %d is not supported for ROTATE transformation.\n", - binding->animationClass); - } - break; - } - - case COLLADAFW::Transformation::MATRIX: -#if 0 - { - COLLADAFW::Matrix *mat = (COLLADAFW::Matrix *)transform; - COLLADABU::Math::Matrix4 mat4 = mat->getMatrix(); - switch (binding->animationClass) { - case COLLADAFW::AnimationList::TRANSFORM: - } - } -#endif - unused_fcurve(curves); - break; - case COLLADAFW::Transformation::SKEW: - case COLLADAFW::Transformation::LOOKAT: - unused_fcurve(curves); - fprintf(stderr, "Animation of SKEW and LOOKAT transformations is not supported yet.\n"); - break; - } -} - -/* creates the rna_paths and array indices of fcurves from animations using color and bound - * animation class of each animation. */ -void AnimationImporter::Assign_color_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const char *anim_type) -{ - char rna_path[100]; - BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - if (animlist == NULL) { - fprintf(stderr, - "Collada: No animlist found for ID: %s of type %s\n", - listid.toAscii().c_str(), - anim_type); - return; - } - - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - - switch (bindings[j].animationClass) { - case COLLADAFW::AnimationList::COLOR_R: - modify_fcurve(&animcurves, rna_path, 0); - break; - case COLLADAFW::AnimationList::COLOR_G: - modify_fcurve(&animcurves, rna_path, 1); - break; - case COLLADAFW::AnimationList::COLOR_B: - modify_fcurve(&animcurves, rna_path, 2); - break; - case COLLADAFW::AnimationList::COLOR_RGB: - case COLLADAFW::AnimationList::COLOR_RGBA: /* to do-> set intensity */ - modify_fcurve(&animcurves, rna_path, -1); - break; - - default: - unused_fcurve(&animcurves); - fprintf(stderr, - "AnimationClass %d is not supported for %s.\n", - bindings[j].animationClass, - "COLOR"); - } - - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); - } - } -} - -void AnimationImporter::Assign_float_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const char *anim_type) -{ - char rna_path[100]; - if (animlist_map.find(listid) == animlist_map.end()) { - return; - } - else { - /* anim_type has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - - BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - modify_fcurve(&animcurves, rna_path, 0); - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - /* All anim_types whose values are to be converted from Degree to Radians can be ORed here - */ - if (STREQ("spot_size", anim_type)) { - /* NOTE: Do NOT convert if imported file was made by blender <= 2.69.10 - * Reason: old blender versions stored spot_size in radians (was a bug) - */ - if (this->import_from_version == "" || - BLI_strcasecmp_natural(this->import_from_version.c_str(), "2.69.10") != -1) { - fcurve_deg_to_rad(fcu); - } - } - /** XXX What About animtype "rotation" ? */ - - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); - } - } - } -} - -float AnimationImporter::convert_to_focal_length(float in_xfov, - int fov_type, - float aspect, - float sensorx) -{ - /* NOTE: Needs more testing (As we currently have no official test data for this) */ - float xfov = (fov_type == CAMERA_YFOV) ? - (2.0f * atanf(aspect * tanf(DEG2RADF(in_xfov) * 0.5f))) : - DEG2RADF(in_xfov); - return fov_to_focallength(xfov, sensorx); -} - -/* - * Lens animations must be stored in COLLADA by using FOV, - * while blender internally uses focal length. - * The imported animation curves must be converted appropriately. - */ -void AnimationImporter::Assign_lens_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const double aspect, - Camera *cam, - const char *anim_type, - int fov_type) -{ - char rna_path[100]; - if (animlist_map.find(listid) == animlist_map.end()) { - return; - } - else { - /* anim_type has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - - BLI_strncpy(rna_path, anim_type, sizeof(rna_path)); - - modify_fcurve(&animcurves, rna_path, 0); - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - - for (unsigned int i = 0; i < fcu->totvert; i++) { - fcu->bezt[i].vec[0][1] = convert_to_focal_length( - fcu->bezt[i].vec[0][1], fov_type, aspect, cam->sensor_x); - fcu->bezt[i].vec[1][1] = convert_to_focal_length( - fcu->bezt[i].vec[1][1], fov_type, aspect, cam->sensor_x); - fcu->bezt[i].vec[2][1] = convert_to_focal_length( - fcu->bezt[i].vec[2][1], fov_type, aspect, cam->sensor_x); - } - - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); - } - } - } -} - -void AnimationImporter::apply_matrix_curves(Object *ob, - std::vector<FCurve *> &animcurves, - COLLADAFW::Node *root, - COLLADAFW::Node *node, - COLLADAFW::Transformation *tm) -{ - bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; - char joint_path[200]; - if (is_joint) { - armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - } - - std::vector<float> frames; - find_frames(&frames, &animcurves); - - float irest_dae[4][4]; - float rest[4][4], irest[4][4]; - - if (is_joint) { - get_joint_rest_mat(irest_dae, root, node); - invert_m4(irest_dae); - - Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); - if (!bone) { - fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); - return; - } - - unit_m4(rest); - copy_m4_m4(rest, bone->arm_mat); - invert_m4_m4(irest, rest); - } - /* new curves to assign matrix transform animation */ - FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */ - unsigned int totcu = 10; - const char *tm_str = NULL; - char rna_path[200]; - for (int i = 0; i < totcu; i++) { - - int axis = i; - - if (i < 4) { - tm_str = "rotation_quaternion"; - axis = i; - } - else if (i < 7) { - tm_str = "location"; - axis = i - 4; - } - else { - tm_str = "scale"; - axis = i - 7; - } - - if (is_joint) { - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str); - } - else { - BLI_strncpy(rna_path, tm_str, sizeof(rna_path)); - } - newcu[i] = create_fcurve(axis, rna_path); - newcu[i]->totvert = frames.size(); - } - - if (frames.size() == 0) { - return; - } - - std::sort(frames.begin(), frames.end()); - - std::vector<float>::iterator it; - -#if 0 - float qref[4]; - unit_qt(qref); -#endif - - /* sample values at each frame */ - for (it = frames.begin(); it != frames.end(); it++) { - float fra = *it; - - float mat[4][4]; - float matfra[4][4]; - - unit_m4(matfra); - - /* calc object-space mat */ - evaluate_transform_at_frame(matfra, node, fra); - - /* for joints, we need a special matrix */ - if (is_joint) { - /* special matrix: iR * M * iR_dae * R - * where R, iR are bone rest and inverse rest mats in world space (Blender bones), - * iR_dae is joint inverse rest matrix (DAE) - * and M is an evaluated joint world-space matrix (DAE) */ - float temp[4][4], par[4][4]; - - /* calc M */ - calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, par, matfra); - -#if 0 - evaluate_joint_world_transform_at_frame(temp, NULL, node, fra); -#endif - - /* calc special matrix */ - mul_m4_series(mat, irest, temp, irest_dae, rest); - } - else { - copy_m4_m4(mat, matfra); - } - - float rot[4], loc[3], scale[3]; - mat4_decompose(loc, rot, scale, mat); - - /* add keys */ - for (int i = 0; i < totcu; i++) { - if (i < 4) { - add_bezt(newcu[i], fra, rot[i]); - } - else if (i < 7) { - add_bezt(newcu[i], fra, loc[i - 4]); - } - else { - add_bezt(newcu[i], fra, scale[i - 7]); - } - } - } - Main *bmain = CTX_data_main(mContext); - ED_id_action_ensure(bmain, (ID *)&ob->id); - - ListBase *curves = &ob->adt->action->curves; - - /* add curves */ - for (int i = 0; i < totcu; i++) { - if (is_joint) { - add_bone_fcurve(ob, node, newcu[i]); - } - else { - BLI_addtail(curves, newcu[i]); - } -#if 0 - fcurve_is_used(newcu[i]); /* never added to unused */ -#endif - } - - if (is_joint) { - bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name); - chan->rotmode = ROT_MODE_QUAT; - } - else { - ob->rotmode = ROT_MODE_QUAT; - } - - return; -} - -/* - * This function returns the aspect ration from the Collada camera. - * - * Note:COLLADA allows to specify either XFov, or YFov alone. - * In that case the aspect ratio can be determined from - * the viewport aspect ratio (which is 1:1 ?) - * XXX: check this: its probably wrong! - * If both values are specified, then the aspect ration is simply xfov/yfov - * and if aspect ratio is efined, then .. well then its that one. - */ -static const double get_aspect_ratio(const COLLADAFW::Camera *camera) -{ - double aspect = camera->getAspectRatio().getValue(); - - if (aspect == 0) { - const double yfov = camera->getYFov().getValue(); - - if (yfov == 0) { - aspect = 1; /* assume yfov and xfov are equal */ - } - else { - const double xfov = camera->getXFov().getValue(); - if (xfov == 0) { - aspect = 1; - } - else { - aspect = xfov / yfov; - } - } - } - return aspect; -} - -static ListBase &get_animation_curves(Main *bmain, Material *ma) -{ - bAction *act; - if (!ma->adt || !ma->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&ma->id); - } - else { - act = ma->adt->action; - } - - return act->curves; -} - -void AnimationImporter::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 is_joint = node->getType() == COLLADAFW::Node::JOINT; - COLLADAFW::UniqueId uid = node->getUniqueId(); - COLLADAFW::Node *root = root_map.find(uid) == root_map.end() ? node : root_map[uid]; - - Object *ob; - if (is_joint) { - ob = armature_importer->get_armature_for_joint(root); - } - else { - ob = object_map.find(uid) == object_map.end() ? NULL : object_map.find(uid)->second; - } - - if (!ob) { - fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); - return; - } - - AnimationImporter::AnimMix *animType = get_animation_type(node, FW_object_map); - bAction *act; - Main *bmain = CTX_data_main(mContext); - - if ((animType->transform) != 0) { - /* const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; */ /* UNUSED */ - char joint_path[200]; - - if (is_joint) { - armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - } - - if (!ob->adt || !ob->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&ob->id); - } - else { - act = ob->adt->action; - } - - /* Get the list of animation curves of the object */ - ListBase *AnimCurves = &(act->curves); - - const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations(); - - /* for each transformation in node */ - for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) { - COLLADAFW::Transformation *transform = nodeTransforms[i]; - COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); - - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; - bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - - const COLLADAFW::UniqueId &listid = transform->getAnimationList(); - - /* check if transformation has animations */ - if (animlist_map.find(listid) == animlist_map.end()) { - continue; - } - else { - /* transformation has animations */ - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = - animlist->getAnimationBindings(); - /* all the curves belonging to the current binding */ - std::vector<FCurve *> animcurves; - for (unsigned int j = 0; j < bindings.getCount(); j++) { - animcurves = curve_map[bindings[j].animation]; - if (is_matrix) { - apply_matrix_curves(ob, animcurves, root, node, transform); - } - else { - /* calculate rnapaths and array index of fcurves according to transformation and - * animation class */ - Assign_transform_animations( - transform, &bindings[j], &animcurves, is_joint, joint_path); - - std::vector<FCurve *>::iterator iter; - /* Add the curves of the current animation to the object */ - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - - BLI_addtail(AnimCurves, fcu); - fcurve_is_used(fcu); - } - } - } - } - if (is_rotation && !(is_joint || is_matrix)) { - ob->rotmode = ROT_MODE_EUL; - } - } - } - - if ((animType->light) != 0) { - Light *lamp = (Light *)ob->data; - if (!lamp->adt || !lamp->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&lamp->id); - } - else { - act = lamp->adt->action; - } - - ListBase *AnimCurves = &(act->curves); - const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights(); - - for (unsigned int i = 0; i < nodeLights.getCount(); i++) { - const COLLADAFW::Light *light = (COLLADAFW::Light *) - FW_object_map[nodeLights[i]->getInstanciatedObjectId()]; - - if ((animType->light & LIGHT_COLOR) != 0) { - const COLLADAFW::Color *col = &(light->getColor()); - const COLLADAFW::UniqueId &listid = col->getAnimationList(); - - Assign_color_animations(listid, AnimCurves, "color"); - } - if ((animType->light & LIGHT_FOA) != 0) { - const COLLADAFW::AnimatableFloat *foa = &(light->getFallOffAngle()); - const COLLADAFW::UniqueId &listid = foa->getAnimationList(); - - Assign_float_animations(listid, AnimCurves, "spot_size"); - } - if ((animType->light & LIGHT_FOE) != 0) { - const COLLADAFW::AnimatableFloat *foe = &(light->getFallOffExponent()); - const COLLADAFW::UniqueId &listid = foe->getAnimationList(); - - Assign_float_animations(listid, AnimCurves, "spot_blend"); - } - } - } - - if (animType->camera != 0) { - - Camera *cam = (Camera *)ob->data; - if (!cam->adt || !cam->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&cam->id); - } - else { - act = cam->adt->action; - } - - ListBase *AnimCurves = &(act->curves); - const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras(); - - for (unsigned int i = 0; i < nodeCameras.getCount(); i++) { - const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) - FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; - - if ((animType->camera & CAMERA_XFOV) != 0) { - const COLLADAFW::AnimatableFloat *xfov = &(camera->getXFov()); - const COLLADAFW::UniqueId &listid = xfov->getAnimationList(); - double aspect = get_aspect_ratio(camera); - Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_XFOV); - } - - else if ((animType->camera & CAMERA_YFOV) != 0) { - const COLLADAFW::AnimatableFloat *yfov = &(camera->getYFov()); - const COLLADAFW::UniqueId &listid = yfov->getAnimationList(); - double aspect = get_aspect_ratio(camera); - Assign_lens_animations(listid, AnimCurves, aspect, cam, "lens", CAMERA_YFOV); - } - - else if ((animType->camera & CAMERA_XMAG) != 0) { - const COLLADAFW::AnimatableFloat *xmag = &(camera->getXMag()); - const COLLADAFW::UniqueId &listid = xmag->getAnimationList(); - Assign_float_animations(listid, AnimCurves, "ortho_scale"); - } - - else if ((animType->camera & CAMERA_YMAG) != 0) { - const COLLADAFW::AnimatableFloat *ymag = &(camera->getYMag()); - const COLLADAFW::UniqueId &listid = ymag->getAnimationList(); - Assign_float_animations(listid, AnimCurves, "ortho_scale"); - } - - if ((animType->camera & CAMERA_ZFAR) != 0) { - const COLLADAFW::AnimatableFloat *zfar = &(camera->getFarClippingPlane()); - const COLLADAFW::UniqueId &listid = zfar->getAnimationList(); - Assign_float_animations(listid, AnimCurves, "clip_end"); - } - - if ((animType->camera & CAMERA_ZNEAR) != 0) { - const COLLADAFW::AnimatableFloat *znear = &(camera->getNearClippingPlane()); - const COLLADAFW::UniqueId &listid = znear->getAnimationList(); - Assign_float_animations(listid, AnimCurves, "clip_start"); - } - } - } - if (animType->material != 0) { - - Material *ma = BKE_object_material_get(ob, 1); - if (!ma->adt || !ma->adt->action) { - act = ED_id_action_ensure(bmain, (ID *)&ma->id); - } - else { - act = ma->adt->action; - } - - const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries(); - for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) { - const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings(); - for (unsigned int j = 0; j < matBinds.getCount(); j++) { - const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial(); - const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]); - if (ef != NULL) { /* can be NULL [#28909] */ - Material *ma = uid_material_map[matuid]; - if (!ma) { - fprintf(stderr, - "Collada: Node %s refers to undefined material\n", - node->getName().c_str()); - continue; - } - ListBase &AnimCurves = get_animation_curves(bmain, ma); - const COLLADAFW::CommonEffectPointerArray &commonEffects = ef->getCommonEffects(); - COLLADAFW::EffectCommon *efc = commonEffects[0]; - if ((animType->material & MATERIAL_SHININESS) != 0) { - const COLLADAFW::FloatOrParam *shin = &(efc->getShininess()); - const COLLADAFW::UniqueId &listid = shin->getAnimationList(); - Assign_float_animations(listid, &AnimCurves, "specular_hardness"); - } - - if ((animType->material & MATERIAL_IOR) != 0) { - const COLLADAFW::FloatOrParam *ior = &(efc->getIndexOfRefraction()); - const COLLADAFW::UniqueId &listid = ior->getAnimationList(); - Assign_float_animations(listid, &AnimCurves, "raytrace_transparency.ior"); - } - - if ((animType->material & MATERIAL_SPEC_COLOR) != 0) { - const COLLADAFW::ColorOrTexture *cot = &(efc->getSpecular()); - const COLLADAFW::UniqueId &listid = cot->getColor().getAnimationList(); - Assign_color_animations(listid, &AnimCurves, "specular_color"); - } - - if ((animType->material & MATERIAL_DIFF_COLOR) != 0) { - const COLLADAFW::ColorOrTexture *cot = &(efc->getDiffuse()); - const COLLADAFW::UniqueId &listid = cot->getColor().getAnimationList(); - Assign_color_animations(listid, &AnimCurves, "diffuse_color"); - } - } - } - } - } - - delete animType; -} - -void AnimationImporter::add_bone_animation_sampled(Object *ob, - std::vector<FCurve *> &animcurves, - COLLADAFW::Node *root, - COLLADAFW::Node *node, - COLLADAFW::Transformation *tm) -{ - const char *bone_name = bc_get_joint_name(node); - char joint_path[200]; - armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - - std::vector<float> frames; - find_frames(&frames, &animcurves); - - /* convert degrees to radians */ - if (tm->getTransformationType() == COLLADAFW::Transformation::ROTATE) { - - std::vector<FCurve *>::iterator iter; - for (iter = animcurves.begin(); iter != animcurves.end(); iter++) { - FCurve *fcu = *iter; - - fcurve_deg_to_rad(fcu); - } - } - - float irest_dae[4][4]; - float rest[4][4], irest[4][4]; - - get_joint_rest_mat(irest_dae, root, node); - invert_m4(irest_dae); - - Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); - if (!bone) { - fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); - return; - } - - unit_m4(rest); - copy_m4_m4(rest, bone->arm_mat); - invert_m4_m4(irest, rest); - - /* new curves to assign matrix transform animation */ - FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale. */ - unsigned int totcu = 10; - const char *tm_str = NULL; - char rna_path[200]; - for (int i = 0; i < totcu; i++) { - - int axis = i; - - if (i < 4) { - tm_str = "rotation_quaternion"; - axis = i; - } - else if (i < 7) { - tm_str = "location"; - axis = i - 4; - } - else { - tm_str = "scale"; - axis = i - 7; - } - - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str); - - newcu[i] = create_fcurve(axis, rna_path); - newcu[i]->totvert = frames.size(); - } - - if (frames.size() == 0) { - return; - } - - std::sort(frames.begin(), frames.end()); - - BCQuat qref; - - std::vector<float>::iterator it; - - /* sample values at each frame */ - for (it = frames.begin(); it != frames.end(); it++) { - float fra = *it; - - Matrix mat; - Matrix matfra; - - unit_m4(matfra); - - /* calc object-space mat */ - evaluate_transform_at_frame(matfra, node, fra); - - /* for joints, we need a special matrix - * special matrix: iR * M * iR_dae * R - * where R, iR are bone rest and inverse rest mats in world space (Blender bones), - * iR_dae is joint inverse rest matrix (DAE) - * and M is an evaluated joint world-space matrix (DAE). */ - Matrix temp, par; - - /* calc M */ - calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, par, matfra); - - /* evaluate_joint_world_transform_at_frame(temp, NULL, node, fra); */ - - /* calc special matrix */ - mul_m4_series(mat, irest, temp, irest_dae, rest); - - Vector loc, scale; - - qref.rotate_to(mat); - - copy_v3_v3(loc, mat[3]); - mat4_to_size(scale, mat); - - /* add keys */ - for (int i = 0; i < totcu; i++) { - if (i < 4) { - add_bezt(newcu[i], fra, qref.quat()[i]); - } - else if (i < 7) { - add_bezt(newcu[i], fra, loc[i - 4]); - } - else { - add_bezt(newcu[i], fra, scale[i - 7]); - } - } - } - Main *bmain = CTX_data_main(mContext); - ED_id_action_ensure(bmain, (ID *)&ob->id); - - /* add curves */ - for (int i = 0; i < totcu; i++) { - add_bone_fcurve(ob, node, newcu[i]); -#if 0 - fcurve_is_used(newcu[i]); /* never added to unused */ -#endif - } - - bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name); - chan->rotmode = ROT_MODE_QUAT; -} - -/* Check if object is animated by checking if animlist_map - * holds the animlist_id of node transforms */ -AnimationImporter::AnimMix *AnimationImporter::get_animation_type( - const COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map) -{ - AnimMix *types = new AnimMix(); - - const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations(); - - /* for each transformation in node */ - for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) { - COLLADAFW::Transformation *transform = nodeTransforms[i]; - const COLLADAFW::UniqueId &listid = transform->getAnimationList(); - - /* check if transformation has animations */ - if (animlist_map.find(listid) == animlist_map.end()) { - continue; - } - else { - types->transform = types->transform | BC_NODE_TRANSFORM; - break; - } - } - const COLLADAFW::InstanceLightPointerArray &nodeLights = node->getInstanceLights(); - - for (unsigned int i = 0; i < nodeLights.getCount(); i++) { - const COLLADAFW::Light *light = (COLLADAFW::Light *) - FW_object_map[nodeLights[i]->getInstanciatedObjectId()]; - types->light = setAnimType(&(light->getColor()), (types->light), LIGHT_COLOR); - types->light = setAnimType(&(light->getFallOffAngle()), (types->light), LIGHT_FOA); - types->light = setAnimType(&(light->getFallOffExponent()), (types->light), LIGHT_FOE); - - if (types->light != 0) { - break; - } - } - - const COLLADAFW::InstanceCameraPointerArray &nodeCameras = node->getInstanceCameras(); - for (unsigned int i = 0; i < nodeCameras.getCount(); i++) { - const COLLADAFW::Camera *camera = (COLLADAFW::Camera *) - FW_object_map[nodeCameras[i]->getInstanciatedObjectId()]; - if (camera == NULL) { - /* Can happen if the node refers to an unknown camera. */ - continue; - } - - const bool is_perspective_type = camera->getCameraType() == COLLADAFW::Camera::PERSPECTIVE; - - int addition; - const COLLADAFW::Animatable *mag; - const COLLADAFW::UniqueId listid = camera->getYMag().getAnimationList(); - if (animlist_map.find(listid) != animlist_map.end()) { - mag = &(camera->getYMag()); - addition = (is_perspective_type) ? CAMERA_YFOV : CAMERA_YMAG; - } - else { - mag = &(camera->getXMag()); - addition = (is_perspective_type) ? CAMERA_XFOV : CAMERA_XMAG; - } - types->camera = setAnimType(mag, (types->camera), addition); - - types->camera = setAnimType(&(camera->getFarClippingPlane()), (types->camera), CAMERA_ZFAR); - types->camera = setAnimType(&(camera->getNearClippingPlane()), (types->camera), CAMERA_ZNEAR); - - if (types->camera != 0) { - break; - } - } - - const COLLADAFW::InstanceGeometryPointerArray &nodeGeoms = node->getInstanceGeometries(); - for (unsigned int i = 0; i < nodeGeoms.getCount(); i++) { - const COLLADAFW::MaterialBindingArray &matBinds = nodeGeoms[i]->getMaterialBindings(); - for (unsigned int j = 0; j < matBinds.getCount(); j++) { - const COLLADAFW::UniqueId &matuid = matBinds[j].getReferencedMaterial(); - const COLLADAFW::Effect *ef = (COLLADAFW::Effect *)(FW_object_map[matuid]); - if (ef != NULL) { /* can be NULL [#28909] */ - const COLLADAFW::CommonEffectPointerArray &commonEffects = ef->getCommonEffects(); - if (!commonEffects.empty()) { - COLLADAFW::EffectCommon *efc = commonEffects[0]; - types->material = setAnimType( - &(efc->getShininess()), (types->material), MATERIAL_SHININESS); - types->material = setAnimType( - &(efc->getSpecular().getColor()), (types->material), MATERIAL_SPEC_COLOR); - types->material = setAnimType( - &(efc->getDiffuse().getColor()), (types->material), MATERIAL_DIFF_COLOR); -#if 0 - types->material = setAnimType(&(efc->get()), (types->material), MATERIAL_TRANSPARENCY); -#endif - types->material = setAnimType( - &(efc->getIndexOfRefraction()), (types->material), MATERIAL_IOR); - } - } - } - } - return types; -} - -int AnimationImporter::setAnimType(const COLLADAFW::Animatable *prop, int types, int addition) -{ - int anim_type; - const COLLADAFW::UniqueId &listid = prop->getAnimationList(); - if (animlist_map.find(listid) != animlist_map.end()) { - anim_type = types | addition; - } - else { - anim_type = types; - } - - return anim_type; -} - -/* Is not used anymore. */ -void AnimationImporter::find_frames_old(std::vector<float> *frames, - COLLADAFW::Node *node, - COLLADAFW::Transformation::TransformationType tm_type) -{ - bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; - /* for each <rotate>, <translate>, etc. there is a separate Transformation */ - const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations(); - - unsigned int i; - /* find frames at which to sample plus convert all rotation keys to radians */ - for (i = 0; i < nodeTransforms.getCount(); i++) { - COLLADAFW::Transformation *transform = nodeTransforms[i]; - COLLADAFW::Transformation::TransformationType nodeTmType = transform->getTransformationType(); - - if (nodeTmType == tm_type) { - /* get animation bindings for the current transformation */ - const COLLADAFW::UniqueId &listid = transform->getAnimationList(); - /* if transform is animated its animlist must exist. */ - if (animlist_map.find(listid) != animlist_map.end()) { - - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = - animlist->getAnimationBindings(); - - if (bindings.getCount()) { - /* for each AnimationBinding get the fcurves which animate the transform */ - for (unsigned int j = 0; j < bindings.getCount(); j++) { - std::vector<FCurve *> &curves = curve_map[bindings[j].animation]; - bool xyz = ((nodeTmType == COLLADAFW::Transformation::TRANSLATE || - nodeTmType == COLLADAFW::Transformation::SCALE) && - bindings[j].animationClass == COLLADAFW::AnimationList::POSITION_XYZ); - - if ((!xyz && curves.size() == 1) || (xyz && curves.size() == 3) || is_matrix) { - std::vector<FCurve *>::iterator iter; - - for (iter = curves.begin(); iter != curves.end(); iter++) { - FCurve *fcu = *iter; - - /* if transform is rotation the fcurves values must be turned in to radian. */ - if (is_rotation) { - fcurve_deg_to_rad(fcu); - } - - for (unsigned int k = 0; k < fcu->totvert; k++) { - /* get frame value from bezTriple */ - float fra = fcu->bezt[k].vec[1][0]; - /* if frame already not added add frame to frames */ - if (std::find(frames->begin(), frames->end(), fra) == frames->end()) { - frames->push_back(fra); - } - } - } - } - else { - fprintf(stderr, "expected %d curves, got %d\n", xyz ? 3 : 1, (int)curves.size()); - } - } - } - } - } - } -} - -/* prerequisites: - * animlist_map - map animlist id -> animlist - * curve_map - map anim id -> curve(s) */ -Object *AnimationImporter::translate_animation_OLD( - COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Object *> &object_map, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map, - COLLADAFW::Transformation::TransformationType tm_type, - Object *par_job) -{ - - bool is_rotation = tm_type == COLLADAFW::Transformation::ROTATE; - bool is_matrix = tm_type == COLLADAFW::Transformation::MATRIX; - bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - - COLLADAFW::Node *root = root_map.find(node->getUniqueId()) == root_map.end() ? - node : - root_map[node->getUniqueId()]; - Object *ob = is_joint ? armature_importer->get_armature_for_joint(node) : - object_map[node->getUniqueId()]; - const char *bone_name = is_joint ? bc_get_joint_name(node) : NULL; - if (!ob) { - fprintf(stderr, "cannot find Object for Node with id=\"%s\"\n", node->getOriginalId().c_str()); - return NULL; - } - - /* frames at which to sample */ - std::vector<float> frames; - - find_frames_old(&frames, node, tm_type); - - unsigned int i; - - float irest_dae[4][4]; - float rest[4][4], irest[4][4]; - - if (is_joint) { - get_joint_rest_mat(irest_dae, root, node); - invert_m4(irest_dae); - - Bone *bone = BKE_armature_find_bone_name((bArmature *)ob->data, bone_name); - if (!bone) { - fprintf(stderr, "cannot find bone \"%s\"\n", bone_name); - return NULL; - } - - unit_m4(rest); - copy_m4_m4(rest, bone->arm_mat); - invert_m4_m4(irest, rest); - } - - Object *job = NULL; - -#ifdef ARMATURE_TEST - FCurve *job_curves[10]; - job = get_joint_object(root, node, par_job); -#endif - - if (frames.size() == 0) { - return job; - } - - std::sort(frames.begin(), frames.end()); - - const char *tm_str = NULL; - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - tm_str = "rotation_quaternion"; - break; - case COLLADAFW::Transformation::SCALE: - tm_str = "scale"; - break; - case COLLADAFW::Transformation::TRANSLATE: - tm_str = "location"; - break; - case COLLADAFW::Transformation::MATRIX: - break; - default: - return job; - } - - char rna_path[200]; - char joint_path[200]; - - if (is_joint) { - armature_importer->get_rna_path_for_joint(node, joint_path, sizeof(joint_path)); - } - - /* new curves */ - FCurve *newcu[10]; /* if tm_type is matrix, then create 10 curves: 4 rot, 3 loc, 3 scale */ - unsigned int totcu = is_matrix ? 10 : (is_rotation ? 4 : 3); - - for (i = 0; i < totcu; i++) { - - int axis = i; - - if (is_matrix) { - if (i < 4) { - tm_str = "rotation_quaternion"; - axis = i; - } - else if (i < 7) { - tm_str = "location"; - axis = i - 4; - } - else { - tm_str = "scale"; - axis = i - 7; - } - } - - if (is_joint) { - BLI_snprintf(rna_path, sizeof(rna_path), "%s.%s", joint_path, tm_str); - } - else { - BLI_strncpy(rna_path, tm_str, sizeof(rna_path)); - } - newcu[i] = create_fcurve(axis, rna_path); - -#ifdef ARMATURE_TEST - if (is_joint) { - job_curves[i] = create_fcurve(axis, tm_str); - } -#endif - } - - std::vector<float>::iterator it; - - /* sample values at each frame */ - for (it = frames.begin(); it != frames.end(); it++) { - float fra = *it; - - float mat[4][4]; - float matfra[4][4]; - - unit_m4(matfra); - - /* calc object-space mat */ - evaluate_transform_at_frame(matfra, node, fra); - - /* for joints, we need a special matrix */ - if (is_joint) { - /* special matrix: iR * M * iR_dae * R - * where R, iR are bone rest and inverse rest mats in world space (Blender bones), - * iR_dae is joint inverse rest matrix (DAE) - * and M is an evaluated joint world-space matrix (DAE). */ - float temp[4][4], par[4][4]; - - /* calc M */ - calc_joint_parent_mat_rest(par, NULL, root, node); - mul_m4_m4m4(temp, par, matfra); - - /* evaluate_joint_world_transform_at_frame(temp, NULL, node, fra); */ - - /* calc special matrix */ - mul_m4_series(mat, irest, temp, irest_dae, rest); - } - else { - copy_m4_m4(mat, matfra); - } - - float val[4] = {}; - float rot[4], loc[3], scale[3]; - - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, mat); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, mat); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, mat[3]); - break; - case COLLADAFW::Transformation::MATRIX: - mat4_to_quat(rot, mat); - copy_v3_v3(loc, mat[3]); - mat4_to_size(scale, mat); - break; - default: - break; - } - - /* add keys */ - for (i = 0; i < totcu; i++) { - if (is_matrix) { - if (i < 4) { - add_bezt(newcu[i], fra, rot[i]); - } - else if (i < 7) { - add_bezt(newcu[i], fra, loc[i - 4]); - } - else { - add_bezt(newcu[i], fra, scale[i - 7]); - } - } - else { - add_bezt(newcu[i], fra, val[i]); - } - } - -#ifdef ARMATURE_TEST - if (is_joint) { - switch (tm_type) { - case COLLADAFW::Transformation::ROTATE: - mat4_to_quat(val, matfra); - break; - case COLLADAFW::Transformation::SCALE: - mat4_to_size(val, matfra); - break; - case COLLADAFW::Transformation::TRANSLATE: - copy_v3_v3(val, matfra[3]); - break; - case MATRIX: - mat4_to_quat(rot, matfra); - copy_v3_v3(loc, matfra[3]); - mat4_to_size(scale, matfra); - break; - default: - break; - } - - for (i = 0; i < totcu; i++) { - if (is_matrix) { - if (i < 4) { - add_bezt(job_curves[i], fra, rot[i]); - } - else if (i < 7) { - add_bezt(job_curves[i], fra, loc[i - 4]); - } - else { - add_bezt(job_curves[i], fra, scale[i - 7]); - } - } - else { - add_bezt(job_curves[i], fra, val[i]); - } - } - } -#endif - } - Main *bmain = CTX_data_main(mContext); - ED_id_action_ensure(bmain, (ID *)&ob->id); - - ListBase *curves = &ob->adt->action->curves; - - /* add curves */ - for (i = 0; i < totcu; i++) { - if (is_joint) { - add_bone_fcurve(ob, node, newcu[i]); - } - else { - BLI_addtail(curves, newcu[i]); - } - -#ifdef ARMATURE_TEST - if (is_joint) { - BLI_addtail(&job->adt->action->curves, job_curves[i]); - } -#endif - } - - if (is_rotation || is_matrix) { - if (is_joint) { - bPoseChannel *chan = BKE_pose_channel_find_name(ob->pose, bone_name); - chan->rotmode = (is_matrix) ? ROT_MODE_QUAT : ROT_MODE_EUL; - } - else { - ob->rotmode = (is_matrix) ? ROT_MODE_QUAT : ROT_MODE_EUL; - } - } - - return job; -} - -/* internal, better make it private - * warning: evaluates only rotation and only assigns matrix transforms now - * prerequisites: animlist_map, curve_map */ -void AnimationImporter::evaluate_transform_at_frame(float mat[4][4], - COLLADAFW::Node *node, - float fra) -{ - const COLLADAFW::TransformationPointerArray &tms = node->getTransformations(); - - unit_m4(mat); - - for (unsigned int i = 0; i < tms.getCount(); i++) { - COLLADAFW::Transformation *tm = tms[i]; - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - float m[4][4]; - - unit_m4(m); - - std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId(); - if (!evaluate_animation(tm, m, fra, nodename.c_str())) { - switch (type) { - case COLLADAFW::Transformation::ROTATE: - dae_rotate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::TRANSLATE: - dae_translate_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::SCALE: - dae_scale_to_mat4(tm, m); - break; - case COLLADAFW::Transformation::MATRIX: - dae_matrix_to_mat4(tm, m); - break; - default: - fprintf(stderr, "unsupported transformation type %d\n", type); - } - } - - float temp[4][4]; - copy_m4_m4(temp, mat); - - mul_m4_m4m4(mat, temp, m); - } -} - -static void report_class_type_unsupported(const char *path, - const COLLADAFW::AnimationList::AnimationClass animclass, - const COLLADAFW::Transformation::TransformationType type) -{ - if (animclass == COLLADAFW::AnimationList::UNKNOWN_CLASS) { - fprintf(stderr, "%s: UNKNOWN animation class\n", path); - } - else { - fprintf(stderr, - "%s: animation class %d is not supported yet for transformation type %d\n", - path, - animclass, - type); - } -} - -/* return true to indicate that mat contains a sane value */ -bool AnimationImporter::evaluate_animation(COLLADAFW::Transformation *tm, - float mat[4][4], - float fra, - const char *node_id) -{ - const COLLADAFW::UniqueId &listid = tm->getAnimationList(); - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - - if (type != COLLADAFW::Transformation::ROTATE && type != COLLADAFW::Transformation::SCALE && - type != COLLADAFW::Transformation::TRANSLATE && type != COLLADAFW::Transformation::MATRIX) { - fprintf(stderr, "animation of transformation %d is not supported yet\n", type); - return false; - } - - if (animlist_map.find(listid) == animlist_map.end()) { - return false; - } - - const COLLADAFW::AnimationList *animlist = animlist_map[listid]; - const COLLADAFW::AnimationList::AnimationBindings &bindings = animlist->getAnimationBindings(); - - if (bindings.getCount()) { - float vec[3]; - - bool is_scale = (type == COLLADAFW::Transformation::SCALE); - bool is_translate = (type == COLLADAFW::Transformation::TRANSLATE); - - if (is_scale) { - dae_scale_to_v3(tm, vec); - } - else if (is_translate) { - dae_translate_to_v3(tm, vec); - } - - for (unsigned int index = 0; index < bindings.getCount(); index++) { - const COLLADAFW::AnimationList::AnimationBinding &binding = bindings[index]; - std::vector<FCurve *> &curves = curve_map[binding.animation]; - COLLADAFW::AnimationList::AnimationClass animclass = binding.animationClass; - char path[100]; - - switch (type) { - case COLLADAFW::Transformation::ROTATE: - BLI_snprintf(path, sizeof(path), "%s.rotate (binding %u)", node_id, index); - break; - case COLLADAFW::Transformation::SCALE: - BLI_snprintf(path, sizeof(path), "%s.scale (binding %u)", node_id, index); - break; - case COLLADAFW::Transformation::TRANSLATE: - BLI_snprintf(path, sizeof(path), "%s.translate (binding %u)", node_id, index); - break; - case COLLADAFW::Transformation::MATRIX: - BLI_snprintf(path, sizeof(path), "%s.matrix (binding %u)", node_id, index); - break; - default: - break; - } - - if (type == COLLADAFW::Transformation::ROTATE) { - if (curves.size() != 1) { - fprintf(stderr, "expected 1 curve, got %d\n", (int)curves.size()); - return false; - } - - /* TODO support other animclasses */ - if (animclass != COLLADAFW::AnimationList::ANGLE) { - report_class_type_unsupported(path, animclass, type); - return false; - } - - COLLADABU::Math::Vector3 &axis = ((COLLADAFW::Rotate *)tm)->getRotationAxis(); - - float ax[3] = {(float)axis[0], (float)axis[1], (float)axis[2]}; - float angle = evaluate_fcurve(curves[0], fra); - axis_angle_to_mat4(mat, ax, angle); - - return true; - } - else if (is_scale || is_translate) { - bool is_xyz = animclass == COLLADAFW::AnimationList::POSITION_XYZ; - - if ((!is_xyz && curves.size() != 1) || (is_xyz && curves.size() != 3)) { - if (is_xyz) { - fprintf(stderr, "%s: expected 3 curves, got %d\n", path, (int)curves.size()); - } - else { - fprintf(stderr, "%s: expected 1 curve, got %d\n", path, (int)curves.size()); - } - return false; - } - - switch (animclass) { - case COLLADAFW::AnimationList::POSITION_X: - vec[0] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Y: - vec[1] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_Z: - vec[2] = evaluate_fcurve(curves[0], fra); - break; - case COLLADAFW::AnimationList::POSITION_XYZ: - vec[0] = evaluate_fcurve(curves[0], fra); - vec[1] = evaluate_fcurve(curves[1], fra); - vec[2] = evaluate_fcurve(curves[2], fra); - break; - default: - report_class_type_unsupported(path, animclass, type); - break; - } - } - else if (type == COLLADAFW::Transformation::MATRIX) { - /* for now, of matrix animation, - * support only the case when all values are packed into one animation */ - if (curves.size() != 16) { - fprintf(stderr, "%s: expected 16 curves, got %d\n", path, (int)curves.size()); - return false; - } - - COLLADABU::Math::Matrix4 matrix; - int mi = 0, mj = 0; - - for (std::vector<FCurve *>::iterator it = curves.begin(); it != curves.end(); it++) { - matrix.setElement(mi, mj, evaluate_fcurve(*it, fra)); - mj++; - if (mj == 4) { - mi++; - mj = 0; - } - } - unit_converter->dae_matrix_to_mat4_(mat, matrix); - return true; - } - } - - if (is_scale) { - size_to_mat4(mat, vec); - } - else { - copy_v3_v3(mat[3], vec); - } - - return is_scale || is_translate; - } - - return false; -} - -/* gives a world-space mat of joint at rest position */ -void AnimationImporter::get_joint_rest_mat(float mat[4][4], - COLLADAFW::Node *root, - COLLADAFW::Node *node) -{ - /* if bind mat is not available, - * use "current" node transform, i.e. all those tms listed inside <node> */ - if (!armature_importer->get_joint_bind_mat(mat, node)) { - float par[4][4], m[4][4]; - - calc_joint_parent_mat_rest(par, NULL, root, node); - get_node_mat(m, node, NULL, NULL); - mul_m4_m4m4(mat, par, m); - } -} - -/* gives a world-space mat, end's mat not included */ -bool AnimationImporter::calc_joint_parent_mat_rest(float mat[4][4], - float par[4][4], - COLLADAFW::Node *node, - COLLADAFW::Node *end) -{ - float m[4][4]; - - if (node == end) { - par ? copy_m4_m4(mat, par) : unit_m4(mat); - return true; - } - - /* use bind matrix if available or calc "current" world mat */ - if (!armature_importer->get_joint_bind_mat(m, node)) { - if (par) { - float temp[4][4]; - get_node_mat(temp, node, NULL, NULL); - mul_m4_m4m4(m, par, temp); - } - else { - get_node_mat(m, node, NULL, NULL); - } - } - - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (calc_joint_parent_mat_rest(mat, m, children[i], end)) { - return true; - } - } - - return false; -} - -#ifdef ARMATURE_TEST -Object *AnimationImporter::get_joint_object(COLLADAFW::Node *root, - COLLADAFW::Node *node, - Object *par_job) -{ - if (joint_objects.find(node->getUniqueId()) == joint_objects.end()) { - Object *job = bc_add_object(scene, OB_EMPTY, (char *)get_joint_name(node)); - - job->lay = BKE_scene_base_find(scene, job)->lay = 2; - - mul_v3_fl(job->scale, 0.5f); - DEG_id_tag_update(&job->id, ID_RECALC_TRANSFORM); - - ED_id_action_ensure((ID *)&job->id); - - job->rotmode = ROT_MODE_QUAT; - - float mat[4][4]; - get_joint_rest_mat(mat, root, node); - - if (par_job) { - float temp[4][4], ipar[4][4]; - invert_m4_m4(ipar, par_job->obmat); - copy_m4_m4(temp, mat); - mul_m4_m4m4(mat, ipar, temp); - } - - bc_decompose(mat, job->loc, NULL, job->quat, job->scale); - - if (par_job) { - job->parent = par_job; - - DEG_id_tag_update(&par_job->id, ID_RECALC_TRANSFORM); - job->parsubstr[0] = 0; - } - - BKE_object_where_is_calc(scene, job); - - /* after parenting and layer change */ - DEG_relations_tag_update(CTX_data_main(C)); - - joint_objects[node->getUniqueId()] = job; - } - - return joint_objects[node->getUniqueId()]; -} -#endif - -#if 0 -/* recursively evaluates joint tree until end is found, - * mat then is world-space matrix of end mat must be identity on enter, node must be root. */ -bool AnimationImporter::evaluate_joint_world_transform_at_frame( - float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra) -{ - float m[4][4]; - if (par) { - float temp[4][4]; - evaluate_transform_at_frame(temp, node, node == end ? fra : 0.0f); - mul_m4_m4m4(m, par, temp); - } - else { - evaluate_transform_at_frame(m, node, node == end ? fra : 0.0f); - } - - if (node == end) { - copy_m4_m4(mat, m); - return true; - } - else { - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (int i = 0; i < children.getCount(); i++) { - if (evaluate_joint_world_transform_at_frame(mat, m, children[i], end, fra)) { - return true; - } - } - } - - return false; -} -#endif - -void AnimationImporter::add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu) -{ - const char *bone_name = bc_get_joint_name(node); - bAction *act = ob->adt->action; - - /* try to find group */ - bActionGroup *grp = BKE_action_group_find_name(act, bone_name); - - /* no matching groups, so add one */ - if (grp == NULL) { - /* Add a new group, and make it active */ - grp = (bActionGroup *)MEM_callocN(sizeof(bActionGroup), "bActionGroup"); - - grp->flag = AGRP_SELECTED; - BLI_strncpy(grp->name, bone_name, sizeof(grp->name)); - - BLI_addtail(&act->groups, grp); - BLI_uniquename(&act->groups, - grp, - CTX_DATA_(BLT_I18NCONTEXT_ID_ACTION, "Group"), - '.', - offsetof(bActionGroup, name), - 64); - } - - /* add F-Curve to group */ - action_groups_add_channel(act, grp, fcu); -} - -void AnimationImporter::set_import_from_version(std::string import_from_version) -{ - this->import_from_version = import_from_version; -} diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h deleted file mode 100644 index 0043dad7116..00000000000 --- a/source/blender/collada/AnimationImporter.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __ANIMATIONIMPORTER_H__ -#define __ANIMATIONIMPORTER_H__ - -#include <map> -#include <vector> - -#include "COLLADAFWAnimation.h" -#include "COLLADAFWAnimationCurve.h" -#include "COLLADAFWAnimationList.h" -#include "COLLADAFWNode.h" -#include "COLLADAFWUniqueId.h" -#include "COLLADAFWLight.h" -#include "COLLADAFWCamera.h" -#include "COLLADAFWMaterial.h" -#include "COLLADAFWEffect.h" -#include "COLLADAFWInstanceGeometry.h" - -extern "C" { -#include "BKE_context.h" -#include "DNA_anim_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_light_types.h" -#include "DNA_camera_types.h" -} - -//#include "ArmatureImporter.h" -#include "TransformReader.h" - -#include "collada_internal.h" - -class ArmatureImporter; - -class AnimationImporterBase { - public: - // virtual void change_eul_to_quat(Object *ob, bAction *act) = 0; -}; - -class AnimationImporter : private TransformReader, public AnimationImporterBase { - private: - bContext *mContext; - ArmatureImporter *armature_importer; - Scene *scene; - - std::map<COLLADAFW::UniqueId, std::vector<FCurve *>> curve_map; - std::map<COLLADAFW::UniqueId, TransformReader::Animation> uid_animated_map; - // std::map<bActionGroup*, std::vector<FCurve*> > fcurves_actionGroup_map; - std::map<COLLADAFW::UniqueId, const COLLADAFW::AnimationList *> animlist_map; - std::vector<FCurve *> unused_curves; - std::map<COLLADAFW::UniqueId, Object *> joint_objects; - - FCurve *create_fcurve(int array_index, const char *rna_path); - - void add_bezt(FCurve *fcu, - float frame, - float value, - eBezTriple_Interpolation ipo = BEZT_IPO_LIN); - - // create one or several fcurves depending on the number of parameters being animated - void animation_to_fcurves(COLLADAFW::AnimationCurve *curve); - - void fcurve_deg_to_rad(FCurve *cu); - void fcurve_scale(FCurve *cu, int scale); - - void fcurve_is_used(FCurve *fcu); - - void add_fcurves_to_object(Main *bmain, - Object *ob, - std::vector<FCurve *> &curves, - char *rna_path, - int array_index, - Animation *animated); - - int typeFlag; - - std::string import_from_version; - - enum lightAnim { - // INANIMATE = 0, - LIGHT_COLOR = 2, - LIGHT_FOA = 4, - LIGHT_FOE = 8, - }; - - enum cameraAnim { - // INANIMATE = 0, - CAMERA_XFOV = 2, - CAMERA_XMAG = 4, - CAMERA_YFOV = 8, - CAMERA_YMAG = 16, - CAMERA_ZFAR = 32, - CAMERA_ZNEAR = 64, - }; - - enum matAnim { - MATERIAL_SHININESS = 2, - MATERIAL_SPEC_COLOR = 4, - MATERIAL_DIFF_COLOR = 1 << 3, - MATERIAL_TRANSPARENCY = 1 << 4, - MATERIAL_IOR = 1 << 5, - }; - - enum AnimationType { - BC_INANIMATE = 0, - BC_NODE_TRANSFORM = 1, - }; - - struct AnimMix { - int transform; - int light; - int camera; - int material; - int texture; - }; - - public: - AnimationImporter(bContext *C, UnitConverter *conv, ArmatureImporter *arm, Scene *scene) - : TransformReader(conv), mContext(C), armature_importer(arm), scene(scene) - { - } - - ~AnimationImporter(); - - void set_import_from_version(std::string import_from_version); - bool write_animation(const COLLADAFW::Animation *anim); - - // called on post-process stage after writeVisualScenes - bool write_animation_list(const COLLADAFW::AnimationList *animlist); - - void read_node_transform(COLLADAFW::Node *node, Object *ob); -#if 0 - virtual void change_eul_to_quat(Object *ob, bAction *act); -#endif - - 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); - - AnimMix *get_animation_type( - const COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map); - - void apply_matrix_curves(Object *ob, - std::vector<FCurve *> &animcurves, - COLLADAFW::Node *root, - COLLADAFW::Node *node, - COLLADAFW::Transformation *tm); - - void add_bone_animation_sampled(Object *ob, - std::vector<FCurve *> &animcurves, - COLLADAFW::Node *root, - COLLADAFW::Node *node, - COLLADAFW::Transformation *tm); - - void Assign_transform_animations(COLLADAFW::Transformation *transform, - const COLLADAFW::AnimationList::AnimationBinding *binding, - std::vector<FCurve *> *curves, - bool is_joint, - char *joint_path); - - void Assign_color_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const char *anim_type); - void Assign_float_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const char *anim_type); - void Assign_lens_animations(const COLLADAFW::UniqueId &listid, - ListBase *AnimCurves, - const double aspect, - Camera *cam, - const char *anim_type, - int fov_type); - - int setAnimType(const COLLADAFW::Animatable *prop, int type, int addition); - - void modify_fcurve(std::vector<FCurve *> *curves, - const char *rna_path, - int array_index, - int scale = 1); - void unused_fcurve(std::vector<FCurve *> *curves); - // prerequisites: - // animlist_map - map animlist id -> animlist - // curve_map - map anim id -> curve(s) - Object *translate_animation_OLD(COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Object *> &object_map, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &root_map, - COLLADAFW::Transformation::TransformationType tm_type, - Object *par_job = NULL); - - void find_frames(std::vector<float> *frames, std::vector<FCurve *> *curves); - void find_frames_old(std::vector<float> *frames, - COLLADAFW::Node *node, - COLLADAFW::Transformation::TransformationType tm_type); - // internal, better make it private - // warning: evaluates only rotation - // prerequisites: animlist_map, curve_map - void evaluate_transform_at_frame(float mat[4][4], COLLADAFW::Node *node, float fra); - - // return true to indicate that mat contains a sane value - bool evaluate_animation(COLLADAFW::Transformation *tm, - float mat[4][4], - float fra, - const char *node_id); - - // gives a world-space mat of joint at rest position - void get_joint_rest_mat(float mat[4][4], COLLADAFW::Node *root, COLLADAFW::Node *node); - - // gives a world-space mat, end's mat not included - bool calc_joint_parent_mat_rest(float mat[4][4], - float par[4][4], - COLLADAFW::Node *node, - COLLADAFW::Node *end); - - float convert_to_focal_length(float in_xfov, int fov_type, float aspect, float sensorx); - -#ifdef ARMATURE_TEST - Object *get_joint_object(COLLADAFW::Node *root, COLLADAFW::Node *node, Object *par_job); -#endif - -#if 0 - // recursively evaluates joint tree until end is found, mat then is world-space matrix of end - // mat must be identity on enter, node must be root - bool evaluate_joint_world_transform_at_frame( - float mat[4][4], float par[4][4], COLLADAFW::Node *node, COLLADAFW::Node *end, float fra); -#endif - - void add_bone_fcurve(Object *ob, COLLADAFW::Node *node, FCurve *fcu); - - void extra_data_importer(std::string elementName); -}; - -#endif diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp deleted file mode 100644 index 84979cc4ca4..00000000000 --- a/source/blender/collada/ArmatureExporter.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "COLLADASWBaseInputElement.h" -#include "COLLADASWInstanceController.h" -#include "COLLADASWPrimitves.h" -#include "COLLADASWSource.h" - -#include "DNA_action_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" - -#include "BKE_action.h" -#include "BKE_armature.h" - -extern "C" { -#include "BKE_global.h" -#include "BKE_mesh.h" -} - -#include "ED_armature.h" - -#include "BLI_listbase.h" - -#include "GeometryExporter.h" -#include "ArmatureExporter.h" -#include "SceneExporter.h" - -// write bone nodes -void ArmatureExporter::add_armature_bones(Object *ob_arm, - ViewLayer *view_layer, - SceneExporter *se, - std::vector<Object *> &child_objects) - -{ - // write bone nodes - - bArmature *armature = (bArmature *)ob_arm->data; - bool is_edited = armature->edbo != NULL; - - if (!is_edited) { - ED_armature_to_edit(armature); - } - - for (Bone *bone = (Bone *)armature->bonebase.first; bone; bone = bone->next) { - add_bone_node(bone, ob_arm, se, child_objects); - } - - if (!is_edited) { - ED_armature_edit_free(armature); - } -} - -void ArmatureExporter::write_bone_URLs(COLLADASW::InstanceController &ins, - Object *ob_arm, - Bone *bone) -{ - if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) { - std::string joint_id = translate_id(id_name(ob_arm) + "_" + bone->name); - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, joint_id)); - } - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - write_bone_URLs(ins, ob_arm, child); - } - } -} - -bool ArmatureExporter::add_instance_controller(Object *ob) -{ - Object *ob_arm = bc_get_assigned_armature(ob); - bArmature *arm = (bArmature *)ob_arm->data; - - const std::string &controller_id = get_controller_id(ob_arm, ob); - - COLLADASW::InstanceController ins(mSW); - ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); - - Mesh *me = (Mesh *)ob->data; - if (!me->dvert) { - return false; - } - - // write root bone URLs - Bone *bone; - for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { - write_bone_URLs(ins, ob_arm, bone); - } - - InstanceWriter::add_material_bindings( - ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); - - ins.add(); - return true; -} - -#if 0 -void ArmatureExporter::operator()(Object *ob) -{ - Object *ob_arm = bc_get_assigned_armature(ob); -} - -bool ArmatureExporter::already_written(Object *ob_arm) -{ - return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != - written_armatures.end(); -} - -void ArmatureExporter::wrote(Object *ob_arm) -{ - written_armatures.push_back(ob_arm); -} - -void ArmatureExporter::find_objects_using_armature(Object *ob_arm, - std::vector<Object *> &objects, - Scene *sce) -{ - objects.clear(); - - Base *base = (Base *)sce->base.first; - while (base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) { - objects.push_back(ob); - } - - base = base->next; - } -} -#endif - -// parent_mat is armature-space -void ArmatureExporter::add_bone_node(Bone *bone, - Object *ob_arm, - SceneExporter *se, - std::vector<Object *> &child_objects) -{ - if (can_export(bone)) { - std::string node_id = translate_id(id_name(ob_arm) + "_" + bone->name); - std::string node_name = std::string(bone->name); - std::string node_sid = get_joint_sid(bone); - - COLLADASW::Node node(mSW); - - node.setType(COLLADASW::Node::JOINT); - node.setNodeId(node_id); - node.setNodeName(node_name); - node.setNodeSid(node_sid); - - if (this->export_settings.get_use_blender_profile()) { - if (!is_export_root(bone)) { - if (bone->flag & BONE_CONNECTED) { - node.addExtraTechniqueParameter("blender", "connect", true); - } - } - std::string layers = BoneExtended::get_bone_layers(bone->layer); - node.addExtraTechniqueParameter("blender", "layer", layers); - - bArmature *armature = (bArmature *)ob_arm->data; - EditBone *ebone = bc_get_edit_bone(armature, bone->name); - if (ebone && ebone->roll != 0) { - node.addExtraTechniqueParameter("blender", "roll", ebone->roll); - } - if (bc_is_leaf_bone(bone)) { - Vector head, tail; - const BCMatrix &global_transform = this->export_settings.get_global_transform(); - if (this->export_settings.get_apply_global_orientation()) { - bc_add_global_transform(head, bone->arm_head, global_transform); - bc_add_global_transform(tail, bone->arm_tail, global_transform); - } - else { - copy_v3_v3(head, bone->arm_head); - copy_v3_v3(tail, bone->arm_tail); - } - node.addExtraTechniqueParameter("blender", "tip_x", tail[0] - head[0]); - node.addExtraTechniqueParameter("blender", "tip_y", tail[1] - head[1]); - node.addExtraTechniqueParameter("blender", "tip_z", tail[2] - head[2]); - } - } - - node.start(); - - add_bone_transform(ob_arm, bone, node); - - // Write nodes of childobjects, remove written objects from list - std::vector<Object *>::iterator iter = child_objects.begin(); - - while (iter != child_objects.end()) { - Object *ob = *iter; - if (ob->partype == PARBONE && STREQ(ob->parsubstr, bone->name)) { - float backup_parinv[4][4]; - copy_m4_m4(backup_parinv, ob->parentinv); - - // crude, temporary change to parentinv - // so transform gets exported correctly. - - // Add bone tail- translation... don't know why - // bone parenting is against the tail of a bone - // and not it's head, seems arbitrary. - ob->parentinv[3][1] += bone->length; - - // OPEN_SIM_COMPATIBILITY - // TODO: when such objects are animated as - // single matrix the tweak must be applied - // to the result. - if (export_settings.get_open_sim()) { - // tweak objects parentinverse to match compatibility - float temp[4][4]; - - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - - mul_m4_m4m4(ob->parentinv, temp, ob->parentinv); - } - - se->writeNode(ob); - copy_m4_m4(ob->parentinv, backup_parinv); - iter = child_objects.erase(iter); - } - else { - iter++; - } - } - - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, se, child_objects); - } - node.end(); - } - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - add_bone_node(child, ob_arm, se, child_objects); - } - } -} - -bool ArmatureExporter::is_export_root(Bone *bone) -{ - Bone *entry = bone->parent; - while (entry) { - if (can_export(entry)) { - return false; - } - entry = entry->parent; - } - return can_export(bone); -} - -void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node) -{ - // bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name); - - float mat[4][4]; - float bone_rest_mat[4][4]; /* derived from bone->arm_mat */ - float parent_rest_mat[4][4]; /* derived from bone->parent->arm_mat */ - - bool has_restmat = bc_get_property_matrix(bone, "rest_mat", mat); - - if (!has_restmat) { - - /* Have no restpose matrix stored, try old style <= Blender 2.78 */ - - bc_create_restpose_mat(this->export_settings, bone, bone_rest_mat, bone->arm_mat, true); - - if (is_export_root(bone)) { - copy_m4_m4(mat, bone_rest_mat); - } - else { - Matrix parent_inverse; - bc_create_restpose_mat( - this->export_settings, bone->parent, parent_rest_mat, bone->parent->arm_mat, true); - - invert_m4_m4(parent_inverse, parent_rest_mat); - mul_m4_m4m4(mat, parent_inverse, bone_rest_mat); - } - - // OPEN_SIM_COMPATIBILITY - - if (export_settings.get_open_sim()) { - // Remove rotations vs armature from transform - // parent_rest_rot * mat * irest_rot - Matrix workmat; - copy_m4_m4(workmat, bone_rest_mat); - - workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; - invert_m4(workmat); - - mul_m4_m4m4(mat, mat, workmat); - - if (!is_export_root(bone)) { - copy_m4_m4(workmat, parent_rest_mat); - workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; - - mul_m4_m4m4(mat, workmat, mat); - } - } - } - - if (this->export_settings.get_limit_precision()) { - BCMatrix::sanitize(mat, LIMITTED_PRECISION); - } - - TransformWriter::add_joint_transform(node, mat, NULL, this->export_settings, has_restmat); -} - -std::string ArmatureExporter::get_controller_id(Object *ob_arm, Object *ob) -{ - return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + - SKIN_CONTROLLER_ID_SUFFIX; -} diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h deleted file mode 100644 index da6d6f79ef5..00000000000 --- a/source/blender/collada/ArmatureExporter.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __ARMATUREEXPORTER_H__ -#define __ARMATUREEXPORTER_H__ - -#include <list> -#include <string> -//#include <vector> - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryControllers.h" -#include "COLLADASWInputList.h" -#include "COLLADASWNode.h" - -#include "DNA_armature_types.h" -#include "DNA_listBase.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" - -#include "TransformWriter.h" -#include "InstanceWriter.h" - -#include "ExportSettings.h" - -class SceneExporter; - -// XXX exporter writes wrong data for shared armatures. A separate -// controller should be written for each armature-mesh binding how do -// we make controller ids then? -class ArmatureExporter : public COLLADASW::LibraryControllers, - protected TransformWriter, - protected InstanceWriter { - public: - // XXX exporter writes wrong data for shared armatures. A separate - // controller should be written for each armature-mesh binding how do - // we make controller ids then? - ArmatureExporter(BlenderContext &blender_context, - COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings) - : COLLADASW::LibraryControllers(sw), - blender_context(blender_context), - export_settings(export_settings) - { - } - - void add_armature_bones(Object *ob_arm, - ViewLayer *view_layer, - SceneExporter *se, - std::vector<Object *> &child_objects); - - bool add_instance_controller(Object *ob); - - private: - BlenderContext &blender_context; - BCExportSettings &export_settings; - -#if 0 - std::vector<Object *> written_armatures; - - bool already_written(Object *ob_arm); - - void wrote(Object *ob_arm); - - void find_objects_using_armature(Object *ob_arm, std::vector<Object *> &objects, Scene *sce); -#endif - - // Scene, SceneExporter and the list of child_objects - // are required for writing bone parented objects - void add_bone_node(Bone *bone, - Object *ob_arm, - SceneExporter *se, - std::vector<Object *> &child_objects); - - inline bool can_export(Bone *bone) - { - return !(export_settings.get_deform_bones_only() && bone->flag & BONE_NO_DEFORM); - } - - bool is_export_root(Bone *bone); - void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node); - - std::string get_controller_id(Object *ob_arm, Object *ob); - - void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); -}; - -#endif diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp deleted file mode 100644 index b8c534f97dd..00000000000 --- a/source/blender/collada/ArmatureImporter.cpp +++ /dev/null @@ -1,1115 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include <algorithm> - -#include "COLLADAFWUniqueId.h" - -extern "C" { -#include "BKE_action.h" -#include "BKE_object.h" -#include "BKE_armature.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "ED_armature.h" -} - -#include "DEG_depsgraph.h" - -#include "collada_utils.h" -#include "ArmatureImporter.h" - -/* use node name, or fall back to original id if not present (name is optional) */ -template<class T> static const char *bc_get_joint_name(T *node) -{ - const std::string &id = node->getName(); - return id.size() ? id.c_str() : node->getOriginalId().c_str(); -} - -ArmatureImporter::ArmatureImporter(UnitConverter *conv, - MeshImporterBase *mesh, - Main *bmain, - Scene *sce, - ViewLayer *view_layer, - const ImportSettings *import_settings) - : TransformReader(conv), - m_bmain(bmain), - scene(sce), - view_layer(view_layer), - unit_converter(conv), - import_settings(import_settings), - empty(NULL), - mesh_importer(mesh) -{ -} - -ArmatureImporter::~ArmatureImporter() -{ - /* free skin controller data if we forget to do this earlier */ - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - it->second.free(); - } -} - -#if 0 -JointData *ArmatureImporter::get_joint_data(COLLADAFW::Node *node); -{ - const COLLADAFW::UniqueId &joint_id = node->getUniqueId(); - - if (joint_id_to_joint_index_map.find(joint_id) == joint_id_to_joint_index_map.end()) { - fprintf( - stderr, "Cannot find a joint index by joint id for %s.\n", node->getOriginalId().c_str()); - return NULL; - } - - int joint_index = joint_id_to_joint_index_map[joint_id]; - - return &joint_index_to_joint_info_map[joint_index]; -} -#endif - -int ArmatureImporter::create_bone(SkinInfo *skin, - COLLADAFW::Node *node, - EditBone *parent, - int totchild, - float parent_mat[4][4], - bArmature *arm, - std::vector<std::string> &layer_labels) -{ - float mat[4][4]; - float joint_inv_bind_mat[4][4]; - float joint_bind_mat[4][4]; - int chain_length = 0; - - /* Checking if bone is already made. */ - std::vector<COLLADAFW::Node *>::iterator it; - it = std::find(finished_joints.begin(), finished_joints.end(), node); - if (it != finished_joints.end()) { - return chain_length; - } - - EditBone *bone = ED_armature_ebone_add(arm, bc_get_joint_name(node)); - totbone++; - - /* - * We use the inv_bind_shape matrix to apply the armature bind pose as its rest pose. - */ - - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator skin_it; - bool bone_is_skinned = false; - for (skin_it = skin_by_data_uid.begin(); skin_it != skin_by_data_uid.end(); skin_it++) { - - SkinInfo *b = &skin_it->second; - if (b->get_joint_inv_bind_matrix(joint_inv_bind_mat, node)) { - - /* get original world-space matrix */ - invert_m4_m4(mat, joint_inv_bind_mat); - copy_m4_m4(joint_bind_mat, mat); - /* And make local to armature */ - Object *ob_arm = skin->BKE_armature_from_object(); - if (ob_arm) { - float invmat[4][4]; - invert_m4_m4(invmat, ob_arm->obmat); - mul_m4_m4m4(mat, invmat, mat); - } - - bone_is_skinned = true; - break; - } - } - - /* create a bone even if there's no joint data for it (i.e. it has no influence) */ - if (!bone_is_skinned) { - get_node_mat(mat, node, NULL, NULL, parent_mat); - } - - if (parent) { - bone->parent = parent; - } - - float loc[3], size[3], rot[3][3]; - BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(arm); - BoneExtended &be = add_bone_extended(bone, node, totchild, layer_labels, extended_bones); - int layer = be.get_bone_layers(); - if (layer) { - bone->layer = layer; - } - arm->layer |= layer; // ensure that all populated bone layers are visible after import - - float *tail = be.get_tail(); - int use_connect = be.get_use_connect(); - - switch (use_connect) { - case 1: - bone->flag |= BONE_CONNECTED; - break; - case -1: /* Connect type not specified */ - case 0: - bone->flag &= ~BONE_CONNECTED; - break; - } - - if (be.has_roll()) { - bone->roll = be.get_roll(); - } - else { - float angle; - mat4_to_loc_rot_size(loc, rot, size, mat); - mat3_to_vec_roll(rot, NULL, &angle); - bone->roll = angle; - } - copy_v3_v3(bone->head, mat[3]); - - if (bone_is_skinned && this->import_settings->keep_bind_info) { - float rest_mat[4][4]; - get_node_mat(rest_mat, node, NULL, NULL, NULL); - bc_set_IDPropertyMatrix(bone, "bind_mat", joint_bind_mat); - bc_set_IDPropertyMatrix(bone, "rest_mat", rest_mat); - } - - add_v3_v3v3(bone->tail, bone->head, tail); /* tail must be non zero */ - - /* find smallest bone length in armature (used later for leaf bone length) */ - if (parent) { - - if (use_connect == 1) { - copy_v3_v3(parent->tail, bone->head); - } - - /* guess reasonable leaf bone length */ - float length = len_v3v3(parent->head, bone->head); - if ((length < leaf_bone_length || totbone == 0) && length > MINIMUM_BONE_LENGTH) { - leaf_bone_length = length; - } - } - - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - - for (unsigned int i = 0; i < children.getCount(); i++) { - int cl = create_bone(skin, children[i], bone, children.getCount(), mat, arm, layer_labels); - if (cl > chain_length) { - chain_length = cl; - } - } - - bone->length = len_v3v3(bone->head, bone->tail); - joint_by_uid[node->getUniqueId()] = node; - finished_joints.push_back(node); - - be.set_chain_length(chain_length + 1); - - return chain_length + 1; -} - -/** - * Collada only knows Joints, hence bones at the end of a bone chain - * don't have a defined length. This function guesses reasonable - * tail locations for the affected bones (nodes which don't have any connected child) - * Hint: The extended_bones set gets populated in ArmatureImporter::create_bone - */ -void ArmatureImporter::fix_leaf_bone_hierarchy(bArmature *armature, - Bone *bone, - bool fix_orientation) -{ - if (bone == NULL) { - return; - } - - if (bc_is_leaf_bone(bone)) { - BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); - BoneExtended *be = extended_bones[bone->name]; - EditBone *ebone = bc_get_edit_bone(armature, bone->name); - fix_leaf_bone(armature, ebone, be, fix_orientation); - } - - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - fix_leaf_bone_hierarchy(armature, child, fix_orientation); - } -} - -void ArmatureImporter::fix_leaf_bone(bArmature *armature, - EditBone *ebone, - BoneExtended *be, - bool fix_orientation) -{ - if (be == NULL || !be->has_tail()) { - - /* Collada only knows Joints, Here we guess a reasonable leaf bone length */ - float leaf_length = (leaf_bone_length == FLT_MAX) ? 1.0 : leaf_bone_length; - - float vec[3]; - - if (fix_orientation && ebone->parent != NULL) { - EditBone *parent = ebone->parent; - sub_v3_v3v3(vec, ebone->head, parent->head); - if (len_squared_v3(vec) < MINIMUM_BONE_LENGTH) { - sub_v3_v3v3(vec, parent->tail, parent->head); - } - } - else { - vec[2] = 0.1f; - sub_v3_v3v3(vec, ebone->tail, ebone->head); - } - - normalize_v3_v3(vec, vec); - mul_v3_fl(vec, leaf_length); - add_v3_v3v3(ebone->tail, ebone->head, vec); - } -} - -void ArmatureImporter::fix_parent_connect(bArmature *armature, Bone *bone) -{ - /* armature has no bones */ - if (bone == NULL) { - return; - } - - if (bone->parent && bone->flag & BONE_CONNECTED) { - copy_v3_v3(bone->parent->tail, bone->head); - } - - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - fix_parent_connect(armature, child); - } -} - -void ArmatureImporter::connect_bone_chains(bArmature *armature, Bone *parentbone, int clip) -{ - BoneExtensionMap &extended_bones = bone_extension_manager.getExtensionMap(armature); - BoneExtended *dominant_child = NULL; - int maxlen = 0; - - if (parentbone == NULL) { - return; - } - - Bone *child = (Bone *)parentbone->childbase.first; - if (child && (import_settings->find_chains || child->next == NULL)) { - for (; child; child = child->next) { - BoneExtended *be = extended_bones[child->name]; - if (be != NULL) { - int chain_len = be->get_chain_length(); - if (chain_len <= clip) { - if (chain_len > maxlen) { - dominant_child = be; - maxlen = chain_len; - } - else if (chain_len == maxlen) { - dominant_child = NULL; - } - } - } - } - } - - BoneExtended *pbe = extended_bones[parentbone->name]; - if (dominant_child != NULL) { - /* Found a valid chain. Now connect current bone with that chain.*/ - EditBone *pebone = bc_get_edit_bone(armature, parentbone->name); - EditBone *cebone = bc_get_edit_bone(armature, dominant_child->get_name()); - if (pebone && !(cebone->flag & BONE_CONNECTED)) { - float vec[3]; - sub_v3_v3v3(vec, cebone->head, pebone->head); - - /* - * It is possible that the child's head is located on the parents head. - * When this happens, then moving the parent's tail to the child's head - * would result in a zero sized bone and Blender would silently remove the bone. - * So we move the tail only when the resulting bone has a minimum length: - */ - - if (len_squared_v3(vec) > MINIMUM_BONE_LENGTH) { - copy_v3_v3(pebone->tail, cebone->head); - pbe->set_tail(pebone->tail); /* to make fix_leafbone happy ...*/ - if (pbe && pbe->get_chain_length() >= this->import_settings->min_chain_length) { - - BoneExtended *cbe = extended_bones[cebone->name]; - cbe->set_use_connect(true); - - cebone->flag |= BONE_CONNECTED; - pbe->set_leaf_bone(false); - printf("Connect Bone chain: parent (%s --> %s) child)\n", pebone->name, cebone->name); - } - } - } - for (Bone *ch = (Bone *)parentbone->childbase.first; ch; ch = ch->next) { - ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX); - } - } - else if (maxlen > 1 && maxlen > this->import_settings->min_chain_length) { - /* Try again with smaller chain length */ - ArmatureImporter::connect_bone_chains(armature, parentbone, maxlen - 1); - } - else { - /* can't connect this Bone. Proceed with children ... */ - if (pbe) { - pbe->set_leaf_bone(true); - } - for (Bone *ch = (Bone *)parentbone->childbase.first; ch; ch = ch->next) { - ArmatureImporter::connect_bone_chains(armature, ch, UNLIMITED_CHAIN_MAX); - } - } -} - -#if 0 -void ArmatureImporter::set_leaf_bone_shapes(Object *ob_arm) -{ - bPose *pose = ob_arm->pose; - - std::vector<LeafBone>::iterator it; - for (it = leaf_bones.begin(); it != leaf_bones.end(); it++) { - LeafBone &leaf = *it; - - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, leaf.name); - if (pchan) { - pchan->custom = get_empty_for_leaves(); - } - else { - fprintf(stderr, "Cannot find a pose channel for leaf bone %s\n", leaf.name); - } - } -} - -void ArmatureImporter::set_euler_rotmode() -{ - /* just set rotmode = ROT_MODE_EUL on pose channel for each joint */ - - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *>::iterator it; - - for (it = joint_by_uid.begin(); it != joint_by_uid.end(); it++) { - - COLLADAFW::Node *joint = it->second; - - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator sit; - - for (sit = skin_by_data_uid.begin(); sit != skin_by_data_uid.end(); sit++) { - SkinInfo &skin = sit->second; - - if (skin.uses_joint_or_descendant(joint)) { - bPoseChannel *pchan = skin.get_pose_channel_from_node(joint); - - if (pchan) { - pchan->rotmode = ROT_MODE_EUL; - } - else { - fprintf(stderr, "Cannot find pose channel for %s.\n", get_joint_name(joint)); - } - - break; - } - } - } -} -#endif - -Object *ArmatureImporter::get_empty_for_leaves() -{ - if (empty) { - return empty; - } - - empty = bc_add_object(m_bmain, scene, view_layer, OB_EMPTY, NULL); - empty->empty_drawtype = OB_EMPTY_SPHERE; - - return empty; -} - -#if 0 -Object *ArmatureImporter::find_armature(COLLADAFW::Node *node) -{ - JointData *jd = get_joint_data(node); - if (jd) { - return jd->ob_arm; - } - - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (int i = 0; i < children.getCount(); i++) { - Object *ob_arm = find_armature(children[i]); - if (ob_arm) { - return ob_arm; - } - } - - return NULL; -} - -ArmatureJoints &ArmatureImporter::get_armature_joints(Object *ob_arm) -{ - /* try finding it */ - std::vector<ArmatureJoints>::iterator it; - for (it = armature_joints.begin(); it != armature_joints.end(); it++) { - if ((*it).ob_arm == ob_arm) { - return *it; - } - } - - /* not found, create one */ - ArmatureJoints aj; - aj.ob_arm = ob_arm; - armature_joints.push_back(aj); - - return armature_joints.back(); -} -#endif -void ArmatureImporter::create_armature_bones(Main *bmain, std::vector<Object *> &ob_arms) -{ - std::vector<COLLADAFW::Node *>::iterator ri; - std::vector<std::string> layer_labels; - - /* if there is an armature created for root_joint next root_joint */ - for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { - COLLADAFW::Node *node = *ri; - if (get_armature_for_joint(node) != NULL) { - continue; - } - - Object *ob_arm = joint_parent_map[node->getUniqueId()]; - if (!ob_arm) { - continue; - } - - bArmature *armature = (bArmature *)ob_arm->data; - if (!armature) { - continue; - } - - char *bone_name = (char *)bc_get_joint_name(node); - Bone *bone = BKE_armature_find_bone_name(armature, bone_name); - if (bone) { - fprintf(stderr, - "Reuse of child bone [%s] as root bone in same Armature is not supported.\n", - bone_name); - continue; - } - - ED_armature_to_edit(armature); - armature->layer = 0; // layer is set according to imported bone set in create_bone() - - create_bone(NULL, node, NULL, node->getChildNodes().getCount(), NULL, armature, layer_labels); - if (this->import_settings->find_chains) { - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - } - - /* exit armature edit mode to populate the Armature object */ - ED_armature_from_edit(bmain, armature); - ED_armature_edit_free(armature); - ED_armature_to_edit(armature); - - fix_leaf_bone_hierarchy( - armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); - unskinned_armature_map[node->getUniqueId()] = ob_arm; - - ED_armature_from_edit(bmain, armature); - ED_armature_edit_free(armature); - - set_bone_transformation_type(node, ob_arm); - - int index = std::find(ob_arms.begin(), ob_arms.end(), ob_arm) - ob_arms.begin(); - if (index == 0) { - ob_arms.push_back(ob_arm); - } - - DEG_id_tag_update(&ob_arm->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - } -} - -Object *ArmatureImporter::create_armature_bones(Main *bmain, SkinInfo &skin) -{ - /* just do like so: - * - get armature - * - enter editmode - * - add edit bones and head/tail properties using matrices and parent-child info - * - exit edit mode - * - set a sphere shape to leaf bones */ - - Object *ob_arm = NULL; - - /* - * find if there's another skin sharing at least one bone with this skin - * if so, use that skin's armature - */ - - /** - * Pseudocode: - * - * find_node_in_tree(node, root_joint) - * - * skin::find_root_joints(root_joints): - * std::vector root_joints; - * for each root in root_joints: - * for each joint in joints: - * if find_node_in_tree(joint, root): - * if (std::find(root_joints.begin(), root_joints.end(), root) == - * root_joints.end()) root_joints.push_back(root); - * - * for (each skin B with armature) { - * find all root joints for skin B - * - * for each joint X in skin A: - * for each root joint R in skin B: - * if (find_node_in_tree(X, R)) { - * shared = 1; - * goto endloop; - * } - * } - * - * endloop: - */ - - SkinInfo *a = &skin; - Object *shared = NULL; - std::vector<COLLADAFW::Node *> skin_root_joints; - std::vector<std::string> layer_labels; - - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo *b = &it->second; - if (b == a || b->BKE_armature_from_object() == NULL) { - continue; - } - - skin_root_joints.clear(); - - b->find_root_joints(root_joints, joint_by_uid, skin_root_joints); - - std::vector<COLLADAFW::Node *>::iterator ri; - for (ri = skin_root_joints.begin(); ri != skin_root_joints.end(); ri++) { - COLLADAFW::Node *node = *ri; - if (a->uses_joint_or_descendant(node)) { - shared = b->BKE_armature_from_object(); - break; - } - } - - if (shared != NULL) { - break; - } - } - - if (!shared && this->joint_parent_map.size() > 0) { - /* All armatures have been created while creating the Node tree. - * The Collada exporter currently does not create a - * strict relationship between geometries and armatures - * So when we reimport a Blender collada file, then we have - * to guess what is meant. - * XXX This is not safe when we have more than one armatures - * in the import. */ - shared = this->joint_parent_map.begin()->second; - } - - if (shared) { - ob_arm = skin.set_armature(shared); - } - else { - ob_arm = skin.create_armature(m_bmain, scene, view_layer); // once for every armature - } - - /* enter armature edit mode */ - bArmature *armature = (bArmature *)ob_arm->data; - ED_armature_to_edit(armature); - - totbone = 0; - // bone_direction_row = 1; // TODO: don't default to Y but use asset and based on it decide on - /* default row */ - - /* create bones */ - /* TODO: - * check if bones have already been created for a given joint */ - - std::vector<COLLADAFW::Node *>::iterator ri; - for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { - COLLADAFW::Node *node = *ri; - /* for shared armature check if bone tree is already created */ - if (shared && std::find(skin_root_joints.begin(), skin_root_joints.end(), node) != - skin_root_joints.end()) { - continue; - } - - /* since root_joints may contain joints for multiple controllers, we need to filter */ - if (skin.uses_joint_or_descendant(node)) { - - create_bone( - &skin, node, NULL, node->getChildNodes().getCount(), NULL, armature, layer_labels); - - if (joint_parent_map.find(node->getUniqueId()) != joint_parent_map.end() && - !skin.get_parent()) { - skin.set_parent(joint_parent_map[node->getUniqueId()]); - } - } - } - - /* exit armature edit mode to populate the Armature object */ - ED_armature_from_edit(bmain, armature); - ED_armature_edit_free(armature); - - for (ri = root_joints.begin(); ri != root_joints.end(); ri++) { - COLLADAFW::Node *node = *ri; - set_bone_transformation_type(node, ob_arm); - } - - ED_armature_to_edit(armature); - if (this->import_settings->find_chains) { - connect_bone_chains(armature, (Bone *)armature->bonebase.first, UNLIMITED_CHAIN_MAX); - } - fix_leaf_bone_hierarchy( - armature, (Bone *)armature->bonebase.first, this->import_settings->fix_orientation); - ED_armature_from_edit(bmain, armature); - ED_armature_edit_free(armature); - - DEG_id_tag_update(&ob_arm->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); - - return ob_arm; -} - -void ArmatureImporter::set_bone_transformation_type(const COLLADAFW::Node *node, Object *ob_arm) -{ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bc_get_joint_name(node)); - if (pchan) { - pchan->rotmode = (node_is_decomposed(node)) ? ROT_MODE_EUL : ROT_MODE_QUAT; - } - - COLLADAFW::NodePointerArray childnodes = node->getChildNodes(); - for (int index = 0; index < childnodes.getCount(); index++) { - node = childnodes[index]; - set_bone_transformation_type(node, ob_arm); - } -} - -void ArmatureImporter::set_pose(Object *ob_arm, - COLLADAFW::Node *root_node, - const char *parentname, - float parent_mat[4][4]) -{ - const char *bone_name = bc_get_joint_name(root_node); - float mat[4][4]; - float obmat[4][4]; - - /* object-space */ - get_node_mat(obmat, root_node, NULL, NULL); - bool is_decomposed = node_is_decomposed(root_node); - - // if (*edbone) - bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone_name); - pchan->rotmode = (is_decomposed) ? ROT_MODE_EUL : ROT_MODE_QUAT; - - // else fprintf ( "", - - /* get world-space */ - if (parentname) { - mul_m4_m4m4(mat, parent_mat, obmat); - bPoseChannel *parchan = BKE_pose_channel_find_name(ob_arm->pose, parentname); - - mul_m4_m4m4(pchan->pose_mat, parchan->pose_mat, mat); - } - else { - - copy_m4_m4(mat, obmat); - float invObmat[4][4]; - invert_m4_m4(invObmat, ob_arm->obmat); - mul_m4_m4m4(pchan->pose_mat, invObmat, mat); - } - -#if 0 - float angle = 0.0f; - mat4_to_axis_angle(ax, &angle, mat); - pchan->bone->roll = angle; -#endif - - COLLADAFW::NodePointerArray &children = root_node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - set_pose(ob_arm, children[i], bone_name, mat); - } -} - -bool ArmatureImporter::node_is_decomposed(const COLLADAFW::Node *node) -{ - const COLLADAFW::TransformationPointerArray &nodeTransforms = node->getTransformations(); - for (unsigned int i = 0; i < nodeTransforms.getCount(); i++) { - COLLADAFW::Transformation *transform = nodeTransforms[i]; - COLLADAFW::Transformation::TransformationType tm_type = transform->getTransformationType(); - if (tm_type == COLLADAFW::Transformation::MATRIX) { - return false; - } - } - return true; -} - -/** - * root - if this joint is the top joint in hierarchy, if a joint - * is a child of a node (not joint), root should be true since - * this is where we build armature bones from - */ -void ArmatureImporter::add_root_joint(COLLADAFW::Node *node, Object *parent) -{ - root_joints.push_back(node); - if (parent) { - joint_parent_map[node->getUniqueId()] = parent; - } -} - -#if 0 -void ArmatureImporter::add_root_joint(COLLADAFW::Node *node) -{ - // root_joints.push_back(node); - Object *ob_arm = find_armature(node); - if (ob_arm) { - get_armature_joints(ob_arm).root_joints.push_back(node); - } -# ifdef COLLADA_DEBUG - else { - fprintf(stderr, "%s cannot be added to armature.\n", get_joint_name(node)); - } -# endif -} -#endif - -/* here we add bones to armatures, having armatures previously created in write_controller */ -void ArmatureImporter::make_armatures(bContext *C, std::vector<Object *> &objects_to_scale) -{ - Main *bmain = CTX_data_main(C); - std::vector<Object *> ob_arms; - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; - - /* TODO: Make this work for more than one armature in the import file. */ - leaf_bone_length = FLT_MAX; - - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - - SkinInfo &skin = it->second; - - Object *ob_arm = create_armature_bones(bmain, skin); - - /* link armature with a mesh object */ - const COLLADAFW::UniqueId &uid = skin.get_controller_uid(); - const COLLADAFW::UniqueId *guid = get_geometry_uid(uid); - if (guid != NULL) { - Object *ob = mesh_importer->get_object_by_geom_uid(*guid); - if (ob) { - skin.link_armature(C, ob, joint_by_uid, this); - - std::vector<Object *>::iterator ob_it = std::find( - objects_to_scale.begin(), objects_to_scale.end(), ob); - - if (ob_it != objects_to_scale.end()) { - int index = ob_it - objects_to_scale.begin(); - objects_to_scale.erase(objects_to_scale.begin() + index); - } - - if (std::find(objects_to_scale.begin(), objects_to_scale.end(), ob_arm) == - objects_to_scale.end()) { - objects_to_scale.push_back(ob_arm); - } - - if (std::find(ob_arms.begin(), ob_arms.end(), ob_arm) == ob_arms.end()) { - ob_arms.push_back(ob_arm); - } - } - else { - fprintf(stderr, "Cannot find object to link armature with.\n"); - } - } - else { - fprintf(stderr, "Cannot find geometry to link armature with.\n"); - } - - /* set armature parent if any */ - Object *par = skin.get_parent(); - if (par) { - bc_set_parent(skin.BKE_armature_from_object(), par, C, false); - } - - /* free memory stolen from SkinControllerData */ - skin.free(); - } - - /* for bones without skins */ - create_armature_bones(bmain, ob_arms); - - /* Fix bone relations */ - std::vector<Object *>::iterator ob_arm_it; - for (ob_arm_it = ob_arms.begin(); ob_arm_it != ob_arms.end(); ob_arm_it++) { - - Object *ob_arm = *ob_arm_it; - bArmature *armature = (bArmature *)ob_arm->data; - - /* and step back to edit mode to fix the leaf nodes */ - ED_armature_to_edit(armature); - - fix_parent_connect(armature, (Bone *)armature->bonebase.first); - - ED_armature_from_edit(bmain, armature); - ED_armature_edit_free(armature); - } -} - -#if 0 -/* link with meshes, create vertex groups, assign weights */ -void ArmatureImporter::link_armature(Object *ob_arm, - const COLLADAFW::UniqueId &geom_id, - const COLLADAFW::UniqueId &controller_data_id) -{ - Object *ob = mesh_importer->get_object_by_geom_uid(geom_id); - - if (!ob) { - fprintf(stderr, "Cannot find object by geometry UID.\n"); - return; - } - - if (skin_by_data_uid.find(controller_data_id) == skin_by_data_uid.end()) { - fprintf(stderr, "Cannot find skin info by controller data UID.\n"); - return; - } - - SkinInfo &skin = skin_by_data_uid[conroller_data_id]; - - /* create vertex groups */ -} -#endif - -bool ArmatureImporter::write_skin_controller_data(const COLLADAFW::SkinControllerData *data) -{ - /* at this stage we get vertex influence info that should go into me->verts and ob->defbase - * there's no info to which object this should be long so we associate it with - * skin controller data UID. */ - - /* don't forget to call BKE_object_defgroup_unique_name before we copy */ - - /* controller data uid -> [armature] -> joint data, - * [mesh object] */ - - SkinInfo skin(unit_converter); - skin.borrow_skin_controller_data(data); - - /* store join inv bind matrix to use it later in armature construction */ - const COLLADAFW::Matrix4Array &inv_bind_mats = data->getInverseBindMatrices(); - for (unsigned int i = 0; i < data->getJointsCount(); i++) { - skin.add_joint(inv_bind_mats[i]); - } - - skin_by_data_uid[data->getUniqueId()] = skin; - - return true; -} - -bool ArmatureImporter::write_controller(const COLLADAFW::Controller *controller) -{ - /* - create and store armature object */ - const COLLADAFW::UniqueId &con_id = controller->getUniqueId(); - - if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_SKIN) { - COLLADAFW::SkinController *co = (COLLADAFW::SkinController *)controller; - /* to be able to find geom id by controller id */ - geom_uid_by_controller_uid[con_id] = co->getSource(); - - const COLLADAFW::UniqueId &data_uid = co->getSkinControllerData(); - if (skin_by_data_uid.find(data_uid) == skin_by_data_uid.end()) { - fprintf(stderr, "Cannot find skin by controller data UID.\n"); - return true; - } - - skin_by_data_uid[data_uid].set_controller(co); - } - /* morph controller */ - else if (controller->getControllerType() == COLLADAFW::Controller::CONTROLLER_TYPE_MORPH) { - COLLADAFW::MorphController *co = (COLLADAFW::MorphController *)controller; - /* to be able to find geom id by controller id */ - geom_uid_by_controller_uid[con_id] = co->getSource(); - /* Shape keys are applied in DocumentImporter->finish() */ - morph_controllers.push_back(co); - } - - return true; -} - -void ArmatureImporter::make_shape_keys(bContext *C) -{ - Main *bmain = CTX_data_main(C); - std::vector<COLLADAFW::MorphController *>::iterator mc; - float weight; - - for (mc = morph_controllers.begin(); mc != morph_controllers.end(); mc++) { - /* Controller data */ - COLLADAFW::UniqueIdArray &morphTargetIds = (*mc)->getMorphTargets(); - COLLADAFW::FloatOrDoubleArray &morphWeights = (*mc)->getMorphWeights(); - - /* Prereq: all the geometries must be imported and mesh objects must be made */ - Object *source_ob = this->mesh_importer->get_object_by_geom_uid((*mc)->getSource()); - - if (source_ob) { - - Mesh *source_me = (Mesh *)source_ob->data; - /* insert key to source mesh */ - Key *key = source_me->key = BKE_key_add(bmain, (ID *)source_me); - key->type = KEY_RELATIVE; - KeyBlock *kb; - - /* insert basis key */ - kb = BKE_keyblock_add_ctime(key, "Basis", false); - BKE_keyblock_convert_from_mesh(source_me, key, kb); - - /* insert other shape keys */ - for (int i = 0; i < morphTargetIds.getCount(); i++) { - /* better to have a separate map of morph objects, - * This'll do for now since only mesh morphing is imported */ - - Mesh *me = this->mesh_importer->get_mesh_by_geom_uid(morphTargetIds[i]); - - if (me) { - me->key = key; - std::string morph_name = *this->mesh_importer->get_geometry_name(me->id.name); - - kb = BKE_keyblock_add_ctime(key, morph_name.c_str(), false); - BKE_keyblock_convert_from_mesh(me, key, kb); - - /* apply weights */ - weight = morphWeights.getFloatValues()->getData()[i]; - kb->curval = weight; - } - else { - fprintf(stderr, "Morph target geometry not found.\n"); - } - } - } - else { - fprintf(stderr, "Morph target object not found.\n"); - } - } -} - -COLLADAFW::UniqueId *ArmatureImporter::get_geometry_uid(const COLLADAFW::UniqueId &controller_uid) -{ - if (geom_uid_by_controller_uid.find(controller_uid) == geom_uid_by_controller_uid.end()) { - return NULL; - } - - return &geom_uid_by_controller_uid[controller_uid]; -} - -Object *ArmatureImporter::get_armature_for_joint(COLLADAFW::Node *node) -{ - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo &skin = it->second; - - if (skin.uses_joint_or_descendant(node)) { - return skin.BKE_armature_from_object(); - } - } - - std::map<COLLADAFW::UniqueId, Object *>::iterator arm; - for (arm = unskinned_armature_map.begin(); arm != unskinned_armature_map.end(); arm++) { - if (arm->first == node->getUniqueId()) { - return arm->second; - } - } - return NULL; -} - -void ArmatureImporter::set_tags_map(TagsMap &tagsMap) -{ - this->uid_tags_map = tagsMap; -} - -void ArmatureImporter::get_rna_path_for_joint(COLLADAFW::Node *node, - char *joint_path, - size_t count) -{ - BLI_snprintf(joint_path, count, "pose.bones[\"%s\"]", bc_get_joint_name(node)); -} - -/* gives a world-space mat */ -bool ArmatureImporter::get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint) -{ - std::map<COLLADAFW::UniqueId, SkinInfo>::iterator it; - bool found = false; - for (it = skin_by_data_uid.begin(); it != skin_by_data_uid.end(); it++) { - SkinInfo &skin = it->second; - if ((found = skin.get_joint_inv_bind_matrix(m, joint))) { - invert_m4(m); - break; - } - } - - return found; -} - -BoneExtended &ArmatureImporter::add_bone_extended(EditBone *bone, - COLLADAFW::Node *node, - int sibcount, - std::vector<std::string> &layer_labels, - BoneExtensionMap &extended_bones) -{ - BoneExtended *be = new BoneExtended(bone); - extended_bones[bone->name] = be; - - TagsMap::iterator etit; - ExtraTags *et = 0; - etit = uid_tags_map.find(node->getUniqueId().toAscii()); - - bool has_connect = false; - int connect_type = -1; - - if (etit != uid_tags_map.end()) { - - float tail[3] = {FLT_MAX, FLT_MAX, FLT_MAX}; - float roll = 0; - std::string layers; - - et = etit->second; - - bool has_tail = false; - has_tail |= et->setData("tip_x", &tail[0]); - has_tail |= et->setData("tip_y", &tail[1]); - has_tail |= et->setData("tip_z", &tail[2]); - - has_connect = et->setData("connect", &connect_type); - bool has_roll = et->setData("roll", &roll); - - layers = et->setData("layer", layers); - - if (has_tail && !has_connect) { - /* got a bone tail definition but no connect info -> bone is not connected */ - has_connect = true; - connect_type = 0; - } - - be->set_bone_layers(layers, layer_labels); - if (has_tail) { - be->set_tail(tail); - } - if (has_roll) { - be->set_roll(roll); - } - } - - if (!has_connect && this->import_settings->auto_connect) { - /* auto connect only whyen parent has exactly one child*/ - connect_type = sibcount == 1; - } - - be->set_use_connect(connect_type); - be->set_leaf_bone(true); - - return *be; -} diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h deleted file mode 100644 index da92c04e5dc..00000000000 --- a/source/blender/collada/ArmatureImporter.h +++ /dev/null @@ -1,187 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __ARMATUREIMPORTER_H__ -#define __ARMATUREIMPORTER_H__ - -#include "COLLADAFWNode.h" -#include "COLLADAFWUniqueId.h" -#include "COLLADAFWMorphController.h" - -extern "C" { -#include "BKE_context.h" -#include "BKE_key.h" - -#include "DNA_armature_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_key_types.h" - -#include "ED_armature.h" -} - -#include "AnimationImporter.h" -#include "MeshImporter.h" -#include "SkinInfo.h" -#include "TransformReader.h" -#include "ExtraTags.h" - -#include <map> -#include <vector> - -#include "collada_internal.h" -#include "collada_utils.h" -#include "ImportSettings.h" - -#define UNLIMITED_CHAIN_MAX INT_MAX -#define MINIMUM_BONE_LENGTH 0.000001f - -class ArmatureImporter : private TransformReader { - private: - Main *m_bmain; - Scene *scene; - ViewLayer *view_layer; - UnitConverter *unit_converter; - const ImportSettings *import_settings; - - // std::map<int, JointData> joint_index_to_joint_info_map; - // std::map<COLLADAFW::UniqueId, int> joint_id_to_joint_index_map; - BoneExtensionManager bone_extension_manager; - // int bone_direction_row; // XXX not used - float leaf_bone_length; - int totbone; - // XXX not used - // float min_angle; // minimum angle between bone head-tail and a row of bone matrix - -#if 0 - struct ArmatureJoints { - Object *ob_arm; - std::vector<COLLADAFW::Node *> root_joints; - }; - std::vector<ArmatureJoints> armature_joints; -#endif - - Object *empty; // empty for leaf bones - - std::map<COLLADAFW::UniqueId, COLLADAFW::UniqueId> geom_uid_by_controller_uid; - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> joint_by_uid; // contains all joints - std::vector<COLLADAFW::Node *> root_joints; - std::vector<COLLADAFW::Node *> finished_joints; - std::vector<COLLADAFW::MorphController *> morph_controllers; - std::map<COLLADAFW::UniqueId, Object *> joint_parent_map; - std::map<COLLADAFW::UniqueId, Object *> unskinned_armature_map; - - MeshImporterBase *mesh_importer; - - // This is used to store data passed in write_controller_data. - // Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members - // so that arrays don't get freed until we free them explicitly. - - std::map<COLLADAFW::UniqueId, SkinInfo> skin_by_data_uid; // data UID = skin controller data UID -#if 0 - JointData *get_joint_data(COLLADAFW::Node *node); -#endif - - int create_bone(SkinInfo *skin, - COLLADAFW::Node *node, - EditBone *parent, - int totchild, - float parent_mat[4][4], - bArmature *arm, - std::vector<std::string> &layer_labels); - - BoneExtended &add_bone_extended(EditBone *bone, - COLLADAFW::Node *node, - int sibcount, - std::vector<std::string> &layer_labels, - BoneExtensionMap &extended_bones); - - void fix_leaf_bone_hierarchy(bArmature *armature, Bone *bone, bool fix_orientation); - void fix_leaf_bone(bArmature *armature, EditBone *ebone, BoneExtended *be, bool fix_orientation); - void fix_parent_connect(bArmature *armature, Bone *bone); - void connect_bone_chains(bArmature *armature, Bone *bone, const int max_chain_length); - - void set_pose(Object *ob_arm, - COLLADAFW::Node *root_node, - const char *parentname, - float parent_mat[4][4]); - - void set_bone_transformation_type(const COLLADAFW::Node *node, Object *ob_arm); - bool node_is_decomposed(const COLLADAFW::Node *node); -#if 0 - void set_leaf_bone_shapes(Object *ob_arm); - void set_euler_rotmode(); -#endif - - Object *get_empty_for_leaves(); - -#if 0 - Object *find_armature(COLLADAFW::Node *node); - - ArmatureJoints &get_armature_joints(Object *ob_arm); -#endif - - Object *create_armature_bones(Main *bmain, SkinInfo &skin); - void create_armature_bones(Main *bmain, std::vector<Object *> &arm_objs); - - /** TagsMap typedef for uid_tags_map. */ - typedef std::map<std::string, ExtraTags *> TagsMap; - TagsMap uid_tags_map; - - public: - ArmatureImporter(UnitConverter *conv, - MeshImporterBase *mesh, - Main *bmain, - Scene *sce, - ViewLayer *view_layer, - const ImportSettings *import_settings); - ~ArmatureImporter(); - - void add_root_joint(COLLADAFW::Node *node, Object *parent); - - // here we add bones to armatures, having armatures previously created in write_controller - void make_armatures(bContext *C, std::vector<Object *> &objects_to_scale); - - void make_shape_keys(bContext *C); - -#if 0 - // link with meshes, create vertex groups, assign weights - void link_armature(Object *ob_arm, - const COLLADAFW::UniqueId &geom_id, - const COLLADAFW::UniqueId &controller_data_id); -#endif - - bool write_skin_controller_data(const COLLADAFW::SkinControllerData *data); - - bool write_controller(const COLLADAFW::Controller *controller); - - COLLADAFW::UniqueId *get_geometry_uid(const COLLADAFW::UniqueId &controller_uid); - - Object *get_armature_for_joint(COLLADAFW::Node *node); - - void get_rna_path_for_joint(COLLADAFW::Node *node, char *joint_path, size_t count); - - // gives a world-space mat - bool get_joint_bind_mat(float m[4][4], COLLADAFW::Node *joint); - - void set_tags_map(TagsMap &tags_map); -}; - -#endif diff --git a/source/blender/collada/BCAnimationCurve.cpp b/source/blender/collada/BCAnimationCurve.cpp deleted file mode 100644 index 36800d611d2..00000000000 --- a/source/blender/collada/BCAnimationCurve.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#include "BCAnimationCurve.h" - -BCAnimationCurve::BCAnimationCurve() -{ - this->curve_key.set_object_type(BC_ANIMATION_TYPE_OBJECT); - this->fcurve = NULL; - this->curve_is_local_copy = false; -} - -BCAnimationCurve::BCAnimationCurve(const BCAnimationCurve &other) -{ - this->min = other.min; - this->max = other.max; - this->fcurve = other.fcurve; - this->curve_key = other.curve_key; - this->curve_is_local_copy = false; - this->id_ptr = other.id_ptr; - - /* The fcurve of the new instance is a copy and can be modified */ - - get_edit_fcurve(); -} - -BCAnimationCurve::BCAnimationCurve(BCCurveKey key, Object *ob, FCurve *fcu) -{ - this->min = 0; - this->max = 0; - this->curve_key = key; - this->fcurve = fcu; - this->curve_is_local_copy = false; - init_pointer_rna(ob); -} - -BCAnimationCurve::BCAnimationCurve(const BCCurveKey &key, Object *ob) -{ - this->curve_key = key; - this->fcurve = NULL; - this->curve_is_local_copy = false; - init_pointer_rna(ob); -} - -void BCAnimationCurve::init_pointer_rna(Object *ob) -{ - switch (this->curve_key.get_animation_type()) { - case BC_ANIMATION_TYPE_BONE: { - bArmature *arm = (bArmature *)ob->data; - RNA_id_pointer_create(&arm->id, &id_ptr); - } break; - case BC_ANIMATION_TYPE_OBJECT: { - RNA_id_pointer_create(&ob->id, &id_ptr); - } break; - case BC_ANIMATION_TYPE_MATERIAL: { - Material *ma = BKE_object_material_get(ob, curve_key.get_subindex() + 1); - RNA_id_pointer_create(&ma->id, &id_ptr); - } break; - case BC_ANIMATION_TYPE_CAMERA: { - Camera *camera = (Camera *)ob->data; - RNA_id_pointer_create(&camera->id, &id_ptr); - } break; - case BC_ANIMATION_TYPE_LIGHT: { - Light *lamp = (Light *)ob->data; - RNA_id_pointer_create(&lamp->id, &id_ptr); - } break; - default: - fprintf( - stderr, "BC_animation_curve_type %d not supported", this->curve_key.get_array_index()); - break; - } -} - -void BCAnimationCurve::delete_fcurve(FCurve *fcu) -{ - free_fcurve(fcu); -} - -FCurve *BCAnimationCurve::create_fcurve(int array_index, const char *rna_path) -{ - FCurve *fcu = (FCurve *)MEM_callocN(sizeof(FCurve), "FCurve"); - fcu->flag = (FCURVE_VISIBLE | FCURVE_AUTO_HANDLES | FCURVE_SELECTED); - fcu->rna_path = BLI_strdupn(rna_path, strlen(rna_path)); - fcu->array_index = array_index; - return fcu; -} - -void BCAnimationCurve::create_bezt(float frame, float output) -{ - FCurve *fcu = get_edit_fcurve(); - BezTriple bez; - memset(&bez, 0, sizeof(BezTriple)); - bez.vec[1][0] = frame; - bez.vec[1][1] = output; - bez.ipo = U.ipo_new; /* use default interpolation mode here... */ - bez.f1 = bez.f2 = bez.f3 = SELECT; - bez.h1 = bez.h2 = HD_AUTO; - insert_bezt_fcurve(fcu, &bez, INSERTKEY_NOFLAGS); - calchandles_fcurve(fcu); -} - -BCAnimationCurve::~BCAnimationCurve() -{ - if (curve_is_local_copy && fcurve) { - // fprintf(stderr, "removed fcurve %s\n", fcurve->rna_path); - delete_fcurve(fcurve); - this->fcurve = NULL; - } -} - -const bool BCAnimationCurve::is_of_animation_type(BC_animation_type type) const -{ - return curve_key.get_animation_type() == type; -} - -const std::string BCAnimationCurve::get_channel_target() const -{ - const std::string path = curve_key.get_path(); - - if (bc_startswith(path, "pose.bones")) { - return bc_string_after(path, "pose.bones"); - } - return bc_string_after(path, "."); -} - -const std::string BCAnimationCurve::get_channel_type() const -{ - const std::string channel = get_channel_target(); - return bc_string_after(channel, "."); -} - -const std::string BCAnimationCurve::get_channel_posebone() const -{ - const std::string channel = get_channel_target(); - std::string pose_bone_name = bc_string_before(channel, "."); - if (pose_bone_name == channel) { - pose_bone_name = ""; - } - else { - pose_bone_name = bc_string_after(pose_bone_name, "\"["); - pose_bone_name = bc_string_before(pose_bone_name, "]\""); - } - return pose_bone_name; -} - -const std::string BCAnimationCurve::get_animation_name(Object *ob) const -{ - std::string name; - - switch (curve_key.get_animation_type()) { - case BC_ANIMATION_TYPE_OBJECT: { - name = id_name(ob); - } break; - - case BC_ANIMATION_TYPE_BONE: { - if (fcurve == NULL || fcurve->rna_path == NULL) { - name = ""; - } - else { - const char *boneName = BLI_str_quoted_substrN(fcurve->rna_path, "pose.bones["); - name = (boneName) ? id_name(ob) + "_" + std::string(boneName) : ""; - } - } break; - - case BC_ANIMATION_TYPE_CAMERA: { - Camera *camera = (Camera *)ob->data; - name = id_name(ob) + "-" + id_name(camera) + "-camera"; - } break; - - case BC_ANIMATION_TYPE_LIGHT: { - Light *lamp = (Light *)ob->data; - name = id_name(ob) + "-" + id_name(lamp) + "-light"; - } break; - - case BC_ANIMATION_TYPE_MATERIAL: { - Material *ma = BKE_object_material_get(ob, this->curve_key.get_subindex() + 1); - name = id_name(ob) + "-" + id_name(ma) + "-material"; - } break; - - default: { - name = ""; - } - } - - return name; -} - -const int BCAnimationCurve::get_channel_index() const -{ - return curve_key.get_array_index(); -} - -const int BCAnimationCurve::get_subindex() const -{ - return curve_key.get_subindex(); -} - -const std::string BCAnimationCurve::get_rna_path() const -{ - return curve_key.get_path(); -} - -const int BCAnimationCurve::sample_count() const -{ - if (fcurve == NULL) { - return 0; - } - return fcurve->totvert; -} - -const int BCAnimationCurve::closest_index_above(const float sample_frame, const int start_at) const -{ - if (fcurve == NULL) { - return -1; - } - - const int cframe = fcurve->bezt[start_at].vec[1][0]; // inacurate! - - if (fabs(cframe - sample_frame) < 0.00001) { - return start_at; - } - return (fcurve->totvert > start_at + 1) ? start_at + 1 : start_at; -} - -const int BCAnimationCurve::closest_index_below(const float sample_frame) const -{ - if (fcurve == NULL) { - return -1; - } - - float lower_frame = sample_frame; - float upper_frame = sample_frame; - int lower_index = 0; - int upper_index = 0; - - for (int fcu_index = 0; fcu_index < fcurve->totvert; fcu_index++) { - upper_index = fcu_index; - - const int cframe = fcurve->bezt[fcu_index].vec[1][0]; // inacurate! - if (cframe <= sample_frame) { - lower_frame = cframe; - lower_index = fcu_index; - } - if (cframe >= sample_frame) { - upper_frame = cframe; - break; - } - } - - if (lower_index == upper_index) { - return lower_index; - } - - const float fraction = float(sample_frame - lower_frame) / (upper_frame - lower_frame); - return (fraction < 0.5) ? lower_index : upper_index; -} - -const int BCAnimationCurve::get_interpolation_type(float sample_frame) const -{ - const int index = closest_index_below(sample_frame); - if (index < 0) { - return BEZT_IPO_BEZ; - } - return fcurve->bezt[index].ipo; -} - -const FCurve *BCAnimationCurve::get_fcurve() const -{ - return fcurve; -} - -FCurve *BCAnimationCurve::get_edit_fcurve() -{ - if (!curve_is_local_copy) { - const int index = curve_key.get_array_index(); - const std::string &path = curve_key.get_path(); - fcurve = create_fcurve(index, path.c_str()); - - /* Caution here: - * Replacing the pointer here is OK only because the original value - * of FCurve was a const pointer into Blender territory. We do not - * touch that! We use the local copy to prepare data for export. */ - - curve_is_local_copy = true; - } - return fcurve; -} - -void BCAnimationCurve::clean_handles() -{ - if (fcurve == NULL) { - fcurve = get_edit_fcurve(); - } - - /* Keep old bezt data for copy)*/ - BezTriple *old_bezts = fcurve->bezt; - int totvert = fcurve->totvert; - fcurve->bezt = NULL; - fcurve->totvert = 0; - - for (int i = 0; i < totvert; i++) { - BezTriple *bezt = &old_bezts[i]; - float x = bezt->vec[1][0]; - float y = bezt->vec[1][1]; - insert_vert_fcurve(fcurve, x, y, (eBezTriple_KeyframeType)BEZKEYTYPE(bezt), INSERTKEY_NOFLAGS); - BezTriple *lastb = fcurve->bezt + (fcurve->totvert - 1); - lastb->f1 = lastb->f2 = lastb->f3 = 0; - } - - /* now free the memory used by the old BezTriples */ - if (old_bezts) { - MEM_freeN(old_bezts); - } -} - -const bool BCAnimationCurve::is_transform_curve() const -{ - std::string channel_type = this->get_channel_type(); - return (is_rotation_curve() || channel_type == "scale" || channel_type == "location"); -} - -const bool BCAnimationCurve::is_rotation_curve() const -{ - std::string channel_type = this->get_channel_type(); - return (channel_type == "rotation" || channel_type == "rotation_euler" || - channel_type == "rotation_quaternion"); -} - -const float BCAnimationCurve::get_value(const float frame) -{ - if (fcurve) { - return evaluate_fcurve(fcurve, frame); - } - return 0; // TODO: handle case where neither sample nor fcu exist -} - -void BCAnimationCurve::update_range(float val) -{ - if (val < min) { - min = val; - } - if (val > max) { - max = val; - } -} - -void BCAnimationCurve::init_range(float val) -{ - min = max = val; -} - -void BCAnimationCurve::adjust_range(const int frame_index) -{ - if (fcurve && fcurve->totvert > 1) { - const float eval = evaluate_fcurve(fcurve, frame_index); - - int first_frame = fcurve->bezt[0].vec[1][0]; - if (first_frame == frame_index) { - init_range(eval); - } - else { - update_range(eval); - } - } -} - -void BCAnimationCurve::add_value(const float val, const int frame_index) -{ - FCurve *fcu = get_edit_fcurve(); - fcu->auto_smoothing = U.auto_smoothing_new; - insert_vert_fcurve(fcu, frame_index, val, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NOFLAGS); - - if (fcu->totvert == 1) { - init_range(val); - } - else { - update_range(val); - } -} - -bool BCAnimationCurve::add_value_from_matrix(const BCSample &sample, const int frame_index) -{ - int array_index = curve_key.get_array_index(); - - /* transformation curves are fed directly from the transformation matrix - * to resolve parent inverse matrix issues with object hierarchies. - * Maybe this can be unified with the - */ - const std::string channel_target = get_channel_target(); - float val = 0; - /* Pick the value from the sample according to the definition of the FCurve */ - bool good = sample.get_value(channel_target, array_index, &val); - if (good) { - add_value(val, frame_index); - } - return good; -} - -bool BCAnimationCurve::add_value_from_rna(const int frame_index) -{ - PointerRNA ptr; - PropertyRNA *prop; - float value = 0.0f; - int array_index = curve_key.get_array_index(); - const std::string full_path = curve_key.get_full_path(); - - /* get property to read from, and get value as appropriate */ - bool path_resolved = RNA_path_resolve_full( - &id_ptr, full_path.c_str(), &ptr, &prop, &array_index); - if (!path_resolved && array_index == 0) { - const std::string rna_path = curve_key.get_path(); - path_resolved = RNA_path_resolve_full(&id_ptr, rna_path.c_str(), &ptr, &prop, &array_index); - } - - if (path_resolved) { - bool is_array = RNA_property_array_check(prop); - if (is_array) { - /* array */ - if ((array_index >= 0) && (array_index < RNA_property_array_length(&ptr, prop))) { - switch (RNA_property_type(prop)) { - case PROP_BOOLEAN: - value = (float)RNA_property_boolean_get_index(&ptr, prop, array_index); - break; - case PROP_INT: - value = (float)RNA_property_int_get_index(&ptr, prop, array_index); - break; - case PROP_FLOAT: - value = RNA_property_float_get_index(&ptr, prop, array_index); - break; - default: - break; - } - } - else { - fprintf(stderr, - "Out of Bounds while reading data for Curve %s\n", - curve_key.get_full_path().c_str()); - return false; - } - } - else { - /* not an array */ - switch (RNA_property_type(prop)) { - case PROP_BOOLEAN: - value = (float)RNA_property_boolean_get(&ptr, prop); - break; - case PROP_INT: - value = (float)RNA_property_int_get(&ptr, prop); - break; - case PROP_FLOAT: - value = RNA_property_float_get(&ptr, prop); - break; - case PROP_ENUM: - value = (float)RNA_property_enum_get(&ptr, prop); - break; - default: - fprintf(stderr, - "property type %d not supported for Curve %s\n", - RNA_property_type(prop), - curve_key.get_full_path().c_str()); - return false; - break; - } - } - } - else { - /* path couldn't be resolved */ - fprintf(stderr, "Path not recognized for Curve %s\n", curve_key.get_full_path().c_str()); - return false; - } - - add_value(value, frame_index); - return true; -} - -void BCAnimationCurve::get_value_map(BCValueMap &value_map) -{ - value_map.clear(); - if (fcurve == NULL) { - return; - } - - for (int i = 0; i < fcurve->totvert; i++) { - const float frame = fcurve->bezt[i].vec[1][0]; - const float val = fcurve->bezt[i].vec[1][1]; - value_map[frame] = val; - } -} - -void BCAnimationCurve::get_frames(BCFrames &frames) const -{ - frames.clear(); - if (fcurve) { - for (int i = 0; i < fcurve->totvert; i++) { - const float val = fcurve->bezt[i].vec[1][0]; - frames.push_back(val); - } - } -} - -void BCAnimationCurve::get_values(BCValues &values) const -{ - values.clear(); - if (fcurve) { - for (int i = 0; i < fcurve->totvert; i++) { - const float val = fcurve->bezt[i].vec[1][1]; - values.push_back(val); - } - } -} - -bool BCAnimationCurve::is_animated() -{ - static float MIN_DISTANCE = 0.00001; - return fabs(max - min) > MIN_DISTANCE; -} - -bool BCAnimationCurve::is_keyframe(int frame) -{ - if (this->fcurve == NULL) { - return false; - } - - for (int i = 0; i < fcurve->totvert; i++) { - const int cframe = nearbyint(fcurve->bezt[i].vec[1][0]); - if (cframe == frame) { - return true; - } - if (cframe > frame) { - break; - } - } - return false; -} - -/* Needed for adding a BCAnimationCurve into a BCAnimationCurveSet */ -inline bool operator<(const BCAnimationCurve &lhs, const BCAnimationCurve &rhs) -{ - std::string lhtgt = lhs.get_channel_target(); - std::string rhtgt = rhs.get_channel_target(); - if (lhtgt == rhtgt) { - const int lha = lhs.get_channel_index(); - const int rha = rhs.get_channel_index(); - return lha < rha; - } - else { - return lhtgt < rhtgt; - } -} - -BCCurveKey::BCCurveKey() -{ - this->key_type = BC_ANIMATION_TYPE_OBJECT; - this->rna_path = ""; - this->curve_array_index = 0; - this->curve_subindex = -1; -} - -BCCurveKey::BCCurveKey(const BC_animation_type type, - const std::string path, - const int array_index, - const int subindex) -{ - this->key_type = type; - this->rna_path = path; - this->curve_array_index = array_index; - this->curve_subindex = subindex; -} - -void BCCurveKey::operator=(const BCCurveKey &other) -{ - this->key_type = other.key_type; - this->rna_path = other.rna_path; - this->curve_array_index = other.curve_array_index; - this->curve_subindex = other.curve_subindex; -} - -const std::string BCCurveKey::get_full_path() const -{ - return this->rna_path + '[' + std::to_string(this->curve_array_index) + ']'; -} - -const std::string BCCurveKey::get_path() const -{ - return this->rna_path; -} - -const int BCCurveKey::get_array_index() const -{ - return this->curve_array_index; -} - -const int BCCurveKey::get_subindex() const -{ - return this->curve_subindex; -} - -void BCCurveKey::set_object_type(BC_animation_type object_type) -{ - this->key_type = object_type; -} - -const BC_animation_type BCCurveKey::get_animation_type() const -{ - return this->key_type; -} - -const bool BCCurveKey::operator<(const BCCurveKey &other) const -{ - /* needed for using this class as key in maps and sets */ - if (this->key_type != other.key_type) { - return this->key_type < other.key_type; - } - - if (this->curve_subindex != other.curve_subindex) { - return this->curve_subindex < other.curve_subindex; - } - - if (this->rna_path != other.rna_path) { - return this->rna_path < other.rna_path; - } - - return this->curve_array_index < other.curve_array_index; -} - -BCBezTriple::BCBezTriple(BezTriple &bezt) : bezt(bezt) -{ -} - -const float BCBezTriple::get_frame() const -{ - return bezt.vec[1][0]; -} - -const float BCBezTriple::get_time(Scene *scene) const -{ - return FRA2TIME(bezt.vec[1][0]); -} - -const float BCBezTriple::get_value() const -{ - return bezt.vec[1][1]; -} - -const float BCBezTriple::get_angle() const -{ - return RAD2DEGF(get_value()); -} - -void BCBezTriple::get_in_tangent(Scene *scene, float point[2], bool as_angle) const -{ - get_tangent(scene, point, as_angle, 0); -} - -void BCBezTriple::get_out_tangent(Scene *scene, float point[2], bool as_angle) const -{ - get_tangent(scene, point, as_angle, 2); -} - -void BCBezTriple::get_tangent(Scene *scene, float point[2], bool as_angle, int index) const -{ - point[0] = FRA2TIME(bezt.vec[index][0]); - if (bezt.ipo != BEZT_IPO_BEZ) { - /* We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain - * unused data */ - point[0] = 0; - point[1] = 0; - } - else if (as_angle) { - point[1] = RAD2DEGF(bezt.vec[index][1]); - } - else { - point[1] = bezt.vec[index][1]; - } -} diff --git a/source/blender/collada/BCAnimationCurve.h b/source/blender/collada/BCAnimationCurve.h deleted file mode 100644 index 7b523ac53ca..00000000000 --- a/source/blender/collada/BCAnimationCurve.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#ifndef __BCANIMATIONCURVE_H__ -#define __BCANIMATIONCURVE_H__ - -#include "collada_utils.h" -#include "BCSampleData.h" - -#include "MEM_guardedalloc.h" - -extern "C" { -#include "BKE_fcurve.h" -#include "BKE_armature.h" -#include "BKE_material.h" -#include "ED_anim_api.h" -#include "ED_keyframing.h" -#include "ED_keyframes_edit.h" -} - -typedef float(TangentPoint)[2]; - -typedef std::set<float> BCFrameSet; -typedef std::vector<float> BCFrames; -typedef std::vector<float> BCValues; -typedef std::vector<float> BCTimes; -typedef std::map<int, float> BCValueMap; - -typedef enum BC_animation_type { - BC_ANIMATION_TYPE_OBJECT, - BC_ANIMATION_TYPE_BONE, - BC_ANIMATION_TYPE_CAMERA, - BC_ANIMATION_TYPE_MATERIAL, - BC_ANIMATION_TYPE_LIGHT, -} BC_animation_type; - -class BCCurveKey { - private: - BC_animation_type key_type; - std::string rna_path; - int curve_array_index; - int curve_subindex; /* only needed for materials */ - - public: - BCCurveKey(); - BCCurveKey(const BC_animation_type type, - const std::string path, - const int array_index, - const int subindex = -1); - void operator=(const BCCurveKey &other); - const std::string get_full_path() const; - const std::string get_path() const; - const int get_array_index() const; - const int get_subindex() const; - void set_object_type(BC_animation_type object_type); - const BC_animation_type get_animation_type() const; - const bool operator<(const BCCurveKey &other) const; -}; - -class BCBezTriple { - public: - BezTriple &bezt; - - BCBezTriple(BezTriple &bezt); - const float get_frame() const; - const float get_time(Scene *scene) const; - const float get_value() const; - const float get_angle() const; - void get_in_tangent(Scene *scene, float point[2], bool as_angle) const; - void get_out_tangent(Scene *scene, float point[2], bool as_angle) const; - void get_tangent(Scene *scene, float point[2], bool as_angle, int index) const; -}; - -class BCAnimationCurve { - private: - BCCurveKey curve_key; - float min = 0; - float max = 0; - - bool curve_is_local_copy = false; - FCurve *fcurve; - PointerRNA id_ptr; - void init_pointer_rna(Object *ob); - void delete_fcurve(FCurve *fcu); - FCurve *create_fcurve(int array_index, const char *rna_path); - void create_bezt(float frame, float output); - void update_range(float val); - void init_range(float val); - - public: - BCAnimationCurve(); - BCAnimationCurve(const BCAnimationCurve &other); - BCAnimationCurve(const BCCurveKey &key, Object *ob); - BCAnimationCurve(BCCurveKey key, Object *ob, FCurve *fcu); - ~BCAnimationCurve(); - - const bool is_of_animation_type(BC_animation_type type) const; - const int get_interpolation_type(float sample_frame) const; - bool is_animated(); - const bool is_transform_curve() const; - const bool is_rotation_curve() const; - bool is_keyframe(int frame); - void adjust_range(int frame); - - const std::string get_animation_name(Object *ob) const; /* xxx: this is collada specific */ - const std::string get_channel_target() const; - const std::string get_channel_type() const; - const std::string get_channel_posebone() const; // returns "" if channel is not a bone channel - - const int get_channel_index() const; - const int get_subindex() const; - const std::string get_rna_path() const; - const FCurve *get_fcurve() const; - const int sample_count() const; - - const float get_value(const float frame); - void get_values(BCValues &values) const; - void get_value_map(BCValueMap &value_map); - - void get_frames(BCFrames &frames) const; - - /* Curve edit functions create a copy of the underlaying FCurve */ - FCurve *get_edit_fcurve(); - bool add_value_from_rna(const int frame); - bool add_value_from_matrix(const BCSample &sample, const int frame); - void add_value(const float val, const int frame); - void clean_handles(); - - /* experimental stuff */ - const int closest_index_above(const float sample_frame, const int start_at) const; - const int closest_index_below(const float sample_frame) const; -}; - -typedef std::map<BCCurveKey, BCAnimationCurve *> BCAnimationCurveMap; - -#endif /* __BCANIMATIONCURVE_H__ */ diff --git a/source/blender/collada/BCAnimationSampler.cpp b/source/blender/collada/BCAnimationSampler.cpp deleted file mode 100644 index e6996e95a5b..00000000000 --- a/source/blender/collada/BCAnimationSampler.cpp +++ /dev/null @@ -1,662 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#include <vector> -#include <map> -#include <algorithm> // std::find - -#include "ExportSettings.h" -#include "BCAnimationCurve.h" -#include "BCAnimationSampler.h" -#include "collada_utils.h" -#include "BCMath.h" - -extern "C" { -#include "BKE_action.h" -#include "BKE_constraint.h" -#include "BKE_key.h" -#include "BKE_main.h" -#include "BKE_lib_id.h" -#include "BKE_material.h" -#include "BLI_listbase.h" -#include "DNA_anim_types.h" -#include "DNA_scene_types.h" -#include "DNA_key_types.h" -#include "DNA_constraint_types.h" -#include "ED_object.h" -} - -static std::string EMPTY_STRING; -static BCAnimationCurveMap BCEmptyAnimationCurves; - -BCAnimationSampler::BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &object_set) - : export_settings(export_settings) -{ - BCObjectSet::iterator it; - for (it = object_set.begin(); it != object_set.end(); ++it) { - Object *ob = *it; - add_object(ob); - } -} - -BCAnimationSampler::~BCAnimationSampler() -{ - BCAnimationObjectMap::iterator it; - for (it = objects.begin(); it != objects.end(); ++it) { - BCAnimation *animation = it->second; - delete animation; - } -} - -void BCAnimationSampler::add_object(Object *ob) -{ - BlenderContext blender_context = export_settings.get_blender_context(); - BCAnimation *animation = new BCAnimation(blender_context.get_context(), ob); - objects[ob] = animation; - - initialize_keyframes(animation->frame_set, ob); - initialize_curves(animation->curve_map, ob); -} - -BCAnimationCurveMap *BCAnimationSampler::get_curves(Object *ob) -{ - BCAnimation &animation = *objects[ob]; - if (animation.curve_map.size() == 0) { - initialize_curves(animation.curve_map, ob); - } - return &animation.curve_map; -} - -static void get_sample_frames(BCFrameSet &sample_frames, - int sampling_rate, - bool keyframe_at_end, - Scene *scene) -{ - sample_frames.clear(); - - if (sampling_rate < 1) { - return; // no sample frames in this case - } - - float sfra = scene->r.sfra; - float efra = scene->r.efra; - - int frame_index; - for (frame_index = nearbyint(sfra); frame_index < efra; frame_index += sampling_rate) { - sample_frames.insert(frame_index); - } - - if (frame_index >= efra && keyframe_at_end) { - sample_frames.insert(efra); - } -} - -static bool is_object_keyframe(Object *ob, int frame_index) -{ - return false; -} - -static void add_keyframes_from(bAction *action, BCFrameSet &frameset) -{ - if (action) { - FCurve *fcu = NULL; - for (fcu = (FCurve *)action->curves.first; fcu; fcu = fcu->next) { - BezTriple *bezt = fcu->bezt; - for (int i = 0; i < fcu->totvert; bezt++, i++) { - int frame_index = nearbyint(bezt->vec[1][0]); - frameset.insert(frame_index); - } - } - } -} - -void BCAnimationSampler::check_property_is_animated( - BCAnimation &animation, float *ref, float *val, std::string data_path, int length) -{ - for (int array_index = 0; array_index < length; array_index++) { - if (!bc_in_range(ref[length], val[length], 0.00001)) { - BCCurveKey key(BC_ANIMATION_TYPE_OBJECT, data_path, array_index); - BCAnimationCurveMap::iterator it = animation.curve_map.find(key); - if (it == animation.curve_map.end()) { - animation.curve_map[key] = new BCAnimationCurve(key, animation.get_reference()); - } - } - } -} - -void BCAnimationSampler::update_animation_curves(BCAnimation &animation, - BCSample &sample, - Object *ob, - int frame) -{ - BCAnimationCurveMap::iterator it; - for (it = animation.curve_map.begin(); it != animation.curve_map.end(); ++it) { - BCAnimationCurve *curve = it->second; - if (curve->is_transform_curve()) { - curve->add_value_from_matrix(sample, frame); - } - else { - curve->add_value_from_rna(frame); - } - } -} - -BCSample &BCAnimationSampler::sample_object(Object *ob, int frame_index, bool for_opensim) -{ - BCSample &ob_sample = sample_data.add(ob, frame_index); - // if (export_settings.get_apply_global_orientation()) { - // const BCMatrix &global_transform = export_settings.get_global_transform(); - // ob_sample.get_matrix(global_transform); - //} - - if (ob->type == OB_ARMATURE) { - bPoseChannel *pchan; - for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) { - Bone *bone = pchan->bone; - Matrix bmat; - if (bc_bone_matrix_local_get(ob, bone, bmat, for_opensim)) { - - ob_sample.add_bone_matrix(bone, bmat); - } - } - } - return ob_sample; -} - -void BCAnimationSampler::sample_scene(BCExportSettings &export_settings, bool keyframe_at_end) -{ - BlenderContext blender_context = export_settings.get_blender_context(); - int sampling_rate = export_settings.get_sampling_rate(); - bool for_opensim = export_settings.get_open_sim(); - bool keep_keyframes = export_settings.get_keep_keyframes(); - BC_export_animation_type export_animation_type = export_settings.get_export_animation_type(); - - Scene *scene = blender_context.get_scene(); - BCFrameSet scene_sample_frames; - get_sample_frames(scene_sample_frames, sampling_rate, keyframe_at_end, scene); - BCFrameSet::iterator it; - - int startframe = scene->r.sfra; - int endframe = scene->r.efra; - - for (int frame_index = startframe; frame_index <= endframe; frame_index++) { - /* Loop over all frames and decide for each frame if sampling is necessary */ - bool is_scene_sample_frame = false; - bool needs_update = true; - if (scene_sample_frames.find(frame_index) != scene_sample_frames.end()) { - bc_update_scene(blender_context, frame_index); - needs_update = false; - is_scene_sample_frame = true; - } - - bool needs_sampling = is_scene_sample_frame || keep_keyframes || - export_animation_type == BC_ANIMATION_EXPORT_KEYS; - if (!needs_sampling) { - continue; - } - - BCAnimationObjectMap::iterator obit; - for (obit = objects.begin(); obit != objects.end(); ++obit) { - Object *ob = obit->first; - BCAnimation *animation = obit->second; - BCFrameSet &object_keyframes = animation->frame_set; - if (is_scene_sample_frame || object_keyframes.find(frame_index) != object_keyframes.end()) { - - if (needs_update) { - bc_update_scene(blender_context, frame_index); - needs_update = false; - } - - BCSample &sample = sample_object(ob, frame_index, for_opensim); - update_animation_curves(*animation, sample, ob, frame_index); - } - } - } -} - -bool BCAnimationSampler::is_animated_by_constraint(Object *ob, - ListBase *conlist, - std::set<Object *> &animated_objects) -{ - bConstraint *con; - for (con = (bConstraint *)conlist->first; con; con = con->next) { - ListBase targets = {NULL, NULL}; - - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - - if (!bc_validateConstraints(con)) { - continue; - } - - if (cti && cti->get_constraint_targets) { - bConstraintTarget *ct; - Object *obtar; - cti->get_constraint_targets(con, &targets); - for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { - obtar = ct->tar; - if (obtar) { - if (animated_objects.find(obtar) != animated_objects.end()) { - return true; - } - } - } - } - } - return false; -} - -void BCAnimationSampler::find_depending_animated(std::set<Object *> &animated_objects, - std::set<Object *> &candidates) -{ - bool found_more; - do { - found_more = false; - std::set<Object *>::iterator it; - for (it = candidates.begin(); it != candidates.end(); ++it) { - Object *cob = *it; - ListBase *conlist = get_active_constraints(cob); - if (is_animated_by_constraint(cob, conlist, animated_objects)) { - animated_objects.insert(cob); - candidates.erase(cob); - found_more = true; - break; - } - } - } while (found_more && candidates.size() > 0); -} - -void BCAnimationSampler::get_animated_from_export_set(std::set<Object *> &animated_objects, - LinkNode &export_set) -{ - /* Check if this object is animated. That is: Check if it has its own action, or: - * - * - Check if it has constraints to other objects. - * - at least one of the other objects is animated as well. - */ - - animated_objects.clear(); - std::set<Object *> static_objects; - std::set<Object *> candidates; - - LinkNode *node; - for (node = &export_set; node; node = node->next) { - Object *cob = (Object *)node->link; - if (bc_has_animations(cob)) { - animated_objects.insert(cob); - } - else { - ListBase conlist = cob->constraints; - if (conlist.first) { - candidates.insert(cob); - } - } - } - find_depending_animated(animated_objects, candidates); -} - -void BCAnimationSampler::get_object_frames(BCFrames &frames, Object *ob) -{ - sample_data.get_frames(ob, frames); -} - -void BCAnimationSampler::get_bone_frames(BCFrames &frames, Object *ob, Bone *bone) -{ - sample_data.get_frames(ob, bone, frames); -} - -bool BCAnimationSampler::get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone) -{ - sample_data.get_matrices(ob, bone, samples); - return bc_is_animated(samples); -} - -bool BCAnimationSampler::get_object_samples(BCMatrixSampleMap &samples, Object *ob) -{ - sample_data.get_matrices(ob, samples); - return bc_is_animated(samples); -} - -#if 0 -/** - * Add sampled values to #FCurve - * If no #FCurve exists, create a temporary #FCurve; - * \note The temporary #FCurve will later be removed when the - * #BCAnimationSampler is removed (by its destructor). - * - * \param curve: The curve to which the data is added. - * \param matrices: The set of matrix values from where the data is taken. - * \param animation_type: - * - #BC_ANIMATION_EXPORT_SAMPLES: Use all matrix data. - * - #BC_ANIMATION_EXPORT_KEYS: Only take data from matrices for keyframes. - */ -void BCAnimationSampler::add_value_set(BCAnimationCurve &curve, - BCFrameSampleMap &samples, - BC_export_animation_type animation_type) -{ - int array_index = curve.get_array_index(); - const BC_animation_transform_type tm_type = curve.get_transform_type(); - - BCFrameSampleMap::iterator it; - for (it = samples.begin(); it != samples.end(); ++it) { - const int frame_index = nearbyint(it->first); - if (animation_type == BC_ANIMATION_EXPORT_SAMPLES || curve.is_keyframe(frame_index)) { - - const BCSample *sample = it->second; - float val = 0; - - int subindex = curve.get_subindex(); - bool good; - if (subindex == -1) { - good = sample->get_value(tm_type, array_index, &val); - } - else { - good = sample->get_value(tm_type, array_index, &val, subindex); - } - - if (good) { - curve.add_value(val, frame_index); - } - } - } - curve.remove_unused_keyframes(); - curve.calchandles(); -} -#endif - -void BCAnimationSampler::generate_transform(Object *ob, - const BCCurveKey &key, - BCAnimationCurveMap &curves) -{ - BCAnimationCurveMap::const_iterator it = curves.find(key); - if (it == curves.end()) { - curves[key] = new BCAnimationCurve(key, ob); - } -} - -void BCAnimationSampler::generate_transforms(Object *ob, - const std::string prep, - const BC_animation_type type, - BCAnimationCurveMap &curves) -{ - generate_transform(ob, BCCurveKey(type, prep + "location", 0), curves); - generate_transform(ob, BCCurveKey(type, prep + "location", 1), curves); - generate_transform(ob, BCCurveKey(type, prep + "location", 2), curves); - generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 0), curves); - generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 1), curves); - generate_transform(ob, BCCurveKey(type, prep + "rotation_euler", 2), curves); - generate_transform(ob, BCCurveKey(type, prep + "scale", 0), curves); - generate_transform(ob, BCCurveKey(type, prep + "scale", 1), curves); - generate_transform(ob, BCCurveKey(type, prep + "scale", 2), curves); -} - -void BCAnimationSampler::generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves) -{ - std::string prep = "pose.bones[\"" + std::string(bone->name) + "\"]."; - generate_transforms(ob, prep, BC_ANIMATION_TYPE_BONE, curves); - - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - generate_transforms(ob, child, curves); - } -} - -/** - * Collect all keyframes from all animation curves related to the object. - * The bc_get... functions check for NULL and correct object type. - * The #add_keyframes_from() function checks for NULL. - */ -void BCAnimationSampler::initialize_keyframes(BCFrameSet &frameset, Object *ob) -{ - frameset.clear(); - add_keyframes_from(bc_getSceneObjectAction(ob), frameset); - add_keyframes_from(bc_getSceneCameraAction(ob), frameset); - add_keyframes_from(bc_getSceneLightAction(ob), frameset); - - for (int a = 0; a < ob->totcol; a++) { - Material *ma = BKE_object_material_get(ob, a + 1); - add_keyframes_from(bc_getSceneMaterialAction(ma), frameset); - } -} - -void BCAnimationSampler::initialize_curves(BCAnimationCurveMap &curves, Object *ob) -{ - BC_animation_type object_type = BC_ANIMATION_TYPE_OBJECT; - - bAction *action = bc_getSceneObjectAction(ob); - if (action) { - FCurve *fcu = (FCurve *)action->curves.first; - - for (; fcu; fcu = fcu->next) { - object_type = BC_ANIMATION_TYPE_OBJECT; - if (ob->type == OB_ARMATURE) { - char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - if (boneName) { - object_type = BC_ANIMATION_TYPE_BONE; - } - } - - /* Adding action curves on object */ - BCCurveKey key(object_type, fcu->rna_path, fcu->array_index); - curves[key] = new BCAnimationCurve(key, ob, fcu); - } - } - - /* Add missing curves */ - object_type = BC_ANIMATION_TYPE_OBJECT; - generate_transforms(ob, EMPTY_STRING, object_type, curves); - if (ob->type == OB_ARMATURE) { - bArmature *arm = (bArmature *)ob->data; - for (Bone *root_bone = (Bone *)arm->bonebase.first; root_bone; root_bone = root_bone->next) { - generate_transforms(ob, root_bone, curves); - } - } - - /* Add curves on Object->data actions */ - action = NULL; - if (ob->type == OB_CAMERA) { - action = bc_getSceneCameraAction(ob); - object_type = BC_ANIMATION_TYPE_CAMERA; - } - else if (ob->type == OB_LAMP) { - action = bc_getSceneLightAction(ob); - object_type = BC_ANIMATION_TYPE_LIGHT; - } - - if (action) { - /* Add light action or Camera action */ - FCurve *fcu = (FCurve *)action->curves.first; - for (; fcu; fcu = fcu->next) { - BCCurveKey key(object_type, fcu->rna_path, fcu->array_index); - curves[key] = new BCAnimationCurve(key, ob, fcu); - } - } - - /* Add curves on Object->material actions*/ - object_type = BC_ANIMATION_TYPE_MATERIAL; - for (int a = 0; a < ob->totcol; a++) { - /* Export Material parameter animations. */ - Material *ma = BKE_object_material_get(ob, a + 1); - if (ma) { - action = bc_getSceneMaterialAction(ma); - if (action) { - /* isMatAnim = true; */ - FCurve *fcu = (FCurve *)action->curves.first; - for (; fcu; fcu = fcu->next) { - BCCurveKey key(object_type, fcu->rna_path, fcu->array_index, a); - curves[key] = new BCAnimationCurve(key, ob, fcu); - } - } - } - } -} - -/* ==================================================================== */ - -BCSample &BCSampleFrame::add(Object *ob) -{ - BCSample *sample = new BCSample(ob); - sampleMap[ob] = sample; - return *sample; -} - -/* Get the matrix for the given key, returns Unity when the key does not exist */ -const BCSample *BCSampleFrame::get_sample(Object *ob) const -{ - BCSampleMap::const_iterator it = sampleMap.find(ob); - if (it == sampleMap.end()) { - return NULL; - } - return it->second; -} - -const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob) const -{ - BCSampleMap::const_iterator it = sampleMap.find(ob); - if (it == sampleMap.end()) { - return NULL; - } - BCSample *sample = it->second; - return &sample->get_matrix(); -} - -/* Get the matrix for the given Bone, returns Unity when the Objewct is not sampled */ -const BCMatrix *BCSampleFrame::get_sample_matrix(Object *ob, Bone *bone) const -{ - BCSampleMap::const_iterator it = sampleMap.find(ob); - if (it == sampleMap.end()) { - return NULL; - } - - BCSample *sample = it->second; - const BCMatrix *bc_bone = sample->get_matrix(bone); - return bc_bone; -} - -/* Check if the key is in this BCSampleFrame */ -const bool BCSampleFrame::has_sample_for(Object *ob) const -{ - return sampleMap.find(ob) != sampleMap.end(); -} - -/* Check if the Bone is in this BCSampleFrame */ -const bool BCSampleFrame::has_sample_for(Object *ob, Bone *bone) const -{ - const BCMatrix *bc_bone = get_sample_matrix(ob, bone); - return (bc_bone); -} - -/* ==================================================================== */ - -BCSample &BCSampleFrameContainer::add(Object *ob, int frame_index) -{ - BCSampleFrame &frame = sample_frames[frame_index]; - return frame.add(ob); -} - -/* ====================================================== */ -/* Below are the getters which we need to export the data */ -/* ====================================================== */ - -/* Return either the BCSampleFrame or NULL if frame does not exist*/ -BCSampleFrame *BCSampleFrameContainer::get_frame(int frame_index) -{ - BCSampleFrameMap::iterator it = sample_frames.find(frame_index); - BCSampleFrame *frame = (it == sample_frames.end()) ? NULL : &it->second; - return frame; -} - -/* Return a list of all frames that need to be sampled */ -const int BCSampleFrameContainer::get_frames(std::vector<int> &frames) const -{ - frames.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - frames.push_back(it->first); - } - return frames.size(); -} - -const int BCSampleFrameContainer::get_frames(Object *ob, BCFrames &frames) const -{ - frames.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - const BCSampleFrame &frame = it->second; - if (frame.has_sample_for(ob)) { - frames.push_back(it->first); - } - } - return frames.size(); -} - -const int BCSampleFrameContainer::get_frames(Object *ob, Bone *bone, BCFrames &frames) const -{ - frames.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - const BCSampleFrame &frame = it->second; - if (frame.has_sample_for(ob, bone)) { - frames.push_back(it->first); - } - } - return frames.size(); -} - -const int BCSampleFrameContainer::get_samples(Object *ob, BCFrameSampleMap &samples) const -{ - samples.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - const BCSampleFrame &frame = it->second; - const BCSample *sample = frame.get_sample(ob); - if (sample) { - samples[it->first] = sample; - } - } - return samples.size(); -} - -const int BCSampleFrameContainer::get_matrices(Object *ob, BCMatrixSampleMap &samples) const -{ - samples.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - const BCSampleFrame &frame = it->second; - const BCMatrix *matrix = frame.get_sample_matrix(ob); - if (matrix) { - samples[it->first] = matrix; - } - } - return samples.size(); -} - -const int BCSampleFrameContainer::get_matrices(Object *ob, - Bone *bone, - BCMatrixSampleMap &samples) const -{ - samples.clear(); // safety; - BCSampleFrameMap::const_iterator it; - for (it = sample_frames.begin(); it != sample_frames.end(); ++it) { - const BCSampleFrame &frame = it->second; - const BCMatrix *sample = frame.get_sample_matrix(ob, bone); - if (sample) { - samples[it->first] = sample; - } - } - return samples.size(); -} diff --git a/source/blender/collada/BCAnimationSampler.h b/source/blender/collada/BCAnimationSampler.h deleted file mode 100644 index 96138d0cbca..00000000000 --- a/source/blender/collada/BCAnimationSampler.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __BCANIMATIONSAMPLER_H__ -#define __BCANIMATIONSAMPLER_H__ - -#include "BCAnimationCurve.h" -#include "BCSampleData.h" -#include "collada_utils.h" - -extern "C" { -#include "BKE_action.h" -#include "BKE_lib_id.h" -#include "BLI_math_rotation.h" -#include "DNA_action_types.h" -} - -/* Collection of animation curves */ -class BCAnimation { - private: - Object *reference = NULL; - bContext *mContext; - - public: - BCFrameSet frame_set; - BCAnimationCurveMap curve_map; - - BCAnimation(bContext *C, Object *ob) : mContext(C) - { - Main *bmain = CTX_data_main(mContext); - reference = BKE_object_copy(bmain, ob); - } - - ~BCAnimation() - { - BCAnimationCurveMap::iterator it; - for (it = curve_map.begin(); it != curve_map.end(); ++it) { - delete it->second; - } - - if (reference && reference->id.us == 0) { - Main *bmain = CTX_data_main(mContext); - BKE_id_delete(bmain, &reference->id); - } - curve_map.clear(); - } - - Object *get_reference() - { - return reference; - } -}; - -typedef std::map<Object *, BCAnimation *> BCAnimationObjectMap; - -class BCSampleFrame { - - /* Each frame on the timeline that needs to be sampled will have - * one BCSampleFrame where we collect sample information about all objects - * that need to be sampled for that frame. */ - - private: - BCSampleMap sampleMap; - - public: - ~BCSampleFrame() - { - BCSampleMap::iterator it; - for (it = sampleMap.begin(); it != sampleMap.end(); ++it) { - BCSample *sample = it->second; - delete sample; - } - sampleMap.clear(); - } - - BCSample &add(Object *ob); - - /* Following methods return NULL if object is not in the sampleMap*/ - const BCSample *get_sample(Object *ob) const; - const BCMatrix *get_sample_matrix(Object *ob) const; - const BCMatrix *get_sample_matrix(Object *ob, Bone *bone) const; - - const bool has_sample_for(Object *ob) const; - const bool has_sample_for(Object *ob, Bone *bone) const; -}; - -typedef std::map<int, BCSampleFrame> BCSampleFrameMap; - -class BCSampleFrameContainer { - - /* - * The BCSampleFrameContainer stores a map of BCSampleFrame objects - * with the timeline frame as key. - * - * Some details on the purpose: - * An Animation is made of multiple FCurves where each FCurve can - * have multiple keyframes. When we want to export the animation we - * also can decide whether we want to export the keyframes or a set - * of sample frames at equidistant locations (sample period). - * In any case we must resample first need to resample it fully - * to resolve things like: - * - * - animations by constraints - * - animations by drivers - * - * For this purpose we need to step through the entire animation and - * then sample each frame that contains at least one keyFrame or - * sampleFrame. Then for each frame we have to store the transform - * information for all exported objects in a BCSampleframe - * - * The entire set of BCSampleframes is finally collected into - * a BCSampleframneContainer - */ - - private: - BCSampleFrameMap sample_frames; - - public: - ~BCSampleFrameContainer() - { - } - - BCSample &add(Object *ob, int frame_index); - BCSampleFrame *get_frame(int frame_index); // returns NULL if frame does not exist - - const int get_frames(std::vector<int> &frames) const; - const int get_frames(Object *ob, BCFrames &frames) const; - const int get_frames(Object *ob, Bone *bone, BCFrames &frames) const; - - const int get_samples(Object *ob, BCFrameSampleMap &samples) const; - const int get_matrices(Object *ob, BCMatrixSampleMap &matrices) const; - const int get_matrices(Object *ob, Bone *bone, BCMatrixSampleMap &bones) const; -}; - -class BCAnimationSampler { - private: - BCExportSettings &export_settings; - BCSampleFrameContainer sample_data; - BCAnimationObjectMap objects; - - void generate_transform(Object *ob, const BCCurveKey &key, BCAnimationCurveMap &curves); - void generate_transforms(Object *ob, - const std::string prep, - const BC_animation_type type, - BCAnimationCurveMap &curves); - void generate_transforms(Object *ob, Bone *bone, BCAnimationCurveMap &curves); - - void initialize_curves(BCAnimationCurveMap &curves, Object *ob); - void initialize_keyframes(BCFrameSet &frameset, Object *ob); - BCSample &sample_object(Object *ob, int frame_index, bool for_opensim); - void update_animation_curves(BCAnimation &animation, - BCSample &sample, - Object *ob, - int frame_index); - void check_property_is_animated( - BCAnimation &animation, float *ref, float *val, std::string data_path, int length); - - public: - BCAnimationSampler(BCExportSettings &export_settings, BCObjectSet &animated_subset); - ~BCAnimationSampler(); - - void add_object(Object *ob); - - void sample_scene(BCExportSettings &export_settings, bool keyframe_at_end); - - BCAnimationCurveMap *get_curves(Object *ob); - void get_object_frames(BCFrames &frames, Object *ob); - bool get_object_samples(BCMatrixSampleMap &samples, Object *ob); - void get_bone_frames(BCFrames &frames, Object *ob, Bone *bone); - bool get_bone_samples(BCMatrixSampleMap &samples, Object *ob, Bone *bone); - - static void get_animated_from_export_set(std::set<Object *> &animated_objects, - LinkNode &export_set); - static void find_depending_animated(std::set<Object *> &animated_objects, - std::set<Object *> &candidates); - static bool is_animated_by_constraint(Object *ob, - ListBase *conlist, - std::set<Object *> &animated_objects); -}; - -#endif /* __BCANIMATIONSAMPLER_H__ */ diff --git a/source/blender/collada/BCMath.cpp b/source/blender/collada/BCMath.cpp deleted file mode 100644 index ec9977c1469..00000000000 --- a/source/blender/collada/BCMath.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#include "BCMath.h" -#include "BlenderContext.h" - -void BCQuat::rotate_to(Matrix &mat_to) -{ - Quat qd; - Matrix matd; - Matrix mati; - Matrix mat_from; - - quat_to_mat4(mat_from, q); - - /* Calculate the difference matrix matd between mat_from and mat_to */ - invert_m4_m4(mati, mat_from); - mul_m4_m4m4(matd, mati, mat_to); - - mat4_to_quat(qd, matd); - - mul_qt_qtqt(q, qd, q); /* rotate to the final rotation to mat_to */ -} - -BCMatrix::BCMatrix(const BCMatrix &mat) -{ - set_transform(mat.matrix); -} - -BCMatrix::BCMatrix(Matrix &mat) -{ - set_transform(mat); -} - -BCMatrix::BCMatrix(Object *ob) -{ - set_transform(ob); -} - -BCMatrix::BCMatrix() -{ - unit(); -} - -BCMatrix::BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis) -{ - float mrot[3][3]; - float mat[4][4]; - mat3_from_axis_conversion( - BC_DEFAULT_FORWARD, BC_DEFAULT_UP, global_forward_axis, global_up_axis, mrot); - - transpose_m3(mrot); // TODO: Verify that mat3_from_axis_conversion() returns a transposed matrix - copy_m4_m3(mat, mrot); - set_transform(mat); -} - -void BCMatrix::add_transform(const Matrix &mat, bool inverse) -{ - add_transform(this->matrix, mat, this->matrix, inverse); -} - -void BCMatrix::add_transform(const BCMatrix &mat, bool inverse) -{ - add_transform(this->matrix, mat.matrix, this->matrix, inverse); -} - -void BCMatrix::apply_transform(const BCMatrix &mat, bool inverse) -{ - apply_transform(this->matrix, mat.matrix, this->matrix, inverse); -} - -void BCMatrix::add_transform(Matrix &to, const Matrix &transform, const Matrix &from, bool inverse) -{ - if (inverse) { - Matrix globinv; - invert_m4_m4(globinv, transform); - add_transform(to, globinv, from, /*inverse=*/false); - } - else { - mul_m4_m4m4(to, transform, from); - } -} - -void BCMatrix::apply_transform(Matrix &to, - const Matrix &transform, - const Matrix &from, - bool inverse) -{ - Matrix globinv; - invert_m4_m4(globinv, transform); - if (inverse) { - add_transform(to, globinv, from, /*inverse=*/false); - } - else { - mul_m4_m4m4(to, transform, from); - mul_m4_m4m4(to, to, globinv); - } -} - -void BCMatrix::add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from) -{ - Matrix workmat; - invert_m4_m4(workmat, transform); - mul_m4_m4m4(to, workmat, from); -} - -void BCMatrix::set_transform(Object *ob) -{ - Matrix lmat; - - BKE_object_matrix_local_get(ob, lmat); - copy_m4_m4(matrix, lmat); - - mat4_decompose(this->loc, this->q, this->size, lmat); - quat_to_compatible_eul(this->rot, ob->rot, this->q); -} - -void BCMatrix::set_transform(Matrix &mat) -{ - copy_m4_m4(matrix, mat); - mat4_decompose(this->loc, this->q, this->size, mat); - quat_to_eul(this->rot, this->q); -} - -void BCMatrix::copy(Matrix &out, Matrix &in) -{ - /* destination comes first: */ - memcpy(out, in, sizeof(Matrix)); -} - -void BCMatrix::transpose(Matrix &mat) -{ - transpose_m4(mat); -} - -void BCMatrix::sanitize(Matrix &mat, int precision) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - double val = (double)mat[i][j]; - val = double_round(val, precision); - mat[i][j] = (float)val; - } - } -} - -void BCMatrix::sanitize(DMatrix &mat, int precision) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - mat[i][j] = double_round(mat[i][j], precision); - } - } -} - -void BCMatrix::unit() -{ - unit_m4(this->matrix); - mat4_decompose(this->loc, this->q, this->size, this->matrix); - quat_to_eul(this->rot, this->q); -} - -/* We need double here because the OpenCollada API needs it. - * precision = -1 indicates to not limit the precision. */ -void BCMatrix::get_matrix(DMatrix &mat, const bool transposed, const int precision) const -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - float val = (transposed) ? matrix[j][i] : matrix[i][j]; - if (precision >= 0) { - val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision); - } - mat[i][j] = val; - } - } -} - -void BCMatrix::get_matrix(Matrix &mat, - const bool transposed, - const int precision, - const bool inverted) const -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - float val = (transposed) ? matrix[j][i] : matrix[i][j]; - if (precision >= 0) { - val = floor((val * pow(10, precision) + 0.5)) / pow(10, precision); - } - mat[i][j] = val; - } - } - - if (inverted) { - invert_m4(mat); - } -} - -const bool BCMatrix::in_range(const BCMatrix &other, float distance) const -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - if (fabs(other.matrix[i][j] - matrix[i][j]) > distance) { - return false; - } - } - } - return true; -} - -float (&BCMatrix::location() const)[3] -{ - return loc; -} - -float (&BCMatrix::rotation() const)[3] -{ - return rot; -} - -float (&BCMatrix::scale() const)[3] -{ - return size; -} - -float (&BCMatrix::quat() const)[4] -{ - return q; -} diff --git a/source/blender/collada/BCMath.h b/source/blender/collada/BCMath.h deleted file mode 100644 index 9ecea85b08c..00000000000 --- a/source/blender/collada/BCMath.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __BCMATH_H__ -#define __BCMATH_H__ - -#include "BlenderTypes.h" - -extern "C" { -#include "BKE_object.h" -#include "BLI_math.h" -} - -class BCQuat { - private: - mutable Quat q; - - public: - BCQuat(const BCQuat &other) - { - copy_v4_v4(q, other.q); - } - - BCQuat(Quat &other) - { - copy_v4_v4(q, other); - } - - BCQuat() - { - unit_qt(q); - } - - Quat &quat() - { - return q; - } - - void rotate_to(Matrix &mat_to); -}; - -class BCMatrix { - - private: - mutable float matrix[4][4]; - mutable float size[3]; - mutable float rot[3]; - mutable float loc[3]; - mutable float q[4]; - - void unit(); - void copy(Matrix &r, Matrix &a); - - public: - float (&location() const)[3]; - float (&rotation() const)[3]; - float (&scale() const)[3]; - float (&quat() const)[4]; - - BCMatrix(BC_global_forward_axis global_forward_axis, BC_global_up_axis global_up_axis); - BCMatrix(const BCMatrix &mat); - BCMatrix(Matrix &mat); - BCMatrix(Object *ob); - BCMatrix(); - - void get_matrix(DMatrix &matrix, const bool transposed = false, const int precision = -1) const; - void get_matrix(Matrix &matrix, - const bool transposed = false, - const int precision = -1, - const bool inverted = false) const; - void set_transform(Object *ob); - void set_transform(Matrix &mat); - void add_transform(Matrix &to, - const Matrix &transform, - const Matrix &from, - const bool inverted = false); - void apply_transform(Matrix &to, - const Matrix &transform, - const Matrix &from, - const bool inverted = false); - void add_inverted_transform(Matrix &to, const Matrix &transform, const Matrix &from); - void add_transform(const Matrix &matrix, const bool inverted = false); - void add_transform(const BCMatrix &matrix, const bool inverted = false); - void apply_transform(const BCMatrix &matrix, const bool inverted = false); - - const bool in_range(const BCMatrix &other, float distance) const; - - static void sanitize(Matrix &matrix, int precision); - static void sanitize(DMatrix &matrix, int precision); - static void transpose(Matrix &matrix); -}; - -#endif /* __BCMATH_H__ */ diff --git a/source/blender/collada/BCSampleData.cpp b/source/blender/collada/BCSampleData.cpp deleted file mode 100644 index 7e23a2de00f..00000000000 --- a/source/blender/collada/BCSampleData.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#include "BCSampleData.h" -#include "collada_utils.h" - -BCSample::~BCSample() -{ - BCBoneMatrixMap::iterator it; - for (it = bonemats.begin(); it != bonemats.end(); ++it) { - delete it->second; - } -} - -void BCSample::add_bone_matrix(Bone *bone, Matrix &mat) -{ - BCMatrix *matrix; - BCBoneMatrixMap::const_iterator it = bonemats.find(bone); - if (it != bonemats.end()) { - throw std::invalid_argument("bone " + std::string(bone->name) + " already defined before"); - } - matrix = new BCMatrix(mat); - bonemats[bone] = matrix; -} - -/* Get channel value */ -const bool BCSample::get_value(std::string channel_target, const int array_index, float *val) const -{ - std::string bname = bc_string_before(channel_target, "."); - std::string channel_type = bc_string_after(channel_target, "."); - - const BCMatrix *matrix = &obmat; - if (bname != channel_target) { - bname = bname.substr(2); - bname = bc_string_before(bname, "\""); - BCBoneMatrixMap::const_iterator it; - for (it = bonemats.begin(); it != bonemats.end(); ++it) { - Bone *bone = it->first; - if (bname == bone->name) { - matrix = it->second; - break; - } - } - } - else { - matrix = &obmat; - } - - if (channel_type == "location") { - *val = matrix->location()[array_index]; - } - else if (channel_type == "scale") { - *val = matrix->scale()[array_index]; - } - else if (channel_type == "rotation" || channel_type == "rotation_euler") { - *val = matrix->rotation()[array_index]; - } - else if (channel_type == "rotation_quaternion") { - *val = matrix->quat()[array_index]; - } - else { - *val = 0; - return false; - } - - return true; -} - -const BCMatrix *BCSample::get_matrix(Bone *bone) const -{ - BCBoneMatrixMap::const_iterator it = bonemats.find(bone); - if (it == bonemats.end()) { - return NULL; - } - return it->second; -} - -const BCMatrix &BCSample::get_matrix() const -{ - return obmat; -} diff --git a/source/blender/collada/BCSampleData.h b/source/blender/collada/BCSampleData.h deleted file mode 100644 index 07ecb544c71..00000000000 --- a/source/blender/collada/BCSampleData.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - */ - -#ifndef __BCSAMPLEDATA_H__ -#define __BCSAMPLEDATA_H__ - -#include <string> -#include <map> -#include <algorithm> - -#include "ExportSettings.h" -#include "BCSampleData.h" -#include "BCMath.h" - -extern "C" { -#include "BKE_object.h" -#include "BLI_math_rotation.h" -#include "DNA_object_types.h" -#include "DNA_armature_types.h" -#include "DNA_material_types.h" -#include "DNA_light_types.h" -#include "DNA_camera_types.h" -} - -typedef std::map<Bone *, BCMatrix *> BCBoneMatrixMap; - -class BCSample { - private: - BCMatrix obmat; - BCBoneMatrixMap bonemats; /* For Armature animation */ - - public: - BCSample(Object *ob) : obmat(ob) - { - } - - ~BCSample(); - - void add_bone_matrix(Bone *bone, Matrix &mat); - - const bool get_value(std::string channel_target, const int array_index, float *val) const; - const BCMatrix &get_matrix() const; - const BCMatrix *get_matrix(Bone *bone) const; // returns NULL if bone is not animated -}; - -typedef std::map<Object *, BCSample *> BCSampleMap; -typedef std::map<int, const BCSample *> BCFrameSampleMap; -typedef std::map<int, const BCMatrix *> BCMatrixSampleMap; - -#endif /* __BCSAMPLEDATA_H__ */ diff --git a/source/blender/collada/BlenderContext.cpp b/source/blender/collada/BlenderContext.cpp deleted file mode 100644 index a9783a9b9c4..00000000000 --- a/source/blender/collada/BlenderContext.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <vector> - -#include "BlenderContext.h" -#include "ExportSettings.h" - -#include "BKE_scene.h" - -bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer) -{ - Object *root = bc_get_highest_exported_ancestor_or_self(export_set, ob, view_layer); - return (root == ob); -} - -/** - * Returns the highest selected ancestor - * returns NULL if no ancestor is selected - * IMPORTANT: This function expects that all exported objects have set: - * ob->id.tag & LIB_TAG_DOIT - */ -Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set, - Object *ob, - ViewLayer *view_layer) -{ - Object *ancestor = ob; - while (ob->parent) { - if (bc_is_in_Export_set(export_set, ob->parent, view_layer)) { - ancestor = ob->parent; - } - ob = ob->parent; - } - return ancestor; -} - -void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer) -{ - Base *base; - for (base = (Base *)view_layer->object_bases.first; base; base = base->next) { - Object *cob = base->object; - if (cob->parent == ob) { - switch (ob->type) { - case OB_MESH: - case OB_CAMERA: - case OB_LAMP: - case OB_EMPTY: - case OB_ARMATURE: - child_set.push_back(cob); - default: - break; - } - } - } -} - -bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer) -{ - bool to_export = (BLI_linklist_index(export_set, ob) != -1); - - if (!to_export) { - /* Mark this object as to_export even if it is not in the - export list, but it contains children to export */ - - std::vector<Object *> children; - bc_get_children(children, ob, view_layer); - for (int i = 0; i < children.size(); i++) { - if (bc_is_in_Export_set(export_set, children[i], view_layer)) { - to_export = true; - break; - } - } - } - return to_export; -} - -int bc_is_marked(Object *ob) -{ - return ob && (ob->id.tag & LIB_TAG_DOIT); -} - -void bc_remove_mark(Object *ob) -{ - ob->id.tag &= ~LIB_TAG_DOIT; -} - -void bc_set_mark(Object *ob) -{ - ob->id.tag |= LIB_TAG_DOIT; -} - -BlenderContext::BlenderContext(bContext *C) -{ - context = C; - main = CTX_data_main(C); - scene = CTX_data_scene(C); - view_layer = CTX_data_view_layer(C); - depsgraph = nullptr; // create only when needed -} - -bContext *BlenderContext::get_context() -{ - return context; -} - -Depsgraph *BlenderContext::get_depsgraph() -{ - if (!depsgraph) { - depsgraph = BKE_scene_get_depsgraph(main, scene, view_layer, true); - } - return depsgraph; -} - -Scene *BlenderContext::get_scene() -{ - return scene; -} - -Scene *BlenderContext::get_evaluated_scene() -{ - Scene *scene_eval = DEG_get_evaluated_scene(get_depsgraph()); - return scene_eval; -} - -Object *BlenderContext::get_evaluated_object(Object *ob) -{ - Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob); - return ob_eval; -} - -ViewLayer *BlenderContext::get_view_layer() -{ - return view_layer; -} - -Main *BlenderContext::get_main() -{ - return main; -} diff --git a/source/blender/collada/BlenderContext.h b/source/blender/collada/BlenderContext.h deleted file mode 100644 index 50781e8eede..00000000000 --- a/source/blender/collada/BlenderContext.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __BLENDERCONTEXT_H__ -#define __BLENDERCONTEXT_H__ - -#ifdef __cplusplus - -extern "C" { -#endif - -#include "DNA_object_types.h" -#include "BLI_linklist.h" -#include "BKE_context.h" -#include "BKE_main.h" -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_query.h" -#include "DNA_layer_types.h" -#include "BlenderTypes.h" - -static const BC_global_forward_axis BC_DEFAULT_FORWARD = BC_GLOBAL_FORWARD_Y; -static const BC_global_up_axis BC_DEFAULT_UP = BC_GLOBAL_UP_Z; - -bool bc_is_in_Export_set(LinkNode *export_set, Object *ob, ViewLayer *view_layer); -bool bc_is_base_node(LinkNode *export_set, Object *ob, ViewLayer *view_layer); -Object *bc_get_highest_exported_ancestor_or_self(LinkNode *export_set, - Object *ob, - ViewLayer *view_layer); -int bc_is_marked(Object *ob); -void bc_remove_mark(Object *ob); -void bc_set_mark(Object *ob); - -#ifdef __cplusplus -} - -class BlenderContext { - private: - bContext *context; - Depsgraph *depsgraph; - Scene *scene; - ViewLayer *view_layer; - Main *main; - - public: - BlenderContext(bContext *C); - bContext *get_context(); - Depsgraph *get_depsgraph(); - Scene *get_scene(); - Scene *get_evaluated_scene(); - Object *get_evaluated_object(Object *ob); - ViewLayer *get_view_layer(); - Main *get_main(); -}; -#endif - -#endif diff --git a/source/blender/collada/BlenderTypes.h b/source/blender/collada/BlenderTypes.h deleted file mode 100644 index 0e024be2374..00000000000 --- a/source/blender/collada/BlenderTypes.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __BLENDERTYPES_H__ -#define __BLENDERTYPES_H__ - -typedef float(Vector)[3]; -typedef float(Quat)[4]; -typedef float(Color)[4]; -typedef float(Matrix)[4][4]; -typedef double(DMatrix)[4][4]; - -typedef enum BC_global_forward_axis { - BC_GLOBAL_FORWARD_X = 0, - BC_GLOBAL_FORWARD_Y = 1, - BC_GLOBAL_FORWARD_Z = 2, - BC_GLOBAL_FORWARD_MINUS_X = 3, - BC_GLOBAL_FORWARD_MINUS_Y = 4, - BC_GLOBAL_FORWARD_MINUS_Z = 5 -} BC_global_forward_axis; - -typedef enum BC_global_up_axis { - BC_GLOBAL_UP_X = 0, - BC_GLOBAL_UP_Y = 1, - BC_GLOBAL_UP_Z = 2, - BC_GLOBAL_UP_MINUS_X = 3, - BC_GLOBAL_UP_MINUS_Y = 4, - BC_GLOBAL_UP_MINUS_Z = 5 -} BC_global_up_axis; - -#endif diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt deleted file mode 100644 index 6f1c6922d63..00000000000 --- a/source/blender/collada/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -# ***** BEGIN GPL LICENSE BLOCK ***** -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# The Original Code is Copyright (C) 2006, Blender Foundation -# All rights reserved. -# ***** END GPL LICENSE BLOCK ***** - -remove_strict_flags() -FIND_FILE(OPENCOLLADA_ANIMATION_CLIP - NAMES - COLLADAFWAnimationClip.h - PATHS - ${OPENCOLLADA_INCLUDE_DIRS} - NO_DEFAULT_PATH -) - -if(OPENCOLLADA_ANIMATION_CLIP) - add_definitions(-DWITH_OPENCOLLADA_ANIMATION_CLIP) -endif() - -set(INC - . - ../blenkernel - ../blenlib - ../blentranslation - ../depsgraph - ../editors/include - ../imbuf - ../makesdna - ../makesrna - ../windowmanager - ../../../intern/guardedalloc - ../ikplugin - ../../../intern/iksolver/extern - ../bmesh -) - -set(INC_SYS - ${OPENCOLLADA_INCLUDE_DIRS} -) - -set(SRC - AnimationClipExporter.cpp - AnimationExporter.cpp - AnimationImporter.cpp - ArmatureExporter.cpp - ArmatureImporter.cpp - BCAnimationCurve.cpp - BCAnimationSampler.cpp - BCMath.cpp - BCSampleData.cpp - BlenderContext.cpp - CameraExporter.cpp - ControllerExporter.cpp - DocumentExporter.cpp - DocumentImporter.cpp - EffectExporter.cpp - ErrorHandler.cpp - ExportSettings.cpp - ExtraHandler.cpp - ExtraTags.cpp - GeometryExporter.cpp - ImageExporter.cpp - ImportSettings.cpp - InstanceWriter.cpp - LightExporter.cpp - MaterialExporter.cpp - Materials.cpp - MeshImporter.cpp - SceneExporter.cpp - SkinInfo.cpp - TransformReader.cpp - TransformWriter.cpp - collada.cpp - collada_internal.cpp - collada_utils.cpp - - AnimationClipExporter.h - AnimationExporter.h - AnimationImporter.h - ArmatureExporter.h - ArmatureImporter.h - BCAnimationCurve.h - BCAnimationSampler.h - BCMath.h - BCSampleData.h - BlenderContext.h - BlenderTypes.h - CameraExporter.h - ControllerExporter.h - DocumentExporter.h - DocumentImporter.h - EffectExporter.h - ErrorHandler.h - ExportSettings.h - ExtraHandler.h - ExtraTags.h - GeometryExporter.h - ImageExporter.h - ImportSettings.h - InstanceWriter.h - LightExporter.h - MaterialExporter.h - Materials.h - MeshImporter.h - SceneExporter.h - SkinInfo.h - TransformReader.h - TransformWriter.h - collada.h - collada_internal.h - collada_utils.h -) - -set(LIB - ${OPENCOLLADA_LIBRARIES} - ${PCRE_LIBRARIES} - ${XML2_LIBRARIES} -) - -if(WITH_BUILDINFO) - add_definitions(-DWITH_BUILDINFO) -endif() - -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX) - # COLLADAFWArray.h gives error with gcc 4.5 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive") -endif() - -blender_add_lib(bf_collada "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/collada/CameraExporter.cpp b/source/blender/collada/CameraExporter.cpp deleted file mode 100644 index 74862c44270..00000000000 --- a/source/blender/collada/CameraExporter.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <string> - -#include "COLLADASWCamera.h" - -extern "C" { -#include "DNA_camera_types.h" -} -#include "CameraExporter.h" - -#include "collada_internal.h" - -CamerasExporter::CamerasExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) - : COLLADASW::LibraryCameras(sw), export_settings(export_settings) -{ -} - -template<class Functor> -void forEachCameraObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) -{ - LinkNode *node; - for (node = export_set; node; node = node->next) { - Object *ob = (Object *)node->link; - - if (ob->type == OB_CAMERA && ob->data) { - f(ob, sce); - } - } -} - -void CamerasExporter::exportCameras(Scene *sce) -{ - openLibrary(); - - forEachCameraObjectInExportSet(sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); -} -void CamerasExporter::operator()(Object *ob, Scene *sce) -{ - Camera *cam = (Camera *)ob->data; - std::string cam_id(get_camera_id(ob)); - std::string cam_name(id_name(cam)); - - switch (cam->type) { - case CAM_PANO: - case CAM_PERSP: { - COLLADASW::PerspectiveOptic persp(mSW); - persp.setXFov(RAD2DEGF(focallength_to_fov(cam->lens, cam->sensor_x)), "xfov"); - persp.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio"); - persp.setZFar(cam->clip_end, false, "zfar"); - persp.setZNear(cam->clip_start, false, "znear"); - COLLADASW::Camera ccam(mSW, &persp, cam_id, cam_name); - exportBlenderProfile(ccam, cam); - addCamera(ccam); - - break; - } - case CAM_ORTHO: - default: { - COLLADASW::OrthographicOptic ortho(mSW); - ortho.setXMag(cam->ortho_scale / 2, "xmag"); - ortho.setAspectRatio((float)(sce->r.xsch) / (float)(sce->r.ysch), false, "aspect_ratio"); - ortho.setZFar(cam->clip_end, false, "zfar"); - ortho.setZNear(cam->clip_start, false, "znear"); - COLLADASW::Camera ccam(mSW, &ortho, cam_id, cam_name); - exportBlenderProfile(ccam, cam); - addCamera(ccam); - break; - } - } -} -bool CamerasExporter::exportBlenderProfile(COLLADASW::Camera &cm, Camera *cam) -{ - cm.addExtraTechniqueParameter("blender", "shiftx", cam->shiftx); - cm.addExtraTechniqueParameter("blender", "shifty", cam->shifty); - cm.addExtraTechniqueParameter("blender", "dof_distance", cam->dof.focus_distance); - return true; -} diff --git a/source/blender/collada/CameraExporter.h b/source/blender/collada/CameraExporter.h deleted file mode 100644 index 04bcc4a5dad..00000000000 --- a/source/blender/collada/CameraExporter.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __CAMERAEXPORTER_H__ -#define __CAMERAEXPORTER_H__ - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryCameras.h" - -extern "C" { -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -} - -#include "ExportSettings.h" -#include "DNA_camera_types.h" - -class CamerasExporter : COLLADASW::LibraryCameras { - public: - CamerasExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); - void exportCameras(Scene *sce); - void operator()(Object *ob, Scene *sce); - - private: - bool exportBlenderProfile(COLLADASW::Camera &cla, Camera *cam); - BCExportSettings &export_settings; -}; - -#endif diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp deleted file mode 100644 index 0119aba7dfd..00000000000 --- a/source/blender/collada/ControllerExporter.cpp +++ /dev/null @@ -1,649 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "COLLADASWBaseInputElement.h" -#include "COLLADASWInstanceController.h" -#include "COLLADASWPrimitves.h" -#include "COLLADASWSource.h" - -#include "DNA_action_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" - -#include "BKE_action.h" -#include "BKE_armature.h" - -extern "C" { -#include "BKE_global.h" -#include "BKE_idprop.h" -#include "BKE_lib_id.h" -#include "BKE_mesh.h" -} - -#include "ED_armature.h" - -#include "BLI_listbase.h" - -#include "GeometryExporter.h" -#include "ArmatureExporter.h" -#include "ControllerExporter.h" -#include "SceneExporter.h" - -#include "collada_utils.h" - -bool ControllerExporter::is_skinned_mesh(Object *ob) -{ - return bc_get_assigned_armature(ob) != NULL; -} - -void ControllerExporter::write_bone_URLs(COLLADASW::InstanceController &ins, - Object *ob_arm, - Bone *bone) -{ - if (bc_is_root_bone(bone, this->export_settings.get_deform_bones_only())) { - std::string node_id = translate_id(id_name(ob_arm) + "_" + bone->name); - ins.addSkeleton(COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, node_id)); - } - else { - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - write_bone_URLs(ins, ob_arm, child); - } - } -} - -bool ControllerExporter::add_instance_controller(Object *ob) -{ - Object *ob_arm = bc_get_assigned_armature(ob); - bArmature *arm = (bArmature *)ob_arm->data; - - const std::string &controller_id = get_controller_id(ob_arm, ob); - - COLLADASW::InstanceController ins(mSW); - ins.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, controller_id)); - - Mesh *me = (Mesh *)ob->data; - if (!me->dvert) { - return false; - } - - /* write root bone URLs */ - Bone *bone; - for (bone = (Bone *)arm->bonebase.first; bone; bone = bone->next) { - write_bone_URLs(ins, ob_arm, bone); - } - - InstanceWriter::add_material_bindings( - ins.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); - - ins.add(); - return true; -} - -void ControllerExporter::export_controllers() -{ - Scene *sce = blender_context.get_scene(); - openLibrary(); - - GeometryFunctor gf; - gf.forEachMeshObjectInExportSet<ControllerExporter>( - sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); -} - -void ControllerExporter::operator()(Object *ob) -{ - Object *ob_arm = bc_get_assigned_armature(ob); - Key *key = BKE_key_from_object(ob); - - if (ob_arm) { - export_skin_controller(ob, ob_arm); - } - if (key && this->export_settings.get_include_shapekeys()) { - export_morph_controller(ob, key); - } -} -#if 0 - -bool ArmatureExporter::already_written(Object *ob_arm) -{ - return std::find(written_armatures.begin(), written_armatures.end(), ob_arm) != - written_armatures.end(); -} - -void ArmatureExporter::wrote(Object *ob_arm) -{ - written_armatures.push_back(ob_arm); -} - -void ArmatureExporter::find_objects_using_armature(Object *ob_arm, - std::vector<Object *> &objects, - Scene *sce) -{ - objects.clear(); - - Base *base = (Base *)sce->base.first; - while (base) { - Object *ob = base->object; - - if (ob->type == OB_MESH && get_assigned_armature(ob) == ob_arm) { - objects.push_back(ob); - } - - base = base->next; - } -} -#endif - -std::string ControllerExporter::get_controller_id(Object *ob_arm, Object *ob) -{ - return translate_id(id_name(ob_arm)) + "_" + translate_id(id_name(ob)) + - SKIN_CONTROLLER_ID_SUFFIX; -} - -std::string ControllerExporter::get_controller_id(Key *key, Object *ob) -{ - return translate_id(id_name(ob)) + MORPH_CONTROLLER_ID_SUFFIX; -} - -/* ob should be of type OB_MESH - * both args are required */ -void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm) -{ - /* joint names - * joint inverse bind matrices - * vertex weights */ - - /* input: - * joint names: ob -> vertex group names - * vertex group weights: me->dvert -> groups -> index, weight */ - - bool use_instantiation = this->export_settings.get_use_object_instantiation(); - Mesh *me; - - if (((Mesh *)ob->data)->dvert == NULL) { - return; - } - - me = bc_get_mesh_copy(blender_context, - ob, - this->export_settings.get_export_mesh_type(), - this->export_settings.get_apply_modifiers(), - this->export_settings.get_triangulate()); - - std::string controller_name = id_name(ob_arm); - std::string controller_id = get_controller_id(ob_arm, ob); - - openSkin(controller_id, - controller_name, - COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation))); - - add_bind_shape_mat(ob); - - std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id); - std::string inv_bind_mat_source_id = add_inv_bind_mats_source( - ob_arm, &ob->defbase, controller_id); - - std::list<int> vcounts; - std::list<int> joints; - std::list<float> weights; - - { - int i, j; - - /* def group index -> joint index */ - std::vector<int> joint_index_by_def_index; - bDeformGroup *def; - - for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) { - if (is_bone_defgroup(ob_arm, def)) { - joint_index_by_def_index.push_back(j++); - } - else { - joint_index_by_def_index.push_back(-1); - } - } - - int oob_counter = 0; - for (i = 0; i < me->totvert; i++) { - MDeformVert *vert = &me->dvert[i]; - std::map<int, float> jw; - - /* We're normalizing the weights later */ - float sumw = 0.0f; - - for (j = 0; j < vert->totweight; j++) { - uint idx = vert->dw[j].def_nr; - if (idx >= joint_index_by_def_index.size()) { - /* XXX: Maybe better find out where and - * why the Out Of Bound indexes get created ? */ - oob_counter += 1; - } - else { - int joint_index = joint_index_by_def_index[idx]; - if (joint_index != -1 && vert->dw[j].weight > 0.0f) { - jw[joint_index] += vert->dw[j].weight; - sumw += vert->dw[j].weight; - } - } - } - - if (sumw > 0.0f) { - float invsumw = 1.0f / sumw; - vcounts.push_back(jw.size()); - for (std::map<int, float>::iterator m = jw.begin(); m != jw.end(); ++m) { - joints.push_back((*m).first); - weights.push_back(invsumw * (*m).second); - } - } - else { - vcounts.push_back(0); -#if 0 - vcounts.push_back(1); - joints.push_back(-1); - weights.push_back(1.0f); -#endif - } - } - - if (oob_counter > 0) { - fprintf(stderr, - "Ignored %d Vertex weights which use index to non existing VGroup %zu.\n", - oob_counter, - joint_index_by_def_index.size()); - } - } - - std::string weights_source_id = add_weights_source(me, controller_id, weights); - add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id); - add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints); - - BKE_id_free(NULL, me); - - closeSkin(); - closeController(); -} - -void ControllerExporter::export_morph_controller(Object *ob, Key *key) -{ - bool use_instantiation = this->export_settings.get_use_object_instantiation(); - Mesh *me; - - me = bc_get_mesh_copy(blender_context, - ob, - this->export_settings.get_export_mesh_type(), - this->export_settings.get_apply_modifiers(), - this->export_settings.get_triangulate()); - - std::string controller_name = id_name(ob) + "-morph"; - std::string controller_id = get_controller_id(key, ob); - - openMorph( - controller_id, - controller_name, - COLLADABU::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, use_instantiation))); - - std::string targets_id = add_morph_targets(key, ob); - std::string morph_weights_id = add_morph_weights(key, ob); - - COLLADASW::TargetsElement targets(mSW); - - COLLADASW::InputList &input = targets.getInputList(); - - input.push_back(COLLADASW::Input( - COLLADASW::InputSemantic::MORPH_TARGET, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, targets_id))); - input.push_back( - COLLADASW::Input(COLLADASW::InputSemantic::MORPH_WEIGHT, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id))); - targets.add(); - - BKE_id_free(NULL, me); - - /* support for animations - * can also try the base element and param alternative */ - add_weight_extras(key); - closeMorph(); - closeController(); -} - -std::string ControllerExporter::add_morph_targets(Key *key, Object *ob) -{ - std::string source_id = translate_id(id_name(ob)) + TARGETS_SOURCE_ID_SUFFIX; - - COLLADASW::IdRefSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(key->totkey - 1); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("IDREF"); - - source.prepareToAppendValues(); - - KeyBlock *kb = (KeyBlock *)key->block.first; - /* skip the basis */ - kb = kb->next; - for (; kb; kb = kb->next) { - std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name); - source.appendValues(geom_id); - } - - source.finish(); - - return source_id; -} - -std::string ControllerExporter::add_morph_weights(Key *key, Object *ob) -{ - std::string source_id = translate_id(id_name(ob)) + WEIGHTS_SOURCE_ID_SUFFIX; - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(key->totkey - 1); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("MORPH_WEIGHT"); - - source.prepareToAppendValues(); - - KeyBlock *kb = (KeyBlock *)key->block.first; - /* skip the basis */ - kb = kb->next; - for (; kb; kb = kb->next) { - float weight = kb->curval; - source.appendValues(weight); - } - source.finish(); - - return source_id; -} - -/* Added to implement support for animations. */ -void ControllerExporter::add_weight_extras(Key *key) -{ - /* can also try the base element and param alternative */ - COLLADASW::BaseExtraTechnique extra; - - KeyBlock *kb = (KeyBlock *)key->block.first; - /* skip the basis */ - kb = kb->next; - for (; kb; kb = kb->next) { - /* XXX why is the weight not used here and set to 0.0? - * float weight = kb->curval; */ - extra.addExtraTechniqueParameter("KHR", "morph_weights", 0.000, "MORPH_WEIGHT_TO_TARGET"); - } -} - -void ControllerExporter::add_joints_element(ListBase *defbase, - const std::string &joints_source_id, - const std::string &inv_bind_mat_source_id) -{ - COLLADASW::JointsElement joints(mSW); - COLLADASW::InputList &input = joints.getInputList(); - - input.push_back(COLLADASW::Input( - COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id))); - input.push_back( - COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, inv_bind_mat_source_id))); - joints.add(); -} - -void ControllerExporter::add_bind_shape_mat(Object *ob) -{ - double bind_mat[4][4]; - float f_obmat[4][4]; - BKE_object_matrix_local_get(ob, f_obmat); - - if (export_settings.get_apply_global_orientation()) { - // do nothing, rotation is going to be applied to the Data - } - else { - bc_add_global_transform(f_obmat, export_settings.get_global_transform()); - } - - // UnitConverter::mat4_to_dae_double(bind_mat, ob->obmat); - UnitConverter::mat4_to_dae_double(bind_mat, f_obmat); - if (this->export_settings.get_limit_precision()) { - BCMatrix::sanitize(bind_mat, LIMITTED_PRECISION); - } - - addBindShapeTransform(bind_mat); -} - -std::string ControllerExporter::add_joints_source(Object *ob_arm, - ListBase *defbase, - const std::string &controller_id) -{ - std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX; - - int totjoint = 0; - bDeformGroup *def; - for (def = (bDeformGroup *)defbase->first; def; def = def->next) { - if (is_bone_defgroup(ob_arm, def)) { - totjoint++; - } - } - - COLLADASW::NameSource source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(totjoint); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("JOINT"); - - source.prepareToAppendValues(); - - for (def = (bDeformGroup *)defbase->first; def; def = def->next) { - Bone *bone = get_bone_from_defgroup(ob_arm, def); - if (bone) { - source.appendValues(get_joint_sid(bone)); - } - } - - source.finish(); - - return source_id; -} - -std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm, - ListBase *defbase, - const std::string &controller_id) -{ - std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX; - - int totjoint = 0; - for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) { - if (is_bone_defgroup(ob_arm, def)) { - totjoint++; - } - } - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(totjoint); // BLI_listbase_count(defbase)); - source.setAccessorStride(16); - - source.setParameterTypeName(&COLLADASW::CSWC::CSW_VALUE_TYPE_FLOAT4x4); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("TRANSFORM"); - - source.prepareToAppendValues(); - - bPose *pose = ob_arm->pose; - bArmature *arm = (bArmature *)ob_arm->data; - - int flag = arm->flag; - - /* put armature in rest position */ - if (!(arm->flag & ARM_RESTPOS)) { - Depsgraph *depsgraph = blender_context.get_depsgraph(); - Scene *scene = blender_context.get_scene(); - - arm->flag |= ARM_RESTPOS; - BKE_pose_where_is(depsgraph, scene, ob_arm); - } - - for (bDeformGroup *def = (bDeformGroup *)defbase->first; def; def = def->next) { - if (is_bone_defgroup(ob_arm, def)) { - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, def->name); - - float mat[4][4]; - float world[4][4]; - float inv_bind_mat[4][4]; - - float bind_mat[4][4]; /* derived from bone->arm_mat */ - - bool has_bindmat = bc_get_property_matrix(pchan->bone, "bind_mat", bind_mat); - - if (!has_bindmat) { - - /* Have no bind matrix stored, try old style <= Blender 2.78 */ - - bc_create_restpose_mat( - this->export_settings, pchan->bone, bind_mat, pchan->bone->arm_mat, true); - - /* SL/OPEN_SIM COMPATIBILITY */ - if (export_settings.get_open_sim()) { - float loc[3]; - float rot[3] = {0, 0, 0}; - float scale[3]; - bc_decompose(bind_mat, loc, NULL, NULL, scale); - - /* Only translations, no rotation vs armature */ - loc_eulO_size_to_mat4(bind_mat, loc, rot, scale, 6); - } - } - - /* make world-space matrix (bind_mat is armature-space) */ - mul_m4_m4m4(world, ob_arm->obmat, bind_mat); - - if (!has_bindmat) { - if (export_settings.get_apply_global_orientation()) { - bc_apply_global_transform(world, export_settings.get_global_transform()); - } - } - - invert_m4_m4(mat, world); - UnitConverter::mat4_to_dae(inv_bind_mat, mat); - if (this->export_settings.get_limit_precision()) { - BCMatrix::sanitize(inv_bind_mat, LIMITTED_PRECISION); - } - source.appendValues(inv_bind_mat); - } - } - - /* back from rest position */ - if (!(flag & ARM_RESTPOS)) { - Depsgraph *depsgraph = blender_context.get_depsgraph(); - Scene *scene = blender_context.get_scene(); - arm->flag = flag; - BKE_pose_where_is(depsgraph, scene, ob_arm); - } - - source.finish(); - - return source_id; -} - -Bone *ControllerExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def) -{ - bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name); - return pchan ? pchan->bone : NULL; -} - -bool ControllerExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def) -{ - return get_bone_from_defgroup(ob_arm, def) != NULL; -} - -std::string ControllerExporter::add_weights_source(Mesh *me, - const std::string &controller_id, - const std::list<float> &weights) -{ - std::string source_id = controller_id + WEIGHTS_SOURCE_ID_SUFFIX; - - COLLADASW::FloatSourceF source(mSW); - source.setId(source_id); - source.setArrayId(source_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(weights.size()); - source.setAccessorStride(1); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("WEIGHT"); - - source.prepareToAppendValues(); - - for (std::list<float>::const_iterator i = weights.begin(); i != weights.end(); ++i) { - source.appendValues(*i); - } - - source.finish(); - - return source_id; -} - -void ControllerExporter::add_vertex_weights_element(const std::string &weights_source_id, - const std::string &joints_source_id, - const std::list<int> &vcounts, - const std::list<int> &joints) -{ - COLLADASW::VertexWeightsElement weightselem(mSW); - COLLADASW::InputList &input = weightselem.getInputList(); - - int offset = 0; - input.push_back(COLLADASW::Input( - COLLADASW::InputSemantic::JOINT, // constant declared in COLLADASWInputList.h - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, joints_source_id), - offset++)); - input.push_back( - COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT, - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, weights_source_id), - offset++)); - - weightselem.setCount(vcounts.size()); - - /* write number of deformers per vertex */ - COLLADASW::PrimitivesBase::VCountList vcountlist; - - vcountlist.resize(vcounts.size()); - std::copy(vcounts.begin(), vcounts.end(), vcountlist.begin()); - - weightselem.prepareToAppendVCountValues(); - weightselem.appendVertexCount(vcountlist); - - weightselem.CloseVCountAndOpenVElement(); - - /* write deformer index - weight index pairs */ - int weight_index = 0; - for (std::list<int>::const_iterator i = joints.begin(); i != joints.end(); ++i) { - weightselem.appendValues(*i, weight_index++); - } - - weightselem.finish(); -} diff --git a/source/blender/collada/ControllerExporter.h b/source/blender/collada/ControllerExporter.h deleted file mode 100644 index ce2ed9fe453..00000000000 --- a/source/blender/collada/ControllerExporter.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __CONTROLLEREXPORTER_H__ -#define __CONTROLLEREXPORTER_H__ - -#include <list> -#include <string> -//#include <vector> - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryControllers.h" -#include "COLLADASWInstanceController.h" -#include "COLLADASWInputList.h" -#include "COLLADASWNode.h" -#include "COLLADASWExtraTechnique.h" - -#include "DNA_armature_types.h" -#include "DNA_listBase.h" -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" -#include "DNA_key_types.h" - -#include "TransformWriter.h" -#include "InstanceWriter.h" - -#include "ExportSettings.h" - -#include "BKE_key.h" - -class SceneExporter; - -class ControllerExporter : public COLLADASW::LibraryControllers, - protected TransformWriter, - protected InstanceWriter { - private: - BlenderContext &blender_context; - BCExportSettings export_settings; - - public: - // XXX exporter writes wrong data for shared armatures. A separate - // controller should be written for each armature-mesh binding how do - // we make controller ids then? - ControllerExporter(BlenderContext &blender_context, - COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings) - : COLLADASW::LibraryControllers(sw), - blender_context(blender_context), - export_settings(export_settings) - { - } - - bool is_skinned_mesh(Object *ob); - - bool add_instance_controller(Object *ob); - - void export_controllers(); - - void operator()(Object *ob); - - private: -#if 0 - std::vector<Object *> written_armatures; - - bool already_written(Object *ob_arm); - - void wrote(Object *ob_arm); - - void find_objects_using_armature(Object *ob_arm, std::vector<Object *> &objects, Scene *sce); -#endif - - std::string get_controller_id(Object *ob_arm, Object *ob); - - std::string get_controller_id(Key *key, Object *ob); - - // ob should be of type OB_MESH - // both args are required - void export_skin_controller(Object *ob, Object *ob_arm); - - void export_morph_controller(Object *ob, Key *key); - - void add_joints_element(ListBase *defbase, - const std::string &joints_source_id, - const std::string &inv_bind_mat_source_id); - - void add_bind_shape_mat(Object *ob); - - std::string add_morph_targets(Key *key, Object *ob); - - std::string add_morph_weights(Key *key, Object *ob); - - void add_weight_extras(Key *key); - - std::string add_joints_source(Object *ob_arm, - ListBase *defbase, - const std::string &controller_id); - - std::string add_inv_bind_mats_source(Object *ob_arm, - ListBase *defbase, - const std::string &controller_id); - - Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def); - - bool is_bone_defgroup(Object *ob_arm, bDeformGroup *def); - - std::string add_weights_source(Mesh *me, - const std::string &controller_id, - const std::list<float> &weights); - - void add_vertex_weights_element(const std::string &weights_source_id, - const std::string &joints_source_id, - const std::list<int> &vcount, - const std::list<int> &joints); - - void write_bone_URLs(COLLADASW::InstanceController &ins, Object *ob_arm, Bone *bone); -}; - -#endif diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp deleted file mode 100644 index 24a960ab287..00000000000 --- a/source/blender/collada/DocumentExporter.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <vector> -#include <algorithm> // std::find - -#include "COLLADASWCamera.h" -#include "COLLADASWAsset.h" -#include "COLLADASWLibraryVisualScenes.h" -#include "COLLADASWNode.h" -#include "COLLADASWSource.h" -#include "COLLADASWInstanceGeometry.h" -#include "COLLADASWInputList.h" -#include "COLLADASWPrimitves.h" -#include "COLLADASWVertices.h" -#include "COLLADASWLibraryAnimations.h" -#include "COLLADASWLibraryImages.h" -#include "COLLADASWLibraryEffects.h" -#include "COLLADASWImage.h" -#include "COLLADASWEffectProfile.h" -#include "COLLADASWColorOrTexture.h" -#include "COLLADASWParamTemplate.h" -#include "COLLADASWParamBase.h" -#include "COLLADASWSurfaceInitOption.h" -#include "COLLADASWSampler.h" -#include "COLLADASWScene.h" -#include "COLLADASWTechnique.h" -#include "COLLADASWTexture.h" -#include "COLLADASWLibraryMaterials.h" -#include "COLLADASWBindMaterial.h" -#include "COLLADASWInstanceCamera.h" -#include "COLLADASWInstanceLight.h" -#include "COLLADASWConstants.h" -#include "COLLADASWLibraryControllers.h" -#include "COLLADASWInstanceController.h" -#include "COLLADASWInstanceNode.h" -#include "COLLADASWBaseInputElement.h" - -#include "MEM_guardedalloc.h" - -extern "C" { -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_collection_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_image_types.h" -#include "DNA_material_types.h" -#include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_curve_types.h" -#include "DNA_armature_types.h" -#include "DNA_modifier_types.h" -#include "DNA_userdef_types.h" - -#include "BLI_path_util.h" -#include "BLI_fileops.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_listbase.h" -#include "BLI_utildefines.h" - -#include "BKE_action.h" // pose functions -#include "BKE_animsys.h" -#include "BKE_armature.h" -#include "BKE_blender_version.h" -#include "BKE_customdata.h" -#include "BKE_fcurve.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_material.h" -#include "BKE_object.h" -#include "BKE_scene.h" -#include "BKE_appdir.h" - -#include "ED_keyframing.h" -#ifdef WITH_BUILDINFO -extern char build_commit_date[]; -extern char build_commit_time[]; -extern char build_hash[]; -#endif - -#include "RNA_access.h" -} - -#include "collada_internal.h" -#include "collada_utils.h" -#include "DocumentExporter.h" - -extern bool bc_has_object_type(LinkNode *export_set, short obtype); - -// can probably go after refactor is complete -#include "InstanceWriter.h" -#include "TransformWriter.h" - -#include "SceneExporter.h" -#include "ArmatureExporter.h" -#include "AnimationExporter.h" -#include "CameraExporter.h" -#include "ControllerExporter.h" -#include "EffectExporter.h" -#include "GeometryExporter.h" -#include "ImageExporter.h" -#include "LightExporter.h" -#include "MaterialExporter.h" - -#include <errno.h> - -char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n) -{ - int layer_index = CustomData_get_layer_index(data, type); - if (layer_index < 0) { - return NULL; - } - - return data->layers[layer_index + n].name; -} - -char *bc_CustomData_get_active_layer_name(const CustomData *data, int type) -{ - /* get the layer index of the active layer of type */ - int layer_index = CustomData_get_active_layer_index(data, type); - if (layer_index < 0) { - return NULL; - } - - return data->layers[layer_index].name; -} - -DocumentExporter::DocumentExporter(BlenderContext &blender_context, ExportSettings *exportSettings) - : blender_context(blender_context), - export_settings(BCExportSettings(exportSettings, blender_context)) -{ -} - -static COLLADABU::NativeString make_temp_filepath(const char *name, const char *extension) -{ - char tempfile[FILE_MAX]; - const char *tempdir = BKE_tempdir_session(); - - if (name == NULL) { - name = "untitled"; - } - - BLI_make_file_string(NULL, tempfile, tempdir, name); - - if (extension) { - BLI_path_extension_ensure(tempfile, FILE_MAX, extension); - } - - COLLADABU::NativeString native_filename = COLLADABU::NativeString( - tempfile, COLLADABU::NativeString::ENCODING_UTF8); - return native_filename; -} - -// TODO: it would be better to instantiate animations rather than create a new one per object -// COLLADA allows this through multiple <channel>s in <animation>. -// For this to work, we need to know objects that use a certain action. - -int DocumentExporter::exportCurrentScene() -{ - Scene *sce = blender_context.get_scene(); - bContext *C = blender_context.get_context(); - - PointerRNA sceneptr, unit_settings; - PropertyRNA *system; /* unused , *scale; */ - - clear_global_id_map(); - - COLLADABU::NativeString native_filename = make_temp_filepath(NULL, ".dae"); - COLLADASW::StreamWriter *writer = new COLLADASW::StreamWriter(native_filename); - - // open <collada> - writer->startDocument(); - - // <asset> - COLLADASW::Asset asset(writer); - - RNA_id_pointer_create(&(sce->id), &sceneptr); - unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); - system = RNA_struct_find_property(&unit_settings, "system"); - // scale = RNA_struct_find_property(&unit_settings, "scale_length"); - - std::string unitname = "meter"; - float linearmeasure = RNA_float_get(&unit_settings, "scale_length"); - - switch (RNA_property_enum_get(&unit_settings, system)) { - case USER_UNIT_NONE: - case USER_UNIT_METRIC: - if (linearmeasure == 0.001f) { - unitname = "millimeter"; - } - else if (linearmeasure == 0.01f) { - unitname = "centimeter"; - } - else if (linearmeasure == 0.1f) { - unitname = "decimeter"; - } - else if (linearmeasure == 1.0f) { - unitname = "meter"; - } - else if (linearmeasure == 1000.0f) { - unitname = "kilometer"; - } - break; - case USER_UNIT_IMPERIAL: - if (linearmeasure == 0.0254f) { - unitname = "inch"; - } - else if (linearmeasure == 0.3048f) { - unitname = "foot"; - } - else if (linearmeasure == 0.9144f) { - unitname = "yard"; - } - break; - default: - break; - } - - asset.setUnit(unitname, linearmeasure); - asset.setUpAxisType(COLLADASW::Asset::Z_UP); - asset.getContributor().mAuthor = "Blender User"; - char version_buf[128]; -#ifdef WITH_BUILDINFO - BLI_snprintf(version_buf, - sizeof(version_buf), - "Blender %d.%02d.%d commit date:%s, commit time:%s, hash:%s", - BLENDER_VERSION / 100, - BLENDER_VERSION % 100, - BLENDER_SUBVERSION, - build_commit_date, - build_commit_time, - build_hash); -#else - BLI_snprintf(version_buf, - sizeof(version_buf), - "Blender %d.%02d.%d", - BLENDER_VERSION / 100, - BLENDER_VERSION % 100, - BLENDER_SUBVERSION); -#endif - asset.getContributor().mAuthoringTool = version_buf; - asset.add(); - - LinkNode *export_set = this->export_settings.get_export_set(); - // <library_cameras> - if (bc_has_object_type(export_set, OB_CAMERA)) { - CamerasExporter ce(writer, this->export_settings); - ce.exportCameras(sce); - } - - // <library_lights> - if (bc_has_object_type(export_set, OB_LAMP)) { - LightsExporter le(writer, this->export_settings); - le.exportLights(sce); - } - - // <library_effects> - EffectsExporter ee(writer, this->export_settings, key_image_map); - ee.exportEffects(C, sce); - - // <library_images> - ImagesExporter ie(writer, this->export_settings, key_image_map); - ie.exportImages(sce); - - // <library_materials> - MaterialsExporter me(writer, this->export_settings); - me.exportMaterials(sce); - - // <library_geometries> - if (bc_has_object_type(export_set, OB_MESH)) { - GeometryExporter ge(blender_context, writer, this->export_settings); - ge.exportGeom(); - } - - // <library_controllers> - ArmatureExporter arm_exporter(blender_context, writer, this->export_settings); - ControllerExporter controller_exporter(blender_context, writer, this->export_settings); - if (bc_has_object_type(export_set, OB_ARMATURE) || - this->export_settings.get_include_shapekeys()) { - controller_exporter.export_controllers(); - } - - // <library_visual_scenes> - - SceneExporter se(blender_context, writer, &arm_exporter, this->export_settings); - - if (this->export_settings.get_include_animations()) { - // <library_animations> - AnimationExporter ae(writer, this->export_settings); - ae.exportAnimations(); - } - - se.exportScene(); - - // <scene> - std::string scene_name(translate_id(id_name(sce))); - COLLADASW::Scene scene(writer, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, scene_name)); - scene.add(); - - // close <Collada> - writer->endDocument(); - delete writer; - - // Finally move the created document into place - fprintf(stdout, "Collada export to: %s\n", this->export_settings.get_filepath()); - int status = BLI_rename(native_filename.c_str(), this->export_settings.get_filepath()); - if (status != 0) { - status = BLI_copy(native_filename.c_str(), this->export_settings.get_filepath()); - BLI_delete(native_filename.c_str(), false, false); - } - return status; -} - -void DocumentExporter::exportScenes(const char *filename) -{ -} - -/* - * NOTES: - * - * AnimationExporter::sample_animation enables all curves on armature, this is undesirable for a - * user - */ diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h deleted file mode 100644 index 70722ae601e..00000000000 --- a/source/blender/collada/DocumentExporter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __DOCUMENTEXPORTER_H__ -#define __DOCUMENTEXPORTER_H__ - -#include "collada.h" -#include "collada_utils.h" -#include "BlenderContext.h" - -extern "C" { -#include "DNA_customdata_types.h" -} - -class DocumentExporter { - public: - DocumentExporter(BlenderContext &blender_context, ExportSettings *export_settings); - int exportCurrentScene(); - void exportScenes(const char *filename); - - private: - BlenderContext &blender_context; - BCExportSettings export_settings; - KeyImageMap key_image_map; -}; - -#endif diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp deleted file mode 100644 index 9b66ff429e1..00000000000 --- a/source/blender/collada/DocumentImporter.cpp +++ /dev/null @@ -1,1265 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* TODO: - * * name imported objects - * * import object rotation as euler */ - -#include <string> -#include <map> -#include <algorithm> // sort() - -#include "COLLADAFWRoot.h" -#include "COLLADAFWStableHeaders.h" -#include "COLLADAFWColorOrTexture.h" -#include "COLLADAFWIndexList.h" -#include "COLLADAFWMeshPrimitiveWithFaceVertexCount.h" -#include "COLLADAFWPolygons.h" -#include "COLLADAFWSampler.h" -#include "COLLADAFWTypes.h" -#include "COLLADAFWVisualScene.h" -#include "COLLADAFWArrayPrimitiveType.h" -#include "COLLADAFWLibraryNodes.h" -#include "COLLADAFWCamera.h" -#include "COLLADAFWLight.h" - -#include "COLLADASaxFWLLoader.h" -#include "COLLADASaxFWLIExtraDataCallbackHandler.h" - -#include "MEM_guardedalloc.h" - -extern "C" { -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_utildefines.h" -#include "BLI_fileops.h" - -#include "BKE_camera.h" -#include "BKE_collection.h" -#include "BKE_fcurve.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_layer.h" -#include "BKE_light.h" -#include "BKE_lib_id.h" -#include "BKE_material.h" -#include "BKE_scene.h" - -#include "BLI_path_util.h" - -#include "DNA_camera_types.h" -#include "DNA_light_types.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" -} - -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_build.h" - -#include "ExtraHandler.h" -#include "ErrorHandler.h" -#include "DocumentImporter.h" -#include "TransformReader.h" - -#include "collada_internal.h" -#include "collada_utils.h" -#include "Materials.h" - -/* - * COLLADA Importer limitations: - * - no multiple scene import, all objects are added to active scene - */ - -// #define COLLADA_DEBUG -// creates empties for each imported bone on layer 2, for debugging -// #define ARMATURE_TEST - -DocumentImporter::DocumentImporter(bContext *C, const ImportSettings *import_settings) - : import_settings(import_settings), - mImportStage(Fetching_Scene_data), - mContext(C), - view_layer(CTX_data_view_layer(mContext)), - armature_importer(&unit_converter, - &mesh_importer, - CTX_data_main(C), - CTX_data_scene(C), - view_layer, - import_settings), - mesh_importer( - &unit_converter, &armature_importer, CTX_data_main(C), CTX_data_scene(C), view_layer), - anim_importer(C, &unit_converter, &armature_importer, CTX_data_scene(C)) -{ -} - -DocumentImporter::~DocumentImporter() -{ - TagsMap::iterator etit; - etit = uid_tags_map.begin(); - while (etit != uid_tags_map.end()) { - delete etit->second; - etit++; - } -} - -bool DocumentImporter::import() -{ - ErrorHandler errorHandler; - COLLADASaxFWL::Loader loader(&errorHandler); - COLLADAFW::Root root(&loader, this); - ExtraHandler *ehandler = new ExtraHandler(this, &(this->anim_importer)); - - loader.registerExtraDataCallbackHandler(ehandler); - - /* deselect all to select new objects */ - BKE_view_layer_base_deselect_all(view_layer); - - std::string mFilename = std::string(this->import_settings->filepath); - const std::string encodedFilename = bc_url_encode(mFilename); - if (!root.loadDocument(encodedFilename)) { - fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 1st pass\n"); - delete ehandler; - return false; - } - - if (errorHandler.hasError()) { - delete ehandler; - return false; - } - - /** TODO set up scene graph and such here */ - mImportStage = Fetching_Controller_data; - COLLADASaxFWL::Loader loader2; - COLLADAFW::Root root2(&loader2, this); - - if (!root2.loadDocument(encodedFilename)) { - fprintf(stderr, "COLLADAFW::Root::loadDocument() returned false on 2nd pass\n"); - delete ehandler; - return false; - } - - delete ehandler; - - return true; -} - -void DocumentImporter::cancel(const COLLADAFW::String &errorMessage) -{ - /* TODO: if possible show error info - * - * Should we get rid of invisible Meshes that were created so far - * or maybe create objects at coordinate space origin? - * - * The latter sounds better. */ -} - -void DocumentImporter::start() -{ -} - -void DocumentImporter::finish() -{ - if (mImportStage == Fetching_Controller_data) { - return; - } - - Main *bmain = CTX_data_main(mContext); - /* TODO: create a new scene except the selected <visual_scene> - - * use current blender scene for it */ - Scene *sce = CTX_data_scene(mContext); - unit_converter.calculate_scale(*sce); - - std::vector<Object *> *objects_to_scale = new std::vector<Object *>(); - - /** TODO Break up and put into 2-pass parsing of DAE */ - std::vector<const COLLADAFW::VisualScene *>::iterator sit; - for (sit = vscenes.begin(); sit != vscenes.end(); sit++) { - PointerRNA sceneptr, unit_settings; - PropertyRNA *system, *scale; - - /* for scene unit settings: system, scale_length */ - - RNA_id_pointer_create(&sce->id, &sceneptr); - unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); - system = RNA_struct_find_property(&unit_settings, "system"); - scale = RNA_struct_find_property(&unit_settings, "scale_length"); - - if (this->import_settings->import_units) { - - switch (unit_converter.isMetricSystem()) { - case UnitConverter::Metric: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); - break; - case UnitConverter::Imperial: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); - break; - default: - RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); - break; - } - float unit_factor = unit_converter.getLinearMeter(); - RNA_property_float_set(&unit_settings, scale, unit_factor); - fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor); - } - - /* Write nodes to scene */ - fprintf(stderr, "+-- Import Scene --------\n"); - const COLLADAFW::NodePointerArray &roots = (*sit)->getRootNodes(); - for (unsigned int i = 0; i < roots.getCount(); i++) { - std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false); - objects_to_scale->insert( - objects_to_scale->end(), objects_done->begin(), objects_done->end()); - delete objects_done; - } - } - - mesh_importer.optimize_material_assignements(); - - armature_importer.set_tags_map(this->uid_tags_map); - armature_importer.make_armatures(mContext, *objects_to_scale); - armature_importer.make_shape_keys(mContext); - -#if 0 - armature_importer.fix_animation(); -#endif - - for (std::vector<const COLLADAFW::VisualScene *>::iterator vsit = vscenes.begin(); - vsit != vscenes.end(); - vsit++) { - const COLLADAFW::NodePointerArray &roots = (*vsit)->getRootNodes(); - - for (unsigned int i = 0; i < roots.getCount(); i++) { - translate_anim_recursive(roots[i], NULL, NULL); - } - } - - if (libnode_ob.size()) { - - fprintf(stderr, "| Cleanup: free %d library nodes\n", (int)libnode_ob.size()); - /* free all library_nodes */ - std::vector<Object *>::iterator it; - for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { - Object *ob = *it; - BKE_scene_collections_object_remove(bmain, sce, ob, true); - } - libnode_ob.clear(); - } - - bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units); - - delete objects_to_scale; - - /* update scene */ - DEG_id_tag_update(&sce->id, ID_RECALC_COPY_ON_WRITE); - DEG_relations_tag_update(bmain); - WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL); -} - -void DocumentImporter::translate_anim_recursive(COLLADAFW::Node *node, - COLLADAFW::Node *par = NULL, - Object *parob = NULL) -{ - /* The split in #29246, rootmap must point at actual root when - * calculating bones in apply_curves_as_matrix. - actual root is the root node. - * This has to do with inverse bind poses being world space - * (the sources for skinned bones' restposes) and the way - * non-skinning nodes have their "restpose" recursively calculated. - * XXX TODO: design issue, how to support unrelated joints taking - * part in skinning. */ - if (par) { // && par->getType() == COLLADAFW::Node::JOINT) { - /* par is root if there's no corresp. key in root_map */ - if (root_map.find(par->getUniqueId()) == root_map.end()) { - root_map[node->getUniqueId()] = node; - } - else { - root_map[node->getUniqueId()] = root_map[par->getUniqueId()]; - } - } - -#if 0 - COLLADAFW::Transformation::TransformationType types[] = { - COLLADAFW::Transformation::ROTATE, - COLLADAFW::Transformation::SCALE, - COLLADAFW::Transformation::TRANSLATE, - COLLADAFW::Transformation::MATRIX, - }; - - Object *ob; -#endif - unsigned int i; - - if (node->getType() == COLLADAFW::Node::JOINT && par == NULL) { - /* For Skeletons without root node we have to simulate the - * root node here and recursively enter the same function - * XXX: maybe this can be made more elegant. */ - translate_anim_recursive(node, node, parob); - } - else { - anim_importer.translate_Animations( - node, root_map, object_map, FW_object_map, uid_material_map); - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (i = 0; i < children.getCount(); i++) { - translate_anim_recursive(children[i], node, NULL); - } - } -} - -/** - * If the imported file was made with Blender, return the Blender version used, - * otherwise return an empty std::string - */ -std::string DocumentImporter::get_import_version(const COLLADAFW::FileInfo *asset) -{ - const char AUTORING_TOOL[] = "authoring_tool"; - const std::string BLENDER("Blender "); - const COLLADAFW::FileInfo::ValuePairPointerArray &valuePairs = asset->getValuePairArray(); - for (size_t i = 0, count = valuePairs.getCount(); i < count; i++) { - const COLLADAFW::FileInfo::ValuePair *valuePair = valuePairs[i]; - const COLLADAFW::String &key = valuePair->first; - const COLLADAFW::String &value = valuePair->second; - if (key == AUTORING_TOOL) { - if (value.compare(0, BLENDER.length(), BLENDER) == 0) { - /* Was made with Blender, now get version string */ - std::string v = value.substr(BLENDER.length()); - std::string::size_type n = v.find(" "); - if (n > 0) { - return v.substr(0, n); - } - } - } - } - return ""; -} - -/** - * When this method is called, the writer must write the global document asset. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeGlobalAsset(const COLLADAFW::FileInfo *asset) -{ - unit_converter.read_asset(asset); - import_from_version = get_import_version(asset); - anim_importer.set_import_from_version(import_from_version); - return true; -} - -/** - * When this method is called, the writer must write the scene. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeScene(const COLLADAFW::Scene *scene) -{ - /* XXX could store the scene id, but do nothing for now */ - return true; -} -Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera, Scene *sce) -{ - const COLLADAFW::UniqueId &cam_uid = camera->getInstanciatedObjectId(); - if (uid_camera_map.find(cam_uid) == uid_camera_map.end()) { - // fprintf(stderr, "Couldn't find camera by UID.\n"); - return NULL; - } - - Main *bmain = CTX_data_main(mContext); - Object *ob = bc_add_object(bmain, sce, view_layer, OB_CAMERA, NULL); - Camera *cam = uid_camera_map[cam_uid]; - Camera *old_cam = (Camera *)ob->data; - ob->data = cam; - BKE_id_free_us(bmain, old_cam); - return ob; -} - -Object *DocumentImporter::create_light_object(COLLADAFW::InstanceLight *lamp, Scene *sce) -{ - const COLLADAFW::UniqueId &lamp_uid = lamp->getInstanciatedObjectId(); - if (uid_light_map.find(lamp_uid) == uid_light_map.end()) { - fprintf(stderr, "Couldn't find light by UID.\n"); - return NULL; - } - - Main *bmain = CTX_data_main(mContext); - Object *ob = bc_add_object(bmain, sce, view_layer, OB_LAMP, NULL); - Light *la = uid_light_map[lamp_uid]; - Light *old_light = (Light *)ob->data; - ob->data = la; - BKE_id_free_us(bmain, old_light); - return ob; -} - -Object *DocumentImporter::create_instance_node(Object *source_ob, - COLLADAFW::Node *source_node, - COLLADAFW::Node *instance_node, - Scene *sce, - bool is_library_node) -{ - // fprintf(stderr, "create <instance_node> under node id=%s from node id=%s\n", instance_node ? - // instance_node->getOriginalId().c_str() : NULL, source_node ? - // source_node->getOriginalId().c_str() : NULL); - - Main *bmain = CTX_data_main(mContext); - Object *obn = BKE_object_copy(bmain, source_ob); - DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); - BKE_collection_object_add_from(bmain, sce, source_ob, obn); - - if (instance_node) { - anim_importer.read_node_transform(instance_node, obn); - /* if we also have a source_node (always ;), take its - * transformation matrix and apply it to the newly instantiated - * object to account for node hierarchy transforms in - * .dae */ - if (source_node) { - COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); - COLLADABU::Math::Matrix4 bmat4 = - mat4.transpose(); // transpose to get blender row-major order - float mat[4][4]; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - mat[i][j] = bmat4[i][j]; - } - } - /* calc new matrix and apply */ - mul_m4_m4m4(obn->obmat, obn->obmat, mat); - BKE_object_apply_mat4(obn, obn->obmat, 0, 0); - } - } - else { - anim_importer.read_node_transform(source_node, obn); - } - - /*DAG_relations_tag_update(CTX_data_main(mContext));*/ - - COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); - if (children.getCount()) { - for (unsigned int i = 0; i < children.getCount(); i++) { - COLLADAFW::Node *child_node = children[i]; - const COLLADAFW::UniqueId &child_id = child_node->getUniqueId(); - if (object_map.find(child_id) == object_map.end()) { - continue; - } - COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); - Object *new_child = NULL; - if (inodes.getCount()) { // \todo loop through instance nodes - const COLLADAFW::UniqueId &id = inodes[0]->getInstanciatedObjectId(); - fprintf(stderr, "Doing %d child nodes\n", (int)node_map.count(id)); - new_child = create_instance_node( - object_map.find(id)->second, node_map[id], child_node, sce, is_library_node); - } - else { - new_child = create_instance_node( - object_map.find(child_id)->second, child_node, NULL, sce, is_library_node); - } - bc_set_parent(new_child, obn, mContext, true); - - if (is_library_node) { - libnode_ob.push_back(new_child); - } - } - } - - return obn; -} - -/* to create constraints off node <extra> tags. Assumes only constraint data in - * current <extra> with blender profile. */ -void DocumentImporter::create_constraints(ExtraTags *et, Object *ob) -{ - if (et && et->isProfile("blender")) { - std::string name; - short type = 0; - et->setData("type", &type); - BKE_constraint_add_for_object(ob, "Test_con", type); - } -} - -void DocumentImporter::report_unknown_reference(const COLLADAFW::Node &node, - const std::string object_type) -{ - std::string id = node.getOriginalId(); - std::string name = node.getName(); - fprintf(stderr, - "error: node id=\"%s\", name=\"%s\" refers to an undefined %s.\n", - id.c_str(), - name.c_str(), - object_type.c_str()); -} - -std::vector<Object *> *DocumentImporter::write_node(COLLADAFW::Node *node, - COLLADAFW::Node *parent_node, - Scene *sce, - Object *par, - bool is_library_node) -{ - Main *bmain = CTX_data_main(mContext); - Object *ob = NULL; - bool is_joint = node->getType() == COLLADAFW::Node::JOINT; - bool read_transform = true; - std::string id = node->getOriginalId(); - std::string name = node->getName(); - - /* if node has child nodes write them */ - COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); - - std::vector<Object *> *objects_done = new std::vector<Object *>(); - std::vector<Object *> *root_objects = new std::vector<Object *>(); - - fprintf( - stderr, "| %s id='%s', name='%s'\n", is_joint ? "JOINT" : "NODE ", id.c_str(), name.c_str()); - - if (is_joint) { - if (parent_node == NULL && !is_library_node) { - /* A Joint on root level is a skeleton without root node. - * Here we add the armature "on the fly": */ - par = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, std::string("Armature").c_str()); - objects_done->push_back(par); - root_objects->push_back(par); - object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), par)); - node_map[node->getUniqueId()] = node; - } - if (parent_node == NULL || parent_node->getType() != COLLADAFW::Node::JOINT) { - armature_importer.add_root_joint(node, par); - } - - if (parent_node == NULL) { - /* for skeletons without root node all has been done above. - * Skeletons with root node are handled further down. */ - goto finally; - } - } - else { - COLLADAFW::InstanceGeometryPointerArray &geom = node->getInstanceGeometries(); - COLLADAFW::InstanceCameraPointerArray &camera = node->getInstanceCameras(); - COLLADAFW::InstanceLightPointerArray &lamp = node->getInstanceLights(); - COLLADAFW::InstanceControllerPointerArray &controller = node->getInstanceControllers(); - COLLADAFW::InstanceNodePointerArray &inst_node = node->getInstanceNodes(); - size_t geom_done = 0; - size_t camera_done = 0; - size_t lamp_done = 0; - size_t controller_done = 0; - size_t inst_done = 0; - - /* XXX linking object with the first <instance_geometry>, though a node may have more of - * them... maybe join multiple <instance_...> meshes into 1, and link object with it? not - * sure... <instance_geometry> */ - while (geom_done < geom.getCount()) { - ob = mesh_importer.create_mesh_object(node, geom[geom_done], false, uid_material_map); - if (ob == NULL) { - report_unknown_reference(*node, "instance_mesh"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - geom_done++; - } - while (camera_done < camera.getCount()) { - ob = create_camera_object(camera[camera_done], sce); - if (ob == NULL) { - report_unknown_reference(*node, "instance_camera"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - camera_done++; - } - while (lamp_done < lamp.getCount()) { - ob = create_light_object(lamp[lamp_done], sce); - if (ob == NULL) { - report_unknown_reference(*node, "instance_light"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - lamp_done++; - } - while (controller_done < controller.getCount()) { - COLLADAFW::InstanceGeometry *geometry = (COLLADAFW::InstanceGeometry *) - controller[controller_done]; - ob = mesh_importer.create_mesh_object(node, geometry, true, uid_material_map); - if (ob == NULL) { - report_unknown_reference(*node, "instance_controller"); - } - else { - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - controller_done++; - } - /* XXX instance_node is not supported yet */ - while (inst_done < inst_node.getCount()) { - const COLLADAFW::UniqueId &node_id = inst_node[inst_done]->getInstanciatedObjectId(); - if (object_map.find(node_id) == object_map.end()) { - fprintf(stderr, - "Cannot find object for node referenced by <instance_node name=\"%s\">.\n", - inst_node[inst_done]->getName().c_str()); - ob = NULL; - } - else { - std::pair<std::multimap<COLLADAFW::UniqueId, Object *>::iterator, - std::multimap<COLLADAFW::UniqueId, Object *>::iterator> - pair_iter = object_map.equal_range(node_id); - for (std::multimap<COLLADAFW::UniqueId, Object *>::iterator it2 = pair_iter.first; - it2 != pair_iter.second; - it2++) { - Object *source_ob = (Object *)it2->second; - COLLADAFW::Node *source_node = node_map[node_id]; - ob = create_instance_node(source_ob, source_node, node, sce, is_library_node); - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - } - inst_done++; - - read_transform = false; - } - - /* if node is empty - create empty object - * XXX empty node may not mean it is empty object, not sure about this */ - if ((geom_done + camera_done + lamp_done + controller_done + inst_done) < 1) { - /* Check if Object is armature, by checking if immediate child is a JOINT node. */ - if (is_armature(node)) { - ob = bc_add_object(bmain, sce, view_layer, OB_ARMATURE, name.c_str()); - } - else { - ob = bc_add_object(bmain, sce, view_layer, OB_EMPTY, NULL); - } - objects_done->push_back(ob); - if (parent_node == NULL) { - root_objects->push_back(ob); - } - } - - /* XXX: if there're multiple instances, only one is stored */ - - if (!ob) { - goto finally; - } - - for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); - ++it) { - ob = *it; - std::string nodename = node->getName().size() ? node->getName() : node->getOriginalId(); - BKE_libblock_rename(bmain, &ob->id, (char *)nodename.c_str()); - object_map.insert(std::pair<COLLADAFW::UniqueId, Object *>(node->getUniqueId(), ob)); - node_map[node->getUniqueId()] = node; - - if (is_library_node) { - libnode_ob.push_back(ob); - } - } - - // create_constraints(et,ob); - } - - for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); - ++it) { - ob = *it; - - if (read_transform) { - anim_importer.read_node_transform(node, ob); // overwrites location set earlier - } - - if (!is_joint) { - if (par && ob) { - ob->parent = par; - ob->partype = PAROBJECT; - ob->parsubstr[0] = 0; - - // bc_set_parent(ob, par, mContext, false); - } - } - } - - if (objects_done->size() > 0) { - ob = *objects_done->begin(); - } - else { - ob = NULL; - } - - for (unsigned int i = 0; i < child_nodes.getCount(); i++) { - std::vector<Object *> *child_objects; - child_objects = write_node(child_nodes[i], node, sce, ob, is_library_node); - delete child_objects; - } - -finally: - delete objects_done; - - return root_objects; -} - -/** - * When this method is called, the writer must write the entire visual scene. - * Return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeVisualScene(const COLLADAFW::VisualScene *visualScene) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - /* This method called on post process after writeGeometry, writeMaterial, etc. */ - - /* For each <node> in <visual_scene>: - * create an Object - * if Mesh (previously created in writeGeometry) to which <node> corresponds exists, - * link Object with that mesh. - * - * Update: since we cannot link a Mesh with Object in - * writeGeometry because <geometry> does not reference <node>, - * we link Objects with Meshes here. - */ - vscenes.push_back(visualScene); - - return true; -} - -/** - * When this method is called, the writer must handle all nodes contained in the - * library nodes. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeLibraryNodes(const COLLADAFW::LibraryNodes *libraryNodes) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - Scene *sce = CTX_data_scene(mContext); - - const COLLADAFW::NodePointerArray &nodes = libraryNodes->getNodes(); - - fprintf(stderr, "+-- Read Library nodes ----------\n"); - for (unsigned int i = 0; i < nodes.getCount(); i++) { - std::vector<Object *> *child_objects; - child_objects = write_node(nodes[i], NULL, sce, NULL, true); - delete child_objects; - } - return true; -} - -/** - * When this method is called, the writer must write the geometry. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeGeometry(const COLLADAFW::Geometry *geom) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - return mesh_importer.write_geometry(geom); -} - -/** - * When this method is called, the writer must write the material. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeMaterial(const COLLADAFW::Material *cmat) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - Main *bmain = CTX_data_main(mContext); - const std::string &str_mat_id = cmat->getName().size() ? cmat->getName() : cmat->getOriginalId(); - Material *ma = BKE_material_add(bmain, (char *)str_mat_id.c_str()); - - this->uid_effect_map[cmat->getInstantiatedEffect()] = ma; - this->uid_material_map[cmat->getUniqueId()] = ma; - - return true; -} - -void DocumentImporter::write_profile_COMMON(COLLADAFW::EffectCommon *ef, Material *ma) -{ - MaterialNode matNode = MaterialNode(mContext, ef, ma, uid_image_map); - - /* Direct mapping to principled BSDF Shader */ - matNode.set_diffuse(ef->getDiffuse()); - matNode.set_emission(ef->getEmission()); - matNode.set_ior(ef->getIndexOfRefraction()); - matNode.set_alpha(ef->getOpaqueMode(), ef->getTransparent(), ef->getTransparency()); - - /* following mapping still needs to be verified */ -#if 0 - // needs rework to be done for 2.81 - matNode.set_shininess(ef->getShininess()); -#endif - matNode.set_reflectivity(ef->getReflectivity()); - - /* not supported by principled BSDF */ - matNode.set_ambient(ef->getAmbient()); - matNode.set_specular(ef->getSpecular()); - matNode.set_reflective(ef->getReflective()); -} - -/** - * When this method is called, the writer must write the effect. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeEffect(const COLLADAFW::Effect *effect) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - const COLLADAFW::UniqueId &uid = effect->getUniqueId(); - - if (uid_effect_map.find(uid) == uid_effect_map.end()) { - fprintf(stderr, "Couldn't find a material by UID.\n"); - return true; - } - - Material *ma = uid_effect_map[uid]; - std::map<COLLADAFW::UniqueId, Material *>::iterator iter; - for (iter = uid_material_map.begin(); iter != uid_material_map.end(); iter++) { - if (iter->second == ma) { - this->FW_object_map[iter->first] = effect; - break; - } - } - COLLADAFW::CommonEffectPointerArray common_efs = effect->getCommonEffects(); - if (common_efs.getCount() < 1) { - fprintf(stderr, "Couldn't find <profile_COMMON>.\n"); - return true; - } - /* XXX TODO: Take all <profile_common>s - * Currently only first <profile_common> is supported */ - COLLADAFW::EffectCommon *ef = common_efs[0]; - write_profile_COMMON(ef, ma); - this->FW_object_map[effect->getUniqueId()] = effect; - - return true; -} - -/** - * When this method is called, the writer must write the camera. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeCamera(const COLLADAFW::Camera *camera) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - Main *bmain = CTX_data_main(mContext); - Camera *cam = NULL; - std::string cam_id, cam_name; - - ExtraTags *et = getExtraTags(camera->getUniqueId()); - cam_id = camera->getOriginalId(); - cam_name = camera->getName(); - if (cam_name.size()) { - cam = (Camera *)BKE_camera_add(bmain, (char *)cam_name.c_str()); - } - else { - cam = (Camera *)BKE_camera_add(bmain, (char *)cam_id.c_str()); - } - - if (!cam) { - fprintf(stderr, "Cannot create camera.\n"); - return true; - } - - if (et && et->isProfile("blender")) { - et->setData("shiftx", &(cam->shiftx)); - et->setData("shifty", &(cam->shifty)); - et->setData("dof_distance", &(cam->dof.focus_distance)); - } - cam->clip_start = camera->getNearClippingPlane().getValue(); - cam->clip_end = camera->getFarClippingPlane().getValue(); - - COLLADAFW::Camera::CameraType type = camera->getCameraType(); - switch (type) { - case COLLADAFW::Camera::ORTHOGRAPHIC: { - cam->type = CAM_ORTHO; - } break; - case COLLADAFW::Camera::PERSPECTIVE: { - cam->type = CAM_PERSP; - } break; - case COLLADAFW::Camera::UNDEFINED_CAMERATYPE: { - fprintf(stderr, "Current camera type is not supported.\n"); - cam->type = CAM_PERSP; - } break; - } - - switch (camera->getDescriptionType()) { - case COLLADAFW::Camera::ASPECTRATIO_AND_Y: { - switch (cam->type) { - case CAM_ORTHO: { - double ymag = 2 * camera->getYMag().getValue(); - double aspect = camera->getAspectRatio().getValue(); - double xmag = aspect * ymag; - cam->ortho_scale = (float)xmag; - } break; - case CAM_PERSP: - default: { - double yfov = camera->getYFov().getValue(); - double aspect = camera->getAspectRatio().getValue(); - - /* NOTE: Needs more testing (As we currently have no official test data for this) */ - - double xfov = 2.0f * atanf(aspect * tanf(DEG2RADF(yfov) * 0.5f)); - cam->lens = fov_to_focallength(xfov, cam->sensor_x); - } break; - } - } break; - /* XXX correct way to do following four is probably to get also render - * size and determine proper settings from that somehow */ - case COLLADAFW::Camera::ASPECTRATIO_AND_X: - case COLLADAFW::Camera::SINGLE_X: - case COLLADAFW::Camera::X_AND_Y: { - switch (cam->type) { - case CAM_ORTHO: - cam->ortho_scale = (float)camera->getXMag().getValue() * 2; - break; - case CAM_PERSP: - default: { - double x = camera->getXFov().getValue(); - /* x is in degrees, cam->lens is in millimiters */ - cam->lens = fov_to_focallength(DEG2RADF(x), cam->sensor_x); - } break; - } - } break; - case COLLADAFW::Camera::SINGLE_Y: { - switch (cam->type) { - case CAM_ORTHO: - cam->ortho_scale = (float)camera->getYMag().getValue(); - break; - case CAM_PERSP: - default: { - double yfov = camera->getYFov().getValue(); - /* yfov is in degrees, cam->lens is in millimiters */ - cam->lens = fov_to_focallength(DEG2RADF(yfov), cam->sensor_x); - } break; - } - } break; - case COLLADAFW::Camera::UNDEFINED: - /* read nothing, use blender defaults. */ - break; - } - - this->uid_camera_map[camera->getUniqueId()] = cam; - this->FW_object_map[camera->getUniqueId()] = camera; - /* XXX import camera options */ - return true; -} - -/** - * When this method is called, the writer must write the image. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeImage(const COLLADAFW::Image *image) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - const std::string &imagepath = image->getImageURI().toNativePath(); - - char dir[FILE_MAX]; - char absolute_path[FILE_MAX]; - const char *workpath; - - BLI_split_dir_part(this->import_settings->filepath, dir, sizeof(dir)); - BLI_join_dirfile(absolute_path, sizeof(absolute_path), dir, imagepath.c_str()); - if (BLI_exists(absolute_path)) { - workpath = absolute_path; - } - else { - /* Maybe imagepath was already absolute ? */ - if (!BLI_exists(imagepath.c_str())) { - fprintf(stderr, "|! Image not found: %s\n", imagepath.c_str()); - return true; - } - workpath = imagepath.c_str(); - } - - Image *ima = BKE_image_load_exists(CTX_data_main(mContext), workpath); - if (!ima) { - fprintf(stderr, "|! Cannot create image: %s\n", workpath); - return true; - } - this->uid_image_map[image->getUniqueId()] = ima; - fprintf(stderr, "| import Image: %s\n", workpath); - return true; -} - -/** - * When this method is called, the writer must write the light. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeLight(const COLLADAFW::Light *light) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - Main *bmain = CTX_data_main(mContext); - Light *lamp = NULL; - std::string la_id, la_name; - - ExtraTags *et = getExtraTags(light->getUniqueId()); -#if 0 - TagsMap::iterator etit; - ExtraTags *et = 0; - etit = uid_tags_map.find(light->getUniqueId().toAscii()); - if (etit != uid_tags_map.end()) { - et = etit->second; - } -#endif - - la_id = light->getOriginalId(); - la_name = light->getName(); - if (la_name.size()) { - lamp = (Light *)BKE_light_add(bmain, (char *)la_name.c_str()); - } - else { - lamp = (Light *)BKE_light_add(bmain, (char *)la_id.c_str()); - } - - if (!lamp) { - fprintf(stderr, "Cannot create light.\n"); - return true; - } - - /* if we find an ExtraTags for this, use that instead. */ - if (et && et->isProfile("blender")) { - et->setData("type", &(lamp->type)); - et->setData("flag", &(lamp->flag)); - et->setData("mode", &(lamp->mode)); - et->setData("gamma", &(lamp->k)); - et->setData("red", &(lamp->r)); - et->setData("green", &(lamp->g)); - et->setData("blue", &(lamp->b)); - et->setData("shadow_r", &(lamp->shdwr)); - et->setData("shadow_g", &(lamp->shdwg)); - et->setData("shadow_b", &(lamp->shdwb)); - et->setData("energy", &(lamp->energy)); - et->setData("dist", &(lamp->dist)); - et->setData("spotsize", &(lamp->spotsize)); - lamp->spotsize = DEG2RADF(lamp->spotsize); - et->setData("spotblend", &(lamp->spotblend)); - et->setData("att1", &(lamp->att1)); - et->setData("att2", &(lamp->att2)); - et->setData("falloff_type", &(lamp->falloff_type)); - et->setData("clipsta", &(lamp->clipsta)); - et->setData("clipend", &(lamp->clipend)); - et->setData("bias", &(lamp->bias)); - et->setData("soft", &(lamp->soft)); - et->setData("bufsize", &(lamp->bufsize)); - et->setData("buffers", &(lamp->buffers)); - et->setData("area_shape", &(lamp->area_shape)); - et->setData("area_size", &(lamp->area_size)); - et->setData("area_sizey", &(lamp->area_sizey)); - et->setData("area_sizez", &(lamp->area_sizez)); - } - else { - float constatt = light->getConstantAttenuation().getValue(); - float linatt = light->getLinearAttenuation().getValue(); - float quadatt = light->getQuadraticAttenuation().getValue(); - float d = 25.0f; - float att1 = 0.0f; - float att2 = 0.0f; - float e = 1.0f; - - if (light->getColor().isValid()) { - COLLADAFW::Color col = light->getColor(); - lamp->r = col.getRed(); - lamp->g = col.getGreen(); - lamp->b = col.getBlue(); - } - - if (IS_EQ(linatt, 0.0f) && quadatt > 0.0f) { - att2 = quadatt; - d = sqrt(1.0f / quadatt); - } - /* linear light */ - else if (IS_EQ(quadatt, 0.0f) && linatt > 0.0f) { - att1 = linatt; - d = (1.0f / linatt); - } - else if (IS_EQ(constatt, 1.0f)) { - att1 = 1.0f; - } - else { - /* assuming point light (const att = 1.0); */ - att1 = 1.0f; - } - - d *= (1.0f / unit_converter.getLinearMeter()); - - lamp->energy = e; - lamp->dist = d; - - switch (light->getLightType()) { - case COLLADAFW::Light::AMBIENT_LIGHT: { - lamp->type = LA_SUN; // TODO needs more thoughts - } break; - case COLLADAFW::Light::SPOT_LIGHT: { - lamp->type = LA_SPOT; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) { - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - } - if (IS_EQ(att2, 0.0f) && att1 > 0) { - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - } - lamp->spotsize = DEG2RADF(light->getFallOffAngle().getValue()); - lamp->spotblend = light->getFallOffExponent().getValue(); - } break; - case COLLADAFW::Light::DIRECTIONAL_LIGHT: { - /* our sun is very strong, so pick a smaller energy level */ - lamp->type = LA_SUN; - } break; - case COLLADAFW::Light::POINT_LIGHT: { - lamp->type = LA_LOCAL; - lamp->att1 = att1; - lamp->att2 = att2; - if (IS_EQ(att1, 0.0f) && att2 > 0) { - lamp->falloff_type = LA_FALLOFF_INVSQUARE; - } - if (IS_EQ(att2, 0.0f) && att1 > 0) { - lamp->falloff_type = LA_FALLOFF_INVLINEAR; - } - } break; - case COLLADAFW::Light::UNDEFINED: { - fprintf(stderr, "Current light type is not supported.\n"); - lamp->type = LA_LOCAL; - } break; - } - } - - this->uid_light_map[light->getUniqueId()] = lamp; - this->FW_object_map[light->getUniqueId()] = light; - return true; -} - -/* this function is called only for animations that pass COLLADAFW::validate */ -bool DocumentImporter::writeAnimation(const COLLADAFW::Animation *anim) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - return anim_importer.write_animation(anim); -} - -/* called on post-process stage after writeVisualScenes */ -bool DocumentImporter::writeAnimationList(const COLLADAFW::AnimationList *animationList) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - /* return true; */ - return anim_importer.write_animation_list(animationList); -} - -#if WITH_OPENCOLLADA_ANIMATION_CLIP -/* Since opencollada 1.6.68 - * called on post-process stage after writeVisualScenes */ -bool DocumentImporter::writeAnimationClip(const COLLADAFW::AnimationClip *animationClip) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - return true; - /* TODO: implement import of AnimationClips */ - // return animation_clip_importer.write_animation_clip(animationClip); -} -#endif - -/** - * When this method is called, the writer must write the skin controller data. - * \return The writer should return true, if writing succeeded, false otherwise. - */ -bool DocumentImporter::writeSkinControllerData(const COLLADAFW::SkinControllerData *skin) -{ - return armature_importer.write_skin_controller_data(skin); -} - -/* this is called on postprocess, before writeVisualScenes */ -bool DocumentImporter::writeController(const COLLADAFW::Controller *controller) -{ - if (mImportStage == Fetching_Controller_data) { - return true; - } - - return armature_importer.write_controller(controller); -} - -bool DocumentImporter::writeFormulas(const COLLADAFW::Formulas *formulas) -{ - return true; -} - -bool DocumentImporter::writeKinematicsScene(const COLLADAFW::KinematicsScene *kinematicsScene) -{ - return true; -} - -ExtraTags *DocumentImporter::getExtraTags(const COLLADAFW::UniqueId &uid) -{ - if (uid_tags_map.find(uid.toAscii()) == uid_tags_map.end()) { - return NULL; - } - return uid_tags_map[uid.toAscii()]; -} - -bool DocumentImporter::addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags) -{ - uid_tags_map[uid.toAscii()] = extra_tags; - return true; -} - -bool DocumentImporter::is_armature(COLLADAFW::Node *node) -{ - COLLADAFW::NodePointerArray &child_nodes = node->getChildNodes(); - for (unsigned int i = 0; i < child_nodes.getCount(); i++) { - if (child_nodes[i]->getType() == COLLADAFW::Node::JOINT) { - return true; - } - else { - continue; - } - } - - /* no child is JOINT */ - return false; -} diff --git a/source/blender/collada/DocumentImporter.h b/source/blender/collada/DocumentImporter.h deleted file mode 100644 index e47c844f7c6..00000000000 --- a/source/blender/collada/DocumentImporter.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __DOCUMENTIMPORTER_H__ -#define __DOCUMENTIMPORTER_H__ - -#include "COLLADAFWIWriter.h" -#include "COLLADAFWMaterial.h" -#include "COLLADAFWEffect.h" -#include "COLLADAFWColor.h" -#include "COLLADAFWImage.h" -#include "COLLADAFWInstanceGeometry.h" -#include "COLLADAFWController.h" -#include "COLLADAFWMorphController.h" -#include "COLLADAFWSkinController.h" -#include "COLLADAFWEffectCommon.h" - -#include "BKE_object.h" -#include "BKE_constraint.h" - -#include "TransformReader.h" -#include "AnimationImporter.h" -#include "ArmatureImporter.h" -#include "ControllerExporter.h" -#include "MeshImporter.h" -#include "ImportSettings.h" - -struct bContext; - -/** Importer class. */ -class DocumentImporter : COLLADAFW::IWriter { - public: - //! Enumeration to denote the stage of import - enum ImportStage { - Fetching_Scene_data, /* First pass to collect all data except controller */ - Fetching_Controller_data, /* Second pass to collect controller data */ - }; - /** Constructor */ - DocumentImporter(bContext *C, const ImportSettings *import_settings); - - /** Destructor */ - ~DocumentImporter(); - - /** Function called by blender UI */ - bool import(); - - /** these should not be here */ - Object *create_camera_object(COLLADAFW::InstanceCamera *, Scene *); - Object *create_light_object(COLLADAFW::InstanceLight *, Scene *); - Object *create_instance_node(Object *, COLLADAFW::Node *, COLLADAFW::Node *, Scene *, bool); - void create_constraints(ExtraTags *et, Object *ob); - std::vector<Object *> *write_node(COLLADAFW::Node *, COLLADAFW::Node *, Scene *, Object *, bool); - void write_profile_COMMON(COLLADAFW::EffectCommon *, Material *); - - void translate_anim_recursive(COLLADAFW::Node *, COLLADAFW::Node *, Object *); - - /** - * This method will be called if an error in the loading process occurred and the loader cannot - * continue to load. The writer should undo all operations that have been performed. - * \param errorMessage: A message containing information about the error that occurred. - */ - void cancel(const COLLADAFW::String &errorMessage); - - /** This is the method called. The writer hast to prepare to receive data.*/ - void start(); - - /** This method is called after the last write* method. No other methods will be called after - * this.*/ - void finish(); - - bool writeGlobalAsset(const COLLADAFW::FileInfo *); - std::string get_import_version(const COLLADAFW::FileInfo *asset); - - bool writeScene(const COLLADAFW::Scene *); - - bool writeVisualScene(const COLLADAFW::VisualScene *); - - bool writeLibraryNodes(const COLLADAFW::LibraryNodes *); - - bool writeAnimation(const COLLADAFW::Animation *); - - bool writeAnimationList(const COLLADAFW::AnimationList *); - -#if WITH_OPENCOLLADA_ANIMATION_CLIP - // Please enable this when building with Collada 1.6.65 or newer (also in DocumentImporter.cpp) - bool writeAnimationClip(const COLLADAFW::AnimationClip *animationClip); -#endif - - bool writeGeometry(const COLLADAFW::Geometry *); - - bool writeMaterial(const COLLADAFW::Material *); - - bool writeEffect(const COLLADAFW::Effect *); - - bool writeCamera(const COLLADAFW::Camera *); - - bool writeImage(const COLLADAFW::Image *); - - bool writeLight(const COLLADAFW::Light *); - - bool writeSkinControllerData(const COLLADAFW::SkinControllerData *); - - bool writeController(const COLLADAFW::Controller *); - - bool writeFormulas(const COLLADAFW::Formulas *); - - bool writeKinematicsScene(const COLLADAFW::KinematicsScene *); - - /** Add element and data for UniqueId */ - bool addExtraTags(const COLLADAFW::UniqueId &uid, ExtraTags *extra_tags); - /** Get an extisting ExtraTags for uid */ - ExtraTags *getExtraTags(const COLLADAFW::UniqueId &uid); - - bool is_armature(COLLADAFW::Node *node); - - private: - const ImportSettings *import_settings; - - /** Current import stage we're in. */ - ImportStage mImportStage; - - bContext *mContext; - ViewLayer *view_layer; - - UnitConverter unit_converter; - ArmatureImporter armature_importer; - MeshImporter mesh_importer; - AnimationImporter anim_importer; - - /** TagsMap typedef for uid_tags_map. */ - typedef std::map<std::string, ExtraTags *> TagsMap; - /** Tags map of unique id as a string and ExtraTags instance. */ - TagsMap uid_tags_map; - - UidImageMap uid_image_map; - std::map<COLLADAFW::UniqueId, Material *> uid_material_map; - std::map<COLLADAFW::UniqueId, Material *> uid_effect_map; - std::map<COLLADAFW::UniqueId, Camera *> uid_camera_map; - std::map<COLLADAFW::UniqueId, Light *> uid_light_map; - std::map<Material *, TexIndexTextureArrayMap> material_texture_mapping_map; - std::multimap<COLLADAFW::UniqueId, Object *> object_map; - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> node_map; - std::vector<const COLLADAFW::VisualScene *> vscenes; - std::vector<Object *> libnode_ob; - - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> - root_map; // find root joint by child joint uid, for bone tree evaluation during resampling - std::map<COLLADAFW::UniqueId, const COLLADAFW::Object *> FW_object_map; - - std::string import_from_version; - - void report_unknown_reference(const COLLADAFW::Node &node, const std::string object_type); -}; - -#endif diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp deleted file mode 100644 index a1174fdff56..00000000000 --- a/source/blender/collada/EffectExporter.cpp +++ /dev/null @@ -1,312 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <map> -#include <set> - -#include "COLLADASWEffectProfile.h" -#include "COLLADAFWColorOrTexture.h" - -#include "EffectExporter.h" -#include "DocumentExporter.h" -#include "MaterialExporter.h" - -#include "collada_internal.h" -#include "collada_utils.h" - -extern "C" { -#include "DNA_mesh_types.h" -#include "DNA_world_types.h" - -#include "BKE_collection.h" -#include "BKE_customdata.h" -#include "BKE_mesh.h" -#include "BKE_material.h" -} - -static std::string getActiveUVLayerName(Object *ob) -{ - Mesh *me = (Mesh *)ob->data; - - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - if (num_layers) { - return std::string(bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV)); - } - - return ""; -} - -EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings, - KeyImageMap &key_image_map) - : COLLADASW::LibraryEffects(sw), export_settings(export_settings), key_image_map(key_image_map) -{ -} - -bool EffectsExporter::hasEffects(Scene *sce) -{ - FOREACH_SCENE_OBJECT_BEGIN (sce, ob) { - int a; - for (a = 0; a < ob->totcol; a++) { - Material *ma = BKE_object_material_get(ob, a + 1); - - // no material, but check all of the slots - if (!ma) { - continue; - } - - return true; - } - } - FOREACH_SCENE_OBJECT_END; - return false; -} - -void EffectsExporter::exportEffects(bContext *C, Scene *sce) -{ - if (hasEffects(sce)) { - this->mContext = C; - this->scene = sce; - openLibrary(); - MaterialFunctor mf; - mf.forEachMaterialInExportSet<EffectsExporter>( - sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); - } -} - -void EffectsExporter::set_shader_type(COLLADASW::EffectProfile &ep, Material *ma) -{ - /* XXX check if BLINN and PHONG can be supported as well */ - ep.setShaderType(COLLADASW::EffectProfile::LAMBERT); -} - -void EffectsExporter::set_transparency(COLLADASW::EffectProfile &ep, Material *ma) -{ - double alpha = bc_get_alpha(ma); - if (alpha < 1) { - // workaround use <transparent> to avoid wrong handling of <transparency> by other tools - COLLADASW::ColorOrTexture cot = bc_get_cot(0, 0, 0, alpha); - ep.setTransparent(cot, false, "alpha"); - ep.setOpaque(COLLADASW::EffectProfile::A_ONE); - } -} - -void EffectsExporter::set_diffuse_color(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot = bc_get_base_color(ma); - ep.setDiffuse(cot, false, "diffuse"); -} - -void EffectsExporter::set_ambient(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot = bc_get_ambient(ma); - ep.setAmbient(cot, false, "ambient"); -} -void EffectsExporter::set_specular(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot = bc_get_specular(ma); - ep.setSpecular(cot, false, "specular"); -} -void EffectsExporter::set_reflective(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot = bc_get_reflective(ma); - ep.setReflective(cot, false, "reflective"); -} - -void EffectsExporter::set_reflectivity(COLLADASW::EffectProfile &ep, Material *ma) -{ - double reflectivity = bc_get_reflectivity(ma); - if (reflectivity > 0.0) { - ep.setReflectivity(reflectivity, false, "specular"); - } -} - -void EffectsExporter::set_emission(COLLADASW::EffectProfile &ep, Material *ma) -{ - COLLADASW::ColorOrTexture cot = bc_get_emission(ma); - ep.setEmission(cot, false, "emission"); -} - -void EffectsExporter::set_ior(COLLADASW::EffectProfile &ep, Material *ma) -{ - double alpha = bc_get_ior(ma); - ep.setIndexOfRefraction(alpha, false, "ior"); -} - -void EffectsExporter::set_shininess(COLLADASW::EffectProfile &ep, Material *ma) -{ - double shininess = bc_get_shininess(ma); - ep.setShininess(shininess, false, "shininess"); -} - -void EffectsExporter::get_images(Material *ma, KeyImageMap &material_image_map) -{ - if (!ma->use_nodes) { - return; - } - - MaterialNode material = MaterialNode(mContext, ma, key_image_map); - Image *image = material.get_diffuse_image(); - if (image == nullptr) { - return; - } - - std::string uid(id_name(image)); - std::string key = translate_id(uid); - - if (material_image_map.find(key) == material_image_map.end()) { - material_image_map[key] = image; - key_image_map[key] = image; - } -} - -void EffectsExporter::create_image_samplers(COLLADASW::EffectProfile &ep, - KeyImageMap &material_image_map, - std::string &active_uv) -{ - KeyImageMap::iterator iter; - - for (iter = material_image_map.begin(); iter != material_image_map.end(); iter++) { - - Image *image = iter->second; - std::string uid(id_name(image)); - std::string key = translate_id(uid); - - COLLADASW::Sampler *sampler = new COLLADASW::Sampler( - COLLADASW::Sampler::SAMPLER_TYPE_2D, - key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, - key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); - - sampler->setImageId(key); - - ep.setDiffuse(createTexture(image, active_uv, sampler), false, "diffuse"); - } -} - -void EffectsExporter::operator()(Material *ma, Object *ob) -{ - KeyImageMap material_image_map; - - openEffect(get_effect_id(ma)); - - COLLADASW::EffectProfile ep(mSW); - ep.setProfileType(COLLADASW::EffectProfile::COMMON); - ep.openProfile(); - set_shader_type(ep, ma); // creates a Lambert Shader for now - - COLLADASW::ColorOrTexture cot; - - set_diffuse_color(ep, ma); - set_emission(ep, ma); - set_ior(ep, ma); - set_reflectivity(ep, ma); - set_transparency(ep, ma); - - /* TODO: */ - // set_shininess(ep, ma); shininess not supported for lambert - // set_ambient(ep, ma); - // set_specular(ep, ma); - - get_images(ma, material_image_map); - std::string active_uv(getActiveUVLayerName(ob)); - create_image_samplers(ep, material_image_map, active_uv); - -#if 0 - unsigned int a, b; - for (a = 0, b = 0; a < tex_indices.size(); a++) { - MTex *t = ma->mtex[tex_indices[a]]; - Image *ima = t->tex->ima; - - // Image not set for texture - if (!ima) { - continue; - } - - std::string key(id_name(ima)); - key = translate_id(key); - - // create only one <sampler>/<surface> pair for each unique image - if (im_samp_map.find(key) == im_samp_map.end()) { - //<newparam> <sampler> <source> - COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D, - key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX, - key + COLLADASW::Sampler::SURFACE_SID_SUFFIX); - sampler.setImageId(key); - // copy values to arrays since they will live longer - samplers[a] = sampler; - - // store pointers so they can be used later when we create <texture>s - samp_surf[b] = &samplers[a]; - //samp_surf[b][1] = &surfaces[a]; - - im_samp_map[key] = b; - b++; - } - } - - for (a = 0; a < tex_indices.size(); a++) { - MTex *t = ma->mtex[tex_indices[a]]; - Image *ima = t->tex->ima; - - if (!ima) { - continue; - } - - std::string key(id_name(ima)); - key = translate_id(key); - int i = im_samp_map[key]; - std::string uvname = strlen(t->uvname) ? t->uvname : active_uv; - COLLADASW::Sampler *sampler = (COLLADASW::Sampler *) - samp_surf[i]; // possibly uninitialized memory ... - writeTextures(ep, key, sampler, t, ima, uvname); - } -#endif - - // performs the actual writing - ep.addProfileElements(); - ep.addExtraTechniques(mSW); - - ep.closeProfile(); - closeEffect(); -} - -COLLADASW::ColorOrTexture EffectsExporter::createTexture(Image *ima, - std::string &uv_layer_name, - COLLADASW::Sampler *sampler - /*COLLADASW::Surface *surface*/) -{ - - COLLADASW::Texture texture(translate_id(id_name(ima))); - texture.setTexcoord(uv_layer_name); - // texture.setSurface(*surface); - texture.setSampler(*sampler); - - COLLADASW::ColorOrTexture cot(texture); - return cot; -} - -COLLADASW::ColorOrTexture EffectsExporter::getcol(float r, float g, float b, float a) -{ - COLLADASW::Color color(r, g, b, a); - COLLADASW::ColorOrTexture cot(color); - return cot; -} diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h deleted file mode 100644 index 57df844233c..00000000000 --- a/source/blender/collada/EffectExporter.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __EFFECTEXPORTER_H__ -#define __EFFECTEXPORTER_H__ - -#include <string> -#include <vector> - -#include "COLLADASWColorOrTexture.h" -#include "COLLADASWStreamWriter.h" -#include "COLLADASWSampler.h" -#include "COLLADASWLibraryEffects.h" - -#include "DNA_image_types.h" -#include "DNA_material_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "ExportSettings.h" -#include "collada_utils.h" - -class EffectsExporter : COLLADASW::LibraryEffects { - public: - EffectsExporter(COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings, - KeyImageMap &key_image_map); - void exportEffects(bContext *C, Scene *sce); - - void operator()(Material *ma, Object *ob); - - COLLADASW::ColorOrTexture createTexture(Image *ima, - std::string &uv_layer_name, - COLLADASW::Sampler *sampler - /*COLLADASW::Surface *surface*/); - - COLLADASW::ColorOrTexture getcol(float r, float g, float b, float a); - - private: - void set_shader_type(COLLADASW::EffectProfile &ep, Material *ma); - - void set_diffuse_color(COLLADASW::EffectProfile &ep, Material *ma); - void set_emission(COLLADASW::EffectProfile &ep, Material *ma); - void set_ior(COLLADASW::EffectProfile &ep, Material *ma); - void set_shininess(COLLADASW::EffectProfile &ep, Material *ma); - void set_reflectivity(COLLADASW::EffectProfile &ep, Material *ma); - void set_transparency(COLLADASW::EffectProfile &ep, Material *ma); - void set_ambient(COLLADASW::EffectProfile &ep, Material *ma); - void set_specular(COLLADASW::EffectProfile &ep, Material *ma); - void set_reflective(COLLADASW::EffectProfile &ep, Material *ma); - - void get_images(Material *ma, KeyImageMap &uid_image_map); - void create_image_samplers(COLLADASW::EffectProfile &ep, - KeyImageMap &uid_image_map, - std::string &active_uv); - - void writeTextures(COLLADASW::EffectProfile &ep, - std::string &key, - COLLADASW::Sampler *sampler, - MTex *t, - Image *ima, - std::string &uvname); - - bool hasEffects(Scene *sce); - - BCExportSettings &export_settings; - KeyImageMap &key_image_map; - Scene *scene; - bContext *mContext; -}; - -#endif diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp deleted file mode 100644 index 286bcbfb759..00000000000 --- a/source/blender/collada/ErrorHandler.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ -#include "ErrorHandler.h" -#include <iostream> - -#include "COLLADASaxFWLIError.h" -#include "COLLADASaxFWLSaxParserError.h" -#include "COLLADASaxFWLSaxFWLError.h" - -#include "GeneratedSaxParserParserError.h" - -#include <string.h> - -#include "BLI_utildefines.h" - -//-------------------------------------------------------------------- -ErrorHandler::ErrorHandler() : mError(false) -{ -} - -//-------------------------------------------------------------------- -ErrorHandler::~ErrorHandler() -{ -} - -//-------------------------------------------------------------------- -bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error) -{ - /* This method must return false when Collada should continue. - * See https://github.com/KhronosGroup/OpenCOLLADA/issues/442 - */ - bool isError = true; - std::string error_context; - std::string error_message; - - if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) { - error_context = "Schema validation"; - - COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *)error; - const GeneratedSaxParser::ParserError &parserError = saxParserError->getError(); - error_message = parserError.getErrorMessage(); - - if (parserError.getErrorType() == - GeneratedSaxParser::ParserError::ERROR_VALIDATION_MIN_OCCURS_UNMATCHED) { - if (STREQ(parserError.getElement(), "effect")) { - isError = false; - } - } - - else if (parserError.getErrorType() == - GeneratedSaxParser::ParserError:: - ERROR_VALIDATION_SEQUENCE_PREVIOUS_SIBLING_NOT_PRESENT) { - if (!(STREQ(parserError.getElement(), "extra") && - STREQ(parserError.getAdditionalText().c_str(), "sibling: fx_profile_abstract"))) { - isError = false; - } - } - - else if (parserError.getErrorType() == - GeneratedSaxParser::ParserError::ERROR_COULD_NOT_OPEN_FILE) { - isError = true; - error_context = "File access"; - } - - else if (parserError.getErrorType() == - GeneratedSaxParser::ParserError::ERROR_REQUIRED_ATTRIBUTE_MISSING) { - isError = true; - } - - else { - isError = (parserError.getSeverity() != - GeneratedSaxParser::ParserError::Severity::SEVERITY_ERROR_NONCRITICAL); - } - } - else if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXFWL) { - error_context = "Sax FWL"; - COLLADASaxFWL::SaxFWLError *saxFWLError = (COLLADASaxFWL::SaxFWLError *)error; - error_message = saxFWLError->getErrorMessage(); - - /* - * Accept non critical errors as warnings (i.e. texture not found) - * This makes the importer more graceful, so it now imports what makes sense. - */ - - isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL); - } - else { - error_context = "OpenCollada"; - error_message = error->getFullErrorMessage(); - isError = true; - } - - std::string severity = (isError) ? "Error" : "Warning"; - std::cout << error_context << " (" << severity << "): " << error_message << std::endl; - if (isError) { - std::cout << "The Collada import has been forced to stop." << std::endl; - std::cout << "Please fix the reported error and then try again."; - mError = true; - } - return isError; -} diff --git a/source/blender/collada/ErrorHandler.h b/source/blender/collada/ErrorHandler.h deleted file mode 100644 index f040855244d..00000000000 --- a/source/blender/collada/ErrorHandler.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __ERRORHANDLER_H__ -#define __ERRORHANDLER_H__ - -#include <string> -#include <map> -#include <vector> -#include <algorithm> // sort() - -#include "COLLADASaxFWLIErrorHandler.h" - -/** \brief Handler class for parser errors - */ -class ErrorHandler : public COLLADASaxFWL::IErrorHandler { - public: - /** Constructor. */ - ErrorHandler(); - - /** Destructor. */ - virtual ~ErrorHandler(); - /** handle any error thrown by the parser. */ - bool virtual handleError(const COLLADASaxFWL::IError *error); - /** True if there was an error during parsing. */ - bool hasError() - { - return mError; - } - - private: - /** Disable default copy ctor. */ - ErrorHandler(const ErrorHandler &pre); - /** Disable default assignment operator. */ - const ErrorHandler &operator=(const ErrorHandler &pre); - /** Hold error status. */ - bool mError; -}; - -#endif /* __ERRORHANDLER_H__ */ diff --git a/source/blender/collada/ExportSettings.cpp b/source/blender/collada/ExportSettings.cpp deleted file mode 100644 index da3c0de0fdf..00000000000 --- a/source/blender/collada/ExportSettings.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "ExportSettings.h" diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h deleted file mode 100644 index 1e158418120..00000000000 --- a/source/blender/collada/ExportSettings.h +++ /dev/null @@ -1,295 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __EXPORTSETTINGS_H__ -#define __EXPORTSETTINGS_H__ - -#ifdef __cplusplus -# include <vector> -# include "BCMath.h" - -extern "C" { -#endif - -#include "BLI_linklist.h" -#include "BlenderContext.h" - -typedef enum BC_export_mesh_type { - BC_MESH_TYPE_VIEW, - BC_MESH_TYPE_RENDER, -} BC_export_mesh_type; - -typedef enum BC_export_transformation_type { - BC_TRANSFORMATION_TYPE_MATRIX, - BC_TRANSFORMATION_TYPE_DECOMPOSED, -} BC_export_transformation_type; - -typedef enum BC_export_animation_type { - BC_ANIMATION_EXPORT_SAMPLES, - BC_ANIMATION_EXPORT_KEYS, -} BC_export_animation_type; - -typedef enum BC_ui_export_section { - BC_UI_SECTION_MAIN, - BC_UI_SECTION_GEOMETRY, - BC_UI_SECTION_ARMATURE, - BC_UI_SECTION_ANIMATION, - BC_UI_SECTION_COLLADA, -} BC_ui_export_section; - -typedef struct ExportSettings { - bool apply_modifiers; - BC_global_forward_axis global_forward; - BC_global_up_axis global_up; - bool apply_global_orientation; - - BC_export_mesh_type export_mesh_type; - - bool selected; - bool include_children; - bool include_armatures; - bool include_shapekeys; - bool deform_bones_only; - bool include_animations; - bool include_all_actions; - int sampling_rate; - bool keep_smooth_curves; - bool keep_keyframes; - bool keep_flat_curves; - - bool active_uv_only; - BC_export_animation_type export_animation_type; - bool use_texture_copies; - - bool triangulate; - bool use_object_instantiation; - bool use_blender_profile; - bool sort_by_name; - BC_export_transformation_type object_transformation_type; - BC_export_transformation_type animation_transformation_type; - - bool open_sim; - bool limit_precision; - bool keep_bind_info; - - char *filepath; - LinkNode *export_set; -} ExportSettings; - -#ifdef __cplusplus -} - -void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer); - -class BCExportSettings { - - private: - const ExportSettings &export_settings; - BlenderContext &blender_context; - const BCMatrix global_transform; - - public: - BCExportSettings(ExportSettings *exportSettings, BlenderContext &blenderContext) - : export_settings(*exportSettings), - blender_context(blenderContext), - global_transform(BCMatrix(exportSettings->global_forward, exportSettings->global_up)) - - { - } - - const BCMatrix &get_global_transform() - { - return global_transform; - } - - bool get_apply_modifiers() - { - return export_settings.apply_modifiers; - } - - BC_global_forward_axis get_global_forward() - { - return export_settings.global_forward; - } - - BC_global_up_axis get_global_up() - { - return export_settings.global_up; - } - - bool get_apply_global_orientation() - { - return export_settings.apply_global_orientation; - } - - BC_export_mesh_type get_export_mesh_type() - { - return export_settings.export_mesh_type; - } - - bool get_selected() - { - return export_settings.selected; - } - - bool get_include_children() - { - return export_settings.include_children; - } - - bool get_include_armatures() - { - return export_settings.include_armatures; - } - - bool get_include_shapekeys() - { - return export_settings.include_shapekeys; - } - - bool get_deform_bones_only() - { - return export_settings.deform_bones_only; - } - - bool get_include_animations() - { - return export_settings.include_animations; - } - - bool get_include_all_actions() - { - return export_settings.include_all_actions; - } - - int get_sampling_rate() - { - return export_settings.sampling_rate; - } - - bool get_keep_smooth_curves() - { - return export_settings.keep_smooth_curves; - } - - bool get_keep_keyframes() - { - return export_settings.keep_keyframes; - } - - bool get_keep_flat_curves() - { - return export_settings.keep_flat_curves; - } - - bool get_active_uv_only() - { - return export_settings.active_uv_only; - } - - BC_export_animation_type get_export_animation_type() - { - return export_settings.export_animation_type; - } - - bool get_use_texture_copies() - { - return export_settings.use_texture_copies; - } - - bool get_triangulate() - { - return export_settings.triangulate; - } - - bool get_use_object_instantiation() - { - return export_settings.use_object_instantiation; - } - - bool get_use_blender_profile() - { - return export_settings.use_blender_profile; - } - - bool get_sort_by_name() - { - return export_settings.sort_by_name; - } - - BC_export_transformation_type get_object_transformation_type() - { - return export_settings.object_transformation_type; - } - - BC_export_transformation_type get_animation_transformation_type() - { - return export_settings.animation_transformation_type; - } - - bool get_open_sim() - { - return export_settings.open_sim; - } - - bool get_limit_precision() - { - return export_settings.limit_precision; - } - - bool get_keep_bind_info() - { - return export_settings.keep_bind_info; - } - - char *get_filepath() - { - return export_settings.filepath; - } - - LinkNode *get_export_set() - { - return export_settings.export_set; - } - - BlenderContext &get_blender_context() - { - return blender_context; - } - - Scene *get_scene() - { - return blender_context.get_scene(); - } - - ViewLayer *get_view_layer() - { - return blender_context.get_view_layer(); - } - - bool is_export_root(Object *ob) - { - return bc_is_base_node(get_export_set(), ob, get_view_layer()); - } -}; - -#endif - -#endif diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp deleted file mode 100644 index 4875ee72b0f..00000000000 --- a/source/blender/collada/ExtraHandler.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <stddef.h> -#include "BLI_string.h" - -#include "ExtraHandler.h" - -ExtraHandler::ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp) : currentExtraTags(0) -{ - this->dimp = dimp; - this->aimp = aimp; -} - -ExtraHandler::~ExtraHandler() -{ -} - -bool ExtraHandler::elementBegin(const char *elementName, const char **attributes) -{ - /* \todo attribute handling for profile tags */ - currentElement = std::string(elementName); - // addToSidTree(attributes[0], attributes[1]); - return true; -} - -bool ExtraHandler::elementEnd(const char *elementName) -{ - return true; -} - -bool ExtraHandler::textData(const char *text, size_t textLength) -{ - char buf[1024]; - - if (currentElement.length() == 0 || currentExtraTags == 0) { - return false; - } - - BLI_strncpy(buf, text, textLength + 1); - currentExtraTags->addTag(currentElement, std::string(buf)); - return true; -} - -bool ExtraHandler::parseElement(const char *profileName, - const unsigned long &elementHash, - const COLLADAFW::UniqueId &uniqueId) -{ - /* implement for backwards compatibility, new version added object parameter */ - return parseElement(profileName, elementHash, uniqueId, NULL); -} - -bool ExtraHandler::parseElement(const char *profileName, - const unsigned long &elementHash, - const COLLADAFW::UniqueId &uniqueId, - COLLADAFW::Object *object) -{ - if (BLI_strcaseeq(profileName, "blender")) { -#if 0 - printf("In parseElement for supported profile %s for id %s\n", - profileName, - uniqueId.toAscii().c_str()); -#endif - currentUid = uniqueId; - ExtraTags *et = dimp->getExtraTags(uniqueId); - if (!et) { - et = new ExtraTags(std::string(profileName)); - dimp->addExtraTags(uniqueId, et); - } - currentExtraTags = et; - return true; - } - // printf("In parseElement for unsupported profile %s for id %s\n", profileName, - // uniqueId.toAscii().c_str()); - return false; -} diff --git a/source/blender/collada/ExtraHandler.h b/source/blender/collada/ExtraHandler.h deleted file mode 100644 index 021eb8e9663..00000000000 --- a/source/blender/collada/ExtraHandler.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __EXTRAHANDLER_H__ -#define __EXTRAHANDLER_H__ - -#include <string> -#include <map> -#include <vector> -#include <algorithm> // sort() - -#include "COLLADASaxFWLIExtraDataCallbackHandler.h" -#include "COLLADASaxFWLFilePartLoader.h" -#include "COLLADASWInstanceController.h" - -#include "DocumentImporter.h" -#include "AnimationImporter.h" - -/** \brief Handler class for \<extra\> data, through which different - * profiles can be handled - */ -class ExtraHandler : public COLLADASaxFWL::IExtraDataCallbackHandler { - public: - /** Constructor. */ - ExtraHandler(DocumentImporter *dimp, AnimationImporter *aimp); - - /** Destructor. */ - virtual ~ExtraHandler(); - - /** Handle the beginning of an element. */ - bool elementBegin(const char *elementName, const char **attributes); - - /** Handle the end of an element. */ - bool elementEnd(const char *elementName); - - /** Receive the data in text format. */ - bool textData(const char *text, size_t textLength); - - /** Method to ask, if the current callback handler want to read the data of the given extra - * element. */ - bool parseElement(const char *profileName, - const unsigned long &elementHash, - const COLLADAFW::UniqueId &uniqueId, - COLLADAFW::Object *object); - - /** For backwards compatibility with older OpenCollada, new version added object parameter */ - bool parseElement(const char *profileName, - const unsigned long &elementHash, - const COLLADAFW::UniqueId &uniqueId); - - private: - /** Disable default copy constructor. */ - ExtraHandler(const ExtraHandler &pre); - /** Disable default assignment operator. */ - const ExtraHandler &operator=(const ExtraHandler &pre); - - /** Handle to DocumentImporter for interface to extra element data saving. */ - DocumentImporter *dimp; - AnimationImporter *aimp; - /** Holds Id of element for which <extra> XML elements are handled. */ - COLLADAFW::UniqueId currentUid; - ExtraTags *currentExtraTags; - std::string currentElement; -}; - -#endif /* __EXTRAHANDLER_H__ */ diff --git a/source/blender/collada/ExtraTags.cpp b/source/blender/collada/ExtraTags.cpp deleted file mode 100644 index 496ba3891f7..00000000000 --- a/source/blender/collada/ExtraTags.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <stddef.h> -#include <stdlib.h> -#include "BLI_string.h" - -#include <iostream> - -#include "ExtraTags.h" - -ExtraTags::ExtraTags(std::string profile) -{ - this->profile = profile; - this->tags = std::map<std::string, std::string>(); -} - -ExtraTags::~ExtraTags() -{ -} - -bool ExtraTags::isProfile(std::string profile) -{ - return this->profile == profile; -} - -bool ExtraTags::addTag(std::string tag, std::string data) -{ - tags[tag] = data; - - return true; -} - -int ExtraTags::asInt(std::string tag, bool *ok) -{ - if (tags.find(tag) == tags.end()) { - *ok = false; - return -1; - } - *ok = true; - return atoi(tags[tag].c_str()); -} - -float ExtraTags::asFloat(std::string tag, bool *ok) -{ - if (tags.find(tag) == tags.end()) { - *ok = false; - return -1.0f; - } - *ok = true; - return (float)atof(tags[tag].c_str()); -} - -std::string ExtraTags::asString(std::string tag, bool *ok) -{ - if (tags.find(tag) == tags.end()) { - *ok = false; - return ""; - } - *ok = true; - return tags[tag]; -} - -bool ExtraTags::setData(std::string tag, short *data) -{ - bool ok = false; - int tmp = asInt(tag, &ok); - if (ok) { - *data = (short)tmp; - } - return ok; -} - -bool ExtraTags::setData(std::string tag, int *data) -{ - bool ok = false; - int tmp = asInt(tag, &ok); - if (ok) { - *data = tmp; - } - return ok; -} - -bool ExtraTags::setData(std::string tag, float *data) -{ - bool ok = false; - float tmp = asFloat(tag, &ok); - if (ok) { - *data = tmp; - } - return ok; -} - -bool ExtraTags::setData(std::string tag, char *data) -{ - bool ok = false; - int tmp = asInt(tag, &ok); - if (ok) { - *data = (char)tmp; - } - return ok; -} - -std::string ExtraTags::setData(std::string tag, std::string &data) -{ - bool ok = false; - std::string tmp = asString(tag, &ok); - return (ok) ? tmp : data; -} diff --git a/source/blender/collada/ExtraTags.h b/source/blender/collada/ExtraTags.h deleted file mode 100644 index 9191182c757..00000000000 --- a/source/blender/collada/ExtraTags.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __EXTRATAGS_H__ -#define __EXTRATAGS_H__ - -#include <string> -#include <map> -#include <vector> - -/** \brief Class for saving \<extra\> tags for a specific UniqueId. - */ -class ExtraTags { - public: - /** Constructor. */ - ExtraTags(const std::string profile); - - /** Destructor. */ - virtual ~ExtraTags(); - - /** Handle the beginning of an element. */ - bool addTag(std::string tag, std::string data); - - /** Set given short pointer to value of tag, if it exists. */ - bool setData(std::string tag, short *data); - - /** Set given int pointer to value of tag, if it exists. */ - bool setData(std::string tag, int *data); - - /** Set given float pointer to value of tag, if it exists. */ - bool setData(std::string tag, float *data); - - /** Set given char pointer to value of tag, if it exists. */ - bool setData(std::string tag, char *data); - std::string setData(std::string tag, std::string &data); - - /** Return true if the extra tags is for specified profile. */ - bool isProfile(std::string profile); - - private: - /** Disable default copy constructor. */ - ExtraTags(const ExtraTags &pre); - /** Disable default assignment operator. */ - const ExtraTags &operator=(const ExtraTags &pre); - - /** The profile for which the tags are. */ - std::string profile; - - /** Map of tag and text pairs. */ - std::map<std::string, std::string> tags; - - /** Get text data for tag as an int. */ - int asInt(std::string tag, bool *ok); - /** Get text data for tag as a float. */ - float asFloat(std::string tag, bool *ok); - /** Get text data for tag as a string. */ - std::string asString(std::string tag, bool *ok); -}; - -#endif /* __EXTRATAGS_H__ */ diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp deleted file mode 100644 index 640bf3c0633..00000000000 --- a/source/blender/collada/GeometryExporter.cpp +++ /dev/null @@ -1,718 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <sstream> - -#include "COLLADASWPrimitves.h" -#include "COLLADASWSource.h" -#include "COLLADASWVertices.h" -#include "COLLADABUUtils.h" - -#include "GeometryExporter.h" - -#include "DNA_meshdata_types.h" - -extern "C" { -#include "BLI_utildefines.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_lib_id.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -} - -#include "collada_internal.h" -#include "collada_utils.h" - -void GeometryExporter::exportGeom() -{ - Scene *sce = blender_context.get_scene(); - openLibrary(); - - GeometryFunctor gf; - gf.forEachMeshObjectInExportSet<GeometryExporter>( - sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); -} - -void GeometryExporter::operator()(Object *ob) -{ - bool use_instantiation = this->export_settings.get_use_object_instantiation(); - Mesh *me = bc_get_mesh_copy(blender_context, - ob, - this->export_settings.get_export_mesh_type(), - this->export_settings.get_apply_modifiers(), - this->export_settings.get_triangulate()); - - std::string geom_id = get_geometry_id(ob, use_instantiation); - std::vector<Normal> nor; - std::vector<BCPolygonNormalsIndices> norind; - - /* Skip if linked geometry was already exported from another reference */ - if (use_instantiation && exportedGeometry.find(geom_id) != exportedGeometry.end()) { - return; - } - - std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob); - geom_name = encode_xml(geom_name); - - exportedGeometry.insert(geom_id); - - bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); - - create_normals(nor, norind, me); - - /* openMesh(geoId, geoName, meshId) */ - openMesh(geom_id, geom_name); - - /* writes <source> for vertex coords */ - createVertsSource(geom_id, me); - - /* writes <source> for normal coords */ - createNormalsSource(geom_id, me, nor); - - bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV); - - /* writes <source> for uv coords if mesh has uv coords */ - if (has_uvs) { - createTexcoordsSource(geom_id, me); - } - - if (has_color) { - createVertexColorSource(geom_id, me); - } - /* <vertices> */ - - COLLADASW::Vertices verts(mSW); - verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX)); - COLLADASW::InputList &input_list = verts.getInputList(); - COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, - getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); - input_list.push_back(input); - verts.add(); - - createLooseEdgeList(ob, me, geom_id); - - /* Only create Polylists if number of faces > 0 */ - if (me->totface > 0) { - /* XXX slow */ - if (ob->totcol) { - for (int a = 0; a < ob->totcol; a++) { - create_mesh_primitive_list(a, has_uvs, has_color, ob, me, geom_id, norind); - } - } - else { - create_mesh_primitive_list(0, has_uvs, has_color, ob, me, geom_id, norind); - } - } - - closeMesh(); - - closeGeometry(); - - if (this->export_settings.get_include_shapekeys()) { - Key *key = BKE_key_from_object(ob); - if (key) { - KeyBlock *kb = (KeyBlock *)key->block.first; - /* skip the basis */ - kb = kb->next; - for (; kb; kb = kb->next) { - BKE_keyblock_convert_to_mesh(kb, me); - export_key_mesh(ob, me, kb); - } - } - } - - BKE_id_free(NULL, me); -} - -void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb) -{ - std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name); - std::vector<Normal> nor; - std::vector<BCPolygonNormalsIndices> norind; - - if (exportedGeometry.find(geom_id) != exportedGeometry.end()) { - return; - } - - std::string geom_name = kb->name; - - exportedGeometry.insert(geom_id); - - bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); - - create_normals(nor, norind, me); - - // openMesh(geoId, geoName, meshId) - openMesh(geom_id, geom_name); - - /* writes <source> for vertex coords */ - createVertsSource(geom_id, me); - - /* writes <source> for normal coords */ - createNormalsSource(geom_id, me, nor); - - bool has_uvs = (bool)CustomData_has_layer(&me->ldata, CD_MLOOPUV); - - /* writes <source> for uv coords if mesh has uv coords */ - if (has_uvs) { - createTexcoordsSource(geom_id, me); - } - - if (has_color) { - createVertexColorSource(geom_id, me); - } - - /* <vertices> */ - - COLLADASW::Vertices verts(mSW); - verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX)); - COLLADASW::InputList &input_list = verts.getInputList(); - COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, - getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); - input_list.push_back(input); - verts.add(); - - // createLooseEdgeList(ob, me, geom_id, norind); - - /* XXX slow */ - if (ob->totcol) { - for (int a = 0; a < ob->totcol; a++) { - create_mesh_primitive_list(a, has_uvs, has_color, ob, me, geom_id, norind); - } - } - else { - create_mesh_primitive_list(0, has_uvs, has_color, ob, me, geom_id, norind); - } - - closeMesh(); - - closeGeometry(); -} - -void GeometryExporter::createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id) -{ - - MEdge *medges = me->medge; - int totedges = me->totedge; - int edges_in_linelist = 0; - std::vector<unsigned int> edge_list; - int index; - - /* Find all loose edges in Mesh - * and save vertex indices in edge_list */ - for (index = 0; index < totedges; index++) { - MEdge *edge = &medges[index]; - - if (edge->flag & ME_LOOSEEDGE) { - edges_in_linelist += 1; - edge_list.push_back(edge->v1); - edge_list.push_back(edge->v2); - } - } - - if (edges_in_linelist > 0) { - /* Create the list of loose edges */ - COLLADASW::Lines lines(mSW); - - lines.setCount(edges_in_linelist); - - COLLADASW::InputList &til = lines.getInputList(); - - /* creates <input> in <lines> for vertices */ - COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, - getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), - 0); - til.push_back(input1); - - lines.prepareToAppendValues(); - - for (index = 0; index < edges_in_linelist; index++) { - lines.appendValues(edge_list[2 * index + 1]); - lines.appendValues(edge_list[2 * index]); - } - lines.finish(); - } -} - -static void prepareToAppendValues(bool is_triangulated, - COLLADASW::PrimitivesBase &primitive_list, - std::vector<unsigned long> &vcount_list) -{ - /* performs the actual writing */ - if (is_triangulated) { - ((COLLADASW::Triangles &)primitive_list).prepareToAppendValues(); - } - else { - /* sets <vcount> */ - primitive_list.setVCountList(vcount_list); - ((COLLADASW::Polylist &)primitive_list).prepareToAppendValues(); - } -} - -static void finish_and_delete_primitive_List(bool is_triangulated, - COLLADASW::PrimitivesBase *primitive_list) -{ - if (is_triangulated) { - ((COLLADASW::Triangles *)primitive_list)->finish(); - } - else { - ((COLLADASW::Polylist *)primitive_list)->finish(); - } - delete primitive_list; -} - -static COLLADASW::PrimitivesBase *create_primitive_list(bool is_triangulated, - COLLADASW::StreamWriter *mSW) -{ - COLLADASW::PrimitivesBase *primitive_list; - - if (is_triangulated) { - primitive_list = new COLLADASW::Triangles(mSW); - } - else { - primitive_list = new COLLADASW::Polylist(mSW); - } - return primitive_list; -} - -static bool collect_vertex_counts_per_poly(Mesh *me, - int material_index, - std::vector<unsigned long> &vcount_list) -{ - MPoly *mpolys = me->mpoly; - int totpolys = me->totpoly; - bool is_triangulated = true; - - int i; - /* Expecting that p->mat_nr is always 0 if the mesh has no materials assigned */ - for (i = 0; i < totpolys; i++) { - MPoly *p = &mpolys[i]; - if (p->mat_nr == material_index) { - int vertex_count = p->totloop; - vcount_list.push_back(vertex_count); - if (vertex_count != 3) { - is_triangulated = false; - } - } - } - return is_triangulated; -} - -std::string GeometryExporter::makeVertexColorSourceId(std::string &geom_id, char *layer_name) -{ - std::string result = getIdBySemantics(geom_id, COLLADASW::InputSemantic::COLOR) + "-" + - layer_name; - return result; -} - -/* powerful because it handles both cases when there is material and when there's not */ -void GeometryExporter::create_mesh_primitive_list(short material_index, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string &geom_id, - std::vector<BCPolygonNormalsIndices> &norind) -{ - - MPoly *mpolys = me->mpoly; - MLoop *mloops = me->mloop; - int totpolys = me->totpoly; - - std::vector<unsigned long> vcount_list; - - bool is_triangulated = collect_vertex_counts_per_poly(me, material_index, vcount_list); - int polygon_count = vcount_list.size(); - - /* no faces using this material */ - if (polygon_count == 0) { - fprintf( - stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index); - return; - } - - Material *ma = ob->totcol ? BKE_object_material_get(ob, material_index + 1) : NULL; - COLLADASW::PrimitivesBase *primitive_list = create_primitive_list(is_triangulated, mSW); - - /* sets count attribute in <polylist> */ - primitive_list->setCount(polygon_count); - - /* sets material name */ - if (ma) { - std::string material_id = get_material_id(ma); - std::ostringstream ostr; - ostr << translate_id(material_id); - primitive_list->setMaterial(ostr.str()); - } - - COLLADASW::Input vertex_input(COLLADASW::InputSemantic::VERTEX, - getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), - 0); - COLLADASW::Input normals_input(COLLADASW::InputSemantic::NORMAL, - getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), - 1); - - COLLADASW::InputList &til = primitive_list->getInputList(); - til.push_back(vertex_input); - til.push_back(normals_input); - - /* if mesh has uv coords writes <input> for TEXCOORD */ - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); - for (int i = 0; i < num_layers; i++) { - int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, i); - if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { - - // char *name = CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, i); - COLLADASW::Input texcoord_input( - COLLADASW::InputSemantic::TEXCOORD, - makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings.get_active_uv_only())), - 2, // this is only until we have optimized UV sets - (this->export_settings.get_active_uv_only()) ? 0 : layer_index - 1 /* set (0,1,2,...) */ - ); - til.push_back(texcoord_input); - } - } - - int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); - if (totlayer_mcol > 0) { - int map_index = 0; - - for (int a = 0; a < totlayer_mcol; a++) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); - COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, - makeUrl(makeVertexColorSourceId(geom_id, layer_name)), - (has_uvs) ? 3 : 2, // all color layers have same index order - map_index // set number equals color map index - ); - til.push_back(input4); - map_index++; - } - } - - /* performs the actual writing */ - prepareToAppendValues(is_triangulated, *primitive_list, vcount_list); - - /* <p> */ - int texindex = 0; - for (int i = 0; i < totpolys; i++) { - MPoly *p = &mpolys[i]; - int loop_count = p->totloop; - - if (p->mat_nr == material_index) { - MLoop *l = &mloops[p->loopstart]; - BCPolygonNormalsIndices normal_indices = norind[i]; - - for (int j = 0; j < loop_count; j++) { - primitive_list->appendValues(l[j].v); - primitive_list->appendValues(normal_indices[j]); - if (has_uvs) { - primitive_list->appendValues(texindex + j); - } - - if (has_color) { - primitive_list->appendValues(texindex + j); - } - } - } - - texindex += loop_count; - } - - finish_and_delete_primitive_List(is_triangulated, primitive_list); -} - -/* creates <source> for positions */ -void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me) -{ -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - int totverts = me->totvert; - MVert *verts = me->mvert; - - COLLADASW::FloatSourceF source(mSW); - source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); - source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::POSITION) + - ARRAY_ID_SUFFIX); - source.setAccessorCount(totverts); - source.setAccessorStride(3); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - /* main function, it creates <source id = "">, <float_array id = "" - * count = ""> */ - source.prepareToAppendValues(); - /* appends data to <float_array> */ - int i = 0; - for (i = 0; i < totverts; i++) { - Vector co; - if (export_settings.get_apply_global_orientation()) { - bc_add_global_transform(co, verts[i].co, export_settings.get_global_transform()); - } - else { - copy_v3_v3(co, verts[i].co); - } - source.appendValues(co[0], co[1], co[2]); - } - - source.finish(); -} - -void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me) -{ - /* Find number of vertex color layers */ - int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL); - if (totlayer_mcol == 0) { - return; - } - - int map_index = 0; - for (int a = 0; a < totlayer_mcol; a++) { - - map_index++; - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, a); - - COLLADASW::FloatSourceF source(mSW); - - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a); - std::string layer_id = makeVertexColorSourceId(geom_id, layer_name); - source.setId(layer_id); - - source.setNodeName(layer_name); - - source.setArrayId(layer_id + ARRAY_ID_SUFFIX); - source.setAccessorCount(me->totloop); - source.setAccessorStride(4); - - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("R"); - param.push_back("G"); - param.push_back("B"); - param.push_back("A"); - - source.prepareToAppendValues(); - - MPoly *mpoly; - int i; - for (i = 0, mpoly = me->mpoly; i < me->totpoly; i++, mpoly++) { - MLoopCol *mlc = mloopcol + mpoly->loopstart; - for (int j = 0; j < mpoly->totloop; j++, mlc++) { - source.appendValues(mlc->r / 255.0f, mlc->g / 255.0f, mlc->b / 255.0f, mlc->a / 255.0f); - } - } - - source.finish(); - } -} - -std::string GeometryExporter::makeTexcoordSourceId(std::string &geom_id, - int layer_index, - bool is_single_layer) -{ - char suffix[20]; - if (is_single_layer) { - suffix[0] = '\0'; - } - else { - sprintf(suffix, "-%d", layer_index); - } - return getIdBySemantics(geom_id, COLLADASW::InputSemantic::TEXCOORD) + suffix; -} - -/* creates <source> for texcoords */ -void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me) -{ - - int totpoly = me->totpoly; - int totuv = me->totloop; - MPoly *mpolys = me->mpoly; - - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - - /* write <source> for each layer - * each <source> will get id like meshName + "map-channel-1" */ - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); - for (int a = 0; a < num_layers; a++) { - int layer_index = CustomData_get_layer_index_n(&me->ldata, CD_MLOOPUV, a); - if (!this->export_settings.get_active_uv_only() || layer_index == active_uv_index) { - MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a); - - COLLADASW::FloatSourceF source(mSW); - std::string layer_id = makeTexcoordSourceId( - geom_id, a, this->export_settings.get_active_uv_only()); - source.setId(layer_id); - source.setArrayId(layer_id + ARRAY_ID_SUFFIX); - - source.setAccessorCount(totuv); - source.setAccessorStride(2); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("S"); - param.push_back("T"); - - source.prepareToAppendValues(); - - for (int index = 0; index < totpoly; index++) { - MPoly *mpoly = mpolys + index; - MLoopUV *mloop = mloops + mpoly->loopstart; - for (int j = 0; j < mpoly->totloop; j++) { - source.appendValues(mloop[j].uv[0], mloop[j].uv[1]); - } - } - - source.finish(); - } - } -} - -bool operator<(const Normal &a, const Normal &b) -{ - /* only needed to sort normal vectors and find() them later in a map.*/ - return a.x < b.x || (a.x == b.x && (a.y < b.y || (a.y == b.y && a.z < b.z))); -} - -/* creates <source> for normals */ -void GeometryExporter::createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal> &nor) -{ -#if 0 - int totverts = dm->getNumVerts(dm); - MVert *verts = dm->getVertArray(dm); -#endif - - COLLADASW::FloatSourceF source(mSW); - source.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL)); - source.setArrayId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL) + ARRAY_ID_SUFFIX); - source.setAccessorCount((unsigned long)nor.size()); - source.setAccessorStride(3); - COLLADASW::SourceBase::ParameterNameList ¶m = source.getParameterNameList(); - param.push_back("X"); - param.push_back("Y"); - param.push_back("Z"); - - source.prepareToAppendValues(); - - std::vector<Normal>::iterator it; - for (it = nor.begin(); it != nor.end(); it++) { - Normal &n = *it; - - Vector no{n.x, n.y, n.z}; - if (export_settings.get_apply_global_orientation()) { - bc_add_global_transform(no, export_settings.get_global_transform()); - } - source.appendValues(no[0], no[1], no[2]); - } - - source.finish(); -} - -void GeometryExporter::create_normals(std::vector<Normal> &normals, - std::vector<BCPolygonNormalsIndices> &polygons_normals, - Mesh *me) -{ - std::map<Normal, unsigned int> shared_normal_indices; - int last_normal_index = -1; - - MVert *verts = me->mvert; - MLoop *mloops = me->mloop; - float(*lnors)[3] = NULL; - bool use_custom_normals = false; - - BKE_mesh_calc_normals_split(me); - if (CustomData_has_layer(&me->ldata, CD_NORMAL)) { - lnors = (float(*)[3])CustomData_get_layer(&me->ldata, CD_NORMAL); - use_custom_normals = true; - } - - for (int poly_index = 0; poly_index < me->totpoly; poly_index++) { - MPoly *mpoly = &me->mpoly[poly_index]; - bool use_vertex_normals = use_custom_normals || mpoly->flag & ME_SMOOTH; - - if (!use_vertex_normals) { - /* For flat faces use face normal as vertex normal: */ - - float vector[3]; - BKE_mesh_calc_poly_normal(mpoly, mloops + mpoly->loopstart, verts, vector); - - Normal n = {vector[0], vector[1], vector[2]}; - normals.push_back(n); - last_normal_index++; - } - - BCPolygonNormalsIndices poly_indices; - for (int loop_index = 0; loop_index < mpoly->totloop; loop_index++) { - unsigned int loop_idx = mpoly->loopstart + loop_index; - if (use_vertex_normals) { - float normalized[3]; - - if (use_custom_normals) { - normalize_v3_v3(normalized, lnors[loop_idx]); - } - else { - normal_short_to_float_v3(normalized, verts[mloops[loop_index].v].no); - normalize_v3(normalized); - } - Normal n = {normalized[0], normalized[1], normalized[2]}; - - if (shared_normal_indices.find(n) != shared_normal_indices.end()) { - poly_indices.add_index(shared_normal_indices[n]); - } - else { - last_normal_index++; - poly_indices.add_index(last_normal_index); - shared_normal_indices[n] = last_normal_index; - normals.push_back(n); - } - } - else { - poly_indices.add_index(last_normal_index); - } - } - - polygons_normals.push_back(poly_indices); - } -} - -std::string GeometryExporter::getIdBySemantics(std::string geom_id, - COLLADASW::InputSemantic::Semantics type, - std::string other_suffix) -{ - return geom_id + getSuffixBySemantic(type) + other_suffix; -} - -COLLADASW::URI GeometryExporter::getUrlBySemantics(std::string geom_id, - COLLADASW::InputSemantic::Semantics type, - std::string other_suffix) -{ - - std::string id(getIdBySemantics(geom_id, type, other_suffix)); - return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); -} - -COLLADASW::URI GeometryExporter::makeUrl(std::string id) -{ - return COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, id); -} diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h deleted file mode 100644 index 8c7a38fc407..00000000000 --- a/source/blender/collada/GeometryExporter.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __GEOMETRYEXPORTER_H__ -#define __GEOMETRYEXPORTER_H__ - -#include <string> -#include <vector> -#include <set> - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryGeometries.h" -#include "COLLADASWInputList.h" - -#include "DNA_mesh_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "DNA_key_types.h" - -#include "ExportSettings.h" -#include "collada_utils.h" -#include "BlenderContext.h" -#include "BKE_key.h" - -class Normal { - public: - float x; - float y; - float z; - - friend bool operator<(const Normal &, const Normal &); -}; - -bool operator<(const Normal &, const Normal &); - -/* TODO: optimize UV sets by making indexed list with duplicates removed */ -class GeometryExporter : COLLADASW::LibraryGeometries { - struct Face { - unsigned int v1, v2, v3, v4; - }; - - public: - /* TODO: optimize UV sets by making indexed list with duplicates removed */ - GeometryExporter(BlenderContext &blender_context, - COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings) - : COLLADASW::LibraryGeometries(sw), - blender_context(blender_context), - export_settings(export_settings) - { - } - - void exportGeom(); - - void operator()(Object *ob); - - void createLooseEdgeList(Object *ob, Mesh *me, std::string &geom_id); - - /* powerful because it handles both cases when there is material and when there's not */ - void create_mesh_primitive_list(short material_index, - bool has_uvs, - bool has_color, - Object *ob, - Mesh *me, - std::string &geom_id, - std::vector<BCPolygonNormalsIndices> &norind); - - /* creates <source> for positions */ - void createVertsSource(std::string geom_id, Mesh *me); - - void createVertexColorSource(std::string geom_id, Mesh *me); - - std::string makeTexcoordSourceId(std::string &geom_id, int layer_index, bool is_single_layer); - - /* creates <source> for texcoords */ - void createTexcoordsSource(std::string geom_id, Mesh *me); - void createTesselatedTexcoordsSource(std::string geom_id, Mesh *me); - - /* creates <source> for normals */ - void createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal> &nor); - - void create_normals(std::vector<Normal> &nor, - std::vector<BCPolygonNormalsIndices> &ind, - Mesh *me); - - std::string getIdBySemantics(std::string geom_id, - COLLADASW::InputSemantic::Semantics type, - std::string other_suffix = ""); - std::string makeVertexColorSourceId(std::string &geom_id, char *layer_name); - - COLLADASW::URI getUrlBySemantics(std::string geom_id, - COLLADASW::InputSemantic::Semantics type, - std::string other_suffix = ""); - - COLLADASW::URI makeUrl(std::string id); - - void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb); - - private: - std::set<std::string> exportedGeometry; - BlenderContext &blender_context; - BCExportSettings &export_settings; - - Mesh *get_mesh(Scene *sce, Object *ob, int apply_modifiers); -}; - -struct GeometryFunctor { - /* f should have - * void operator()(Object *ob) */ - template<class Functor> - void forEachMeshObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) - { - LinkNode *node; - for (node = export_set; node; node = node->next) { - Object *ob = (Object *)node->link; - if (ob->type == OB_MESH) { - f(ob); - } - } - } -}; - -#endif diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp deleted file mode 100644 index 6e31e17fb26..00000000000 --- a/source/blender/collada/ImageExporter.cpp +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "COLLADABUURI.h" -#include "COLLADASWImage.h" - -extern "C" { -#include "DNA_texture_types.h" -#include "DNA_image_types.h" -#include "DNA_meshdata_types.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_mesh.h" - -#include "BLI_fileops.h" -#include "BLI_path_util.h" -#include "BLI_string.h" - -#include "IMB_imbuf_types.h" -} - -#include "ImageExporter.h" -#include "MaterialExporter.h" - -ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings, - KeyImageMap &key_image_map) - : COLLADASW::LibraryImages(sw), export_settings(export_settings), key_image_map(key_image_map) -{ - /* pass */ -} - -void ImagesExporter::export_UV_Image(Image *image, bool use_copies) -{ - std::string name(id_name(image)); - std::string translated_name(translate_id(name)); - - ImBuf *imbuf = BKE_image_acquire_ibuf(image, NULL, NULL); - if (!imbuf) { - fprintf(stderr, "Collada export: image does not exist:\n%s\n", image->name); - return; - } - - bool is_dirty = BKE_image_is_dirty(image); - - ImageFormatData imageFormat; - BKE_imbuf_to_image_format(&imageFormat, imbuf); - - short image_source = image->source; - bool is_generated = image_source == IMA_SRC_GENERATED; - bool is_packed = BKE_image_has_packedfile(image); - - char export_path[FILE_MAX]; - char source_path[FILE_MAX]; - char export_dir[FILE_MAX]; - char export_file[FILE_MAX]; - - /* Destination folder for exported assets */ - BLI_split_dir_part(this->export_settings.get_filepath(), export_dir, sizeof(export_dir)); - - if (is_generated || is_dirty || use_copies || is_packed) { - - /* make absolute destination path */ - - BLI_strncpy(export_file, name.c_str(), sizeof(export_file)); - BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat); - - BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file); - - /* make dest directory if it doesn't exist */ - BLI_make_existing_file(export_path); - } - - if (is_generated || is_dirty || is_packed) { - - /* This image in its current state only exists in Blender memory. - * So we have to export it. The export will keep the image state intact, - * so the exported file will not be associated with the image. */ - - if (BKE_imbuf_write_as(imbuf, export_path, &imageFormat, true) == 0) { - fprintf(stderr, "Collada export: Cannot export image to:\n%s\n", export_path); - return; - } - BLI_strncpy(export_path, export_file, sizeof(export_path)); - } - else { - - /* make absolute source path */ - BLI_strncpy(source_path, image->name, sizeof(source_path)); - BLI_path_abs(source_path, ID_BLEND_PATH_FROM_GLOBAL(&image->id)); - BLI_cleanup_path(NULL, source_path); - - if (use_copies) { - - /* This image is already located on the file system. - * But we want to create copies here. - * To move images into the same export directory. - * Note: If an image is already located in the export folder, - * then skip the copy (as it would result in a file copy error). */ - - if (BLI_path_cmp(source_path, export_path) != 0) { - if (BLI_copy(source_path, export_path) != 0) { - fprintf(stderr, - "Collada export: Cannot copy image:\n source:%s\ndest :%s\n", - source_path, - export_path); - return; - } - } - - BLI_strncpy(export_path, export_file, sizeof(export_path)); - } - else { - - /* Do not make any copies, but use the source path directly as reference - * to the original image */ - - BLI_strncpy(export_path, source_path, sizeof(export_path)); - } - } - - /* Set name also to mNameNC. - * This helps other viewers import files exported from Blender better. */ - COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), - translated_name, - translated_name); - img.add(mSW); - fprintf(stdout, "Collada export: Added image: %s\n", export_file); - - BKE_image_release_ibuf(image, imbuf, NULL); -} - -void ImagesExporter::exportImages(Scene *sce) -{ - bool use_texture_copies = this->export_settings.get_use_texture_copies(); - openLibrary(); - - KeyImageMap::iterator iter; - for (iter = key_image_map.begin(); iter != key_image_map.end(); iter++) { - - Image *image = iter->second; - std::string uid(id_name(image)); - std::string key = translate_id(uid); - - export_UV_Image(image, use_texture_copies); - } - - closeLibrary(); -} diff --git a/source/blender/collada/ImageExporter.h b/source/blender/collada/ImageExporter.h deleted file mode 100644 index b72d2709382..00000000000 --- a/source/blender/collada/ImageExporter.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __IMAGEEXPORTER_H__ -#define __IMAGEEXPORTER_H__ - -#include <vector> -#include <string> - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryImages.h" - -#include "DNA_material_types.h" -#include "DNA_image_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "ExportSettings.h" -#include "collada_utils.h" - -class ImagesExporter : COLLADASW::LibraryImages { - public: - ImagesExporter(COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings, - KeyImageMap &key_image_map); - void exportImages(Scene *sce); - - private: - BCExportSettings &export_settings; - KeyImageMap &key_image_map; - void export_UV_Image(Image *image, bool use_texture_copies); -}; - -#endif diff --git a/source/blender/collada/ImportSettings.cpp b/source/blender/collada/ImportSettings.cpp deleted file mode 100644 index 049ee1d0975..00000000000 --- a/source/blender/collada/ImportSettings.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "ImportSettings.h" diff --git a/source/blender/collada/ImportSettings.h b/source/blender/collada/ImportSettings.h deleted file mode 100644 index 608d8bff882..00000000000 --- a/source/blender/collada/ImportSettings.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __IMPORTSETTINGS_H__ -#define __IMPORTSETTINGS_H__ - -typedef struct ImportSettings { - bool import_units; - bool find_chains; - bool auto_connect; - bool fix_orientation; - int min_chain_length; - char *filepath; - bool keep_bind_info; -} ImportSettings; - -#endif diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp deleted file mode 100644 index c9390d23fe7..00000000000 --- a/source/blender/collada/InstanceWriter.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <string> -#include <sstream> - -#include "COLLADASWInstanceMaterial.h" - -extern "C" { -#include "BKE_customdata.h" -#include "BKE_material.h" -#include "DNA_mesh_types.h" -} - -#include "InstanceWriter.h" -#include "collada_internal.h" -#include "collada_utils.h" - -void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial &bind_material, - Object *ob, - bool active_uv_only) -{ - for (int a = 0; a < ob->totcol; a++) { - Material *ma = BKE_object_material_get(ob, a + 1); - - COLLADASW::InstanceMaterialList &iml = bind_material.getInstanceMaterialList(); - - if (ma) { - std::string matid(get_material_id(ma)); - matid = translate_id(matid); - std::ostringstream ostr; - ostr << matid; - COLLADASW::InstanceMaterial im(ostr.str(), - COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid)); - - // create <bind_vertex_input> for each uv map - Mesh *me = (Mesh *)ob->data; - - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - - int map_index = 0; - int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); - for (int b = 0; b < num_layers; b++) { - if (!active_uv_only || b == active_uv_index) { - char *name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, b); - im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++)); - } - } - - iml.push_back(im); - } - } -} diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h deleted file mode 100644 index cfec1cf7006..00000000000 --- a/source/blender/collada/InstanceWriter.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __INSTANCEWRITER_H__ -#define __INSTANCEWRITER_H__ - -#include "COLLADASWBindMaterial.h" - -#include "DNA_object_types.h" - -class InstanceWriter { - protected: - void add_material_bindings(COLLADASW::BindMaterial &bind_material, - Object *ob, - bool active_uv_only); -}; - -#endif diff --git a/source/blender/collada/LightExporter.cpp b/source/blender/collada/LightExporter.cpp deleted file mode 100644 index 463981ceefa..00000000000 --- a/source/blender/collada/LightExporter.cpp +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <string> - -#include "COLLADASWColor.h" -#include "COLLADASWLight.h" - -#include "BLI_math.h" - -#include "LightExporter.h" -#include "collada_internal.h" - -template<class Functor> -void forEachLightObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set) -{ - LinkNode *node; - for (node = export_set; node; node = node->next) { - Object *ob = (Object *)node->link; - - if (ob->type == OB_LAMP && ob->data) { - f(ob); - } - } -} - -LightsExporter::LightsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings) - : COLLADASW::LibraryLights(sw), export_settings(export_settings) -{ -} - -void LightsExporter::exportLights(Scene *sce) -{ - openLibrary(); - - forEachLightObjectInExportSet(sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); -} - -void LightsExporter::operator()(Object *ob) -{ - Light *la = (Light *)ob->data; - std::string la_id(get_light_id(ob)); - std::string la_name(id_name(la)); - COLLADASW::Color col(la->r * la->energy, la->g * la->energy, la->b * la->energy); - float d, constatt, linatt, quadatt; - - d = la->dist; - - constatt = 1.0f; - - if (la->falloff_type == LA_FALLOFF_INVLINEAR) { - linatt = 1.0f / d; - quadatt = 0.0f; - } - else { - linatt = 0.0f; - quadatt = 1.0f / (d * d); - } - - // sun - if (la->type == LA_SUN) { - COLLADASW::DirectionalLight cla(mSW, la_id, la_name); - cla.setColor(col, false, "color"); - cla.setConstantAttenuation(constatt); - exportBlenderProfile(cla, la); - addLight(cla); - } - - // spot - else if (la->type == LA_SPOT) { - COLLADASW::SpotLight cla(mSW, la_id, la_name); - cla.setColor(col, false, "color"); - cla.setFallOffAngle(RAD2DEGF(la->spotsize), false, "fall_off_angle"); - cla.setFallOffExponent(la->spotblend, false, "fall_off_exponent"); - cla.setConstantAttenuation(constatt); - cla.setLinearAttenuation(linatt); - cla.setQuadraticAttenuation(quadatt); - exportBlenderProfile(cla, la); - addLight(cla); - } - // lamp - else if (la->type == LA_LOCAL) { - COLLADASW::PointLight cla(mSW, la_id, la_name); - cla.setColor(col, false, "color"); - cla.setConstantAttenuation(constatt); - cla.setLinearAttenuation(linatt); - cla.setQuadraticAttenuation(quadatt); - exportBlenderProfile(cla, la); - addLight(cla); - } - // area light is not supported - // it will be exported as a local lamp - else { - COLLADASW::PointLight cla(mSW, la_id, la_name); - cla.setColor(col, false, "color"); - cla.setConstantAttenuation(constatt); - cla.setLinearAttenuation(linatt); - cla.setQuadraticAttenuation(quadatt); - exportBlenderProfile(cla, la); - addLight(cla); - } -} - -bool LightsExporter::exportBlenderProfile(COLLADASW::Light &cla, Light *la) -{ - cla.addExtraTechniqueParameter("blender", "type", la->type); - cla.addExtraTechniqueParameter("blender", "flag", la->flag); - cla.addExtraTechniqueParameter("blender", "mode", la->mode); - cla.addExtraTechniqueParameter("blender", "gamma", la->k, "blender_gamma"); - cla.addExtraTechniqueParameter("blender", "red", la->r); - cla.addExtraTechniqueParameter("blender", "green", la->g); - cla.addExtraTechniqueParameter("blender", "blue", la->b); - cla.addExtraTechniqueParameter("blender", "shadow_r", la->shdwr, "blender_shadow_r"); - cla.addExtraTechniqueParameter("blender", "shadow_g", la->shdwg, "blender_shadow_g"); - cla.addExtraTechniqueParameter("blender", "shadow_b", la->shdwb, "blender_shadow_b"); - cla.addExtraTechniqueParameter("blender", "energy", la->energy, "blender_energy"); - cla.addExtraTechniqueParameter("blender", "dist", la->dist, "blender_dist"); - cla.addExtraTechniqueParameter("blender", "spotsize", RAD2DEGF(la->spotsize)); - cla.addExtraTechniqueParameter("blender", "spotblend", la->spotblend); - cla.addExtraTechniqueParameter("blender", "att1", la->att1); - cla.addExtraTechniqueParameter("blender", "att2", la->att2); - // \todo figure out how we can have falloff curve supported here - cla.addExtraTechniqueParameter("blender", "falloff_type", la->falloff_type); - cla.addExtraTechniqueParameter("blender", "clipsta", la->clipsta); - cla.addExtraTechniqueParameter("blender", "clipend", la->clipend); - cla.addExtraTechniqueParameter("blender", "bias", la->bias); - cla.addExtraTechniqueParameter("blender", "soft", la->soft); - cla.addExtraTechniqueParameter("blender", "bufsize", la->bufsize); - cla.addExtraTechniqueParameter("blender", "samp", la->samp); - cla.addExtraTechniqueParameter("blender", "buffers", la->buffers); - cla.addExtraTechniqueParameter("blender", "area_shape", la->area_shape); - cla.addExtraTechniqueParameter("blender", "area_size", la->area_size); - cla.addExtraTechniqueParameter("blender", "area_sizey", la->area_sizey); - cla.addExtraTechniqueParameter("blender", "area_sizez", la->area_sizez); - - return true; -} diff --git a/source/blender/collada/LightExporter.h b/source/blender/collada/LightExporter.h deleted file mode 100644 index 045ccfe1ce8..00000000000 --- a/source/blender/collada/LightExporter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __LIGHTEXPORTER_H__ -#define __LIGHTEXPORTER_H__ - -#include "COLLADASWStreamWriter.h" -#include "COLLADASWLibraryLights.h" - -#include "DNA_light_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "ExportSettings.h" - -class LightsExporter : COLLADASW::LibraryLights { - public: - LightsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); - void exportLights(Scene *sce); - void operator()(Object *ob); - - private: - bool exportBlenderProfile(COLLADASW::Light &cla, Light *la); - BCExportSettings &export_settings; -}; - -#endif diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp deleted file mode 100644 index 488d1833e48..00000000000 --- a/source/blender/collada/MaterialExporter.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "MaterialExporter.h" -#include "COLLADABUUtils.h" -#include "collada_internal.h" - -MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, - BCExportSettings &export_settings) - : COLLADASW::LibraryMaterials(sw), export_settings(export_settings) -{ - /* pass */ -} - -void MaterialsExporter::exportMaterials(Scene *sce) -{ - if (hasMaterials(sce)) { - openLibrary(); - - MaterialFunctor mf; - mf.forEachMaterialInExportSet<MaterialsExporter>( - sce, *this, this->export_settings.get_export_set()); - - closeLibrary(); - } -} - -bool MaterialsExporter::hasMaterials(Scene *sce) -{ - LinkNode *node; - for (node = this->export_settings.get_export_set(); node; node = node->next) { - Object *ob = (Object *)node->link; - int a; - for (a = 0; a < ob->totcol; a++) { - Material *ma = BKE_object_material_get(ob, a + 1); - - // no material, but check all of the slots - if (!ma) { - continue; - } - - return true; - } - } - return false; -} - -void MaterialsExporter::operator()(Material *ma, Object *ob) -{ - std::string mat_name = encode_xml(id_name(ma)); - std::string mat_id = get_material_id(ma); - std::string eff_id = get_effect_id(ma); - - openMaterial(mat_id, mat_name); - addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, eff_id)); - - closeMaterial(); -} diff --git a/source/blender/collada/MaterialExporter.h b/source/blender/collada/MaterialExporter.h deleted file mode 100644 index be0d939b68a..00000000000 --- a/source/blender/collada/MaterialExporter.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __MATERIALEXPORTER_H__ -#define __MATERIALEXPORTER_H__ - -#include <string> -#include <vector> - -#include "COLLADASWLibraryMaterials.h" -#include "COLLADASWStreamWriter.h" - -extern "C" { -#include "BKE_material.h" -#include "DNA_material_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -} - -#include "GeometryExporter.h" -#include "collada_internal.h" -#include "ExportSettings.h" -#include "Materials.h" - -class MaterialsExporter : COLLADASW::LibraryMaterials { - public: - MaterialsExporter(COLLADASW::StreamWriter *sw, BCExportSettings &export_settings); - void exportMaterials(Scene *sce); - void operator()(Material *ma, Object *ob); - - private: - bool hasMaterials(Scene *sce); - BCExportSettings &export_settings; -}; - -// used in forEachMaterialInScene -template<class Functor> class ForEachMaterialFunctor { - std::vector<std::string> - mMat; // contains list of material names, to avoid duplicate calling of f - Functor *f; - - public: - ForEachMaterialFunctor(Functor *f) : f(f) - { - } - - void operator()(Object *ob) - { - int a; - for (a = 0; a < ob->totcol; a++) { - - Material *ma = BKE_object_material_get(ob, a + 1); - - if (!ma) { - continue; - } - - std::string translated_id = translate_id(id_name(ma)); - if (find(mMat.begin(), mMat.end(), translated_id) == mMat.end()) { - (*this->f)(ma, ob); - - mMat.push_back(translated_id); - } - } - } -}; - -struct MaterialFunctor { - // calls f for each unique material linked to each object in sce - // f should have - // void operator()(Material *ma) - template<class Functor> - void forEachMaterialInExportSet(Scene *sce, Functor &f, LinkNode *export_set) - { - ForEachMaterialFunctor<Functor> matfunc(&f); - GeometryFunctor gf; - gf.forEachMeshObjectInExportSet<ForEachMaterialFunctor<Functor>>(sce, matfunc, export_set); - } -}; - -#endif diff --git a/source/blender/collada/Materials.cpp b/source/blender/collada/Materials.cpp deleted file mode 100644 index 06f54884668..00000000000 --- a/source/blender/collada/Materials.cpp +++ /dev/null @@ -1,396 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "Materials.h" - -MaterialNode::MaterialNode(bContext *C, Material *ma, KeyImageMap &key_image_map) - : mContext(C), material(ma), effect(nullptr), key_image_map(&key_image_map) -{ - bNodeTree *new_ntree = prepare_material_nodetree(); - setShaderType(); - if (new_ntree) { - shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300, ""); - output_node = add_node(SH_NODE_OUTPUT_MATERIAL, 300, 300, ""); - add_link(shader_node, 0, output_node, 0); - } -} - -MaterialNode::MaterialNode(bContext *C, - COLLADAFW::EffectCommon *ef, - Material *ma, - UidImageMap &uid_image_map) - : mContext(C), material(ma), effect(ef), uid_image_map(&uid_image_map) -{ - prepare_material_nodetree(); - setShaderType(); - - std::map<std::string, bNode *> nmap; -#if 0 - nmap["main"] = add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, -300, 300); - nmap["emission"] = add_node(C, ntree, SH_NODE_EMISSION, -300, 500, "emission"); - nmap["add"] = add_node(C, ntree, SH_NODE_ADD_SHADER, 100, 400); - nmap["transparent"] = add_node(C, ntree, SH_NODE_BSDF_TRANSPARENT, 100, 200); - nmap["mix"] = add_node(C, ntree, SH_NODE_MIX_SHADER, 400, 300, "transparency"); - nmap["out"] = add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 600, 300); - nmap["out"]->flag &= ~NODE_SELECT; - - add_link(ntree, nmap["emission"], 0, nmap["add"], 0); - add_link(ntree, nmap["main"], 0, nmap["add"], 1); - add_link(ntree, nmap["add"], 0, nmap["mix"], 1); - add_link(ntree, nmap["transparent"], 0, nmap["mix"], 2); - - add_link(ntree, nmap["mix"], 0, nmap["out"], 0); - // experimental, probably not used. - make_group(C, ntree, nmap); -#else - shader_node = add_node(SH_NODE_BSDF_PRINCIPLED, 0, 300, ""); - output_node = add_node(SH_NODE_OUTPUT_MATERIAL, 300, 300, ""); - add_link(shader_node, 0, output_node, 0); -#endif -} - -void MaterialNode::setShaderType() -{ -#if 0 - COLLADAFW::EffectCommon::ShaderType shader = ef->getShaderType(); - // Currently we only support PBR based shaders - // TODO: simulate the effects with PBR - - // blinn - if (shader == COLLADAFW::EffectCommon::SHADER_BLINN) { - ma->spec_shader = MA_SPEC_BLINN; - ma->spec = ef->getShininess().getFloatValue(); - } - // phong - else if (shader == COLLADAFW::EffectCommon::SHADER_PHONG) { - ma->spec_shader = MA_SPEC_PHONG; - ma->har = ef->getShininess().getFloatValue(); - } - // lambert - else if (shader == COLLADAFW::EffectCommon::SHADER_LAMBERT) { - ma->diff_shader = MA_DIFF_LAMBERT; - } - // default - lambert - else { - ma->diff_shader = MA_DIFF_LAMBERT; - fprintf(stderr, "Current shader type is not supported, default to lambert.\n"); - } -#endif -} - -// returns null if material already has a node tree -bNodeTree *MaterialNode::prepare_material_nodetree() -{ - if (material->nodetree) { - ntree = material->nodetree; - return NULL; - } - - material->nodetree = ntreeAddTree(NULL, "Shader Nodetree", "ShaderNodeTree"); - material->use_nodes = true; - ntree = material->nodetree; - return ntree; -} - -bNode *MaterialNode::add_node(int node_type, int locx, int locy, std::string label) -{ - bNode *node = nodeAddStaticNode(mContext, ntree, node_type); - if (node) { - if (label.length() > 0) { - strcpy(node->label, label.c_str()); - } - node->locx = locx; - node->locy = locy; - node->flag |= NODE_SELECT; - } - node_map[label] = node; - return node; -} - -void MaterialNode::add_link(bNode *from_node, int from_index, bNode *to_node, int to_index) -{ - bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index); - bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index); - - nodeAddLink(ntree, from_node, from_socket, to_node, to_socket); -} - -void MaterialNode::set_reflectivity(COLLADAFW::FloatOrParam &val) -{ - float reflectivity = val.getFloatValue(); - if (reflectivity >= 0) { - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Metallic"); - ((bNodeSocketValueFloat *)socket->default_value)->value = reflectivity; - material->metallic = reflectivity; - } -} - -#if 0 -// needs rework to be done for 2.81 -void MaterialNode::set_shininess(COLLADAFW::FloatOrParam &val) -{ - float roughness = val.getFloatValue(); - if (roughness >= 0) { - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Roughness"); - ((bNodeSocketValueFloat *)socket->default_value)->value = roughness; - } -} -#endif - -void MaterialNode::set_ior(COLLADAFW::FloatOrParam &val) -{ - float ior = val.getFloatValue(); - if (ior < 0) { - fprintf(stderr, - "IOR of negative value is not allowed for materials (using Blender default value " - "instead)"); - return; - } - - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "IOR"); - ((bNodeSocketValueFloat *)socket->default_value)->value = ior; -} - -void MaterialNode::set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode, - COLLADAFW::ColorOrTexture &cot, - COLLADAFW::FloatOrParam &val) -{ - /* Handling the alpha value according to the Collada 1.4 reference guide - * see page 7-5 Determining Transparency (Opacity) - */ - - if (effect == nullptr) { - return; - } - - if (cot.isColor() || !cot.isValid()) { - // transparent_cot is either a color or not defined - - float transparent_alpha; - if (cot.isValid()) { - COLLADAFW::Color col = cot.getColor(); - transparent_alpha = col.getAlpha(); - } - else { - // no transparent color defined - transparent_alpha = 1; - } - - float transparency_alpha = val.getFloatValue(); - if (transparency_alpha < 0) { - // transparency is not defined - transparency_alpha = 1; // set to opaque - } - - float alpha = transparent_alpha * transparency_alpha; - if (mode == COLLADAFW::EffectCommon::RGB_ZERO) { - alpha = 1 - alpha; - } - - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Alpha"); - ((bNodeSocketValueFloat *)socket->default_value)->value = alpha; - material->a = alpha; - } - else if (cot.isTexture()) { - int locy = -300 * (node_map.size() - 2); - add_texture_node(cot, -300, locy, "Alpha"); - } -} - -void MaterialNode::set_diffuse(COLLADAFW::ColorOrTexture &cot) -{ - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = cot.getColor(); - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Base Color"); - float *fcol = (float *)socket->default_value; - - fcol[0] = material->r = col.getRed(); - fcol[1] = material->g = col.getGreen(); - fcol[2] = material->b = col.getBlue(); - fcol[3] = material->a = col.getAlpha(); - } - else if (cot.isTexture()) { - bNode *texture_node = add_texture_node(cot, -300, locy, "Base Color"); - if (texture_node != NULL) { - add_link(texture_node, 0, shader_node, 0); - } - } -} - -Image *MaterialNode::get_diffuse_image() -{ - bNode *shader = ntreeFindType(ntree, SH_NODE_BSDF_PRINCIPLED); - if (shader == nullptr) { - return nullptr; - } - - bNodeSocket *in_socket = nodeFindSocket(shader, SOCK_IN, "Base Color"); - if (in_socket == nullptr) { - return nullptr; - } - - bNodeLink *link = in_socket->link; - if (link == nullptr) { - return nullptr; - } - - bNode *texture = link->fromnode; - if (texture == nullptr) { - return nullptr; - } - - if (texture->type != SH_NODE_TEX_IMAGE) { - return nullptr; - } - - Image *image = (Image *)texture->id; - return image; -} - -static bNodeSocket *set_color(bNode *node, COLLADAFW::Color col) -{ - bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->outputs, 0); - float *fcol = (float *)socket->default_value; - fcol[0] = col.getRed(); - fcol[1] = col.getGreen(); - fcol[2] = col.getBlue(); - - return socket; -} - -void MaterialNode::set_ambient(COLLADAFW::ColorOrTexture &cot) -{ - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = cot.getColor(); - bNode *node = add_node(SH_NODE_RGB, -300, locy, "Ambient"); - set_color(node, col); - // TODO: Connect node - } - // texture - else if (cot.isTexture()) { - add_texture_node(cot, -300, locy, "Ambient"); - // TODO: Connect node - } -} - -void MaterialNode::set_reflective(COLLADAFW::ColorOrTexture &cot) -{ - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = cot.getColor(); - bNode *node = add_node(SH_NODE_RGB, -300, locy, "Reflective"); - set_color(node, col); - // TODO: Connect node - } - // texture - else if (cot.isTexture()) { - add_texture_node(cot, -300, locy, "Reflective"); - // TODO: Connect node - } -} - -void MaterialNode::set_emission(COLLADAFW::ColorOrTexture &cot) -{ - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = cot.getColor(); - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Emission"); - float *fcol = (float *)socket->default_value; - - fcol[0] = col.getRed(); - fcol[1] = col.getGreen(); - fcol[2] = col.getBlue(); - fcol[3] = col.getAlpha(); - } - else if (cot.isTexture()) { - bNode *texture_node = add_texture_node(cot, -300, locy, "Emission"); - if (texture_node != NULL) { - add_link(texture_node, 0, shader_node, 0); - } - } -} - -void MaterialNode::set_opacity(COLLADAFW::ColorOrTexture &cot) -{ - if (effect == nullptr) { - return; - } - - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = effect->getTransparent().getColor(); - float alpha = effect->getTransparency().getFloatValue(); - - if (col.isValid()) { - alpha *= col.getAlpha(); // Assuming A_ONE opaque mode - } - - bNodeSocket *socket = nodeFindSocket(shader_node, SOCK_IN, "Alpha"); - ((bNodeSocketValueFloat *)socket->default_value)->value = alpha; - } - // texture - else if (cot.isTexture()) { - add_texture_node(cot, -300, locy, "Alpha"); - // TODO: Connect node - } -} - -void MaterialNode::set_specular(COLLADAFW::ColorOrTexture &cot) -{ - int locy = -300 * (node_map.size() - 2); - if (cot.isColor()) { - COLLADAFW::Color col = cot.getColor(); - bNode *node = add_node(SH_NODE_RGB, -300, locy, "Specular"); - set_color(node, col); - // TODO: Connect node - } - // texture - else if (cot.isTexture()) { - add_texture_node(cot, -300, locy, "Specular"); - // TODO: Connect node - } -} - -bNode *MaterialNode::add_texture_node(COLLADAFW::ColorOrTexture &cot, - int locx, - int locy, - std::string label) -{ - if (effect == nullptr) { - return nullptr; - } - - UidImageMap &image_map = *uid_image_map; - - COLLADAFW::Texture ctex = cot.getTexture(); - - COLLADAFW::SamplerPointerArray &samp_array = effect->getSamplerPointerArray(); - COLLADAFW::Sampler *sampler = samp_array[ctex.getSamplerId()]; - - const COLLADAFW::UniqueId &ima_uid = sampler->getSourceImage(); - - if (image_map.find(ima_uid) == image_map.end()) { - fprintf(stderr, "Couldn't find an image by UID.\n"); - return NULL; - } - - Image *ima = image_map[ima_uid]; - bNode *texture_node = add_node(SH_NODE_TEX_IMAGE, locx, locy, label); - texture_node->id = &ima->id; - return texture_node; -} diff --git a/source/blender/collada/Materials.h b/source/blender/collada/Materials.h deleted file mode 100644 index 0a4f2ee61a5..00000000000 --- a/source/blender/collada/Materials.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef __MATERIALS_H__ -#define __MATERIALS_H__ - -#include <map> -#include <string> - -extern "C" { -#include "BKE_context.h" -#include "BKE_node.h" -#include "BLI_listbase.h" -#include "DNA_material_types.h" -#include "DNA_node_types.h" -} - -#include "collada_utils.h" -#include "COLLADAFWEffectCommon.h" - -typedef std::map<std::string, bNode *> NodeMap; - -class MaterialNode { - - private: - bContext *mContext; - Material *material; - COLLADAFW::EffectCommon *effect; - UidImageMap *uid_image_map = nullptr; - KeyImageMap *key_image_map = nullptr; - - NodeMap node_map; - bNodeTree *ntree; - - bNode *shader_node; - bNode *output_node; - - bNodeTree *prepare_material_nodetree(); - bNode *add_node(int node_type, int locx, int locy, std::string label); - void add_link(bNode *from_node, int from_index, bNode *to_node, int to_index); - bNode *add_texture_node(COLLADAFW::ColorOrTexture &cot, int locx, int locy, std::string label); - void setShaderType(); - - public: - MaterialNode(bContext *C, COLLADAFW::EffectCommon *ef, Material *ma, UidImageMap &uid_image_map); - MaterialNode(bContext *C, Material *ma, KeyImageMap &key_image_map); - Image *get_diffuse_image(); - - void set_diffuse(COLLADAFW::ColorOrTexture &cot); - void set_specular(COLLADAFW::ColorOrTexture &cot); - void set_ambient(COLLADAFW::ColorOrTexture &cot); - void set_reflective(COLLADAFW::ColorOrTexture &cot); - void set_emission(COLLADAFW::ColorOrTexture &cot); - void set_opacity(COLLADAFW::ColorOrTexture &cot); - void set_reflectivity(COLLADAFW::FloatOrParam &val); - void set_shininess(COLLADAFW::FloatOrParam &val); - void set_ior(COLLADAFW::FloatOrParam &val); - void set_alpha(COLLADAFW::EffectCommon::OpaqueMode mode, - COLLADAFW::ColorOrTexture &cot, - COLLADAFW::FloatOrParam &val); -}; - -#endif /* __MATERIALS_H__ */ diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp deleted file mode 100644 index bc6dd4202b1..00000000000 --- a/source/blender/collada/MeshImporter.cpp +++ /dev/null @@ -1,1208 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <algorithm> -#include <iostream> - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "COLLADAFWMeshPrimitive.h" -#include "COLLADAFWMeshVertexData.h" -#include "COLLADAFWPolygons.h" - -#include "MEM_guardedalloc.h" - -extern "C" { -#include "BKE_customdata.h" -#include "BKE_displist.h" -#include "BKE_global.h" -#include "BKE_lib_id.h" -#include "BKE_material.h" -#include "BKE_mesh.h" -#include "BKE_object.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_string.h" -#include "BLI_edgehash.h" -} - -#include "ArmatureImporter.h" -#include "MeshImporter.h" -#include "collada_utils.h" - -// get node name, or fall back to original id if not present (name is optional) -template<class T> static const std::string bc_get_dae_name(T *node) -{ - return node->getName().size() ? node->getName() : node->getOriginalId(); -} - -static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type) -{ - switch (type) { - case COLLADAFW::MeshPrimitive::LINES: - return "LINES"; - case COLLADAFW::MeshPrimitive::LINE_STRIPS: - return "LINESTRIPS"; - case COLLADAFW::MeshPrimitive::POLYGONS: - return "POLYGONS"; - case COLLADAFW::MeshPrimitive::POLYLIST: - return "POLYLIST"; - case COLLADAFW::MeshPrimitive::TRIANGLES: - return "TRIANGLES"; - case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: - return "TRIANGLE_FANS"; - case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS: - return "TRIANGLE_STRIPS"; - case COLLADAFW::MeshPrimitive::POINTS: - return "POINTS"; - case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE: - return "UNDEFINED_PRIMITIVE_TYPE"; - } - return "UNKNOWN"; -} - -static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type) -{ - switch (type) { - case COLLADAFW::Geometry::GEO_TYPE_MESH: - return "MESH"; - case COLLADAFW::Geometry::GEO_TYPE_SPLINE: - return "SPLINE"; - case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH: - return "CONVEX_MESH"; - case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN: - default: - return "UNKNOWN"; - } -} - -UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData &vdata) : mVData(&vdata) -{ -} - -#ifdef COLLADA_DEBUG -void WVDataWrapper::print() -{ - fprintf(stderr, "UVs:\n"); - switch (mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); - if (values->getCount()) { - for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]); - } - } - } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); - if (values->getCount()) { - for (int i = 0; i < values->getCount(); i += 2) { - fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]); - } - } - } break; - } - fprintf(stderr, "\n"); -} -#endif - -void UVDataWrapper::getUV(int uv_index, float *uv) -{ - int stride = mVData->getStride(0); - if (stride == 0) { - stride = 2; - } - - switch (mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); - if (values->empty()) { - return; - } - uv[0] = (*values)[uv_index * stride]; - uv[1] = (*values)[uv_index * stride + 1]; - - } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); - if (values->empty()) { - return; - } - uv[0] = (float)(*values)[uv_index * stride]; - uv[1] = (float)(*values)[uv_index * stride + 1]; - - } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN: - default: - fprintf(stderr, "MeshImporter.getUV(): unknown data type\n"); - } -} - -VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData &vdata) : mVData(&vdata) -{ -} - -void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol) -{ - int stride = mVData->getStride(0); - if (stride == 0) { - stride = 3; - } - - switch (mVData->getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues(); - if (values->empty() || values->getCount() <= (v_index * stride + 2)) { - return; // xxx need to create an error instead - } - - mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]); - mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]); - mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]); - } break; - - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues(); - if (values->empty() || values->getCount() <= (v_index * stride + 2)) { - return; // xxx need to create an error instead - } - - mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]); - mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]); - mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]); - } break; - default: - fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n"); - } -} - -MeshImporter::MeshImporter( - UnitConverter *unitconv, ArmatureImporter *arm, Main *bmain, Scene *sce, ViewLayer *view_layer) - : unitconverter(unitconv), - m_bmain(bmain), - scene(sce), - view_layer(view_layer), - armature_importer(arm) -{ - /* pass */ -} - -bool MeshImporter::set_poly_indices( - MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count) -{ - mpoly->loopstart = loop_index; - mpoly->totloop = loop_count; - bool broken_loop = false; - for (int index = 0; index < loop_count; index++) { - - /* Test if loop defines a hole */ - if (!broken_loop) { - for (int i = 0; i < index; i++) { - if (indices[i] == indices[index]) { - // duplicate index -> not good - broken_loop = true; - } - } - } - - mloop->v = indices[index]; - mloop++; - } - return broken_loop; -} - -void MeshImporter::set_vcol(MLoopCol *mlc, - VCOLDataWrapper &vob, - int loop_index, - COLLADAFW::IndexList &index_list, - int count) -{ - int index; - for (index = 0; index < count; index++, mlc++) { - int v_index = index_list.getIndex(index + loop_index); - vob.get_vcol(v_index, mlc); - } -} - -void MeshImporter::set_face_uv(MLoopUV *mloopuv, - UVDataWrapper &uvs, - int start_index, - COLLADAFW::IndexList &index_list, - int count) -{ - // per face vertex indices, this means for quad we have 4 indices, not 8 - COLLADAFW::UIntValuesArray &indices = index_list.getIndices(); - - for (int index = 0; index < count; index++) { - int uv_index = indices[index + start_index]; - uvs.getUV(uv_index, mloopuv[index].uv); - } -} - -#ifdef COLLADA_DEBUG -void MeshImporter::print_index_list(COLLADAFW::IndexList &index_list) -{ - fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str()); - for (int i = 0; i < index_list.getIndicesCount(); i += 2) { - fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1)); - } - fprintf(stderr, "\n"); -} -#endif - -/* checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans */ -bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) -{ - COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives(); - - const std::string &name = bc_get_dae_name(mesh); - - for (unsigned int i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType(); - - const char *type_str = bc_primTypeToStr(type); - - // OpenCollada passes POLYGONS type for <polylist> - if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) { - - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; - COLLADAFW::Polygons::VertexCountArray &vca = mpvc->getGroupedVerticesVertexCountArray(); - - int hole_count = 0; - int nonface_count = 0; - - for (unsigned int j = 0; j < vca.getCount(); j++) { - int count = vca[j]; - if (abs(count) < 3) { - nonface_count++; - } - - if (count < 0) { - hole_count++; - } - } - - if (hole_count > 0) { - fprintf(stderr, - "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", - type_str, - name.c_str(), - hole_count); - } - - if (nonface_count > 0) { - fprintf(stderr, - "WARNING: Primitive %s in %s: %d faces with vertex count < 3 (rejected)\n", - type_str, - name.c_str(), - nonface_count); - } - } - - else if (type == COLLADAFW::MeshPrimitive::LINES) { - // TODO: Add Checker for line syntax here - } - - else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && - type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { - fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str); - return false; - } - } - - return true; -} - -void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me) -{ - // vertices - COLLADAFW::MeshVertexData &pos = mesh->getPositions(); - if (pos.empty()) { - return; - } - - int stride = pos.getStride(0); - if (stride == 0) { - stride = 3; - } - - me->totvert = pos.getFloatValues()->getCount() / stride; - me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - - MVert *mvert; - int i; - - for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) { - get_vector(mvert->co, pos, i, stride); - } -} - -// ===================================================================== -// condition 1: The Primitive has normals -// condition 2: The number of normals equals the number of faces. -// return true if both conditions apply. -// return false otherwise. -// ===================================================================== -bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) -{ - - bool has_useable_normals = false; - - int normals_count = mp->getNormalIndices().getCount(); - if (normals_count > 0) { - int index_count = mp->getPositionIndices().getCount(); - if (index_count == normals_count) { - has_useable_normals = true; - } - else { - fprintf(stderr, - "Warning: Number of normals %d is different from the number of vertices %d, " - "skipping normals\n", - normals_count, - index_count); - } - } - - return has_useable_normals; -} - -// ===================================================================== -// Assume that only TRIANGLES, TRIANGLE_FANS, POLYLIST and POLYGONS -// have faces. (to be verified) -// ===================================================================== -bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) -{ - - bool has_faces = false; - int type = mp->getPrimitiveType(); - switch (type) { - case COLLADAFW::MeshPrimitive::TRIANGLES: - case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: - case COLLADAFW::MeshPrimitive::POLYLIST: - case COLLADAFW::MeshPrimitive::POLYGONS: { - has_faces = true; - break; - } - default: { - has_faces = false; - break; - } - } - return has_faces; -} - -static std::string extract_vcolname(const COLLADAFW::String &collada_id) -{ - std::string colname = collada_id; - int spos = colname.find("-mesh-colors-"); - if (spos != std::string::npos) { - colname = colname.substr(spos + 13); - } - return colname; -} - -// ================================================================= -// Return the number of faces by summing up -// the facecounts of the parts. -// hint: This is done because mesh->getFacesCount() does -// count loose edges as extra faces, which is not what we want here. -// ================================================================= -void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me) -{ - COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives(); - int total_poly_count = 0; - int total_loop_count = 0; - - // collect edge_count and face_count from all parts - for (int i = 0; i < prim_arr.getCount(); i++) { - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - int type = mp->getPrimitiveType(); - switch (type) { - case COLLADAFW::MeshPrimitive::TRIANGLES: - case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: - case COLLADAFW::MeshPrimitive::POLYLIST: - case COLLADAFW::MeshPrimitive::POLYGONS: { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; - size_t prim_poly_count = mpvc->getFaceCount(); - - size_t prim_loop_count = 0; - for (int index = 0; index < prim_poly_count; index++) { - int vcount = get_vertex_count(mpvc, index); - if (vcount > 0) { - prim_loop_count += vcount; - total_poly_count++; - } - else { - // TODO: this is a hole and not another polygon! - } - } - - total_loop_count += prim_loop_count; - - break; - } - default: - break; - } - } - - // Add the data containers - if (total_poly_count > 0) { - me->totpoly = total_poly_count; - me->totloop = total_loop_count; - me->mpoly = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, me->totpoly); - me->mloop = (MLoop *)CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, me->totloop); - - unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount(); - for (int i = 0; i < totuvset; i++) { - if (collada_mesh->getUVCoords().getLength(i) == 0) { - totuvset = 0; - break; - } - } - - if (totuvset > 0) { - for (int i = 0; i < totuvset; i++) { - COLLADAFW::MeshVertexData::InputInfos *info = - collada_mesh->getUVCoords().getInputInfosArray()[i]; - COLLADAFW::String &uvname = info->mName; - // Allocate space for UV_data - CustomData_add_layer_named( - &me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str()); - } - // activate the first uv map - me->mloopuv = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0); - } - - int totcolset = collada_mesh->getColors().getInputInfosArray().getCount(); - if (totcolset > 0) { - for (int i = 0; i < totcolset; i++) { - COLLADAFW::MeshVertexData::InputInfos *info = - collada_mesh->getColors().getInputInfosArray()[i]; - COLLADAFW::String colname = extract_vcolname(info->mName); - CustomData_add_layer_named( - &me->ldata, CD_MLOOPCOL, CD_DEFAULT, NULL, me->totloop, colname.c_str()); - } - me->mloopcol = (MLoopCol *)CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0); - } - } -} - -unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index) -{ - int type = mp->getPrimitiveType(); - int result; - switch (type) { - case COLLADAFW::MeshPrimitive::TRIANGLES: - case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: { - result = 3; - break; - } - case COLLADAFW::MeshPrimitive::POLYLIST: - case COLLADAFW::MeshPrimitive::POLYGONS: { - result = mp->getGroupedVerticesVertexCountArray()[index]; - break; - } - default: { - result = -1; - break; - } - } - return result; -} - -unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) -{ - COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives(); - int loose_edge_count = 0; - - // collect edge_count and face_count from all parts - for (int i = 0; i < prim_arr.getCount(); i++) { - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - int type = mp->getPrimitiveType(); - switch (type) { - case COLLADAFW::MeshPrimitive::LINES: { - size_t prim_totface = mp->getFaceCount(); - loose_edge_count += prim_totface; - break; - } - default: - break; - } - } - return loose_edge_count; -} - -// ================================================================= -// This function is copied from source/blender/editors/mesh/mesh_data.c -// -// TODO: (As discussed with sergey-) : -// Maybe move this function to blenderkernel/intern/mesh.c -// and add definition to BKE_mesh.c -// ================================================================= -void MeshImporter::mesh_add_edges(Mesh *mesh, int len) -{ - CustomData edata; - MEdge *medge; - int totedge; - - if (len == 0) { - return; - } - - totedge = mesh->totedge + len; - - /* update customdata */ - CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH.emask, CD_DEFAULT, totedge); - CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge); - - if (!CustomData_has_layer(&edata, CD_MEDGE)) { - CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge); - } - - CustomData_free(&mesh->edata, mesh->totedge); - mesh->edata = edata; - BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */ - - /* set default flags */ - medge = &mesh->medge[mesh->totedge]; - for (int i = 0; i < len; i++, medge++) { - medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT; - } - - mesh->totedge = totedge; -} - -// ================================================================= -// Read all loose edges. -// Important: This function assumes that all edges from existing -// faces have already been generated and added to me->medge -// So this function MUST be called after read_faces() (see below) -// ================================================================= -void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me) -{ - unsigned int loose_edge_count = get_loose_edge_count(mesh); - if (loose_edge_count > 0) { - - unsigned int face_edge_count = me->totedge; - /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */ - - mesh_add_edges(me, loose_edge_count); - MEdge *med = me->medge + face_edge_count; - - COLLADAFW::MeshPrimitiveArray &prim_arr = mesh->getMeshPrimitives(); - - for (int index = 0; index < prim_arr.getCount(); index++) { - COLLADAFW::MeshPrimitive *mp = prim_arr[index]; - - int type = mp->getPrimitiveType(); - if (type == COLLADAFW::MeshPrimitive::LINES) { - unsigned int edge_count = mp->getFaceCount(); - unsigned int *indices = mp->getPositionIndices().getData(); - - for (int j = 0; j < edge_count; j++, med++) { - med->bweight = 0; - med->crease = 0; - med->flag |= ME_LOOSEEDGE; - med->v1 = indices[2 * j]; - med->v2 = indices[2 * j + 1]; - } - } - } - } -} - -// ======================================================================= -// Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON -// Important: This function MUST be called before read_lines() -// Otherwise we will loose all edges from faces (see read_lines() above) -// -// TODO: import uv set names -// ======================================================================== -void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me) -{ - unsigned int i; - - allocate_poly_data(collada_mesh, me); - - UVDataWrapper uvs(collada_mesh->getUVCoords()); - VCOLDataWrapper vcol(collada_mesh->getColors()); - - MPoly *mpoly = me->mpoly; - MLoop *mloop = me->mloop; - int loop_index = 0; - - MaterialIdPrimitiveArrayMap mat_prim_map; - - COLLADAFW::MeshPrimitiveArray &prim_arr = collada_mesh->getMeshPrimitives(); - COLLADAFW::MeshVertexData &nor = collada_mesh->getNormals(); - - for (i = 0; i < prim_arr.getCount(); i++) { - - COLLADAFW::MeshPrimitive *mp = prim_arr[i]; - - // faces - size_t prim_totpoly = mp->getFaceCount(); - unsigned int *position_indices = mp->getPositionIndices().getData(); - unsigned int *normal_indices = mp->getNormalIndices().getData(); - - bool mp_has_normals = primitive_has_useable_normals(mp); - bool mp_has_faces = primitive_has_faces(mp); - - int collada_meshtype = mp->getPrimitiveType(); - - // since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive - Primitive prim = {mpoly, 0}; - - // If MeshPrimitive is TRIANGLE_FANS we split it into triangles - // The first trifan vertex will be the first vertex in every triangle - // XXX The proper function of TRIANGLE_FANS is not tested!!! - // XXX In particular the handling of the normal_indices looks very wrong to me - if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) { - unsigned int grouped_vertex_count = mp->getGroupedVertexElementsCount(); - for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) { - unsigned int first_vertex = position_indices[0]; // Store first trifan vertex - unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal - unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index); - - for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) { - // For each triangle store indices of its 3 vertices - unsigned int triangle_vertex_indices[3] = { - first_vertex, position_indices[1], position_indices[2]}; - set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3); - - if (mp_has_normals) { // vertex normals, same implementation as for the triangles - // the same for vertces normals - unsigned int vertex_normal_indices[3] = { - first_normal, normal_indices[1], normal_indices[2]}; - if (!is_flat_face(vertex_normal_indices, nor, 3)) { - mpoly->flag |= ME_SMOOTH; - } - normal_indices++; - } - - mpoly++; - mloop += 3; - loop_index += 3; - prim.totpoly++; - } - - // Moving cursor to the next triangle fan. - if (mp_has_normals) { - normal_indices += 2; - } - - position_indices += 2; - } - } - - if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST || - collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS || - collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) { - COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp; - unsigned int start_index = 0; - - COLLADAFW::IndexListArray &index_list_array_uvcoord = mp->getUVCoordIndicesArray(); - COLLADAFW::IndexListArray &index_list_array_vcolor = mp->getColorIndicesArray(); - - int invalid_loop_holes = 0; - for (unsigned int j = 0; j < prim_totpoly; j++) { - - // Vertices in polygon: - int vcount = get_vertex_count(mpvc, j); - if (vcount < 0) { - continue; // TODO: add support for holes - } - - bool broken_loop = set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount); - if (broken_loop) { - invalid_loop_holes += 1; - } - - for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); - uvset_index++) { - // get mtface by face index and uv set index - COLLADAFW::IndexList &index_list = *index_list_array_uvcoord[uvset_index]; - MLoopUV *mloopuv = (MLoopUV *)CustomData_get_layer_named( - &me->ldata, CD_MLOOPUV, index_list.getName().c_str()); - if (mloopuv == NULL) { - fprintf(stderr, - "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", - me->id.name, - index_list.getName().c_str()); - } - else { - set_face_uv(mloopuv + loop_index, - uvs, - start_index, - *index_list_array_uvcoord[uvset_index], - vcount); - } - } - - if (mp_has_normals) { - if (!is_flat_face(normal_indices, nor, vcount)) { - mpoly->flag |= ME_SMOOTH; - } - } - - if (mp->hasColorIndices()) { - int vcolor_count = index_list_array_vcolor.getCount(); - - for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) { - - COLLADAFW::IndexList &color_index_list = *mp->getColorIndices(vcolor_index); - COLLADAFW::String colname = extract_vcolname(color_index_list.getName()); - MLoopCol *mloopcol = (MLoopCol *)CustomData_get_layer_named( - &me->ldata, CD_MLOOPCOL, colname.c_str()); - if (mloopcol == NULL) { - fprintf(stderr, - "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", - me->id.name, - color_index_list.getName().c_str()); - } - else { - set_vcol(mloopcol + loop_index, vcol, start_index, color_index_list, vcount); - } - } - } - - mpoly++; - mloop += vcount; - loop_index += vcount; - start_index += vcount; - prim.totpoly++; - - if (mp_has_normals) { - normal_indices += vcount; - } - - position_indices += vcount; - } - - if (invalid_loop_holes > 0) { - fprintf(stderr, - "Collada import: Mesh [%s] : contains %d unsupported loops (holes).\n", - me->id.name, - invalid_loop_holes); - } - } - - else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) { - continue; // read the lines later after all the rest is done - } - - if (mp_has_faces) { - mat_prim_map[mp->getMaterialId()].push_back(prim); - } - } - - geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map; -} - -void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i, int stride) -{ - i *= stride; - - switch (arr.getType()) { - case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT: { - COLLADAFW::ArrayPrimitiveType<float> *values = arr.getFloatValues(); - if (values->empty()) { - return; - } - - v[0] = (*values)[i++]; - v[1] = (*values)[i++]; - if (stride >= 3) { - v[2] = (*values)[i]; - } - else { - v[2] = 0.0f; - } - - } break; - case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE: { - COLLADAFW::ArrayPrimitiveType<double> *values = arr.getDoubleValues(); - if (values->empty()) { - return; - } - - v[0] = (float)(*values)[i++]; - v[1] = (float)(*values)[i++]; - if (stride >= 3) { - v[2] = (float)(*values)[i]; - } - else { - v[2] = 0.0f; - } - } break; - default: - break; - } -} - -bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData &nor, int count) -{ - float a[3], b[3]; - - get_vector(a, nor, *nind, 3); - normalize_v3(a); - - nind++; - - for (int i = 1; i < count; i++, nind++) { - get_vector(b, nor, *nind, 3); - normalize_v3(b); - - float dp = dot_v3v3(a, b); - - if (dp < 0.99999f || dp > 1.00001f) { - return false; - } - } - - return true; -} - -Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId &geom_uid) -{ - if (uid_object_map.find(geom_uid) != uid_object_map.end()) { - return uid_object_map[geom_uid]; - } - return NULL; -} - -Mesh *MeshImporter::get_mesh_by_geom_uid(const COLLADAFW::UniqueId &mesh_uid) -{ - if (uid_mesh_map.find(mesh_uid) != uid_mesh_map.end()) { - return uid_mesh_map[mesh_uid]; - } - return NULL; -} - -std::string *MeshImporter::get_geometry_name(const std::string &mesh_name) -{ - if (this->mesh_geom_map.find(mesh_name) != this->mesh_geom_map.end()) { - return &this->mesh_geom_map[mesh_name]; - } - return NULL; -} - -/** - * this function checks if both objects have the same - * materials assigned to Object (in the same order) - * returns true if condition matches, otherwise false; - */ -static bool bc_has_same_material_configuration(Object *ob1, Object *ob2) -{ - if (ob1->totcol != ob2->totcol) { - return false; // not same number of materials - } - if (ob1->totcol == 0) { - return false; // no material at all - } - - for (int index = 0; index < ob1->totcol; index++) { - if (ob1->matbits[index] != ob2->matbits[index]) { - return false; // shouldn't happen - } - if (ob1->matbits[index] == 0) { - return false; // shouldn't happen - } - if (ob1->mat[index] != ob2->mat[index]) { - return false; // different material assignment - } - } - return true; -} - -/** - * - * Caution here: This code assumes that all materials are assigned to Object - * and no material is assigned to Data. - * That is true right after the objects have been imported. - * - */ -static void bc_copy_materials_to_data(Object *ob, Mesh *me) -{ - for (int index = 0; index < ob->totcol; index++) { - ob->matbits[index] = 0; - me->mat[index] = ob->mat[index]; - } -} - -/** - * - * Remove all references to materials from the object - * - */ -static void bc_remove_materials_from_object(Object *ob, Mesh *me) -{ - for (int index = 0; index < ob->totcol; index++) { - ob->matbits[index] = 0; - ob->mat[index] = NULL; - } -} - -/** - * Returns the list of Users of the given Mesh object. - * Note: This function uses the object user flag to control - * which objects have already been processed. - */ -std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh) -{ - std::vector<Object *> mesh_users; - for (std::vector<Object *>::iterator it = imported_objects.begin(); it != imported_objects.end(); - ++it) { - Object *ob = (*it); - if (bc_is_marked(ob)) { - bc_remove_mark(ob); - Mesh *me = (Mesh *)ob->data; - if (me == reference_mesh) { - mesh_users.push_back(ob); - } - } - } - return mesh_users; -} - -/** - * - * During import all materials have been assigned to Object. - * Now we iterate over the imported objects and optimize - * the assignments as follows: - * - * for each imported geometry: - * if number of users is 1: - * get the user (object) - * move the materials from Object to Data - * else: - * determine which materials are assigned to the first user - * check if all other users have the same materials in the same order - * if the check is positive: - * Add the materials of the first user to the geometry - * adjust all other users accordingly. - * - */ -void MeshImporter::optimize_material_assignements() -{ - for (std::vector<Object *>::iterator it = imported_objects.begin(); it != imported_objects.end(); - ++it) { - Object *ob = (*it); - Mesh *me = (Mesh *)ob->data; - if (ID_REAL_USERS(&me->id) == 1) { - bc_copy_materials_to_data(ob, me); - bc_remove_materials_from_object(ob, me); - bc_remove_mark(ob); - } - else if (ID_REAL_USERS(&me->id) > 1) { - bool can_move = true; - std::vector<Object *> mesh_users = get_all_users_of(me); - if (mesh_users.size() > 1) { - Object *ref_ob = mesh_users[0]; - for (int index = 1; index < mesh_users.size(); index++) { - if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) { - can_move = false; - break; - } - } - if (can_move) { - bc_copy_materials_to_data(ref_ob, me); - for (int index = 0; index < mesh_users.size(); index++) { - Object *object = mesh_users[index]; - bc_remove_materials_from_object(object, me); - bc_remove_mark(object); - } - } - } - } - } -} - -/** - * We do not know in advance which objects will share geometries. - * And we do not know either if the objects which share geometries - * come along with different materials. So we first create the objects - * and assign the materials to Object, then in a later cleanup we decide - * which materials shall be moved to the created geometries. Also see - * optimize_material_assignements() above. - */ -void MeshImporter::assign_material_to_geom( - COLLADAFW::MaterialBinding cmaterial, - std::map<COLLADAFW::UniqueId, Material *> &uid_material_map, - Object *ob, - const COLLADAFW::UniqueId *geom_uid, - short mat_index) -{ - const COLLADAFW::UniqueId &ma_uid = cmaterial.getReferencedMaterial(); - - // do we know this material? - if (uid_material_map.find(ma_uid) == uid_material_map.end()) { - - fprintf(stderr, "Cannot find material by UID.\n"); - return; - } - - // first time we get geom_uid, ma_uid pair. Save for later check. - materials_mapped_to_geom.insert( - std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid)); - - Material *ma = uid_material_map[ma_uid]; - - // Attention! This temporarily assigns material to object on purpose! - // See note above. - ob->actcol = 0; - BKE_object_material_assign(m_bmain, ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); - - MaterialIdPrimitiveArrayMap &mat_prim_map = geom_uid_mat_mapping_map[*geom_uid]; - COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId(); - - // assign material indices to mesh faces - if (mat_prim_map.find(mat_id) != mat_prim_map.end()) { - - std::vector<Primitive> &prims = mat_prim_map[mat_id]; - - std::vector<Primitive>::iterator it; - - for (it = prims.begin(); it != prims.end(); it++) { - Primitive &prim = *it; - MPoly *mpoly = prim.mpoly; - - for (int i = 0; i < prim.totpoly; i++, mpoly++) { - mpoly->mat_nr = mat_index; - } - } - } -} - -Object *MeshImporter::create_mesh_object( - COLLADAFW::Node *node, - COLLADAFW::InstanceGeometry *geom, - bool isController, - std::map<COLLADAFW::UniqueId, Material *> &uid_material_map) -{ - const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId(); - - // check if node instantiates controller or geometry - if (isController) { - - geom_uid = armature_importer->get_geometry_uid(*geom_uid); - - if (!geom_uid) { - fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n"); - return NULL; - } - } - else { - - if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) { - // this could happen if a mesh was not created - // (e.g. if it contains unsupported geometry) - fprintf(stderr, "Couldn't find a mesh by UID.\n"); - return NULL; - } - } - if (!uid_mesh_map[*geom_uid]) { - return NULL; - } - - // name Object - const std::string &id = node->getName().size() ? node->getName() : node->getOriginalId(); - const char *name = (id.length()) ? id.c_str() : NULL; - - // add object - Object *ob = bc_add_object(m_bmain, scene, view_layer, OB_MESH, name); - bc_set_mark(ob); // used later for material assignment optimization - - // store object pointer for ArmatureImporter - uid_object_map[*geom_uid] = ob; - imported_objects.push_back(ob); - - // replace ob->data freeing the old one - Mesh *old_mesh = (Mesh *)ob->data; - Mesh *new_mesh = uid_mesh_map[*geom_uid]; - - BKE_mesh_assign_object(m_bmain, ob, new_mesh); - BKE_mesh_calc_normals(new_mesh); - - /* Because BKE_mesh_assign_object would have already decreased it... */ - id_us_plus(&old_mesh->id); - - BKE_id_free_us(m_bmain, old_mesh); - - COLLADAFW::MaterialBindingArray &mat_array = geom->getMaterialBindings(); - - // loop through geom's materials - for (unsigned int i = 0; i < mat_array.getCount(); i++) { - - if (mat_array[i].getReferencedMaterial().isValid()) { - assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid, i); - } - else { - fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str()); - } - } - - // clean up the mesh - BKE_mesh_validate((Mesh *)ob->data, false, false); - - return ob; -} - -// create a mesh storing a pointer in a map so it can be retrieved later by geometry UID -bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom) -{ - - if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) { - // TODO: report warning - fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType())); - return true; - } - - COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom; - - if (!is_nice_mesh(mesh)) { - fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str()); - return true; - } - - const std::string &str_geom_id = mesh->getName().size() ? mesh->getName() : - mesh->getOriginalId(); - Mesh *me = BKE_mesh_add(m_bmain, (char *)str_geom_id.c_str()); - id_us_min(&me->id); // is already 1 here, but will be set later in BKE_mesh_assign_object - - // store the Mesh pointer to link it later with an Object - // mesh_geom_map needed to map mesh to its geometry name (for shape key naming) - this->uid_mesh_map[mesh->getUniqueId()] = me; - this->mesh_geom_map[std::string(me->id.name)] = str_geom_id; - - read_vertices(mesh, me); - read_polys(mesh, me); - BKE_mesh_calc_edges(me, false, false); - // read_lines() must be called after the face edges have been generated. - // Otherwise the loose edges will be silently deleted again. - read_lines(mesh, me); - - return true; -} diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h deleted file mode 100644 index 9517587013d..00000000000 --- a/source/blender/collada/MeshImporter.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __MESHIMPORTER_H__ -#define __MESHIMPORTER_H__ - -#include <map> -#include <vector> - -#include "COLLADAFWIndexList.h" -#include "COLLADAFWPolygons.h" -#include "COLLADAFWInstanceGeometry.h" -#include "COLLADAFWMaterialBinding.h" -#include "COLLADAFWMesh.h" -#include "COLLADAFWMeshVertexData.h" -#include "COLLADAFWNode.h" -#include "COLLADAFWTextureCoordinateBinding.h" -#include "COLLADAFWTypes.h" -#include "COLLADAFWUniqueId.h" - -#include "ArmatureImporter.h" -#include "collada_utils.h" - -extern "C" { -#include "BLI_edgehash.h" -#include "DNA_material_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -} - -/* only for ArmatureImporter to "see" MeshImporter::get_object_by_geom_uid */ -class MeshImporterBase { - public: - virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId &geom_uid) = 0; - virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId &mesh_uid) = 0; - virtual std::string *get_geometry_name(const std::string &mesh_name) = 0; -}; - -class UVDataWrapper { - COLLADAFW::MeshVertexData *mVData; - - public: - UVDataWrapper(COLLADAFW::MeshVertexData &vdata); - -#ifdef COLLADA_DEBUG - void print(); -#endif - - void getUV(int uv_index, float *uv); -}; - -class VCOLDataWrapper { - COLLADAFW::MeshVertexData *mVData; - - public: - VCOLDataWrapper(COLLADAFW::MeshVertexData &vdata); - void get_vcol(int v_index, MLoopCol *mloopcol); -}; - -class MeshImporter : public MeshImporterBase { - private: - UnitConverter *unitconverter; - - Main *m_bmain; - Scene *scene; - ViewLayer *view_layer; - - ArmatureImporter *armature_importer; - - std::map<std::string, std::string> mesh_geom_map; /* needed for correct shape key naming */ - std::map<COLLADAFW::UniqueId, Mesh *> uid_mesh_map; /* geometry unique id-to-mesh map */ - std::map<COLLADAFW::UniqueId, Object *> uid_object_map; /* geom uid-to-object */ - std::vector<Object *> imported_objects; /* list of imported objects */ - - /* this structure is used to assign material indices to polygons - * it holds a portion of Mesh faces and corresponds to a DAE primitive list - * (<triangles>, <polylist>, etc.) */ - struct Primitive { - MPoly *mpoly; - unsigned int totpoly; - }; - typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive>> MaterialIdPrimitiveArrayMap; - /* crazy name! */ - std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; - /* < materials that have already been mapped to a geometry. - * A pair/of geom uid and mat uid, one geometry can have several materials */ - std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom; - - bool set_poly_indices( - MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count); - - void set_face_uv(MLoopUV *mloopuv, - UVDataWrapper &uvs, - int loop_index, - COLLADAFW::IndexList &index_list, - int count); - - void set_vcol(MLoopCol *mloopcol, - VCOLDataWrapper &vob, - int loop_index, - COLLADAFW::IndexList &index_list, - int count); - -#ifdef COLLADA_DEBUG - void print_index_list(COLLADAFW::IndexList &index_list); -#endif - - bool is_nice_mesh(COLLADAFW::Mesh *mesh); - - void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me); - - bool primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp); - bool primitive_has_faces(COLLADAFW::MeshPrimitive *mp); - - static void mesh_add_edges(Mesh *mesh, int len); - - unsigned int get_loose_edge_count(COLLADAFW::Mesh *mesh); - - CustomData create_edge_custom_data(EdgeHash *eh); - - void allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me); - - /* TODO: import uv set names */ - void read_polys(COLLADAFW::Mesh *mesh, Mesh *me); - void read_lines(COLLADAFW::Mesh *mesh, Mesh *me); - unsigned int get_vertex_count(COLLADAFW::Polygons *mp, int index); - - void get_vector(float v[3], COLLADAFW::MeshVertexData &arr, int i, int stride); - - bool is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData &nor, int count); - - std::vector<Object *> get_all_users_of(Mesh *reference_mesh); - - public: - MeshImporter(UnitConverter *unitconv, - ArmatureImporter *arm, - Main *bmain, - Scene *sce, - ViewLayer *view_layer); - - virtual Object *get_object_by_geom_uid(const COLLADAFW::UniqueId &geom_uid); - - virtual Mesh *get_mesh_by_geom_uid(const COLLADAFW::UniqueId &geom_uid); - - void optimize_material_assignements(); - - void assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial, - std::map<COLLADAFW::UniqueId, Material *> &uid_material_map, - Object *ob, - const COLLADAFW::UniqueId *geom_uid, - short mat_index); - - Object *create_mesh_object(COLLADAFW::Node *node, - COLLADAFW::InstanceGeometry *geom, - bool isController, - std::map<COLLADAFW::UniqueId, Material *> &uid_material_map); - - /* create a mesh storing a pointer in a map so it can be retrieved later by geometry UID */ - bool write_geometry(const COLLADAFW::Geometry *geom); - std::string *get_geometry_name(const std::string &mesh_name); -}; - -#endif diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp deleted file mode 100644 index 42901bd2a4a..00000000000 --- a/source/blender/collada/SceneExporter.cpp +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -extern "C" { -#include "BLI_utildefines.h" -#include "BKE_collection.h" -#include "BKE_object.h" -#include "BLI_listbase.h" -#include "BKE_lib_id.h" -} - -#include "SceneExporter.h" -#include "collada_utils.h" -#include "BCSampleData.h" - -void SceneExporter::exportScene() -{ - Scene *scene = blender_context.get_scene(); - - /* <library_visual_scenes> <visual_scene> */ - std::string name = id_name(scene); - openVisualScene(translate_id(name), encode_xml(name)); - exportHierarchy(); - closeVisualScene(); - closeLibrary(); -} - -void SceneExporter::exportHierarchy() -{ - LinkNode *node; - ColladaBaseNodes base_objects; - - /* Ensure all objects in the export_set are marked */ - for (node = this->export_settings.get_export_set(); node; node = node->next) { - Object *ob = (Object *)node->link; - ob->id.tag |= LIB_TAG_DOIT; - } - - /* Now find all exportable base objects (highest in export hierarchy) */ - for (node = this->export_settings.get_export_set(); node; node = node->next) { - Object *ob = (Object *)node->link; - if (this->export_settings.is_export_root(ob)) { - switch (ob->type) { - case OB_MESH: - case OB_CAMERA: - case OB_LAMP: - case OB_EMPTY: - case OB_GPENCIL: - case OB_ARMATURE: - base_objects.add(ob); - break; - } - } - } - - /* And now export the base objects: */ - for (int index = 0; index < base_objects.size(); index++) { - Object *ob = base_objects.get(index); - writeNode(ob); - if (bc_is_marked(ob)) { - bc_remove_mark(ob); - } - } -} - -void SceneExporter::writeNodeList(std::vector<Object *> &child_objects, Object *parent) -{ - /* TODO: Handle the case where a parent is not exported - * Actually i am not even sure if this can be done at all - * in a good way. - * I really prefer to enforce the export of hidden - * elements in an object hierarchy. When the children of - * the hidden elements are exported as well. */ - for (int i = 0; i < child_objects.size(); i++) { - Object *child = child_objects[i]; - writeNode(child); - if (bc_is_marked(child)) { - bc_remove_mark(child); - } - } -} - -void SceneExporter::writeNode(Object *ob) -{ - ViewLayer *view_layer = blender_context.get_view_layer(); - - std::vector<Object *> child_objects; - bc_get_children(child_objects, ob, view_layer); - bool can_export = bc_is_in_Export_set(this->export_settings.get_export_set(), ob, view_layer); - - /* Add associated armature first if available */ - bool armature_exported = false; - Object *ob_arm = bc_get_assigned_armature(ob); - - if (ob_arm != NULL) { - armature_exported = bc_is_in_Export_set( - this->export_settings.get_export_set(), ob_arm, view_layer); - if (armature_exported && bc_is_marked(ob_arm)) { - writeNode(ob_arm); - bc_remove_mark(ob_arm); - armature_exported = true; - } - } - - if (can_export) { - COLLADASW::Node colladaNode(mSW); - colladaNode.setNodeId(translate_id(id_name(ob))); - colladaNode.setNodeName(encode_xml(id_name(ob))); - colladaNode.setType(COLLADASW::Node::NODE); - - colladaNode.start(); - if (ob->type == OB_MESH && armature_exported) { - /* for skinned mesh we write obmat in <bind_shape_matrix> */ - TransformWriter::add_node_transform_identity(colladaNode, this->export_settings); - } - else { - TransformWriter::add_node_transform_ob(colladaNode, ob, this->export_settings); - } - - /* <instance_geometry> */ - if (ob->type == OB_MESH) { - bool instance_controller_created = false; - if (armature_exported) { - instance_controller_created = arm_exporter->add_instance_controller(ob); - } - if (!instance_controller_created) { - COLLADASW::InstanceGeometry instGeom(mSW); - instGeom.setUrl(COLLADASW::URI( - COLLADABU::Utils::EMPTY_STRING, - get_geometry_id(ob, this->export_settings.get_use_object_instantiation()))); - instGeom.setName(encode_xml(id_name(ob))); - InstanceWriter::add_material_bindings( - instGeom.getBindMaterial(), ob, this->export_settings.get_active_uv_only()); - instGeom.add(); - } - } - - /* <instance_controller> */ - else if (ob->type == OB_ARMATURE) { - arm_exporter->add_armature_bones(ob, view_layer, this, child_objects); - } - - /* <instance_camera> */ - else if (ob->type == OB_CAMERA) { - COLLADASW::InstanceCamera instCam( - mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_camera_id(ob))); - instCam.add(); - } - - /* <instance_light> */ - else if (ob->type == OB_LAMP) { - COLLADASW::InstanceLight instLa( - mSW, COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_light_id(ob))); - instLa.add(); - } - - /* empty object */ - else if (ob->type == OB_EMPTY) { /* TODO: handle groups (OB_DUPLICOLLECTION */ - if ((ob->transflag & OB_DUPLICOLLECTION) == OB_DUPLICOLLECTION && ob->instance_collection) { - Collection *collection = ob->instance_collection; - /* printf("group detected '%s'\n", group->id.name + 2); */ - FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN (collection, object) { - printf("\t%s\n", object->id.name); - } - FOREACH_COLLECTION_OBJECT_RECURSIVE_END; - } - - if (BLI_listbase_is_empty(&ob->constraints) == false) { - bConstraint *con = (bConstraint *)ob->constraints.first; - while (con) { - std::string con_name(encode_xml(con->name)); - std::string con_tag = con_name + "_constraint"; - printf("%s\n", con_name.c_str()); - printf("%s\n\n", con_tag.c_str()); - colladaNode.addExtraTechniqueChildParameter("blender", con_tag, "type", con->type); - colladaNode.addExtraTechniqueChildParameter("blender", con_tag, "enforce", con->enforce); - colladaNode.addExtraTechniqueChildParameter("blender", con_tag, "flag", con->flag); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "headtail", con->headtail); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "lin_error", con->lin_error); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "own_space", con->ownspace); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "rot_error", con->rot_error); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "tar_space", con->tarspace); - colladaNode.addExtraTechniqueChildParameter( - "blender", con_tag, "lin_error", con->lin_error); - - /* not ideal: add the target object name as another parameter. - * No real mapping in the .dae - * Need support for multiple target objects also. */ - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - ListBase targets = {NULL, NULL}; - if (cti && cti->get_constraint_targets) { - - bConstraintTarget *ct; - Object *obtar; - - cti->get_constraint_targets(con, &targets); - - for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { - obtar = ct->tar; - std::string tar_id((obtar) ? id_name(obtar) : ""); - colladaNode.addExtraTechniqueChildParameter("blender", con_tag, "target_id", tar_id); - } - - if (cti->flush_constraint_targets) { - cti->flush_constraint_targets(con, &targets, 1); - } - } - - con = con->next; - } - } - } - bc_remove_mark(ob); - writeNodeList(child_objects, ob); - colladaNode.end(); - } - else { - writeNodeList(child_objects, ob); - } -} diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h deleted file mode 100644 index a61d045ad5d..00000000000 --- a/source/blender/collada/SceneExporter.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __SCENEEXPORTER_H__ -#define __SCENEEXPORTER_H__ - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> - -extern "C" { -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_collection_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_image_types.h" -#include "DNA_material_types.h" -#include "DNA_texture_types.h" -#include "DNA_anim_types.h" -#include "DNA_action_types.h" -#include "DNA_curve_types.h" -#include "DNA_constraint_types.h" -#include "DNA_armature_types.h" -#include "DNA_modifier_types.h" -#include "DNA_userdef_types.h" - -#include "BKE_fcurve.h" -#include "BKE_animsys.h" -#include "BLI_path_util.h" -#include "BKE_constraint.h" -#include "BLI_fileops.h" -#include "ED_keyframing.h" -} - -#include "COLLADASWAsset.h" -#include "COLLADASWLibraryVisualScenes.h" -#include "COLLADASWNode.h" -#include "COLLADASWSource.h" -#include "COLLADASWInstanceGeometry.h" -#include "COLLADASWInputList.h" -#include "COLLADASWPrimitves.h" -#include "COLLADASWVertices.h" -#include "COLLADASWLibraryAnimations.h" -#include "COLLADASWLibraryImages.h" -#include "COLLADASWLibraryEffects.h" -#include "COLLADASWImage.h" -#include "COLLADASWEffectProfile.h" -#include "COLLADASWColorOrTexture.h" -#include "COLLADASWParamTemplate.h" -#include "COLLADASWParamBase.h" -#include "COLLADASWSurfaceInitOption.h" -#include "COLLADASWSampler.h" -#include "COLLADASWScene.h" -#include "COLLADASWTechnique.h" -#include "COLLADASWTexture.h" -#include "COLLADASWLibraryMaterials.h" -#include "COLLADASWBindMaterial.h" -#include "COLLADASWInstanceCamera.h" -#include "COLLADASWInstanceLight.h" -#include "COLLADASWConstants.h" -#include "COLLADASWLibraryControllers.h" -#include "COLLADASWInstanceController.h" -#include "COLLADASWInstanceNode.h" -#include "COLLADASWBaseInputElement.h" - -#include "ArmatureExporter.h" -#include "ExportSettings.h" - -extern void bc_get_children(std::vector<Object *> &child_set, Object *ob, ViewLayer *view_layer); - -class SceneExporter : COLLADASW::LibraryVisualScenes, - protected TransformWriter, - protected InstanceWriter { - public: - SceneExporter(BlenderContext &blender_context, - COLLADASW::StreamWriter *sw, - ArmatureExporter *arm, - BCExportSettings &export_settings) - : COLLADASW::LibraryVisualScenes(sw), - blender_context(blender_context), - arm_exporter(arm), - export_settings(export_settings) - { - } - - void exportScene(); - - private: - BlenderContext &blender_context; - friend class ArmatureExporter; - ArmatureExporter *arm_exporter; - BCExportSettings &export_settings; - - void exportHierarchy(); - void writeNodeList(std::vector<Object *> &child_objects, Object *parent); - void writeNode(Object *ob); -}; - -#endif diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp deleted file mode 100644 index d8804a1e831..00000000000 --- a/source/blender/collada/SkinInfo.cpp +++ /dev/null @@ -1,357 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include <algorithm> - -#if !defined(WIN32) -# include <stdint.h> -#endif - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "BLI_listbase.h" -#include "BLI_math.h" -#include "BLI_compiler_attrs.h" - -#include "DNA_armature_types.h" -#include "DNA_modifier_types.h" -#include "DNA_scene_types.h" - -#include "BKE_action.h" -#include "BKE_object.h" -#include "BKE_object_deform.h" - -#include "ED_mesh.h" -#include "ED_object.h" - -#include "SkinInfo.h" -#include "collada_utils.h" - -/* use name, or fall back to original id if name not present (name is optional) */ -template<class T> static const char *bc_get_joint_name(T *node) -{ - const std::string &id = node->getName(); - return id.size() ? id.c_str() : node->getOriginalId().c_str(); -} - -/* This is used to store data passed in write_controller_data. - * Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members - * so that arrays don't get freed until we free them explicitly. */ -SkinInfo::SkinInfo() -{ - /* pass */ -} - -SkinInfo::SkinInfo(const SkinInfo &skin) - : weights(skin.weights), - joint_data(skin.joint_data), - unit_converter(skin.unit_converter), - ob_arm(skin.ob_arm), - controller_uid(skin.controller_uid), - parent(skin.parent) -{ - copy_m4_m4(bind_shape_matrix, (float(*)[4])skin.bind_shape_matrix); - - transfer_uint_array_data_const(skin.joints_per_vertex, joints_per_vertex); - transfer_uint_array_data_const(skin.weight_indices, weight_indices); - transfer_int_array_data_const(skin.joint_indices, joint_indices); -} - -SkinInfo::SkinInfo(UnitConverter *conv) : unit_converter(conv), ob_arm(NULL), parent(NULL) -{ -} - -/* nobody owns the data after this, so it should be freed manually with releaseMemory */ -template<class T> void SkinInfo::transfer_array_data(T &src, T &dest) -{ - dest.setData(src.getData(), src.getCount()); - src.yieldOwnerShip(); - dest.yieldOwnerShip(); -} - -/* when src is const we cannot src.yieldOwnerShip, this is used by copy constructor */ -void SkinInfo::transfer_int_array_data_const(const COLLADAFW::IntValuesArray &src, - COLLADAFW::IntValuesArray &dest) -{ - dest.setData((int *)src.getData(), src.getCount()); - dest.yieldOwnerShip(); -} - -void SkinInfo::transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray &src, - COLLADAFW::UIntValuesArray &dest) -{ - dest.setData((unsigned int *)src.getData(), src.getCount()); - dest.yieldOwnerShip(); -} - -void SkinInfo::borrow_skin_controller_data(const COLLADAFW::SkinControllerData *skin) -{ - transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getJointsPerVertex(), joints_per_vertex); - transfer_array_data((COLLADAFW::UIntValuesArray &)skin->getWeightIndices(), weight_indices); - transfer_array_data((COLLADAFW::IntValuesArray &)skin->getJointIndices(), joint_indices); - // transfer_array_data(skin->getWeights(), weights); - - /* cannot transfer data for FloatOrDoubleArray, copy values manually */ - const COLLADAFW::FloatOrDoubleArray &weight = skin->getWeights(); - for (unsigned int i = 0; i < weight.getValuesCount(); i++) { - weights.push_back(bc_get_float_value(weight, i)); - } - - unit_converter->dae_matrix_to_mat4_(bind_shape_matrix, skin->getBindShapeMatrix()); -} - -void SkinInfo::free() -{ - joints_per_vertex.releaseMemory(); - weight_indices.releaseMemory(); - joint_indices.releaseMemory(); - // weights.releaseMemory(); -} - -/* using inverse bind matrices to construct armature - * it is safe to invert them to get the original matrices - * because if they are inverse matrices, they can be inverted */ -void SkinInfo::add_joint(const COLLADABU::Math::Matrix4 &matrix) -{ - JointData jd; - unit_converter->dae_matrix_to_mat4_(jd.inv_bind_mat, matrix); - joint_data.push_back(jd); -} - -void SkinInfo::set_controller(const COLLADAFW::SkinController *co) -{ - controller_uid = co->getUniqueId(); - - /* fill in joint UIDs */ - const COLLADAFW::UniqueIdArray &joint_uids = co->getJoints(); - for (unsigned int i = 0; i < joint_uids.getCount(); i++) { - joint_data[i].joint_uid = joint_uids[i]; - - /* store armature pointer */ - // JointData& jd = joint_index_to_joint_info_map[i]; - // jd.ob_arm = ob_arm; - - /* now we'll be able to get inv bind matrix from joint id */ - // joint_id_to_joint_index_map[joint_ids[i]] = i; - } -} - -/* called from write_controller */ -Object *SkinInfo::create_armature(Main *bmain, Scene *scene, ViewLayer *view_layer) -{ - ob_arm = bc_add_object(bmain, scene, view_layer, OB_ARMATURE, NULL); - return ob_arm; -} - -Object *SkinInfo::set_armature(Object *ob_arm) -{ - if (this->ob_arm) { - return this->ob_arm; - } - - this->ob_arm = ob_arm; - return ob_arm; -} - -bool SkinInfo::get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node) -{ - const COLLADAFW::UniqueId &uid = node->getUniqueId(); - std::vector<JointData>::iterator it; - for (it = joint_data.begin(); it != joint_data.end(); it++) { - if ((*it).joint_uid == uid) { - copy_m4_m4(inv_bind_mat, (*it).inv_bind_mat); - return true; - } - } - - return false; -} - -Object *SkinInfo::BKE_armature_from_object() -{ - return ob_arm; -} - -const COLLADAFW::UniqueId &SkinInfo::get_controller_uid() -{ - return controller_uid; -} - -/* check if this skin controller references a joint or any descendant of it - * - * some nodes may not be referenced by SkinController, - * in this case to determine if the node belongs to this armature, - * we need to search down the tree */ -bool SkinInfo::uses_joint_or_descendant(COLLADAFW::Node *node) -{ - const COLLADAFW::UniqueId &uid = node->getUniqueId(); - std::vector<JointData>::iterator it; - for (it = joint_data.begin(); it != joint_data.end(); it++) { - if ((*it).joint_uid == uid) { - return true; - } - } - - COLLADAFW::NodePointerArray &children = node->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (uses_joint_or_descendant(children[i])) { - return true; - } - } - - return false; -} - -void SkinInfo::link_armature(bContext *C, - Object *ob, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &joint_by_uid, - TransformReader *tm) -{ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - - ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); - ArmatureModifierData *amd = (ArmatureModifierData *)md; - amd->object = ob_arm; - -#if 1 - /* XXX Why do we enforce objects to be children of Armatures if they weren't so before ?*/ - if (!BKE_object_is_child_recursive(ob_arm, ob)) { - bc_set_parent(ob, ob_arm, C); - } -#else - Object workob; - ob->parent = ob_arm; - ob->partype = PAROBJECT; - - BKE_object_workob_calc_parent(scene, ob, &workob); - invert_m4_m4(ob->parentinv, workob.obmat); - - DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); -#endif - copy_m4_m4(ob->obmat, bind_shape_matrix); - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); - - amd->deformflag = ARM_DEF_VGROUP; - - /* create all vertex groups */ - std::vector<JointData>::iterator it; - int joint_index; - for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { - const char *name = "Group"; - - /* skip joints that have invalid UID */ - if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) { - continue; - } - - /* name group by joint node name */ - - if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { - name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); - } - - BKE_object_defgroup_add_name(ob, name); - } - - /* <vcount> - number of joints per vertex - joints_per_vertex - * <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices - * ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? - * - * for each vertex in weight indices - * for each bone index in vertex - * add vertex to group at group index - * treat group index -1 specially - * - * get def group by index with BLI_findlink */ - - for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { - - unsigned int limit = weight + joints_per_vertex[vertex]; - for (; weight < limit; weight++) { - int joint = joint_indices[weight], joint_weight = weight_indices[weight]; - - /* -1 means "weight towards the bind shape", we just don't assign it to any group */ - if (joint != -1) { - bDeformGroup *def = (bDeformGroup *)BLI_findlink(&ob->defbase, joint); - - ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); - } - } - } -} - -bPoseChannel *SkinInfo::get_pose_channel_from_node(COLLADAFW::Node *node) -{ - return BKE_pose_channel_find_name(ob_arm->pose, bc_get_joint_name(node)); -} - -void SkinInfo::set_parent(Object *_parent) -{ - parent = _parent; -} - -Object *SkinInfo::get_parent() -{ - return parent; -} - -void SkinInfo::find_root_joints(const std::vector<COLLADAFW::Node *> &root_joints, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &joint_by_uid, - std::vector<COLLADAFW::Node *> &result) -{ - std::vector<COLLADAFW::Node *>::const_iterator it; - /* for each root_joint */ - for (it = root_joints.begin(); it != root_joints.end(); it++) { - COLLADAFW::Node *root = *it; - std::vector<JointData>::iterator ji; - /* for each joint_data in this skin */ - for (ji = joint_data.begin(); ji != joint_data.end(); ji++) { - if (joint_by_uid.find((*ji).joint_uid) != joint_by_uid.end()) { - /* get joint node from joint map */ - COLLADAFW::Node *joint = joint_by_uid[(*ji).joint_uid]; - - /* find if joint node is in the tree belonging to the root_joint */ - if (find_node_in_tree(joint, root)) { - if (std::find(result.begin(), result.end(), root) == result.end()) { - result.push_back(root); - } - } - } - } - } -} - -bool SkinInfo::find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root) -{ - if (node == tree_root) { - return true; - } - - COLLADAFW::NodePointerArray &children = tree_root->getChildNodes(); - for (unsigned int i = 0; i < children.getCount(); i++) { - if (find_node_in_tree(node, children[i])) { - return true; - } - } - - return false; -} diff --git a/source/blender/collada/SkinInfo.h b/source/blender/collada/SkinInfo.h deleted file mode 100644 index 255d6d9b1f3..00000000000 --- a/source/blender/collada/SkinInfo.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __SKININFO_H__ -#define __SKININFO_H__ - -#include <map> -#include <vector> - -#include "COLLADAFWUniqueId.h" -#include "COLLADAFWTypes.h" -#include "COLLADAFWNode.h" -#include "COLLADAFWSkinController.h" -#include "COLLADAFWSkinControllerData.h" - -#include "DNA_object_types.h" -#include "BKE_context.h" - -#include "TransformReader.h" -#include "collada_internal.h" - -// This is used to store data passed in write_controller_data. -// Arrays from COLLADAFW::SkinControllerData lose ownership, so do this class members -// so that arrays don't get freed until we free them explicitly. -class SkinInfo { - private: - // to build armature bones from inverse bind matrices - struct JointData { - float inv_bind_mat[4][4]; // joint inverse bind matrix - COLLADAFW::UniqueId joint_uid; // joint node UID - // Object *ob_arm; // armature object - }; - - float bind_shape_matrix[4][4]; - - // data from COLLADAFW::SkinControllerData, each array should be freed - COLLADAFW::UIntValuesArray joints_per_vertex; - COLLADAFW::UIntValuesArray weight_indices; - COLLADAFW::IntValuesArray joint_indices; - // COLLADAFW::FloatOrDoubleArray weights; - std::vector<float> weights; - - std::vector<JointData> joint_data; // index to this vector is joint index - - UnitConverter *unit_converter; - - Object *ob_arm; - COLLADAFW::UniqueId controller_uid; - Object *parent; - - public: - SkinInfo(); - SkinInfo(const SkinInfo &skin); - SkinInfo(UnitConverter *conv); - - // nobody owns the data after this, so it should be freed manually with releaseMemory - template<typename T> void transfer_array_data(T &src, T &dest); - - // when src is const we cannot src.yieldOwnerShip, this is used by copy constructor - void transfer_int_array_data_const(const COLLADAFW::IntValuesArray &src, - COLLADAFW::IntValuesArray &dest); - - void transfer_uint_array_data_const(const COLLADAFW::UIntValuesArray &src, - COLLADAFW::UIntValuesArray &dest); - - void borrow_skin_controller_data(const COLLADAFW::SkinControllerData *skin); - - void free(); - - // using inverse bind matrices to construct armature - // it is safe to invert them to get the original matrices - // because if they are inverse matrices, they can be inverted - void add_joint(const COLLADABU::Math::Matrix4 &matrix); - - void set_controller(const COLLADAFW::SkinController *co); - - // called from write_controller - Object *create_armature(Main *bmain, Scene *scene, ViewLayer *view_layer); - - Object *set_armature(Object *ob_arm); - - bool get_joint_inv_bind_matrix(float inv_bind_mat[4][4], COLLADAFW::Node *node); - - Object *BKE_armature_from_object(); - - const COLLADAFW::UniqueId &get_controller_uid(); - - // check if this skin controller references a joint or any descendant of it - // - // some nodes may not be referenced by SkinController, - // in this case to determine if the node belongs to this armature, - // we need to search down the tree - bool uses_joint_or_descendant(COLLADAFW::Node *node); - - void link_armature(bContext *C, - Object *ob, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &joint_by_uid, - TransformReader *tm); - - bPoseChannel *get_pose_channel_from_node(COLLADAFW::Node *node); - - void set_parent(Object *_parent); - - Object *get_parent(); - - void find_root_joints(const std::vector<COLLADAFW::Node *> &root_joints, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node *> &joint_by_uid, - std::vector<COLLADAFW::Node *> &result); - - bool find_node_in_tree(COLLADAFW::Node *node, COLLADAFW::Node *tree_root); -}; - -#endif diff --git a/source/blender/collada/TransformReader.cpp b/source/blender/collada/TransformReader.cpp deleted file mode 100644 index 8ee31f80405..00000000000 --- a/source/blender/collada/TransformReader.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "TransformReader.h" - -TransformReader::TransformReader(UnitConverter *conv) : unit_converter(conv) -{ - /* pass */ -} - -void TransformReader::get_node_mat(float mat[4][4], - COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Animation> *animation_map, - Object *ob) -{ - get_node_mat(mat, node, animation_map, ob, NULL); -} - -void TransformReader::get_node_mat(float mat[4][4], - COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Animation> *animation_map, - Object *ob, - float parent_mat[4][4]) -{ - float cur[4][4]; - float copy[4][4]; - - unit_m4(mat); - - for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) { - - COLLADAFW::Transformation *tm = node->getTransformations()[i]; - COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); - - switch (type) { - case COLLADAFW::Transformation::MATRIX: - // When matrix AND Trans/Rot/Scale are defined for a node, - // then this is considered as redundant information. - // So if we find a Matrix we use that and return. - dae_matrix_to_mat4(tm, mat); - if (parent_mat) { - mul_m4_m4m4(mat, parent_mat, mat); - } - return; - case COLLADAFW::Transformation::TRANSLATE: - dae_translate_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::ROTATE: - dae_rotate_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::SCALE: - dae_scale_to_mat4(tm, cur); - break; - case COLLADAFW::Transformation::LOOKAT: - fprintf(stderr, "|! LOOKAT transformations are not supported yet.\n"); - break; - case COLLADAFW::Transformation::SKEW: - fprintf(stderr, "|! SKEW transformations are not supported yet.\n"); - break; - } - - copy_m4_m4(copy, mat); - mul_m4_m4m4(mat, copy, cur); - - if (animation_map) { - // AnimationList that drives this Transformation - const COLLADAFW::UniqueId &anim_list_id = tm->getAnimationList(); - - // store this so later we can link animation data with ob - Animation anim = {ob, node, tm}; - (*animation_map)[anim_list_id] = anim; - } - } - - if (parent_mat) { - mul_m4_m4m4(mat, parent_mat, mat); - } -} - -void TransformReader::dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) -{ - COLLADAFW::Rotate *ro = (COLLADAFW::Rotate *)tm; - COLLADABU::Math::Vector3 &axis = ro->getRotationAxis(); - const float angle = (float)DEG2RAD(ro->getRotationAngle()); - const float ax[] = {(float)axis[0], (float)axis[1], (float)axis[2]}; - // float quat[4]; - // axis_angle_to_quat(quat, axis, angle); - // quat_to_mat4(m, quat); - axis_angle_to_mat4(m, ax, angle); -} - -void TransformReader::dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) -{ - COLLADAFW::Translate *tra = (COLLADAFW::Translate *)tm; - COLLADABU::Math::Vector3 &t = tra->getTranslation(); - - unit_m4(m); - - m[3][0] = (float)t[0]; - m[3][1] = (float)t[1]; - m[3][2] = (float)t[2]; -} - -void TransformReader::dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) -{ - COLLADABU::Math::Vector3 &s = ((COLLADAFW::Scale *)tm)->getScale(); - float size[3] = {(float)s[0], (float)s[1], (float)s[2]}; - size_to_mat4(m, size); -} - -void TransformReader::dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]) -{ - unit_converter->dae_matrix_to_mat4_(m, ((COLLADAFW::Matrix *)tm)->getMatrix()); -} - -void TransformReader::dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]) -{ - dae_vector3_to_v3(((COLLADAFW::Translate *)tm)->getTranslation(), v); -} - -void TransformReader::dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]) -{ - dae_vector3_to_v3(((COLLADAFW::Scale *)tm)->getScale(), v); -} - -void TransformReader::dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]) -{ - v[0] = v3.x; - v[1] = v3.y; - v[2] = v3.z; -} diff --git a/source/blender/collada/TransformReader.h b/source/blender/collada/TransformReader.h deleted file mode 100644 index 2cf3ee795ae..00000000000 --- a/source/blender/collada/TransformReader.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __TRANSFORMREADER_H__ -#define __TRANSFORMREADER_H__ - -#include "COLLADAFWNode.h" -#include "COLLADAFWTransformation.h" -#include "COLLADAFWTranslate.h" -#include "COLLADAFWRotate.h" -#include "COLLADAFWScale.h" -#include "COLLADAFWMatrix.h" -#include "COLLADAFWUniqueId.h" -#include "Math/COLLADABUMathVector3.h" - -#include "DNA_object_types.h" -#include "BLI_math.h" - -#include "collada_internal.h" - -// struct Object; - -class TransformReader { - protected: - UnitConverter *unit_converter; - - public: - struct Animation { - Object *ob; - COLLADAFW::Node *node; - COLLADAFW::Transformation *tm; // which transform is animated by an AnimationList->id - }; - - TransformReader(UnitConverter *conv); - - void get_node_mat(float mat[4][4], - COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Animation> *animation_map, - Object *ob); - void get_node_mat(float mat[4][4], - COLLADAFW::Node *node, - std::map<COLLADAFW::UniqueId, Animation> *animation_map, - Object *ob, - float parent_mat[4][4]); - - void dae_rotate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); - void dae_translate_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); - void dae_scale_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); - void dae_matrix_to_mat4(COLLADAFW::Transformation *tm, float m[4][4]); - void dae_translate_to_v3(COLLADAFW::Transformation *tm, float v[3]); - void dae_scale_to_v3(COLLADAFW::Transformation *tm, float v[3]); - void dae_vector3_to_v3(const COLLADABU::Math::Vector3 &v3, float v[3]); -}; - -#endif diff --git a/source/blender/collada/TransformWriter.cpp b/source/blender/collada/TransformWriter.cpp deleted file mode 100644 index 0a66db72cb9..00000000000 --- a/source/blender/collada/TransformWriter.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#include "BLI_math.h" -#include "BLI_sys_types.h" - -#include "BKE_object.h" - -#include "TransformWriter.h" - -void TransformWriter::add_joint_transform(COLLADASW::Node &node, - float mat[4][4], - float parent_mat[4][4], - BCExportSettings &export_settings, - bool has_restmat) -{ - float local[4][4]; - - if (parent_mat) { - float invpar[4][4]; - invert_m4_m4(invpar, parent_mat); - mul_m4_m4m4(local, invpar, mat); - } - else { - copy_m4_m4(local, mat); - } - - if (!has_restmat && export_settings.get_apply_global_orientation()) { - bc_apply_global_transform(local, export_settings.get_global_transform()); - } - - double dmat[4][4]; - UnitConverter *converter = new UnitConverter(); - converter->mat4_to_dae_double(dmat, local); - delete converter; - - if (export_settings.get_object_transformation_type() == BC_TRANSFORMATION_TYPE_MATRIX) { - node.addMatrix("transform", dmat); - } - else { - float loc[3], rot[3], scale[3]; - bc_decompose(local, loc, rot, NULL, scale); - add_transform(node, loc, rot, scale); - } -} - -void TransformWriter::add_node_transform_ob(COLLADASW::Node &node, - Object *ob, - BCExportSettings &export_settings) -{ - bool limit_precision = export_settings.get_limit_precision(); - - /* Export the local Matrix (relative to the object parent, - * be it an object, bone or vertex(-tices)). */ - Matrix f_obmat; - BKE_object_matrix_local_get(ob, f_obmat); - - if (export_settings.get_apply_global_orientation()) { - bc_apply_global_transform(f_obmat, export_settings.get_global_transform()); - } - else { - bc_add_global_transform(f_obmat, export_settings.get_global_transform()); - } - - switch (export_settings.get_object_transformation_type()) { - case BC_TRANSFORMATION_TYPE_MATRIX: { - UnitConverter converter; - double d_obmat[4][4]; - converter.mat4_to_dae_double(d_obmat, f_obmat); - - if (limit_precision) { - BCMatrix::sanitize(d_obmat, LIMITTED_PRECISION); - } - node.addMatrix("transform", d_obmat); - break; - } - case BC_TRANSFORMATION_TYPE_DECOMPOSED: { - float loc[3], rot[3], scale[3]; - bc_decompose(f_obmat, loc, rot, NULL, scale); - if (limit_precision) { - bc_sanitize_v3(loc, LIMITTED_PRECISION); - bc_sanitize_v3(rot, LIMITTED_PRECISION); - bc_sanitize_v3(scale, LIMITTED_PRECISION); - } - add_transform(node, loc, rot, scale); - break; - } - } -} - -void TransformWriter::add_node_transform_identity(COLLADASW::Node &node, - BCExportSettings &export_settings) -{ - BC_export_transformation_type transformation_type = - export_settings.get_object_transformation_type(); - switch (transformation_type) { - case BC_TRANSFORMATION_TYPE_MATRIX: { - BCMatrix mat; - DMatrix d_obmat; - mat.get_matrix(d_obmat); - node.addMatrix("transform", d_obmat); - break; - } - default: { - float loc[3] = {0.0f, 0.0f, 0.0f}; - float scale[3] = {1.0f, 1.0f, 1.0f}; - float rot[3] = {0.0f, 0.0f, 0.0f}; - add_transform(node, loc, rot, scale); - break; - } - } -} - -void TransformWriter::add_transform(COLLADASW::Node &node, - float loc[3], - float rot[3], - float scale[3]) -{ - node.addScale("scale", scale[0], scale[1], scale[2]); - node.addRotateZ("rotationZ", RAD2DEGF(rot[2])); - node.addRotateY("rotationY", RAD2DEGF(rot[1])); - node.addRotateX("rotationX", RAD2DEGF(rot[0])); - node.addTranslate("location", loc[0], loc[1], loc[2]); -} diff --git a/source/blender/collada/TransformWriter.h b/source/blender/collada/TransformWriter.h deleted file mode 100644 index d2e4b369cdc..00000000000 --- a/source/blender/collada/TransformWriter.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __TRANSFORMWRITER_H__ -#define __TRANSFORMWRITER_H__ - -#include "COLLADASWNode.h" - -#include "DNA_object_types.h" - -#include "collada_internal.h" -#include "collada_utils.h" -#include "collada.h" - -class TransformWriter { - protected: - void add_joint_transform(COLLADASW::Node &node, - float mat[4][4], - float parent_mat[4][4], - BCExportSettings &export_settings, - bool has_restmat); - - void add_node_transform_ob(COLLADASW::Node &node, Object *ob, BCExportSettings &export_settings); - - void add_node_transform_identity(COLLADASW::Node &node, BCExportSettings &export_settings); - - private: - void add_transform(COLLADASW::Node &node, float loc[3], float rot[3], float scale[3]); -}; - -#endif diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp deleted file mode 100644 index ea5600aa850..00000000000 --- a/source/blender/collada/collada.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "DocumentExporter.h" -#include "DocumentImporter.h" -#include "ExportSettings.h" -#include "ImportSettings.h" -#include "collada.h" - -extern "C" { -#include "BKE_scene.h" -#include "BKE_context.h" -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_query.h" - -/* make dummy file */ -#include "BLI_fileops.h" -#include "BLI_linklist.h" - -static void print_import_header(ImportSettings &import_settings) -{ - fprintf(stderr, "+-- Collada Import parameters------\n"); - fprintf(stderr, "| input file : %s\n", import_settings.filepath); - fprintf(stderr, "| use units : %s\n", (import_settings.import_units) ? "yes" : "no"); - fprintf(stderr, "| autoconnect : %s\n", (import_settings.auto_connect) ? "yes" : "no"); - fprintf(stderr, "+-- Armature Import parameters ----\n"); - fprintf(stderr, "| find bone chains: %s\n", (import_settings.find_chains) ? "yes" : "no"); - fprintf(stderr, "| min chain len : %d\n", import_settings.min_chain_length); - fprintf(stderr, "| fix orientation : %s\n", (import_settings.fix_orientation) ? "yes" : "no"); - fprintf(stderr, "| keep bind info : %s\n", (import_settings.keep_bind_info) ? "yes" : "no"); -} - -static void print_import_footer(int status) -{ - fprintf(stderr, "+----------------------------------\n"); - fprintf(stderr, "| Collada Import : %s\n", (status) ? "OK" : "FAIL"); - fprintf(stderr, "+----------------------------------\n"); -} - -int collada_import(bContext *C, ImportSettings *import_settings) -{ - print_import_header(*import_settings); - DocumentImporter imp(C, import_settings); - int status = imp.import() ? 1 : 0; - print_import_footer(status); - - return status; -} - -int collada_export(bContext *C, ExportSettings *export_settings) -{ - BlenderContext blender_context(C); - ViewLayer *view_layer = blender_context.get_view_layer(); - - int includeFilter = OB_REL_NONE; - if (export_settings->include_armatures) { - includeFilter |= OB_REL_MOD_ARMATURE; - } - if (export_settings->include_children) { - includeFilter |= OB_REL_CHILDREN_RECURSIVE; - } - - /* Fetch the complete set of exported objects - * ATTENTION: Invisible objects will not be exported - */ - eObjectSet objectSet = (export_settings->selected) ? OB_SET_SELECTED : OB_SET_ALL; - export_settings->export_set = BKE_object_relational_superset( - view_layer, objectSet, (eObRelationTypes)includeFilter); - - int export_count = BLI_linklist_count(export_settings->export_set); - - if (export_count == 0) { - if (export_settings->selected) { - fprintf(stderr, - "Collada: Found no objects to export.\nPlease ensure that all objects which shall " - "be exported are also visible in the 3D Viewport.\n"); - } - else { - fprintf(stderr, "Collada: Your scene seems to be empty. No Objects will be exported.\n"); - } - } - else { - if (export_settings->sort_by_name) { - bc_bubble_sort_by_Object_name(export_settings->export_set); - } - } - - DocumentExporter exporter(blender_context, export_settings); - int status = exporter.exportCurrentScene(); - - BLI_linklist_free(export_settings->export_set, NULL); - - return (status) ? -1 : export_count; -} - -/* end extern C */ -} diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h deleted file mode 100644 index 72753e170a3..00000000000 --- a/source/blender/collada/collada.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __COLLADA_H__ -#define __COLLADA_H__ - -#include <stdlib.h> - -#include "ImportSettings.h" -#include "ExportSettings.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "BLI_linklist.h" -#include "BLI_path_util.h" -#include "RNA_types.h" - -struct bContext; - -/* - * both return 1 on success, 0 on error - */ -int collada_import(struct bContext *C, ImportSettings *import_settings); - -int collada_export(struct bContext *C, ExportSettings *export_settings); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp deleted file mode 100644 index 7e834045795..00000000000 --- a/source/blender/collada/collada_internal.cpp +++ /dev/null @@ -1,340 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" -#include "collada_utils.h" - -#include "BLI_linklist.h" -#include "ED_armature.h" - -UnitConverter::UnitConverter() : unit(), up_axis(COLLADAFW::FileInfo::Z_UP) -{ - axis_angle_to_mat4_single(x_up_mat4, 'Y', -0.5 * M_PI); - axis_angle_to_mat4_single(y_up_mat4, 'X', 0.5 * M_PI); - - unit_m4(z_up_mat4); - unit_m4(scale_mat4); -} - -void UnitConverter::read_asset(const COLLADAFW::FileInfo *asset) -{ - unit = asset->getUnit(); - up_axis = asset->getUpAxisType(); -} - -UnitConverter::UnitSystem UnitConverter::isMetricSystem() -{ - switch (unit.getLinearUnitUnit()) { - case COLLADAFW::FileInfo::Unit::MILLIMETER: - case COLLADAFW::FileInfo::Unit::CENTIMETER: - case COLLADAFW::FileInfo::Unit::DECIMETER: - case COLLADAFW::FileInfo::Unit::METER: - case COLLADAFW::FileInfo::Unit::KILOMETER: - return UnitConverter::Metric; - case COLLADAFW::FileInfo::Unit::INCH: - case COLLADAFW::FileInfo::Unit::FOOT: - case COLLADAFW::FileInfo::Unit::YARD: - return UnitConverter::Imperial; - default: - return UnitConverter::None; - } -} - -float UnitConverter::getLinearMeter() -{ - return (float)unit.getLinearUnitMeter(); -} - -void UnitConverter::convertVector3(COLLADABU::Math::Vector3 &vec, float *v) -{ - v[0] = vec.x; - v[1] = vec.y; - v[2] = vec.z; -} - -// TODO need also for angle conversion, time conversion... - -void UnitConverter::dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in) -{ - // in DAE, matrices use columns vectors, (see comments in COLLADABUMathMatrix4.h) - // so here, to make a blender matrix, we swap columns and rows - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - out[i][j] = in[j][i]; - } - } -} - -void UnitConverter::mat4_to_dae(float out[4][4], float in[4][4]) -{ - transpose_m4_m4(out, in); -} - -void UnitConverter::mat4_to_dae_double(double out[4][4], float in[4][4]) -{ - float mat[4][4]; - - mat4_to_dae(mat, in); - - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - out[i][j] = mat[i][j]; - } - } -} - -float (&UnitConverter::get_rotation())[4][4] -{ - switch (up_axis) { - case COLLADAFW::FileInfo::X_UP: - return x_up_mat4; - break; - case COLLADAFW::FileInfo::Y_UP: - return y_up_mat4; - break; - default: - return z_up_mat4; - break; - } -} - -float (&UnitConverter::get_scale())[4][4] -{ - return scale_mat4; -} - -void UnitConverter::calculate_scale(Scene &sce) -{ - PointerRNA scene_ptr, unit_settings; - PropertyRNA *system_ptr, *scale_ptr; - RNA_id_pointer_create(&sce.id, &scene_ptr); - - unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings"); - system_ptr = RNA_struct_find_property(&unit_settings, "system"); - scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length"); - - int type = RNA_property_enum_get(&unit_settings, system_ptr); - - float bl_scale; - - switch (type) { - case USER_UNIT_NONE: - bl_scale = 1.0; // map 1 Blender unit to 1 Meter - break; - - case USER_UNIT_METRIC: - bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); - break; - - default: - bl_scale = RNA_property_float_get(&unit_settings, scale_ptr); - // it looks like the conversion to Imperial is done implicitly. - // So nothing to do here. - break; - } - - float rescale[3]; - rescale[0] = rescale[1] = rescale[2] = getLinearMeter() / bl_scale; - - size_to_mat4(scale_mat4, rescale); -} - -/** - * Translation map. - * Used to translate every COLLADA id to a valid id, no matter what "wrong" letters may be - * included. Look at the IDREF XSD declaration for more. - * Follows strictly the COLLADA XSD declaration which explicitly allows non-english chars, - * like special chars (e.g. micro sign), umlauts and so on. - * The COLLADA spec also allows additional chars for member access ('.'), these - * must obviously be removed too, otherwise they would be heavily misinterpreted. - */ -const unsigned char translate_start_name_map[256] = { - - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95, - 95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95, - - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, -}; - -const unsigned char translate_name_map[256] = { - - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 45, 95, 95, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 95, 95, 95, 95, 95, 95, 95, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 95, 95, 95, 95, - 95, 95, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 95, 95, 95, 95, 95, - - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, -}; - -typedef std::map<std::string, std::vector<std::string>> map_string_list; -map_string_list global_id_map; - -void clear_global_id_map() -{ - global_id_map.clear(); -} - -/** Look at documentation of translate_map */ -std::string translate_id(const char *idString) -{ - std::string id = std::string(idString); - return translate_id(id); -} - -std::string translate_id(const std::string &id) -{ - if (id.size() == 0) { - return id; - } - - std::string id_translated = id; - id_translated[0] = translate_start_name_map[(unsigned int)id_translated[0]]; - for (unsigned int i = 1; i < id_translated.size(); i++) { - id_translated[i] = translate_name_map[(unsigned int)id_translated[i]]; - } - // It's so much workload now, the if () should speed up things. - if (id_translated != id) { - // Search duplicates - map_string_list::iterator iter = global_id_map.find(id_translated); - if (iter != global_id_map.end()) { - unsigned int i = 0; - bool found = false; - for (i = 0; i < iter->second.size(); i++) { - if (id == iter->second[i]) { - found = true; - break; - } - } - bool convert = false; - if (found) { - if (i > 0) { - convert = true; - } - } - else { - convert = true; - global_id_map[id_translated].push_back(id); - } - if (convert) { - std::stringstream out; - out << ++i; - id_translated += out.str(); - } - } - else { - global_id_map[id_translated].push_back(id); - } - } - return id_translated; -} - -std::string id_name(void *id) -{ - return ((ID *)id)->name + 2; -} - -std::string encode_xml(std::string xml) -{ - const std::map<char, std::string> escape{ - {'<', "<"}, {'>', ">"}, {'"', """}, {'\'', "'"}, {'&', "&"}}; - - std::map<char, std::string>::const_iterator it; - std::string encoded_xml = ""; - - for (unsigned int i = 0; i < xml.size(); i++) { - char c = xml.at(i); - it = escape.find(c); - - if (it == escape.end()) { - encoded_xml += c; - } - else { - encoded_xml += it->second; - } - } - return encoded_xml; -} - -std::string get_geometry_id(Object *ob) -{ - return translate_id(id_name(ob->data)) + "-mesh"; -} - -std::string get_geometry_id(Object *ob, bool use_instantiation) -{ - std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob); - - return translate_id(geom_name) + "-mesh"; -} - -std::string get_light_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-light"; -} - -std::string get_joint_sid(Bone *bone) -{ - return translate_id(bone->name); -} -static std::string get_joint_sid(EditBone *bone) -{ - return translate_id(bone->name); -} - -std::string get_camera_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-camera"; -} - -std::string get_effect_id(Material *mat) -{ - return translate_id(id_name(mat)) + "-effect"; -} - -std::string get_material_id(Material *mat) -{ - return translate_id(id_name(mat)) + "-material"; -} - -std::string get_morph_id(Object *ob) -{ - return translate_id(id_name(ob)) + "-morph"; -} diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h deleted file mode 100644 index 297ea9c0bbb..00000000000 --- a/source/blender/collada/collada_internal.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __COLLADA_INTERNAL_H__ -#define __COLLADA_INTERNAL_H__ - -#include <string> -#include <vector> -#include <map> - -#include "COLLADAFWFileInfo.h" -#include "Math/COLLADABUMathMatrix4.h" - -#include "DNA_armature_types.h" -#include "DNA_material_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "BLI_math.h" -#include "BLI_linklist.h" - -class UnitConverter { - private: - COLLADAFW::FileInfo::Unit unit; - COLLADAFW::FileInfo::UpAxisType up_axis; - - float x_up_mat4[4][4]; - float y_up_mat4[4][4]; - float z_up_mat4[4][4]; - float scale_mat4[4][4]; - - public: - enum UnitSystem { - None, - Metric, - Imperial, - }; - - // Initialize with Z_UP, since Blender uses right-handed, z-up - UnitConverter(); - - void read_asset(const COLLADAFW::FileInfo *asset); - - void convertVector3(COLLADABU::Math::Vector3 &vec, float *v); - - UnitConverter::UnitSystem isMetricSystem(void); - - float getLinearMeter(void); - - // TODO need also for angle conversion, time conversion... - - static void dae_matrix_to_mat4_(float out[4][4], const COLLADABU::Math::Matrix4 &in); - static void mat4_to_dae(float out[4][4], float in[4][4]); - static void mat4_to_dae_double(double out[4][4], float in[4][4]); - - float (&get_rotation())[4][4]; - float (&get_scale())[4][4]; - void calculate_scale(Scene &sce); -}; - -extern void clear_global_id_map(); -/** Look at documentation of translate_map */ -extern std::string translate_id(const std::string &id); -extern std::string translate_id(const char *idString); - -extern std::string id_name(void *id); -extern std::string encode_xml(std::string xml); - -extern std::string get_geometry_id(Object *ob); -extern std::string get_geometry_id(Object *ob, bool use_instantiation); - -extern std::string get_light_id(Object *ob); - -extern std::string get_joint_sid(Bone *bone); - -extern std::string get_camera_id(Object *ob); -extern std::string get_morph_id(Object *ob); - -extern std::string get_effect_id(Material *mat); -extern std::string get_material_id(Material *mat); - -#endif /* __COLLADA_INTERNAL_H__ */ diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp deleted file mode 100644 index 26b392af0a1..00000000000 --- a/source/blender/collada/collada_utils.cpp +++ /dev/null @@ -1,1458 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -/* COLLADABU_ASSERT, may be able to remove later */ -#include "COLLADABUPlatform.h" - -#include "COLLADAFWGeometry.h" -#include "COLLADAFWMeshPrimitive.h" -#include "COLLADAFWMeshVertexData.h" - -#include <set> -#include <string> - -#include "MEM_guardedalloc.h" - -extern "C" { -#include "DNA_modifier_types.h" -#include "DNA_customdata_types.h" -#include "DNA_key_types.h" -#include "DNA_object_types.h" -#include "DNA_constraint_types.h" -#include "DNA_mesh_types.h" -#include "DNA_scene_types.h" -#include "DNA_armature_types.h" - -#include "BLI_math.h" -#include "BLI_linklist.h" -#include "BLI_listbase.h" - -#include "BKE_action.h" -#include "BKE_context.h" -#include "BKE_customdata.h" -#include "BKE_constraint.h" -#include "BKE_key.h" -#include "BKE_material.h" -#include "BKE_node.h" -#include "BKE_object.h" -#include "BKE_global.h" -#include "BKE_layer.h" -#include "BKE_lib_id.h" -#include "BKE_mesh.h" -#include "BKE_mesh_runtime.h" -#include "BKE_object.h" -#include "BKE_scene.h" - -#include "ED_armature.h" -#include "ED_screen.h" -#include "ED_node.h" -#include "ED_object.h" - -#include "WM_api.h" /* XXX hrm, see if we can do without this */ -#include "WM_types.h" - -#include "bmesh.h" -#include "bmesh_tools.h" - -#include "DEG_depsgraph.h" -#include "DEG_depsgraph_query.h" -#if 0 -# include "NOD_common.h" -#endif -} - -#include "collada_utils.h" -#include "ExportSettings.h" -#include "BlenderContext.h" - -float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index) -{ - if (index >= array.getValuesCount()) { - return 0.0f; - } - - if (array.getType() == COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT) { - return array.getFloatValues()->getData()[index]; - } - else { - return array.getDoubleValues()->getData()[index]; - } -} - -/* copied from /editors/object/object_relations.c */ -int bc_test_parent_loop(Object *par, Object *ob) -{ - /* test if 'ob' is a parent somewhere in par's parents */ - - if (par == NULL) { - return 0; - } - if (ob == par) { - return 1; - } - - return bc_test_parent_loop(par->parent, ob); -} - -bool bc_validateConstraints(bConstraint *con) -{ - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - - /* these we can skip completely (invalid constraints...) */ - if (cti == NULL) { - return false; - } - if (con->flag & (CONSTRAINT_DISABLE | CONSTRAINT_OFF)) { - return false; - } - - /* these constraints can't be evaluated anyway */ - if (cti->evaluate_constraint == NULL) { - return false; - } - - /* influence == 0 should be ignored */ - if (con->enforce == 0.0f) { - return false; - } - - /* validation passed */ - return true; -} - -bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) -{ - Scene *scene = CTX_data_scene(C); - int partype = PAR_OBJECT; - const bool xmirror = false; - const bool keep_transform = false; - - if (par && is_parent_space) { - mul_m4_m4m4(ob->obmat, par->obmat, ob->obmat); - } - - bool ok = ED_object_parent_set(NULL, C, scene, ob, par, partype, xmirror, keep_transform, NULL); - return ok; -} - -std::vector<bAction *> bc_getSceneActions(const bContext *C, Object *ob, bool all_actions) -{ - std::vector<bAction *> actions; - if (all_actions) { - Main *bmain = CTX_data_main(C); - ID *id; - - for (id = (ID *)bmain->actions.first; id; id = (ID *)(id->next)) { - bAction *act = (bAction *)id; - /* XXX This currently creates too many actions. - * TODO Need to check if the action is compatible to the given object. */ - actions.push_back(act); - } - } - else { - bAction *action = bc_getSceneObjectAction(ob); - actions.push_back(action); - } - - return actions; -} - -std::string bc_get_action_id(std::string action_name, - std::string ob_name, - std::string channel_type, - std::string axis_name, - std::string axis_separator) -{ - std::string result = action_name + "_" + channel_type; - if (ob_name.length() > 0) { - result = ob_name + "_" + result; - } - if (axis_name.length() > 0) { - result += axis_separator + axis_name; - } - return translate_id(result); -} - -void bc_update_scene(BlenderContext &blender_context, float ctime) -{ - Main *bmain = blender_context.get_main(); - Scene *scene = blender_context.get_scene(); - Depsgraph *depsgraph = blender_context.get_depsgraph(); - - /* See remark in physics_fluid.c lines 395...) */ - // BKE_scene_update_for_newframe(ev_context, bmain, scene, scene->lay); - BKE_scene_frame_set(scene, ctime); - ED_update_for_newframe(bmain, depsgraph); -} - -Object *bc_add_object(Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name) -{ - Object *ob = BKE_object_add_only_object(bmain, type, name); - - ob->data = BKE_object_obdata_add_from_type(bmain, type, name); - DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); - - LayerCollection *layer_collection = BKE_layer_collection_get_active(view_layer); - BKE_collection_object_add(bmain, layer_collection->collection, ob); - - Base *base = BKE_view_layer_base_find(view_layer, ob); - /* TODO: is setting active needed? */ - BKE_view_layer_base_select_and_set_active(view_layer, base); - - return ob; -} - -Mesh *bc_get_mesh_copy(BlenderContext &blender_context, - Object *ob, - BC_export_mesh_type export_mesh_type, - bool apply_modifiers, - bool triangulate) -{ - CustomData_MeshMasks mask = CD_MASK_MESH; - Mesh *tmpmesh = NULL; - if (apply_modifiers) { -#if 0 /* Not supported by new system currently... */ - switch (export_mesh_type) { - case BC_MESH_TYPE_VIEW: { - dm = mesh_create_derived_view(depsgraph, scene, ob, &mask); - break; - } - case BC_MESH_TYPE_RENDER: { - dm = mesh_create_derived_render(depsgraph, scene, ob, &mask); - break; - } - } -#else - Depsgraph *depsgraph = blender_context.get_depsgraph(); - Scene *scene_eval = blender_context.get_evaluated_scene(); - Object *ob_eval = blender_context.get_evaluated_object(ob); - tmpmesh = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, &mask); -#endif - } - else { - tmpmesh = (Mesh *)ob->data; - } - - BKE_id_copy_ex(NULL, &tmpmesh->id, (ID **)&tmpmesh, LIB_ID_COPY_LOCALIZE); - - if (triangulate) { - bc_triangulate_mesh(tmpmesh); - } - BKE_mesh_tessface_ensure(tmpmesh); - return tmpmesh; -} - -Object *bc_get_assigned_armature(Object *ob) -{ - Object *ob_arm = NULL; - - if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) { - ob_arm = ob->parent; - } - else { - ModifierData *mod; - for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) { - if (mod->type == eModifierType_Armature) { - ob_arm = ((ArmatureModifierData *)mod)->object; - } - } - } - - return ob_arm; -} - -bool bc_has_object_type(LinkNode *export_set, short obtype) -{ - LinkNode *node; - - for (node = export_set; node; node = node->next) { - Object *ob = (Object *)node->link; - /* XXX - why is this checking for ob->data? - we could be looking for empties */ - if (ob->type == obtype && ob->data) { - return true; - } - } - return false; -} - -/* Use bubble sort algorithm for sorting the export set */ -void bc_bubble_sort_by_Object_name(LinkNode *export_set) -{ - bool sorted = false; - LinkNode *node; - for (node = export_set; node->next && !sorted; node = node->next) { - - sorted = true; - - LinkNode *current; - for (current = export_set; current->next; current = current->next) { - Object *a = (Object *)current->link; - Object *b = (Object *)current->next->link; - - if (strcmp(a->id.name, b->id.name) > 0) { - current->link = b; - current->next->link = a; - sorted = false; - } - } - } -} - -/* Check if a bone is the top most exportable bone in the bone hierarchy. - * When deform_bones_only == false, then only bones with NO parent - * can be root bones. Otherwise the top most deform bones in the hierarchy - * are root bones. - */ -bool bc_is_root_bone(Bone *aBone, bool deform_bones_only) -{ - if (deform_bones_only) { - Bone *root = NULL; - Bone *bone = aBone; - while (bone) { - if (!(bone->flag & BONE_NO_DEFORM)) { - root = bone; - } - bone = bone->parent; - } - return (aBone == root); - } - else { - return !(aBone->parent); - } -} - -int bc_get_active_UVLayer(Object *ob) -{ - Mesh *me = (Mesh *)ob->data; - return CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV); -} - -std::string bc_url_encode(std::string data) -{ - /* XXX We probably do not need to do a full encoding. - * But in case that is necessary,then it can be added here. - */ - return bc_replace_string(data, "#", "%23"); -} - -std::string bc_replace_string(std::string data, - const std::string &pattern, - const std::string &replacement) -{ - size_t pos = 0; - while ((pos = data.find(pattern, pos)) != std::string::npos) { - data.replace(pos, pattern.length(), replacement); - pos += replacement.length(); - } - return data; -} - -/** - * Calculate a rescale factor such that the imported scene's scale - * is preserved. I.e. 1 meter in the import will also be - * 1 meter in the current scene. - */ - -void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene) -{ - if (scale_to_scene) { - mul_m4_m4m4(ob->obmat, bc_unit.get_scale(), ob->obmat); - } - mul_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat); - BKE_object_apply_mat4(ob, ob->obmat, 0, 0); -} - -void bc_match_scale(std::vector<Object *> *objects_done, - UnitConverter &bc_unit, - bool scale_to_scene) -{ - for (std::vector<Object *>::iterator it = objects_done->begin(); it != objects_done->end(); - ++it) { - Object *ob = *it; - if (ob->parent == NULL) { - bc_match_scale(*it, bc_unit, scale_to_scene); - } - } -} - -/* - * Convenience function to get only the needed components of a matrix - */ -void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size) -{ - if (size) { - mat4_to_size(size, mat); - } - - if (eul) { - mat4_to_eul(eul, mat); - } - - if (quat) { - mat4_to_quat(quat, mat); - } - - if (loc) { - copy_v3_v3(loc, mat[3]); - } -} - -/* - * Create rotation_quaternion from a delta rotation and a reference quat - * - * Input: - * mat_from: The rotation matrix before rotation - * mat_to : The rotation matrix after rotation - * qref : the quat corresponding to mat_from - * - * Output: - * rot : the calculated result (quaternion) - */ -void bc_rotate_from_reference_quat(float quat_to[4], float quat_from[4], float mat_to[4][4]) -{ - float qd[4]; - float matd[4][4]; - float mati[4][4]; - float mat_from[4][4]; - quat_to_mat4(mat_from, quat_from); - - /* Calculate the difference matrix matd between mat_from and mat_to */ - invert_m4_m4(mati, mat_from); - mul_m4_m4m4(matd, mati, mat_to); - - mat4_to_quat(qd, matd); - - mul_qt_qtqt(quat_to, qd, quat_from); /* rot is the final rotation corresponding to mat_to */ -} - -void bc_triangulate_mesh(Mesh *me) -{ - bool use_beauty = false; - bool tag_only = false; - - /* XXX: The triangulation method selection could be offered in the UI. */ - int quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; - - const struct BMeshCreateParams bm_create_params = {0}; - BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default, &bm_create_params); - BMeshFromMeshParams bm_from_me_params = {0}; - bm_from_me_params.calc_face_normal = true; - BM_mesh_bm_from_me(bm, me, &bm_from_me_params); - BM_mesh_triangulate(bm, quad_method, use_beauty, 4, tag_only, NULL, NULL, NULL); - - BMeshToMeshParams bm_to_me_params = {0}; - bm_to_me_params.calc_object_remap = false; - BM_mesh_bm_to_me(NULL, bm, me, &bm_to_me_params); - BM_mesh_free(bm); -} - -/* - * A bone is a leaf when it has no children or all children are not connected. - */ -bool bc_is_leaf_bone(Bone *bone) -{ - for (Bone *child = (Bone *)bone->childbase.first; child; child = child->next) { - if (child->flag & BONE_CONNECTED) { - return false; - } - } - return true; -} - -EditBone *bc_get_edit_bone(bArmature *armature, char *name) -{ - EditBone *eBone; - - for (eBone = (EditBone *)armature->edbo->first; eBone; eBone = eBone->next) { - if (STREQ(name, eBone->name)) { - return eBone; - } - } - - return NULL; -} -int bc_set_layer(int bitfield, int layer) -{ - return bc_set_layer(bitfield, layer, true); /* enable */ -} - -int bc_set_layer(int bitfield, int layer, bool enable) -{ - int bit = 1u << layer; - - if (enable) { - bitfield |= bit; - } - else { - bitfield &= ~bit; - } - - return bitfield; -} - -/** - * This method creates a new extension map when needed. - * \note The ~BoneExtensionManager destructor takes care - * to delete the created maps when the manager is removed. - */ -BoneExtensionMap &BoneExtensionManager::getExtensionMap(bArmature *armature) -{ - std::string key = armature->id.name; - BoneExtensionMap *result = extended_bone_maps[key]; - if (result == NULL) { - result = new BoneExtensionMap(); - extended_bone_maps[key] = result; - } - return *result; -} - -BoneExtensionManager::~BoneExtensionManager() -{ - std::map<std::string, BoneExtensionMap *>::iterator map_it; - for (map_it = extended_bone_maps.begin(); map_it != extended_bone_maps.end(); ++map_it) { - BoneExtensionMap *extended_bones = map_it->second; - for (BoneExtensionMap::iterator ext_it = extended_bones->begin(); - ext_it != extended_bones->end(); - ++ext_it) { - if (ext_it->second != NULL) { - delete ext_it->second; - } - } - extended_bones->clear(); - delete extended_bones; - } -} - -/** - * BoneExtended is a helper class needed for the Bone chain finder - * See ArmatureImporter::fix_leaf_bones() - * and ArmatureImporter::connect_bone_chains() - */ - -BoneExtended::BoneExtended(EditBone *aBone) -{ - this->set_name(aBone->name); - this->chain_length = 0; - this->is_leaf = false; - this->tail[0] = 0.0f; - this->tail[1] = 0.5f; - this->tail[2] = 0.0f; - this->use_connect = -1; - this->roll = 0; - this->bone_layers = 0; - - this->has_custom_tail = false; - this->has_custom_roll = false; -} - -char *BoneExtended::get_name() -{ - return name; -} - -void BoneExtended::set_name(char *aName) -{ - BLI_strncpy(name, aName, MAXBONENAME); -} - -int BoneExtended::get_chain_length() -{ - return chain_length; -} - -void BoneExtended::set_chain_length(const int aLength) -{ - chain_length = aLength; -} - -void BoneExtended::set_leaf_bone(bool state) -{ - is_leaf = state; -} - -bool BoneExtended::is_leaf_bone() -{ - return is_leaf; -} - -void BoneExtended::set_roll(float roll) -{ - this->roll = roll; - this->has_custom_roll = true; -} - -bool BoneExtended::has_roll() -{ - return this->has_custom_roll; -} - -float BoneExtended::get_roll() -{ - return this->roll; -} - -void BoneExtended::set_tail(float vec[]) -{ - this->tail[0] = vec[0]; - this->tail[1] = vec[1]; - this->tail[2] = vec[2]; - this->has_custom_tail = true; -} - -bool BoneExtended::has_tail() -{ - return this->has_custom_tail; -} - -float *BoneExtended::get_tail() -{ - return this->tail; -} - -inline bool isInteger(const std::string &s) -{ - if (s.empty() || ((!isdigit(s[0])) && (s[0] != '-') && (s[0] != '+'))) { - return false; - } - - char *p; - strtol(s.c_str(), &p, 10); - - return (*p == 0); -} - -void BoneExtended::set_bone_layers(std::string layerString, std::vector<std::string> &layer_labels) -{ - std::stringstream ss(layerString); - std::string layer; - int pos; - - while (ss >> layer) { - - /* Blender uses numbers to specify layers*/ - if (isInteger(layer)) { - pos = atoi(layer.c_str()); - if (pos >= 0 && pos < 32) { - this->bone_layers = bc_set_layer(this->bone_layers, pos); - continue; - } - } - - /* layer uses labels (not supported by blender). Map to layer numbers:*/ - pos = find(layer_labels.begin(), layer_labels.end(), layer) - layer_labels.begin(); - if (pos >= layer_labels.size()) { - layer_labels.push_back(layer); /* remember layer number for future usage*/ - } - - if (pos > 31) { - fprintf(stderr, - "Too many layers in Import. Layer %s mapped to Blender layer 31\n", - layer.c_str()); - pos = 31; - } - - /* If numeric layers and labeled layers are used in parallel (unlikely), - * we get a potential mixup. Just leave as is for now. - */ - this->bone_layers = bc_set_layer(this->bone_layers, pos); - } -} - -std::string BoneExtended::get_bone_layers(int bitfield) -{ - std::string result = ""; - std::string sep = ""; - int bit = 1u; - - std::ostringstream ss; - for (int i = 0; i < 32; i++) { - if (bit & bitfield) { - ss << sep << i; - sep = " "; - } - bit = bit << 1; - } - return ss.str(); -} - -int BoneExtended::get_bone_layers() -{ - /* ensure that the bone is in at least one bone layer! */ - return (bone_layers == 0) ? 1 : bone_layers; -} - -void BoneExtended::set_use_connect(int use_connect) -{ - this->use_connect = use_connect; -} - -int BoneExtended::get_use_connect() -{ - return this->use_connect; -} - -/** - * Stores a 4*4 matrix as a custom bone property array of size 16 - */ -void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4]) -{ - IDProperty *idgroup = (IDProperty *)ebone->prop; - if (idgroup == NULL) { - IDPropertyTemplate val = {0}; - idgroup = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties"); - ebone->prop = idgroup; - } - - IDPropertyTemplate val = {0}; - val.array.len = 16; - val.array.type = IDP_FLOAT; - - IDProperty *data = IDP_New(IDP_ARRAY, &val, key); - float *array = (float *)IDP_Array(data); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - array[4 * i + j] = mat[i][j]; - } - } - - IDP_AddToGroup(idgroup, data); -} - -#if 0 -/** - * Stores a Float value as a custom bone property - * - * Note: This function is currently not needed. Keep for future usage - */ -static void bc_set_IDProperty(EditBone *ebone, const char *key, float value) -{ - if (ebone->prop == NULL) { - IDPropertyTemplate val = {0}; - ebone->prop = IDP_New(IDP_GROUP, &val, "RNA_EditBone ID properties"); - } - - IDProperty *pgroup = (IDProperty *)ebone->prop; - IDPropertyTemplate val = {0}; - IDProperty *prop = IDP_New(IDP_FLOAT, &val, key); - IDP_Float(prop) = value; - IDP_AddToGroup(pgroup, prop); -} -#endif - -/** - * Get a custom property when it exists. - * This function is also used to check if a property exists. - */ -IDProperty *bc_get_IDProperty(Bone *bone, std::string key) -{ - return (bone->prop == NULL) ? NULL : IDP_GetPropertyFromGroup(bone->prop, key.c_str()); -} - -/** - * Read a custom bone property and convert to float - * Return def if the property does not exist. - */ -float bc_get_property(Bone *bone, std::string key, float def) -{ - float result = def; - IDProperty *property = bc_get_IDProperty(bone, key); - if (property) { - switch (property->type) { - case IDP_INT: - result = (float)(IDP_Int(property)); - break; - case IDP_FLOAT: - result = (float)(IDP_Float(property)); - break; - case IDP_DOUBLE: - result = (float)(IDP_Double(property)); - break; - default: - result = def; - } - } - return result; -} - -/** - * Read a custom bone property and convert to matrix - * Return true if conversion was successful - * - * Return false if: - * - the property does not exist - * - is not an array of size 16 - */ -bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4]) -{ - IDProperty *property = bc_get_IDProperty(bone, key); - if (property && property->type == IDP_ARRAY && property->len == 16) { - float *array = (float *)IDP_Array(property); - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - mat[i][j] = array[4 * i + j]; - } - } - return true; - } - return false; -} - -/** - * get a vector that is stored in 3 custom properties (used in Blender <= 2.78) - */ -void bc_get_property_vector(Bone *bone, std::string key, float val[3], const float def[3]) -{ - val[0] = bc_get_property(bone, key + "_x", def[0]); - val[1] = bc_get_property(bone, key + "_y", def[1]); - val[2] = bc_get_property(bone, key + "_z", def[2]); -} - -/** - * Check if vector exist stored in 3 custom properties (used in Blender <= 2.78) - */ -static bool has_custom_props(Bone *bone, bool enabled, std::string key) -{ - if (!enabled) { - return false; - } - - return (bc_get_IDProperty(bone, key + "_x") || bc_get_IDProperty(bone, key + "_y") || - bc_get_IDProperty(bone, key + "_z")); -} - -void bc_enable_fcurves(bAction *act, char *bone_name) -{ - FCurve *fcu; - char prefix[200]; - - if (bone_name) { - BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name); - } - - for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) { - if (bone_name) { - if (STREQLEN(fcu->rna_path, prefix, strlen(prefix))) { - fcu->flag &= ~FCURVE_DISABLED; - } - else { - fcu->flag |= FCURVE_DISABLED; - } - } - else { - fcu->flag &= ~FCURVE_DISABLED; - } - } -} - -bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim) -{ - - /* Ok, lets be super cautious and check if the bone exists */ - bPose *pose = ob->pose; - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name); - if (!pchan) { - return false; - } - - bAction *action = bc_getSceneObjectAction(ob); - bPoseChannel *parchan = pchan->parent; - - bc_enable_fcurves(action, bone->name); - float ipar[4][4]; - - if (bone->parent) { - invert_m4_m4(ipar, parchan->pose_mat); - mul_m4_m4m4(mat, ipar, pchan->pose_mat); - } - else { - copy_m4_m4(mat, pchan->pose_mat); - } - - /* OPEN_SIM_COMPATIBILITY - * AFAIK animation to second life is via BVH, but no - * reason to not have the collada-animation be correct */ - if (for_opensim) { - float temp[4][4]; - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - invert_m4(temp); - - mul_m4_m4m4(mat, mat, temp); - - if (bone->parent) { - copy_m4_m4(temp, bone->parent->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - - mul_m4_m4m4(mat, temp, mat); - } - } - bc_enable_fcurves(action, NULL); - return true; -} - -bool bc_is_animated(BCMatrixSampleMap &values) -{ - static float MIN_DISTANCE = 0.00001; - - if (values.size() < 2) { - return false; /* need at least 2 entries to be not flat */ - } - - BCMatrixSampleMap::iterator it; - const BCMatrix *refmat = NULL; - for (it = values.begin(); it != values.end(); ++it) { - const BCMatrix *matrix = it->second; - - if (refmat == NULL) { - refmat = matrix; - continue; - } - - if (!matrix->in_range(*refmat, MIN_DISTANCE)) { - return true; - } - } - return false; -} - -bool bc_has_animations(Object *ob) -{ - /* Check for object, light and camera transform animations */ - if ((bc_getSceneObjectAction(ob) && bc_getSceneObjectAction(ob)->curves.first) || - (bc_getSceneLightAction(ob) && bc_getSceneLightAction(ob)->curves.first) || - (bc_getSceneCameraAction(ob) && bc_getSceneCameraAction(ob)->curves.first)) { - return true; - } - - /* Check Material Effect parameter animations. */ - for (int a = 0; a < ob->totcol; a++) { - Material *ma = BKE_object_material_get(ob, a + 1); - if (!ma) { - continue; - } - if (ma->adt && ma->adt->action && ma->adt->action->curves.first) { - return true; - } - } - - Key *key = BKE_key_from_object(ob); - if ((key && key->adt && key->adt->action) && key->adt->action->curves.first) { - return true; - } - - return false; -} - -bool bc_has_animations(Scene *sce, LinkNode *export_set) -{ - LinkNode *node; - if (export_set) { - for (node = export_set; node; node = node->next) { - Object *ob = (Object *)node->link; - - if (bc_has_animations(ob)) { - return true; - } - } - } - return false; -} - -void bc_add_global_transform(Matrix &to_mat, - const Matrix &from_mat, - const BCMatrix &global_transform, - const bool invert) -{ - copy_m4_m4(to_mat, from_mat); - bc_add_global_transform(to_mat, global_transform, invert); -} - -void bc_add_global_transform(Vector &to_vec, - const Vector &from_vec, - const BCMatrix &global_transform, - const bool invert) -{ - copy_v3_v3(to_vec, from_vec); - bc_add_global_transform(to_vec, global_transform, invert); -} - -void bc_add_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert) -{ - BCMatrix mat(to_mat); - mat.add_transform(global_transform, invert); - mat.get_matrix(to_mat); -} - -void bc_add_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert) -{ - Matrix mat; - Vector from_vec; - copy_v3_v3(from_vec, to_vec); - global_transform.get_matrix(mat, false, 6, invert); - mul_v3_m4v3(to_vec, mat, from_vec); -} - -void bc_apply_global_transform(Matrix &to_mat, const BCMatrix &global_transform, const bool invert) -{ - BCMatrix mat(to_mat); - mat.apply_transform(global_transform, invert); - mat.get_matrix(to_mat); -} - -void bc_apply_global_transform(Vector &to_vec, const BCMatrix &global_transform, const bool invert) -{ - Matrix transform; - global_transform.get_matrix(transform); - mul_v3_m4v3(to_vec, transform, to_vec); -} - -/** - * Check if custom information about bind matrix exists and modify the from_mat - * accordingly. - * - * Note: This is old style for Blender <= 2.78 only kept for compatibility - */ -void bc_create_restpose_mat(BCExportSettings &export_settings, - Bone *bone, - float to_mat[4][4], - float from_mat[4][4], - bool use_local_space) -{ - float loc[3]; - float rot[3]; - float scale[3]; - static const float V0[3] = {0, 0, 0}; - - if (!has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_loc") && - !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_rot") && - !has_custom_props(bone, export_settings.get_keep_bind_info(), "restpose_scale")) { - /* No need */ - copy_m4_m4(to_mat, from_mat); - return; - } - - bc_decompose(from_mat, loc, rot, NULL, scale); - loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6); - - if (export_settings.get_keep_bind_info()) { - bc_get_property_vector(bone, "restpose_loc", loc, loc); - - if (use_local_space && bone->parent) { - Bone *b = bone; - while (b->parent) { - b = b->parent; - float ploc[3]; - bc_get_property_vector(b, "restpose_loc", ploc, V0); - loc[0] += ploc[0]; - loc[1] += ploc[1]; - loc[2] += ploc[2]; - } - } - } - - if (export_settings.get_keep_bind_info()) { - if (bc_get_IDProperty(bone, "restpose_rot_x")) { - rot[0] = DEG2RADF(bc_get_property(bone, "restpose_rot_x", 0)); - } - if (bc_get_IDProperty(bone, "restpose_rot_y")) { - rot[1] = DEG2RADF(bc_get_property(bone, "restpose_rot_y", 0)); - } - if (bc_get_IDProperty(bone, "restpose_rot_z")) { - rot[2] = DEG2RADF(bc_get_property(bone, "restpose_rot_z", 0)); - } - } - - if (export_settings.get_keep_bind_info()) { - bc_get_property_vector(bone, "restpose_scale", scale, scale); - } - - loc_eulO_size_to_mat4(to_mat, loc, rot, scale, 6); -} - -void bc_sanitize_v3(float v[3], int precision) -{ - for (int i = 0; i < 3; i++) { - double val = (double)v[i]; - val = double_round(val, precision); - v[i] = (float)val; - } -} - -void bc_sanitize_v3(double v[3], int precision) -{ - for (int i = 0; i < 3; i++) { - v[i] = double_round(v[i], precision); - } -} - -void bc_copy_m4_farray(float r[4][4], float *a) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - r[i][j] = *a++; - } - } -} - -void bc_copy_farray_m4(float *r, float a[4][4]) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - *r++ = a[i][j]; - } - } -} - -void bc_copy_darray_m4d(double *r, double a[4][4]) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - *r++ = a[i][j]; - } - } -} - -void bc_copy_v44_m4d(std::vector<std::vector<double>> &r, double (&a)[4][4]) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - r[i][j] = a[i][j]; - } - } -} - -void bc_copy_m4d_v44(double (&r)[4][4], std::vector<std::vector<double>> &a) -{ - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - r[i][j] = a[i][j]; - } - } -} - -/** - * Returns name of Active UV Layer or empty String if no active UV Layer defined - */ -static std::string bc_get_active_uvlayer_name(Mesh *me) -{ - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - if (num_layers) { - char *layer_name = bc_CustomData_get_active_layer_name(&me->ldata, CD_MLOOPUV); - if (layer_name) { - return std::string(layer_name); - } - } - return ""; -} - -/** - * Returns name of Active UV Layer or empty String if no active UV Layer defined. - * Assuming the Object is of type MESH - */ -static std::string bc_get_active_uvlayer_name(Object *ob) -{ - Mesh *me = (Mesh *)ob->data; - return bc_get_active_uvlayer_name(me); -} - -/** - * Returns UV Layer name or empty string if layer index is out of range - */ -static std::string bc_get_uvlayer_name(Mesh *me, int layer) -{ - int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV); - if (num_layers && layer < num_layers) { - char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPUV, layer); - if (layer_name) { - return std::string(layer_name); - } - } - return ""; -} - -std::string bc_find_bonename_in_path(std::string path, std::string probe) -{ - std::string result; - char *boneName = BLI_str_quoted_substrN(path.c_str(), probe.c_str()); - if (boneName) { - result = std::string(boneName); - MEM_freeN(boneName); - } - return result; -} - -static bNodeTree *prepare_material_nodetree(Material *ma) -{ - if (ma->nodetree == NULL) { - ma->nodetree = ntreeAddTree(NULL, "Shader Nodetree", "ShaderNodeTree"); - ma->use_nodes = true; - } - return ma->nodetree; -} - -static bNode *bc_add_node( - bContext *C, bNodeTree *ntree, int node_type, int locx, int locy, std::string label) -{ - bNode *node = nodeAddStaticNode(C, ntree, node_type); - if (node) { - if (label.length() > 0) { - strcpy(node->label, label.c_str()); - } - node->locx = locx; - node->locy = locy; - node->flag |= NODE_SELECT; - } - return node; -} - -static bNode *bc_add_node(bContext *C, bNodeTree *ntree, int node_type, int locx, int locy) -{ - return bc_add_node(C, ntree, node_type, locx, locy, ""); -} - -#if 0 -/* experimental, probably not used */ -static bNodeSocket *bc_group_add_input_socket(bNodeTree *ntree, - bNode *to_node, - int to_index, - std::string label) -{ - bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index); - - //bNodeSocket *socket = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket); - //return socket; - - bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket); - bNode *inputGroup = ntreeFindType(ntree, NODE_GROUP_INPUT); - node_group_input_verify(ntree, inputGroup, (ID *)ntree); - bNodeSocket *newsock = node_group_input_find_socket(inputGroup, gsock->identifier); - nodeAddLink(ntree, inputGroup, newsock, to_node, to_socket); - strcpy(newsock->name, label.c_str()); - return newsock; -} - -static bNodeSocket *bc_group_add_output_socket(bNodeTree *ntree, - bNode *from_node, - int from_index, - std::string label) -{ - bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index); - - //bNodeSocket *socket = ntreeAddSocketInterfaceFromSocket(ntree, to_node, to_socket); - //return socket; - - bNodeSocket *gsock = ntreeAddSocketInterfaceFromSocket(ntree, from_node, from_socket); - bNode *outputGroup = ntreeFindType(ntree, NODE_GROUP_OUTPUT); - node_group_output_verify(ntree, outputGroup, (ID *)ntree); - bNodeSocket *newsock = node_group_output_find_socket(outputGroup, gsock->identifier); - nodeAddLink(ntree, from_node, from_socket, outputGroup, newsock); - strcpy(newsock->name, label.c_str()); - return newsock; -} - -void bc_make_group(bContext *C, bNodeTree *ntree, std::map<std::string, bNode *> nmap) -{ - bNode *gnode = node_group_make_from_selected(C, ntree, "ShaderNodeGroup", "ShaderNodeTree"); - bNodeTree *gtree = (bNodeTree *)gnode->id; - - bc_group_add_input_socket(gtree, nmap["main"], 0, "Diffuse"); - bc_group_add_input_socket(gtree, nmap["emission"], 0, "Emission"); - bc_group_add_input_socket(gtree, nmap["mix"], 0, "Transparency"); - bc_group_add_input_socket(gtree, nmap["emission"], 1, "Emission"); - bc_group_add_input_socket(gtree, nmap["main"], 4, "Metallic"); - bc_group_add_input_socket(gtree, nmap["main"], 5, "Specular"); - - bc_group_add_output_socket(gtree, nmap["mix"], 0, "Shader"); -} -#endif - -static void bc_node_add_link( - bNodeTree *ntree, bNode *from_node, int from_index, bNode *to_node, int to_index) -{ - bNodeSocket *from_socket = (bNodeSocket *)BLI_findlink(&from_node->outputs, from_index); - bNodeSocket *to_socket = (bNodeSocket *)BLI_findlink(&to_node->inputs, to_index); - - nodeAddLink(ntree, from_node, from_socket, to_node, to_socket); -} - -void bc_add_default_shader(bContext *C, Material *ma) -{ - bNodeTree *ntree = prepare_material_nodetree(ma); - std::map<std::string, bNode *> nmap; -#if 0 - nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, -300, 300); - nmap["emission"] = bc_add_node(C, ntree, SH_NODE_EMISSION, -300, 500, "emission"); - nmap["add"] = bc_add_node(C, ntree, SH_NODE_ADD_SHADER, 100, 400); - nmap["transparent"] = bc_add_node(C, ntree, SH_NODE_BSDF_TRANSPARENT, 100, 200); - nmap["mix"] = bc_add_node(C, ntree, SH_NODE_MIX_SHADER, 400, 300, "transparency"); - nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 600, 300); - nmap["out"]->flag &= ~NODE_SELECT; - - bc_node_add_link(ntree, nmap["emission"], 0, nmap["add"], 0); - bc_node_add_link(ntree, nmap["main"], 0, nmap["add"], 1); - bc_node_add_link(ntree, nmap["add"], 0, nmap["mix"], 1); - bc_node_add_link(ntree, nmap["transparent"], 0, nmap["mix"], 2); - - bc_node_add_link(ntree, nmap["mix"], 0, nmap["out"], 0); - /* experimental, probably not used. */ - bc_make_group(C, ntree, nmap); -#else - nmap["main"] = bc_add_node(C, ntree, SH_NODE_BSDF_PRINCIPLED, 0, 300); - nmap["out"] = bc_add_node(C, ntree, SH_NODE_OUTPUT_MATERIAL, 300, 300); - bc_node_add_link(ntree, nmap["main"], 0, nmap["out"], 0); -#endif -} - -COLLADASW::ColorOrTexture bc_get_base_color(Material *ma) -{ - /* for alpha see bc_get_alpha() */ - Color default_color = {ma->r, ma->g, ma->b, 1.0}; - bNode *shader = bc_get_master_shader(ma); - if (ma->use_nodes && shader) { - return bc_get_cot_from_shader(shader, "Base Color", default_color, false); - } - else { - return bc_get_cot(default_color); - } -} - -COLLADASW::ColorOrTexture bc_get_emission(Material *ma) -{ - Color default_color = {0, 0, 0, 1}; - bNode *shader = bc_get_master_shader(ma); - if (ma->use_nodes && shader) { - return bc_get_cot_from_shader(shader, "Emission", default_color); - } - else { - return bc_get_cot(default_color); /* default black */ - } -} - -COLLADASW::ColorOrTexture bc_get_ambient(Material *ma) -{ - Color default_color = {0, 0, 0, 1.0}; - return bc_get_cot(default_color); -} - -COLLADASW::ColorOrTexture bc_get_specular(Material *ma) -{ - Color default_color = {0, 0, 0, 1.0}; - return bc_get_cot(default_color); -} - -COLLADASW::ColorOrTexture bc_get_reflective(Material *ma) -{ - Color default_color = {0, 0, 0, 1.0}; - return bc_get_cot(default_color); -} - -double bc_get_alpha(Material *ma) -{ - double alpha = ma->a; /* fallback if no socket found */ - bNode *master_shader = bc_get_master_shader(ma); - if (ma->use_nodes && master_shader) { - bc_get_float_from_shader(master_shader, alpha, "Alpha"); - } - return alpha; -} - -double bc_get_ior(Material *ma) -{ - double ior = -1; /* fallback if no socket found */ - bNode *master_shader = bc_get_master_shader(ma); - if (ma->use_nodes && master_shader) { - bc_get_float_from_shader(master_shader, ior, "IOR"); - } - return ior; -} - -double bc_get_shininess(Material *ma) -{ - double ior = -1; /* fallback if no socket found */ - bNode *master_shader = bc_get_master_shader(ma); - if (ma->use_nodes && master_shader) { - bc_get_float_from_shader(master_shader, ior, "Roughness"); - } - return ior; -} - -double bc_get_reflectivity(Material *ma) -{ - double reflectivity = ma->spec; /* fallback if no socket found */ - bNode *master_shader = bc_get_master_shader(ma); - if (ma->use_nodes && master_shader) { - bc_get_float_from_shader(master_shader, reflectivity, "Metallic"); - } - return reflectivity; -} - -double bc_get_float_from_shader(bNode *shader, double &val, std::string nodeid) -{ - bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, nodeid.c_str()); - if (socket) { - bNodeSocketValueFloat *ref = (bNodeSocketValueFloat *)socket->default_value; - val = (double)ref->value; - return true; - } - return false; -} - -COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader, - std::string nodeid, - Color &default_color, - bool with_alpha) -{ - bNodeSocket *socket = nodeFindSocket(shader, SOCK_IN, nodeid.c_str()); - if (socket) { - bNodeSocketValueRGBA *dcol = (bNodeSocketValueRGBA *)socket->default_value; - float *col = dcol->value; - return bc_get_cot(col, with_alpha); - } - else { - return bc_get_cot(default_color, with_alpha); - } -} - -bNode *bc_get_master_shader(Material *ma) -{ - bNodeTree *nodetree = ma->nodetree; - if (nodetree) { - for (bNode *node = (bNode *)nodetree->nodes.first; node; node = node->next) { - if (node->typeinfo->type == SH_NODE_BSDF_PRINCIPLED) { - return node; - } - } - } - return NULL; -} - -COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a) -{ - COLLADASW::Color color(r, g, b, a); - COLLADASW::ColorOrTexture cot(color); - return cot; -} - -COLLADASW::ColorOrTexture bc_get_cot(Color col, bool with_alpha) -{ - COLLADASW::Color color(col[0], col[1], col[2], (with_alpha) ? col[3] : 1.0); - COLLADASW::ColorOrTexture cot(color); - return cot; -} diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h deleted file mode 100644 index 5c5e1415422..00000000000 --- a/source/blender/collada/collada_utils.h +++ /dev/null @@ -1,399 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -/** \file - * \ingroup collada - */ - -#ifndef __COLLADA_UTILS_H__ -#define __COLLADA_UTILS_H__ - -#include "COLLADAFWMeshPrimitive.h" -#include "COLLADAFWGeometry.h" -#include "COLLADAFWFloatOrDoubleArray.h" -#include "COLLADAFWTypes.h" -#include "COLLADASWEffectProfile.h" -#include "COLLADAFWColorOrTexture.h" - -#include <vector> -#include <map> -#include <set> -#include <algorithm> - -extern "C" { -#include "DNA_object_types.h" -#include "DNA_anim_types.h" -#include "DNA_constraint_types.h" -#include "DNA_mesh_types.h" -#include "DNA_light_types.h" -#include "DNA_camera_types.h" - -#include "DNA_customdata_types.h" -#include "DNA_texture_types.h" -#include "DNA_scene_types.h" - -#include "RNA_access.h" - -#include "BLI_linklist.h" -#include "BLI_utildefines.h" -#include "BLI_string.h" - -#include "BKE_main.h" -#include "BKE_context.h" -#include "BKE_object.h" -#include "BKE_scene.h" -#include "BKE_idprop.h" -#include "BKE_node.h" -} - -#include "DEG_depsgraph_query.h" - -#include "ImportSettings.h" -#include "ExportSettings.h" -#include "collada_internal.h" -#include "BCSampleData.h" -#include "BlenderContext.h" - -constexpr int LIMITTED_PRECISION = 6; - -typedef std::map<COLLADAFW::UniqueId, Image *> UidImageMap; -typedef std::map<std::string, Image *> KeyImageMap; -typedef std::map<COLLADAFW::TextureMapId, std::vector<MTex *>> TexIndexTextureArrayMap; -typedef std::set<Object *> BCObjectSet; - -extern void bc_update_scene(BlenderContext &blender_context, float ctime); - -/* Action helpers */ - -std::vector<bAction *> bc_getSceneActions(const bContext *C, Object *ob, bool all_actions); - -/* Action helpers */ - -inline bAction *bc_getSceneObjectAction(Object *ob) -{ - return (ob->adt && ob->adt->action) ? ob->adt->action : NULL; -} - -/* Returns Light Action or NULL */ -inline bAction *bc_getSceneLightAction(Object *ob) -{ - if (ob->type != OB_LAMP) { - return NULL; - } - - Light *lamp = (Light *)ob->data; - return (lamp->adt && lamp->adt->action) ? lamp->adt->action : NULL; -} - -/* Return Camera Action or NULL */ -inline bAction *bc_getSceneCameraAction(Object *ob) -{ - if (ob->type != OB_CAMERA) { - return NULL; - } - - Camera *camera = (Camera *)ob->data; - return (camera->adt && camera->adt->action) ? camera->adt->action : NULL; -} - -/* returns material action or NULL */ -inline bAction *bc_getSceneMaterialAction(Material *ma) -{ - if (ma == NULL) { - return NULL; - } - - return (ma->adt && ma->adt->action) ? ma->adt->action : NULL; -} - -std::string bc_get_action_id(std::string action_name, - std::string ob_name, - std::string channel_type, - std::string axis_name, - std::string axis_separator = "_"); - -extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray &array, unsigned int index); -extern int bc_test_parent_loop(Object *par, Object *ob); - -extern bool bc_validateConstraints(bConstraint *con); - -bool bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true); -extern Object *bc_add_object( - Main *bmain, Scene *scene, ViewLayer *view_layer, int type, const char *name); -extern Mesh *bc_get_mesh_copy(BlenderContext &blender_context, - Object *ob, - BC_export_mesh_type export_mesh_type, - bool apply_modifiers, - bool triangulate); - -extern Object *bc_get_assigned_armature(Object *ob); -extern bool bc_has_object_type(LinkNode *export_set, short obtype); - -extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n); -extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type); - -extern void bc_bubble_sort_by_Object_name(LinkNode *export_set); -extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only); -extern int bc_get_active_UVLayer(Object *ob); - -std::string bc_find_bonename_in_path(std::string path, std::string probe); - -inline std::string bc_string_after(const std::string &s, const std::string probe) -{ - size_t i = s.rfind(probe); - if (i != std::string::npos) { - return (s.substr(i + probe.length(), s.length() - i)); - } - return (s); -} - -inline std::string bc_string_before(const std::string &s, const std::string probe) -{ - size_t i = s.find(probe); - if (i != std::string::npos) { - return s.substr(0, i); - } - return (s); -} - -inline bool bc_startswith(std::string const &value, std::string const &starting) -{ - if (starting.size() > value.size()) { - return false; - } - return (value.substr(0, starting.size()) == starting); -} - -inline bool bc_endswith(const std::string &value, const std::string &ending) -{ - if (ending.size() > value.size()) { - return false; - } - - return value.compare(value.size() - ending.size(), ending.size(), ending) == 0; -} - -#if 0 /* UNUSED */ -inline bool bc_endswith(std::string const &value, std::string const &ending) -{ - if (ending.size() > value.size()) { - return false; - } - return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); -} -#endif - -extern std::string bc_replace_string(std::string data, - const std::string &pattern, - const std::string &replacement); -extern std::string bc_url_encode(std::string data); -extern void bc_match_scale(Object *ob, UnitConverter &bc_unit, bool scale_to_scene); -extern void bc_match_scale(std::vector<Object *> *objects_done, - UnitConverter &unit_converter, - bool scale_to_scene); - -extern void bc_decompose(float mat[4][4], float *loc, float eul[3], float quat[4], float *size); -extern void bc_rotate_from_reference_quat(float quat_to[4], - float quat_from[4], - float mat_to[4][4]); - -extern void bc_triangulate_mesh(Mesh *me); -extern bool bc_is_leaf_bone(Bone *bone); -extern EditBone *bc_get_edit_bone(bArmature *armature, char *name); -extern int bc_set_layer(int bitfield, int layer, bool enable); -extern int bc_set_layer(int bitfield, int layer); - -inline bool bc_in_range(float a, float b, float range) -{ - return fabsf(a - b) < range; -} -void bc_copy_m4_farray(float r[4][4], float *a); -void bc_copy_farray_m4(float *r, float a[4][4]); -void bc_copy_darray_m4d(double *r, double a[4][4]); -void bc_copy_m4d_v44(double (&r)[4][4], std::vector<std::vector<double>> &a); -void bc_copy_v44_m4d(std::vector<std::vector<double>> &a, double (&r)[4][4]); - -void bc_sanitize_v3(double v[3], int precision); -void bc_sanitize_v3(float v[3], int precision); - -extern IDProperty *bc_get_IDProperty(Bone *bone, std::string key); -extern void bc_set_IDProperty(EditBone *ebone, const char *key, float value); -extern void bc_set_IDPropertyMatrix(EditBone *ebone, const char *key, float mat[4][4]); - -extern float bc_get_property(Bone *bone, std::string key, float def); -extern void bc_get_property_vector(Bone *bone, std::string key, float val[3], const float def[3]); -extern bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4]); - -extern void bc_enable_fcurves(bAction *act, char *bone_name); -extern bool bc_bone_matrix_local_get(Object *ob, Bone *bone, Matrix &mat, bool for_opensim); -extern bool bc_is_animated(BCMatrixSampleMap &values); -extern bool bc_has_animations(Scene *sce, LinkNode *node); -extern bool bc_has_animations(Object *ob); - -extern void bc_add_global_transform(Matrix &to_mat, - const Matrix &from_mat, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_add_global_transform(Vector &to_vec, - const Vector &from_vec, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_add_global_transform(Vector &to_vec, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_add_global_transform(Matrix &to_mat, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_apply_global_transform(Matrix &to_mat, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_apply_global_transform(Vector &to_vec, - const BCMatrix &global_transform, - const bool invert = false); -extern void bc_create_restpose_mat(BCExportSettings &export_settings, - Bone *bone, - float to_mat[4][4], - float from_mat[4][4], - bool use_local_space); - -class ColladaBaseNodes { - private: - std::vector<Object *> base_objects; - - public: - void add(Object *ob) - { - base_objects.push_back(ob); - } - - bool contains(Object *ob) - { - std::vector<Object *>::iterator it = std::find(base_objects.begin(), base_objects.end(), ob); - return (it != base_objects.end()); - } - - int size() - { - return base_objects.size(); - } - - Object *get(int index) - { - return base_objects[index]; - } -}; - -class BCPolygonNormalsIndices { - std::vector<unsigned int> normal_indices; - - public: - void add_index(unsigned int index) - { - normal_indices.push_back(index); - } - - unsigned int operator[](unsigned int i) - { - return normal_indices[i]; - } -}; - -class BoneExtended { - - private: - char name[MAXBONENAME]; - int chain_length; - bool is_leaf; - float tail[3]; - float roll; - - int bone_layers; - int use_connect; - bool has_custom_tail; - bool has_custom_roll; - - public: - BoneExtended(EditBone *aBone); - - void set_name(char *aName); - char *get_name(); - - void set_chain_length(const int aLength); - int get_chain_length(); - - void set_leaf_bone(bool state); - bool is_leaf_bone(); - - void set_bone_layers(std::string layers, std::vector<std::string> &layer_labels); - int get_bone_layers(); - static std::string get_bone_layers(int bitfield); - - void set_roll(float roll); - bool has_roll(); - float get_roll(); - - void set_tail(float vec[]); - float *get_tail(); - bool has_tail(); - - void set_use_connect(int use_connect); - int get_use_connect(); -}; - -/* a map to store bone extension maps - * std:string : an armature name - * BoneExtended * : a map that contains extra data for bones - */ -typedef std::map<std::string, BoneExtended *> BoneExtensionMap; - -/* - * A class to organize bone extension data for multiple Armatures. - * this is needed for the case where a Collada file contains 2 or more - * separate armatures. - */ -class BoneExtensionManager { - private: - std::map<std::string, BoneExtensionMap *> extended_bone_maps; - - public: - BoneExtensionMap &getExtensionMap(bArmature *armature); - ~BoneExtensionManager(); -}; - -void bc_add_default_shader(bContext *C, Material *ma); -bNode *bc_get_master_shader(Material *ma); - -COLLADASW::ColorOrTexture bc_get_base_color(Material *ma); -COLLADASW::ColorOrTexture bc_get_emission(Material *ma); -COLLADASW::ColorOrTexture bc_get_ambient(Material *ma); -COLLADASW::ColorOrTexture bc_get_specular(Material *ma); -COLLADASW::ColorOrTexture bc_get_reflective(Material *ma); - -double bc_get_reflectivity(Material *ma); -double bc_get_alpha(Material *ma); -double bc_get_ior(Material *ma); -double bc_get_shininess(Material *ma); - -double bc_get_float_from_shader(bNode *shader, double &ior, std::string nodeid); -COLLADASW::ColorOrTexture bc_get_cot_from_shader(bNode *shader, - std::string nodeid, - Color &default_color, - bool with_alpha = true); - -COLLADASW::ColorOrTexture bc_get_cot(float r, float g, float b, float a); -COLLADASW::ColorOrTexture bc_get_cot(Color col, bool with_alpha = true); - -#endif diff --git a/source/blender/collada/version.conf b/source/blender/collada/version.conf deleted file mode 100644 index d39af7a53df..00000000000 --- a/source/blender/collada/version.conf +++ /dev/null @@ -1 +0,0 @@ -463ba8a2ef5a021ce21df614dde29e0ee800e10b |