~ubuntu-branches/ubuntu/trusty/blender/trusty

« back to all changes in this revision

Viewing changes to source/blender/collada/collada_utils.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include "COLLADAFWMeshPrimitive.h"
33
33
#include "COLLADAFWMeshVertexData.h"
34
34
 
 
35
#include "collada_utils.h"
 
36
 
 
37
extern "C" {
 
38
#include "DNA_modifier_types.h"
35
39
#include "DNA_customdata_types.h"
36
40
#include "DNA_object_types.h"
 
41
#include "DNA_mesh_types.h"
37
42
#include "DNA_scene_types.h"
 
43
#include "DNA_armature_types.h"
38
44
 
39
45
#include "BLI_math.h"
 
46
#include "BLI_linklist.h"
40
47
 
41
48
#include "BKE_context.h"
42
49
#include "BKE_customdata.h"
43
50
#include "BKE_depsgraph.h"
44
51
#include "BKE_object.h"
 
52
#include "BKE_global.h"
 
53
#include "BKE_mesh.h"
45
54
#include "BKE_scene.h"
 
55
#include "BKE_DerivedMesh.h"
46
56
 
47
57
#include "WM_api.h" // XXX hrm, see if we can do without this
48
58
#include "WM_types.h"
 
59
}
49
60
 
50
61
float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index)
51
62
{
88
99
        if (is_parent_space) {
89
100
                float mat[4][4];
90
101
                // calc par->obmat
91
 
                where_is_object(sce, par);
 
102
                BKE_object_where_is_calc(sce, par);
92
103
 
93
104
                // move child obmat into world space
94
105
                mult_m4_m4m4(mat, par->obmat, ob->obmat);
96
107
        }
97
108
        
98
109
        // apply child obmat (i.e. decompose it into rot/loc/size)
99
 
        object_apply_mat4(ob, ob->obmat, 0, 0);
 
110
        BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
100
111
 
101
112
        // compute parentinv
102
 
        what_does_parent(sce, ob, &workob);
 
113
        BKE_object_workob_calc_parent(sce, ob, &workob);
103
114
        invert_m4_m4(ob->parentinv, workob.obmat);
104
115
 
105
116
        ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA;
106
117
        par->recalc |= OB_RECALC_OB;
107
118
 
 
119
        /** done once after import
108
120
        DAG_scene_sort(bmain, sce);
109
121
        DAG_ids_flush_update(bmain, 0);
110
 
        WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
 
122
        WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
 
123
    */
 
124
 
111
125
 
112
126
        return true;
113
127
}
114
128
 
115
129
Object *bc_add_object(Scene *scene, int type, const char *name)
116
130
{
117
 
        Object *ob = add_only_object(type, name);
118
 
 
119
 
        ob->data= add_obdata_from_type(type);
120
 
        ob->lay= scene->lay;
121
 
        ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME;
122
 
 
123
 
        scene_select_base(scene, scene_add_base(scene, ob));
 
131
        Object *ob = BKE_object_add_only_object(G.main, type, name);
 
132
 
 
133
        ob->data = BKE_object_obdata_add_from_type(type);
 
134
        ob->lay = scene->lay;
 
135
        ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
 
136
 
 
137
        BKE_scene_base_select(scene, BKE_scene_base_add(scene, ob));
124
138
 
125
139
        return ob;
126
140
}
127
141
 
 
142
Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type)
 
143
{
 
144
        Mesh *tmpmesh;
 
145
        CustomDataMask mask = CD_MASK_MESH;
 
146
        DerivedMesh *dm = NULL;
 
147
        switch (export_mesh_type) {
 
148
                case BC_MESH_TYPE_VIEW: {
 
149
                        dm = mesh_create_derived_view(scene, ob, mask);
 
150
                        break;
 
151
                }
 
152
                case BC_MESH_TYPE_RENDER: {
 
153
                        dm = mesh_create_derived_render(scene, ob, mask);
 
154
                        break;
 
155
                }
 
156
        }
 
157
 
 
158
        tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
 
159
        DM_to_mesh(dm, tmpmesh, ob);
 
160
        dm->release(dm);
 
161
        return tmpmesh;
 
162
}
 
163
 
 
164
Object *bc_get_assigned_armature(Object *ob)
 
165
{
 
166
        Object *ob_arm = NULL;
 
167
 
 
168
        if (ob->parent && ob->partype == PARSKEL && ob->parent->type == OB_ARMATURE) {
 
169
                ob_arm = ob->parent;
 
170
        }
 
171
        else {
 
172
                ModifierData *mod;
 
173
                for (mod = (ModifierData *)ob->modifiers.first; mod; mod = mod->next) {
 
174
                        if (mod->type == eModifierType_Armature) {
 
175
                                ob_arm = ((ArmatureModifierData *)mod)->object;
 
176
                        }
 
177
                }
 
178
        }
 
179
 
 
180
        return ob_arm;
 
181
}
 
182
 
 
183
// Returns the highest selected ancestor
 
184
// returns NULL if no ancestor is selected
 
185
// IMPORTANT: This function expects that
 
186
// all exported objects have set:
 
187
// ob->id.flag & LIB_DOIT
 
188
Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob) 
 
189
{
 
190
        Object *ancestor = ob;
 
191
        while (ob->parent && bc_is_marked(ob->parent)) {
 
192
                ob = ob->parent;
 
193
                ancestor = ob;
 
194
        }
 
195
        return ancestor;
 
196
}
 
197
 
 
198
 
 
199
bool bc_is_base_node(LinkNode *export_set, Object *ob)
 
200
{
 
201
        Object *root = bc_get_highest_selected_ancestor_or_self(export_set, ob);
 
202
        return (root == ob);
 
203
}
 
204
 
 
205
bool bc_is_in_Export_set(LinkNode *export_set, Object *ob)
 
206
{
 
207
        return (BLI_linklist_index(export_set, ob) != -1);
 
208
}
 
209
 
 
210
bool bc_has_object_type(LinkNode *export_set, short obtype)
 
211
{
 
212
        LinkNode *node;
 
213
        
 
214
        for (node = export_set; node; node = node->next) {
 
215
                Object *ob = (Object *)node->link;
 
216
                /* XXX - why is this checking for ob->data? - we could be looking for empties */
 
217
                if (ob->type == obtype && ob->data) {
 
218
                        return true;
 
219
                }
 
220
        }
 
221
        return false;
 
222
}
 
223
 
 
224
int bc_is_marked(Object *ob)
 
225
{
 
226
        return ob && (ob->id.flag & LIB_DOIT);
 
227
}
 
228
 
 
229
void bc_remove_mark(Object *ob)
 
230
{
 
231
        ob->id.flag &= ~LIB_DOIT;
 
232
}
 
233
 
 
234
void bc_set_mark(Object *ob)
 
235
{
 
236
        ob->id.flag |= LIB_DOIT;
 
237
}
 
238
 
 
239
// Use bubble sort algorithm for sorting the export set
 
240
void bc_bubble_sort_by_Object_name(LinkNode *export_set)
 
241
{
 
242
        bool sorted = false;
 
243
        LinkNode *node;
 
244
        for (node = export_set; node->next && !sorted; node = node->next) {
 
245
 
 
246
                sorted = true;
 
247
                
 
248
                LinkNode *current;
 
249
                for (current = export_set; current->next; current = current->next) {
 
250
                        Object *a = (Object *)current->link;
 
251
                        Object *b = (Object *)current->next->link;
 
252
 
 
253
                        if (strcmp(a->id.name, b->id.name) > 0) {
 
254
                                current->link       = b;
 
255
                                current->next->link = a;
 
256
                                sorted = false;
 
257
                        }
 
258
                        
 
259
                }
 
260
        }
 
261
}
 
262
 
 
263
/* Check if a bone is the top most exportable bone in the bone hierarchy. 
 
264
 * When deform_bones_only == false, then only bones with NO parent 
 
265
 * can be root bones. Otherwise the top most deform bones in the hierarchy
 
266
 * are root bones.
 
267
 */
 
268
bool bc_is_root_bone(Bone *aBone, bool deform_bones_only)
 
269
{
 
270
        if (deform_bones_only) {
 
271
                Bone *root = NULL;
 
272
                Bone *bone = aBone;
 
273
                while (bone) {
 
274
                        if (!(bone->flag & BONE_NO_DEFORM))
 
275
                                root = bone;
 
276
                        bone = bone->parent;
 
277
                }
 
278
                return (aBone == root);
 
279
        }
 
280
        else
 
281
                return !(aBone->parent);
 
282
}
 
283
 
 
284
int bc_get_active_UVLayer(Object *ob)
 
285
{
 
286
        Mesh *me = (Mesh *)ob->data;
 
287
        return CustomData_get_active_layer_index(&me->fdata, CD_MTFACE);
 
288
}
 
289
 
 
290
std::string bc_url_encode(std::string data) {
 
291
        /* XXX We probably do not need to do a full encoding.
 
292
           But in case that is necessary,then it can be added here.
 
293
        */
 
294
        return bc_replace_string(data,"#", "%23");
 
295
}
 
296
 
 
297
std::string bc_replace_string(std::string data, const std::string& pattern,
 
298
                                                          const std::string& replacement) {
 
299
        size_t pos = 0;
 
300
        while((pos = data.find(pattern, pos)) != std::string::npos) {
 
301
                data.replace(pos, pattern.length(), replacement);
 
302
                pos += replacement.length();
 
303
        }
 
304
        return data;
 
305
}
 
306
 
 
307
/**
 
308
        Calculate a rescale factor such that the imported scene's scale
 
309
        is preserved. I.e. 1 meter in the import will also be
 
310
        1 meter in the current scene.
 
311
        XXX : I am not sure if it is correct to map 1 Blender Unit
 
312
        to 1 Meter for unit type NONE. But it looks reasonable to me.
 
313
*/
 
314
void bc_match_scale(std::vector<Object *> *objects_done, 
 
315
                                        Scene &sce, 
 
316
                                        UnitConverter &bc_unit) {
 
317
 
 
318
        Object *ob = NULL;
 
319
 
 
320
        PointerRNA scene_ptr, unit_settings;
 
321
        PropertyRNA *system_ptr, *scale_ptr;
 
322
        RNA_id_pointer_create(&sce.id, &scene_ptr);
 
323
 
 
324
        unit_settings = RNA_pointer_get(&scene_ptr, "unit_settings");
 
325
        system_ptr = RNA_struct_find_property(&unit_settings, "system");
 
326
        scale_ptr = RNA_struct_find_property(&unit_settings, "scale_length");
 
327
 
 
328
        int   type  = RNA_property_enum_get(&unit_settings, system_ptr);
 
329
 
 
330
        float bl_scale;
 
331
        
 
332
        switch (type) {
 
333
                case USER_UNIT_NONE:
 
334
                        bl_scale = 1.0; // map 1 Blender unit to 1 Meter
 
335
                        break;
 
336
 
 
337
                case USER_UNIT_METRIC:
 
338
                        bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
 
339
                        break;
 
340
 
 
341
                default :
 
342
                        bl_scale = RNA_property_float_get(&unit_settings, scale_ptr);
 
343
                        // it looks like the conversion to Imperial is done implicitly.
 
344
                        // So nothing to do here.
 
345
                        break;
 
346
        }
 
347
        
 
348
        float scale_conv = bc_unit.getLinearMeter() / bl_scale;
 
349
 
 
350
        float rescale[3];
 
351
        rescale[0] = rescale[1] = rescale[2] = scale_conv;
 
352
 
 
353
        float size_mat4[4][4];
 
354
 
 
355
        float axis_mat4[4][4];
 
356
        unit_m4(axis_mat4);
 
357
 
 
358
        size_to_mat4(size_mat4, rescale);
 
359
 
 
360
        for (std::vector<Object *>::iterator it = objects_done->begin();
 
361
                        it != objects_done->end();
 
362
                        ++it) 
 
363
        {
 
364
                ob = *it;
 
365
                mult_m4_m4m4(ob->obmat, size_mat4, ob->obmat);
 
366
                mult_m4_m4m4(ob->obmat, bc_unit.get_rotation(), ob->obmat);
 
367
                BKE_object_apply_mat4(ob, ob->obmat, 0, 0);
 
368
        }
 
369
 
 
370
}
 
 
b'\\ No newline at end of file'