~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/blender/src/editobject.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: editobject.c 16921 2008-10-04 19:58:08Z blendix $
 
3
 *
 
4
 * ***** BEGIN GPL LICENSE BLOCK *****
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * as published by the Free Software Foundation; either version 2
 
9
 * of the License, or (at your option) any later version.
 
10
 *
 
11
 * This program is distributed in the hope that it will be useful,
 
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 * GNU General Public License for more details.
 
15
 *
 
16
 * You should have received a copy of the GNU General Public License
 
17
 * along with this program; if not, write to the Free Software Foundation,
 
18
 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 *
 
20
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 
21
 * All rights reserved.
 
22
 *
 
23
 * The Original Code is: all of this file.
 
24
 *
 
25
 * Contributor(s): none yet.
 
26
 *
 
27
 * ***** END GPL LICENSE BLOCK *****
 
28
 */
 
29
 
 
30
/** 
 
31
 * Theorie: (matrices) A x B x C == A x ( B x C x Binv) x B
 
32
 * ofwel: OB x PAR x EDIT = OB x (PAR x EDIT x PARinv) x PAR
 
33
 */
 
34
 
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <math.h>
 
38
 
 
39
#ifdef HAVE_CONFIG_H
 
40
#include <config.h>
 
41
#endif
 
42
 
 
43
#ifndef WIN32
 
44
#include <unistd.h>
 
45
#else
 
46
#include <io.h>
 
47
#endif
 
48
#include "MEM_guardedalloc.h"
 
49
#include "PIL_time.h"
 
50
 
 
51
#include "BMF_Api.h"
 
52
 
 
53
 
 
54
#include "IMB_imbuf_types.h"
 
55
 
 
56
#include "DNA_action_types.h"
 
57
#include "DNA_armature_types.h"
 
58
#include "DNA_camera_types.h"
 
59
#include "DNA_constraint_types.h"
 
60
#include "DNA_curve_types.h"
 
61
#include "DNA_effect_types.h"
 
62
#include "DNA_group_types.h"
 
63
#include "DNA_image_types.h"
 
64
#include "DNA_ipo_types.h"
 
65
#include "DNA_key_types.h"
 
66
#include "DNA_lamp_types.h"
 
67
#include "DNA_lattice_types.h"
 
68
#include "DNA_material_types.h"
 
69
#include "DNA_mesh_types.h"
 
70
#include "DNA_meshdata_types.h"
 
71
#include "DNA_meta_types.h"
 
72
#include "DNA_nla_types.h"
 
73
#include "DNA_object_types.h"
 
74
#include "DNA_object_fluidsim.h"
 
75
#include "DNA_object_force.h"
 
76
#include "DNA_scene_types.h"
 
77
#include "DNA_space_types.h"
 
78
#include "DNA_screen_types.h"
 
79
#include "DNA_texture_types.h"
 
80
#include "DNA_particle_types.h"
 
81
#include "DNA_property_types.h"
 
82
#include "DNA_userdef_types.h"
 
83
#include "DNA_view3d_types.h"
 
84
#include "DNA_vfont_types.h"
 
85
#include "DNA_world_types.h"
 
86
#include "DNA_modifier_types.h"
 
87
 
 
88
#include "BLI_blenlib.h"
 
89
#include "BLI_arithb.h"
 
90
#include "BLI_editVert.h"
 
91
#include "BLI_ghash.h"
 
92
#include "BLI_rand.h"
 
93
 
 
94
#include "BKE_action.h"
 
95
#include "BKE_anim.h"
 
96
#include "BKE_armature.h"
 
97
#include "BKE_constraint.h"
 
98
#include "BKE_customdata.h"
 
99
#include "BKE_blender.h"
 
100
#include "BKE_booleanops.h"
 
101
#include "BKE_cloth.h"
 
102
#include "BKE_curve.h"
 
103
#include "BKE_displist.h"
 
104
#include "BKE_depsgraph.h"
 
105
#include "BKE_DerivedMesh.h"
 
106
#include "BKE_effect.h"
 
107
#include "BKE_font.h"
 
108
#include "BKE_global.h"
 
109
#include "BKE_group.h"
 
110
#include "BKE_ipo.h"
 
111
#include "BKE_image.h"
 
112
#include "BKE_key.h"
 
113
#include "BKE_lattice.h"
 
114
#include "BKE_library.h"
 
115
#include "BKE_main.h"
 
116
#include "BKE_material.h"
 
117
#include "BKE_mball.h"
 
118
#include "BKE_mesh.h"
 
119
#include "BKE_multires.h"
 
120
#include "BKE_nla.h"
 
121
#include "BKE_object.h"
 
122
#include "BKE_particle.h"
 
123
#include "BKE_property.h"
 
124
#include "BKE_sca.h"
 
125
#include "BKE_scene.h"
 
126
#include "BKE_softbody.h"
 
127
#include "BKE_subsurf.h"
 
128
#include "BKE_texture.h"
 
129
#include "BKE_utildefines.h"
 
130
#include "BKE_modifier.h"
 
131
 
 
132
#include "BIF_butspace.h"
 
133
#include "BIF_editconstraint.h"
 
134
#include "BIF_editdeform.h"
 
135
#include "BIF_editfont.h"
 
136
#include "BIF_editlattice.h"
 
137
#include "BIF_editmesh.h"
 
138
#include "BIF_editoops.h"
 
139
#include "BIF_editparticle.h"
 
140
#include "BIF_editview.h"
 
141
#include "BIF_editarmature.h"
 
142
#include "BIF_gl.h"
 
143
#include "BIF_graphics.h"
 
144
#include "BIF_interface.h"
 
145
#include "BIF_meshtools.h"
 
146
#include "BIF_mywindow.h"
 
147
#include "BIF_previewrender.h"
 
148
#include "BIF_resources.h"
 
149
#include "BIF_retopo.h"
 
150
#include "BIF_screen.h"
 
151
#include "BIF_space.h"
 
152
#include "BIF_toolbox.h"
 
153
#include "BIF_toets.h"
 
154
 
 
155
#ifdef WITH_VERSE
 
156
#include "BIF_verse.h"
 
157
#endif
 
158
 
 
159
#include "BSE_edit.h"
 
160
#include "BSE_editipo.h"
 
161
#include "BSE_filesel.h"        /* For activate_databrowse() */
 
162
#include "BSE_view.h"
 
163
#include "BSE_drawview.h"
 
164
#include "BSE_trans_types.h"
 
165
#include "BSE_editipo_types.h"
 
166
 
 
167
#include "BDR_vpaint.h"
 
168
#include "BDR_sculptmode.h"
 
169
#include "BDR_editface.h"
 
170
#include "BDR_editmball.h"
 
171
#include "BDR_editobject.h"
 
172
#include "BDR_drawobject.h"
 
173
#include "BDR_editcurve.h"
 
174
#include "BDR_unwrapper.h"
 
175
#include "BDR_gpencil.h"
 
176
 
 
177
#include <time.h>
 
178
#include "mydevice.h"
 
179
#include "nla.h"
 
180
 
 
181
#include "blendef.h"
 
182
#include "butspace.h"
 
183
#include "BIF_transform.h"
 
184
 
 
185
#include "BIF_poseobject.h"
 
186
 
 
187
 
 
188
/* --------------------------------- */
 
189
 
 
190
void exit_paint_modes(void)
 
191
{
 
192
        if(G.f & G_VERTEXPAINT) set_vpaint();
 
193
        if(G.f & G_TEXTUREPAINT) set_texturepaint();
 
194
        if(G.f & G_WEIGHTPAINT) set_wpaint();
 
195
        if(G.f & G_SCULPTMODE) set_sculptmode();
 
196
        if(G.f & G_PARTICLEEDIT) PE_set_particle_edit();
 
197
 
 
198
        G.f &= ~(G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT+G_SCULPTMODE+G_PARTICLEEDIT);
 
199
}
 
200
 
 
201
void add_object_draw(int type)  /* for toolbox or menus, only non-editmode stuff */
 
202
{
 
203
        Object *ob;
 
204
        
 
205
        exit_paint_modes();
 
206
        setcursor_space(SPACE_VIEW3D, CURSOR_STD);
 
207
 
 
208
        if ELEM3(curarea->spacetype, SPACE_VIEW3D, SPACE_BUTS, SPACE_INFO) {
 
209
                if (G.obedit) exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
 
210
                ob= add_object(type);
 
211
                set_active_base(BASACT);
 
212
                base_init_from_view3d(BASACT, G.vd);
 
213
                
 
214
                /* only undo pushes on objects without editmode... */
 
215
                if(type==OB_EMPTY) BIF_undo_push("Add Empty");
 
216
                else if(type==OB_LAMP) {
 
217
                        BIF_undo_push("Add Lamp");
 
218
                        reshadeall_displist();  /* only frees */
 
219
                }
 
220
                else if(type==OB_LATTICE) BIF_undo_push("Add Lattice");
 
221
                else if(type==OB_CAMERA) BIF_undo_push("Add Camera");
 
222
                
 
223
                allqueue(REDRAWVIEW3D, 0);
 
224
        }
 
225
 
 
226
        redraw_test_buttons(OBACT);
 
227
 
 
228
        allqueue(REDRAWALL, 0);
 
229
 
 
230
        deselect_all_area_oops();
 
231
        set_select_flag_oops();
 
232
        
 
233
        DAG_scene_sort(G.scene);
 
234
        allqueue(REDRAWINFO, 1);        /* 1, because header->win==0! */
 
235
}
 
236
 
 
237
void add_objectLamp(short type)
 
238
{
 
239
        Lamp *la;
 
240
 
 
241
        /* this function also comes from an info window */
 
242
        if ELEM(curarea->spacetype, SPACE_VIEW3D, SPACE_INFO); else return;
 
243
        
 
244
        if(G.obedit==0) {
 
245
                add_object_draw(OB_LAMP);
 
246
                base_init_from_view3d(BASACT, G.vd);
 
247
        }
 
248
        
 
249
        la = BASACT->object->data;
 
250
        la->type = type;        
 
251
 
 
252
        allqueue(REDRAWALL, 0);
 
253
}
 
254
 
 
255
/* remove base from a specific scene */
 
256
/* note: now unlinks constraints as well */
 
257
void free_and_unlink_base_from_scene(Scene *scene, Base *base)
 
258
{
 
259
        BLI_remlink(&scene->base, base);
 
260
        free_libblock_us(&G.main->object, base->object);
 
261
        MEM_freeN(base);
 
262
}
 
263
 
 
264
/* remove base from the current scene */
 
265
void free_and_unlink_base(Base *base)
 
266
{
 
267
        if (base==BASACT)
 
268
                BASACT= NULL;
 
269
        free_and_unlink_base_from_scene(G.scene, base);
 
270
}
 
271
 
 
272
void delete_obj(int ok)
 
273
{
 
274
        Base *base;
 
275
        int islamp= 0;
 
276
        
 
277
        if(G.obedit) return;
 
278
        if(G.scene->id.lib) return;
 
279
 
 
280
        base= FIRSTBASE;
 
281
        while(base) {
 
282
                Base *nbase= base->next;
 
283
 
 
284
                if TESTBASE(base) { 
 
285
                        if(ok==0) {
 
286
                                /* Shift Del is global delete */
 
287
                                if (G.qual & LR_SHIFTKEY) {
 
288
                                        if(!okee("Erase selected Object(s) Globally")) return;
 
289
                                        ok= 2;
 
290
                                } else {
 
291
                                        if(!okee("Erase selected Object(s)")) return;
 
292
                                        ok= 1;
 
293
                                }
 
294
                        }
 
295
                        
 
296
                        exit_paint_modes();
 
297
 
 
298
                        if(base->object->type==OB_LAMP) islamp= 1;
 
299
#ifdef WITH_VERSE
 
300
                        if(base->object->vnode) b_verse_delete_object(base->object);
 
301
#endif
 
302
                        if (ok==2) {
 
303
                                Scene *scene; 
 
304
                                Base *base_other;
 
305
                                
 
306
                                for (scene= G.main->scene.first; scene; scene= scene->id.next) {
 
307
                                        if (scene != G.scene && !(scene->id.lib)) {
 
308
                                                base_other= object_in_scene( base->object, scene );
 
309
                                                if (base_other) {
 
310
                                                        if (base_other == scene->basact) scene->basact= NULL;   /* in case the object was active */
 
311
                                                        free_and_unlink_base_from_scene( scene, base_other );
 
312
                                                }
 
313
                                        }
 
314
                                }
 
315
                        }
 
316
                        
 
317
                        /* remove from current scene only */
 
318
                        free_and_unlink_base(base);
 
319
                }
 
320
                
 
321
                base= nbase;
 
322
        }
 
323
        countall();
 
324
 
 
325
        setcursor_space(SPACE_VIEW3D, CURSOR_STD);
 
326
        
 
327
        if(islamp) reshadeall_displist();       /* only frees displist */
 
328
 
 
329
        redraw_test_buttons(OBACT);
 
330
        allqueue(REDRAWVIEW3D, 0);
 
331
        allqueue (REDRAWACTION, 0);
 
332
        allqueue(REDRAWIPO, 0);
 
333
        allqueue(REDRAWDATASELECT, 0);
 
334
        allspace(OOPS_TEST, 0);
 
335
        allqueue(REDRAWOOPS, 0);
 
336
        allqueue(REDRAWACTION, 0);
 
337
        allqueue(REDRAWNLA, 0);
 
338
        
 
339
        DAG_scene_sort(G.scene);
 
340
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
341
 
 
342
        BIF_undo_push("Delete object(s)");
 
343
}
 
344
 
 
345
static int return_editmesh_indexar(int *tot, int **indexar, float *cent)
 
346
{
 
347
        EditMesh *em = G.editMesh;
 
348
        EditVert *eve;
 
349
        int *index, nr, totvert=0;
 
350
        
 
351
        for(eve= em->verts.first; eve; eve= eve->next) {
 
352
                if(eve->f & SELECT) totvert++;
 
353
        }
 
354
        if(totvert==0) return 0;
 
355
        
 
356
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
 
357
        *tot= totvert;
 
358
        nr= 0;
 
359
        cent[0]= cent[1]= cent[2]= 0.0;
 
360
        
 
361
        for(eve= em->verts.first; eve; eve= eve->next) {
 
362
                if(eve->f & SELECT) {
 
363
                        *index= nr; index++;
 
364
                        VecAddf(cent, cent, eve->co);
 
365
                }
 
366
                nr++;
 
367
        }
 
368
        
 
369
        VecMulf(cent, 1.0f/(float)totvert);
 
370
        
 
371
        return totvert;
 
372
}
 
373
 
 
374
static int return_editmesh_vgroup(char *name, float *cent)
 
375
{
 
376
        EditMesh *em = G.editMesh;
 
377
        MDeformVert *dvert;
 
378
        EditVert *eve;
 
379
        int i, totvert=0;
 
380
        
 
381
        cent[0]= cent[1]= cent[2]= 0.0;
 
382
        
 
383
        if(G.obedit->actdef) {
 
384
                
 
385
                /* find the vertices */
 
386
                for(eve= em->verts.first; eve; eve= eve->next) {
 
387
                        dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 
388
 
 
389
                        if(dvert) {
 
390
                                for(i=0; i<dvert->totweight; i++){
 
391
                                        if(dvert->dw[i].def_nr == (G.obedit->actdef-1)) {
 
392
                                                totvert++;
 
393
                                                VecAddf(cent, cent, eve->co);
 
394
                                        }
 
395
                                }
 
396
                        }
 
397
                }
 
398
                if(totvert) {
 
399
                        bDeformGroup *defGroup = BLI_findlink(&G.obedit->defbase, G.obedit->actdef-1);
 
400
                        strcpy(name, defGroup->name);
 
401
                        VecMulf(cent, 1.0f/(float)totvert);
 
402
                        return 1;
 
403
                }
 
404
        }
 
405
        
 
406
        return 0;
 
407
}       
 
408
 
 
409
static void select_editmesh_hook(HookModifierData *hmd)
 
410
{
 
411
        EditMesh *em = G.editMesh;
 
412
        EditVert *eve;
 
413
        int index=0, nr=0;
 
414
        
 
415
        for(eve= em->verts.first; eve; eve= eve->next, nr++) {
 
416
                if(nr==hmd->indexar[index]) {
 
417
                        eve->f |= SELECT;
 
418
                        if(index < hmd->totindex-1) index++;
 
419
                }
 
420
        }
 
421
        EM_select_flush();
 
422
}
 
423
 
 
424
static int return_editlattice_indexar(int *tot, int **indexar, float *cent)
 
425
{
 
426
        BPoint *bp;
 
427
        int *index, nr, totvert=0, a;
 
428
        
 
429
        /* count */
 
430
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
431
        bp= editLatt->def;
 
432
        while(a--) {
 
433
                if(bp->f1 & SELECT) {
 
434
                        if(bp->hide==0) totvert++;
 
435
                }
 
436
                bp++;
 
437
        }
 
438
 
 
439
        if(totvert==0) return 0;
 
440
        
 
441
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
 
442
        *tot= totvert;
 
443
        nr= 0;
 
444
        cent[0]= cent[1]= cent[2]= 0.0;
 
445
        
 
446
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
447
        bp= editLatt->def;
 
448
        while(a--) {
 
449
                if(bp->f1 & SELECT) {
 
450
                        if(bp->hide==0) {
 
451
                                *index= nr; index++;
 
452
                                VecAddf(cent, cent, bp->vec);
 
453
                        }
 
454
                }
 
455
                bp++;
 
456
                nr++;
 
457
        }
 
458
        
 
459
        VecMulf(cent, 1.0f/(float)totvert);
 
460
        
 
461
        return totvert;
 
462
}
 
463
 
 
464
static void select_editlattice_hook(HookModifierData *hmd)
 
465
{
 
466
        BPoint *bp;
 
467
        int index=0, nr=0, a;
 
468
        
 
469
        /* count */
 
470
        a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
471
        bp= editLatt->def;
 
472
        while(a--) {
 
473
                if(hmd->indexar[index]==nr) {
 
474
                        bp->f1 |= SELECT;
 
475
                        if(index < hmd->totindex-1) index++;
 
476
                }
 
477
                nr++;
 
478
                bp++;
 
479
        }
 
480
}
 
481
 
 
482
static int return_editcurve_indexar(int *tot, int **indexar, float *cent)
 
483
{
 
484
        extern ListBase editNurb;
 
485
        Nurb *nu;
 
486
        BPoint *bp;
 
487
        BezTriple *bezt;
 
488
        int *index, a, nr, totvert=0;
 
489
        
 
490
        for(nu= editNurb.first; nu; nu= nu->next) {
 
491
                if((nu->type & 7)==CU_BEZIER) {
 
492
                        bezt= nu->bezt;
 
493
                        a= nu->pntsu;
 
494
                        while(a--) {
 
495
                                if(bezt->f1 & SELECT) totvert++;
 
496
                                if(bezt->f2 & SELECT) totvert++;
 
497
                                if(bezt->f3 & SELECT) totvert++;
 
498
                                bezt++;
 
499
                        }
 
500
                }
 
501
                else {
 
502
                        bp= nu->bp;
 
503
                        a= nu->pntsu*nu->pntsv;
 
504
                        while(a--) {
 
505
                                if(bp->f1 & SELECT) totvert++;
 
506
                                bp++;
 
507
                        }
 
508
                }
 
509
        }
 
510
        if(totvert==0) return 0;
 
511
        
 
512
        *indexar= index= MEM_mallocN(4*totvert, "hook indexar");
 
513
        *tot= totvert;
 
514
        nr= 0;
 
515
        cent[0]= cent[1]= cent[2]= 0.0;
 
516
        
 
517
        for(nu= editNurb.first; nu; nu= nu->next) {
 
518
                if((nu->type & 7)==CU_BEZIER) {
 
519
                        bezt= nu->bezt;
 
520
                        a= nu->pntsu;
 
521
                        while(a--) {
 
522
                                if(bezt->f1 & SELECT) {
 
523
                                        *index= nr; index++;
 
524
                                        VecAddf(cent, cent, bezt->vec[0]);
 
525
                                }
 
526
                                nr++;
 
527
                                if(bezt->f2 & SELECT) {
 
528
                                        *index= nr; index++;
 
529
                                        VecAddf(cent, cent, bezt->vec[1]);
 
530
                                }
 
531
                                nr++;
 
532
                                if(bezt->f3 & SELECT) {
 
533
                                        *index= nr; index++;
 
534
                                        VecAddf(cent, cent, bezt->vec[2]);
 
535
                                }
 
536
                                nr++;
 
537
                                bezt++;
 
538
                        }
 
539
                }
 
540
                else {
 
541
                        bp= nu->bp;
 
542
                        a= nu->pntsu*nu->pntsv;
 
543
                        while(a--) {
 
544
                                if(bp->f1 & SELECT) {
 
545
                                        *index= nr; index++;
 
546
                                        VecAddf(cent, cent, bp->vec);
 
547
                                }
 
548
                                nr++;
 
549
                                bp++;
 
550
                        }
 
551
                }
 
552
        }
 
553
        
 
554
        VecMulf(cent, 1.0f/(float)totvert);
 
555
        
 
556
        return totvert;
 
557
}
 
558
 
 
559
/* use this when the loc/size/rot of the parent has changed but the children should stay in the same place
 
560
 * apply-size-rot or object center for eg */
 
561
static void ignore_parent_tx( Object *ob ) {
 
562
        Object *ob_child;
 
563
        /* a change was made, adjust the children to compensate */
 
564
        for (ob_child=G.main->object.first; ob_child; ob_child=ob_child->id.next) {
 
565
                if (ob_child->parent == ob) {
 
566
                        apply_obmat(ob_child);
 
567
                        what_does_parent(ob_child);
 
568
                        Mat4Invert(ob_child->parentinv, workob.obmat);
 
569
                }
 
570
        }
 
571
}
 
572
 
 
573
static void select_editcurve_hook(HookModifierData *hmd)
 
574
{
 
575
        extern ListBase editNurb;
 
576
        Nurb *nu;
 
577
        BPoint *bp;
 
578
        BezTriple *bezt;
 
579
        int index=0, a, nr=0;
 
580
        
 
581
        for(nu= editNurb.first; nu; nu= nu->next) {
 
582
                if((nu->type & 7)==CU_BEZIER) {
 
583
                        bezt= nu->bezt;
 
584
                        a= nu->pntsu;
 
585
                        while(a--) {
 
586
                                if(nr == hmd->indexar[index]) {
 
587
                                        bezt->f1 |= SELECT;
 
588
                                        if(index<hmd->totindex-1) index++;
 
589
                                }
 
590
                                nr++;
 
591
                                if(nr == hmd->indexar[index]) {
 
592
                                        bezt->f2 |= SELECT;
 
593
                                        if(index<hmd->totindex-1) index++;
 
594
                                }
 
595
                                nr++;
 
596
                                if(nr == hmd->indexar[index]) {
 
597
                                        bezt->f3 |= SELECT;
 
598
                                        if(index<hmd->totindex-1) index++;
 
599
                                }
 
600
                                nr++;
 
601
 
 
602
                                bezt++;
 
603
                        }
 
604
                }
 
605
                else {
 
606
                        bp= nu->bp;
 
607
                        a= nu->pntsu*nu->pntsv;
 
608
                        while(a--) {
 
609
                                if(nr == hmd->indexar[index]) {
 
610
                                        bp->f1 |= SELECT;
 
611
                                        if(index<hmd->totindex-1) index++;
 
612
                                }
 
613
                                nr++;
 
614
                                bp++;
 
615
                        }
 
616
                }
 
617
        }
 
618
}
 
619
 
 
620
void hook_select(HookModifierData *hmd) 
 
621
{
 
622
        if(G.obedit->type==OB_MESH) select_editmesh_hook(hmd);
 
623
        else if(G.obedit->type==OB_LATTICE) select_editlattice_hook(hmd);
 
624
        else if(G.obedit->type==OB_CURVE) select_editcurve_hook(hmd);
 
625
        else if(G.obedit->type==OB_SURF) select_editcurve_hook(hmd);
 
626
}
 
627
 
 
628
int hook_getIndexArray(int *tot, int **indexar, char *name, float *cent_r)
 
629
{
 
630
        *indexar= NULL;
 
631
        *tot= 0;
 
632
        name[0]= 0;
 
633
 
 
634
        switch(G.obedit->type) {
 
635
        case OB_MESH:
 
636
                /* check selected vertices first */
 
637
                if( return_editmesh_indexar(tot, indexar, cent_r)) return 1;
 
638
                else return return_editmesh_vgroup(name, cent_r);
 
639
        case OB_CURVE:
 
640
        case OB_SURF:
 
641
                return return_editcurve_indexar(tot, indexar, cent_r);
 
642
        case OB_LATTICE:
 
643
                return return_editlattice_indexar(tot, indexar, cent_r);
 
644
        default:
 
645
                return 0;
 
646
        }
 
647
}
 
648
 
 
649
void add_hook_menu(void)
 
650
{
 
651
        int mode;
 
652
        
 
653
        if(G.obedit==NULL) return;
 
654
        
 
655
        if(modifiers_findByType(G.obedit, eModifierType_Hook))
 
656
                mode= pupmenu("Hooks %t|Add, To New Empty %x1|Add, To Selected Object %x2|Remove... %x3|Reassign... %x4|Select... %x5|Clear Offset...%x6");
 
657
        else
 
658
                mode= pupmenu("Hooks %t|Add, New Empty %x1|Add, To Selected Object %x2");
 
659
 
 
660
        if(mode<1) return;
 
661
                
 
662
        /* do operations */
 
663
        add_hook(mode);
 
664
        
 
665
        allqueue(REDRAWVIEW3D, 0);
 
666
        allqueue(REDRAWBUTSOBJECT, 0);
 
667
        
 
668
        BIF_undo_push("Add hook");
 
669
}
 
670
 
 
671
void add_hook(int mode)
 
672
{
 
673
        ModifierData *md = NULL;
 
674
        HookModifierData *hmd = NULL;
 
675
        Object *ob=NULL;
 
676
        
 
677
        if(G.obedit==NULL) return;
 
678
        
 
679
        /* preconditions */
 
680
        if(mode==2) { /* selected object */
 
681
                Base *base= FIRSTBASE;
 
682
                while(base) {
 
683
                        if TESTBASELIB(base) {
 
684
                                if(base!=BASACT) {
 
685
                                        ob= base->object;
 
686
                                        break;
 
687
                                }
 
688
                        }
 
689
                        base= base->next;
 
690
                }
 
691
                if(ob==NULL) {
 
692
                        error("Requires selected Object");
 
693
                        return;
 
694
                }
 
695
        }
 
696
        else if(mode!=1) {
 
697
                int maxlen=0, a, nr;
 
698
                char *cp;
 
699
                
 
700
                /* make pupmenu with hooks */
 
701
                for(md=G.obedit->modifiers.first; md; md= md->next) {
 
702
                        if (md->type==eModifierType_Hook) 
 
703
                                maxlen+=32;
 
704
                }
 
705
                
 
706
                if(maxlen==0) {
 
707
                        error("Object has no hooks yet");
 
708
                        return;
 
709
                }
 
710
                
 
711
                cp= MEM_callocN(maxlen+32, "temp string");
 
712
                if(mode==3) strcpy(cp, "Remove %t|");
 
713
                else if(mode==4) strcpy(cp, "Reassign %t|");
 
714
                else if(mode==5) strcpy(cp, "Select %t|");
 
715
                else if(mode==6) strcpy(cp, "Clear Offset %t|");
 
716
                
 
717
                for(md=G.obedit->modifiers.first; md; md= md->next) {
 
718
                        if (md->type==eModifierType_Hook) {
 
719
                                strcat(cp, md->name);
 
720
                                strcat(cp, " |");
 
721
                        }
 
722
                }
 
723
        
 
724
                nr= pupmenu(cp);
 
725
                MEM_freeN(cp);
 
726
                
 
727
                if(nr<1) return;
 
728
                
 
729
                a= 1;
 
730
                for(md=G.obedit->modifiers.first; md; md=md->next) {
 
731
                        if (md->type==eModifierType_Hook) {
 
732
                                if(a==nr) break;
 
733
                                a++;
 
734
                        }
 
735
                }
 
736
                
 
737
                hmd = (HookModifierData*) md;
 
738
                ob= hmd->object;
 
739
        }
 
740
        
 
741
        /* do it, new hooks or reassign */
 
742
        if(mode==1 || mode==2 || mode==4) {
 
743
                float cent[3];
 
744
                int tot, ok, *indexar;
 
745
                char name[32];
 
746
                
 
747
                ok = hook_getIndexArray(&tot, &indexar, name, cent);
 
748
                
 
749
                if(ok==0) {
 
750
                        error("Requires selected vertices or active Vertex Group");
 
751
                }
 
752
                else {
 
753
                        
 
754
                        if(mode==1) {
 
755
                                Base *base= BASACT, *newbase;
 
756
                                
 
757
                                ob= add_object(OB_EMPTY);
 
758
                                /* set layers OK */
 
759
                                newbase= BASACT;
 
760
                                newbase->lay= base->lay;
 
761
                                ob->lay= newbase->lay;
 
762
                                
 
763
                                /* transform cent to global coords for loc */
 
764
                                VecMat4MulVecfl(ob->loc, G.obedit->obmat, cent);
 
765
                                
 
766
                                /* restore, add_object sets active */
 
767
                                BASACT= base;
 
768
                        }
 
769
                        /* if mode is 2 or 4, ob has been set */
 
770
                        
 
771
                        /* new hook */
 
772
                        if(mode==1 || mode==2) {
 
773
                                ModifierData *md = G.obedit->modifiers.first;
 
774
                                
 
775
                                while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
 
776
                                        md = md->next;
 
777
                                }
 
778
                                
 
779
                                hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
 
780
                                BLI_insertlinkbefore(&G.obedit->modifiers, md, hmd);
 
781
                                sprintf(hmd->modifier.name, "Hook-%s", ob->id.name+2);
 
782
                        }
 
783
                        else if (hmd->indexar) MEM_freeN(hmd->indexar); /* reassign, hook was set */
 
784
 
 
785
                        hmd->object= ob;
 
786
                        hmd->indexar= indexar;
 
787
                        VECCOPY(hmd->cent, cent);
 
788
                        hmd->totindex= tot;
 
789
                        BLI_strncpy(hmd->name, name, 32);
 
790
                        
 
791
                        if(mode==1 || mode==2) {
 
792
                                /* matrix calculus */
 
793
                                /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
 
794
                                /*        (parentinv         )                          */
 
795
                                
 
796
                                where_is_object(ob);
 
797
                                
 
798
                                Mat4Invert(ob->imat, ob->obmat);
 
799
                                /* apparently this call goes from right to left... */
 
800
                                Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
 
801
                                                        NULL, NULL, NULL, NULL, NULL);
 
802
                        }
 
803
                }
 
804
        }
 
805
        else if(mode==3) { /* remove */
 
806
                BLI_remlink(&G.obedit->modifiers, md);
 
807
                modifier_free(md);
 
808
        }
 
809
        else if(mode==5) { /* select */
 
810
                hook_select(hmd);
 
811
        }
 
812
        else if(mode==6) { /* clear offset */
 
813
                where_is_object(ob);    /* ob is hook->parent */
 
814
                
 
815
                Mat4Invert(ob->imat, ob->obmat);
 
816
                /* this call goes from right to left... */
 
817
                Mat4MulSerie(hmd->parentinv, ob->imat, G.obedit->obmat, NULL, 
 
818
                                        NULL, NULL, NULL, NULL, NULL);
 
819
        }
 
820
 
 
821
        DAG_scene_sort(G.scene);
 
822
}
 
823
 
 
824
void make_track(void)
 
825
{
 
826
        Base *base;
 
827
        short mode=0;
 
828
        
 
829
        if(G.scene->id.lib) return;
 
830
        if(G.obedit) {
 
831
                return;
 
832
        }
 
833
        if(BASACT==0) return;
 
834
 
 
835
        mode= pupmenu("Make Track %t|TrackTo Constraint %x1|LockTrack Constraint %x2|Old Track %x3");
 
836
        if (mode == 0){
 
837
                return;
 
838
        }
 
839
        else if (mode == 1){
 
840
                bConstraint *con;
 
841
                bTrackToConstraint *data;
 
842
 
 
843
                base= FIRSTBASE;
 
844
                while(base) {
 
845
                        if TESTBASELIB(base) {
 
846
                                if(base!=BASACT) {
 
847
                                        con = add_new_constraint(CONSTRAINT_TYPE_TRACKTO);
 
848
                                        strcpy (con->name, "AutoTrack");
 
849
 
 
850
                                        data = con->data;
 
851
                                        data->tar = BASACT->object;
 
852
                                        base->object->recalc |= OB_RECALC;
 
853
                                        
 
854
                                        /* Lamp and Camera track differently by default */
 
855
                                        if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
 
856
                                                data->reserved1 = TRACK_nZ;
 
857
                                                data->reserved2 = UP_Y;
 
858
                                        }
 
859
 
 
860
                                        add_constraint_to_object(con, base->object);
 
861
                                }
 
862
                        }
 
863
                        base= base->next;
 
864
                }
 
865
 
 
866
        }
 
867
        else if (mode == 2){
 
868
                bConstraint *con;
 
869
                bLockTrackConstraint *data;
 
870
 
 
871
                base= FIRSTBASE;
 
872
                while(base) {
 
873
                        if TESTBASELIB(base) {
 
874
                                if(base!=BASACT) {
 
875
                                        con = add_new_constraint(CONSTRAINT_TYPE_LOCKTRACK);
 
876
                                        strcpy (con->name, "AutoTrack");
 
877
 
 
878
                                        data = con->data;
 
879
                                        data->tar = BASACT->object;
 
880
                                        base->object->recalc |= OB_RECALC;
 
881
                                        
 
882
                                        /* Lamp and Camera track differently by default */
 
883
                                        if (base->object->type == OB_LAMP || base->object->type == OB_CAMERA) {
 
884
                                                data->trackflag = TRACK_nZ;
 
885
                                                data->lockflag = LOCK_Y;
 
886
                                        }
 
887
 
 
888
                                        add_constraint_to_object(con, base->object);
 
889
                                }
 
890
                        }
 
891
                        base= base->next;
 
892
                }
 
893
 
 
894
        }
 
895
        else if (mode == 3){
 
896
                base= FIRSTBASE;
 
897
                while(base) {
 
898
                        if TESTBASELIB(base) {
 
899
                                if(base!=BASACT) {
 
900
                                        base->object->track= BASACT->object;
 
901
                                        base->object->recalc |= OB_RECALC;
 
902
                                }
 
903
                        }
 
904
                        base= base->next;
 
905
                }
 
906
        }
 
907
 
 
908
        allqueue(REDRAWOOPS, 0);
 
909
        allqueue(REDRAWVIEW3D, 0);
 
910
        DAG_scene_sort(G.scene);
 
911
        
 
912
        BIF_undo_push("Make Track");
 
913
}
 
914
 
 
915
void apply_obmat(Object *ob)
 
916
{
 
917
        float mat[3][3], imat[3][3], tmat[3][3];
 
918
        
 
919
        /* from obmat to loc rot size */
 
920
        
 
921
        if(ob==0) return;
 
922
        Mat3CpyMat4(mat, ob->obmat);
 
923
        
 
924
        VECCOPY(ob->loc, ob->obmat[3]);
 
925
        /* Quats arnt used yet */
 
926
        /*if(ob->transflag & OB_QUAT) {
 
927
                Mat3ToQuat(mat, ob->quat);
 
928
                QuatToMat3(ob->quat, tmat);
 
929
        }
 
930
        else {*/
 
931
                Mat3ToEul(mat, ob->rot);
 
932
                EulToMat3(ob->rot, tmat);
 
933
        /*}*/
 
934
        Mat3Inv(imat, tmat);
 
935
        
 
936
        Mat3MulMat3(tmat, imat, mat);
 
937
        
 
938
        ob->size[0]= tmat[0][0];
 
939
        ob->size[1]= tmat[1][1];
 
940
        ob->size[2]= tmat[2][2];
 
941
 
 
942
}
 
943
 
 
944
void clear_parent(void)
 
945
{
 
946
        Object *par;
 
947
        Base *base;
 
948
        int mode;
 
949
        
 
950
        if(G.obedit) return;
 
951
        if(G.scene->id.lib) return;
 
952
 
 
953
        mode= pupmenu("OK? %t|Clear Parent %x1|Clear and Keep Transformation (Clear Track) %x2|Clear Parent Inverse %x3");
 
954
        
 
955
        if(mode<1) return;
 
956
 
 
957
        base= FIRSTBASE;
 
958
        while(base) {
 
959
                if TESTBASELIB(base) {
 
960
                        par= NULL;
 
961
                        if(mode==1 || mode==2) {
 
962
                                par= base->object->parent;
 
963
                                base->object->parent= NULL;
 
964
                                base->object->recalc |= OB_RECALC;
 
965
                                
 
966
                                if(mode==2) {
 
967
                                        base->object->track= NULL;
 
968
                                        apply_obmat(base->object);
 
969
                                }
 
970
                        }
 
971
                        else if(mode==3) {
 
972
                                Mat4One(base->object->parentinv);
 
973
                                base->object->recalc |= OB_RECALC;
 
974
                        }
 
975
                }
 
976
                base= base->next;
 
977
        }
 
978
 
 
979
        DAG_scene_sort(G.scene);
 
980
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
981
        allqueue(REDRAWVIEW3D, 0);
 
982
        allqueue(REDRAWOOPS, 0);
 
983
        
 
984
        BIF_undo_push("Clear Parent");  
 
985
}
 
986
 
 
987
void clear_track(void)
 
988
{
 
989
        Base *base;
 
990
        int mode;
 
991
        
 
992
        if(G.obedit) return;
 
993
        if(G.scene->id.lib) return;
 
994
 
 
995
        mode= pupmenu("OK? %t|Clear Track %x1| Clear Track and Keep Transform %x2");
 
996
 
 
997
        if(mode<1) return;
 
998
 
 
999
        base= FIRSTBASE;
 
1000
        while(base) {
 
1001
                if TESTBASELIB(base) {
 
1002
                        base->object->track= NULL;
 
1003
                        base->object->recalc |= OB_RECALC;
 
1004
                        
 
1005
                        if(mode==2) {
 
1006
                                apply_obmat(base->object);
 
1007
                        }                       
 
1008
                }
 
1009
                base= base->next;
 
1010
        }
 
1011
 
 
1012
        DAG_scene_sort(G.scene);
 
1013
        allqueue(REDRAWVIEW3D, 0);
 
1014
        allqueue(REDRAWOOPS, 0);
 
1015
        
 
1016
        BIF_undo_push("Clear Track");   
 
1017
}
 
1018
 
 
1019
void clear_object(char mode)
 
1020
{
 
1021
        Base *base;
 
1022
        Object *ob;
 
1023
        float *v1, *v3, mat[3][3];
 
1024
        int armature_clear= 0;
 
1025
        char *str=NULL;
 
1026
        
 
1027
        if(G.obedit) return;
 
1028
        if(G.scene->id.lib) return;
 
1029
        
 
1030
        if(mode=='r') str= "Clear rotation";
 
1031
        else if(mode=='g') str= "Clear location";
 
1032
        else if(mode=='s') str= "Clear scale";
 
1033
        else if(mode=='o') str= "Clear origin";
 
1034
        else return;
 
1035
        
 
1036
        base= FIRSTBASE;
 
1037
        while(base) {
 
1038
                if TESTBASELIB(base) {
 
1039
                        ob= base->object;
 
1040
                        
 
1041
                        if ((ob->flag & OB_POSEMODE)) {
 
1042
                                /* only clear pose transforms if:
 
1043
                                 *      - with a mesh in weightpaint mode, it's related armature needs to be cleared
 
1044
                                 *      - with clearing transform of object being edited at the time
 
1045
                                 */
 
1046
                                if ((G.f & G_WEIGHTPAINT) || (ob==OBACT)) {
 
1047
                                        clear_armature(ob, mode);
 
1048
                                        armature_clear= 1;      /* silly system to prevent another dag update, so no action applied */
 
1049
                                }
 
1050
                        }
 
1051
                        else if((G.f & G_WEIGHTPAINT)==0) {
 
1052
                                /* only clear transforms of 'normal' (not armature) object if:
 
1053
                                 *      - not in weightpaint mode or editmode
 
1054
                                 *      - if that object's transform locks are not enabled (this is done on a per-channel basis)
 
1055
                                 */
 
1056
                                if (mode=='r') {
 
1057
                                        /* eulers can only get cleared if they are not protected */
 
1058
                                        if ((ob->protectflag & OB_LOCK_ROTX)==0)
 
1059
                                                ob->rot[0]= ob->drot[0]= 0.0f;
 
1060
                                        if ((ob->protectflag & OB_LOCK_ROTY)==0)
 
1061
                                                ob->rot[1]= ob->drot[1]= 0.0f;
 
1062
                                        if ((ob->protectflag & OB_LOCK_ROTZ)==0)
 
1063
                                                ob->rot[2]= ob->drot[2]= 0.0f;
 
1064
                                        
 
1065
                                        /* quats here are not really used anymore anywhere, so it probably doesn't 
 
1066
                                         * matter to not clear them whether the euler-based rotation is used
 
1067
                                         */
 
1068
                                        /*QuatOne(ob->quat);
 
1069
                                        QuatOne(ob->dquat);*/
 
1070
                                        
 
1071
#ifdef WITH_VERSE
 
1072
                                        if(ob->vnode) {
 
1073
                                                struct VNode *vnode = (VNode*)ob->vnode;
 
1074
                                                ((VObjectData*)vnode->data)->flag |= ROT_SEND_READY;
 
1075
                                                b_verse_send_transformation(ob);
 
1076
                                        }
 
1077
#endif
 
1078
 
 
1079
                                }
 
1080
                                else if (mode=='g') {
 
1081
                                        if ((ob->protectflag & OB_LOCK_LOCX)==0)
 
1082
                                                ob->loc[0]= ob->dloc[0]= 0.0f;
 
1083
                                        if ((ob->protectflag & OB_LOCK_LOCY)==0)
 
1084
                                                ob->loc[1]= ob->dloc[1]= 0.0f;
 
1085
                                        if ((ob->protectflag & OB_LOCK_LOCZ)==0)
 
1086
                                                ob->loc[2]= ob->dloc[2]= 0.0f;
 
1087
                                        
 
1088
#ifdef WITH_VERSE
 
1089
                                        if(ob->vnode) {
 
1090
                                                struct VNode *vnode = (VNode*)ob->vnode;
 
1091
                                                ((VObjectData*)vnode->data)->flag |= POS_SEND_READY;
 
1092
                                                b_verse_send_transformation(ob);
 
1093
                                        }
 
1094
#endif
 
1095
 
 
1096
                                }
 
1097
                                else if (mode=='s') {
 
1098
                                        if ((ob->protectflag & OB_LOCK_SCALEX)==0) {
 
1099
                                                ob->dsize[0]= 0.0f;
 
1100
                                                ob->size[0]= 1.0f;
 
1101
                                        }
 
1102
                                        if ((ob->protectflag & OB_LOCK_SCALEY)==0) {
 
1103
                                                ob->dsize[1]= 0.0f;
 
1104
                                                ob->size[1]= 1.0f;
 
1105
                                        }
 
1106
                                        if ((ob->protectflag & OB_LOCK_SCALEZ)==0) {
 
1107
                                                ob->dsize[2]= 0.0f;
 
1108
                                                ob->size[2]= 1.0f;
 
1109
                                        }
 
1110
#ifdef WITH_VERSE
 
1111
                                        if(ob->vnode) {
 
1112
                                                struct VNode *vnode = (VNode*)ob->vnode;
 
1113
                                                ((VObjectData*)vnode->data)->flag |= SCALE_SEND_READY;
 
1114
                                                b_verse_send_transformation(ob);
 
1115
                                        }
 
1116
#endif
 
1117
 
 
1118
                                }
 
1119
                                else if(mode=='o') {
 
1120
                                        if(ob->parent) {
 
1121
                                                v1= ob->loc;
 
1122
                                                v3= ob->parentinv[3];
 
1123
                                                
 
1124
                                                Mat3CpyMat4(mat, ob->parentinv);
 
1125
                                                VECCOPY(v3, v1);
 
1126
                                                v3[0]= -v3[0];
 
1127
                                                v3[1]= -v3[1];
 
1128
                                                v3[2]= -v3[2];
 
1129
                                                Mat3MulVecfl(mat, v3);
 
1130
                                        }
 
1131
                                }
 
1132
                                
 
1133
                                ob->recalc |= OB_RECALC_OB;
 
1134
                        }                       
 
1135
                }
 
1136
                base= base->next;
 
1137
        }
 
1138
        
 
1139
        allqueue(REDRAWVIEW3D, 0);
 
1140
        if(armature_clear==0) /* in this case flush was done */
 
1141
                DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
1142
        BIF_undo_push(str);
 
1143
}
 
1144
 
 
1145
void reset_slowparents(void)
 
1146
{
 
1147
        /* back to original locations */
 
1148
        Base *base;
 
1149
 
 
1150
        base= FIRSTBASE;
 
1151
        while(base) {
 
1152
                if(base->object->parent) {
 
1153
                        if(base->object->partype & PARSLOW) {
 
1154
                                base->object->partype -= PARSLOW;
 
1155
                                where_is_object(base->object);
 
1156
                                base->object->partype |= PARSLOW;
 
1157
                        }
 
1158
                }
 
1159
                base= base->next;
 
1160
        }
 
1161
}
 
1162
 
 
1163
void set_slowparent(void)
 
1164
{
 
1165
        Base *base;
 
1166
 
 
1167
        if( okee("Set slow parent")==0 ) return;
 
1168
 
 
1169
        base= FIRSTBASE;
 
1170
        while(base) {
 
1171
                if TESTBASELIB(base) {
 
1172
                        if(base->object->parent) base->object->partype |= PARSLOW;
 
1173
                }
 
1174
                base= base->next;
 
1175
        }
 
1176
        BIF_undo_push("Slow parent");
 
1177
}
 
1178
 
 
1179
void make_vertex_parent(void)
 
1180
{
 
1181
        EditMesh *em = G.editMesh;
 
1182
        EditVert *eve;
 
1183
        Base *base;
 
1184
        Nurb *nu;
 
1185
        BezTriple *bezt;
 
1186
        BPoint *bp;
 
1187
        Object *par, *ob;
 
1188
        int a, v1=0, v2=0, v3=0, v4=0, nr=1;
 
1189
        
 
1190
        /* we need 1 to 3 selected vertices */
 
1191
        
 
1192
        if(G.obedit->type==OB_MESH) {
 
1193
                eve= em->verts.first;
 
1194
                while(eve) {
 
1195
                        if(eve->f & 1) {
 
1196
                                if(v1==0) v1= nr;
 
1197
                                else if(v2==0) v2= nr;
 
1198
                                else if(v3==0) v3= nr;
 
1199
                                else if(v4==0) v4= nr;
 
1200
                                else break;
 
1201
                        }
 
1202
                        nr++;
 
1203
                        eve= eve->next;
 
1204
                }
 
1205
        }
 
1206
        else if ELEM(G.obedit->type, OB_SURF, OB_CURVE) {
 
1207
                extern ListBase editNurb;
 
1208
                nu= editNurb.first;
 
1209
                while(nu) {
 
1210
                        if((nu->type & 7)==CU_BEZIER) {
 
1211
                                bezt= nu->bezt;
 
1212
                                a= nu->pntsu;
 
1213
                                while(a--) {
 
1214
                                        if(BEZSELECTED_HIDDENHANDLES(bezt)) {
 
1215
                                                if(v1==0) v1= nr;
 
1216
                                                else if(v2==0) v2= nr;
 
1217
                                                else if(v3==0) v3= nr;
 
1218
                                                else if(v4==0) v4= nr;
 
1219
                                                else break;
 
1220
                                        }
 
1221
                                        nr++;
 
1222
                                        bezt++;
 
1223
                                }
 
1224
                        }
 
1225
                        else {
 
1226
                                bp= nu->bp;
 
1227
                                a= nu->pntsu*nu->pntsv;
 
1228
                                while(a--) {
 
1229
                                        if(bp->f1 & SELECT) {
 
1230
                                                if(v1==0) v1= nr;
 
1231
                                                else if(v2==0) v2= nr;
 
1232
                                                else if(v3==0) v3= nr;
 
1233
                                                else if(v4==0) v4= nr;
 
1234
                                                else break;
 
1235
                                        }
 
1236
                                        nr++;
 
1237
                                        bp++;
 
1238
                                }
 
1239
                        }
 
1240
                        nu= nu->next;
 
1241
                }
 
1242
        }
 
1243
        else if(G.obedit->type==OB_LATTICE) {
 
1244
                
 
1245
                a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
1246
                bp= editLatt->def;
 
1247
                while(a--) {
 
1248
                        if(bp->f1 & SELECT) {
 
1249
                                if(v1==0) v1= nr;
 
1250
                                else if(v2==0) v2= nr;
 
1251
                                else if(v3==0) v3= nr;
 
1252
                                else if(v4==0) v4= nr;
 
1253
                                else break;
 
1254
                        }
 
1255
                        nr++;
 
1256
                        bp++;
 
1257
                }
 
1258
        }
 
1259
        
 
1260
        if(v4 || !((v1 && v2==0 && v3==0) || (v1 && v2 && v3)) ) {
 
1261
                error("Select either 1 or 3 vertices to parent to");
 
1262
                return;
 
1263
        }
 
1264
        
 
1265
        if(okee("Make vertex parent")==0) return;
 
1266
        
 
1267
        base= FIRSTBASE;
 
1268
        while(base) {
 
1269
                if TESTBASELIB(base) {
 
1270
                        if(base!=BASACT) {
 
1271
                                
 
1272
                                ob= base->object;
 
1273
                                ob->recalc |= OB_RECALC;
 
1274
                                par= BASACT->object->parent;
 
1275
                                
 
1276
                                while(par) {
 
1277
                                        if(par==ob) break;
 
1278
                                        par= par->parent;
 
1279
                                }
 
1280
                                if(par) {
 
1281
                                        error("Loop in parents");
 
1282
                                }
 
1283
                                else {
 
1284
                                        ob->parent= BASACT->object;
 
1285
                                        if(v3) {
 
1286
                                                ob->partype= PARVERT3;
 
1287
                                                ob->par1= v1-1;
 
1288
                                                ob->par2= v2-1;
 
1289
                                                ob->par3= v3-1;
 
1290
 
 
1291
                                                /* inverse parent matrix */
 
1292
                                                what_does_parent(ob);
 
1293
                                                Mat4Invert(ob->parentinv, workob.obmat);
 
1294
                                                clear_workob();
 
1295
                                        }
 
1296
                                        else {
 
1297
                                                ob->partype= PARVERT1;
 
1298
                                                ob->par1= v1-1;
 
1299
 
 
1300
                                                /* inverse parent matrix */
 
1301
                                                what_does_parent(ob);
 
1302
                                                Mat4Invert(ob->parentinv, workob.obmat);
 
1303
                                                clear_workob();
 
1304
                                        }
 
1305
                                }
 
1306
                        }
 
1307
                }
 
1308
                base= base->next;
 
1309
        }
 
1310
        allqueue(REDRAWVIEW3D, 0);
 
1311
        
 
1312
        DAG_scene_sort(G.scene);
 
1313
        /* BIF_undo_push(str); not, conflicts with editmode undo... */
 
1314
}
 
1315
 
 
1316
static Object *group_objects_menu(Group *group)
 
1317
{
 
1318
        GroupObject *go;
 
1319
        int len= 0;
 
1320
        short a, nr;
 
1321
        char *str;
 
1322
                
 
1323
        for(go= group->gobject.first; go; go= go->next) {
 
1324
                if(go->ob)
 
1325
                        len++;
 
1326
        }
 
1327
        if(len==0) return NULL;
 
1328
        
 
1329
        str= MEM_callocN(40+32*len, "menu");
 
1330
        
 
1331
        strcpy(str, "Make Proxy for: %t");
 
1332
        a= strlen(str);
 
1333
        for(nr=1, go= group->gobject.first; go; go= go->next, nr++) {
 
1334
                a+= sprintf(str+a, "|%s %%x%d", go->ob->id.name+2, nr);
 
1335
        }
 
1336
        
 
1337
        a= pupmenu_col(str, 20);
 
1338
        MEM_freeN(str);
 
1339
        if(a>0) {
 
1340
                go= BLI_findlink(&group->gobject, a-1);
 
1341
                return go->ob;
 
1342
        }
 
1343
        return NULL;
 
1344
}
 
1345
 
 
1346
 
 
1347
/* adds empty object to become local replacement data of a library-linked object */
 
1348
void make_proxy(void)
 
1349
{
 
1350
        Object *ob= OBACT;
 
1351
        Object *gob= NULL;
 
1352
        
 
1353
        if(G.scene->id.lib) return;
 
1354
        if(ob==NULL) return;
 
1355
        
 
1356
        
 
1357
        if(ob->dup_group && ob->dup_group->id.lib) {
 
1358
                gob= ob;
 
1359
                /* gives menu with list of objects in group */
 
1360
                ob= group_objects_menu(ob->dup_group);
 
1361
        }
 
1362
        else if(ob->id.lib) {
 
1363
                if(okee("Make Proxy Object")==0)
 
1364
                return;
 
1365
        }
 
1366
        else {
 
1367
                error("Can only make proxy for a referenced object or group");
 
1368
                return;
 
1369
        }
 
1370
        
 
1371
        if(ob) {
 
1372
                Object *newob;
 
1373
                Base *newbase, *oldbase= BASACT;
 
1374
                char name[32];
 
1375
                
 
1376
                newob= add_object(OB_EMPTY);
 
1377
                if(gob)
 
1378
                        strcpy(name, gob->id.name+2);
 
1379
                else
 
1380
                        strcpy(name, ob->id.name+2);
 
1381
                strcat(name, "_proxy");
 
1382
                rename_id(&newob->id, name);
 
1383
                
 
1384
                /* set layers OK */
 
1385
                newbase= BASACT;        /* add_object sets active... */
 
1386
                newbase->lay= oldbase->lay;
 
1387
                newob->lay= newbase->lay;
 
1388
                
 
1389
                /* remove base, leave user count of object, it gets linked in object_make_proxy */
 
1390
                if(gob==NULL) {
 
1391
                        BLI_remlink(&G.scene->base, oldbase);
 
1392
                        MEM_freeN(oldbase);
 
1393
                }               
 
1394
                object_make_proxy(newob, ob, gob);
 
1395
                
 
1396
                DAG_scene_sort(G.scene);
 
1397
                DAG_object_flush_update(G.scene, newob, OB_RECALC);
 
1398
                allqueue(REDRAWALL, 0);
 
1399
                BIF_undo_push("Make Proxy Object");
 
1400
        }
 
1401
}
 
1402
 
 
1403
int test_parent_loop(Object *par, Object *ob)
 
1404
{
 
1405
        /* test if 'ob' is a parent somewhere in par's parents */
 
1406
        
 
1407
        if(par==0) return 0;
 
1408
        if(ob == par) return 1;
 
1409
        
 
1410
        return test_parent_loop(par->parent, ob);
 
1411
 
 
1412
}
 
1413
 
 
1414
void make_parent(void)
 
1415
{
 
1416
        Base *base;
 
1417
        Object *par;
 
1418
        bPoseChannel *pchan= NULL;
 
1419
        short qual, mode=0;
 
1420
 
 
1421
        if(G.scene->id.lib) return;
 
1422
        if(G.obedit) {
 
1423
                if ELEM4(G.obedit->type, OB_MESH, OB_CURVE, OB_SURF, OB_LATTICE) make_vertex_parent();
 
1424
                else if (G.obedit->type==OB_ARMATURE) make_bone_parent();
 
1425
                return;
 
1426
        }
 
1427
        if(BASACT==0) return;
 
1428
        
 
1429
        qual= G.qual;
 
1430
        par= BASACT->object;
 
1431
 
 
1432
        if(par->type == OB_LATTICE){
 
1433
                mode= pupmenu("Make Parent %t|Normal Parent %x1|Lattice Deform %x2");
 
1434
                if(mode<=0){
 
1435
                        return;
 
1436
                }
 
1437
                else if(mode==1) {
 
1438
                        mode= PAROBJECT;
 
1439
                }
 
1440
                else if(mode==2) {
 
1441
                        mode= PARSKEL;
 
1442
                }
 
1443
        }
 
1444
        else if(par->type == OB_CURVE){
 
1445
                mode= pupmenu("Make Parent %t|Normal Parent %x1|Follow Path %x2|Curve Deform %x3|Path Constraint %x4");
 
1446
                if(mode<=0){
 
1447
                        return;
 
1448
                }
 
1449
                else if(mode==1) {
 
1450
                        mode= PAROBJECT;
 
1451
                }
 
1452
                else if(mode==2) {
 
1453
                        Curve *cu= par->data;
 
1454
                        
 
1455
                        mode= PAROBJECT;
 
1456
                        if((cu->flag & CU_PATH)==0) {
 
1457
                                cu->flag |= CU_PATH|CU_FOLLOW;
 
1458
                                makeDispListCurveTypes(par, 0);  /* force creation of path data */
 
1459
                        }
 
1460
                        else cu->flag |= CU_FOLLOW;
 
1461
                }
 
1462
                else if(mode==3) {
 
1463
                        mode= PARSKEL;
 
1464
                }
 
1465
                else if(mode==4) {
 
1466
                        bConstraint *con;
 
1467
                        bFollowPathConstraint *data;
 
1468
                                
 
1469
                        base= FIRSTBASE;
 
1470
                        while(base) {
 
1471
                                if TESTBASELIB(base) {
 
1472
                                        if(base!=BASACT) {
 
1473
                                                float cmat[4][4], vec[3];
 
1474
                                                
 
1475
                                                con = add_new_constraint(CONSTRAINT_TYPE_FOLLOWPATH);
 
1476
                                                strcpy (con->name, "AutoPath");
 
1477
                                                
 
1478
                                                data = con->data;
 
1479
                                                data->tar = BASACT->object;
 
1480
                                                
 
1481
                                                add_constraint_to_object(con, base->object);
 
1482
                                                
 
1483
                                                get_constraint_target_matrix(con, 0, CONSTRAINT_OBTYPE_OBJECT, NULL, cmat, G.scene->r.cfra - give_timeoffset(base->object));
 
1484
                                                VecSubf(vec, base->object->obmat[3], cmat[3]);
 
1485
                                                
 
1486
                                                base->object->loc[0] = vec[0];
 
1487
                                                base->object->loc[1] = vec[1];
 
1488
                                                base->object->loc[2] = vec[2];
 
1489
                                        }
 
1490
                                }
 
1491
                                base= base->next;
 
1492
                        }
 
1493
 
 
1494
                        allqueue(REDRAWVIEW3D, 0);
 
1495
                        DAG_scene_sort(G.scene);
 
1496
                        BIF_undo_push("Make Parent");
 
1497
                        return;
 
1498
                }
 
1499
        }
 
1500
        else if(par->type == OB_ARMATURE){
 
1501
                
 
1502
                base= FIRSTBASE;
 
1503
                while(base) {
 
1504
                        if TESTBASELIB(base) {
 
1505
                                if(base!=BASACT) {
 
1506
                                        if(ELEM(base->object->type, OB_MESH, OB_LATTICE)) {
 
1507
                                                if(par->flag & OB_POSEMODE)
 
1508
                                                        mode= pupmenu("Make Parent To%t|Bone %x1|Armature %x2|Object %x3");
 
1509
                                                else
 
1510
                                                        mode= pupmenu("Make Parent To%t|Armature %x2|Object %x3");
 
1511
                                                break;
 
1512
                                        }
 
1513
                                        else {
 
1514
                                                if(par->flag & OB_POSEMODE)
 
1515
                                                        mode= pupmenu("Make Parent To %t|Bone %x1|Object %x3");
 
1516
                                                else
 
1517
                                                        mode= pupmenu("Make Parent To %t|Object %x3");
 
1518
                                                break;
 
1519
                                        }
 
1520
                                }
 
1521
                        }
 
1522
                        base= base->next;
 
1523
                }
 
1524
        
 
1525
                switch (mode){
 
1526
                case 1:
 
1527
                        mode=PARBONE;
 
1528
                        pchan= get_active_posechannel(par);
 
1529
 
 
1530
                        if(pchan==NULL) {
 
1531
                                error("No active Bone");
 
1532
                                allqueue(REDRAWVIEW3D, 0);
 
1533
                                return;
 
1534
                        }
 
1535
 
 
1536
                        break;
 
1537
                case 2:
 
1538
                        mode=PARSKEL;
 
1539
                        break;
 
1540
                case 3:
 
1541
                        mode=PAROBJECT;
 
1542
                        break;
 
1543
                default:
 
1544
                        return;
 
1545
                }
 
1546
        }
 
1547
        else {
 
1548
                if(qual & LR_SHIFTKEY) {
 
1549
                        if(okee("Make parent without inverse")==0) return;
 
1550
                }
 
1551
                else {
 
1552
                        if(qual & LR_ALTKEY) {
 
1553
                                if(okee("Make vertex parent")==0) return;
 
1554
                        }
 
1555
                        else if(okee("Make parent")==0) return;
 
1556
 
 
1557
                        /* now we'll clearparentandkeeptransform all objects */
 
1558
                        base= FIRSTBASE;
 
1559
                        while(base) {
 
1560
                                if TESTBASELIB(base) {
 
1561
                                        if(base!=BASACT && base->object->parent) {
 
1562
                                                base->object->parent= NULL;
 
1563
                                                apply_obmat(base->object);
 
1564
                                        }
 
1565
                                }
 
1566
                                base= base->next;
 
1567
                        }
 
1568
                }
 
1569
        }
 
1570
        
 
1571
        par->recalc |= OB_RECALC_OB;
 
1572
        
 
1573
        base= FIRSTBASE;
 
1574
        while(base) {
 
1575
                if TESTBASELIB(base) {
 
1576
                        if(base!=BASACT) {
 
1577
                                
 
1578
                                if( test_parent_loop(par, base->object) ) {
 
1579
                                        error("Loop in parents");
 
1580
                                }
 
1581
                                else {
 
1582
                                        
 
1583
                                        base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
 
1584
                                        
 
1585
                                        /* the ifs below are horrible code (ton) */
 
1586
                                        
 
1587
                                        if (par->type==OB_ARMATURE) {
 
1588
                                                base->object->partype= mode;
 
1589
                                                if (pchan)
 
1590
                                                        strcpy (base->object->parsubstr, pchan->name);
 
1591
                                                else
 
1592
                                                        base->object->parsubstr[0]=0;
 
1593
                                        }
 
1594
                                        else {
 
1595
                                                if(qual & LR_ALTKEY) {
 
1596
                                                        base->object->partype= PARVERT1;
 
1597
                                                }
 
1598
                                                else if(ELEM(par->type, OB_CURVE, OB_LATTICE)) {
 
1599
                                                        base->object->partype= mode;
 
1600
                                                }
 
1601
                                                else {
 
1602
                                                        base->object->partype= PAROBJECT;
 
1603
                                                }
 
1604
                                        }
 
1605
                                        
 
1606
                                        base->object->parent= par;
 
1607
                                        
 
1608
                                        /* calculate inverse parent matrix? */
 
1609
                                        if( (qual & LR_SHIFTKEY) ) {
 
1610
                                                /* not... */
 
1611
                                                Mat4One(base->object->parentinv);
 
1612
                                                memset(base->object->loc, 0, 3*sizeof(float));
 
1613
                                        }
 
1614
                                        else {
 
1615
                                                if(mode==PARSKEL && base->object->type==OB_MESH && par->type == OB_ARMATURE) {
 
1616
                                                        /* Prompt the user as to whether he wants to
 
1617
                                                                * add some vertex groups based on the bones
 
1618
                                                                * in the parent armature.
 
1619
                                                                */
 
1620
                                                        create_vgroups_from_armature(base->object, 
 
1621
                                                                                                                        par);
 
1622
 
 
1623
                                                        base->object->partype= PAROBJECT;
 
1624
                                                        what_does_parent(base->object);
 
1625
                                                        Mat4One (base->object->parentinv);
 
1626
                                                        base->object->partype= mode;
 
1627
                                                }
 
1628
                                                else
 
1629
                                                        what_does_parent(base->object);
 
1630
                                                Mat4Invert(base->object->parentinv, workob.obmat);
 
1631
                                        }
 
1632
                                }
 
1633
                        }
 
1634
                }
 
1635
                base= base->next;
 
1636
        }
 
1637
        allqueue(REDRAWVIEW3D, 0);
 
1638
        allqueue(REDRAWOOPS, 0);
 
1639
        
 
1640
        DAG_scene_sort(G.scene);
 
1641
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
1642
        
 
1643
        BIF_undo_push("make Parent");
 
1644
}
 
1645
 
 
1646
 
 
1647
void enter_editmode(int wc)
 
1648
{
 
1649
        Base *base;
 
1650
        Object *ob;
 
1651
        Mesh *me;
 
1652
        bArmature *arm;
 
1653
        int ok= 0;
 
1654
        
 
1655
        if(G.scene->id.lib) return;
 
1656
        base= BASACT;
 
1657
        if(base==0) return;
 
1658
        if((G.vd==NULL || (base->lay & G.vd->lay))==0) return;
 
1659
        
 
1660
        strcpy(G.editModeTitleExtra, "");
 
1661
 
 
1662
        ob= base->object;
 
1663
        if(ob->data==0) return;
 
1664
        
 
1665
        if (object_data_is_libdata(ob)) {
 
1666
                error_libdata();
 
1667
                return;
 
1668
        }
 
1669
        
 
1670
        if(wc) waitcursor(1);
 
1671
        
 
1672
        if(ob->type==OB_MESH) {
 
1673
                me= get_mesh(ob);
 
1674
                if( me==0 ) return;
 
1675
                if(me->pv) mesh_pmv_off(ob, me);
 
1676
                ok= 1;
 
1677
                G.obedit= ob;
 
1678
                make_editMesh();
 
1679
                allqueue(REDRAWBUTSLOGIC, 0);
 
1680
                /*if(G.f & G_FACESELECT) allqueue(REDRAWIMAGE, 0);*/
 
1681
                if (EM_texFaceCheck())
 
1682
                        allqueue(REDRAWIMAGE, 0);
 
1683
                
 
1684
        }
 
1685
        if (ob->type==OB_ARMATURE){
 
1686
                arm= base->object->data;
 
1687
                if (!arm) return;
 
1688
                /*
 
1689
                 * The function object_data_is_libdata make a problem here, the
 
1690
                 * check for ob->proxy return 0 and let blender enter to edit mode
 
1691
                 * this causa a crash when you try leave the edit mode.
 
1692
                 * The problem is that i can't remove the ob->proxy check from
 
1693
                 * object_data_is_libdata that prevent the bugfix #6614, so
 
1694
                 * i add this little hack here.
 
1695
                 */
 
1696
                if(arm->id.lib) {
 
1697
                        error_libdata();
 
1698
                        return;
 
1699
                }
 
1700
                ok=1;
 
1701
                G.obedit=ob;
 
1702
                make_editArmature();
 
1703
                /* to ensure all goes in restposition and without striding */
 
1704
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC);
 
1705
 
 
1706
                allqueue (REDRAWVIEW3D,0);
 
1707
        }
 
1708
        else if(ob->type==OB_FONT) {
 
1709
                G.obedit= ob;
 
1710
                ok= 1;
 
1711
                make_editText();
 
1712
        }
 
1713
        else if(ob->type==OB_MBALL) {
 
1714
                G.obedit= ob;
 
1715
                ok= 1;
 
1716
                make_editMball();
 
1717
        }
 
1718
        else if(ob->type==OB_LATTICE) {
 
1719
                G.obedit= ob;
 
1720
                ok= 1;
 
1721
                make_editLatt();
 
1722
        }
 
1723
        else if(ob->type==OB_SURF || ob->type==OB_CURVE) {
 
1724
                ok= 1;
 
1725
                G.obedit= ob;
 
1726
                make_editNurb();
 
1727
        }
 
1728
        allqueue(REDRAWBUTSEDIT, 0);
 
1729
        allqueue(REDRAWOOPS, 0);
 
1730
        countall();
 
1731
        
 
1732
        if(ok) {
 
1733
                setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
 
1734
        
 
1735
                allqueue(REDRAWVIEW3D, 1);
 
1736
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
1737
                
 
1738
        }
 
1739
        else G.obedit= NULL;
 
1740
        
 
1741
        if(wc) waitcursor(0);
 
1742
        
 
1743
        scrarea_queue_headredraw(curarea);
 
1744
}
 
1745
 
 
1746
void exit_editmode(int flag)    /* freedata==0 at render, 1= freedata, 2= do undo buffer too */
 
1747
{
 
1748
        Object *ob;
 
1749
        int freedata = flag & EM_FREEDATA;
 
1750
        
 
1751
        if(G.obedit==NULL) return;
 
1752
 
 
1753
        if(flag & EM_WAITCURSOR) waitcursor(1);
 
1754
        if(G.obedit->type==OB_MESH) {
 
1755
 
 
1756
                /* temporal */
 
1757
                countall();
 
1758
                
 
1759
                if(EM_texFaceCheck())
 
1760
                        allqueue(REDRAWIMAGE, 0);
 
1761
                
 
1762
                if(retopo_mesh_paint_check())
 
1763
                        retopo_end_okee();
 
1764
 
 
1765
                if(G.totvert>MESH_MAX_VERTS) {
 
1766
                        error("Too many vertices");
 
1767
                        return;
 
1768
                }
 
1769
                load_editMesh();
 
1770
 
 
1771
                if(freedata) free_editMesh(G.editMesh);
 
1772
                
 
1773
                if(G.f & G_WEIGHTPAINT)
 
1774
                        mesh_octree_table(G.obedit, NULL, 'e');
 
1775
        }
 
1776
        else if (G.obedit->type==OB_ARMATURE){  
 
1777
                load_editArmature();
 
1778
                if (freedata) free_editArmature();
 
1779
        }
 
1780
        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
 
1781
                extern ListBase editNurb;
 
1782
                load_editNurb();
 
1783
                if(freedata) freeNurblist(&editNurb);
 
1784
        }
 
1785
        else if(G.obedit->type==OB_FONT && freedata) {
 
1786
                load_editText();
 
1787
        }
 
1788
        else if(G.obedit->type==OB_LATTICE) {
 
1789
                load_editLatt();
 
1790
                if(freedata) free_editLatt();
 
1791
        }
 
1792
        else if(G.obedit->type==OB_MBALL) {
 
1793
                extern ListBase editelems;
 
1794
                load_editMball();
 
1795
                if(freedata) BLI_freelistN(&editelems);
 
1796
        }
 
1797
 
 
1798
        ob= G.obedit;
 
1799
        
 
1800
        /* for example; displist make is different in editmode */
 
1801
        if(freedata) G.obedit= NULL;
 
1802
 
 
1803
        if(ob->type==OB_MESH && get_mesh(ob)->mr)
 
1804
                multires_edge_level_update(ob, get_mesh(ob));
 
1805
        
 
1806
        /* also flush ob recalc, doesn't take much overhead, but used for particles */
 
1807
        DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA);
 
1808
 
 
1809
        if(freedata) {
 
1810
                setcursor_space(SPACE_VIEW3D, CURSOR_STD);
 
1811
        }
 
1812
        
 
1813
        countall();
 
1814
        allqueue(REDRAWVIEW3D, 1);
 
1815
        allqueue(REDRAWBUTSALL, 0);
 
1816
        allqueue(REDRAWACTION, 0);
 
1817
        allqueue(REDRAWNLA, 0);
 
1818
        allqueue(REDRAWIPO, 0);
 
1819
        allqueue(REDRAWOOPS, 0);
 
1820
 
 
1821
        scrarea_queue_headredraw(curarea);
 
1822
        
 
1823
        if(G.obedit==NULL && (flag & EM_FREEUNDO)) 
 
1824
                BIF_undo_push("Editmode");
 
1825
        
 
1826
        if(flag & EM_WAITCURSOR) waitcursor(0);
 
1827
}
 
1828
 
 
1829
void check_editmode(int type)
 
1830
{
 
1831
        
 
1832
        if (G.obedit==0 || G.obedit->type==type) return;
 
1833
 
 
1834
        exit_editmode(EM_FREEDATA|EM_FREEUNDO|EM_WAITCURSOR); /* freedata, and undo */
 
1835
}
 
1836
 
 
1837
/* 0 == do center, 1 == center new, 2 == center cursor */
 
1838
 
 
1839
void docenter(int centermode)
 
1840
{
 
1841
        EditMesh *em = G.editMesh;
 
1842
        Base *base;
 
1843
        Object *ob;
 
1844
        Mesh *me, *tme;
 
1845
        Curve *cu;
 
1846
/*      BezTriple *bezt;
 
1847
        BPoint *bp; */
 
1848
        Nurb *nu, *nu1;
 
1849
        EditVert *eve;
 
1850
        float cent[3], centn[3], min[3], max[3], omat[3][3];
 
1851
        int a, total= 0;
 
1852
        
 
1853
        /* keep track of what is changed */
 
1854
        int tot_change=0, tot_lib_error=0, tot_key_error=0, tot_multiuser_arm_error=0;
 
1855
        MVert *mvert;
 
1856
 
 
1857
        if(G.scene->id.lib || G.vd==NULL) return;
 
1858
        
 
1859
        cent[0]= cent[1]= cent[2]= 0.0;
 
1860
        
 
1861
        if(G.obedit) {
 
1862
 
 
1863
                INIT_MINMAX(min, max);
 
1864
        
 
1865
                if(G.obedit->type==OB_MESH) {
 
1866
                        for(eve= em->verts.first; eve; eve= eve->next) {
 
1867
                                if(G.vd->around==V3D_CENTROID) {
 
1868
                                        total++;
 
1869
                                        VECADD(cent, cent, eve->co);
 
1870
                                }
 
1871
                                else {
 
1872
                                        DO_MINMAX(eve->co, min, max);
 
1873
                                }
 
1874
                        }
 
1875
                        
 
1876
                        if(G.vd->around==V3D_CENTROID) {
 
1877
                                VecMulf(cent, 1.0f/(float)total);
 
1878
                        }
 
1879
                        else {
 
1880
                                cent[0]= (min[0]+max[0])/2.0f;
 
1881
                                cent[1]= (min[1]+max[1])/2.0f;
 
1882
                                cent[2]= (min[2]+max[2])/2.0f;
 
1883
                        }
 
1884
                        
 
1885
                        for(eve= em->verts.first; eve; eve= eve->next) {
 
1886
                                VecSubf(eve->co, eve->co, cent);                        
 
1887
                        }
 
1888
                        
 
1889
                        recalc_editnormals();
 
1890
                        tot_change++;
 
1891
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
1892
                }
 
1893
        }
 
1894
        
 
1895
        /* reset flags */
 
1896
        for (base=FIRSTBASE; base; base= base->next) {
 
1897
                if TESTBASELIB(base)
 
1898
                        base->object->flag &= ~OB_DONE;
 
1899
        }
 
1900
        
 
1901
        for (me= G.main->mesh.first; me; me= me->id.next) {
 
1902
                me->flag &= ~ME_ISDONE;
 
1903
        }
 
1904
        
 
1905
        base= FIRSTBASE;
 
1906
        while(base) {
 
1907
                
 
1908
                if TESTBASELIB(base) {
 
1909
                        if((base->object->flag & OB_DONE)==0) {
 
1910
                                base->object->flag |= OB_DONE;
 
1911
                                
 
1912
                                if(base->object->id.lib) {
 
1913
                                        tot_lib_error++;
 
1914
                                }
 
1915
                                else if(G.obedit==0 && (me=get_mesh(base->object)) ) {
 
1916
                                        
 
1917
                                        if(me->key) {
 
1918
                                                /*error("Can't change the center of a mesh with vertex keys");
 
1919
                                                return;*/
 
1920
                                                tot_key_error++;
 
1921
                                        } else if (me->id.lib) {
 
1922
                                                tot_lib_error++;
 
1923
                                        } else {
 
1924
                                                if(centermode==2) {
 
1925
                                                        VECCOPY(cent, give_cursor());
 
1926
                                                        Mat4Invert(base->object->imat, base->object->obmat);
 
1927
                                                        Mat4MulVecfl(base->object->imat, cent);
 
1928
                                                } else {
 
1929
                                                        INIT_MINMAX(min, max);
 
1930
                                                        mvert= me->mvert;
 
1931
                                                        for(a=0; a<me->totvert; a++, mvert++) {
 
1932
                                                                DO_MINMAX(mvert->co, min, max);
 
1933
                                                        }
 
1934
                                        
 
1935
                                                        cent[0]= (min[0]+max[0])/2.0f;
 
1936
                                                        cent[1]= (min[1]+max[1])/2.0f;
 
1937
                                                        cent[2]= (min[2]+max[2])/2.0f;
 
1938
                                                }
 
1939
 
 
1940
                                                mvert= me->mvert;
 
1941
                                                for(a=0; a<me->totvert; a++, mvert++) {
 
1942
                                                        VecSubf(mvert->co, mvert->co, cent);
 
1943
                                                }
 
1944
                                                me->flag |= ME_ISDONE;
 
1945
                                                
 
1946
                                                if(centermode) {
 
1947
                                                        Mat3CpyMat4(omat, base->object->obmat);
 
1948
                                                        
 
1949
                                                        VECCOPY(centn, cent);
 
1950
                                                        Mat3MulVecfl(omat, centn);
 
1951
                                                        base->object->loc[0]+= centn[0];
 
1952
                                                        base->object->loc[1]+= centn[1];
 
1953
                                                        base->object->loc[2]+= centn[2];
 
1954
                                                        
 
1955
                                                        where_is_object(base->object);
 
1956
                                                        ignore_parent_tx(base->object);
 
1957
                                                        
 
1958
                                                        /* other users? */
 
1959
                                                        ob= G.main->object.first;
 
1960
                                                        while(ob) {
 
1961
                                                                if((ob->flag & OB_DONE)==0) {
 
1962
                                                                        tme= get_mesh(ob);
 
1963
                                                                        
 
1964
                                                                        if(tme==me) {
 
1965
                                                                                
 
1966
                                                                                ob->flag |= OB_DONE;
 
1967
                                                                                ob->recalc= OB_RECALC_OB|OB_RECALC_DATA;
 
1968
 
 
1969
                                                                                Mat3CpyMat4(omat, ob->obmat);
 
1970
                                                                                VECCOPY(centn, cent);
 
1971
                                                                                Mat3MulVecfl(omat, centn);
 
1972
                                                                                ob->loc[0]+= centn[0];
 
1973
                                                                                ob->loc[1]+= centn[1];
 
1974
                                                                                ob->loc[2]+= centn[2];
 
1975
                                                                                
 
1976
                                                                                where_is_object(ob);
 
1977
                                                                                ignore_parent_tx(ob);
 
1978
                                                                                
 
1979
                                                                                if(tme && (tme->flag & ME_ISDONE)==0) {
 
1980
                                                                                        mvert= tme->mvert;
 
1981
                                                                                        for(a=0; a<tme->totvert; a++, mvert++) {
 
1982
                                                                                                VecSubf(mvert->co, mvert->co, cent);
 
1983
                                                                                        }
 
1984
                                                                                        tme->flag |= ME_ISDONE;
 
1985
                                                                                }
 
1986
                                                                        }
 
1987
                                                                }
 
1988
                                                                
 
1989
                                                                ob= ob->id.next;
 
1990
                                                        }
 
1991
                                                }
 
1992
                                                tot_change++;
 
1993
                                        }
 
1994
                                }
 
1995
                                else if ELEM(base->object->type, OB_CURVE, OB_SURF) {
 
1996
                                        
 
1997
                                        /* totally weak code here... (ton) */
 
1998
                                        if(G.obedit==base->object) {
 
1999
                                                extern ListBase editNurb;
 
2000
                                                nu1= editNurb.first;
 
2001
                                                cu= G.obedit->data;
 
2002
                                        }
 
2003
                                        else {
 
2004
                                                cu= base->object->data;
 
2005
                                                nu1= cu->nurb.first;
 
2006
                                        }
 
2007
                                        
 
2008
                                        if (cu->id.lib) {
 
2009
                                                tot_lib_error++;
 
2010
                                        } else {
 
2011
                                                if(centermode==2) {
 
2012
                                                        VECCOPY(cent, give_cursor());
 
2013
                                                        Mat4Invert(base->object->imat, base->object->obmat);
 
2014
                                                        Mat4MulVecfl(base->object->imat, cent);
 
2015
 
 
2016
                                                        /* don't allow Z change if curve is 2D */
 
2017
                                                        if( !( cu->flag & CU_3D ) )
 
2018
                                                                cent[2] = 0.0;
 
2019
                                                } else {
 
2020
                                                        INIT_MINMAX(min, max);
 
2021
                
 
2022
                                                        nu= nu1;
 
2023
                                                        while(nu) {
 
2024
                                                                minmaxNurb(nu, min, max);
 
2025
                                                                nu= nu->next;
 
2026
                                                        }
 
2027
                                                        
 
2028
                                                        cent[0]= (min[0]+max[0])/2.0f;
 
2029
                                                        cent[1]= (min[1]+max[1])/2.0f;
 
2030
                                                        cent[2]= (min[2]+max[2])/2.0f;
 
2031
                                                }
 
2032
                                                
 
2033
                                                nu= nu1;
 
2034
                                                while(nu) {
 
2035
                                                        if( (nu->type & 7)==1) {
 
2036
                                                                a= nu->pntsu;
 
2037
                                                                while (a--) {
 
2038
                                                                        VecSubf(nu->bezt[a].vec[0], nu->bezt[a].vec[0], cent);
 
2039
                                                                        VecSubf(nu->bezt[a].vec[1], nu->bezt[a].vec[1], cent);
 
2040
                                                                        VecSubf(nu->bezt[a].vec[2], nu->bezt[a].vec[2], cent);
 
2041
                                                                }
 
2042
                                                        }
 
2043
                                                        else {
 
2044
                                                                a= nu->pntsu*nu->pntsv;
 
2045
                                                                while (a--)
 
2046
                                                                        VecSubf(nu->bp[a].vec, nu->bp[a].vec, cent);
 
2047
                                                        }
 
2048
                                                        nu= nu->next;
 
2049
                                                }
 
2050
                                
 
2051
                                                if(centermode && G.obedit==0) {
 
2052
                                                        Mat3CpyMat4(omat, base->object->obmat);
 
2053
                                                        
 
2054
                                                        Mat3MulVecfl(omat, cent);
 
2055
                                                        base->object->loc[0]+= cent[0];
 
2056
                                                        base->object->loc[1]+= cent[1];
 
2057
                                                        base->object->loc[2]+= cent[2];
 
2058
                                                        
 
2059
                                                        where_is_object(base->object);
 
2060
                                                        ignore_parent_tx(base->object);
 
2061
                                                }
 
2062
                                                
 
2063
                                                tot_change++;
 
2064
                                                if(G.obedit) {
 
2065
                                                        if (centermode==0) {
 
2066
                                                                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
2067
                                                        }
 
2068
                                                        break;
 
2069
                                                }
 
2070
                                        }
 
2071
                                }
 
2072
                                else if(base->object->type==OB_FONT) {
 
2073
                                        /* get from bb */
 
2074
                                        
 
2075
                                        cu= base->object->data;
 
2076
                                        
 
2077
                                        if(cu->bb==0) {
 
2078
                                                /* do nothing*/
 
2079
                                        } else if (cu->id.lib) {
 
2080
                                                tot_lib_error++;
 
2081
                                        } else {
 
2082
                                                cu->xof= -0.5f*( cu->bb->vec[4][0] - cu->bb->vec[0][0]);
 
2083
                                                cu->yof= -0.5f -0.5f*( cu->bb->vec[0][1] - cu->bb->vec[2][1]);  /* extra 0.5 is the height of above line */
 
2084
                                                
 
2085
                                                /* not really ok, do this better once! */
 
2086
                                                cu->xof /= cu->fsize;
 
2087
                                                cu->yof /= cu->fsize;
 
2088
 
 
2089
                                                allqueue(REDRAWBUTSEDIT, 0);
 
2090
                                                tot_change++;
 
2091
                                        }
 
2092
                                }
 
2093
                                else if(base->object->type==OB_ARMATURE) {
 
2094
                                        bArmature *arm = base->object->data;
 
2095
                                        
 
2096
                                        if (arm->id.lib) {
 
2097
                                                tot_lib_error++;
 
2098
                                        } else if(arm->id.us>1) {
 
2099
                                                /*error("Can't apply to a multi user armature");
 
2100
                                                return;*/
 
2101
                                                tot_multiuser_arm_error++;
 
2102
                                        } else {
 
2103
                                                /* Function to recenter armatures in editarmature.c 
 
2104
                                                 * Bone + object locations are handled there.
 
2105
                                                 */
 
2106
                                                docenter_armature(base->object, centermode);
 
2107
                                                tot_change++;
 
2108
                                                
 
2109
                                                where_is_object(base->object);
 
2110
                                                ignore_parent_tx(base->object);
 
2111
                                                
 
2112
                                                if(G.obedit) 
 
2113
                                                        break;
 
2114
                                        }
 
2115
                                }
 
2116
                                base->object->recalc= OB_RECALC_OB|OB_RECALC_DATA;
 
2117
                        }
 
2118
                }
 
2119
                base= base->next;
 
2120
        }
 
2121
        if (tot_change) {
 
2122
                DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
2123
                allqueue(REDRAWVIEW3D, 0);
 
2124
                BIF_undo_push("Do Center");     
 
2125
        }
 
2126
        
 
2127
        /* Warn if any errors occured */
 
2128
        if (tot_lib_error+tot_key_error+tot_multiuser_arm_error) {
 
2129
                char err[512];
 
2130
                sprintf(err, "Warning %i Object(s) Not Centered, %i Changed:", tot_lib_error+tot_key_error+tot_multiuser_arm_error, tot_change);
 
2131
                
 
2132
                if (tot_lib_error)
 
2133
                        sprintf(err+strlen(err), "|%i linked library objects", tot_lib_error);
 
2134
                if (tot_key_error)
 
2135
                        sprintf(err+strlen(err), "|%i mesh key object(s)", tot_key_error);
 
2136
                if (tot_multiuser_arm_error)
 
2137
                        sprintf(err+strlen(err), "|%i multiuser armature object(s)", tot_multiuser_arm_error);
 
2138
                
 
2139
                error(err);
 
2140
        }
 
2141
}
 
2142
 
 
2143
void docenter_new(void)
 
2144
{
 
2145
        if(G.scene->id.lib) return;
 
2146
 
 
2147
        if(G.obedit) {
 
2148
                error("Unable to center new in Edit Mode");
 
2149
        }
 
2150
        else {
 
2151
                docenter(1);
 
2152
        }
 
2153
}
 
2154
 
 
2155
void docenter_cursor(void)
 
2156
{
 
2157
        if(G.scene->id.lib) return;
 
2158
 
 
2159
        if(G.obedit) {
 
2160
                error("Unable to center cursor in Edit Mode");
 
2161
        }
 
2162
        else {
 
2163
                docenter(2);
 
2164
        }
 
2165
}
 
2166
 
 
2167
void movetolayer(void)
 
2168
{
 
2169
        Base *base;
 
2170
        unsigned int lay= 0, local;
 
2171
        int islamp= 0;
 
2172
        
 
2173
        if(G.scene->id.lib) return;
 
2174
 
 
2175
        base= FIRSTBASE;
 
2176
        while(base) {
 
2177
                if TESTBASE(base) lay |= base->lay;
 
2178
                base= base->next;
 
2179
        }
 
2180
        if(lay==0) return;
 
2181
        lay &= 0xFFFFFF;
 
2182
        
 
2183
        if(lay==0) return;
 
2184
        
 
2185
        if(G.vd->localview) {
 
2186
                /* now we can move out of localview. */
 
2187
                if (!okee("Move from localview")) return;
 
2188
                base= FIRSTBASE;
 
2189
                while(base) {
 
2190
                        if TESTBASE(base) {
 
2191
                                lay= base->lay & ~G.vd->lay;
 
2192
                                base->lay= lay;
 
2193
                                base->object->lay= lay;
 
2194
                                base->object->flag &= ~SELECT;
 
2195
                                base->flag &= ~SELECT;
 
2196
                                if(base->object->type==OB_LAMP) islamp= 1;
 
2197
                        }
 
2198
                        base= base->next;
 
2199
                }
 
2200
        } else {
 
2201
                if( movetolayer_buts(&lay, NULL)==0 ) return;
 
2202
                
 
2203
                /* normal non localview operation */
 
2204
                base= FIRSTBASE;
 
2205
                while(base) {
 
2206
                        if TESTBASE(base) {
 
2207
                                /* upper byte is used for local view */
 
2208
                                local= base->lay & 0xFF000000;  
 
2209
                                base->lay= lay + local;
 
2210
                                base->object->lay= lay;
 
2211
                                if(base->object->type==OB_LAMP) islamp= 1;
 
2212
                        }
 
2213
                        base= base->next;
 
2214
                }
 
2215
        }
 
2216
        if(islamp) reshadeall_displist();       /* only frees */
 
2217
        
 
2218
        /* warning, active object may be hidden now */
 
2219
        
 
2220
        countall();
 
2221
        DAG_scene_sort(G.scene);
 
2222
        
 
2223
        allqueue(REDRAWBUTSEDIT, 0);
 
2224
        allqueue(REDRAWVIEW3D, 0);
 
2225
        allqueue(REDRAWOOPS, 0);
 
2226
        allqueue(REDRAWINFO, 0);
 
2227
        
 
2228
        BIF_undo_push("Move to layer");
 
2229
}
 
2230
 
 
2231
/* THIS IS BAD CODE! do not bring back before it has a real implementation (ton) */
 
2232
void split_font()
 
2233
{
 
2234
        Object *ob = OBACT;
 
2235
        Base *oldbase = BASACT;
 
2236
        Curve *cu= ob->data;
 
2237
        char *p= cu->str;
 
2238
        int slen= strlen(p);
 
2239
        int i;
 
2240
 
 
2241
        for (i = 0; i<=slen; p++, i++) {
 
2242
                adduplicate(1, U.dupflag);
 
2243
                cu= OBACT->data;
 
2244
                cu->sepchar = i+1;
 
2245
                text_to_curve(OBACT, 0);        /* pass 1: only one letter, adapt position */
 
2246
                text_to_curve(OBACT, 0);        /* pass 2: remake */
 
2247
                freedisplist(&OBACT->disp);
 
2248
                makeDispListCurveTypes(OBACT, 0);
 
2249
                
 
2250
                OBACT->flag &= ~SELECT;
 
2251
                BASACT->flag &= ~SELECT;
 
2252
                oldbase->flag |= SELECT;
 
2253
                oldbase->object->flag |= SELECT;
 
2254
                set_active_base(oldbase);               
 
2255
        }
 
2256
}
 
2257
 
 
2258
static void helpline(short *mval, int *center2d)
 
2259
{
 
2260
        
 
2261
        /* helpline, copied from transform.c actually */
 
2262
        persp(PERSP_WIN);
 
2263
        glDrawBuffer(GL_FRONT);
 
2264
        
 
2265
        BIF_ThemeColor(TH_WIRE);
 
2266
        
 
2267
        setlinestyle(3);
 
2268
        glBegin(GL_LINE_STRIP); 
 
2269
        glVertex2sv(mval); 
 
2270
        glVertex2iv((GLint *)center2d); 
 
2271
        glEnd();
 
2272
        setlinestyle(0);
 
2273
        
 
2274
        persp(PERSP_VIEW);
 
2275
        bglFlush(); // flush display for frontbuffer
 
2276
        glDrawBuffer(GL_BACK);
 
2277
        
 
2278
        
 
2279
}
 
2280
 
 
2281
/* context: ob = lamp */
 
2282
/* code should be replaced with proper (custom) transform handles for lamp properties */
 
2283
static void spot_interactive(Object *ob, int mode)
 
2284
{
 
2285
        Lamp *la= ob->data;
 
2286
        float transfac, dx, dy, ratio, origval;
 
2287
        int keep_running= 1, center2d[2];
 
2288
        short mval[2], mvalo[2];
 
2289
        
 
2290
        getmouseco_areawin(mval);
 
2291
        getmouseco_areawin(mvalo);
 
2292
        
 
2293
        project_int(ob->obmat[3], center2d);
 
2294
        if( center2d[0] > 100000 ) {            /* behind camera */
 
2295
                center2d[0]= curarea->winx/2;
 
2296
                center2d[1]= curarea->winy/2;
 
2297
        }
 
2298
 
 
2299
        helpline(mval, center2d);
 
2300
        
 
2301
        /* ratio is like scaling */
 
2302
        dx = (float)(center2d[0] - mval[0]);
 
2303
        dy = (float)(center2d[1] - mval[1]);
 
2304
        transfac = (float)sqrt( dx*dx + dy*dy);
 
2305
        if(transfac==0.0f) transfac= 1.0f;
 
2306
        
 
2307
        if(mode==1)     
 
2308
                origval= la->spotsize;
 
2309
        else if(mode==2)        
 
2310
                origval= la->dist;
 
2311
        else if(mode==3)        
 
2312
                origval= la->clipsta;
 
2313
        else    
 
2314
                origval= la->clipend;
 
2315
        
 
2316
        while (keep_running>0) {
 
2317
                
 
2318
                getmouseco_areawin(mval);
 
2319
                
 
2320
                /* essential for idling subloop */
 
2321
                if(mval[0]==mvalo[0] && mval[1]==mvalo[1]) {
 
2322
                        PIL_sleep_ms(2);
 
2323
                }
 
2324
                else {
 
2325
                        char str[32];
 
2326
                        
 
2327
                        dx = (float)(center2d[0] - mval[0]);
 
2328
                        dy = (float)(center2d[1] - mval[1]);
 
2329
                        ratio = (float)(sqrt( dx*dx + dy*dy))/transfac;
 
2330
                        
 
2331
                        /* do the trick */
 
2332
                        
 
2333
                        if(mode==1) {   /* spot */
 
2334
                                la->spotsize = ratio*origval;
 
2335
                                CLAMP(la->spotsize, 1.0f, 180.0f);
 
2336
                                sprintf(str, "Spot size %.2f\n", la->spotsize);
 
2337
                        }
 
2338
                        else if(mode==2) {      /* dist */
 
2339
                                la->dist = ratio*origval;
 
2340
                                CLAMP(la->dist, 0.01f, 5000.0f);
 
2341
                                sprintf(str, "Distance %.2f\n", la->dist);
 
2342
                        }
 
2343
                        else if(mode==3) {      /* sta */
 
2344
                                la->clipsta = ratio*origval;
 
2345
                                CLAMP(la->clipsta, 0.001f, 5000.0f);
 
2346
                                sprintf(str, "Distance %.2f\n", la->clipsta);
 
2347
                        }
 
2348
                        else if(mode==4) {      /* end */
 
2349
                                la->clipend = ratio*origval;
 
2350
                                CLAMP(la->clipend, 0.1f, 5000.0f);
 
2351
                                sprintf(str, "Clip End %.2f\n", la->clipend);
 
2352
                        }
 
2353
 
 
2354
                        /* cleanup */
 
2355
                        mvalo[0]= mval[0];
 
2356
                        mvalo[1]= mval[1];
 
2357
                        
 
2358
                        /* handle shaded mode */
 
2359
                        shade_buttons_change_3d();
 
2360
 
 
2361
                        /* DRAW */      
 
2362
                        headerprint(str);
 
2363
                        force_draw_plus(SPACE_BUTS, 0);
 
2364
 
 
2365
                        helpline(mval, center2d);
 
2366
                }
 
2367
                
 
2368
                while( qtest() ) {
 
2369
                        short val;
 
2370
                        unsigned short event= extern_qread(&val);
 
2371
                        
 
2372
                        switch (event){
 
2373
                                case ESCKEY:
 
2374
                                case RIGHTMOUSE:
 
2375
                                        keep_running= 0;
 
2376
                                        break;
 
2377
                                case LEFTMOUSE:
 
2378
                                case SPACEKEY:
 
2379
                                case PADENTER:
 
2380
                                case RETKEY:
 
2381
                                        if(val)
 
2382
                                                keep_running= -1;
 
2383
                                        break;
 
2384
                        }
 
2385
                }
 
2386
        }
 
2387
 
 
2388
        if(keep_running==0) {
 
2389
                if(mode==1)     
 
2390
                        la->spotsize= origval;
 
2391
                else if(mode==2)        
 
2392
                        la->dist= origval;
 
2393
                else if(mode==3)        
 
2394
                        la->clipsta= origval;
 
2395
                else    
 
2396
                        la->clipend= origval;
 
2397
        }
 
2398
 
 
2399
        allqueue(REDRAWVIEW3D, 0);
 
2400
        allqueue(REDRAWBUTSSHADING, 0);
 
2401
        BIF_preview_changed(ID_LA);
 
2402
}
 
2403
 
 
2404
 
 
2405
void special_editmenu(void)
 
2406
{
 
2407
        static short numcuts= 2;
 
2408
        Object *ob= OBACT;
 
2409
        float fac;
 
2410
        int nr,ret;
 
2411
        short randfac;
 
2412
        
 
2413
        if(ob==NULL) return;
 
2414
        
 
2415
        if(G.obedit==NULL) {
 
2416
                
 
2417
                if(ob->flag & OB_POSEMODE) {
 
2418
                        pose_special_editmenu();
 
2419
                }
 
2420
                else if(FACESEL_PAINT_TEST) {
 
2421
                        Mesh *me= get_mesh(ob);
 
2422
                        MTFace *tface;
 
2423
                        MFace *mface;
 
2424
                        int a;
 
2425
                        
 
2426
                        if(me==0 || me->mtface==0) return;
 
2427
                        
 
2428
                        nr= pupmenu("Specials%t|Set     Tex%x1|         Shared%x2|         Light%x3|         Invisible%x4|         Collision%x5|         TwoSide%x6|Clr     Tex%x7|         Shared%x8|         Light%x9|         Invisible%x10|         Collision%x11|         TwoSide%x12");
 
2429
                        
 
2430
                        tface= me->mtface;
 
2431
                        mface= me->mface;
 
2432
                        for(a=me->totface; a>0; a--, tface++, mface++) {
 
2433
                                if(mface->flag & ME_FACE_SEL) {
 
2434
                                        switch(nr) {
 
2435
                                        case 1:
 
2436
                                                tface->mode |= TF_TEX; break;
 
2437
                                        case 2:
 
2438
                                                tface->mode |= TF_SHAREDCOL; break;
 
2439
                                        case 3:
 
2440
                                                tface->mode |= TF_LIGHT; break; 
 
2441
                                        case 4:
 
2442
                                                tface->mode |= TF_INVISIBLE; break;
 
2443
                                        case 5:
 
2444
                                                tface->mode |= TF_DYNAMIC; break;
 
2445
                                        case 6:
 
2446
                                                tface->mode |= TF_TWOSIDE; break;
 
2447
                                        case 7:
 
2448
                                                tface->mode &= ~TF_TEX;
 
2449
                                                tface->tpage= 0;
 
2450
                                                break;
 
2451
                                        case 8:
 
2452
                                                tface->mode &= ~TF_SHAREDCOL; break;
 
2453
                                        case 9:
 
2454
                                                tface->mode &= ~TF_LIGHT; break;
 
2455
                                        case 10:
 
2456
                                                tface->mode &= ~TF_INVISIBLE; break;
 
2457
                                        case 11:
 
2458
                                                tface->mode &= ~TF_DYNAMIC; break;
 
2459
                                        case 12:
 
2460
                                                tface->mode &= ~TF_TWOSIDE; break;
 
2461
                                        }
 
2462
                                }
 
2463
                        }
 
2464
                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2465
                        allqueue(REDRAWVIEW3D, 0);
 
2466
                        allqueue(REDRAWBUTSEDIT, 0);
 
2467
                        BIF_undo_push("Change texture face");
 
2468
                }
 
2469
                else if(G.f & G_VERTEXPAINT) {
 
2470
                        Mesh *me= get_mesh(ob);
 
2471
                        
 
2472
                        if(me==0 || (me->mcol==NULL && me->mtface==NULL) ) return;
 
2473
                        
 
2474
                        nr= pupmenu("Specials%t|Shared VertexCol%x1");
 
2475
                        if(nr==1) {
 
2476
                                
 
2477
                                do_shared_vertexcol(me);
 
2478
                                
 
2479
                                BIF_undo_push("Shared VertexCol");
 
2480
 
 
2481
                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
2482
                        }
 
2483
                }
 
2484
                else if(G.f & G_WEIGHTPAINT) {
 
2485
                        Object *par= modifiers_isDeformedByArmature(ob);
 
2486
 
 
2487
                        if(par && (par->flag & OB_POSEMODE)) {
 
2488
                                nr= pupmenu("Specials%t|Apply Bone Envelopes to Vertex Groups %x1|Apply Bone Heat Weights to Vertex Groups %x2");
 
2489
 
 
2490
                                if(nr==1 || nr==2)
 
2491
                                        pose_adds_vgroups(ob, (nr == 2));
 
2492
                        }
 
2493
                }
 
2494
                else if(G.f & G_PARTICLEEDIT) {
 
2495
                        ParticleSystem *psys = PE_get_current(ob);
 
2496
                        ParticleEditSettings *pset = PE_settings();
 
2497
 
 
2498
                        if(!psys)
 
2499
                                return;
 
2500
 
 
2501
                        if(G.scene->selectmode & SCE_SELECT_POINT)
 
2502
                                nr= pupmenu("Specials%t|Rekey%x1|Subdivide%x2|Select First%x3|Select Last%x4|Remove Doubles%x5");
 
2503
                        else
 
2504
                                nr= pupmenu("Specials%t|Rekey%x1|Remove Doubles%x5");
 
2505
                        
 
2506
                        switch(nr) {
 
2507
                        case 1:
 
2508
                                if(button(&pset->totrekey, 2, 100, "Number of Keys:")==0) return;
 
2509
                                waitcursor(1);
 
2510
                                PE_rekey();
 
2511
                                break;
 
2512
                        case 2:
 
2513
                                PE_subdivide();
 
2514
                                break;
 
2515
                        case 3:
 
2516
                                PE_select_root();
 
2517
                                break;
 
2518
                        case 4:
 
2519
                                PE_select_tip();
 
2520
                                break;
 
2521
                        case 5:
 
2522
                                PE_remove_doubles();
 
2523
                                break;
 
2524
                        }
 
2525
                        
 
2526
                        DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
2527
                        
 
2528
                        if(nr>0) waitcursor(0);
 
2529
                }
 
2530
                else {
 
2531
                        Base *base, *base_select= NULL;
 
2532
                        
 
2533
                        /* Get the active object mesh. */
 
2534
                        Mesh *me= get_mesh(ob);
 
2535
 
 
2536
                        /* Booleans, if the active object is a mesh... */
 
2537
                        if (me && ob->id.lib==NULL) {
 
2538
                                
 
2539
                                /* Bring up a little menu with the boolean operation choices on. */
 
2540
                                nr= pupmenu("Boolean Tools%t|Intersect%x1|Union%x2|Difference%x3|Add Intersect Modifier%x4|Add Union Modifier%x5|Add Difference Modifier%x6");
 
2541
 
 
2542
                                if (nr > 0) {
 
2543
                                        /* user has made a choice of a menu element.
 
2544
                                           All of the boolean functions require 2 mesh objects 
 
2545
                                           we search through the object list to find the other 
 
2546
                                           selected item and make sure it is distinct and a mesh. */
 
2547
 
 
2548
                                        for(base= FIRSTBASE; base; base= base->next) {
 
2549
                                                if TESTBASELIB(base) {
 
2550
                                                        if(base->object != ob) base_select= base;
 
2551
                                                }
 
2552
                                        }
 
2553
 
 
2554
                                        if (base_select) {
 
2555
                                                if (get_mesh(base_select->object)) {
 
2556
                                                        if(nr <= 3){
 
2557
                                                                waitcursor(1);
 
2558
                                                                ret = NewBooleanMesh(BASACT,base_select,nr);
 
2559
                                                                if (ret==0) {
 
2560
                                                                        error("An internal error occurred");
 
2561
                                                                } else if(ret==-1) {
 
2562
                                                                        error("Selected meshes must have faces to perform boolean operations");
 
2563
                                                                } else if (ret==-2) {
 
2564
                                                                        error("Both meshes must be a closed mesh");
 
2565
                                                                }
 
2566
                                                                else BIF_undo_push("Boolean");
 
2567
                                                                waitcursor(0);
 
2568
                                                        } else {
 
2569
                                                                BooleanModifierData *bmd = NULL;
 
2570
                                                                bmd = (BooleanModifierData *)modifier_new(eModifierType_Boolean);
 
2571
                                                                BLI_addtail(&ob->modifiers, bmd);
 
2572
                                                                bmd->object = base_select->object;
 
2573
                                                                bmd->modifier.mode |= eModifierMode_Realtime;
 
2574
                                                                switch(nr){
 
2575
                                                                        case 4: bmd->operation = eBooleanModifierOp_Intersect; break;
 
2576
                                                                        case 5: bmd->operation = eBooleanModifierOp_Union; break;
 
2577
                                                                        case 6: bmd->operation = eBooleanModifierOp_Difference; break;
 
2578
                                                                }
 
2579
                                                                do_common_editbuts(B_CHANGEDEP);
 
2580
                                                                BIF_undo_push("Add Boolean modifier");                                                          
 
2581
                                                        }                                                               
 
2582
                                                } else {
 
2583
                                                        error("Please select 2 meshes");
 
2584
                                                }
 
2585
                                        } else {
 
2586
                                                error("Please select 2 meshes");
 
2587
                                        }
 
2588
                                }
 
2589
 
 
2590
                                allqueue(REDRAWVIEW3D, 0);
 
2591
                        }
 
2592
                        else if (ob->type == OB_LAMP) {
 
2593
                                Lamp *la= ob->data;
 
2594
                                if(la->type==LA_SPOT) {
 
2595
                                        short nr= pupmenu("Lamp Tools%t|Spot Size%x1|Distance%x2|Clip Start%x3|Clip End%x4");
 
2596
                                        if(nr>0)
 
2597
                                                spot_interactive(ob, nr);
 
2598
                                }
 
2599
                        }
 
2600
                        else if (ob->type == OB_FONT) {
 
2601
                                /* removed until this gets a decent implementation (ton) */
 
2602
/*                              nr= pupmenu("Split %t|Characters%x1");
 
2603
                                if (nr > 0) {
 
2604
                                        switch(nr) {
 
2605
                                                case 1: split_font();
 
2606
                                        }
 
2607
                                }
 
2608
*/
 
2609
                        }                       
 
2610
                }
 
2611
        }
 
2612
        else if(G.obedit->type==OB_MESH) {
 
2613
                /* This is all that is needed, since all other functionality is in Ctrl+ V/E/F but some users didnt like, so for now have the old/big menu */
 
2614
                /*
 
2615
                nr= pupmenu("Subdivide Mesh%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x4");
 
2616
                switch(nr) {
 
2617
                case 1:
 
2618
                        waitcursor(1);
 
2619
                        esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, 1, 0);
 
2620
                        
 
2621
                        BIF_undo_push("ESubdivide Single");            
 
2622
                        break;
 
2623
                case 2:
 
2624
                        if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
 
2625
                        waitcursor(1);
 
2626
                        esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, numcuts, 0);
 
2627
                        BIF_undo_push("ESubdivide");
 
2628
                        break;
 
2629
                case 3:
 
2630
                        if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
 
2631
                        randfac= 10;
 
2632
                        if(button(&randfac, 1, 100, "Rand fac:")==0) return;
 
2633
                        waitcursor(1);                  
 
2634
                        fac= -( (float)randfac )/100;
 
2635
                        esubdivideflag(1, fac, G.scene->toolsettings->editbutflag, numcuts, 0);
 
2636
                        BIF_undo_push("Subdivide Fractal");
 
2637
                        break;
 
2638
                        
 
2639
                case 4:
 
2640
                        fac= 1.0f;
 
2641
                        if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return;
 
2642
                                fac= 0.292f*fac;
 
2643
                        
 
2644
                        waitcursor(1);
 
2645
                        esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
 
2646
                        BIF_undo_push("Subdivide Smooth");
 
2647
                        break;          
 
2648
                }
 
2649
                */
 
2650
                
 
2651
                nr= pupmenu("Specials%t|Subdivide%x1|Subdivide Multi%x2|Subdivide Multi Fractal%x3|Subdivide Smooth%x12|Merge%x4|Remove Doubles%x5|Hide%x6|Reveal%x7|Select Swap%x8|Flip Normals %x9|Smooth %x10|Bevel %x11|Set Smooth %x14|Set Solid %x15|Blend From Shape%x16|Propagate To All Shapes%x17|Select Vertex Path%x18");
 
2652
                
 
2653
                switch(nr) {
 
2654
                case 1:
 
2655
                        waitcursor(1);
 
2656
                        esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, 1, 0);
 
2657
                        
 
2658
                        BIF_undo_push("ESubdivide Single");            
 
2659
                        break;
 
2660
                case 2:
 
2661
                        if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
 
2662
                        waitcursor(1);
 
2663
                        esubdivideflag(1, 0.0, G.scene->toolsettings->editbutflag, numcuts, 0);
 
2664
                        BIF_undo_push("ESubdivide");
 
2665
                        break;
 
2666
                case 3:
 
2667
                        if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
 
2668
                        randfac= 10;
 
2669
                        if(button(&randfac, 1, 100, "Rand fac:")==0) return;
 
2670
                        waitcursor(1);                  
 
2671
                        fac= -( (float)randfac )/100;
 
2672
                        esubdivideflag(1, fac, G.scene->toolsettings->editbutflag, numcuts, 0);
 
2673
                        BIF_undo_push("Subdivide Fractal");
 
2674
                        break;
 
2675
                        
 
2676
                case 12:        /* smooth */
 
2677
                        /* if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return; */
 
2678
                        fac= 1.0f;
 
2679
                        if(fbutton(&fac, 0.0f, 5.0f, 10, 10, "Smooth:")==0) return;
 
2680
                                fac= 0.292f*fac;
 
2681
                        
 
2682
                        waitcursor(1);
 
2683
                        esubdivideflag(1, fac, G.scene->toolsettings->editbutflag | B_SMOOTH, 1, 0);
 
2684
                        BIF_undo_push("Subdivide Smooth");
 
2685
                        break;          
 
2686
 
 
2687
                case 4:
 
2688
                        mergemenu();
 
2689
                        break;
 
2690
                case 5:
 
2691
                        notice("Removed %d Vertices", removedoublesflag(1, 0, G.scene->toolsettings->doublimit));
 
2692
                        BIF_undo_push("Remove Doubles");
 
2693
                        break;
 
2694
                case 6:
 
2695
                        hide_mesh(0);
 
2696
                        break;
 
2697
                case 7:
 
2698
                        reveal_mesh();
 
2699
                        break;
 
2700
                case 8:
 
2701
                        selectswap_mesh();
 
2702
                        break;
 
2703
                case 9:
 
2704
                        flip_editnormals();
 
2705
                        BIF_undo_push("Flip Normals");
 
2706
                        break;
 
2707
                case 10:
 
2708
                        vertexsmooth();
 
2709
                        break;
 
2710
                case 11:
 
2711
                        bevel_menu();
 
2712
                        break;
 
2713
                case 14:
 
2714
                        mesh_set_smooth_faces(1);
 
2715
                        break;
 
2716
                case 15: 
 
2717
                        mesh_set_smooth_faces(0);
 
2718
                        break;
 
2719
                case 16: 
 
2720
                        shape_copy_select_from();
 
2721
                        break;
 
2722
                case 17: 
 
2723
                        shape_propagate();
 
2724
                        break;
 
2725
                case 18:
 
2726
                        pathselect();
 
2727
                        BIF_undo_push("Select Vertex Path");
 
2728
                        break;
 
2729
                }
 
2730
                
 
2731
                
 
2732
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
2733
                
 
2734
                if(nr>0) waitcursor(0);
 
2735
                
 
2736
        }
 
2737
        else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
 
2738
 
 
2739
                nr= pupmenu("Specials%t|Subdivide%x1|Switch Direction%x2|Set Goal Weight%x3|Set Radius%x4|Smooth%x5|Smooth Radius%x6");
 
2740
                
 
2741
                switch(nr) {
 
2742
                case 1:
 
2743
                        subdivideNurb();
 
2744
                        break;
 
2745
                case 2:
 
2746
                        switchdirectionNurb2();
 
2747
                        break;
 
2748
                case 3:
 
2749
                        setweightNurb();
 
2750
                        break;
 
2751
                case 4:
 
2752
                        setradiusNurb();
 
2753
                        break;
 
2754
                case 5:
 
2755
                        smoothNurb();
 
2756
                        break;
 
2757
                case 6:
 
2758
                        smoothradiusNurb();
 
2759
                        break;
 
2760
                }
 
2761
                DAG_object_flush_update(G.scene, G.obedit, OB_RECALC_DATA);
 
2762
        }
 
2763
        else if(G.obedit->type==OB_ARMATURE) {
 
2764
                nr= pupmenu("Specials%t|Subdivide %x1|Subdivide Multi%x2|Switch Direction%x7|Flip Left-Right Names%x3|%l|AutoName Left-Right%x4|AutoName Front-Back%x5|AutoName Top-Bottom%x6");
 
2765
                if(nr==1)
 
2766
                        subdivide_armature(1);
 
2767
                if(nr==2) {
 
2768
                        if(button(&numcuts, 1, 128, "Number of Cuts:")==0) return;
 
2769
                        waitcursor(1);
 
2770
                        subdivide_armature(numcuts);
 
2771
                }
 
2772
                else if(nr==3)
 
2773
                        armature_flip_names();
 
2774
                else if(ELEM3(nr, 4, 5, 6)) {
 
2775
                        armature_autoside_names(nr-4);
 
2776
                }
 
2777
                else if(nr == 7)
 
2778
                        switch_direction_armature();
 
2779
        }
 
2780
        else if(G.obedit->type==OB_LATTICE) {
 
2781
                static float weight= 1.0f;
 
2782
                if(fbutton(&weight, 0.0f, 1.0f, 10, 10, "Set Weight")) {
 
2783
                        int a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
 
2784
                        BPoint *bp= editLatt->def;
 
2785
                        
 
2786
                        while(a--) {
 
2787
                                if(bp->f1 & SELECT)
 
2788
                                        bp->weight= weight;
 
2789
                                bp++;
 
2790
                        }       
 
2791
                }
 
2792
        }
 
2793
 
 
2794
        countall();
 
2795
        allqueue(REDRAWVIEW3D, 0);
 
2796
        
 
2797
}
 
2798
 
 
2799
static void curvetomesh(Object *ob) 
 
2800
{
 
2801
        Curve *cu;
 
2802
        DispList *dl;
 
2803
        
 
2804
        ob->flag |= OB_DONE;
 
2805
        cu= ob->data;
 
2806
        
 
2807
        dl= cu->disp.first;
 
2808
        if(dl==0) makeDispListCurveTypes(ob, 0);                /* force creation */
 
2809
 
 
2810
        nurbs_to_mesh(ob); /* also does users */
 
2811
        if (ob->type != OB_MESH) {
 
2812
                error("can't convert curve to mesh");
 
2813
        } else {
 
2814
                object_free_modifiers(ob);
 
2815
        }
 
2816
}
 
2817
 
 
2818
void convertmenu(void)
 
2819
{
 
2820
        Base *base, *basen=NULL, *basact, *basedel=NULL;
 
2821
        Object *obact, *ob, *ob1;
 
2822
        Curve *cu;
 
2823
        Nurb *nu;
 
2824
        MetaBall *mb;
 
2825
        Mesh *me;
 
2826
        int ok=0, nr = 0, a;
 
2827
        
 
2828
        if(G.scene->id.lib) return;
 
2829
 
 
2830
        obact= OBACT;
 
2831
        if (obact == NULL) return;
 
2832
        if(!obact->flag & SELECT) return;
 
2833
        if(G.obedit) return;
 
2834
        
 
2835
        basact= BASACT; /* will be restored */
 
2836
                
 
2837
        if(obact->type==OB_FONT) {
 
2838
                nr= pupmenu("Convert Font to%t|Curve%x1|Curve (Single filling group)%x2|Mesh%x3");
 
2839
                if(nr>0) ok= 1;
 
2840
        }
 
2841
        else if(obact->type==OB_MBALL) {
 
2842
                nr= pupmenu("Convert Metaball to%t|Mesh (keep original)%x1|Mesh (Delete Original)%x2");
 
2843
                if(nr>0) ok= 1;
 
2844
        }
 
2845
        else if(obact->type==OB_CURVE) {
 
2846
                nr= pupmenu("Convert Curve to%t|Mesh");
 
2847
                if(nr>0) ok= 1;
 
2848
        }
 
2849
        else if(obact->type==OB_SURF) {
 
2850
                nr= pupmenu("Convert Nurbs Surface to%t|Mesh");
 
2851
                if(nr>0) ok= 1;
 
2852
        }
 
2853
        else if(obact->type==OB_MESH) {
 
2854
                nr= pupmenu("Convert Modifiers to%t|Mesh (Keep Original)%x1|Mesh (Delete Original)%x2");
 
2855
                if(nr>0) ok= 1;
 
2856
        }
 
2857
        if(ok==0) return;
 
2858
 
 
2859
        /* don't forget multiple users! */
 
2860
 
 
2861
        /* reset flags */
 
2862
        base= FIRSTBASE;
 
2863
        while(base) {
 
2864
                if TESTBASELIB(base) {
 
2865
                        base->object->flag &= ~OB_DONE;
 
2866
                }
 
2867
                base= base->next;
 
2868
        }
 
2869
 
 
2870
        base= FIRSTBASE;
 
2871
        while(base) {
 
2872
                if TESTBASELIB(base) {
 
2873
                        
 
2874
                        ob= base->object;
 
2875
                        
 
2876
                        if(ob->flag & OB_DONE);
 
2877
                        else if(ob->type==OB_MESH && ob->modifiers.first) { /* converting a mesh with no modifiers causes a segfault */
 
2878
                                DerivedMesh *dm;
 
2879
                                
 
2880
                                basedel = base;
 
2881
 
 
2882
                                ob->flag |= OB_DONE;
 
2883
 
 
2884
                                ob1= copy_object(ob);
 
2885
                                ob1->recalc |= OB_RECALC;
 
2886
 
 
2887
                                basen= MEM_mallocN(sizeof(Base), "duplibase");
 
2888
                                *basen= *base;
 
2889
                                BLI_addhead(&G.scene->base, basen);     /* addhead: otherwise eternal loop */
 
2890
                                basen->object= ob1;
 
2891
                                basen->flag |= SELECT;
 
2892
                                base->flag &= ~SELECT;
 
2893
                                ob->flag &= ~SELECT;
 
2894
 
 
2895
                                /* decrement original mesh's usage count  */
 
2896
                                me= ob1->data;
 
2897
                                me->id.us--;
 
2898
 
 
2899
                                /* make a new copy of the mesh */
 
2900
                                ob1->data= copy_mesh(me);
 
2901
                                G.totmesh++;
 
2902
 
 
2903
                                /* make new mesh data from the original copy */
 
2904
                                dm= mesh_get_derived_final(ob1, CD_MASK_MESH);
 
2905
                                /* dm= mesh_create_derived_no_deform(ob1, NULL);        this was called original (instead of get_derived). man o man why! (ton) */
 
2906
                                
 
2907
                                DM_to_mesh(dm, ob1->data);
 
2908
 
 
2909
                                dm->release(dm);
 
2910
                                object_free_modifiers(ob1);     /* after derivedmesh calls! */
 
2911
                                
 
2912
                                /* If the original object is active then make this object active */
 
2913
                                if (ob == obact) {
 
2914
                                        set_active_base( basen );
 
2915
                                        basact = basen;
 
2916
                                }
 
2917
                        }
 
2918
                        else if(ob->type==OB_FONT) {
 
2919
                                ob->flag |= OB_DONE;
 
2920
 
 
2921
                                ob->type= OB_CURVE;
 
2922
                                cu= ob->data;
 
2923
 
 
2924
                                if(cu->vfont) {
 
2925
                                        cu->vfont->id.us--;
 
2926
                                        cu->vfont= 0;
 
2927
                                }
 
2928
                                if(cu->vfontb) {
 
2929
                                        cu->vfontb->id.us--;
 
2930
                                        cu->vfontb= 0;
 
2931
                                }
 
2932
                                if(cu->vfonti) {
 
2933
                                        cu->vfonti->id.us--;
 
2934
                                        cu->vfonti= 0;
 
2935
                                }
 
2936
                                if(cu->vfontbi) {
 
2937
                                        cu->vfontbi->id.us--;
 
2938
                                        cu->vfontbi= 0;
 
2939
                                }                                       
 
2940
                                /* other users */
 
2941
                                if(cu->id.us>1) {
 
2942
                                        ob1= G.main->object.first;
 
2943
                                        while(ob1) {
 
2944
                                                if(ob1->data==cu) {
 
2945
                                                        ob1->type= OB_CURVE;
 
2946
                                                        ob1->recalc |= OB_RECALC;
 
2947
                                                }
 
2948
                                                ob1= ob1->id.next;
 
2949
                                        }
 
2950
                                }
 
2951
                                if (nr==2 || nr==3) {
 
2952
                                        nu= cu->nurb.first;
 
2953
                                        while(nu) {
 
2954
                                                nu->charidx= 0;
 
2955
                                                nu= nu->next;
 
2956
                                        }                                       
 
2957
                                }
 
2958
                                if (nr==3) {
 
2959
                                        curvetomesh(ob);
 
2960
                                }
 
2961
                        }
 
2962
                        else if ELEM(ob->type, OB_CURVE, OB_SURF) {
 
2963
                                if(nr==1) {
 
2964
                                        curvetomesh(ob);
 
2965
                                }
 
2966
                        }
 
2967
                        else if(ob->type==OB_MBALL) {
 
2968
                        
 
2969
                                if(nr==1 || nr == 2) {
 
2970
                                        ob= find_basis_mball(ob);
 
2971
                                        
 
2972
                                        if(ob->disp.first && !(ob->flag&OB_DONE)) {
 
2973
                                                basedel = base;
 
2974
                                        
 
2975
                                                ob->flag |= OB_DONE;
 
2976
 
 
2977
                                                ob1= copy_object(ob);
 
2978
                                                ob1->recalc |= OB_RECALC;
 
2979
 
 
2980
                                                basen= MEM_mallocN(sizeof(Base), "duplibase");
 
2981
                                                *basen= *base;
 
2982
                                                BLI_addhead(&G.scene->base, basen);     /* addhead: othwise eternal loop */
 
2983
                                                basen->object= ob1;
 
2984
                                                basen->flag |= SELECT;
 
2985
                                                basedel->flag &= ~SELECT;
 
2986
                                                ob->flag &= ~SELECT;
 
2987
                                                
 
2988
                                                mb= ob1->data;
 
2989
                                                mb->id.us--;
 
2990
                                                
 
2991
                                                ob1->data= add_mesh("Mesh");
 
2992
                                                G.totmesh++;
 
2993
                                                ob1->type= OB_MESH;
 
2994
                                                
 
2995
                                                me= ob1->data;
 
2996
                                                me->totcol= mb->totcol;
 
2997
                                                if(ob1->totcol) {
 
2998
                                                        me->mat= MEM_dupallocN(mb->mat);
 
2999
                                                        for(a=0; a<ob1->totcol; a++) id_us_plus((ID *)me->mat[a]);
 
3000
                                                }
 
3001
                                                
 
3002
                                                mball_to_mesh(&ob->disp, ob1->data);
 
3003
                                                
 
3004
                                                /* So we can see the wireframe */
 
3005
                                                BASACT= basen;
 
3006
                                                
 
3007
                                                /* If the original object is active then make this object active */
 
3008
                                                if (ob == obact) {
 
3009
                                                        set_active_base( basen );
 
3010
                                                        basact = basen;
 
3011
                                                }
 
3012
                                                
 
3013
                                        }
 
3014
                                }
 
3015
                        }
 
3016
                }
 
3017
                base= base->next;
 
3018
                if(basedel != NULL && nr == 2) {
 
3019
                        if(basedel==basact)
 
3020
                                basact= NULL;
 
3021
                        free_and_unlink_base(basedel);  
 
3022
                }
 
3023
                basedel = NULL;                         
 
3024
        }
 
3025
        
 
3026
        /* delete object should renew depsgraph */
 
3027
        if(nr==2)
 
3028
                DAG_scene_sort(G.scene);
 
3029
 
 
3030
        /* texspace and normals */
 
3031
        if(!basen) BASACT= base;
 
3032
 
 
3033
        enter_editmode(EM_WAITCURSOR);
 
3034
        exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
 
3035
        BASACT= basact;
 
3036
 
 
3037
        countall();
 
3038
        allqueue(REDRAWVIEW3D, 0);
 
3039
        allqueue(REDRAWOOPS, 0);
 
3040
        allspace(OOPS_TEST, 0);
 
3041
        allqueue(REDRAWBUTSEDIT, 0);
 
3042
        BIF_undo_push("Convert Object");
 
3043
 
 
3044
        DAG_scene_sort(G.scene);
 
3045
}
 
3046
 
 
3047
/* Change subdivision or particle properties of mesh object ob, if level==-1
 
3048
 * then toggle subsurf, else set to level set allows to toggle multiple
 
3049
 * selections */
 
3050
 
 
3051
static void object_has_subdivision_particles(Object *ob, int *havesubdiv, int *havepart, int depth)
 
3052
{
 
3053
        if(ob->type==OB_MESH) {
 
3054
                if(modifiers_findByType(ob, eModifierType_Subsurf))
 
3055
                        *havesubdiv= 1;
 
3056
                if(modifiers_findByType(ob, eModifierType_ParticleSystem))
 
3057
                        *havepart= 1;
 
3058
        }
 
3059
 
 
3060
        if(ob->dup_group && depth <= 4) {
 
3061
                GroupObject *go;
 
3062
 
 
3063
                for(go= ob->dup_group->gobject.first; go; go= go->next)
 
3064
                        object_has_subdivision_particles(go->ob, havesubdiv, havepart, depth+1);
 
3065
        }
 
3066
}
 
3067
 
 
3068
static void object_flip_subdivison_particles(Object *ob, int *set, int level, int mode, int particles, int depth)
 
3069
{
 
3070
        ModifierData *md;
 
3071
 
 
3072
        if(ob->type==OB_MESH) {
 
3073
                if(particles) {
 
3074
                        for(md=ob->modifiers.first; md; md=md->next) {
 
3075
                                if(md->type == eModifierType_ParticleSystem) {
 
3076
                                        ParticleSystemModifierData *psmd = (ParticleSystemModifierData*)md;
 
3077
 
 
3078
                                        if(*set == -1)
 
3079
                                                *set= psmd->modifier.mode&(mode);
 
3080
 
 
3081
                                        if (*set)
 
3082
                                                psmd->modifier.mode &= ~(mode);
 
3083
                                        else
 
3084
                                                psmd->modifier.mode |= (mode);
 
3085
                                }
 
3086
                        }
 
3087
                }
 
3088
                else {
 
3089
                        md = modifiers_findByType(ob, eModifierType_Subsurf);
 
3090
 
 
3091
                        if (md) {
 
3092
                                SubsurfModifierData *smd = (SubsurfModifierData*) md;
 
3093
 
 
3094
                                if (level == -1) {
 
3095
                                        if(*set == -1) 
 
3096
                                                *set= smd->modifier.mode&(mode);
 
3097
 
 
3098
                                        if (*set)
 
3099
                                                smd->modifier.mode &= ~(mode);
 
3100
                                        else
 
3101
                                                smd->modifier.mode |= (mode);
 
3102
                                } else {
 
3103
                                        smd->levels = level;
 
3104
                                }
 
3105
                        } 
 
3106
                        else if(depth == 0 && *set != 0) {
 
3107
                                SubsurfModifierData *smd = (SubsurfModifierData*) modifier_new(eModifierType_Subsurf);
 
3108
 
 
3109
                                BLI_addtail(&ob->modifiers, smd);
 
3110
 
 
3111
                                if (level!=-1) {
 
3112
                                        smd->levels = level;
 
3113
                                }
 
3114
                                
 
3115
                                if(*set == -1)
 
3116
                                        *set= 1;
 
3117
                        }
 
3118
                }
 
3119
 
 
3120
                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
3121
        }
 
3122
 
 
3123
        if(ob->dup_group && depth<=4) {
 
3124
                GroupObject *go;
 
3125
 
 
3126
                for(go= ob->dup_group->gobject.first; go; go= go->next)
 
3127
                        object_flip_subdivison_particles(go->ob, set, level, mode, particles, depth+1);
 
3128
        }
 
3129
}
 
3130
 
 
3131
/* Change subdivision properties of mesh object ob, if
 
3132
* level==-1 then toggle subsurf, else set to level.
 
3133
*/
 
3134
 
 
3135
void flip_subdivison(int level)
 
3136
{
 
3137
        Base *base;
 
3138
        int set= -1;
 
3139
        int mode, pupmode, particles= 0, havesubdiv= 0, havepart= 0;
 
3140
        
 
3141
        if(G.qual & LR_ALTKEY)
 
3142
                mode= eModifierMode_Realtime;
 
3143
        else
 
3144
                mode= eModifierMode_Render|eModifierMode_Realtime;
 
3145
        
 
3146
        if(level == -1) {
 
3147
                if (G.obedit) {
 
3148
                        object_has_subdivision_particles(G.obedit, &havesubdiv, &havepart, 0);                  
 
3149
                } else {
 
3150
                        for(base= G.scene->base.first; base; base= base->next) {
 
3151
                                if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base))) {
 
3152
                                        object_has_subdivision_particles(base->object, &havesubdiv, &havepart, 0);
 
3153
                                }
 
3154
                        }
 
3155
                }
 
3156
        }
 
3157
        else
 
3158
                havesubdiv= 1;
 
3159
        
 
3160
        if(havesubdiv && havepart) {
 
3161
                pupmode= pupmenu("Switch%t|Subsurf %x1|Particle Systems %x2");
 
3162
                if(pupmode <= 0)
 
3163
                        return;
 
3164
                else if(pupmode == 2)
 
3165
                        particles= 1;
 
3166
        }
 
3167
        else if(havepart)
 
3168
                particles= 1;
 
3169
 
 
3170
        if (G.obedit) { 
 
3171
                object_flip_subdivison_particles(G.obedit, &set, level, mode, particles, 0);
 
3172
        } else {
 
3173
                for(base= G.scene->base.first; base; base= base->next) {
 
3174
                        if(((level==-1) && (TESTBASE(base))) || (TESTBASELIB(base))) {
 
3175
                                object_flip_subdivison_particles(base->object, &set, level, mode, particles, 0);
 
3176
                        }
 
3177
                }
 
3178
        }
 
3179
        
 
3180
        countall();
 
3181
        allqueue(REDRAWVIEW3D, 0);
 
3182
        allqueue(REDRAWOOPS, 0);
 
3183
        allqueue(REDRAWBUTSEDIT, 0);
 
3184
        allqueue(REDRAWBUTSOBJECT, 0);
 
3185
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
3186
        
 
3187
        if(particles)
 
3188
                BIF_undo_push("Switch particles on/off");
 
3189
        else
 
3190
                BIF_undo_push("Switch subsurf on/off");
 
3191
}
 
3192
 
 
3193
static void copymenu_properties(Object *ob)
 
3194
{       
 
3195
        bProperty *prop;
 
3196
        Base *base;
 
3197
        int nr, tot=0;
 
3198
        char *str;
 
3199
        
 
3200
        prop= ob->prop.first;
 
3201
        while(prop) {
 
3202
                tot++;
 
3203
                prop= prop->next;
 
3204
        }
 
3205
        
 
3206
        if(tot==0) {
 
3207
                error("No properties in the active object to copy");
 
3208
                return;
 
3209
        }
 
3210
        
 
3211
        str= MEM_callocN(50 + 33*tot, "copymenu prop");
 
3212
        
 
3213
        strcpy(str, "Copy Property %t|Replace All|Merge All|%l");
 
3214
        
 
3215
        tot= 0; 
 
3216
        prop= ob->prop.first;
 
3217
        while(prop) {
 
3218
                tot++;
 
3219
                strcat(str, "|");
 
3220
                strcat(str, prop->name);
 
3221
                prop= prop->next;
 
3222
        }
 
3223
 
 
3224
        nr= pupmenu(str);
 
3225
        
 
3226
        if ( nr==1 || nr==2 ) {
 
3227
                base= FIRSTBASE;
 
3228
                while(base) {
 
3229
                        if((base != BASACT) && TESTBASELIB(base)) {
 
3230
                                if (nr==1) { /* replace */
 
3231
                                        copy_properties( &base->object->prop, &ob->prop );
 
3232
                                } else {
 
3233
                                        for(prop = ob->prop.first; prop; prop= prop->next ) {
 
3234
                                                set_ob_property(base->object, prop);
 
3235
                                        }
 
3236
                                }
 
3237
                        }
 
3238
                        base= base->next;
 
3239
                }
 
3240
        } else if(nr>0) {
 
3241
                prop = BLI_findlink(&ob->prop, nr-4); /* account for first 3 menu items & menu index starting at 1*/
 
3242
                
 
3243
                if(prop) {
 
3244
                        for(base= FIRSTBASE; base; base= base->next) {
 
3245
                                if((base != BASACT) && TESTBASELIB(base)) {
 
3246
                                        set_ob_property(base->object, prop);
 
3247
                                }
 
3248
                        }
 
3249
                }
 
3250
        }
 
3251
        MEM_freeN(str);
 
3252
        allqueue(REDRAWVIEW3D, 0);
 
3253
        
 
3254
        BIF_undo_push("Copy properties");
 
3255
}
 
3256
 
 
3257
static void copymenu_logicbricks(Object *ob)
 
3258
{
 
3259
        Base *base;
 
3260
        
 
3261
        base= FIRSTBASE;
 
3262
        while(base) {
 
3263
                if(base->object != ob) {
 
3264
                        if(TESTBASELIB(base)) {
 
3265
                                
 
3266
                                /* first: free all logic */
 
3267
                                free_sensors(&base->object->sensors);                           
 
3268
                                unlink_controllers(&base->object->controllers);
 
3269
                                free_controllers(&base->object->controllers);
 
3270
                                unlink_actuators(&base->object->actuators);
 
3271
                                free_actuators(&base->object->actuators);
 
3272
                                
 
3273
                                /* now copy it, this also works without logicbricks! */
 
3274
                                clear_sca_new_poins_ob(ob);
 
3275
                                copy_sensors(&base->object->sensors, &ob->sensors);
 
3276
                                copy_controllers(&base->object->controllers, &ob->controllers);
 
3277
                                copy_actuators(&base->object->actuators, &ob->actuators);
 
3278
                                set_sca_new_poins_ob(base->object);
 
3279
                                
 
3280
                                /* some menu settings */
 
3281
                                base->object->scavisflag= ob->scavisflag;
 
3282
                                base->object->scaflag= ob->scaflag;
 
3283
                                
 
3284
                                /* set the initial state */
 
3285
                                base->object->state= ob->state;
 
3286
                                base->object->init_state= ob->init_state;
 
3287
                        }
 
3288
                }
 
3289
                base= base->next;
 
3290
        }
 
3291
        BIF_undo_push("Copy logic");
 
3292
}
 
3293
 
 
3294
static void copymenu_modifiers(Object *ob)
 
3295
{
 
3296
        Base *base;
 
3297
        int i, event;
 
3298
        char str[512];
 
3299
        char *errorstr= NULL;
 
3300
 
 
3301
        strcpy(str, "Copy Modifiers %t");
 
3302
 
 
3303
        sprintf(str+strlen(str), "|All%%x%d|%%l", NUM_MODIFIER_TYPES);
 
3304
 
 
3305
        for (i=eModifierType_None+1; i<NUM_MODIFIER_TYPES; i++) {
 
3306
                ModifierTypeInfo *mti = modifierType_getInfo(i);
 
3307
 
 
3308
                if(ELEM3(i, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue;
 
3309
                
 
3310
                if(i == eModifierType_Collision)
 
3311
                        continue;
 
3312
 
 
3313
                if (    (mti->flags&eModifierTypeFlag_AcceptsCVs) || 
 
3314
                                (ob->type==OB_MESH && (mti->flags&eModifierTypeFlag_AcceptsMesh))) {
 
3315
                        sprintf(str+strlen(str), "|%s%%x%d", mti->name, i);
 
3316
                }
 
3317
        }
 
3318
 
 
3319
        event = pupmenu(str);
 
3320
        if(event<=0) return;
 
3321
 
 
3322
        for (base= FIRSTBASE; base; base= base->next) {
 
3323
                if(base->object != ob) {
 
3324
                        if(TESTBASELIB(base)) {
 
3325
                                ModifierData *md;
 
3326
 
 
3327
                                base->object->recalc |= OB_RECALC_OB|OB_RECALC_DATA;
 
3328
 
 
3329
                                if (base->object->type==ob->type) {
 
3330
                                        /* copy all */
 
3331
                                        if (event==NUM_MODIFIER_TYPES) {
 
3332
                                                object_free_modifiers(base->object);
 
3333
 
 
3334
                                                for (md=ob->modifiers.first; md; md=md->next) {
 
3335
                                                        ModifierData *nmd = NULL;
 
3336
                                                        
 
3337
                                                        if(ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_ParticleInstance)) continue;
 
3338
                
 
3339
                                                        if(md->type == eModifierType_Collision)
 
3340
                                                                continue;
 
3341
                                                        
 
3342
                                                        nmd = modifier_new(md->type);
 
3343
                                                        modifier_copyData(md, nmd);
 
3344
                                                        BLI_addtail(&base->object->modifiers, nmd);
 
3345
                                                }
 
3346
 
 
3347
                                                copy_object_particlesystems(base->object, ob);
 
3348
                                                copy_object_softbody(base->object, ob);
 
3349
                                        } else {
 
3350
                                                /* copy specific types */
 
3351
                                                ModifierData *md, *mdn;
 
3352
                                                
 
3353
                                                /* remove all with type 'event' */
 
3354
                                                for (md=base->object->modifiers.first; md; md=mdn) {
 
3355
                                                        mdn= md->next;
 
3356
                                                        if(md->type==event) {
 
3357
                                                                BLI_remlink(&base->object->modifiers, md);
 
3358
                                                                modifier_free(md);
 
3359
                                                        }
 
3360
                                                }
 
3361
                                                
 
3362
                                                /* copy all with type 'event' */
 
3363
                                                for (md=ob->modifiers.first; md; md=md->next) {
 
3364
                                                        if (md->type==event) {
 
3365
                                                                
 
3366
                                                                mdn = modifier_new(event);
 
3367
                                                                BLI_addtail(&base->object->modifiers, mdn);
 
3368
 
 
3369
                                                                modifier_copyData(md, mdn);
 
3370
                                                        }
 
3371
                                                }
 
3372
 
 
3373
                                                if(event == eModifierType_ParticleSystem) {
 
3374
                                                        object_free_particlesystems(base->object);
 
3375
                                                        copy_object_particlesystems(base->object, ob);
 
3376
                                                }
 
3377
                                                else if(event == eModifierType_Softbody) {
 
3378
                                                        object_free_softbody(base->object);
 
3379
                                                        copy_object_softbody(base->object, ob);
 
3380
                                                }
 
3381
                                        }
 
3382
                                }
 
3383
                                else
 
3384
                                        errorstr= "Did not copy modifiers to other Object types";
 
3385
                        }
 
3386
                }
 
3387
        }
 
3388
        
 
3389
        if(errorstr) notice(errorstr);
 
3390
        
 
3391
        allqueue(REDRAWVIEW3D, 0);
 
3392
        allqueue(REDRAWBUTSOBJECT, 0);
 
3393
        DAG_scene_sort(G.scene);
 
3394
        
 
3395
        BIF_undo_push("Copy modifiers");
 
3396
}
 
3397
 
 
3398
/* both pointers should exist */
 
3399
static void copy_texture_space(Object *to, Object *ob)
 
3400
{
 
3401
        float *poin1= NULL, *poin2= NULL;
 
3402
        int texflag= 0;
 
3403
        
 
3404
        if(ob->type==OB_MESH) {
 
3405
                texflag= ((Mesh *)ob->data)->texflag;
 
3406
                poin2= ((Mesh *)ob->data)->loc;
 
3407
        }
 
3408
        else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
 
3409
                texflag= ((Curve *)ob->data)->texflag;
 
3410
                poin2= ((Curve *)ob->data)->loc;
 
3411
        }
 
3412
        else if(ob->type==OB_MBALL) {
 
3413
                texflag= ((MetaBall *)ob->data)->texflag;
 
3414
                poin2= ((MetaBall *)ob->data)->loc;
 
3415
        }
 
3416
        else
 
3417
                return;
 
3418
                
 
3419
        if(to->type==OB_MESH) {
 
3420
                ((Mesh *)to->data)->texflag= texflag;
 
3421
                poin1= ((Mesh *)to->data)->loc;
 
3422
        }
 
3423
        else if (ELEM3(to->type, OB_CURVE, OB_SURF, OB_FONT)) {
 
3424
                ((Curve *)to->data)->texflag= texflag;
 
3425
                poin1= ((Curve *)to->data)->loc;
 
3426
        }
 
3427
        else if(to->type==OB_MBALL) {
 
3428
                ((MetaBall *)to->data)->texflag= texflag;
 
3429
                poin1= ((MetaBall *)to->data)->loc;
 
3430
        }
 
3431
        else
 
3432
                return;
 
3433
        
 
3434
        memcpy(poin1, poin2, 9*sizeof(float));  /* this was noted in DNA_mesh, curve, mball */
 
3435
        
 
3436
        if(to->type==OB_MESH) ;
 
3437
        else if(to->type==OB_MBALL) tex_space_mball(to);
 
3438
        else tex_space_curve(to->data);
 
3439
        
 
3440
}
 
3441
 
 
3442
void copy_attr(short event)
 
3443
{
 
3444
        Object *ob;
 
3445
        Base *base;
 
3446
        Curve *cu, *cu1;
 
3447
        Nurb *nu;
 
3448
        int do_scene_sort= 0;
 
3449
        
 
3450
        if(G.scene->id.lib) return;
 
3451
 
 
3452
        if(!(ob=OBACT)) return;
 
3453
        
 
3454
        if(G.obedit) {
 
3455
                /* obedit_copymenu(); */
 
3456
                return;
 
3457
        }
 
3458
        if(event==9) {
 
3459
                copymenu_properties(ob);
 
3460
                return;
 
3461
        }
 
3462
        else if(event==10) {
 
3463
                copymenu_logicbricks(ob);
 
3464
                return;
 
3465
        }
 
3466
        else if(event==24) {
 
3467
                copymenu_modifiers(ob);
 
3468
                return;
 
3469
        }
 
3470
 
 
3471
        base= FIRSTBASE;
 
3472
        while(base) {
 
3473
                if(base != BASACT) {
 
3474
                        if(TESTBASELIB(base)) {
 
3475
                                base->object->recalc |= OB_RECALC_OB;
 
3476
                                
 
3477
                                if(event==1) {  /* loc */
 
3478
                                        VECCOPY(base->object->loc, ob->loc);
 
3479
                                        VECCOPY(base->object->dloc, ob->dloc);
 
3480
                                }
 
3481
                                else if(event==2) {  /* rot */
 
3482
                                        VECCOPY(base->object->rot, ob->rot);
 
3483
                                        VECCOPY(base->object->drot, ob->drot);
 
3484
                                        /* Quats arnt used yet */
 
3485
                                        /*VECCOPY(base->object->quat, ob->quat);
 
3486
                                        VECCOPY(base->object->dquat, ob->dquat);*/
 
3487
                                }
 
3488
                                else if(event==3) {  /* size */
 
3489
                                        VECCOPY(base->object->size, ob->size);
 
3490
                                        VECCOPY(base->object->dsize, ob->dsize);
 
3491
                                }
 
3492
                                else if(event==4) {  /* drawtype */
 
3493
                                        base->object->dt= ob->dt;
 
3494
                                        base->object->dtx= ob->dtx;
 
3495
                                        base->object->empty_drawtype= ob->empty_drawtype;
 
3496
                                        base->object->empty_drawsize= ob->empty_drawsize;
 
3497
                                }
 
3498
                                else if(event==5) {  /* time offs */
 
3499
                                        base->object->sf= ob->sf;
 
3500
                                }
 
3501
                                else if(event==6) {  /* dupli */
 
3502
                                        base->object->dupon= ob->dupon;
 
3503
                                        base->object->dupoff= ob->dupoff;
 
3504
                                        base->object->dupsta= ob->dupsta;
 
3505
                                        base->object->dupend= ob->dupend;
 
3506
                                        
 
3507
                                        base->object->transflag &= ~OB_DUPLI;
 
3508
                                        base->object->transflag |= (ob->transflag & OB_DUPLI);
 
3509
 
 
3510
                                        base->object->dup_group= ob->dup_group;
 
3511
                                        if(ob->dup_group)
 
3512
                                                id_us_plus((ID *)ob->dup_group);
 
3513
                                }
 
3514
                                else if(event==7) {     /* mass */
 
3515
                                        base->object->mass= ob->mass;
 
3516
                                }
 
3517
                                else if(event==8) {     /* damping */
 
3518
                                        base->object->damping= ob->damping;
 
3519
                                        base->object->rdamping= ob->rdamping;
 
3520
                                }
 
3521
                                else if(event==11) {    /* all physical attributes */
 
3522
                                        base->object->gameflag = ob->gameflag;
 
3523
                                        base->object->inertia = ob->inertia;
 
3524
                                        base->object->formfactor = ob->formfactor;
 
3525
                                        base->object->damping= ob->damping;
 
3526
                                        base->object->rdamping= ob->rdamping;
 
3527
                                        base->object->mass= ob->mass;
 
3528
                                        if (ob->gameflag & OB_BOUNDS) {
 
3529
                                                base->object->boundtype = ob->boundtype;
 
3530
                                        }
 
3531
                                        base->object->margin= ob->margin;
 
3532
                                        base->object->bsoft= copy_bulletsoftbody(ob->bsoft);
 
3533
 
 
3534
                                }
 
3535
                                else if(event==17) {    /* tex space */
 
3536
                                        copy_texture_space(base->object, ob);
 
3537
                                }
 
3538
                                else if(event==18) {    /* font settings */
 
3539
                                        
 
3540
                                        if(base->object->type==ob->type) {
 
3541
                                                cu= ob->data;
 
3542
                                                cu1= base->object->data;
 
3543
                                                
 
3544
                                                cu1->spacemode= cu->spacemode;
 
3545
                                                cu1->spacing= cu->spacing;
 
3546
                                                cu1->linedist= cu->linedist;
 
3547
                                                cu1->shear= cu->shear;
 
3548
                                                cu1->fsize= cu->fsize;
 
3549
                                                cu1->xof= cu->xof;
 
3550
                                                cu1->yof= cu->yof;
 
3551
                                                cu1->textoncurve= cu->textoncurve;
 
3552
                                                cu1->wordspace= cu->wordspace;
 
3553
                                                cu1->ulpos= cu->ulpos;
 
3554
                                                cu1->ulheight= cu->ulheight;
 
3555
                                                if(cu1->vfont) cu1->vfont->id.us--;
 
3556
                                                cu1->vfont= cu->vfont;
 
3557
                                                id_us_plus((ID *)cu1->vfont);
 
3558
                                                if(cu1->vfontb) cu1->vfontb->id.us--;
 
3559
                                                cu1->vfontb= cu->vfontb;
 
3560
                                                id_us_plus((ID *)cu1->vfontb);
 
3561
                                                if(cu1->vfonti) cu1->vfonti->id.us--;
 
3562
                                                cu1->vfonti= cu->vfonti;
 
3563
                                                id_us_plus((ID *)cu1->vfonti);
 
3564
                                                if(cu1->vfontbi) cu1->vfontbi->id.us--;
 
3565
                                                cu1->vfontbi= cu->vfontbi;
 
3566
                                                id_us_plus((ID *)cu1->vfontbi);                                         
 
3567
 
 
3568
                                                text_to_curve(base->object, 0);         /* needed? */
 
3569
 
 
3570
                                                
 
3571
                                                strcpy(cu1->family, cu->family);
 
3572
                                                
 
3573
                                                base->object->recalc |= OB_RECALC_DATA;
 
3574
                                        }
 
3575
                                }
 
3576
                                else if(event==19) {    /* bevel settings */
 
3577
                                        
 
3578
                                        if ELEM(base->object->type, OB_CURVE, OB_FONT) {
 
3579
                                                cu= ob->data;
 
3580
                                                cu1= base->object->data;
 
3581
                                                
 
3582
                                                cu1->bevobj= cu->bevobj;
 
3583
                                                cu1->taperobj= cu->taperobj;
 
3584
                                                cu1->width= cu->width;
 
3585
                                                cu1->bevresol= cu->bevresol;
 
3586
                                                cu1->ext1= cu->ext1;
 
3587
                                                cu1->ext2= cu->ext2;
 
3588
                                                
 
3589
                                                base->object->recalc |= OB_RECALC_DATA;
 
3590
                                        }
 
3591
                                }
 
3592
                                else if(event==25) {    /* curve resolution */
 
3593
 
 
3594
                                        if ELEM(base->object->type, OB_CURVE, OB_FONT) {
 
3595
                                                cu= ob->data;
 
3596
                                                cu1= base->object->data;
 
3597
                                                
 
3598
                                                cu1->resolu= cu->resolu;
 
3599
                                                cu1->resolu_ren= cu->resolu_ren;
 
3600
                                                
 
3601
                                                nu= cu1->nurb.first;
 
3602
                                                
 
3603
                                                while(nu) {
 
3604
                                                        nu->resolu= cu1->resolu;
 
3605
                                                        nu= nu->next;
 
3606
                                                }
 
3607
                                                
 
3608
                                                base->object->recalc |= OB_RECALC_DATA;
 
3609
                                        }
 
3610
                                }
 
3611
                                else if(event==21){
 
3612
                                        if (base->object->type==OB_MESH) {
 
3613
                                                ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf);
 
3614
 
 
3615
                                                if (md) {
 
3616
                                                        ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf);
 
3617
 
 
3618
                                                        if (!tmd) {
 
3619
                                                                tmd = modifier_new(eModifierType_Subsurf);
 
3620
                                                                BLI_addtail(&base->object->modifiers, tmd);
 
3621
                                                        }
 
3622
 
 
3623
                                                        modifier_copyData(md, tmd);
 
3624
                                                        base->object->recalc |= OB_RECALC_DATA;
 
3625
                                                }
 
3626
                                        }
 
3627
                                }
 
3628
                                else if(event==22) {
 
3629
                                        /* Copy the constraint channels over */
 
3630
                                        copy_constraints(&base->object->constraints, &ob->constraints);
 
3631
                                        if (U.dupflag& USER_DUP_IPO)
 
3632
                                                copy_constraint_channels(&base->object->constraintChannels, &ob->constraintChannels);
 
3633
                                        else
 
3634
                                                clone_constraint_channels (&base->object->constraintChannels, &ob->constraintChannels);
 
3635
                                        
 
3636
                                        do_scene_sort= 1;
 
3637
                                }
 
3638
                                else if(event==23) {
 
3639
                                        base->object->softflag= ob->softflag;
 
3640
                                        if(base->object->soft) sbFree(base->object->soft);
 
3641
                                        
 
3642
                                        base->object->soft= copy_softbody(ob->soft);
 
3643
 
 
3644
                                        if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
 
3645
                                                BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
 
3646
                                        }
 
3647
                                }
 
3648
                                else if(event==26) {
 
3649
                                        copy_nlastrips(&base->object->nlastrips, &ob->nlastrips);
 
3650
                                }
 
3651
                                else if(event==27) {    /* autosmooth */
 
3652
                                        if (base->object->type==OB_MESH) {
 
3653
                                                Mesh *me= ob->data;
 
3654
                                                Mesh *cme= base->object->data;
 
3655
                                                cme->smoothresh= me->smoothresh;
 
3656
                                                if(me->flag & ME_AUTOSMOOTH)
 
3657
                                                        cme->flag |= ME_AUTOSMOOTH;
 
3658
                                                else
 
3659
                                                        cme->flag &= ~ME_AUTOSMOOTH;
 
3660
                                        }
 
3661
                                }
 
3662
                                else if(event==28) { /* UV orco */
 
3663
                                        if ELEM(base->object->type, OB_CURVE, OB_SURF) {
 
3664
                                                cu= ob->data;
 
3665
                                                cu1= base->object->data;
 
3666
                                                
 
3667
                                                if(cu->flag & CU_UV_ORCO)
 
3668
                                                        cu1->flag |= CU_UV_ORCO;
 
3669
                                                else
 
3670
                                                        cu1->flag &= ~CU_UV_ORCO;
 
3671
                                        }               
 
3672
                                }
 
3673
                                else if(event==29) { /* protected bits */
 
3674
                                        base->object->protectflag= ob->protectflag;
 
3675
                                }
 
3676
                                else if(event==30) { /* index object */
 
3677
                                        base->object->index= ob->index;
 
3678
                                }
 
3679
                                else if(event==31) { /* object color */
 
3680
                                        QUATCOPY(base->object->col, ob->col);
 
3681
                                }
 
3682
                        }
 
3683
                }
 
3684
                base= base->next;
 
3685
        }
 
3686
        
 
3687
        allqueue(REDRAWVIEW3D, 0);
 
3688
        if(do_scene_sort)
 
3689
                DAG_scene_sort(G.scene);
 
3690
 
 
3691
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
3692
 
 
3693
        if(event==20) {
 
3694
                allqueue(REDRAWBUTSOBJECT, 0);
 
3695
        }
 
3696
        
 
3697
        BIF_undo_push("Copy Attributes");
 
3698
}
 
3699
 
 
3700
void copy_attr_menu()
 
3701
{
 
3702
        Object *ob;
 
3703
        short event;
 
3704
        char str[512];
 
3705
        
 
3706
        if(!(ob=OBACT)) return;
 
3707
        
 
3708
        if (G.obedit) {
 
3709
                if (ob->type == OB_MESH)
 
3710
                        mesh_copy_menu();
 
3711
                return;
 
3712
        }
 
3713
        
 
3714
        /* Object Mode */
 
3715
        
 
3716
        /* If you change this menu, don't forget to update the menu in header_view3d.c
 
3717
         * view3d_edit_object_copyattrmenu() and in toolbox.c
 
3718
         */
 
3719
        
 
3720
        strcpy(str, "Copy Attributes %t|Location%x1|Rotation%x2|Size%x3|Draw Options%x4|Time Offset%x5|Dupli%x6|Object Color%x31|%l|Mass%x7|Damping%x8|All Physical Attributes%x11|Properties%x9|Logic Bricks%x10|Protected Transform%x29|%l");
 
3721
        
 
3722
        strcat (str, "|Object Constraints%x22");
 
3723
        strcat (str, "|NLA Strips%x26");
 
3724
        
 
3725
        if (OB_SUPPORT_MATERIAL(ob)) {
 
3726
                strcat(str, "|Texture Space%x17");
 
3727
        }       
 
3728
        
 
3729
        if(ob->type == OB_FONT) strcat(str, "|Font Settings%x18|Bevel Settings%x19");
 
3730
        if(ob->type == OB_CURVE) strcat(str, "|Bevel Settings%x19|UV Orco%x28");
 
3731
        
 
3732
        if((ob->type == OB_FONT) || (ob->type == OB_CURVE)) {
 
3733
                        strcat(str, "|Curve Resolution%x25");
 
3734
        }
 
3735
 
 
3736
        if(ob->type==OB_MESH){
 
3737
                strcat(str, "|Subsurf Settings%x21|AutoSmooth%x27");
 
3738
        }
 
3739
 
 
3740
        if(ob->soft) strcat(str, "|Soft Body Settings%x23");
 
3741
        
 
3742
        strcat(str, "|Pass Index%x30");
 
3743
        
 
3744
        if(ob->type==OB_MESH || ob->type==OB_CURVE || ob->type==OB_LATTICE || ob->type==OB_SURF){
 
3745
                strcat(str, "|Modifiers ...%x24");
 
3746
        }
 
3747
 
 
3748
        event= pupmenu(str);
 
3749
        if(event<= 0) return;
 
3750
        
 
3751
        copy_attr(event);
 
3752
}
 
3753
 
 
3754
 
 
3755
void link_to_scene(unsigned short nr)
 
3756
{       
 
3757
        Scene *sce= (Scene*) BLI_findlink(&G.main->scene, G.curscreen->scenenr-1);
 
3758
        Base *base, *nbase;
 
3759
        
 
3760
        if(sce==0) return;
 
3761
        if(sce->id.lib) return;
 
3762
        
 
3763
        base= FIRSTBASE;
 
3764
        while(base) {
 
3765
                if(TESTBASE(base)) {
 
3766
                        
 
3767
                        nbase= MEM_mallocN( sizeof(Base), "newbase");
 
3768
                        *nbase= *base;
 
3769
                        BLI_addhead( &(sce->base), nbase);
 
3770
                        id_us_plus((ID *)base->object);
 
3771
                }
 
3772
                base= base->next;
 
3773
        }
 
3774
}
 
3775
 
 
3776
void make_links_menu()
 
3777
{
 
3778
        Object *ob;
 
3779
        short event=0;
 
3780
        char str[140];
 
3781
        
 
3782
        if(!(ob=OBACT)) return;
 
3783
        
 
3784
        strcpy(str, "Make Links %t|To Scene...%x1|%l|Object Ipo%x4");
 
3785
        
 
3786
        if(ob->type==OB_MESH)
 
3787
                strcat(str, "|Mesh Data%x2|Materials%x3");
 
3788
        else if(ob->type==OB_CURVE)
 
3789
                strcat(str, "|Curve Data%x2|Materials%x3");
 
3790
        else if(ob->type==OB_FONT)
 
3791
                strcat(str, "|Text Data%x2|Materials%x3");
 
3792
        else if(ob->type==OB_SURF)
 
3793
                strcat(str, "|Surface Data%x2|Materials%x3");
 
3794
        else if(ob->type==OB_MBALL)
 
3795
                strcat(str, "|Materials%x3");
 
3796
        else if(ob->type==OB_CAMERA)
 
3797
                strcat(str, "|Camera Data%x2");
 
3798
        else if(ob->type==OB_LAMP)
 
3799
                strcat(str, "|Lamp Data%x2");
 
3800
        else if(ob->type==OB_LATTICE)
 
3801
                strcat(str, "|Lattice Data%x2");
 
3802
        else if(ob->type==OB_ARMATURE)
 
3803
                strcat(str, "|Armature Data%x2");
 
3804
        
 
3805
        event= pupmenu(str);
 
3806
 
 
3807
        if(event<= 0) return;
 
3808
        
 
3809
        make_links(event);
 
3810
}
 
3811
 
 
3812
void make_links(short event)
 
3813
{
 
3814
        Object *ob, *obt;
 
3815
        Base *base, *nbase, *sbase;
 
3816
        Scene *sce = NULL;
 
3817
        ID *id;
 
3818
        int a;
 
3819
        short nr=0;
 
3820
        char *strp;
 
3821
 
 
3822
        if(!(ob=OBACT)) return;
 
3823
 
 
3824
        if(event==1) {
 
3825
                IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), 0, &nr);
 
3826
                
 
3827
                if(nr == -2) {
 
3828
                        MEM_freeN(strp);
 
3829
 
 
3830
                        activate_databrowse((ID *)G.scene, ID_SCE, 0, B_INFOSCE, &(G.curscreen->scenenr), link_to_scene );
 
3831
                        
 
3832
                        return;                 
 
3833
                }
 
3834
                else {
 
3835
                        event= pupmenu_col(strp, 20);
 
3836
                        MEM_freeN(strp);
 
3837
                
 
3838
                        if(event<= 0) return;
 
3839
                
 
3840
                        nr= 1;
 
3841
                        sce= G.main->scene.first;
 
3842
                        while(sce) {
 
3843
                                if(nr==event) break;
 
3844
                                nr++;
 
3845
                                sce= sce->id.next;
 
3846
                        }
 
3847
                        if(sce==G.scene) {
 
3848
                                error("This is the current scene");
 
3849
                                return;
 
3850
                        }
 
3851
                        if(sce==0 || sce->id.lib) return;
 
3852
                        
 
3853
                        /* remember: is needed below */
 
3854
                        event= 1;
 
3855
                }
 
3856
        }
 
3857
 
 
3858
        /* All non group linking */
 
3859
        base= FIRSTBASE;
 
3860
        while(base) {
 
3861
                if(event==1 || base != BASACT) {
 
3862
                        
 
3863
                        obt= base->object;
 
3864
 
 
3865
                        if(TESTBASE(base)) {
 
3866
                                
 
3867
                                if(event==1) {          /* to scene */
 
3868
                                        
 
3869
                                        /* test if already linked */
 
3870
                                        sbase= sce->base.first;
 
3871
                                        while(sbase) {
 
3872
                                                if(sbase->object==base->object) break;
 
3873
                                                sbase= sbase->next;
 
3874
                                        }
 
3875
                                        if(sbase) {     /* remove */
 
3876
                                                base= base->next;
 
3877
                                                continue;
 
3878
                                        }
 
3879
                                        
 
3880
                                        nbase= MEM_mallocN( sizeof(Base), "newbase");
 
3881
                                        *nbase= *base;
 
3882
                                        BLI_addhead( &(sce->base), nbase);
 
3883
                                        id_us_plus((ID *)base->object);
 
3884
                                }
 
3885
                        }
 
3886
                        if(TESTBASELIB(base)) {
 
3887
                                if(event==2 || event==5) {  /* obdata */
 
3888
                                        if(ob->type==obt->type) {
 
3889
                                                
 
3890
                                                        id= obt->data;
 
3891
                                                        id->us--;
 
3892
                                                        
 
3893
                                                        id= ob->data;
 
3894
                                                        id_us_plus(id);
 
3895
                                                        obt->data= id;
 
3896
                                                        
 
3897
                                                        /* if amount of material indices changed: */
 
3898
                                                        test_object_materials(obt->data);
 
3899
 
 
3900
                                                        obt->recalc |= OB_RECALC_DATA;
 
3901
                                                }
 
3902
                                        }
 
3903
                                else if(event==4) {  /* ob ipo */
 
3904
                                        if(obt->ipo) obt->ipo->id.us--;
 
3905
                                        obt->ipo= ob->ipo;
 
3906
                                        if(obt->ipo) {
 
3907
                                                id_us_plus((ID *)obt->ipo);
 
3908
                                                do_ob_ipo(obt);
 
3909
                                        }
 
3910
                                }
 
3911
                                else if(event==6) {
 
3912
                                        if(ob->dup_group) ob->dup_group->id.us--;
 
3913
                                        obt->dup_group= ob->dup_group;
 
3914
                                        if(obt->dup_group) {
 
3915
                                                id_us_plus((ID *)obt->dup_group);
 
3916
                                                obt->transflag |= OB_DUPLIGROUP;
 
3917
                                        }
 
3918
                                }
 
3919
                                else if(event==3) {  /* materials */
 
3920
                                        
 
3921
                                        /* new approach, using functions from kernel */
 
3922
                                        for(a=0; a<ob->totcol; a++) {
 
3923
                                                Material *ma= give_current_material(ob, a+1);
 
3924
                                                assign_material(obt, ma, a+1);  /* also works with ma==NULL */
 
3925
                                        }
 
3926
                                }
 
3927
                        }
 
3928
                }
 
3929
                base= base->next;
 
3930
        }
 
3931
        
 
3932
        allqueue(REDRAWVIEW3D, 0);
 
3933
        allqueue(REDRAWOOPS, 0);
 
3934
        allqueue(REDRAWBUTSHEAD, 0);
 
3935
 
 
3936
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
3937
 
 
3938
        BIF_undo_push("Create links");
 
3939
}
 
3940
 
 
3941
static void apply_objects_internal( int apply_scale, int apply_rot )
 
3942
{
 
3943
        Base *base, *basact;
 
3944
        Object *ob;
 
3945
        bArmature *arm;
 
3946
        Mesh *me;
 
3947
        Curve *cu;
 
3948
        Nurb *nu;
 
3949
        BPoint *bp;
 
3950
        BezTriple *bezt;
 
3951
        MVert *mvert;
 
3952
        float mat[3][3];
 
3953
        int a, change = 0;
 
3954
        
 
3955
        if (!apply_scale && !apply_rot) {
 
3956
                /* do nothing? */
 
3957
                error("Nothing to do!");
 
3958
                return;
 
3959
        }
 
3960
        /* first check if we can execute */
 
3961
        for (base= FIRSTBASE; base; base= base->next) {
 
3962
                if TESTBASELIB(base) {
 
3963
                        ob= base->object;
 
3964
                        if(ob->type==OB_MESH) {
 
3965
                                me= ob->data;
 
3966
                                
 
3967
                                if(me->id.us>1) {
 
3968
                                        error("Can't apply to a multi user mesh, doing nothing.");
 
3969
                                        return;
 
3970
                                }
 
3971
                                if(me->key) {
 
3972
                                        error("Can't apply to a mesh with vertex keys, doing nothing.");
 
3973
                                        return;
 
3974
                                }
 
3975
                        }
 
3976
                        else if (ob->type==OB_ARMATURE) {
 
3977
                                arm= ob->data;
 
3978
                                
 
3979
                                if(arm->id.us>1) {
 
3980
                                        error("Can't apply to a multi user armature, doing nothing.");
 
3981
                                        return;
 
3982
                                }
 
3983
                        }
 
3984
                        else if ELEM(ob->type, OB_CURVE, OB_SURF) {
 
3985
                                cu= ob->data;
 
3986
                                
 
3987
                                if(cu->id.us>1) {
 
3988
                                        error("Can't apply to a multi user curve, doing nothing.");
 
3989
                                        return;
 
3990
                                }
 
3991
                                if(cu->key) {
 
3992
                                        error("Can't apply to a curve with vertex keys, doing nothing.");
 
3993
                                        return;
 
3994
                                }
 
3995
                        }
 
3996
                }
 
3997
        }
 
3998
        
 
3999
        /* now execute */
 
4000
        basact= BASACT;
 
4001
        base= FIRSTBASE;
 
4002
        for (base= FIRSTBASE; base; base= base->next) {
 
4003
                if TESTBASELIB(base) {
 
4004
                        ob= base->object;
 
4005
                        
 
4006
                        if(ob->type==OB_MESH) {
 
4007
                                if (apply_scale && apply_rot)
 
4008
                                        object_to_mat3(ob, mat);
 
4009
                                else if (apply_scale)
 
4010
                                        object_scale_to_mat3(ob, mat);
 
4011
                                else
 
4012
                                        object_rot_to_mat3(ob, mat);
 
4013
 
 
4014
                                me= ob->data;
 
4015
                                
 
4016
                                /* see checks above */
 
4017
                                
 
4018
                                mvert= me->mvert;
 
4019
                                for(a=0; a<me->totvert; a++, mvert++) {
 
4020
                                        Mat3MulVecfl(mat, mvert->co);
 
4021
                                }
 
4022
                                if (apply_scale)
 
4023
                                        ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
 
4024
                                if (apply_rot)
 
4025
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
 
4026
                                /*QuatOne(ob->quat);*/ /* Quats arnt used yet */
 
4027
                                
 
4028
                                where_is_object(ob);
 
4029
                                
 
4030
                                /* texspace and normals */
 
4031
                                BASACT= base;
 
4032
                                enter_editmode(EM_WAITCURSOR);
 
4033
                                BIF_undo_push("Applied object");        /* editmode undo itself */
 
4034
                                exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
 
4035
                                BASACT= basact;
 
4036
                                
 
4037
                                change = 1;
 
4038
                        }
 
4039
                        else if (ob->type==OB_ARMATURE) {
 
4040
                                if (apply_scale && apply_rot)
 
4041
                                        object_to_mat3(ob, mat);
 
4042
                                else if (apply_scale)
 
4043
                                        object_scale_to_mat3(ob, mat);
 
4044
                                else
 
4045
                                        object_rot_to_mat3(ob, mat);
 
4046
                                arm= ob->data;
 
4047
                                
 
4048
                                /* see checks above */
 
4049
                                apply_rot_armature(ob, mat);
 
4050
                                
 
4051
                                /* Reset the object's transforms */
 
4052
                                if (apply_scale)
 
4053
                                        ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
 
4054
                                if (apply_rot)
 
4055
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
 
4056
                                /*QuatOne(ob->quat); (not used anymore)*/
 
4057
                                
 
4058
                                where_is_object(ob);
 
4059
                                
 
4060
                                change = 1;
 
4061
                        }
 
4062
                        else if ELEM(ob->type, OB_CURVE, OB_SURF) {
 
4063
                                float scale;
 
4064
                                if (apply_scale && apply_rot)
 
4065
                                        object_to_mat3(ob, mat);
 
4066
                                else if (apply_scale)
 
4067
                                        object_scale_to_mat3(ob, mat);
 
4068
                                else
 
4069
                                        object_rot_to_mat3(ob, mat);
 
4070
                                scale = Mat3ToScalef(mat);
 
4071
                                cu= ob->data;
 
4072
                                
 
4073
                                /* see checks above */
 
4074
                                
 
4075
                                nu= cu->nurb.first;
 
4076
                                while(nu) {
 
4077
                                        if( (nu->type & 7)==1) {
 
4078
                                                a= nu->pntsu;
 
4079
                                                bezt= nu->bezt;
 
4080
                                                while(a--) {
 
4081
                                                        Mat3MulVecfl(mat, bezt->vec[0]);
 
4082
                                                        Mat3MulVecfl(mat, bezt->vec[1]);
 
4083
                                                        Mat3MulVecfl(mat, bezt->vec[2]);
 
4084
                                                        bezt->radius *= scale;
 
4085
                                                        bezt++;
 
4086
                                                }
 
4087
                                        }
 
4088
                                        else {
 
4089
                                                a= nu->pntsu*nu->pntsv;
 
4090
                                                bp= nu->bp;
 
4091
                                                while(a--) {
 
4092
                                                        Mat3MulVecfl(mat, bp->vec);
 
4093
                                                        bp++;
 
4094
                                                }
 
4095
                                        }
 
4096
                                        nu= nu->next;
 
4097
                                }
 
4098
                                if (apply_scale)
 
4099
                                        ob->size[0]= ob->size[1]= ob->size[2]= 1.0;
 
4100
                                if (apply_rot)
 
4101
                                        ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0;
 
4102
                                /*QuatOne(ob->quat); (quats arnt used anymore)*/
 
4103
                                
 
4104
                                where_is_object(ob);
 
4105
                                
 
4106
                                /* texspace and normals */
 
4107
                                BASACT= base;
 
4108
                                enter_editmode(EM_WAITCURSOR);
 
4109
                                BIF_undo_push("Applied object");        /* editmode undo itself */
 
4110
                                exit_editmode(EM_FREEDATA|EM_WAITCURSOR); /* freedata, but no undo */
 
4111
                                BASACT= basact;
 
4112
                                
 
4113
                                change = 1;
 
4114
                        } else {
 
4115
                                continue;
 
4116
                        }
 
4117
                        
 
4118
                        ignore_parent_tx(ob);
 
4119
                }
 
4120
        }
 
4121
        if (change) {
 
4122
                allqueue(REDRAWVIEW3D, 0);
 
4123
                if (apply_scale && apply_rot)
 
4124
                        BIF_undo_push("Apply Objects Scale & Rotation");
 
4125
                else if (apply_scale)
 
4126
                        BIF_undo_push("Apply Objects Scale");
 
4127
                else
 
4128
                        BIF_undo_push("Apply Objects Rotation");
 
4129
        }
 
4130
}
 
4131
 
 
4132
void apply_objects_locrot(void)
 
4133
{
 
4134
        apply_objects_internal(1, 1);
 
4135
}
 
4136
 
 
4137
void apply_objects_scale(void)
 
4138
{
 
4139
        apply_objects_internal(1, 0);
 
4140
}
 
4141
 
 
4142
void apply_objects_rot(void)
 
4143
{
 
4144
        apply_objects_internal(0, 1);
 
4145
}
 
4146
 
 
4147
void apply_objects_visual_tx( void )
 
4148
{
 
4149
        Base *base;
 
4150
        Object *ob;
 
4151
        int change = 0;
 
4152
        
 
4153
        for (base= FIRSTBASE; base; base= base->next) {
 
4154
                if TESTBASELIB(base) {
 
4155
                        ob= base->object;
 
4156
                        where_is_object(ob);
 
4157
                        VECCOPY(ob->loc, ob->obmat[3]);
 
4158
                        Mat4ToSize(ob->obmat, ob->size);
 
4159
                        Mat4ToEul(ob->obmat, ob->rot);
 
4160
                        
 
4161
                        where_is_object(ob);
 
4162
                        
 
4163
                        change = 1;
 
4164
                }
 
4165
        }
 
4166
        if (change) {
 
4167
                allqueue(REDRAWVIEW3D, 0);
 
4168
                BIF_undo_push("Apply Objects Visual Transform");
 
4169
        }
 
4170
}
 
4171
 
 
4172
void apply_object( void )
 
4173
{
 
4174
        Object *ob;
 
4175
        int evt;
 
4176
        if(G.scene->id.lib) return;
 
4177
        if(G.obedit) return;
 
4178
        
 
4179
        if(G.qual & LR_SHIFTKEY) {
 
4180
                ob= OBACT;
 
4181
                if(ob==0) return;
 
4182
                
 
4183
                if(ob->transflag & OB_DUPLI) {
 
4184
                        make_duplilist_real();
 
4185
                }
 
4186
                else {
 
4187
                        if(okee("Apply deformation")) {
 
4188
                                object_apply_deform(ob);
 
4189
                                BIF_undo_push("Apply deformation");
 
4190
                        }
 
4191
                }
 
4192
                allqueue(REDRAWVIEW3D, 0);
 
4193
                
 
4194
        } 
 
4195
        else {
 
4196
                ob= OBACT;
 
4197
                if(ob==0) return;
 
4198
                
 
4199
                if ((ob->pose) && (ob->flag & OB_POSEMODE))
 
4200
                        evt = pupmenu("Apply Object%t|Current Pose as RestPose%x3");
 
4201
                else
 
4202
                        evt = pupmenu("Apply Object%t|Scale and Rotation to ObData%x1|Visual Transform to Objects Loc/Scale/Rot%x2|Scale to ObData%x4|Rotation to ObData%x5");
 
4203
                if (evt==-1) return;
 
4204
                
 
4205
                switch (evt) {
 
4206
                        case 1:
 
4207
                                apply_objects_locrot();
 
4208
                                break;
 
4209
                        case 2:
 
4210
                                apply_objects_visual_tx();
 
4211
                                break;
 
4212
                        case 3:
 
4213
                                apply_armature_pose2bones();
 
4214
                                break;
 
4215
                        case 4:
 
4216
                                apply_objects_scale();
 
4217
                                break;
 
4218
                        case 5:
 
4219
                                apply_objects_rot();
 
4220
                                break;
 
4221
                }
 
4222
        }
 
4223
}
 
4224
 
 
4225
 
 
4226
 
 
4227
/* ************ GENERAL  *************** */
 
4228
 
 
4229
 
 
4230
/* now only used in 2d spaces, like ipo, nla, sima... */
 
4231
void apply_keyb_grid(float *val, float fac1, float fac2, float fac3, int invert)
 
4232
{
 
4233
        /* fac1 is for 'nothing', fac2 for CTRL, fac3 for SHIFT */
 
4234
        int ctrl;
 
4235
 
 
4236
        if(invert) {
 
4237
                if(G.qual & LR_CTRLKEY) ctrl= 0;
 
4238
                else ctrl= 1;
 
4239
        }
 
4240
        else ctrl= (G.qual & LR_CTRLKEY);
 
4241
 
 
4242
        if(ctrl && (G.qual & LR_SHIFTKEY)) {
 
4243
                if(fac3!= 0.0) *val= fac3*floor(*val/fac3 +.5);
 
4244
        }
 
4245
        else if(ctrl) {
 
4246
                if(fac2!= 0.0) *val= fac2*floor(*val/fac2 +.5);
 
4247
        }
 
4248
        else {
 
4249
                if(fac1!= 0.0) *val= fac1*floor(*val/fac1 +.5);
 
4250
        }
 
4251
}
 
4252
 
 
4253
int cylinder_intersect_test(void)
 
4254
{
 
4255
        EditMesh *em = G.editMesh;
 
4256
        float *oldloc, speed[3], s, t, labda, labdacor, dist, len, len2, axis[3], *base, rc[3], n[3], o[3];
 
4257
        EditVert *v1;
 
4258
        
 
4259
        v1= em->verts.first;
 
4260
 
 
4261
        base= v1->co;
 
4262
        v1= v1->next;
 
4263
        VecSubf(axis, v1->co, base);
 
4264
        
 
4265
        v1= v1->next;
 
4266
        oldloc= v1->co;
 
4267
        v1= v1->next;
 
4268
        VecSubf(speed, v1->co, oldloc);
 
4269
        
 
4270
        VecSubf(rc, oldloc, base);
 
4271
        
 
4272
        /* the axis */
 
4273
        len2= Normalize(axis);
 
4274
        
 
4275
        Crossf(n, speed, axis);
 
4276
        len= Normalize(n);
 
4277
        if(len==0.0) return 0;
 
4278
        
 
4279
        dist= fabs( rc[0]*n[0] + rc[1]*n[1] + rc[2]*n[2] );
 
4280
        
 
4281
        if( dist>=G.scene->editbutsize ) return 0;
 
4282
        
 
4283
        Crossf(o, rc, axis);
 
4284
        t= -(o[0]*n[0] + o[1]*n[1] + o[2]*n[2])/len;
 
4285
        
 
4286
        Crossf(o, n, axis);
 
4287
        s=  fabs(sqrt(G.scene->editbutsize*G.scene->editbutsize-dist*dist) / (o[0]*speed[0] + o[1]*speed[1] + o[2]*speed[2]));
 
4288
        
 
4289
        labdacor= t-s;
 
4290
        labda= t+s;
 
4291
 
 
4292
        /* two cases with no intersection point */
 
4293
        if(labdacor>=1.0 && labda>=1.0) return 0;
 
4294
        if(labdacor<=0.0 && labda<=0.0) return 0;
 
4295
        
 
4296
        /* calc normal */
 
4297
        /* intersection: */
 
4298
        
 
4299
        rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
 
4300
        rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
 
4301
        rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
 
4302
        
 
4303
        s= (rc[0]*axis[0] + rc[1]*axis[1] + rc[2]*axis[2]) ;
 
4304
        
 
4305
        if(s<0.0 || s>len2) return 0;
 
4306
        
 
4307
        n[0]= (rc[0] - s*axis[0]);
 
4308
        n[1]= (rc[1] - s*axis[1]);
 
4309
        n[2]= (rc[2] - s*axis[2]);
 
4310
 
 
4311
        printf("var1: %f, var2: %f, var3: %f\n", labdacor, len2, s);    
 
4312
        printf("var1: %f, var2: %f, var3: %f\n", rc[0], rc[1], rc[2]);  
 
4313
        printf("var1: %f, var2: %f, var3: %f\n", n[0], n[1], n[2]);     
 
4314
 
 
4315
        return 1;
 
4316
}
 
4317
 
 
4318
int sphere_intersect_test(void)
 
4319
{
 
4320
        EditMesh *em = G.editMesh;
 
4321
        float *oldloc, speed[3], labda, labdacor, len, bsq, u, disc, *base, rc[3];
 
4322
        EditVert *v1;
 
4323
        
 
4324
        v1= em->verts.first;
 
4325
        base= v1->co;
 
4326
        
 
4327
        v1= v1->next;
 
4328
        oldloc= v1->co;
 
4329
        
 
4330
        v1= v1->next;
 
4331
        VecSubf(speed, v1->co, oldloc);
 
4332
        len= Normalize(speed);
 
4333
        if(len==0.0) return 0;
 
4334
        
 
4335
        VecSubf(rc, oldloc, base);
 
4336
        bsq= rc[0]*speed[0] + rc[1]*speed[1] + rc[2]*speed[2]; 
 
4337
        u= rc[0]*rc[0] + rc[1]*rc[1] + rc[2]*rc[2] - G.scene->editbutsize*G.scene->editbutsize;
 
4338
 
 
4339
        disc= bsq*bsq - u;
 
4340
        
 
4341
        if(disc>=0.0) {
 
4342
                disc= sqrt(disc);
 
4343
                labdacor= (-bsq - disc)/len;    /* entry point */
 
4344
                labda= (-bsq + disc)/len;
 
4345
                
 
4346
                printf("var1: %f, var2: %f, var3: %f\n", labdacor, labda, G.scene->editbutsize);
 
4347
        }
 
4348
        else return 0;
 
4349
 
 
4350
        /* intersection and normal */
 
4351
        rc[0]= oldloc[0] + labdacor*speed[0] - base[0];
 
4352
        rc[1]= oldloc[1] + labdacor*speed[1] - base[1];
 
4353
        rc[2]= oldloc[2] + labdacor*speed[2] - base[2];
 
4354
 
 
4355
 
 
4356
        return 1;
 
4357
}
 
4358
 
 
4359
 
 
4360
void std_rmouse_transform(void (*xf_func)(int, int))
 
4361
{
 
4362
        short mval[2];
 
4363
        short xo, yo;
 
4364
        short timer=0;
 
4365
        short mousebut;
 
4366
        short context = (U.flag & USER_DRAGIMMEDIATE)?CTX_TWEAK:CTX_NONE;
 
4367
        
 
4368
        /* check for left mouse select/right mouse select */
 
4369
        
 
4370
        if(curarea->spacetype==SPACE_NODE)
 
4371
                mousebut = L_MOUSE|R_MOUSE;
 
4372
        else if (U.flag & USER_LMOUSESELECT) 
 
4373
                mousebut = L_MOUSE;
 
4374
        else 
 
4375
                mousebut = R_MOUSE;
 
4376
        
 
4377
        getmouseco_areawin(mval);
 
4378
        xo= mval[0]; 
 
4379
        yo= mval[1];
 
4380
         
 
4381
        while(get_mbut() & mousebut) {
 
4382
                getmouseco_areawin(mval);
 
4383
                if(abs(mval[0]-xo)+abs(mval[1]-yo) > 10) {
 
4384
                        if(curarea->spacetype==SPACE_VIEW3D) {
 
4385
                                initTransform(TFM_TRANSLATION, context);
 
4386
                                Transform();
 
4387
                        }
 
4388
                        else if(curarea->spacetype==SPACE_IMAGE) {
 
4389
                                initTransform(TFM_TRANSLATION, context);
 
4390
                                Transform();
 
4391
                        }
 
4392
                        else if(xf_func)
 
4393
                                xf_func('g', 0);
 
4394
 
 
4395
                        while(get_mbut() & mousebut) BIF_wait_for_statechange();
 
4396
                        return;
 
4397
                }
 
4398
                else {
 
4399
                        PIL_sleep_ms(10);
 
4400
                        timer++;
 
4401
                        if(timer>=10*U.tb_rightmouse) {
 
4402
                                if(curarea->spacetype==SPACE_VIEW3D) {
 
4403
                                        toolbox_n();
 
4404
                                        return;
 
4405
                                }
 
4406
                        }
 
4407
                }
 
4408
        }
 
4409
        /* if gets here it's a select */
 
4410
        BIF_undo_push("Select");
 
4411
}
 
4412
 
 
4413
void rightmouse_transform(void)
 
4414
{
 
4415
        std_rmouse_transform(NULL);
 
4416
}
 
4417
 
 
4418
 
 
4419
/* ************************************** */
 
4420
 
 
4421
 
 
4422
static void single_object_users__forwardModifierLinks(void *userData, Object *ob, Object **obpoin)
 
4423
{
 
4424
        ID_NEW(*obpoin);
 
4425
}
 
4426
void single_object_users(int flag)      
 
4427
{
 
4428
        Base *base;
 
4429
        Object *ob, *obn;
 
4430
        
 
4431
        clear_sca_new_poins();  /* sensor/contr/act */
 
4432
 
 
4433
        /* duplicate (must set newid) */
 
4434
        base= FIRSTBASE;
 
4435
        while(base) {
 
4436
                ob= base->object;
 
4437
                
 
4438
                if( (base->flag & flag)==flag ) {
 
4439
                        if(ob->id.lib==NULL && ob->id.us>1) {
 
4440
                                /* base gets copy of object */
 
4441
                                obn= copy_object(ob);
 
4442
                                base->object= obn;
 
4443
                                ob->id.us--;
 
4444
                        }
 
4445
                }
 
4446
                base= base->next;
 
4447
        }
 
4448
        
 
4449
        ID_NEW(G.scene->camera);
 
4450
        if(G.vd) ID_NEW(G.vd->camera);
 
4451
        
 
4452
        /* object pointers */
 
4453
        base= FIRSTBASE;
 
4454
        while(base) {
 
4455
                ob= base->object;
 
4456
                if(ob->id.lib==NULL) {
 
4457
                        relink_constraints(&base->object->constraints);
 
4458
                        if (base->object->pose){
 
4459
                                bPoseChannel *chan;
 
4460
                                for (chan = base->object->pose->chanbase.first; chan; chan=chan->next){
 
4461
                                        relink_constraints(&chan->constraints);
 
4462
                                }
 
4463
                        }
 
4464
                        modifiers_foreachObjectLink(base->object, single_object_users__forwardModifierLinks, NULL);
 
4465
                        
 
4466
                        ID_NEW(ob->parent);
 
4467
                        ID_NEW(ob->track);
 
4468
                }
 
4469
                base= base->next;
 
4470
        }
 
4471
 
 
4472
        set_sca_new_poins();
 
4473
}
 
4474
 
 
4475
void new_id_matar(Material **matar, int totcol)
 
4476
{
 
4477
        ID *id;
 
4478
        int a;
 
4479
        
 
4480
        for(a=0; a<totcol; a++) {
 
4481
                id= (ID *)matar[a];
 
4482
                if(id && id->lib==0) {
 
4483
                        if(id->newid) {
 
4484
                                matar[a]= (Material *)id->newid;
 
4485
                                id_us_plus(id->newid);
 
4486
                                id->us--;
 
4487
                        }
 
4488
                        else if(id->us>1) {
 
4489
                                matar[a]= copy_material(matar[a]);
 
4490
                                id->us--;
 
4491
                                id->newid= (ID *)matar[a];
 
4492
                        }
 
4493
                }
 
4494
        }
 
4495
}
 
4496
 
 
4497
void single_obdata_users(int flag)
 
4498
{
 
4499
        Object *ob;
 
4500
        Lamp *la;
 
4501
        Curve *cu;
 
4502
        Camera *cam;
 
4503
        Base *base;
 
4504
        Mesh *me;
 
4505
        ID *id;
 
4506
        int a;
 
4507
 
 
4508
#ifdef WITH_VERSE
 
4509
        base= FIRSTBASE;
 
4510
        while(base) {
 
4511
                ob= base->object;
 
4512
                if(ob->vnode) {
 
4513
                        error("Can't make data single user, when data are shared at verse server");
 
4514
                        return;
 
4515
                }
 
4516
                base = base->next;
 
4517
        }
 
4518
#endif
 
4519
 
 
4520
        base= FIRSTBASE;
 
4521
        while(base) {
 
4522
                ob= base->object;
 
4523
                if(ob->id.lib==NULL && (base->flag & flag)==flag ) {
 
4524
                        id= ob->data;
 
4525
                        
 
4526
                        if(id && id->us>1 && id->lib==0) {
 
4527
                                ob->recalc= OB_RECALC_DATA;
 
4528
                                
 
4529
                                switch(ob->type) {
 
4530
                                case OB_LAMP:
 
4531
                                        if(id && id->us>1 && id->lib==NULL) {
 
4532
                                                ob->data= la= copy_lamp(ob->data);
 
4533
                                                for(a=0; a<MAX_MTEX; a++) {
 
4534
                                                        if(la->mtex[a]) {
 
4535
                                                                ID_NEW(la->mtex[a]->object);
 
4536
                                                        }
 
4537
                                                }
 
4538
                                        }
 
4539
                                        break;
 
4540
                                case OB_CAMERA:
 
4541
                                        ob->data= copy_camera(ob->data);
 
4542
                                        break;
 
4543
                                case OB_MESH:
 
4544
                                        me= ob->data= copy_mesh(ob->data);
 
4545
                                        if(me && me->key)
 
4546
                                                ipo_idnew(me->key->ipo);        /* drivers */
 
4547
                                        break;
 
4548
                                case OB_MBALL:
 
4549
                                        ob->data= copy_mball(ob->data);
 
4550
                                        break;
 
4551
                                case OB_CURVE:
 
4552
                                case OB_SURF:
 
4553
                                case OB_FONT:
 
4554
                                        ob->data= cu= copy_curve(ob->data);
 
4555
                                        ID_NEW(cu->bevobj);
 
4556
                                        ID_NEW(cu->taperobj);
 
4557
                                        break;
 
4558
                                case OB_LATTICE:
 
4559
                                        ob->data= copy_lattice(ob->data);
 
4560
                                        break;
 
4561
                                case OB_ARMATURE:
 
4562
                                        ob->recalc |= OB_RECALC_DATA;
 
4563
                                        ob->data= copy_armature(ob->data);
 
4564
                                        armature_rebuild_pose(ob, ob->data);
 
4565
                                        break;
 
4566
                                default:
 
4567
                                        printf("ERROR single_obdata_users: %s\n", id->name);
 
4568
                                        error("Read console");
 
4569
                                        return;
 
4570
                                }
 
4571
                                
 
4572
                                id->us--;
 
4573
                                id->newid= ob->data;
 
4574
                                
 
4575
                        }
 
4576
                        
 
4577
                        id= (ID *)ob->action;
 
4578
                        if (id && id->us>1 && id->lib==NULL){
 
4579
                                if(id->newid){
 
4580
                                        ob->action= (bAction *)id->newid;
 
4581
                                        id_us_plus(id->newid);
 
4582
                                }
 
4583
                                else {
 
4584
                                        ob->action= copy_action(ob->action);
 
4585
                                        id->us--;
 
4586
                                        id->newid=(ID *)ob->action;
 
4587
                                }
 
4588
                        }
 
4589
                        id= (ID *)ob->ipo;
 
4590
                        if(id && id->us>1 && id->lib==NULL) {
 
4591
                                if(id->newid) {
 
4592
                                        ob->ipo= (Ipo *)id->newid;
 
4593
                                        id_us_plus(id->newid);
 
4594
                                }
 
4595
                                else {
 
4596
                                        ob->ipo= copy_ipo(ob->ipo);
 
4597
                                        id->us--;
 
4598
                                        id->newid= (ID *)ob->ipo;
 
4599
                                }
 
4600
                                ipo_idnew(ob->ipo);     /* drivers */
 
4601
                        }
 
4602
                        /* other ipos */
 
4603
                        switch(ob->type) {
 
4604
                        case OB_LAMP:
 
4605
                                la= ob->data;
 
4606
                                if(la->ipo && la->ipo->id.us>1) {
 
4607
                                        la->ipo->id.us--;
 
4608
                                        la->ipo= copy_ipo(la->ipo);
 
4609
                                        ipo_idnew(la->ipo);     /* drivers */
 
4610
                                }
 
4611
                                break;
 
4612
                        case OB_CAMERA:
 
4613
                                cam= ob->data;
 
4614
                                if(cam->ipo && cam->ipo->id.us>1) {
 
4615
                                        cam->ipo->id.us--;
 
4616
                                        cam->ipo= copy_ipo(cam->ipo);
 
4617
                                        ipo_idnew(cam->ipo);    /* drivers */
 
4618
                                }
 
4619
                                break;
 
4620
                        }
 
4621
                        
 
4622
                }
 
4623
                base= base->next;
 
4624
        }
 
4625
        
 
4626
        me= G.main->mesh.first;
 
4627
        while(me) {
 
4628
                ID_NEW(me->texcomesh);
 
4629
                me= me->id.next;
 
4630
        }
 
4631
}
 
4632
 
 
4633
void single_ipo_users(int flag)
 
4634
{
 
4635
        Object *ob;
 
4636
        Base *base;
 
4637
        ID *id;
 
4638
        
 
4639
        base= FIRSTBASE;
 
4640
        while(base) {
 
4641
                ob= base->object;
 
4642
                if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) {
 
4643
                        ob->recalc= OB_RECALC_DATA;
 
4644
                        
 
4645
                        id= (ID *)ob->ipo;
 
4646
                        if(id && id->us>1 && id->lib==NULL) {
 
4647
                                ob->ipo= copy_ipo(ob->ipo);
 
4648
                                id->us--;
 
4649
                                ipo_idnew(ob->ipo);     /* drivers */
 
4650
                        }
 
4651
                }
 
4652
                base= base->next;
 
4653
        }
 
4654
}
 
4655
 
 
4656
void single_mat_users(int flag)
 
4657
{
 
4658
        Object *ob;
 
4659
        Base *base;
 
4660
        Material *ma, *man;
 
4661
        Tex *tex;
 
4662
        int a, b;
 
4663
        
 
4664
        
 
4665
        base= FIRSTBASE;
 
4666
        while(base) {
 
4667
                ob= base->object;
 
4668
                if(ob->id.lib==NULL && (flag==0 || (base->flag & SELECT)) ) {
 
4669
        
 
4670
                        for(a=1; a<=ob->totcol; a++) {
 
4671
                                ma= give_current_material(ob, a);
 
4672
                                if(ma) {
 
4673
                                        /* do not test for LIB_NEW: this functions guaranteed delivers single_users! */
 
4674
                                        
 
4675
                                        if(ma->id.us>1) {
 
4676
                                                man= copy_material(ma);
 
4677
                                        
 
4678
                                                man->id.us= 0;
 
4679
                                                assign_material(ob, man, a);
 
4680
                                                
 
4681
                                                if(ma->ipo) {
 
4682
                                                        man->ipo= copy_ipo(ma->ipo);
 
4683
                                                        ma->ipo->id.us--;
 
4684
                                                        ipo_idnew(ma->ipo);     /* drivers */
 
4685
                                                }
 
4686
                                                
 
4687
                                                for(b=0; b<MAX_MTEX; b++) {
 
4688
                                                        if(ma->mtex[b] && ma->mtex[b]->tex) {
 
4689
                                                                tex= ma->mtex[b]->tex;
 
4690
                                                                if(tex->id.us>1) {
 
4691
                                                                        ma->mtex[b]->tex= copy_texture(tex);
 
4692
                                                                        tex->id.us--;
 
4693
                                                                }
 
4694
                                                        }
 
4695
                                                }
 
4696
                                                
 
4697
                                        }
 
4698
                                }
 
4699
                        }
 
4700
                }
 
4701
                base= base->next;
 
4702
        }
 
4703
}
 
4704
 
 
4705
void do_single_tex_user(Tex **from)
 
4706
{
 
4707
        Tex *tex, *texn;
 
4708
        
 
4709
        tex= *from;
 
4710
        if(tex==0) return;
 
4711
        
 
4712
        if(tex->id.newid) {
 
4713
                *from= (Tex *)tex->id.newid;
 
4714
                id_us_plus(tex->id.newid);
 
4715
                tex->id.us--;
 
4716
        }
 
4717
        else if(tex->id.us>1) {
 
4718
                texn= copy_texture(tex);
 
4719
                tex->id.newid= (ID *)texn;
 
4720
                tex->id.us--;
 
4721
                *from= texn;
 
4722
        }
 
4723
        
 
4724
}
 
4725
 
 
4726
void single_tex_users_expand()
 
4727
{
 
4728
        /* only when 'parent' blocks are LIB_NEW */
 
4729
        Material *ma;
 
4730
        Lamp *la;
 
4731
        World *wo;
 
4732
        int b;
 
4733
                
 
4734
        ma= G.main->mat.first;
 
4735
        while(ma) {
 
4736
                if(ma->id.flag & LIB_NEW) {
 
4737
                        for(b=0; b<MAX_MTEX; b++) {
 
4738
                                if(ma->mtex[b] && ma->mtex[b]->tex) {
 
4739
                                        do_single_tex_user( &(ma->mtex[b]->tex) );
 
4740
                                }
 
4741
                        }
 
4742
                }
 
4743
                ma= ma->id.next;
 
4744
        }
 
4745
 
 
4746
        la= G.main->lamp.first;
 
4747
        while(la) {
 
4748
                if(la->id.flag & LIB_NEW) {
 
4749
                        for(b=0; b<MAX_MTEX; b++) {
 
4750
                                if(la->mtex[b] && la->mtex[b]->tex) {
 
4751
                                        do_single_tex_user( &(la->mtex[b]->tex) );
 
4752
                                }
 
4753
                        }
 
4754
                }
 
4755
                la= la->id.next;
 
4756
        }
 
4757
        wo= G.main->world.first;
 
4758
        while(wo) {
 
4759
                if(wo->id.flag & LIB_NEW) {
 
4760
                        for(b=0; b<MAX_MTEX; b++) {
 
4761
                                if(wo->mtex[b] && wo->mtex[b]->tex) {
 
4762
                                        do_single_tex_user( &(wo->mtex[b]->tex) );
 
4763
                                }
 
4764
                        }
 
4765
                }
 
4766
                wo= wo->id.next;
 
4767
        }
 
4768
}
 
4769
 
 
4770
void single_mat_users_expand(void)
 
4771
{
 
4772
        /* only when 'parent' blocks are LIB_NEW */
 
4773
 
 
4774
        Object *ob;
 
4775
        Mesh *me;
 
4776
        Curve *cu;
 
4777
        MetaBall *mb;
 
4778
        Material *ma;
 
4779
        int a;
 
4780
        
 
4781
        ob= G.main->object.first;
 
4782
        while(ob) {
 
4783
                if(ob->id.flag & LIB_NEW) {
 
4784
                        new_id_matar(ob->mat, ob->totcol);
 
4785
                }
 
4786
                ob= ob->id.next;
 
4787
        }
 
4788
 
 
4789
        me= G.main->mesh.first;
 
4790
        while(me) {
 
4791
                if(me->id.flag & LIB_NEW) {
 
4792
                        new_id_matar(me->mat, me->totcol);
 
4793
                }
 
4794
                me= me->id.next;
 
4795
        }
 
4796
 
 
4797
        cu= G.main->curve.first;
 
4798
        while(cu) {
 
4799
                if(cu->id.flag & LIB_NEW) {
 
4800
                        new_id_matar(cu->mat, cu->totcol);
 
4801
                }
 
4802
                cu= cu->id.next;
 
4803
        }
 
4804
 
 
4805
        mb= G.main->mball.first;
 
4806
        while(mb) {
 
4807
                if(mb->id.flag & LIB_NEW) {
 
4808
                        new_id_matar(mb->mat, mb->totcol);
 
4809
                }
 
4810
                mb= mb->id.next;
 
4811
        }
 
4812
 
 
4813
        /* material imats  */
 
4814
        ma= G.main->mat.first;
 
4815
        while(ma) {
 
4816
                if(ma->id.flag & LIB_NEW) {
 
4817
                        for(a=0; a<MAX_MTEX; a++) {
 
4818
                                if(ma->mtex[a]) {
 
4819
                                        ID_NEW(ma->mtex[a]->object);
 
4820
                                }
 
4821
                        }
 
4822
                }
 
4823
                ma= ma->id.next;
 
4824
        }
 
4825
}
 
4826
 
 
4827
void single_user(void)
 
4828
{
 
4829
        int nr;
 
4830
        
 
4831
        if(G.scene->id.lib) return;
 
4832
 
 
4833
        clear_id_newpoins();
 
4834
        
 
4835
        nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex|Ipos");
 
4836
        if(nr>0) {
 
4837
        
 
4838
                if(nr==1) single_object_users(1);
 
4839
        
 
4840
                else if(nr==2) {
 
4841
                        single_object_users(1);
 
4842
                        single_obdata_users(1);
 
4843
                }
 
4844
                else if(nr==3) {
 
4845
                        single_object_users(1);
 
4846
                        single_obdata_users(1);
 
4847
                        single_mat_users(1); /* also tex */
 
4848
                        
 
4849
                }
 
4850
                else if(nr==4) {
 
4851
                        single_mat_users(1);
 
4852
                }
 
4853
                else if(nr==5) {
 
4854
                        single_ipo_users(1);
 
4855
                }
 
4856
                
 
4857
                
 
4858
                clear_id_newpoins();
 
4859
 
 
4860
                countall();
 
4861
                allqueue(REDRAWALL, 0);
 
4862
                BIF_undo_push("Single user");
 
4863
        }
 
4864
}
 
4865
 
 
4866
/* ************************************************************* */
 
4867
 
 
4868
/* helper for below, ma was checked to be not NULL */
 
4869
static void make_local_makelocalmaterial(Material *ma)
 
4870
{
 
4871
        ID *id;
 
4872
        int b;
 
4873
        
 
4874
        make_local_material(ma);
 
4875
        
 
4876
        for(b=0; b<MAX_MTEX; b++) {
 
4877
                if(ma->mtex[b] && ma->mtex[b]->tex) {
 
4878
                        make_local_texture(ma->mtex[b]->tex);
 
4879
                }
 
4880
        }
 
4881
        
 
4882
        id= (ID *)ma->ipo;
 
4883
        if(id && id->lib) make_local_ipo(ma->ipo);      
 
4884
        
 
4885
        /* nodetree? XXX */
 
4886
}
 
4887
 
 
4888
void make_local_menu(void)
 
4889
{
 
4890
        int mode;
 
4891
        
 
4892
        /* If you modify this menu, please remember to update view3d_edit_object_makelocalmenu
 
4893
        * in header_view3d.c and the menu in toolbox.c
 
4894
        */
 
4895
        
 
4896
        if(G.scene->id.lib) return;
 
4897
        
 
4898
        mode = pupmenu("Make Local%t|Selected Objects %x1|Selected Objects and Data %x2|All %x3");
 
4899
        
 
4900
        if (mode <= 0) return;
 
4901
        
 
4902
        make_local(mode);
 
4903
}
 
4904
 
 
4905
void make_local(int mode)
 
4906
{
 
4907
        Base *base;
 
4908
        Object *ob;
 
4909
        bActionStrip *strip;
 
4910
        ParticleSystem *psys;
 
4911
        Material *ma, ***matarar;
 
4912
        Lamp *la;
 
4913
        Curve *cu;
 
4914
        ID *id;
 
4915
        int a, b;
 
4916
        
 
4917
        /* WATCH: the function new_id(..) re-inserts the id block!!! */
 
4918
        if(G.scene->id.lib) return;
 
4919
        
 
4920
        if(mode==3) {
 
4921
                all_local(NULL, 0);     /* NULL is all libs */
 
4922
                allqueue(REDRAWALL, 0);
 
4923
                return;
 
4924
        }
 
4925
        else if(mode<1) return;
 
4926
 
 
4927
        clear_id_newpoins();
 
4928
        
 
4929
        base= FIRSTBASE;
 
4930
        while(base) {
 
4931
                if( TESTBASE(base) ) {
 
4932
                        ob= base->object;
 
4933
                        if(ob->id.lib) {
 
4934
                                make_local_object(ob);
 
4935
                        }
 
4936
                }
 
4937
                base= base->next;
 
4938
        }
 
4939
        
 
4940
        /* maybe object pointers */
 
4941
        base= FIRSTBASE;
 
4942
        while(base) {
 
4943
                if( TESTBASE(base) ) {
 
4944
                        ob= base->object;
 
4945
                        if(ob->id.lib==NULL) {
 
4946
                                ID_NEW(ob->parent);
 
4947
                                ID_NEW(ob->track);
 
4948
                        }
 
4949
                }
 
4950
                base= base->next;
 
4951
        }
 
4952
 
 
4953
        base= FIRSTBASE;
 
4954
        while(base) {
 
4955
                if( TESTBASE(base) ) {
 
4956
                        ob= base->object;
 
4957
                        id= ob->data;
 
4958
                        
 
4959
                        if(id && mode>1) {
 
4960
                                
 
4961
                                switch(ob->type) {
 
4962
                                case OB_LAMP:
 
4963
                                        make_local_lamp((Lamp *)id);
 
4964
                                        
 
4965
                                        la= ob->data;
 
4966
                                        id= (ID *)la->ipo;
 
4967
                                        if(id && id->lib) make_local_ipo(la->ipo);
 
4968
                                        
 
4969
                                        break;
 
4970
                                case OB_CAMERA:
 
4971
                                        make_local_camera((Camera *)id);
 
4972
                                        break;
 
4973
                                case OB_MESH:
 
4974
                                        make_local_mesh((Mesh *)id);
 
4975
                                        make_local_key( ((Mesh *)id)->key );
 
4976
                                        break;
 
4977
                                case OB_MBALL:
 
4978
                                        make_local_mball((MetaBall *)id);
 
4979
                                        break;
 
4980
                                case OB_CURVE:
 
4981
                                case OB_SURF:
 
4982
                                case OB_FONT:
 
4983
                                        cu= (Curve *)id;
 
4984
                                        make_local_curve(cu);
 
4985
                                        id= (ID *)cu->ipo;
 
4986
                                        if(id && id->lib) make_local_ipo(cu->ipo);
 
4987
                                        make_local_key( cu->key );
 
4988
                                        break;
 
4989
                                case OB_LATTICE:
 
4990
                                        make_local_lattice((Lattice *)id);
 
4991
                                        make_local_key( ((Lattice *)id)->key );
 
4992
                                        break;
 
4993
                                case OB_ARMATURE:
 
4994
                                        make_local_armature ((bArmature *)id);
 
4995
                                        break;
 
4996
                                }
 
4997
 
 
4998
                                for(psys=ob->particlesystem.first; psys; psys=psys->next)
 
4999
                                        make_local_particlesettings(psys->part);
 
5000
                        }
 
5001
                        id= (ID *)ob->ipo;
 
5002
                        if(id && id->lib) make_local_ipo(ob->ipo);
 
5003
 
 
5004
                        id= (ID *)ob->action;
 
5005
                        if(id && id->lib) make_local_action(ob->action);
 
5006
                        
 
5007
                        for(strip=ob->nlastrips.first; strip; strip=strip->next) {
 
5008
                                if(strip->act && strip->act->id.lib)
 
5009
                                        make_local_action(strip->act);
 
5010
                        }
 
5011
                }
 
5012
                base= base->next;               
 
5013
        }
 
5014
 
 
5015
        if(mode>1) {
 
5016
                base= FIRSTBASE;
 
5017
                while(base) {
 
5018
                        if( TESTBASE(base) ) {
 
5019
                                ob= base->object;
 
5020
                                if(ob->type==OB_LAMP) {
 
5021
                                        la= ob->data;
 
5022
                                        for(b=0; b<MAX_MTEX; b++) {
 
5023
                                                if(la->mtex[b] && la->mtex[b]->tex) {
 
5024
                                                        make_local_texture(la->mtex[b]->tex);
 
5025
                                                }
 
5026
                                        }
 
5027
                                }
 
5028
                                else {
 
5029
                                        
 
5030
                                        for(a=0; a<ob->totcol; a++) {
 
5031
                                                ma= ob->mat[a];
 
5032
                                                if(ma)
 
5033
                                                        make_local_makelocalmaterial(ma);
 
5034
                                        }
 
5035
                                        
 
5036
                                        matarar= (Material ***)give_matarar(ob);
 
5037
                                        if (matarar) {
 
5038
                                                for(a=0; a<ob->totcol; a++) {
 
5039
                                                        ma= (*matarar)[a];
 
5040
                                                        if(ma)
 
5041
                                                                make_local_makelocalmaterial(ma);
 
5042
                                                }
 
5043
                                        }
 
5044
                                }
 
5045
                        }
 
5046
                        base= base->next;
 
5047
                }
 
5048
        }
 
5049
 
 
5050
        allqueue(REDRAWALL, 0);
 
5051
        BIF_undo_push("Make local");
 
5052
}
 
5053
 
 
5054
static void copy_object__forwardModifierLinks(void *userData, Object *ob,
 
5055
                                              ID **idpoin)
 
5056
{
 
5057
        /* this is copied from ID_NEW; it might be better to have a macro */
 
5058
        if(*idpoin && (*idpoin)->newid) *idpoin = (*idpoin)->newid;
 
5059
}
 
5060
 
 
5061
 
 
5062
/* after copying objects, copied data should get new pointers */
 
5063
static void copy_object_set_idnew(int dupflag)
 
5064
{
 
5065
        Base *base;
 
5066
        Object *ob;
 
5067
        Material *ma, *mao;
 
5068
        ID *id;
 
5069
        Ipo *ipo;
 
5070
        bActionStrip *strip;
 
5071
        int a;
 
5072
        
 
5073
        /* check object pointers */
 
5074
        for(base= FIRSTBASE; base; base= base->next) {
 
5075
                if TESTBASELIB(base) {
 
5076
                        ob= base->object;
 
5077
                        relink_constraints(&ob->constraints);
 
5078
                        if (ob->pose){
 
5079
                                bPoseChannel *chan;
 
5080
                                for (chan = ob->pose->chanbase.first; chan; chan=chan->next){
 
5081
                                        relink_constraints(&chan->constraints);
 
5082
                                }
 
5083
                        }
 
5084
                        modifiers_foreachIDLink(ob, copy_object__forwardModifierLinks, NULL);
 
5085
                        ID_NEW(ob->parent);
 
5086
                        ID_NEW(ob->track);
 
5087
                        ID_NEW(ob->proxy);
 
5088
                        ID_NEW(ob->proxy_group);
 
5089
                        
 
5090
                        for(strip= ob->nlastrips.first; strip; strip= strip->next) {
 
5091
                                bActionModifier *amod;
 
5092
                                for(amod= strip->modifiers.first; amod; amod= amod->next)
 
5093
                                        ID_NEW(amod->ob);
 
5094
                        }
 
5095
                }
 
5096
        }
 
5097
        
 
5098
        /* materials */
 
5099
        if( dupflag & USER_DUP_MAT) {
 
5100
                mao= G.main->mat.first;
 
5101
                while(mao) {
 
5102
                        if(mao->id.newid) {
 
5103
                                
 
5104
                                ma= (Material *)mao->id.newid;
 
5105
                                
 
5106
                                if(dupflag & USER_DUP_TEX) {
 
5107
                                        for(a=0; a<MAX_MTEX; a++) {
 
5108
                                                if(ma->mtex[a]) {
 
5109
                                                        id= (ID *)ma->mtex[a]->tex;
 
5110
                                                        if(id) {
 
5111
                                                                ID_NEW_US(ma->mtex[a]->tex)
 
5112
                                                                else ma->mtex[a]->tex= copy_texture(ma->mtex[a]->tex);
 
5113
                                                                id->us--;
 
5114
                                                        }
 
5115
                                                }
 
5116
                                        }
 
5117
                                }
 
5118
                                id= (ID *)ma->ipo;
 
5119
                                if(id) {
 
5120
                                        ID_NEW_US(ma->ipo)
 
5121
                                        else ma->ipo= copy_ipo(ma->ipo);
 
5122
                                        id->us--;
 
5123
                                }
 
5124
                        }
 
5125
                        mao= mao->id.next;
 
5126
                }
 
5127
        }
 
5128
        
 
5129
        /* lamps */
 
5130
        if( dupflag & USER_DUP_IPO) {
 
5131
                Lamp *la= G.main->lamp.first;
 
5132
                while(la) {
 
5133
                        if(la->id.newid) {
 
5134
                                Lamp *lan= (Lamp *)la->id.newid;
 
5135
                                id= (ID *)lan->ipo;
 
5136
                                if(id) {
 
5137
                                        ID_NEW_US(lan->ipo)
 
5138
                                        else lan->ipo= copy_ipo(lan->ipo);
 
5139
                                        id->us--;
 
5140
                                }
 
5141
                        }
 
5142
                        la= la->id.next;
 
5143
                }
 
5144
        }
 
5145
        
 
5146
        /* ipos */
 
5147
        ipo= G.main->ipo.first;
 
5148
        while(ipo) {
 
5149
                if(ipo->id.lib==NULL && ipo->id.newid) {
 
5150
                        Ipo *ipon= (Ipo *)ipo->id.newid;
 
5151
                        IpoCurve *icu;
 
5152
                        for(icu= ipon->curve.first; icu; icu= icu->next) {
 
5153
                                if(icu->driver) {
 
5154
                                        ID_NEW(icu->driver->ob);
 
5155
                                }
 
5156
                        }
 
5157
                }
 
5158
                ipo= ipo->id.next;
 
5159
        }
 
5160
        
 
5161
        set_sca_new_poins();
 
5162
        
 
5163
        clear_id_newpoins();
 
5164
 
 
5165
}
 
5166
 
 
5167
/* This function duplicated the current visible selection, its used by Duplicate and Linked Duplicate
 
5168
Alt+D/Shift+D as well as Pythons Object.Duplicate(), it takes
 
5169
mode: 
 
5170
        0: Duplicate with transform, Redraw.
 
5171
        1: Duplicate, no transform, Redraw
 
5172
        2: Duplicate, no transform, no redraw (Only used by python)
 
5173
if true the user will not be dropped into grab mode directly after and..
 
5174
dupflag: a flag made from constants declared in DNA_userdef_types.h
 
5175
        The flag tells adduplicate() weather to copy data linked to the object, or to reference the existing data.
 
5176
        U.dupflag for default operations or you can construct a flag as python does
 
5177
        if the dupflag is 0 then no data will be copied (linked duplicate) */
 
5178
 
 
5179
void adduplicate(int mode, int dupflag)
 
5180
{
 
5181
        Base *base, *basen;
 
5182
        Material ***matarar;
 
5183
        Object *ob, *obn;
 
5184
        ID *id;
 
5185
        int a, didit;
 
5186
        
 
5187
        if(G.scene->id.lib) return;
 
5188
        clear_id_newpoins();
 
5189
        clear_sca_new_poins();  /* sensor/contr/act */
 
5190
        
 
5191
        base= FIRSTBASE;
 
5192
        while(base) {
 
5193
                if TESTBASE(base) {
 
5194
                
 
5195
                        ob= base->object;
 
5196
                        if(ob->flag & OB_POSEMODE) {
 
5197
                                ; /* nothing? */
 
5198
                        }
 
5199
                        else {
 
5200
                                obn= copy_object(ob);
 
5201
                                obn->recalc |= OB_RECALC;
 
5202
                                
 
5203
                                basen= MEM_mallocN(sizeof(Base), "duplibase");
 
5204
                                *basen= *base;
 
5205
                                BLI_addhead(&G.scene->base, basen);     /* addhead: prevent eternal loop */
 
5206
                                basen->object= obn;
 
5207
                                base->flag &= ~SELECT;
 
5208
                                
 
5209
                                if(basen->flag & OB_FROMGROUP) {
 
5210
                                        Group *group;
 
5211
                                        for(group= G.main->group.first; group; group= group->id.next) {
 
5212
                                                if(object_in_group(ob, group))
 
5213
                                                        add_to_group(group, obn);
 
5214
                                        }
 
5215
                                        obn->flag |= OB_FROMGROUP; /* this flag is unset with copy_object() */
 
5216
                                }
 
5217
                                
 
5218
                                if(BASACT==base) BASACT= basen;
 
5219
 
 
5220
                                /* duplicates using userflags */
 
5221
                                
 
5222
                                if(dupflag & USER_DUP_IPO) {
 
5223
                                        bConstraintChannel *chan;
 
5224
                                        id= (ID *)obn->ipo;
 
5225
                                        
 
5226
                                        if(id) {
 
5227
                                                ID_NEW_US( obn->ipo)
 
5228
                                                else obn->ipo= copy_ipo(obn->ipo);
 
5229
                                                id->us--;
 
5230
                                        }
 
5231
                                        /* Handle constraint ipos */
 
5232
                                        for (chan=obn->constraintChannels.first; chan; chan=chan->next){
 
5233
                                                id= (ID *)chan->ipo;
 
5234
                                                if(id) {
 
5235
                                                        ID_NEW_US( chan->ipo)
 
5236
                                                        else chan->ipo= copy_ipo(chan->ipo);
 
5237
                                                        id->us--;
 
5238
                                                }
 
5239
                                        }
 
5240
                                }
 
5241
                                if(dupflag & USER_DUP_ACT){ /* Not buttons in the UI to modify this, add later? */
 
5242
                                        id= (ID *)obn->action;
 
5243
                                        if (id){
 
5244
                                                ID_NEW_US(obn->action)
 
5245
                                                else{
 
5246
                                                        obn->action= copy_action(obn->action);
 
5247
                                                }
 
5248
                                                id->us--;
 
5249
                                        }
 
5250
                                }
 
5251
                                if(dupflag & USER_DUP_MAT) {
 
5252
                                        for(a=0; a<obn->totcol; a++) {
 
5253
                                                id= (ID *)obn->mat[a];
 
5254
                                                if(id) {
 
5255
                                                        ID_NEW_US(obn->mat[a])
 
5256
                                                        else obn->mat[a]= copy_material(obn->mat[a]);
 
5257
                                                        id->us--;
 
5258
                                                }
 
5259
                                        }
 
5260
                                }
 
5261
                                
 
5262
                                id= obn->data;
 
5263
                                didit= 0;
 
5264
                                
 
5265
                                switch(obn->type) {
 
5266
                                case OB_MESH:
 
5267
                                        if(dupflag & USER_DUP_MESH) {
 
5268
                                                ID_NEW_US2( obn->data )
 
5269
                                                else {
 
5270
                                                        obn->data= copy_mesh(obn->data);
 
5271
                                                        
 
5272
                                                        if(obn->fluidsimSettings) {
 
5273
                                                        obn->fluidsimSettings->orgMesh = (Mesh *)obn->data;
 
5274
                                                        }
 
5275
                                                        
 
5276
                                                        didit= 1;
 
5277
                                                }
 
5278
                                                id->us--;
 
5279
                                        }
 
5280
                                        break;
 
5281
                                case OB_CURVE:
 
5282
                                        if(dupflag & USER_DUP_CURVE) {
 
5283
                                                ID_NEW_US2(obn->data )
 
5284
                                                else {
 
5285
                                                        obn->data= copy_curve(obn->data);
 
5286
                                                        didit= 1;
 
5287
                                                }
 
5288
                                                id->us--;
 
5289
                                        }
 
5290
                                        break;
 
5291
                                case OB_SURF:
 
5292
                                        if(dupflag & USER_DUP_SURF) {
 
5293
                                                ID_NEW_US2( obn->data )
 
5294
                                                else {
 
5295
                                                        obn->data= copy_curve(obn->data);
 
5296
                                                        didit= 1;
 
5297
                                                }
 
5298
                                                id->us--;
 
5299
                                        }
 
5300
                                        break;
 
5301
                                case OB_FONT:
 
5302
                                        if(dupflag & USER_DUP_FONT) {
 
5303
                                                ID_NEW_US2( obn->data )
 
5304
                                                else {
 
5305
                                                        obn->data= copy_curve(obn->data);
 
5306
                                                        didit= 1;
 
5307
                                                }
 
5308
                                                id->us--;
 
5309
                                        }
 
5310
                                        break;
 
5311
                                case OB_MBALL:
 
5312
                                        if(dupflag & USER_DUP_MBALL) {
 
5313
                                                ID_NEW_US2(obn->data )
 
5314
                                                else {
 
5315
                                                        obn->data= copy_mball(obn->data);
 
5316
                                                        didit= 1;
 
5317
                                                }
 
5318
                                                id->us--;
 
5319
                                        }
 
5320
                                        break;
 
5321
                                case OB_LAMP:
 
5322
                                        if(dupflag & USER_DUP_LAMP) {
 
5323
                                                ID_NEW_US2(obn->data )
 
5324
                                                else obn->data= copy_lamp(obn->data);
 
5325
                                                id->us--;
 
5326
                                        }
 
5327
                                        break;
 
5328
 
 
5329
                                case OB_ARMATURE:
 
5330
                                        obn->recalc |= OB_RECALC_DATA;
 
5331
                                        if(obn->pose) obn->pose->flag |= POSE_RECALC;
 
5332
                                        
 
5333
                                        if(dupflag & USER_DUP_ARM) {
 
5334
                                                ID_NEW_US2(obn->data )
 
5335
                                                else {
 
5336
                                                        obn->data= copy_armature(obn->data);
 
5337
                                                        armature_rebuild_pose(obn, obn->data);
 
5338
                                                        didit= 1;
 
5339
                                                }
 
5340
                                                id->us--;
 
5341
                                        }
 
5342
                                        
 
5343
                                        break;
 
5344
                                        
 
5345
                                case OB_LATTICE:
 
5346
                                        if(dupflag!=0) {
 
5347
                                                ID_NEW_US2(obn->data )
 
5348
                                                else obn->data= copy_lattice(obn->data);
 
5349
                                                id->us--;
 
5350
                                        }
 
5351
                                        break;
 
5352
                                case OB_CAMERA:
 
5353
                                        if(dupflag!=0) {
 
5354
                                                ID_NEW_US2(obn->data )
 
5355
                                                else obn->data= copy_camera(obn->data);
 
5356
                                                id->us--;
 
5357
                                        }
 
5358
                                        break;
 
5359
                                }
 
5360
                                
 
5361
                                if(dupflag & USER_DUP_MAT) {
 
5362
                                        matarar= give_matarar(obn);
 
5363
                                        if(didit && matarar) {
 
5364
                                                for(a=0; a<obn->totcol; a++) {
 
5365
                                                        id= (ID *)(*matarar)[a];
 
5366
                                                        if(id) {
 
5367
                                                                ID_NEW_US( (*matarar)[a] )
 
5368
                                                                else (*matarar)[a]= copy_material((*matarar)[a]);
 
5369
                                                                
 
5370
                                                                id->us--;
 
5371
                                                        }
 
5372
                                                }
 
5373
                                        }
 
5374
                                }
 
5375
#ifdef WITH_VERSE
 
5376
                                /* send new created object to verse server,
 
5377
                                 * when original object was linked with object node */
 
5378
                                if(ob->vnode) {
 
5379
                                        b_verse_duplicate_object(((VNode*)ob->vnode)->session, ob, obn);
 
5380
                                }
 
5381
#endif
 
5382
                        }
 
5383
                                                
 
5384
                }
 
5385
                base= base->next;
 
5386
        }
 
5387
 
 
5388
        copy_object_set_idnew(dupflag);
 
5389
 
 
5390
        DAG_scene_sort(G.scene);
 
5391
        DAG_scene_flush_update(G.scene, screen_view3d_layers(), 0);
 
5392
 
 
5393
        countall();
 
5394
        if(mode==0) {
 
5395
                BIF_TransformSetUndo("Add Duplicate");
 
5396
                initTransform(TFM_TRANSLATION, CTX_NONE);
 
5397
                Transform();
 
5398
        }
 
5399
        set_active_base(BASACT);
 
5400
        if(mode!=2) { /* mode of 2 is used by python to avoid unrequested redraws */
 
5401
                allqueue(REDRAWNLA, 0);
 
5402
                allqueue(REDRAWACTION, 0);      /* also oops */
 
5403
                allqueue(REDRAWIPO, 0); /* also oops */
 
5404
        }
 
5405
}
 
5406
 
 
5407
void make_object_duplilist_real(Base *base)
 
5408
{
 
5409
        Base *basen;
 
5410
        Object *ob;
 
5411
        ListBase *lb;
 
5412
        DupliObject *dob;
 
5413
 
 
5414
        if(!base && !(base = BASACT))
 
5415
                return;
 
5416
 
 
5417
        if(!(base->object->transflag & OB_DUPLI))
 
5418
                return;
 
5419
 
 
5420
        lb= object_duplilist(G.scene, base->object);
 
5421
        
 
5422
        for(dob= lb->first; dob; dob= dob->next) {
 
5423
                ob= copy_object(dob->ob);
 
5424
                /* font duplis can have a totcol without material, we get them from parent
 
5425
                * should be implemented better...
 
5426
                */
 
5427
                if(ob->mat==NULL) ob->totcol= 0;
 
5428
                
 
5429
                basen= MEM_dupallocN(base);
 
5430
                basen->flag &= ~OB_FROMDUPLI;
 
5431
                BLI_addhead(&G.scene->base, basen);     /* addhead: othwise eternal loop */
 
5432
                basen->object= ob;
 
5433
                ob->ipo= NULL;          /* make sure apply works */
 
5434
                ob->parent= ob->track= NULL;
 
5435
                ob->disp.first= ob->disp.last= NULL;
 
5436
                ob->transflag &= ~OB_DUPLI;     
 
5437
                
 
5438
                Mat4CpyMat4(ob->obmat, dob->mat);
 
5439
                apply_obmat(ob);
 
5440
        }
 
5441
        
 
5442
        copy_object_set_idnew(0);
 
5443
        
 
5444
        free_object_duplilist(lb);
 
5445
        
 
5446
        base->object->transflag &= ~OB_DUPLI;   
 
5447
}
 
5448
 
 
5449
void make_duplilist_real()
 
5450
{
 
5451
        Base *base;
 
5452
        /*      extern ListBase duplilist; */
 
5453
        
 
5454
        if(okee("Make dupli objects real")==0) return;
 
5455
        
 
5456
        clear_id_newpoins();
 
5457
        
 
5458
        base= FIRSTBASE;
 
5459
        while(base) {
 
5460
                if TESTBASE(base) {
 
5461
                        make_object_duplilist_real(base);
 
5462
                }
 
5463
                base= base->next;
 
5464
        }
 
5465
        
 
5466
        DAG_scene_sort(G.scene);
 
5467
        
 
5468
        allqueue(REDRAWVIEW3D, 0);
 
5469
        allqueue(REDRAWOOPS, 0);
 
5470
        
 
5471
        BIF_undo_push("Make duplicates real");
 
5472
}
 
5473
 
 
5474
void selectlinks_menu(void)
 
5475
{
 
5476
        Object *ob;
 
5477
        int nr;
 
5478
        
 
5479
        ob= OBACT;
 
5480
        if(ob==0) return;
 
5481
        
 
5482
        /* If you modify this menu, please remember to update view3d_select_linksmenu
 
5483
         * in header_view3d.c and the menu in toolbox.c
 
5484
         */
 
5485
        nr= pupmenu("Select Linked%t|Object Ipo%x1|ObData%x2|Material%x3|Texture%x4|DupliGroup%x5|ParticleSystem%x6");
 
5486
        
 
5487
        if (nr <= 0) return;
 
5488
        
 
5489
        selectlinks(nr);
 
5490
}
 
5491
 
 
5492
void selectlinks(int nr)
 
5493
{
 
5494
        Object *ob;
 
5495
        Base *base;
 
5496
        void *obdata = NULL;
 
5497
        Ipo *ipo = NULL;
 
5498
        Material *mat = NULL, *mat1;
 
5499
        Tex *tex=0;
 
5500
        int a, b;
 
5501
        short changed = 0;
 
5502
        /* events (nr):
 
5503
         * Object Ipo: 1
 
5504
         * ObData: 2
 
5505
         * Current Material: 3
 
5506
         * Current Texture: 4
 
5507
         * DupliGroup: 5
 
5508
         * PSys: 6
 
5509
         */
 
5510
        
 
5511
        
 
5512
        ob= OBACT;
 
5513
        if(ob==0) return;
 
5514
        
 
5515
        if(nr==1) {
 
5516
                ipo= ob->ipo;
 
5517
                if(ipo==0) return;
 
5518
        }
 
5519
        else if(nr==2) {
 
5520
                if(ob->data==0) return;
 
5521
                obdata= ob->data;
 
5522
        }
 
5523
        else if(nr==3 || nr==4) {
 
5524
                mat= give_current_material(ob, ob->actcol);
 
5525
                if(mat==0) return;
 
5526
                if(nr==4) {
 
5527
                        if(mat->mtex[ (int)mat->texact ]) tex= mat->mtex[ (int)mat->texact ]->tex;
 
5528
                        if(tex==0) return;
 
5529
                }
 
5530
        }
 
5531
        else if(nr==5) {
 
5532
                if(ob->dup_group==NULL) return;
 
5533
        }
 
5534
        else if(nr==6) {
 
5535
                if(ob->particlesystem.first==NULL) return;
 
5536
        }
 
5537
        else return;
 
5538
        
 
5539
        base= FIRSTBASE;
 
5540
        while(base) {
 
5541
                if (BASE_SELECTABLE(base) && !(base->flag & SELECT)) {
 
5542
                        if(nr==1) {
 
5543
                                if(base->object->ipo==ipo) base->flag |= SELECT;
 
5544
                                changed = 1;
 
5545
                        }
 
5546
                        else if(nr==2) {
 
5547
                                if(base->object->data==obdata) base->flag |= SELECT;
 
5548
                                changed = 1;
 
5549
                        }
 
5550
                        else if(nr==3 || nr==4) {
 
5551
                                ob= base->object;
 
5552
                                
 
5553
                                for(a=1; a<=ob->totcol; a++) {
 
5554
                                        mat1= give_current_material(ob, a);
 
5555
                                        if(nr==3) {
 
5556
                                                if(mat1==mat) base->flag |= SELECT;
 
5557
                                                changed = 1;
 
5558
                                        }
 
5559
                                        else if(mat1 && nr==4) {
 
5560
                                                for(b=0; b<MAX_MTEX; b++) {
 
5561
                                                        if(mat1->mtex[b]) {
 
5562
                                                                if(tex==mat1->mtex[b]->tex) {
 
5563
                                                                        base->flag |= SELECT;
 
5564
                                                                        changed = 1;
 
5565
                                                                        break;
 
5566
                                                                }
 
5567
                                                        }
 
5568
                                                }
 
5569
                                        }
 
5570
                                }
 
5571
                        }
 
5572
                        else if(nr==5) {
 
5573
                                if(base->object->dup_group==ob->dup_group) {
 
5574
                                         base->flag |= SELECT;
 
5575
                                         changed = 1;
 
5576
                                }
 
5577
                        }
 
5578
                        else if(nr==6) {
 
5579
                                /* loop through other, then actives particles*/
 
5580
                                ParticleSystem *psys;
 
5581
                                ParticleSystem *psys_act;
 
5582
                                
 
5583
                                for(psys=base->object->particlesystem.first; psys; psys=psys->next) {
 
5584
                                        for(psys_act=ob->particlesystem.first; psys_act; psys_act=psys_act->next) {
 
5585
                                                if (psys->part == psys_act->part) {
 
5586
                                                        base->flag |= SELECT;
 
5587
                                                        changed = 1;
 
5588
                                                        break;
 
5589
                                                }
 
5590
                                        }
 
5591
                                        
 
5592
                                        if (base->flag & SELECT) {
 
5593
                                                break;
 
5594
                                        }
 
5595
                                }
 
5596
                        }
 
5597
                        base->object->flag= base->flag;
 
5598
                }
 
5599
                base= base->next;
 
5600
        }
 
5601
        
 
5602
        if (changed) {
 
5603
                allqueue(REDRAWVIEW3D, 0);
 
5604
                allqueue(REDRAWDATASELECT, 0);
 
5605
                allqueue(REDRAWOOPS, 0);
 
5606
                BIF_undo_push("Select linked");
 
5607
                countall();
 
5608
        }
 
5609
}
 
5610
 
 
5611
void image_aspect(void)
 
5612
{
 
5613
        /* all selected objects with an image map: scale in image aspect */
 
5614
        Base *base;
 
5615
        Object *ob;
 
5616
        Material *ma;
 
5617
        Tex *tex;
 
5618
        float x, y, space;
 
5619
        int a, b, done;
 
5620
        
 
5621
        if(G.obedit) return;
 
5622
        if(G.scene->id.lib) return;
 
5623
        
 
5624
        base= FIRSTBASE;
 
5625
        while(base) {
 
5626
                if TESTBASELIB(base) {
 
5627
                        ob= base->object;
 
5628
                        done= 0;
 
5629
                        
 
5630
                        for(a=1; a<=ob->totcol; a++) {
 
5631
                                ma= give_current_material(ob, a);
 
5632
                                if(ma) {
 
5633
                                        for(b=0; b<MAX_MTEX; b++) {
 
5634
                                                if(ma->mtex[b] && ma->mtex[b]->tex) {
 
5635
                                                        tex= ma->mtex[b]->tex;
 
5636
                                                        if(tex->type==TEX_IMAGE && tex->ima) {
 
5637
                                                                ImBuf *ibuf= BKE_image_get_ibuf(tex->ima, NULL);
 
5638
                                                                
 
5639
                                                                /* texturespace */
 
5640
                                                                space= 1.0;
 
5641
                                                                if(ob->type==OB_MESH) {
 
5642
                                                                        float size[3];
 
5643
                                                                        mesh_get_texspace(ob->data, NULL, NULL, size);
 
5644
                                                                        space= size[0]/size[1];
 
5645
                                                                }
 
5646
                                                                else if ELEM3(ob->type, OB_CURVE, OB_FONT, OB_SURF) {
 
5647
                                                                        Curve *cu= ob->data;
 
5648
                                                                        space= cu->size[0]/cu->size[1];
 
5649
                                                                }
 
5650
                                                        
 
5651
                                                                x= ibuf->x/space;
 
5652
                                                                y= ibuf->y;
 
5653
                                                                
 
5654
                                                                if(x>y) ob->size[0]= ob->size[1]*x/y;
 
5655
                                                                else ob->size[1]= ob->size[0]*y/x;
 
5656
                                                                
 
5657
                                                                done= 1;
 
5658
                                                                DAG_object_flush_update(G.scene, ob, OB_RECALC_OB);                                                             
 
5659
                                                        }
 
5660
                                                }
 
5661
                                                if(done) break;
 
5662
                                        }
 
5663
                                }
 
5664
                                if(done) break;
 
5665
                        }
 
5666
                }
 
5667
                base= base->next;
 
5668
        }
 
5669
        
 
5670
        allqueue(REDRAWVIEW3D, 0);
 
5671
        BIF_undo_push("Image aspect");
 
5672
}
 
5673
 
 
5674
void set_ob_ipoflags(void)
 
5675
{
 
5676
        Base *base;
 
5677
        int set= 1;
 
5678
        
 
5679
        if (!G.vd) {
 
5680
                error("Can't do this! Open a 3D window");
 
5681
                return;
 
5682
        }
 
5683
        
 
5684
        base= FIRSTBASE;
 
5685
        while(base) {
 
5686
                if TESTBASELIB(base) {
 
5687
                        if(base->object->ipoflag & OB_DRAWKEY) {
 
5688
                                set= 0;
 
5689
                                break;
 
5690
                        }
 
5691
                }
 
5692
                base= base->next;
 
5693
        }
 
5694
        
 
5695
        base= FIRSTBASE;
 
5696
        while(base) {
 
5697
                if TESTBASELIB(base) {
 
5698
                        if(set) {
 
5699
                                base->object->ipoflag |= OB_DRAWKEY;
 
5700
                                if(base->object->ipo) base->object->ipo->showkey= 1;
 
5701
                        }
 
5702
                        else {
 
5703
                                base->object->ipoflag &= ~OB_DRAWKEY;
 
5704
                                if(base->object->ipo) base->object->ipo->showkey= 0;
 
5705
                        }
 
5706
                }
 
5707
                base= base->next;
 
5708
        }
 
5709
        allqueue(REDRAWVIEW3D, 0);
 
5710
        allqueue(REDRAWBUTSOBJECT, 0);
 
5711
        allqueue(REDRAWNLA, 0);
 
5712
        allqueue (REDRAWACTION, 0);
 
5713
        allspace(REMAKEIPO, 0);
 
5714
        allqueue(REDRAWIPO, 0);
 
5715
}
 
5716
 
 
5717
void select_select_keys(void)
 
5718
{
 
5719
        Base *base;
 
5720
        IpoCurve *icu;
 
5721
        BezTriple *bezt;
 
5722
        int a;
 
5723
        
 
5724
        if (!G.vd) {
 
5725
                error("Can't do this! Open a 3D window");
 
5726
                return;
 
5727
        }
 
5728
        
 
5729
        if(G.scene->id.lib) return;
 
5730
 
 
5731
        if(okee("Show and select all keys")==0) return;
 
5732
 
 
5733
        base= FIRSTBASE;
 
5734
        while(base) {
 
5735
                if TESTBASELIB(base) {
 
5736
                        if(base->object->ipo) {
 
5737
                                base->object->ipoflag |= OB_DRAWKEY;
 
5738
                                base->object->ipo->showkey= 1;
 
5739
                                icu= base->object->ipo->curve.first;
 
5740
                                while(icu) {
 
5741
                                        a= icu->totvert;
 
5742
                                        bezt= icu->bezt;
 
5743
                                        while(a--) {
 
5744
                                                bezt->f1 |= SELECT;
 
5745
                                                bezt->f2 |= SELECT;
 
5746
                                                bezt->f3 |= SELECT;
 
5747
                                                bezt++;
 
5748
                                        }
 
5749
                                        icu= icu->next;
 
5750
                                }
 
5751
                        }
 
5752
                }
 
5753
                base= base->next;
 
5754
        }
 
5755
 
 
5756
        allqueue(REDRAWNLA, 0);
 
5757
        allqueue(REDRAWACTION, 0);
 
5758
        allqueue(REDRAWVIEW3D, 0);
 
5759
        allspace(REMAKEIPO, 0);
 
5760
        allqueue(REDRAWIPO, 0);
 
5761
 
 
5762
        BIF_undo_push("Select keys");
 
5763
 
 
5764
}
 
5765
 
 
5766
 
 
5767
int vergbaseco(const void *a1, const void *a2)
 
5768
{
 
5769
        Base **x1, **x2;
 
5770
        
 
5771
        x1= (Base **) a1;
 
5772
        x2= (Base **) a2;
 
5773
        
 
5774
        if( (*x1)->sy > (*x2)->sy ) return 1;
 
5775
        else if( (*x1)->sy < (*x2)->sy) return -1;
 
5776
        else if( (*x1)->sx > (*x2)->sx ) return 1;
 
5777
        else if( (*x1)->sx < (*x2)->sx ) return -1;
 
5778
 
 
5779
        return 0;
 
5780
}
 
5781
 
 
5782
 
 
5783
void auto_timeoffs(void)
 
5784
{
 
5785
        Base *base, **basesort, **bs;
 
5786
        float start, delta;
 
5787
        int tot=0, a;
 
5788
        short offset=25;
 
5789
 
 
5790
        if(BASACT==0 || G.vd==NULL) return;
 
5791
        if(button(&offset, 0, 1000,"Total time")==0) return;
 
5792
 
 
5793
        /* make array of all bases, xco yco (screen) */
 
5794
        base= FIRSTBASE;
 
5795
        while(base) {
 
5796
                if(TESTBASELIB(base)) {
 
5797
                        tot++;
 
5798
                }
 
5799
                base= base->next;
 
5800
        }
 
5801
 
 
5802
        delta= (float)offset/(float)tot;
 
5803
        start= OBACT->sf;
 
5804
 
 
5805
        bs= basesort= MEM_mallocN(sizeof(void *)*tot,"autotimeoffs");
 
5806
        base= FIRSTBASE;
 
5807
 
 
5808
        while(base) {
 
5809
                if(TESTBASELIB(base)) {
 
5810
                        *bs= base;
 
5811
                        bs++;
 
5812
                }
 
5813
                base= base->next;
 
5814
        }
 
5815
        qsort(basesort, tot, sizeof(void *), vergbaseco);
 
5816
 
 
5817
        bs= basesort;
 
5818
        for(a=0; a<tot; a++) {
 
5819
                
 
5820
                (*bs)->object->sf= start;
 
5821
                start+= delta;
 
5822
 
 
5823
                bs++;
 
5824
        }
 
5825
        MEM_freeN(basesort);
 
5826
 
 
5827
        allqueue(REDRAWVIEW3D, 0);
 
5828
        allqueue(REDRAWBUTSOBJECT, 0);
 
5829
}
 
5830
 
 
5831
void ofs_timeoffs(void)
 
5832
{
 
5833
        Base *base;
 
5834
        float offset=0.0f;
 
5835
 
 
5836
        if(BASACT==0 || G.vd==NULL) return;
 
5837
        
 
5838
        if(fbutton(&offset, -10000.0f, 10000.0f, 10, 10, "Offset")==0) return;
 
5839
 
 
5840
        /* make array of all bases, xco yco (screen) */
 
5841
        base= FIRSTBASE;
 
5842
        while(base) {
 
5843
                if(TESTBASELIB(base)) {
 
5844
                        base->object->sf += offset;
 
5845
                        if (base->object->sf < -MAXFRAMEF)              base->object->sf = -MAXFRAMEF;
 
5846
                        else if (base->object->sf > MAXFRAMEF)  base->object->sf = MAXFRAMEF;
 
5847
                }
 
5848
                base= base->next;
 
5849
        }
 
5850
 
 
5851
        allqueue(REDRAWVIEW3D, 0);
 
5852
        allqueue(REDRAWBUTSOBJECT, 0);
 
5853
}
 
5854
 
 
5855
 
 
5856
void rand_timeoffs(void)
 
5857
{
 
5858
        Base *base;
 
5859
        float rand=0.0f;
 
5860
 
 
5861
        if(BASACT==0 || G.vd==NULL) return;
 
5862
        
 
5863
        if(fbutton(&rand, 0.0f, 10000.0f, 10, 10, "Randomize")==0) return;
 
5864
        
 
5865
        rand *= 2;
 
5866
        
 
5867
        base= FIRSTBASE;
 
5868
        while(base) {
 
5869
                if(TESTBASELIB(base)) {
 
5870
                        base->object->sf += (BLI_drand()-0.5) * rand;
 
5871
                        if (base->object->sf < -MAXFRAMEF)              base->object->sf = -MAXFRAMEF;
 
5872
                        else if (base->object->sf > MAXFRAMEF)  base->object->sf = MAXFRAMEF;
 
5873
                }
 
5874
                base= base->next;
 
5875
        }
 
5876
 
 
5877
        allqueue(REDRAWVIEW3D, 0);
 
5878
        allqueue(REDRAWBUTSOBJECT, 0);
 
5879
}
 
5880
 
 
5881
 
 
5882
void texspace_edit(void)
 
5883
{
 
5884
        Base *base;
 
5885
        int nr=0;
 
5886
        
 
5887
        /* first test if from visible and selected objects
 
5888
         * texspacedraw is set:
 
5889
         */
 
5890
        
 
5891
        if(G.obedit) return;
 
5892
        
 
5893
        base= FIRSTBASE;
 
5894
        while(base) {
 
5895
                if TESTBASELIB(base) {
 
5896
                        break;
 
5897
                }
 
5898
                base= base->next;
 
5899
        }
 
5900
 
 
5901
        if(base==0) {
 
5902
                return;
 
5903
        }
 
5904
        
 
5905
        nr= pupmenu("Texture Space %t|Grab/Move%x1|Size%x2");
 
5906
        if(nr<1) return;
 
5907
        
 
5908
        base= FIRSTBASE;
 
5909
        while(base) {
 
5910
                if TESTBASELIB(base) {
 
5911
                        base->object->dtx |= OB_TEXSPACE;
 
5912
                }
 
5913
                base= base->next;
 
5914
        }
 
5915
        
 
5916
 
 
5917
        if(nr==1) {
 
5918
                initTransform(TFM_TRANSLATION, CTX_TEXTURE);
 
5919
                Transform();
 
5920
        }
 
5921
        else if(nr==2) {
 
5922
                initTransform(TFM_RESIZE, CTX_TEXTURE);
 
5923
                Transform();
 
5924
        }
 
5925
        else if(nr==3) {
 
5926
                initTransform(TFM_ROTATION, CTX_TEXTURE);
 
5927
                Transform();
 
5928
        }
 
5929
}
 
5930
 
 
5931
/* ******************************************************************** */
 
5932
/* Mirror function in Edit Mode */
 
5933
 
 
5934
void mirrormenu(void)
 
5935
{
 
5936
        if(G.f & G_PARTICLEEDIT) {
 
5937
                PE_mirror_x(0);
 
5938
        }
 
5939
        else {
 
5940
                initTransform(TFM_MIRROR, CTX_NO_PET);
 
5941
                Transform();
 
5942
        }
 
5943
}
 
5944
 
 
5945
void hookmenu(void)
 
5946
{
 
5947
        /* only called in object mode */
 
5948
        short event, changed=0;
 
5949
        Object *ob;
 
5950
        Base *base;
 
5951
        ModifierData *md;
 
5952
        HookModifierData *hmd;
 
5953
        
 
5954
        event= pupmenu("Modify Hooks for Selected...%t|Reset Offset%x1|Recenter at Cursor%x2");
 
5955
        if (event==-1) return;
 
5956
        if (event==2 && !(G.vd)) {
 
5957
                error("Cannot perform this operation without a 3d view");
 
5958
                return;
 
5959
        }
 
5960
        
 
5961
        for (base= FIRSTBASE; base; base= base->next) {
 
5962
                if TESTBASELIB(base) {
 
5963
                        for (md = base->object->modifiers.first; md; md=md->next) {
 
5964
                                if (md->type==eModifierType_Hook) {
 
5965
                                        ob = base->object;
 
5966
                                        hmd = (HookModifierData*) md;
 
5967
                                        
 
5968
                                        /*
 
5969
                                         * Copied from modifiers_cursorHookCenter and
 
5970
                                         * modifiers_clearHookOffset, should consolidate
 
5971
                                         * */
 
5972
                                        
 
5973
                                        if (event==1) {
 
5974
                                                if(hmd->object) {
 
5975
                                                        Mat4Invert(hmd->object->imat, hmd->object->obmat);
 
5976
                                                        Mat4MulSerie(hmd->parentinv, hmd->object->imat, ob->obmat, NULL, NULL, NULL, NULL, NULL, NULL);
 
5977
                                                        
 
5978
                                                        changed= 1;
 
5979
                                                        DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
5980
                                                }
 
5981
                                        } else {
 
5982
                                                float *curs = give_cursor();
 
5983
                                                float bmat[3][3], imat[3][3];
 
5984
                                                
 
5985
                                                where_is_object(ob);
 
5986
                                        
 
5987
                                                Mat3CpyMat4(bmat, ob->obmat);
 
5988
                                                Mat3Inv(imat, bmat);
 
5989
                                
 
5990
                                                curs= give_cursor();
 
5991
                                                hmd->cent[0]= curs[0]-ob->obmat[3][0];
 
5992
                                                hmd->cent[1]= curs[1]-ob->obmat[3][1];
 
5993
                                                hmd->cent[2]= curs[2]-ob->obmat[3][2];
 
5994
                                                Mat3MulVecfl(imat, hmd->cent);
 
5995
                                                
 
5996
                                                changed= 1;
 
5997
                                                DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
 
5998
                                        } 
 
5999
                                }
 
6000
                        }
 
6001
                }
 
6002
        }
 
6003
        
 
6004
        if (changed) {
 
6005
                if (event==1)
 
6006
                        BIF_undo_push("Clear hook offset for selected");
 
6007
                else if (event==2)
 
6008
                        BIF_undo_push("Hook cursor center for selected");
 
6009
                
 
6010
                allqueue(REDRAWVIEW3D, 0);
 
6011
                allqueue(REDRAWBUTSEDIT, 0);
 
6012
        }       
 
6013
}
 
6014
 
 
6015
/*
 
6016
 * Returns true if the Object is a from an external blend file (libdata)
 
6017
 */
 
6018
int object_is_libdata(Object *ob)
 
6019
{
 
6020
        if (!ob) return 0;
 
6021
        if (ob->proxy) return 0;
 
6022
        if (ob->id.lib) return 1;
 
6023
        return 0;
 
6024
}
 
6025
 
 
6026
 
 
6027
/*
 
6028
 * Returns true if the Object data is a from an external blend file (libdata)
 
6029
 */
 
6030
int object_data_is_libdata(Object *ob)
 
6031
{
 
6032
        if (!ob) return 0;
 
6033
        if (ob->proxy) return 0;
 
6034
        if (ob->id.lib) return 1;
 
6035
        if (!ob->data) return 0;
 
6036
        if (((ID *)ob->data)->lib) return 1;
 
6037
        return 0;
 
6038
}
 
6039
 
 
6040
void hide_objects(int select)
 
6041
{
 
6042
        Base *base;
 
6043
        short changed = 0, changed_act = 0;
 
6044
        for(base = FIRSTBASE; base; base=base->next){
 
6045
                if ((base->lay & G.vd->lay) && (TESTBASELIB(base)==select)) {
 
6046
                        base->flag &= ~SELECT;
 
6047
                        base->object->flag = base->flag;
 
6048
                        base->object->restrictflag |= OB_RESTRICT_VIEW;
 
6049
                        changed = 1;
 
6050
                        if (base==BASACT) {
 
6051
                                BASACT= NULL;
 
6052
                                changed_act = 1;
 
6053
                        }
 
6054
                }
 
6055
        }
 
6056
        if (changed) {
 
6057
                if(select) BIF_undo_push("Hide Selected Objects");
 
6058
                else if(select) BIF_undo_push("Hide Unselected Objects");
 
6059
                DAG_scene_sort(G.scene);
 
6060
                allqueue(REDRAWVIEW3D,0);
 
6061
                allqueue(REDRAWOOPS,0);
 
6062
                allqueue(REDRAWDATASELECT,0);
 
6063
                if (changed_act) { /* these spaces depend on the active object */
 
6064
                        allqueue(REDRAWBUTSALL,0);
 
6065
                        allqueue(REDRAWIPO,0);
 
6066
                        allqueue(REDRAWACTION,0);
 
6067
                }
 
6068
                countall();
 
6069
        }
 
6070
}
 
6071
 
 
6072
void show_objects(void)
 
6073
{
 
6074
        Base *base;
 
6075
        int changed = 0;
 
6076
        for(base = FIRSTBASE; base; base=base->next){
 
6077
                if((base->lay & G.vd->lay) && base->object->restrictflag & OB_RESTRICT_VIEW) {
 
6078
                        base->flag |= SELECT;
 
6079
                        base->object->flag = base->flag;
 
6080
                        base->object->restrictflag &= ~OB_RESTRICT_VIEW; 
 
6081
                        changed = 1;
 
6082
                }
 
6083
        }
 
6084
        if (changed) {
 
6085
                BIF_undo_push("Unhide Objects");
 
6086
                DAG_scene_sort(G.scene);
 
6087
                allqueue(REDRAWVIEW3D,0);
 
6088
                allqueue(REDRAWOOPS,0);
 
6089
                countall();
 
6090
        }
 
6091
}