Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/src/editoops.c')
-rw-r--r--source/blender/src/editoops.c595
1 files changed, 595 insertions, 0 deletions
diff --git a/source/blender/src/editoops.c b/source/blender/src/editoops.c
new file mode 100644
index 00000000000..9ec2001ce5f
--- /dev/null
+++ b/source/blender/src/editoops.c
@@ -0,0 +1,595 @@
+/**
+ * $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>
+#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 */
+
+}