#ifdef HAVE_CONFIG_H #include <config.h> #endif Just need to finish cpp files now :) Kent -- mein@cs.umn.edu
601 lines
11 KiB
C
601 lines
11 KiB
C
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#include <unistd.h>
|
|
#else
|
|
#include <io.h>
|
|
#include "BLI_winstuff.h"
|
|
#endif
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "BLI_blenlib.h"
|
|
#include "BLI_arithb.h"
|
|
#include "BLI_editVert.h"
|
|
|
|
#include "DNA_material_types.h"
|
|
#include "DNA_object_types.h"
|
|
#include "DNA_oops_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "DNA_space_types.h"
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "BKE_global.h"
|
|
#include "BKE_scene.h"
|
|
#include "BKE_material.h"
|
|
|
|
#include "BIF_space.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_editoops.h"
|
|
#include "BIF_editview.h"
|
|
#include "BIF_drawscene.h"
|
|
#include "BIF_mywindow.h"
|
|
|
|
#include "BDR_editobject.h"
|
|
|
|
#include "BSE_edit.h"
|
|
#include "BSE_drawipo.h"
|
|
|
|
#include "blendef.h"
|
|
#include "mydevice.h"
|
|
|
|
|
|
typedef struct TransOops {
|
|
float *loc;
|
|
float oldloc[2];
|
|
} TransOops;
|
|
|
|
|
|
static void oops_to_select_objects(void)
|
|
{
|
|
Oops *oops;
|
|
Base *base;
|
|
Object *ob;
|
|
|
|
if(G.soops==0) return;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->type==ID_OB) {
|
|
ob= (Object *)oops->id;
|
|
if(oops->flag & SELECT) ob->flag |= SELECT;
|
|
else ob->flag &= ~SELECT;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
base= FIRSTBASE;
|
|
while(base) {
|
|
if(base->flag != base->object->flag) {
|
|
base->flag= base->object->flag;
|
|
}
|
|
base= base->next;
|
|
}
|
|
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWOOPS, 0);
|
|
}
|
|
|
|
void swap_select_all_oops(void)
|
|
{
|
|
Oops *oops;
|
|
int sel= 0;
|
|
|
|
if(G.soops==0) return;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & SELECT) {
|
|
sel= 1;
|
|
break;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(sel) oops->flag &= ~SELECT;
|
|
else oops->flag |= SELECT;
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops_to_select_objects(); /* ook redr */
|
|
|
|
G.soops->lockpoin= 0;
|
|
}
|
|
|
|
/* never used... check CVS 1.12 for the code */
|
|
/* static void select_swap_oops(void) */
|
|
|
|
static void deselect_all_oops(void)
|
|
{
|
|
Oops *oops;
|
|
|
|
if(G.soops==0) return;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
oops->flag &= ~SELECT;
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
G.soops->lockpoin= 0;
|
|
}
|
|
|
|
void set_select_flag_oops(void) /* alle areas */
|
|
{
|
|
SpaceOops *so;
|
|
ScrArea *sa;
|
|
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if(sa->spacetype==SPACE_OOPS) {
|
|
so= sa->spacedata.first;
|
|
so->flag |= SO_NEWSELECTED;
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
if(G.soops) G.soops->lockpoin= 0;
|
|
}
|
|
|
|
void deselect_all_area_oops(void) /* alle areas */
|
|
{
|
|
SpaceOops *so;
|
|
Oops *oops;
|
|
ScrArea *sa;
|
|
|
|
sa= G.curscreen->areabase.first;
|
|
while(sa) {
|
|
if(sa->spacetype==SPACE_OOPS) {
|
|
so= sa->spacedata.first;
|
|
|
|
oops= so->oops.first;
|
|
while(oops) {
|
|
oops->flag &= ~SELECT;
|
|
oops= oops->next;
|
|
}
|
|
}
|
|
sa= sa->next;
|
|
}
|
|
|
|
if(G.soops) G.soops->lockpoin= 0;
|
|
}
|
|
|
|
void transform_oops(int mode)
|
|
{
|
|
TransOops *transmain, *tv;
|
|
Oops *oops;
|
|
float dx, dy, div, dvec[3], cent[3], min[3], max[3];
|
|
float sizefac, size[2], xref=1.0, yref=1.0;
|
|
int a, tot= 0, midtog= 0;
|
|
unsigned short event = 0;
|
|
short firsttime= 1, proj = 0, afbreek=0, xc, yc, xo, yo, xn, yn, mval[2];
|
|
short val;
|
|
char str[32];
|
|
|
|
if(G.soops==0) return;
|
|
|
|
/* welke oopsen doen mee */
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & SELECT) {
|
|
tot++;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
if(tot==0) return;
|
|
|
|
G.moving= 1;
|
|
|
|
INIT_MINMAX(min, max);
|
|
|
|
tv=transmain= MEM_callocN(tot*sizeof(TransOops), "transmain");
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & SELECT) {
|
|
tv->loc= &oops->x;
|
|
tv->oldloc[0]= tv->loc[0];
|
|
tv->oldloc[1]= tv->loc[1];
|
|
DO_MINMAX2(tv->loc, min, max);
|
|
tv++;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
cent[0]= (min[0]+max[0])/2.0;
|
|
cent[1]= (min[1]+max[1])/2.0;
|
|
|
|
ipoco_to_areaco_noclip(G.v2d, cent, mval);
|
|
xc= mval[0];
|
|
yc= mval[1];
|
|
|
|
getmouseco_areawin(mval);
|
|
xo= xn= mval[0];
|
|
yo= yn= mval[1];
|
|
dvec[0]= dvec[1]= 0.0;
|
|
|
|
sizefac= sqrt( (float)((yc-yn)*(yc-yn)+(xn-xc)*(xn-xc)) );
|
|
if(sizefac<2.0) sizefac= 2.0;
|
|
|
|
while(afbreek==0) {
|
|
getmouseco_areawin(mval);
|
|
if(mval[0]!=xo || mval[1]!=yo || firsttime) {
|
|
|
|
if(mode=='g') {
|
|
|
|
dx= mval[0]- xo;
|
|
dy= mval[1]- yo;
|
|
|
|
div= G.v2d->mask.xmax-G.v2d->mask.xmin;
|
|
dvec[0]+= (G.v2d->cur.xmax-G.v2d->cur.xmin)*(dx)/div;
|
|
|
|
div= G.v2d->mask.ymax-G.v2d->mask.ymin;
|
|
dvec[1]+= (G.v2d->cur.ymax-G.v2d->cur.ymin)*(dy)/div;
|
|
|
|
if(midtog) dvec[proj]= 0.0;
|
|
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
|
|
tv->loc[0]= tv->oldloc[0]+dvec[0];
|
|
tv->loc[1]= tv->oldloc[1]+dvec[1];
|
|
|
|
}
|
|
|
|
sprintf(str, "X: %.2f Y: %.2f ", dvec[0], dvec[1]);
|
|
headerprint(str);
|
|
}
|
|
else if(mode=='s') {
|
|
size[0]=size[1]= (sqrt( (float)((yc-mval[1])*(yc-mval[1])+(mval[0]-xc)*(mval[0]-xc)) ))/sizefac;
|
|
|
|
if(midtog) size[proj]= 1.0;
|
|
size[0]*= xref;
|
|
size[1]*= yref;
|
|
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
|
|
tv->loc[0]= size[0]*(tv->oldloc[0]-cent[0])+ cent[0];
|
|
tv->loc[1]= size[1]*(tv->oldloc[1]-cent[1])+ cent[1];
|
|
|
|
}
|
|
|
|
sprintf(str, "sizeX: %.3f sizeY: %.3f ", size[0], size[1]);
|
|
headerprint(str);
|
|
}
|
|
|
|
|
|
xo= mval[0];
|
|
yo= mval[1];
|
|
|
|
force_draw();
|
|
|
|
firsttime= 0;
|
|
|
|
}
|
|
else BIF_wait_for_statechange();
|
|
|
|
while(qtest()) {
|
|
event= extern_qread(&val);
|
|
if(val) {
|
|
switch(event) {
|
|
case ESCKEY:
|
|
case LEFTMOUSE:
|
|
case SPACEKEY:
|
|
case RETKEY:
|
|
afbreek= 1;
|
|
break;
|
|
case MIDDLEMOUSE:
|
|
|
|
midtog= ~midtog;
|
|
if(midtog) {
|
|
if( abs(mval[0]-xn) > abs(mval[1]-yn)) proj= 1;
|
|
else proj= 0;
|
|
firsttime= 1;
|
|
}
|
|
|
|
break;
|
|
default:
|
|
arrows_move_cursor(event);
|
|
}
|
|
}
|
|
if(afbreek) break;
|
|
}
|
|
}
|
|
|
|
if(event==ESCKEY) {
|
|
tv= transmain;
|
|
for(a=0; a<tot; a++, tv++) {
|
|
tv->loc[0]= tv->oldloc[0];
|
|
tv->loc[1]= tv->oldloc[1];
|
|
}
|
|
}
|
|
MEM_freeN(transmain);
|
|
|
|
G.moving= 0;
|
|
|
|
scrarea_queue_redraw(curarea);
|
|
}
|
|
|
|
static Oops *find_nearest_oops(void)
|
|
{
|
|
Oops *oops;
|
|
float x, y;
|
|
short mval[2];
|
|
|
|
getmouseco_areawin(mval);
|
|
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide == 0) {
|
|
if(oops->x <=x && oops->x+OOPSX >= x) {
|
|
if(oops->y <=y && oops->y+OOPSY >= y) {
|
|
return oops;
|
|
}
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static void do_activate_oops(Oops *oops)
|
|
{
|
|
Base *base;
|
|
Object *ob;
|
|
|
|
switch(oops->type) {
|
|
case ID_SCE:
|
|
if(oops->id) set_scene((Scene *)oops->id);
|
|
break;
|
|
case ID_OB:
|
|
base= FIRSTBASE;
|
|
while(base) {
|
|
if(base->object == (Object *)oops->id) break;
|
|
base= base->next;
|
|
}
|
|
if(base) {
|
|
set_active_base(base); /* editview.c */
|
|
allqueue(REDRAWVIEW3D, 0);
|
|
allqueue(REDRAWINFO, 1);
|
|
}
|
|
break;
|
|
case ID_MA:
|
|
ob= OBACT;
|
|
if(ob && oops->id) {
|
|
assign_material(ob, (Material *)oops->id, ob->actcol);
|
|
allqueue(REDRAWBUTSMAT, 0);
|
|
scrarea_queue_winredraw(curarea);
|
|
}
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
void mouse_select_oops(void)
|
|
{
|
|
Oops *oops;
|
|
extern float oopslastx, oopslasty; /* oops.c */
|
|
|
|
if(G.soops==0) return;
|
|
|
|
/* welke oopsen doen mee */
|
|
oops= G.soops->oops.first;
|
|
|
|
oops= find_nearest_oops();
|
|
if(oops==0) return;
|
|
|
|
if((G.qual & LR_SHIFTKEY)==0) deselect_all_oops();
|
|
|
|
if(oops) {
|
|
/* last_seq= seq; */
|
|
|
|
if(G.qual==0) {
|
|
oops->flag |= SELECT;
|
|
}
|
|
else {
|
|
if(oops->flag & SELECT) {
|
|
oops->flag &= ~SELECT;
|
|
}
|
|
else {
|
|
oops->flag |= SELECT;
|
|
}
|
|
}
|
|
|
|
oopslastx= oops->x;
|
|
oopslasty= oops->y;
|
|
|
|
if(G.qual & LR_CTRLKEY) do_activate_oops(oops);
|
|
G.soops->lockpoin= oops;
|
|
}
|
|
|
|
oops_to_select_objects(); /* ook redr */
|
|
scrarea_queue_headredraw(curarea);
|
|
|
|
force_draw();
|
|
|
|
std_rmouse_transform(transform_oops);
|
|
}
|
|
|
|
void borderselect_oops(void)
|
|
{
|
|
Oops *oops;
|
|
rcti rect;
|
|
rctf rectf, rq;
|
|
int val;
|
|
short mval[2];
|
|
|
|
if(G.soops==0) return;
|
|
|
|
val= get_border(&rect, 3);
|
|
|
|
if(val) {
|
|
mval[0]= rect.xmin;
|
|
mval[1]= rect.ymin;
|
|
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmin, &rectf.ymin);
|
|
mval[0]= rect.xmax;
|
|
mval[1]= rect.ymax;
|
|
areamouseco_to_ipoco(G.v2d, mval, &rectf.xmax, &rectf.ymax);
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide == 0) {
|
|
|
|
rq.xmin= oops->x;
|
|
rq.xmax= oops->x+OOPSX;
|
|
rq.ymin= oops->y;
|
|
rq.ymax= oops->y+OOPSY;
|
|
|
|
if(BLI_isect_rctf(&rq, &rectf, 0)) {
|
|
if(val==LEFTMOUSE) {
|
|
oops->flag |= SELECT;
|
|
}
|
|
else {
|
|
oops->flag &= ~SELECT;
|
|
}
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops_to_select_objects(); /* ook redr */
|
|
}
|
|
}
|
|
|
|
static void select_oops_lib(ID *id)
|
|
{
|
|
Oops *oops;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->id->lib== (Library *)id) oops->flag |= OOPS_DOSELECT;
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
}
|
|
|
|
void select_linked_oops(void)
|
|
{
|
|
Oops *oops;
|
|
OopsLink *ol;
|
|
|
|
if(G.soops==0) return;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & SELECT) {
|
|
if(oops->type==ID_LI) select_oops_lib(oops->id);
|
|
ol= oops->link.first;
|
|
while(ol) {
|
|
if(ol->to && ol->to->hide==0) ol->to->flag |= OOPS_DOSELECT;
|
|
ol= ol->next;
|
|
}
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & OOPS_DOSELECT) {
|
|
oops->flag |= SELECT;
|
|
oops->flag &= ~OOPS_DOSELECT;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops_to_select_objects(); /* ook redr */
|
|
|
|
}
|
|
|
|
void select_backlinked_oops(void)
|
|
{
|
|
Oops *oops;
|
|
OopsLink *ol;
|
|
|
|
if(G.soops==0) return;
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if( (oops->flag & SELECT)==0) {
|
|
ol= oops->link.first;
|
|
while(ol) {
|
|
if(ol->to && ol->to->hide==0) {
|
|
if(ol->to->flag & SELECT) oops->flag |= OOPS_DOSELECT;
|
|
}
|
|
ol= ol->next;
|
|
}
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops= G.soops->oops.first;
|
|
while(oops) {
|
|
if(oops->hide==0) {
|
|
if(oops->flag & OOPS_DOSELECT) {
|
|
oops->flag |= SELECT;
|
|
oops->flag &= ~OOPS_DOSELECT;
|
|
}
|
|
}
|
|
oops= oops->next;
|
|
}
|
|
|
|
oops_to_select_objects(); /* ook redr */
|
|
|
|
}
|