2002-10-12 11:37:38 +00:00
|
|
|
/**
|
|
|
|
* $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 <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
2002-11-25 12:02:15 +00:00
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BMF_Api.h"
|
|
|
|
|
|
|
|
#include "IMB_imbuf.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include "MTC_matrixops.h"
|
|
|
|
|
2005-07-12 15:47:53 +00:00
|
|
|
#include "DNA_armature_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_camera_types.h"
|
|
|
|
#include "DNA_curve_types.h"
|
2003-11-11 16:56:51 +00:00
|
|
|
#include "DNA_constraint_types.h" // for drawing constraint
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_effect_types.h"
|
|
|
|
#include "DNA_ipo_types.h"
|
|
|
|
#include "DNA_lamp_types.h"
|
|
|
|
#include "DNA_lattice_types.h"
|
|
|
|
#include "DNA_material_types.h"
|
|
|
|
#include "DNA_mesh_types.h"
|
2004-03-20 22:55:42 +00:00
|
|
|
#include "DNA_meshdata_types.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_meta_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
2005-05-02 13:28:13 +00:00
|
|
|
#include "DNA_object_force.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "DNA_space_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_view3d_types.h"
|
|
|
|
#include "DNA_world_types.h"
|
|
|
|
|
Fix for undo... it didn't do the UV coords (tface) nor the vertexpaint
colors. This because of the pretty weird (ab)use of load & make editmesh...
For each added undo step, the load_editmesh was fed with an empty mesh
to assign data to, without knowledge of what was in the original mesh.
That way UV and color data got lost.
Solved it in 2 steps:
1. removing the ->tface pointer from EditVlak, and make TFace a builtin
struct inside EditVlak. This didnt cost much extra mem, since it already
stored UV and color. This enabled some pretty cleanup in editmesh.c as
well, storing tface pointers was cumbersome.
2. for each undo step, it then generates always a tface and mcol block to
link to the undo Mesh.
Even when it wasn't in the actual Mesh, at exit editmode the original
Mesh is used as reference anyway, and undo-meshes are freed correctly.
The enormous commit is because I had to change the BLI_editVert.h file, and
found it was included in about every file unnecessary. I removed it there.
ALso found out that subsurf has code ready (unfinished) to make UV coords for
the displaylist in EditMode as well, nice to know for later...
2003-11-19 22:00:14 +00:00
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_arithb.h"
|
|
|
|
#include "BLI_editVert.h"
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_utildefines.h"
|
|
|
|
#include "BKE_curve.h"
|
2003-11-11 16:56:51 +00:00
|
|
|
#include "BKE_constraint.h" // for the get_constraint_target function
|
2004-09-14 19:03:11 +00:00
|
|
|
#include "BKE_deform.h" // lattice_modifier()
|
2005-03-27 20:39:28 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_displist.h"
|
|
|
|
#include "BKE_effect.h"
|
2005-06-17 21:04:27 +00:00
|
|
|
#include "BKE_font.h"
|
2004-09-14 19:03:11 +00:00
|
|
|
#include "BKE_global.h"
|
2005-07-09 18:04:53 +00:00
|
|
|
#include "BKE_image.h"
|
2004-09-14 19:03:11 +00:00
|
|
|
#include "BKE_ipo.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BKE_lattice.h"
|
2004-09-14 19:03:11 +00:00
|
|
|
#include "BKE_mesh.h"
|
|
|
|
#include "BKE_material.h"
|
|
|
|
#include "BKE_mball.h"
|
|
|
|
#include "BKE_object.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "BIF_gl.h"
|
2005-03-26 17:29:37 +00:00
|
|
|
#include "BIF_glutil.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
#include "BIF_mywindow.h"
|
|
|
|
#include "BIF_screen.h"
|
|
|
|
#include "BIF_space.h"
|
|
|
|
#include "BIF_editarmature.h"
|
|
|
|
#include "BIF_editmesh.h"
|
2004-07-10 21:35:17 +00:00
|
|
|
#include "BIF_glutil.h"
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
#include "BIF_resources.h"
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
#include "BDR_drawmesh.h"
|
|
|
|
#include "BDR_drawobject.h"
|
|
|
|
#include "BDR_editobject.h"
|
|
|
|
|
|
|
|
#include "BSE_view.h"
|
|
|
|
#include "BSE_drawview.h"
|
|
|
|
#include "BSE_trans_types.h"
|
|
|
|
|
|
|
|
#include "blendef.h"
|
|
|
|
#include "mydevice.h"
|
|
|
|
#include "nla.h"
|
|
|
|
|
|
|
|
#include "BKE_deform.h"
|
|
|
|
|
|
|
|
/* pretty stupid */
|
|
|
|
/* extern Lattice *editLatt; already in BKE_lattice.h */
|
|
|
|
/* editcurve.c */
|
|
|
|
extern ListBase editNurb;
|
|
|
|
/* editmball.c */
|
|
|
|
extern ListBase editelems;
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void draw_bounding_volume(Object *ob);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
/* ************* Setting OpenGL Material ************ */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
// Materials start counting at # one....
|
|
|
|
#define MAXMATBUF (MAXMAT + 1)
|
|
|
|
static float matbuf[MAXMATBUF][2][4];
|
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
static int set_gl_material(int nr)
|
|
|
|
{
|
|
|
|
static int last_gl_matnr= -1;
|
|
|
|
static int last_ret_val= 1;
|
|
|
|
|
|
|
|
if(nr<0) {
|
|
|
|
last_gl_matnr= -1;
|
|
|
|
last_ret_val= 1;
|
|
|
|
}
|
|
|
|
else if(nr<MAXMATBUF && nr!=last_gl_matnr) {
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matbuf[nr][0]);
|
|
|
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matbuf[nr][1]);
|
|
|
|
last_gl_matnr = nr;
|
|
|
|
last_ret_val= matbuf[nr][0][3]!=0.0;
|
|
|
|
|
|
|
|
/* matbuf alpha: 0.0 = skip draw, 1.0 = no blending, else blend */
|
|
|
|
if(matbuf[nr][0][3]!= 0.0 && matbuf[nr][0][3]!= 1.0) {
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return last_ret_val;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns 1: when there's alpha needed to be drawn in a 2nd pass */
|
|
|
|
static int init_gl_materials(Object *ob)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
Biiig commit! Thanks to 2-3 weeks of cvs freeze...
Render:
- New; support for dual CPU render (SDL thread)
Currently only works with alternating scanlines, but gives excellent
performance. For both normal render as unified implemented.
Note the "mutex" locks on z-transp buffer render and imbuf loads.
- This has been made possible by major cleanups in render code, especially
getting rid of globals (example Tin Tr Tg Tb Ta for textures) or struct
OSA or using Materials or Texture data to write to.
- Made normal render fully 4x32 floats too, and removed all old optimizes
with chars or shorts.
- Made normal render and unified render use same code for sky and halo
render, giving equal (and better) results for halo render. Old render
now also uses PostProcess options (brightness, mul, gamma)
- Added option ("FBuf") in F10 Output Panel, this keeps a 4x32 bits buffer
after render. Using PostProcess menu you will note an immediate re-
display of image too (32 bits RGBA)
- Added "Hue" and "Saturation" sliders to PostProcess options
- Render module is still not having a "nice" API, but amount of dependencies
went down a lot. Next todo: remove abusive "previewrender" code.
The last main global in Render (struct Render) now can be re-used for fully
controlling a render, to allow multiple "instances" of render to open.
- Renderwindow now displays a smal bar on top with the stats, and keeps the
stats after render too. Including "spare" page support.
Not only easier visible that way, but also to remove the awkward code that
was drawing stats in the Info header (extreme slow on some ATIs too)
- Cleaned up blendef.h and BKE_utildefines.h, these two had overlapping
defines.
- I might have forgotten stuff... and will write a nice doc on the architecture!
2004-12-27 19:28:52 +00:00
|
|
|
extern Material defmaterial; // render module abuse...
|
2002-10-12 11:37:38 +00:00
|
|
|
Material *ma;
|
2005-07-14 12:44:33 +00:00
|
|
|
int a, has_alpha= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(ob->totcol==0) {
|
|
|
|
matbuf[0][0][0]= defmaterial.r;
|
|
|
|
matbuf[0][0][1]= defmaterial.g;
|
|
|
|
matbuf[0][0][2]= defmaterial.b;
|
|
|
|
matbuf[0][0][3]= 1.0;
|
|
|
|
|
|
|
|
matbuf[0][1][0]= defmaterial.specr;
|
|
|
|
matbuf[0][1][1]= defmaterial.specg;
|
|
|
|
matbuf[0][1][2]= defmaterial.specb;
|
|
|
|
matbuf[0][1][3]= 1.0;
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* do material 1 too, for displists! */
|
2005-07-14 12:44:33 +00:00
|
|
|
QUATCOPY(matbuf[1][0], matbuf[0][0]);
|
|
|
|
QUATCOPY(matbuf[1][1], matbuf[0][1]);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for(a=1; a<=ob->totcol; a++) {
|
|
|
|
ma= give_current_material(ob, a);
|
|
|
|
if(ma==NULL) ma= &defmaterial;
|
|
|
|
if(a<MAXMATBUF) {
|
|
|
|
matbuf[a][0][0]= (ma->ref+ma->emit)*ma->r;
|
|
|
|
matbuf[a][0][1]= (ma->ref+ma->emit)*ma->g;
|
|
|
|
matbuf[a][0][2]= (ma->ref+ma->emit)*ma->b;
|
2005-07-14 12:44:33 +00:00
|
|
|
|
|
|
|
/* draw transparent, not in pick-select, nor editmode */
|
|
|
|
if(!(G.f & G_PICKSEL) && (ob->dtx & OB_DRAWTRANSP) && !(G.obedit && G.obedit->data==ob->data)) {
|
|
|
|
if(G.vd->transp) { // drawing the transparent pass
|
|
|
|
if(ma->alpha==1.0) matbuf[a][0][3]= 0.0; // means skip solid
|
|
|
|
else matbuf[a][0][3]= ma->alpha;
|
|
|
|
}
|
|
|
|
else { // normal pass
|
|
|
|
if(ma->alpha==1.0) matbuf[a][0][3]= 1.0;
|
|
|
|
else {
|
|
|
|
matbuf[a][0][3]= 0.0; // means skip transparent
|
|
|
|
has_alpha= 1; // return value, to indicate adding to after-draw queue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
matbuf[a][0][3]= 1.0;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
matbuf[a][1][0]= ma->spec*ma->specr;
|
|
|
|
matbuf[a][1][1]= ma->spec*ma->specg;
|
|
|
|
matbuf[a][1][2]= ma->spec*ma->specb;
|
|
|
|
matbuf[a][1][3]= 1.0;
|
|
|
|
}
|
|
|
|
}
|
2005-03-27 20:39:28 +00:00
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
set_gl_material(-1); // signal for static variable
|
|
|
|
return has_alpha;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***/
|
|
|
|
|
|
|
|
unsigned int rect_desel[16]= {0x707070,0x0,0x0,0x707070,0x407070,0x70cccc,0x407070,0x0,0xaaffff,0xffffff,0x70cccc,0x0,0x70cccc,0xaaffff,0x407070,0x707070};
|
|
|
|
unsigned int rect_sel[16]= {0x707070,0x0,0x0,0x707070,0x702070,0xcc50cc,0x702070,0x0,0xff80ff,0xffffff,0xcc50cc,0x0,0xcc50cc,0xff80ff,0x702070,0x707070};
|
|
|
|
|
|
|
|
unsigned int rectu_desel[16]= {0xff4e4e4e,0xff5c2309,0xff000000,0xff4e4f4d,0xff000000,0xffff9d72,0xffff601c,0xff000000,0xff5d2409,0xffffffff,0xffff9d72,0xff5b2209,0xff4e4e4e,0xff5c2309,0xff010100,0xff4f4f4f};
|
|
|
|
unsigned int rectu_sel[16]= {0xff4e4e4e,0xff403c00,0xff000000,0xff4e4e4d,0xff000000,0xfffff64c,0xffaaa100,0xff000000,0xff403c00,0xffffffff,0xfffff64c,0xff403c00,0xff4f4f4f,0xff403c00,0xff010100,0xff4e4e4e};
|
|
|
|
|
|
|
|
unsigned int rectl_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x124040,0x0,0x4e4e4e,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0x227777,0x55cccc,0x227777,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x124040,0x88ffff,0xffffff,0x55cccc,0x124040,0x777777,0xaaffff,0xaaffff,0x777777,0x0,0x55cccc,0x88ffff,0x227777,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4f4f4f,0x0,0x124040,0x0,0x4e4e4e,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
|
|
|
|
unsigned int rectl_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0x774477,0xcc77cc,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x402440,0xffaaff,0xffffff,0xcc77cc,0x412541,0x777777,0xffaaff,0xffaaff,0x777777,0x10101,0xcc77cc,0xffaaff,0x774477,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4e4e4e,0x10101,0x402440,0x0,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
|
|
|
|
unsigned int rectlus_desel[81]= {0x777777,0x777777,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777,0x777777,0xa9fefe,0xaafefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0xaaffff,0xa9fefe,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xaafefe,0xaaffff,0xaaffff,0x777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0x777777,0xaaffff,0xaaffff,0x777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0x777777,0xaaffff,0xaaffff,0x777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0x777777,0xaaffff,0xaafefe,0xaafefe,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xa9fefe,0xaaffff,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0x777777,0x777777,0x777777,0xa9fefe,0xa9fefe,0xaaffff,0xaaffff,0xaaffff,0x777777,0x777777};
|
|
|
|
unsigned int rectlus_sel[81]= {0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xffaaff,0xffaaff,0xffaaff,0x777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0x777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0x777777,0xffaaff,0xffaaff,0x777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0x777777,0xffaaff,0xffaaff,0xffaaff,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xffaaff,0xffaaff,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0x777777,0x777777,0x777777,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0xffaaff,0x777777,0x777777};
|
|
|
|
unsigned int rectllib_desel[81]= {0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x0,0x4e4f4d,0xb9b237,0xb9b237,0xb9b237,0xff777777,0x0,0xff601c,0xff9d72,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xff777777,0x5d2409,0xffceb8,0xff9d72,0xff9d72,0x5b2209,0xff777777,0xb9b237,0xb9b237,0xff777777,0x10100,0xffceb8,0xffceb8,0xff601c,0x0,0xff777777,0xb9b237,0xb9b237,0xb9b237,0x4e4e4e,0x0,0x5c2309,0x10100,0x4f4f4f,0xb9b237,0xb9b237,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xff777777,0xff777777,0xff777777,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xb9b237,0xff777777,0xff777777};
|
|
|
|
unsigned int rectllib_sel[81]= {0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0x4e4e4e,0x10100,0x403c00,0x0,0x4e4e4d,0xfff64c,0xfff64c,0xfff64c,0xff777777,0x0,0xaaa100,0xfff64c,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xff777777,0x403c00,0xfffde2,0xffffff,0xfff64c,0x403c00,0xff777777,0xfff64c,0xfff64c,0xff777777,0x10100,0xfff64c,0xfffde2,0xaaa100,0x0,0xff777777,0xfff64c,0xfff64c,0xfff64c,0x4f4f4f,0x0,0x403c00,0x10100,0x4e4e4e,0xfff64c,0xfff64c,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xff777777,0xff777777,0xff777777,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xfff64c,0xff777777,0xff777777};
|
|
|
|
|
|
|
|
unsigned int rectl_set[81]= {0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0x4e4e4e,0x10100,0x202020,0x0,0x4e4e4d,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0x0,0xaaa100,0xaaaaaa,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x202020,0xfffde2,0xffffff,0xaaaaaa,0x202020,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0x10100,0xaaaaaa,0xfffde2,0xaaa100,0x0,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0x4f4f4f,0x0,0x202020,0x10100,0x4e4e4e,0xaaaaaa,0xaaaaaa,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777,0xff777777,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xaaaaaa,0xff777777,0xff777777};
|
|
|
|
|
|
|
|
|
|
|
|
static unsigned int colortab[24]=
|
|
|
|
{0x0, 0xFF88FF, 0xFFBBFF,
|
|
|
|
0x403000, 0xFFFF88, 0xFFFFBB,
|
|
|
|
0x104040, 0x66CCCC, 0x77CCCC,
|
|
|
|
0x101040, 0x5588FF, 0x88BBFF,
|
|
|
|
0xFFFFFF
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static float cube[8][3] = {
|
|
|
|
{-1.0, -1.0, -1.0},
|
|
|
|
{-1.0, -1.0, 1.0},
|
|
|
|
{-1.0, 1.0, 1.0},
|
|
|
|
{-1.0, 1.0, -1.0},
|
|
|
|
{ 1.0, -1.0, -1.0},
|
|
|
|
{ 1.0, -1.0, 1.0},
|
|
|
|
{ 1.0, 1.0, 1.0},
|
|
|
|
{ 1.0, 1.0, -1.0},
|
|
|
|
};
|
|
|
|
|
|
|
|
void init_draw_rects(void)
|
|
|
|
{
|
|
|
|
if(G.order==B_ENDIAN) {
|
|
|
|
IMB_convert_rgba_to_abgr(16, rect_desel);
|
|
|
|
IMB_convert_rgba_to_abgr(16, rect_sel);
|
|
|
|
|
|
|
|
IMB_convert_rgba_to_abgr(16, rectu_desel);
|
|
|
|
IMB_convert_rgba_to_abgr(16, rectu_sel);
|
|
|
|
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectl_desel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectl_sel);
|
|
|
|
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectlus_desel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectlus_sel);
|
|
|
|
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectllib_desel);
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectllib_sel);
|
|
|
|
|
|
|
|
IMB_convert_rgba_to_abgr(81, rectl_set);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_icon_centered(float *pos, unsigned int *rect, int rectsize)
|
|
|
|
{
|
|
|
|
float hsize= (float) rectsize/2.0;
|
|
|
|
GLubyte dummy= 0;
|
|
|
|
|
|
|
|
glRasterPos3fv(pos);
|
|
|
|
|
|
|
|
/* use bitmap to shift rasterpos in pixels */
|
2003-05-02 10:44:14 +00:00
|
|
|
glBitmap(0, 0, 0.0, 0.0, -hsize, -hsize, &dummy);
|
2004-03-06 19:32:33 +00:00
|
|
|
#if defined (__sun__) || defined ( __sun ) || defined (__sparc) || defined (__sparc__)
|
2004-06-16 11:34:45 +00:00
|
|
|
glFlush();
|
2003-07-11 20:02:52 +00:00
|
|
|
#endif
|
2002-10-12 11:37:38 +00:00
|
|
|
glDrawPixels(rectsize, rectsize, GL_RGBA, GL_UNSIGNED_BYTE, rect);
|
|
|
|
}
|
|
|
|
|
2005-03-25 11:17:59 +00:00
|
|
|
/* bad frontbuffer call... because it is used in transform after force_draw() */
|
2002-10-12 11:37:38 +00:00
|
|
|
void helpline(float *vec)
|
|
|
|
{
|
2004-05-09 21:15:05 +00:00
|
|
|
float vecrot[3], cent[2];
|
|
|
|
short mval[2];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
VECCOPY(vecrot, vec);
|
|
|
|
if(G.obedit) Mat4MulVecfl(G.obedit->obmat, vecrot);
|
2005-02-22 16:50:04 +00:00
|
|
|
else if(G.obpose) Mat4MulVecfl(G.obpose->obmat, vecrot);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
getmouseco_areawin(mval);
|
2004-05-09 21:15:05 +00:00
|
|
|
project_float(vecrot, cent); // no overflow in extreme cases
|
2005-03-25 11:17:59 +00:00
|
|
|
if(cent[0]!=3200.0f) {
|
|
|
|
persp(PERSP_WIN);
|
|
|
|
|
|
|
|
glDrawBuffer(GL_FRONT);
|
|
|
|
|
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-25 11:17:59 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex2sv(mval);
|
|
|
|
glVertex2fv(cent);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
persp(PERSP_VIEW);
|
|
|
|
glFlush(); // flush display for frontbuffer
|
|
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void drawaxes(float size)
|
|
|
|
{
|
|
|
|
int axis;
|
|
|
|
|
|
|
|
for (axis=0; axis<3; axis++) {
|
|
|
|
float v1[3]= {0.0, 0.0, 0.0};
|
|
|
|
float v2[3]= {0.0, 0.0, 0.0};
|
|
|
|
int arrow_axis= (axis==0)?1:0;
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
|
|
|
v2[axis]= size;
|
|
|
|
glVertex3fv(v1);
|
|
|
|
glVertex3fv(v2);
|
|
|
|
|
|
|
|
v1[axis]= size*0.8;
|
|
|
|
v1[arrow_axis]= -size*0.125;
|
|
|
|
glVertex3fv(v1);
|
|
|
|
glVertex3fv(v2);
|
|
|
|
|
|
|
|
v1[arrow_axis]= size*0.125;
|
|
|
|
glVertex3fv(v1);
|
|
|
|
glVertex3fv(v2);
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
v2[axis]+= size*0.125;
|
|
|
|
glRasterPos3fv(v2);
|
2004-05-10 20:14:21 +00:00
|
|
|
|
|
|
|
// patch for 3d cards crashing on glSelect for text drawing (IBM)
|
|
|
|
if((G.f & G_PICKSEL) == 0) {
|
|
|
|
if (axis==0)
|
|
|
|
BMF_DrawString(G.font, "x");
|
|
|
|
else if (axis==1)
|
|
|
|
BMF_DrawString(G.font, "y");
|
|
|
|
else
|
|
|
|
BMF_DrawString(G.font, "z");
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-19 12:17:06 +00:00
|
|
|
|
|
|
|
void drawsolidcube(float size)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
float n[3];
|
|
|
|
|
2005-03-19 12:17:06 +00:00
|
|
|
glPushMatrix();
|
|
|
|
glScalef(size, size, size);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
n[0]=0; n[1]=0; n[2]=0;
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[0]= -1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]); glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
|
|
n[0]=0;
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[1]= -1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]); glVertex3fv(cube[5]); glVertex3fv(cube[1]);
|
|
|
|
n[1]=0;
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[0]= 1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[4]); glVertex3fv(cube[7]); glVertex3fv(cube[6]); glVertex3fv(cube[5]);
|
|
|
|
n[0]=0;
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[1]= 1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[3]); glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
|
|
n[1]=0;
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[2]= 1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]); glVertex3fv(cube[6]); glVertex3fv(cube[2]);
|
|
|
|
n[2]=0;
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
n[2]= -1.0;
|
|
|
|
glNormal3fv(n);
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]); glVertex3fv(cube[0]); glVertex3fv(cube[3]);
|
|
|
|
glEnd();
|
2005-03-19 12:17:06 +00:00
|
|
|
|
|
|
|
glPopMatrix();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void drawcube(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
static void drawcube_size(float *size)
|
|
|
|
{
|
|
|
|
|
|
|
|
glPushMatrix();
|
|
|
|
glScalef(size[0], size[1], size[2]);
|
|
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[1]);glVertex3fv(cube[2]); glVertex3fv(cube[3]);
|
|
|
|
glVertex3fv(cube[0]); glVertex3fv(cube[4]);glVertex3fv(cube[5]); glVertex3fv(cube[6]);
|
|
|
|
glVertex3fv(cube[7]); glVertex3fv(cube[4]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[1]); glVertex3fv(cube[5]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[2]); glVertex3fv(cube[6]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(cube[3]); glVertex3fv(cube[7]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static void tekenshadbuflimits(Lamp *la, float mat[][4])
|
|
|
|
{
|
|
|
|
float sta[3], end[3], lavec[3];
|
|
|
|
|
|
|
|
lavec[0]= -mat[2][0];
|
|
|
|
lavec[1]= -mat[2][1];
|
|
|
|
lavec[2]= -mat[2][2];
|
|
|
|
Normalise(lavec);
|
|
|
|
|
|
|
|
sta[0]= mat[3][0]+ la->clipsta*lavec[0];
|
|
|
|
sta[1]= mat[3][1]+ la->clipsta*lavec[1];
|
|
|
|
sta[2]= mat[3][2]+ la->clipsta*lavec[2];
|
|
|
|
|
|
|
|
end[0]= mat[3][0]+ la->clipend*lavec[0];
|
|
|
|
end[1]= mat[3][1]+ la->clipend*lavec[1];
|
|
|
|
end[2]= mat[3][2]+ la->clipend*lavec[2];
|
|
|
|
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(sta);
|
|
|
|
glVertex3fv(end);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glPointSize(3.0);
|
2004-07-10 21:35:17 +00:00
|
|
|
bglBegin(GL_POINTS);
|
|
|
|
bglVertex3fv(sta);
|
|
|
|
bglVertex3fv(end);
|
|
|
|
bglEnd();
|
2002-10-12 11:37:38 +00:00
|
|
|
glPointSize(1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void spotvolume(float *lvec, float *vvec, float inp)
|
|
|
|
{
|
2003-04-28 14:43:20 +00:00
|
|
|
/* camera is at 0,0,0 */
|
2002-10-12 11:37:38 +00:00
|
|
|
float temp[3],plane[3],mat1[3][3],mat2[3][3],mat3[3][3],mat4[3][3],q[4],co,si,hoek;
|
|
|
|
|
|
|
|
Normalise(lvec);
|
2003-04-28 14:43:20 +00:00
|
|
|
Normalise(vvec); /* is this the correct vector ? */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
Crossf(temp,vvec,lvec); /* equation for a plane through vvec en lvec */
|
|
|
|
Crossf(plane,lvec,temp); /* a plane perpendicular to this, parrallel with lvec */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
Normalise(plane);
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* now we've got two equations: one of a cone and one of a plane, but we have
|
|
|
|
three unknowns. We remove one unkown by rotating the plane to z=0 (the plane normal) */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* rotate around cross product vector of (0,0,1) and plane normal, dot product degrees */
|
|
|
|
/* according definition, we derive cross product is (plane[1],-plane[0],0), en cos = plane[2]);*/
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* translating this comment to english didnt really help me understanding the math! :-) (ton) */
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
q[1] = plane[1] ;
|
|
|
|
q[2] = -plane[0] ;
|
|
|
|
q[3] = 0 ;
|
|
|
|
Normalise(&q[1]);
|
|
|
|
|
|
|
|
hoek = saacos(plane[2])/2.0;
|
|
|
|
co = cos(hoek);
|
|
|
|
si = sqrt(1-co*co);
|
|
|
|
|
|
|
|
q[0] = co;
|
|
|
|
q[1] *= si;
|
|
|
|
q[2] *= si;
|
|
|
|
q[3] = 0;
|
|
|
|
|
|
|
|
QuatToMat3(q,mat1);
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* rotate lamp vector now over acos(inp) degrees */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
vvec[0] = lvec[0] ;
|
|
|
|
vvec[1] = lvec[1] ;
|
|
|
|
vvec[2] = lvec[2] ;
|
|
|
|
|
|
|
|
Mat3One(mat2);
|
|
|
|
co = inp;
|
|
|
|
si = sqrt(1-inp*inp);
|
|
|
|
|
|
|
|
mat2[0][0] = co;
|
|
|
|
mat2[1][0] = -si;
|
|
|
|
mat2[0][1] = si;
|
|
|
|
mat2[1][1] = co;
|
|
|
|
Mat3MulMat3(mat3,mat2,mat1);
|
|
|
|
|
|
|
|
mat2[1][0] = si;
|
|
|
|
mat2[0][1] = -si;
|
|
|
|
Mat3MulMat3(mat4,mat2,mat1);
|
|
|
|
Mat3Transp(mat1);
|
|
|
|
|
|
|
|
Mat3MulMat3(mat2,mat1,mat3);
|
|
|
|
Mat3MulVecfl(mat2,lvec);
|
|
|
|
Mat3MulMat3(mat2,mat1,mat4);
|
|
|
|
Mat3MulVecfl(mat2,vvec);
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void drawlamp(Object *ob)
|
|
|
|
{
|
|
|
|
Lamp *la;
|
|
|
|
float vec[3], lvec[3], vvec[3],x,y,z;
|
|
|
|
|
|
|
|
la= ob->data;
|
|
|
|
vec[0]=vec[1]=vec[2]= 0.0;
|
|
|
|
|
|
|
|
setlinestyle(4);
|
|
|
|
|
Major update, all implemented a bit in a hurry, and probably will need bugfixes at some point.
Extended the range of the depth and cdepth parameters as reqested by leope.
Bumpmapping should now be a bit more similar to the Blender render.
Added support for all remaining lightsources in yafray, tried to make use of
as much of the existing Blender parameters as possible.
Blender Lamp: added switch to enable rendering with shadowbuffer ('softlight' in yafray).
All other parameters are similar to the Blender settings, for yafray both the
bias parameter and the shadowbuffer size can be lower than equivalent Blender
settings, since the yafray buffer is floating point. Remember that 6 shadowmaps
are created in this case, so can use quite a bit of memory with large
buffer settings.
When 'ray shadow' is enabled for this lamp type, it is possible to set a light
radius to create a spherical arealight source ('spherelight' in yafray),
when this is 0, it is exported as a pointlight instead.
Blender Spot: as in Blender now supports 'halo' rendering.
Halo spots always use shadowbuffers, so when enabled the buttons for shadowmap
settings will appear. The 'ray shadow' button can still be used to disable
shadows cast onto other objects, independent of halo shadows.
One thing to remember, halo's don't work with empty backgrounds, something must
be behind the spotlight for it to be visible.
And finally, the photonlight:
probably the most confusing (as more things related to yafray), the photonlight
is not a real lightsource, it is only used as a source to shoot photons from.
Since indirect lighting is already supported (and looks better as well)
only caustics mode is supported.
So to be able to use this properly other lightsources must be used with it.
For the photonlighting to be 'correct' similar lightsettings as for the 'source'
light are needed.
Probably the best way to do this, when you are happy with the lighting setup
you have, and want to add caustics, copy the light you want to enable for
caustics (shift-D) and leave everything as is, then change the mode to
'Photon'.
To not waiste any photons, the photonlight behaves similar to the spotlight,
you can set the width of the beam with the 'angle' parameter. Make sure
that any object that needs to cast caustics is within that beam, make
the beam width as small as possible to tightly fit the object.
The following other parameters can be set:
-photons: the number of photons to shoot.
-search: the number of photons to search when rendering, the higher,
the blurrier the caustics.
-depth: the amount of photon bounces allowed, since the primary use is for
caustics, you probably best set this to the same level as the 'ray depth'
parameter.
-Blur: this controls the amount of caustics blur (in addition to the search
parameter), very low values will cause very sharp caustics, which when used
with a low photonnumber, probably lead to only some noisy specks being rendered.
-Use QMC: Use quasi monte carlo sampling, can lead to cleaner results, but also
can sometimes cause patterns.
Since the photonlight has no meaning to Blender, when using photonlights and
switching back to the internal render, the light doesn't do anything, and no
type button will be selected. The lightsource can still be selected, but unless
switching to yafray, no parameters can set.
Apologies to Anexus, I had no time to really do something with your code,
I'll still look at it later, to see if I can improve anything in my implementation.
2004-07-28 22:37:12 +00:00
|
|
|
/* yafray: for photonlight also draw lightcone as for spot */
|
|
|
|
if ((la->type==LA_SPOT) || (la->type==LA_YF_PHOTON)) {
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
lvec[0]=lvec[1]= 0.0;
|
|
|
|
lvec[2] = 1.0;
|
|
|
|
x = G.vd->persmat[0][2];
|
|
|
|
y = G.vd->persmat[1][2];
|
|
|
|
z = G.vd->persmat[2][2];
|
|
|
|
vvec[0]= x*ob->obmat[0][0] + y*ob->obmat[0][1] + z*ob->obmat[0][2];
|
|
|
|
vvec[1]= x*ob->obmat[1][0] + y*ob->obmat[1][1] + z*ob->obmat[1][2];
|
|
|
|
vvec[2]= x*ob->obmat[2][0] + y*ob->obmat[2][1] + z*ob->obmat[2][2];
|
|
|
|
|
|
|
|
y = cos( M_PI*la->spotsize/360.0 );
|
|
|
|
spotvolume(lvec, vvec, y);
|
|
|
|
x = -la->dist;
|
|
|
|
lvec[0] *= x ;
|
|
|
|
lvec[1] *= x ;
|
|
|
|
lvec[2] *= x;
|
|
|
|
vvec[0] *= x ;
|
|
|
|
vvec[1] *= x ;
|
|
|
|
vvec[2] *= x;
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(vvec);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glVertex3fv(lvec);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
z = x*sqrt(1.0 - y*y);
|
|
|
|
x *= y;
|
|
|
|
|
|
|
|
glTranslatef(0.0 , 0.0 , x);
|
|
|
|
if(la->mode & LA_SQUARE) {
|
|
|
|
vvec[0]= fabs(z);
|
|
|
|
vvec[1]= fabs(z);
|
|
|
|
vvec[2]= 0.0;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3fv(vvec);
|
|
|
|
vvec[1]= -fabs(z);
|
|
|
|
glVertex3fv(vvec);
|
|
|
|
vvec[0]= -fabs(z);
|
|
|
|
glVertex3fv(vvec);
|
|
|
|
vvec[1]= fabs(z);
|
|
|
|
glVertex3fv(vvec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else circ(0.0, 0.0, fabs(z));
|
|
|
|
|
|
|
|
}
|
|
|
|
else if ELEM(la->type, LA_HEMI, LA_SUN) {
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
vec[2]= -la->dist;
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else {
|
Area lights and more...
- New lamp type added "Area". This uses the radiosity formula (Stoke) to
calculate the amount of energy which is received from a plane. Result
is very nice local light, which nicely spreads out.
- Area lamps have a 'gamma' option to control the light spread
- Area lamp builtin sizes: square, rect, cube & box. Only first 2 are
implemented. Set a type, and define area size
- Button area size won't affect the amount of energy. But scaling the lamp
in 3d window will do. This is to cover the case when you scale an entire
scene, the light then will remain identical
If you just want to change area lamp size, use buttons when you dont want
to make the scene too bright or too dark
- Since area lights realistically are sensitive for distance (quadratic), the
effect it has is quickly too much, or too less. For this the "Dist" value
in Lamp can be used. Set it at Dist=10 to have reasonable light on distance
10 Blender units (assumed you didnt scale lamp object).
- I tried square sized specularity, but this looked totally weird. Not
committed
- Plan is to extend area light with 3d dimensions, boxes and cubes.
- Note that area light is one-sided, towards negative Z. I need to design
a nice drawing method for it.
Area Shadow
- Since there are a lot of variables associated with soft shadow, they now
only are available for Area lights. Allowing spot & normal lamp to have
soft shadow is possible though, but will require a reorganisation of the
Lamp buttons. Is a point of research & feedback still.
- Apart from area size, you now can individually set amount of samples in
X and Y direction (for area lamp type 'Rect'). For box type area lamp,
this will become 3 dimensions
- Area shadows have four options:
"Clip circle" : only uses a circular shape of samples, gives smoother
results
"Dither" : use a 2x2 dither mask
"Jitter" : applys a pseudo-random offset to samples
"Umbra" : extra emphasis on area that's fully in shadow.
Raytrace speedup
- improved filling in faces in Octree. Large faces occupied too many nodes
- added a coherence check; rays fired sequentially that begin and end in
same octree nodes, and that don't intersect, are quickly rejected
- rendering shadow scenes benefits from this 20-40%. My statue test monkey
file now renders in 19 seconds (was 30).
Plus:
- adjusted specular max to 511, and made sure Blinn spec has again this
incredible small spec size
- for UI rounded theme: the color "button" displayed RGB color too dark
- fixed countall() function, to also include Subsurf totals
- removed setting the 'near' clipping for pressing dot-key numpad
- when you press the buttons-window icon for 'Shading Context' the context
automaticilly switches as with F5 hotkey
Please be warned that this is not a release... settings in files might not
work as it did, nor guaranteed to work when we do a release. :)
2003-12-29 16:52:51 +00:00
|
|
|
if(la->type==LA_AREA) {
|
|
|
|
setlinestyle(0);
|
|
|
|
if(la->area_shape==LA_AREA_SQUARE)
|
|
|
|
fdrawbox(-la->area_size*0.5, -la->area_size*0.5, la->area_size*0.5, la->area_size*0.5);
|
|
|
|
else if(la->area_shape==LA_AREA_RECT)
|
|
|
|
fdrawbox(-la->area_size*0.5, -la->area_sizey*0.5, la->area_size*0.5, la->area_sizey*0.5);
|
2004-01-18 16:55:07 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3f(0.0,0.0,0.0);
|
|
|
|
glVertex3f(0.0,0.0,-la->dist);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
Area lights and more...
- New lamp type added "Area". This uses the radiosity formula (Stoke) to
calculate the amount of energy which is received from a plane. Result
is very nice local light, which nicely spreads out.
- Area lamps have a 'gamma' option to control the light spread
- Area lamp builtin sizes: square, rect, cube & box. Only first 2 are
implemented. Set a type, and define area size
- Button area size won't affect the amount of energy. But scaling the lamp
in 3d window will do. This is to cover the case when you scale an entire
scene, the light then will remain identical
If you just want to change area lamp size, use buttons when you dont want
to make the scene too bright or too dark
- Since area lights realistically are sensitive for distance (quadratic), the
effect it has is quickly too much, or too less. For this the "Dist" value
in Lamp can be used. Set it at Dist=10 to have reasonable light on distance
10 Blender units (assumed you didnt scale lamp object).
- I tried square sized specularity, but this looked totally weird. Not
committed
- Plan is to extend area light with 3d dimensions, boxes and cubes.
- Note that area light is one-sided, towards negative Z. I need to design
a nice drawing method for it.
Area Shadow
- Since there are a lot of variables associated with soft shadow, they now
only are available for Area lights. Allowing spot & normal lamp to have
soft shadow is possible though, but will require a reorganisation of the
Lamp buttons. Is a point of research & feedback still.
- Apart from area size, you now can individually set amount of samples in
X and Y direction (for area lamp type 'Rect'). For box type area lamp,
this will become 3 dimensions
- Area shadows have four options:
"Clip circle" : only uses a circular shape of samples, gives smoother
results
"Dither" : use a 2x2 dither mask
"Jitter" : applys a pseudo-random offset to samples
"Umbra" : extra emphasis on area that's fully in shadow.
Raytrace speedup
- improved filling in faces in Octree. Large faces occupied too many nodes
- added a coherence check; rays fired sequentially that begin and end in
same octree nodes, and that don't intersect, are quickly rejected
- rendering shadow scenes benefits from this 20-40%. My statue test monkey
file now renders in 19 seconds (was 30).
Plus:
- adjusted specular max to 511, and made sure Blinn spec has again this
incredible small spec size
- for UI rounded theme: the color "button" displayed RGB color too dark
- fixed countall() function, to also include Subsurf totals
- removed setting the 'near' clipping for pressing dot-key numpad
- when you press the buttons-window icon for 'Shading Context' the context
automaticilly switches as with F5 hotkey
Please be warned that this is not a release... settings in files might not
work as it did, nor guaranteed to work when we do a release. :)
2003-12-29 16:52:51 +00:00
|
|
|
}
|
|
|
|
else if(la->mode & LA_SPHERE) {
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
float tmat[4][4], imat[4][4];
|
|
|
|
|
|
|
|
vec[0]= vec[1]= vec[2]= 0.0;
|
|
|
|
mygetmatrix(tmat);
|
|
|
|
Mat4Invert(imat, tmat);
|
|
|
|
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, la->dist, imat);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glPushMatrix();
|
2005-03-26 21:41:39 +00:00
|
|
|
glLoadMatrixf(G.vd->viewmat);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
VECCOPY(vec, ob->obmat[3]);
|
|
|
|
|
Area lights and more...
- New lamp type added "Area". This uses the radiosity formula (Stoke) to
calculate the amount of energy which is received from a plane. Result
is very nice local light, which nicely spreads out.
- Area lamps have a 'gamma' option to control the light spread
- Area lamp builtin sizes: square, rect, cube & box. Only first 2 are
implemented. Set a type, and define area size
- Button area size won't affect the amount of energy. But scaling the lamp
in 3d window will do. This is to cover the case when you scale an entire
scene, the light then will remain identical
If you just want to change area lamp size, use buttons when you dont want
to make the scene too bright or too dark
- Since area lights realistically are sensitive for distance (quadratic), the
effect it has is quickly too much, or too less. For this the "Dist" value
in Lamp can be used. Set it at Dist=10 to have reasonable light on distance
10 Blender units (assumed you didnt scale lamp object).
- I tried square sized specularity, but this looked totally weird. Not
committed
- Plan is to extend area light with 3d dimensions, boxes and cubes.
- Note that area light is one-sided, towards negative Z. I need to design
a nice drawing method for it.
Area Shadow
- Since there are a lot of variables associated with soft shadow, they now
only are available for Area lights. Allowing spot & normal lamp to have
soft shadow is possible though, but will require a reorganisation of the
Lamp buttons. Is a point of research & feedback still.
- Apart from area size, you now can individually set amount of samples in
X and Y direction (for area lamp type 'Rect'). For box type area lamp,
this will become 3 dimensions
- Area shadows have four options:
"Clip circle" : only uses a circular shape of samples, gives smoother
results
"Dither" : use a 2x2 dither mask
"Jitter" : applys a pseudo-random offset to samples
"Umbra" : extra emphasis on area that's fully in shadow.
Raytrace speedup
- improved filling in faces in Octree. Large faces occupied too many nodes
- added a coherence check; rays fired sequentially that begin and end in
same octree nodes, and that don't intersect, are quickly rejected
- rendering shadow scenes benefits from this 20-40%. My statue test monkey
file now renders in 19 seconds (was 30).
Plus:
- adjusted specular max to 511, and made sure Blinn spec has again this
incredible small spec size
- for UI rounded theme: the color "button" displayed RGB color too dark
- fixed countall() function, to also include Subsurf totals
- removed setting the 'near' clipping for pressing dot-key numpad
- when you press the buttons-window icon for 'Shading Context' the context
automaticilly switches as with F5 hotkey
Please be warned that this is not a release... settings in files might not
work as it did, nor guaranteed to work when we do a release. :)
2003-12-29 16:52:51 +00:00
|
|
|
setlinestyle(3);
|
2002-10-12 11:37:38 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
vec[2]= 0;
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
2005-03-27 20:39:28 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(la->type==LA_SPOT && (la->mode & LA_SHAD) ) {
|
|
|
|
tekenshadbuflimits(la, ob->obmat);
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
glPopMatrix();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_limit_line(float sta, float end, unsigned int col)
|
|
|
|
{
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3f(0.0, 0.0, -sta);
|
|
|
|
glVertex3f(0.0, 0.0, -end);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glPointSize(3.0);
|
|
|
|
glBegin(GL_POINTS);
|
|
|
|
cpack(col);
|
|
|
|
glVertex3f(0.0, 0.0, -sta);
|
|
|
|
glVertex3f(0.0, 0.0, -end);
|
|
|
|
glEnd();
|
|
|
|
glPointSize(1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-13 19:22:41 +00:00
|
|
|
/* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */
|
|
|
|
static void draw_focus_cross(float dist, float size)
|
|
|
|
{
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3f(-size, 0.f, -dist);
|
|
|
|
glVertex3f(size, 0.f, -dist);
|
|
|
|
glVertex3f(0.f, -size, -dist);
|
|
|
|
glVertex3f(0.f, size, -dist);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
void drawcamera(Object *ob)
|
|
|
|
{
|
2003-04-28 14:43:20 +00:00
|
|
|
/* a standing up pyramid with (0,0,0) as top */
|
2002-10-12 11:37:38 +00:00
|
|
|
Camera *cam;
|
|
|
|
World *wrld;
|
|
|
|
float vec[8][4], tmat[4][4], fac, facx, facy, depth;
|
|
|
|
|
|
|
|
cam= ob->data;
|
2004-07-21 21:27:14 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glDisable(GL_CULL_FACE);
|
|
|
|
|
2005-01-30 11:25:27 +00:00
|
|
|
if(G.vd->persp>=2 && cam->type==CAM_ORTHO && ob==G.vd->camera) {
|
|
|
|
facx= 0.5*cam->ortho_scale*1.28;
|
|
|
|
facy= 0.5*cam->ortho_scale*1.024;
|
|
|
|
depth= -cam->clipsta-0.1;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
fac= cam->drawsize;
|
|
|
|
if(G.vd->persp>=2 && ob==G.vd->camera) fac= cam->clipsta+0.1; /* that way it's always visible */
|
|
|
|
|
|
|
|
depth= - fac*cam->lens/16.0;
|
|
|
|
facx= fac*1.28;
|
|
|
|
facy= fac*1.024;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-01-30 11:25:27 +00:00
|
|
|
vec[0][0]= 0.0; vec[0][1]= 0.0; vec[0][2]= 0.001; /* GLBUG: for picking at iris Entry (well thats old!) */
|
2002-10-12 11:37:38 +00:00
|
|
|
vec[1][0]= facx; vec[1][1]= facy; vec[1][2]= depth;
|
|
|
|
vec[2][0]= facx; vec[2][1]= -facy; vec[2][2]= depth;
|
|
|
|
vec[3][0]= -facx; vec[3][1]= -facy; vec[3][2]= depth;
|
|
|
|
vec[4][0]= -facx; vec[4][1]= facy; vec[4][2]= depth;
|
|
|
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3fv(vec[1]);
|
|
|
|
glVertex3fv(vec[2]);
|
|
|
|
glVertex3fv(vec[3]);
|
|
|
|
glVertex3fv(vec[4]);
|
|
|
|
glEnd();
|
|
|
|
|
2005-01-30 11:25:27 +00:00
|
|
|
if(G.vd->persp>=2 && ob==G.vd->camera) return;
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2002-10-12 11:37:38 +00:00
|
|
|
glVertex3fv(vec[2]);
|
2005-01-30 11:25:27 +00:00
|
|
|
glVertex3fv(vec[0]);
|
2002-10-12 11:37:38 +00:00
|
|
|
glVertex3fv(vec[1]);
|
2005-01-30 11:25:27 +00:00
|
|
|
glVertex3fv(vec[4]);
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
glVertex3fv(vec[3]);
|
2002-10-12 11:37:38 +00:00
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* arrow on top */
|
2002-10-12 11:37:38 +00:00
|
|
|
vec[0][2]= depth;
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
|
|
|
vec[0][0]= -0.2*cam->drawsize;
|
|
|
|
vec[0][1]= cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
vec[0][0]= 0.2*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
vec[0][0]= -0.2*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
|
|
|
|
vec[0][0]= -0.4*cam->drawsize;
|
|
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
vec[0][0]= 0.0;
|
|
|
|
vec[0][1]= 2.0*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
vec[0][0]= 0.4*cam->drawsize;
|
|
|
|
vec[0][1]= 1.6*cam->drawsize;
|
|
|
|
glVertex3fv(vec[0]);
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
if(cam->flag & (CAM_SHOWLIMITS+CAM_SHOWMIST)) {
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
Mat4CpyMat4(vec, ob->obmat);
|
|
|
|
Mat4Ortho(vec);
|
|
|
|
mymultmatrix(vec);
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, tmat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
2004-07-13 19:22:41 +00:00
|
|
|
if(cam->flag & CAM_SHOWLIMITS) {
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
draw_limit_line(cam->clipsta, cam->clipend, 0x77FFFF);
|
2004-07-13 19:22:41 +00:00
|
|
|
/* yafray: dof focus point */
|
|
|
|
if (G.scene->r.renderer==R_YAFRAY) draw_focus_cross(cam->YF_dofdist, cam->drawsize);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
wrld= G.scene->world;
|
|
|
|
if(cam->flag & CAM_SHOWMIST)
|
|
|
|
if(wrld) draw_limit_line(wrld->miststa, wrld->miststa+wrld->mistdist, 0xFFFFFF);
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, tmat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tekenvertslatt(short sel)
|
|
|
|
{
|
|
|
|
Lattice *lt;
|
|
|
|
BPoint *bp;
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
float size;
|
2002-10-12 11:37:38 +00:00
|
|
|
int a, uxt, u, vxt, v, wxt, w;
|
|
|
|
|
Another mega commit... loadsof restructure, and a pretty good one! :)
- changed the BIF_DrawString() function. it used to work different for
AA fonts as for default fonts. Now it's identical. Setting color for fonts
can just be done with OpenGL, for both font types.
Removed: BIF_DrawStringRGB()
- added theme color options for Buttons
- recoded DefButton, so it automatically chooses the right color.
- had to remove a 1000 uiBlockSetCol() calls for that reason...
- uiBlockSetCol() still works, to override automatic color
- removed entirely the silly old color system (BIFColorID). All color
calls can now be done with a BIF_ThemeColor() call, including fonts and
buttons and opengl stuff
- all buttons in button header have headercolor by default
- recoded drawing icons, it was a really bad & old loop doing manually
colorshading and blending... which was per pixel a load of code!
Now it uses a single OpenGL call to blend or colorize. Quite faster!
- (as test, for review) icons don't colorize anymore with button color,
but have a different alpha to blend in (when not active)
- recoded the entire interface_draw.c file...:
- drawing buttons is separated in three parts:
1. main drawing function for text and icons
2. free definable callback for button itself
3. free definable callback for slider
- removed a load of redundant code for this!
- coded a minimal theme, and adjusted Matt's buttons to match new
callback system
- adding new drawing themes is piece of cake now
- for coders, default 'themes' to be aware of:
UI_EMBOSS : the themable drawing style
UI_EMBOSSP: the pulldown menu system (apart from color not themable)
UI_EMBOSSN: draw nothing, only text and/or icon
UI_EMBOSSM: minimal theme, still in use for Logic and Constraintsa
this can be set with uiBlockSetEmboss(block) or in the uiNewBlock() call.
TODO: make UI API call for button alignment
(plus removed another series of warnings from code...)
Plus: fixed bug in Matts commit: he used a 'short' button for an 'int'
2003-10-20 15:40:20 +00:00
|
|
|
size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
glPointSize(size);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
if(sel) BIF_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
else BIF_ThemeColor(TH_VERTEX);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-07-10 21:35:17 +00:00
|
|
|
bglBegin(GL_POINTS);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
bp= editLatt->def;
|
|
|
|
lt= editLatt;
|
|
|
|
|
|
|
|
if(lt->flag & LT_OUTSIDE) {
|
|
|
|
|
|
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
|
|
if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
|
|
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
|
|
if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
|
|
|
|
|
|
|
|
for(u=0; u<lt->pntsu; u++, bp++) {
|
|
|
|
if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
|
|
|
|
if(uxt || vxt || wxt) {
|
|
|
|
if(bp->hide==0) {
|
2004-07-10 21:35:17 +00:00
|
|
|
if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
|
|
|
while(a--) {
|
|
|
|
if(bp->hide==0) {
|
2004-07-10 21:35:17 +00:00
|
|
|
if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
glPointSize(1.0);
|
2004-07-10 21:35:17 +00:00
|
|
|
bglEnd();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void calc_lattverts(void)
|
|
|
|
{
|
|
|
|
BPoint *bp;
|
|
|
|
float mat[4][4];
|
|
|
|
int a;
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
|
|
|
bp= editLatt->def;
|
|
|
|
|
|
|
|
a= editLatt->pntsu*editLatt->pntsv*editLatt->pntsw;
|
|
|
|
while(a--) {
|
|
|
|
project_short(bp->vec, bp->s);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void calc_lattverts_ext(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
areawinset(curarea->win);
|
2003-10-21 12:23:38 +00:00
|
|
|
persp(PERSP_VIEW);
|
2002-10-12 11:37:38 +00:00
|
|
|
mymultmatrix(G.obedit->obmat);
|
|
|
|
calc_lattverts();
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void drawlattice(Object *ob)
|
|
|
|
{
|
|
|
|
Lattice *lt;
|
|
|
|
BPoint *bp, *bpu;
|
|
|
|
int u, v, w, dv, dw, uxt, vxt, wxt;
|
|
|
|
|
|
|
|
lt= ob->data;
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
bp= editLatt->def;
|
|
|
|
|
|
|
|
cpack(0x004000);
|
|
|
|
}
|
|
|
|
else {
|
2004-09-14 19:03:11 +00:00
|
|
|
lattice_modifier(ob, 's');
|
2002-10-12 11:37:38 +00:00
|
|
|
bp= lt->def;
|
|
|
|
}
|
|
|
|
|
|
|
|
dv= lt->pntsu;
|
|
|
|
dw= dv*lt->pntsv;
|
|
|
|
|
|
|
|
if(lt->flag & LT_OUTSIDE) {
|
|
|
|
|
|
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
|
|
|
|
|
|
if(w==0 || w==lt->pntsw-1) wxt= 1; else wxt= 0;
|
|
|
|
|
|
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
|
|
|
|
|
|
if(v==0 || v==lt->pntsv-1) vxt= 1; else vxt= 0;
|
|
|
|
|
|
|
|
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
|
|
|
|
|
|
|
if(u==0 || u==lt->pntsu-1) uxt= 1; else uxt= 0;
|
|
|
|
|
|
|
|
if(uxt || vxt || wxt) {
|
|
|
|
|
|
|
|
if(w && (uxt || vxt)) {
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
if(v && (uxt || wxt)) {
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
if(u && (vxt || wxt)) {
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bpu= bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(w=0; w<lt->pntsw; w++) {
|
|
|
|
|
|
|
|
for(v=0; v<lt->pntsv; v++) {
|
|
|
|
|
|
|
|
for(u=0, bpu=0; u<lt->pntsu; u++, bp++) {
|
|
|
|
|
|
|
|
if(w) {
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv( (bp-dw)->vec ); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
if(v) {
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv( (bp-dv)->vec ); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
if(u) {
|
|
|
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(bpu->vec); glVertex3fv(bp->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
bpu= bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
|
|
|
|
calc_lattverts();
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
tekenvertslatt(0);
|
|
|
|
tekenvertslatt(1);
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-09-14 19:03:11 +00:00
|
|
|
else lattice_modifier(ob, 'e');
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ***************** ******************** */
|
|
|
|
|
EditMesh refactory + undo recode
The changelog is very long... it's on the web too:
http://www.blender3d.org/cms/Mesh_editing_rewrite.425.0.html
EditMesh refactor notes (user)
**** New selection modes
When entering Edit Mode for a Mesh, you now have the choice for three selection modes. These are shown as icons in the 3D header (hotkey is being searched for!).
- Vertex Select
Select vertices as usual, fully compatible with how previous version work
- Edge Select
Vertices are not drawn anymore, and selections happen by default on the edges. It is a true edge select, meaning that you can select three out of four edges in a face, without automatic having the 4th edge selected.
- Face Select
Instead of vertices, now selection 'points' are drawn in the face centers. Selected faces also get a colored outline, like for edges. This also is true face select, for each face individual regardless selection status of its vertices or edges.
While holding SHIFT, and press a selection mode, you can also combine the above choices. Now selection becomes mixed, and will behave as expected.
For example; in Edge+Face select mode, selecting the 4 edges of a face will select the face too.
The selection modes and optional drawing modes (like transparant faces, normals, or solid drawing) all work together. All of Blender's mesh editing tools now react to the correct selection mode as well.
Most noticeable it's in:
**** Extrude
Extruding in Edge or Face Select mode allows much more precise control over what's extruded and what should be excluded. Try for example a checker pattern selection, and extrude it.
New is the fixed translation when faces are extruded. This always follows the (averaged) face normal(s) of the old face(s), enabling much easier working in 3D views . A single 'G' (Grab) or 'R' (Rotate) or 'S' (Scale) will change transform modus as usual.
**** Other things to note
- Hiding edges/faces will also behave different based on Select Mode.
- while editing, normals of faces are updated always now
- Border select (BKEY) has 2 different rules for edges; when one edge is fully inside of the border, it will only select edges that are fully inside. Otherwise it selects each edge intersecting with the border.
- in face mode, adding vertices, edges or a circle is invisible...
- "Add monkey" now works as a normal primitive (rotated and on 3d cursor)
- Mesh undo was fully recoded, hopefully solving issues now with Vertex Keys and Groups
- Going in and out of editmode was fully recoded. Especially on larger models you'll notice substantial speed gain.
**** Todo
Add 'FaceSelect mode' functionality in EditMode, including zbuffered selection, display and editing of UV texture.
EditMesh refactor notes (coder)
**** Usage of flags in general
The "->f" flags are reserved for the editmesh.c and editmesh_lib.c core functions. Actually only selection status is there now.
The "->f1" and "->f2" flags are free to use. They're available in vertex/edge/face structs. Since they're free, check carefully when calling other functions that use these flags... for example extrude() or subdivide() use them.
**** Selection flags
EditVert: eve->f & SELECT
EditEdge: eed->f & SELECT
EditFace: efa->f & SELECT
- Selection is only possible when not-hidden!
- Selection flags are always up-to-date, BUT:
if selection mode >= SELECT_EDGE vertex selection flags can be incorrect
if selection mode == SELECT_FACE vertex/edge selection flags can be incorrect
This because of shared vertices or edges.
- use for selecting vertices:
eve->f &= SELECT
- use for selecting edges always:
void EM_select_edge(eed, 1) // 1 = select, 0 = deselect
- use for selecting faces always:
void EM_select_face(efa, 1) // 1 = select, 0 = deselect
- To set the 'f' flags in all of the data:
void EM_set_flag_all(int flag);
void EM_clear_flag_all(int flag);
- the old faceselectedOR() and faceselectedAND() are still there, but only
to be used for evaluating its vertices
**** Code hints for handling selection
If the selectmode is 'face'; vertex or edge selections need to be flushed upward. Same is true for 'edge' selection mode. This means that you'll have to keep track of all selections while coding... selecting the four vertices in a face doesn't automatically select the face anymore.
However, by using the above calls, at least selections flush downward (to vertex level). You then can call:
void EM_selectmode_flush(void);
Which flushes selections back upward, based on the selectmode setting. This function does the following:
- if selectmode 'vertex': select edges/faces based on its selected vertices
- if selectmode 'edge': select faces based its selected edges
This works fine in nice controlled situations.
However, only changing the vertex selections then still doesn't select a face in face mode! If you really can't avoid only working with vertex selections, you can use this call:
void EM_select_flush(void);
Now selection is flushed upward regardless current selectmode. That can be destructive for special cases however, like checkerboard selected faces. So use this only when you know everything else was deselected (or deselect it). Example: adding primitives.
**** Hide flags
EditVert: eve->h
EditEdge: eed->h
EditFace: efa->h
- all hide flags are always up-to-date
- hidden vertices/edges/faces are always deselected. so when you operate on selection only, there's no need to check for hide flag.
**** Unified undo for editmode
New file: editmode_undo.h
A pretty nice function pointer handler style undo. Just code three functions, and your undo will fly! The c file has a good reference.
Also note that the old undo system has been replaced. It currently uses minimal dependencies on Meshes themselves (no abuse of going in/out editmode), and is restricted nicely to editmode functions.
**** Going in/out editmode
As speedup now all vertices/faces/edges are allocated in three big chunks. In vertices/faces/edges now tags are set to denote such data cannot be freed.
ALso the hashtable (lookup) for edges uses no mallocs at all anymore, but is part of the EditEdge itself.
2004-09-23 20:52:51 +00:00
|
|
|
void calc_mesh_facedots_ext(void)
|
|
|
|
{
|
|
|
|
EditMesh *em = G.editMesh;
|
|
|
|
EditFace *efa;
|
|
|
|
float mat[4][4];
|
|
|
|
|
|
|
|
if(em->faces.first==NULL) return;
|
|
|
|
efa= em->faces.first;
|
|
|
|
|
|
|
|
areawinset(curarea->win);
|
|
|
|
persp(PERSP_VIEW);
|
|
|
|
|
|
|
|
mymultmatrix(G.obedit->obmat);
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
|
|
|
efa= em->faces.first;
|
|
|
|
while(efa) {
|
|
|
|
if( efa->h==0) {
|
|
|
|
project_short(efa->cent, &(efa->xs));
|
|
|
|
}
|
|
|
|
efa= efa->next;
|
|
|
|
}
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
}
|
|
|
|
|
2003-06-30 19:51:18 +00:00
|
|
|
/* window coord, assuming all matrices are set OK */
|
2005-03-29 16:43:39 +00:00
|
|
|
static void calc_meshverts(DerivedMesh *dm)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2005-03-28 07:10:32 +00:00
|
|
|
float co[3], mat[4][4];
|
2002-10-12 11:37:38 +00:00
|
|
|
EditVert *eve;
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
2005-03-28 07:10:32 +00:00
|
|
|
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
|
|
|
|
if(eve->h==0) {
|
|
|
|
dm->getMappedVertCoEM(dm, eve, co);
|
|
|
|
project_short(co, &(eve->xs));
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-28 07:10:32 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
}
|
|
|
|
|
2003-06-30 19:51:18 +00:00
|
|
|
/* window coord for current window, sets matrices temporal */
|
2002-10-12 11:37:38 +00:00
|
|
|
void calc_meshverts_ext(void)
|
|
|
|
{
|
2005-03-29 16:43:39 +00:00
|
|
|
int dmNeedsFree;
|
2005-07-19 00:21:01 +00:00
|
|
|
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
areawinset(curarea->win);
|
2003-10-16 09:39:19 +00:00
|
|
|
persp(PERSP_VIEW);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
mymultmatrix(G.obedit->obmat);
|
2005-03-29 16:43:39 +00:00
|
|
|
calc_meshverts(dm);
|
2002-10-12 11:37:38 +00:00
|
|
|
myloadmatrix(G.vd->viewmat);
|
2005-03-29 16:43:39 +00:00
|
|
|
|
|
|
|
if (dmNeedsFree) {
|
|
|
|
dm->release(dm);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2003-06-30 19:51:18 +00:00
|
|
|
/* window coord for current window, sets matrices temporal, sets (eve->f & 2) when not visible */
|
|
|
|
void calc_meshverts_ext_f2(void)
|
|
|
|
{
|
2005-03-29 16:43:39 +00:00
|
|
|
int dmNeedsFree;
|
2005-07-19 00:21:01 +00:00
|
|
|
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
|
2005-03-28 07:10:32 +00:00
|
|
|
float co[3], mat[4][4];
|
2003-06-30 19:51:18 +00:00
|
|
|
EditVert *eve;
|
2004-09-26 17:15:52 +00:00
|
|
|
|
2003-06-30 19:51:18 +00:00
|
|
|
/* matrices */
|
|
|
|
areawinset(curarea->win);
|
2003-10-16 20:36:29 +00:00
|
|
|
persp(PERSP_VIEW);
|
2003-06-30 19:51:18 +00:00
|
|
|
mymultmatrix(G.obedit->obmat);
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
2005-03-28 07:10:32 +00:00
|
|
|
for(eve= G.editMesh->verts.first; eve; eve= eve->next) {
|
2003-06-30 19:51:18 +00:00
|
|
|
eve->f &= ~2;
|
|
|
|
if(eve->h==0) {
|
2005-03-28 07:10:32 +00:00
|
|
|
dm->getMappedVertCoEM(dm, eve, co);
|
|
|
|
project_short_noclip(co, &(eve->xs));
|
2004-09-30 20:38:35 +00:00
|
|
|
|
2003-06-30 19:51:18 +00:00
|
|
|
if( eve->xs >= 0 && eve->ys >= 0 && eve->xs<curarea->winx && eve->ys<curarea->winy);
|
|
|
|
else eve->f |= 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* restore */
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
2005-03-28 07:10:32 +00:00
|
|
|
|
2005-03-29 16:43:39 +00:00
|
|
|
if (dmNeedsFree) {
|
|
|
|
dm->release(dm);
|
|
|
|
}
|
2003-06-30 19:51:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
static void calc_Nurbverts(Nurb *nurb)
|
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
|
|
|
float mat[4][4];
|
|
|
|
int a;
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
mygetsingmatrix(G.vd->persmat);
|
|
|
|
|
|
|
|
nu= nurb;
|
|
|
|
while(nu) {
|
|
|
|
if((nu->type & 7)==1) {
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
project_short(bezt->vec[0], bezt->s[0]);
|
|
|
|
project_short(bezt->vec[1], bezt->s[1]);
|
|
|
|
project_short(bezt->vec[2], bezt->s[2]);
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
project_short(bp->vec, bp->s);
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
MTC_Mat4SwapMat4(G.vd->persmat, mat);
|
|
|
|
}
|
|
|
|
|
|
|
|
void calc_nurbverts_ext(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
areawinset(curarea->win);
|
2003-10-21 12:23:38 +00:00
|
|
|
persp(PERSP_VIEW);
|
2002-10-12 11:37:38 +00:00
|
|
|
mymultmatrix(G.obedit->obmat);
|
|
|
|
calc_Nurbverts(editNurb.first);
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
////
|
2004-09-25 15:15:26 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void calc_weightpaint_vert_color(Object *ob, int vert, unsigned char *col)
|
|
|
|
{
|
|
|
|
Mesh *me = ob->data;
|
|
|
|
float fr, fg, fb, input = 0.0;
|
|
|
|
int i;
|
2004-07-10 21:35:17 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if (me->dvert) {
|
|
|
|
for (i=0; i<me->dvert[vert].totweight; i++)
|
|
|
|
if (me->dvert[vert].dw[i].def_nr==ob->actdef-1)
|
|
|
|
input+=me->dvert[vert].dw[i].weight;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
CLAMP(input, 0.0, 1.0);
|
2004-09-25 13:42:31 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
fr = fg = fb = 85;
|
|
|
|
if (input<=0.25f){
|
|
|
|
fr=0.0f;
|
|
|
|
fg=255.0f * (input*4.0f);
|
|
|
|
fb=255.0f;
|
EditMesh refactory + undo recode
The changelog is very long... it's on the web too:
http://www.blender3d.org/cms/Mesh_editing_rewrite.425.0.html
EditMesh refactor notes (user)
**** New selection modes
When entering Edit Mode for a Mesh, you now have the choice for three selection modes. These are shown as icons in the 3D header (hotkey is being searched for!).
- Vertex Select
Select vertices as usual, fully compatible with how previous version work
- Edge Select
Vertices are not drawn anymore, and selections happen by default on the edges. It is a true edge select, meaning that you can select three out of four edges in a face, without automatic having the 4th edge selected.
- Face Select
Instead of vertices, now selection 'points' are drawn in the face centers. Selected faces also get a colored outline, like for edges. This also is true face select, for each face individual regardless selection status of its vertices or edges.
While holding SHIFT, and press a selection mode, you can also combine the above choices. Now selection becomes mixed, and will behave as expected.
For example; in Edge+Face select mode, selecting the 4 edges of a face will select the face too.
The selection modes and optional drawing modes (like transparant faces, normals, or solid drawing) all work together. All of Blender's mesh editing tools now react to the correct selection mode as well.
Most noticeable it's in:
**** Extrude
Extruding in Edge or Face Select mode allows much more precise control over what's extruded and what should be excluded. Try for example a checker pattern selection, and extrude it.
New is the fixed translation when faces are extruded. This always follows the (averaged) face normal(s) of the old face(s), enabling much easier working in 3D views . A single 'G' (Grab) or 'R' (Rotate) or 'S' (Scale) will change transform modus as usual.
**** Other things to note
- Hiding edges/faces will also behave different based on Select Mode.
- while editing, normals of faces are updated always now
- Border select (BKEY) has 2 different rules for edges; when one edge is fully inside of the border, it will only select edges that are fully inside. Otherwise it selects each edge intersecting with the border.
- in face mode, adding vertices, edges or a circle is invisible...
- "Add monkey" now works as a normal primitive (rotated and on 3d cursor)
- Mesh undo was fully recoded, hopefully solving issues now with Vertex Keys and Groups
- Going in and out of editmode was fully recoded. Especially on larger models you'll notice substantial speed gain.
**** Todo
Add 'FaceSelect mode' functionality in EditMode, including zbuffered selection, display and editing of UV texture.
EditMesh refactor notes (coder)
**** Usage of flags in general
The "->f" flags are reserved for the editmesh.c and editmesh_lib.c core functions. Actually only selection status is there now.
The "->f1" and "->f2" flags are free to use. They're available in vertex/edge/face structs. Since they're free, check carefully when calling other functions that use these flags... for example extrude() or subdivide() use them.
**** Selection flags
EditVert: eve->f & SELECT
EditEdge: eed->f & SELECT
EditFace: efa->f & SELECT
- Selection is only possible when not-hidden!
- Selection flags are always up-to-date, BUT:
if selection mode >= SELECT_EDGE vertex selection flags can be incorrect
if selection mode == SELECT_FACE vertex/edge selection flags can be incorrect
This because of shared vertices or edges.
- use for selecting vertices:
eve->f &= SELECT
- use for selecting edges always:
void EM_select_edge(eed, 1) // 1 = select, 0 = deselect
- use for selecting faces always:
void EM_select_face(efa, 1) // 1 = select, 0 = deselect
- To set the 'f' flags in all of the data:
void EM_set_flag_all(int flag);
void EM_clear_flag_all(int flag);
- the old faceselectedOR() and faceselectedAND() are still there, but only
to be used for evaluating its vertices
**** Code hints for handling selection
If the selectmode is 'face'; vertex or edge selections need to be flushed upward. Same is true for 'edge' selection mode. This means that you'll have to keep track of all selections while coding... selecting the four vertices in a face doesn't automatically select the face anymore.
However, by using the above calls, at least selections flush downward (to vertex level). You then can call:
void EM_selectmode_flush(void);
Which flushes selections back upward, based on the selectmode setting. This function does the following:
- if selectmode 'vertex': select edges/faces based on its selected vertices
- if selectmode 'edge': select faces based its selected edges
This works fine in nice controlled situations.
However, only changing the vertex selections then still doesn't select a face in face mode! If you really can't avoid only working with vertex selections, you can use this call:
void EM_select_flush(void);
Now selection is flushed upward regardless current selectmode. That can be destructive for special cases however, like checkerboard selected faces. So use this only when you know everything else was deselected (or deselect it). Example: adding primitives.
**** Hide flags
EditVert: eve->h
EditEdge: eed->h
EditFace: efa->h
- all hide flags are always up-to-date
- hidden vertices/edges/faces are always deselected. so when you operate on selection only, there's no need to check for hide flag.
**** Unified undo for editmode
New file: editmode_undo.h
A pretty nice function pointer handler style undo. Just code three functions, and your undo will fly! The c file has a good reference.
Also note that the old undo system has been replaced. It currently uses minimal dependencies on Meshes themselves (no abuse of going in/out editmode), and is restricted nicely to editmode functions.
**** Going in/out editmode
As speedup now all vertices/faces/edges are allocated in three big chunks. In vertices/faces/edges now tags are set to denote such data cannot be freed.
ALso the hashtable (lookup) for edges uses no mallocs at all anymore, but is part of the EditEdge itself.
2004-09-23 20:52:51 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else if (input<=0.50f){
|
|
|
|
fr=0.0f;
|
|
|
|
fg=255.0f;
|
|
|
|
fb=255.0f * (1.0f-((input-0.25f)*4.0f));
|
|
|
|
}
|
|
|
|
else if (input<=0.75){
|
|
|
|
fr=255.0f * ((input-0.50f)*4.0f);
|
|
|
|
fg=255.0f;
|
|
|
|
fb=0.0f;
|
|
|
|
}
|
|
|
|
else if (input<=1.0){
|
|
|
|
fr=255.0f;
|
|
|
|
fg=255.0f * (1.0f-((input-0.75f)*4.0f));
|
|
|
|
fb=0.0f;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
col[3] = (unsigned char)(fr * ((input/2.0f)+0.5f));
|
|
|
|
col[2] = (unsigned char)(fg * ((input/2.0f)+0.5f));
|
|
|
|
col[1] = (unsigned char)(fb * ((input/2.0f)+0.5f));
|
|
|
|
col[0] = 255;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-03-27 20:39:28 +00:00
|
|
|
static unsigned char *calc_weightpaint_colors(Object *ob)
|
2004-07-08 20:38:27 +00:00
|
|
|
{
|
2005-03-26 17:29:37 +00:00
|
|
|
Mesh *me = ob->data;
|
|
|
|
MFace *mf = me->mface;
|
|
|
|
unsigned char *wtcol;
|
|
|
|
int i;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
|
2004-07-08 20:38:27 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
|
|
|
|
for (i=0; i<me->totface; i++, mf++){
|
|
|
|
calc_weightpaint_vert_color(ob, mf->v1, &wtcol[(i*4 + 0)*4]);
|
|
|
|
calc_weightpaint_vert_color(ob, mf->v2, &wtcol[(i*4 + 1)*4]);
|
|
|
|
if (mf->v3)
|
|
|
|
calc_weightpaint_vert_color(ob, mf->v3, &wtcol[(i*4 + 2)*4]);
|
|
|
|
if (mf->v4)
|
|
|
|
calc_weightpaint_vert_color(ob, mf->v4, &wtcol[(i*4 + 3)*4]);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
return wtcol;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* ************** DRAW MESH ****************** */
|
|
|
|
|
|
|
|
/* First section is all the "simple" draw routines,
|
|
|
|
* ones that just pass some sort of primitive to GL,
|
|
|
|
* with perhaps various options to control lighting,
|
|
|
|
* color, etc.
|
|
|
|
*
|
|
|
|
* These routines should not have user interface related
|
|
|
|
* logic!!!
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void draw_em_face_normals(EditMesh *em, float normalLength)
|
|
|
|
{
|
|
|
|
EditFace *efa;
|
2004-09-27 10:12:45 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
for(efa= em->faces.first; efa; efa= efa->next) {
|
|
|
|
if(efa->h==0 && efa->fgonf!=EM_FGON) {
|
|
|
|
glVertex3fv(efa->cent);
|
|
|
|
glVertex3f( efa->cent[0] + normalLength*efa->n[0],
|
|
|
|
efa->cent[1] + normalLength*efa->n[1],
|
|
|
|
efa->cent[2] + normalLength*efa->n[2]);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void draw_em_face_centers(EditMesh *em, int sel) {
|
|
|
|
EditFace *efa;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
bglBegin(GL_POINTS);
|
|
|
|
for(efa= em->faces.first; efa; efa= efa->next) {
|
|
|
|
if(efa->h==0 && efa->fgonf!=EM_FGON && (efa->f&SELECT)==sel) {
|
|
|
|
bglVertex3fv(efa->cent);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
bglEnd();
|
|
|
|
}
|
|
|
|
|
2005-03-30 00:32:10 +00:00
|
|
|
|
|
|
|
/* Draw verts with color set based on selection */
|
2005-03-30 05:57:40 +00:00
|
|
|
static int draw_dm_verts__setDrawOptions(void *userData, EditVert *eve)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
int sel = *((int*) userData);
|
|
|
|
|
|
|
|
return (eve->h==0 && (eve->f&SELECT)==sel);
|
|
|
|
}
|
|
|
|
static void draw_dm_verts(DerivedMesh *dm, int sel)
|
|
|
|
{
|
|
|
|
dm->drawMappedVertsEM(dm, draw_dm_verts__setDrawOptions, &sel);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw edges with color set based on selection */
|
2005-03-30 05:57:40 +00:00
|
|
|
static int draw_dm_edges_sel__setDrawOptions(void *userData, EditEdge *eed)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
unsigned char **cols = userData;
|
|
|
|
|
|
|
|
if (eed->h==0) {
|
|
|
|
glColor4ubv(cols[(eed->f&SELECT)?1:0]);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void draw_dm_edges_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
|
|
|
|
{
|
|
|
|
unsigned char *cols[2];
|
|
|
|
cols[0] = baseCol;
|
|
|
|
cols[1] = selCol;
|
|
|
|
dm->drawMappedEdgesEM(dm, draw_dm_edges_sel__setDrawOptions, cols);
|
|
|
|
}
|
|
|
|
|
2005-04-03 15:13:38 +00:00
|
|
|
/* Draw edges */
|
|
|
|
static int draw_dm_edges__setDrawOptions(void *userData, EditEdge *eed)
|
|
|
|
{
|
|
|
|
return eed->h==0;
|
|
|
|
}
|
|
|
|
static void draw_dm_edges(DerivedMesh *dm)
|
|
|
|
{
|
|
|
|
dm->drawMappedEdgesEM(dm, draw_dm_edges__setDrawOptions, NULL);
|
|
|
|
}
|
|
|
|
|
2005-03-30 00:32:10 +00:00
|
|
|
/* Draw edges with color interpolated based on selection */
|
2005-03-30 05:57:40 +00:00
|
|
|
static int draw_dm_edges_sel_interp__setDrawOptions(void *userData, EditEdge *eed)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
return (eed->h==0);
|
|
|
|
}
|
2005-03-30 05:57:40 +00:00
|
|
|
static void draw_dm_edges_sel_interp__setDrawInterpOptions(void *userData, EditEdge *eed, float t)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
unsigned char **cols = userData;
|
|
|
|
unsigned char *col0 = cols[(eed->v1->f&SELECT)?1:0];
|
|
|
|
unsigned char *col1 = cols[(eed->v2->f&SELECT)?1:0];
|
|
|
|
|
|
|
|
glColor4ub( col0[0] + (col1[0]-col0[0])*t,
|
|
|
|
col0[1] + (col1[1]-col0[1])*t,
|
|
|
|
col0[2] + (col1[2]-col0[2])*t,
|
|
|
|
col0[3] + (col1[3]-col0[3])*t);
|
|
|
|
}
|
|
|
|
static void draw_dm_edges_sel_interp(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
|
|
|
|
{
|
|
|
|
unsigned char *cols[2];
|
|
|
|
cols[0] = baseCol;
|
|
|
|
cols[1] = selCol;
|
|
|
|
dm->drawMappedEdgesInterpEM(dm, draw_dm_edges_sel_interp__setDrawOptions, draw_dm_edges_sel_interp__setDrawInterpOptions, cols);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw only seam edges */
|
2005-03-30 05:57:40 +00:00
|
|
|
static int draw_dm_edges_seams__setDrawOptions(void *userData, EditEdge *eed)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
return (eed->h==0 && eed->seam);
|
|
|
|
}
|
|
|
|
static void draw_dm_edges_seams(DerivedMesh *dm)
|
|
|
|
{
|
2005-03-30 05:35:01 +00:00
|
|
|
dm->drawMappedEdgesEM(dm, draw_dm_edges_seams__setDrawOptions, NULL);
|
2005-03-30 00:32:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw faces with color set based on selection */
|
2005-03-30 05:57:40 +00:00
|
|
|
static int draw_dm_faces_sel__setDrawOptions(void *userData, EditFace *efa)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
unsigned char **cols = userData;
|
|
|
|
|
|
|
|
if (efa->h==0) {
|
|
|
|
glColor4ubv(cols[(efa->f&SELECT)?1:0]);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol)
|
|
|
|
{
|
|
|
|
unsigned char *cols[2];
|
|
|
|
cols[0] = baseCol;
|
|
|
|
cols[1] = selCol;
|
|
|
|
dm->drawMappedFacesEM(dm, draw_dm_faces_sel__setDrawOptions, cols);
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* Second section of routines: Combine first sets to form fancy
|
|
|
|
* drawing routines (for example rendering twice to get overlays).
|
|
|
|
*
|
|
|
|
* Also includes routines that are basic drawing but are too
|
|
|
|
* specialized to be split out (like drawing creases or measurements).
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* EditMesh drawing routines*/
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
static void draw_em_fancy_verts(EditMesh *em, DerivedMesh *cageDM)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2005-03-27 20:39:28 +00:00
|
|
|
int sel;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glDepthMask(0); // disable write in zbuffer, zbuf select
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
for (sel=0; sel<2; sel++) {
|
|
|
|
char col[4], fcol[4];
|
|
|
|
int pass;
|
|
|
|
|
|
|
|
BIF_GetThemeColor3ubv(sel?TH_VERTEX_SELECT:TH_VERTEX, col);
|
|
|
|
BIF_GetThemeColor3ubv(sel?TH_FACE_DOT:TH_WIRE, fcol);
|
|
|
|
|
|
|
|
for (pass=0; pass<2; pass++) {
|
|
|
|
float size = BIF_GetThemeValuef(TH_VERTEX_SIZE);
|
|
|
|
float fsize = BIF_GetThemeValuef(TH_FACEDOT_SIZE);
|
|
|
|
|
|
|
|
if (pass==0) {
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf && !(G.vd->flag&V3D_ZBUF_SELECT)) {
|
2005-03-27 20:39:28 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
size = (size>2.1?size/2.0:size);
|
|
|
|
fsize = (fsize>2.1?fsize/2.0:fsize);
|
|
|
|
col[3] = fcol[3] = 100;
|
2005-03-26 17:29:37 +00:00
|
|
|
} else {
|
2005-03-27 20:39:28 +00:00
|
|
|
col[3] = fcol[3] = 255;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(G.scene->selectmode & SCE_SELECT_VERTEX) {
|
|
|
|
glPointSize(size);
|
|
|
|
glColor4ubv(col);
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_verts(cageDM, sel);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
if(G.scene->selectmode & SCE_SELECT_FACE) {
|
|
|
|
glPointSize(fsize);
|
|
|
|
glColor4ubv(fcol);
|
|
|
|
draw_em_face_centers(em, sel);
|
2004-10-29 15:39:01 +00:00
|
|
|
}
|
2005-03-27 20:39:28 +00:00
|
|
|
|
|
|
|
if (pass==0) {
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glDepthMask(1);
|
2005-03-26 17:29:37 +00:00
|
|
|
glPointSize(1.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
static void draw_em_fancy_edges(DerivedMesh *cageDM)
|
2005-03-26 17:29:37 +00:00
|
|
|
{
|
|
|
|
int pass;
|
|
|
|
char wire[4], sel[4];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* since this function does transparant... */
|
|
|
|
BIF_GetThemeColor3ubv(TH_EDGE_SELECT, sel);
|
|
|
|
BIF_GetThemeColor3ubv(TH_WIRE, wire);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
for (pass=0; pass<2; pass++) {
|
|
|
|
/* show wires in transparant when no zbuf clipping for select */
|
|
|
|
if (pass==0) {
|
2005-07-13 19:42:08 +00:00
|
|
|
if (G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0) {
|
2005-03-26 17:29:37 +00:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
wire[3] = sel[3] = 85;
|
|
|
|
} else {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
wire[3] = sel[3] = 255;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(G.scene->selectmode == SCE_SELECT_FACE) {
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_edges_sel(cageDM, wire, sel);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
else if( (G.f & G_DRAWEDGES) || (G.scene->selectmode & SCE_SELECT_EDGE) ) {
|
2005-03-30 00:32:10 +00:00
|
|
|
if(cageDM->drawMappedEdgesInterpEM && (G.scene->selectmode & SCE_SELECT_VERTEX)) {
|
2005-03-26 17:29:37 +00:00
|
|
|
glShadeModel(GL_SMOOTH);
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_edges_sel_interp(cageDM, wire, sel);
|
2005-03-26 17:29:37 +00:00
|
|
|
glShadeModel(GL_FLAT);
|
2005-03-27 20:39:28 +00:00
|
|
|
} else {
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_edges_sel(cageDM, wire, sel);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else {
|
|
|
|
glColor4ubv(wire);
|
2005-04-03 15:13:38 +00:00
|
|
|
draw_dm_edges(cageDM);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if (pass==0) {
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void draw_em_creases(EditMesh *em)
|
2004-09-26 19:55:02 +00:00
|
|
|
{
|
|
|
|
EditEdge *eed;
|
|
|
|
float fac, *v1, *v2, vec[3];
|
|
|
|
|
|
|
|
glLineWidth(3.0);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
for(eed= em->edges.first; eed; eed= eed->next) {
|
|
|
|
if(eed->h==0 && eed->crease!=0.0) {
|
2005-03-27 20:39:28 +00:00
|
|
|
BIF_ThemeColor((eed->f&SELECT)?TH_EDGE_SELECT:TH_WIRE);
|
2004-09-26 19:55:02 +00:00
|
|
|
|
|
|
|
v1= eed->v1->co; v2= eed->v2->co;
|
|
|
|
VECSUB(vec, v2, v1);
|
|
|
|
fac= 0.5 + eed->crease/2.0;
|
|
|
|
glVertex3f(v1[0] + fac*vec[0], v1[1] + fac*vec[1], v1[2] + fac*vec[2] );
|
|
|
|
glVertex3f(v2[0] - fac*vec[0], v2[1] - fac*vec[1], v2[2] - fac*vec[2] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
glLineWidth(1.0);
|
|
|
|
}
|
|
|
|
|
2005-04-29 18:43:17 +00:00
|
|
|
static void draw_em_measure_stats(Object *ob, EditMesh *em)
|
2004-09-25 13:42:31 +00:00
|
|
|
{
|
2004-09-30 22:29:19 +00:00
|
|
|
EditEdge *eed;
|
2005-03-26 17:29:37 +00:00
|
|
|
EditFace *efa;
|
2005-04-29 18:43:17 +00:00
|
|
|
float v1[3], v2[3], v3[3], v4[3];
|
|
|
|
float fvec[3];
|
2005-03-26 17:29:37 +00:00
|
|
|
char val[32]; /* Stores the measurement display text here */
|
|
|
|
float area, col[3]; /* area of the face, colour of the text to draw */
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf && (G.vd->flag & V3D_ZBUF_SELECT)==0)
|
2005-03-26 17:29:37 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) bglPolygonOffset(5.0);
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(G.f & G_DRAW_EDGELEN) {
|
|
|
|
BIF_GetThemeColor3fv(TH_TEXT, col);
|
|
|
|
/* make color a bit more red */
|
|
|
|
if(col[0]> 0.5) {col[1]*=0.7; col[2]*= 0.7;}
|
|
|
|
else col[0]= col[0]*0.7 + 0.3;
|
|
|
|
glColor3fv(col);
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
for(eed= em->edges.first; eed; eed= eed->next) {
|
2005-04-28 15:41:09 +00:00
|
|
|
if((eed->f & SELECT) || (G.moving && ((eed->v1->f & SELECT) || (eed->v2->f & SELECT)) )) {
|
2005-04-29 18:43:17 +00:00
|
|
|
VECCOPY(v1, eed->v1->co);
|
|
|
|
VECCOPY(v2, eed->v2->co);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glRasterPos3f( 0.5*(v1[0]+v2[0]), 0.5*(v1[1]+v2[1]), 0.5*(v1[2]+v2[2]));
|
2005-04-29 18:43:17 +00:00
|
|
|
|
|
|
|
if(G.vd->flag & V3D_GLOBAL_STATS) {
|
|
|
|
Mat4MulVecfl(ob->obmat, v1);
|
|
|
|
Mat4MulVecfl(ob->obmat, v2);
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
sprintf(val,"%.3f", VecLenf(v1, v2));
|
|
|
|
BMF_DrawString( G.fonts, val);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(G.f & G_DRAW_FACEAREA) {
|
2005-04-28 15:41:09 +00:00
|
|
|
extern int faceselectedOR(EditFace *efa, int flag); // editmesh.h shouldn't be in this file... ok for now?
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
BIF_GetThemeColor3fv(TH_TEXT, col);
|
|
|
|
/* make color a bit more green */
|
|
|
|
if(col[1]> 0.5) {col[0]*=0.7; col[2]*= 0.7;}
|
|
|
|
else col[1]= col[1]*0.7 + 0.3;
|
|
|
|
glColor3fv(col);
|
|
|
|
|
|
|
|
for(efa= em->faces.first; efa; efa= efa->next) {
|
2005-04-28 15:41:09 +00:00
|
|
|
if((efa->f & SELECT) || (G.moving && faceselectedOR(efa, SELECT)) ) {
|
2005-04-29 18:43:17 +00:00
|
|
|
VECCOPY(v1, efa->v1->co);
|
|
|
|
VECCOPY(v2, efa->v2->co);
|
2005-06-01 18:36:58 +00:00
|
|
|
VECCOPY(v3, efa->v3->co);
|
2005-04-29 18:43:17 +00:00
|
|
|
if (efa->v4) {
|
|
|
|
VECCOPY(v4, efa->v4->co);
|
|
|
|
}
|
|
|
|
if(G.vd->flag & V3D_GLOBAL_STATS) {
|
|
|
|
Mat4MulVecfl(ob->obmat, v1);
|
|
|
|
Mat4MulVecfl(ob->obmat, v2);
|
|
|
|
Mat4MulVecfl(ob->obmat, v3);
|
|
|
|
if (efa->v4) Mat4MulVecfl(ob->obmat, v4);
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if (efa->v4)
|
2005-04-29 18:43:17 +00:00
|
|
|
area= AreaQ3Dfl(v1, v2, v3, v4);
|
2005-03-26 17:29:37 +00:00
|
|
|
else
|
2005-04-29 18:43:17 +00:00
|
|
|
area = AreaT3Dfl(v1, v2, v3);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
sprintf(val,"%.3f", area);
|
|
|
|
glRasterPos3fv(efa->cent);
|
|
|
|
BMF_DrawString( G.fonts, val);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(G.f & G_DRAW_EDGEANG) {
|
|
|
|
EditEdge *e1, *e2, *e3, *e4;
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
BIF_GetThemeColor3fv(TH_TEXT, col);
|
|
|
|
/* make color a bit more blue */
|
|
|
|
if(col[2]> 0.5) {col[0]*=0.7; col[1]*= 0.7;}
|
|
|
|
else col[2]= col[2]*0.7 + 0.3;
|
|
|
|
glColor3fv(col);
|
|
|
|
|
|
|
|
for(efa= em->faces.first; efa; efa= efa->next) {
|
2005-04-29 18:43:17 +00:00
|
|
|
VECCOPY(v1, efa->v1->co);
|
|
|
|
VECCOPY(v2, efa->v2->co);
|
|
|
|
VECCOPY(v3, efa->v3->co);
|
|
|
|
if(efa->v4) {
|
|
|
|
VECCOPY(v4, efa->v4->co);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
VECCOPY(v4, v3);
|
|
|
|
}
|
|
|
|
if(G.vd->flag & V3D_GLOBAL_STATS) {
|
|
|
|
Mat4MulVecfl(ob->obmat, v1);
|
|
|
|
Mat4MulVecfl(ob->obmat, v2);
|
|
|
|
Mat4MulVecfl(ob->obmat, v3);
|
|
|
|
if (efa->v4) Mat4MulVecfl(ob->obmat, v4);
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
e1= efa->e1;
|
|
|
|
e2= efa->e2;
|
|
|
|
e3= efa->e3;
|
|
|
|
if(efa->e4) e4= efa->e4; else e4= e3;
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* Calculate the angles */
|
2004-09-30 22:29:19 +00:00
|
|
|
|
2005-04-28 15:41:09 +00:00
|
|
|
if( (e4->f & e1->f & SELECT) || (G.moving && (efa->v1->f & SELECT)) ) {
|
2005-03-26 17:29:37 +00:00
|
|
|
/* Vec 1 */
|
|
|
|
sprintf(val,"%.3f", VecAngle3(v4, v1, v2));
|
2005-04-29 18:43:17 +00:00
|
|
|
fvec[0]= 0.2*efa->cent[0] + 0.8*efa->v1->co[0];
|
|
|
|
fvec[1]= 0.2*efa->cent[1] + 0.8*efa->v1->co[1];
|
|
|
|
fvec[2]= 0.2*efa->cent[2] + 0.8*efa->v1->co[2];
|
2005-03-26 17:29:37 +00:00
|
|
|
glRasterPos3fv(fvec);
|
|
|
|
BMF_DrawString( G.fonts, val);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
2005-04-28 15:41:09 +00:00
|
|
|
if( (e1->f & e2->f & SELECT) || (G.moving && (efa->v2->f & SELECT)) ) {
|
2005-03-26 17:29:37 +00:00
|
|
|
/* Vec 2 */
|
|
|
|
sprintf(val,"%.3f", VecAngle3(v1, v2, v3));
|
2005-04-29 18:43:17 +00:00
|
|
|
fvec[0]= 0.2*efa->cent[0] + 0.8*efa->v2->co[0];
|
|
|
|
fvec[1]= 0.2*efa->cent[1] + 0.8*efa->v2->co[1];
|
|
|
|
fvec[2]= 0.2*efa->cent[2] + 0.8*efa->v3->co[2];
|
2005-03-26 17:29:37 +00:00
|
|
|
glRasterPos3fv(fvec);
|
|
|
|
BMF_DrawString( G.fonts, val);
|
|
|
|
}
|
2005-04-28 15:41:09 +00:00
|
|
|
if( (e2->f & e3->f & SELECT) || (G.moving && (efa->v3->f & SELECT)) ) {
|
2005-03-26 17:29:37 +00:00
|
|
|
/* Vec 3 */
|
|
|
|
if(efa->v4)
|
|
|
|
sprintf(val,"%.3f", VecAngle3(v2, v3, v4));
|
|
|
|
else
|
|
|
|
sprintf(val,"%.3f", VecAngle3(v2, v3, v1));
|
2005-04-29 18:43:17 +00:00
|
|
|
fvec[0]= 0.2*efa->cent[0] + 0.8*efa->v3->co[0];
|
|
|
|
fvec[1]= 0.2*efa->cent[1] + 0.8*efa->v3->co[1];
|
|
|
|
fvec[2]= 0.2*efa->cent[2] + 0.8*efa->v3->co[2];
|
2005-03-26 17:29:37 +00:00
|
|
|
glRasterPos3fv(fvec);
|
|
|
|
BMF_DrawString( G.fonts, val);
|
|
|
|
}
|
|
|
|
/* Vec 4 */
|
|
|
|
if(efa->v4) {
|
2005-04-28 15:41:09 +00:00
|
|
|
if( (e3->f & e4->f & SELECT) || (G.moving && (efa->v4->f & SELECT)) ) {
|
2005-03-26 17:29:37 +00:00
|
|
|
sprintf(val,"%.3f", VecAngle3(v3, v4, v1));
|
|
|
|
|
2005-04-29 18:43:17 +00:00
|
|
|
fvec[0]= 0.2*efa->cent[0] + 0.8*efa->v4->co[0];
|
|
|
|
fvec[1]= 0.2*efa->cent[1] + 0.8*efa->v4->co[1];
|
|
|
|
fvec[2]= 0.2*efa->cent[2] + 0.8*efa->v4->co[2];
|
2005-03-26 17:29:37 +00:00
|
|
|
glRasterPos3fv(fvec);
|
|
|
|
BMF_DrawString( G.fonts, val);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) {
|
2005-03-26 17:29:37 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
bglPolygonOffset(0.0);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
static void draw_em_fancy(Object *ob, EditMesh *em, DerivedMesh *cageDM, DerivedMesh *finalDM, int dt)
|
2005-03-26 17:29:37 +00:00
|
|
|
{
|
|
|
|
Mesh *me = ob->data;
|
|
|
|
|
|
|
|
if(dt>OB_WIRE) {
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED);
|
|
|
|
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
|
2005-03-27 20:39:28 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
finalDM->drawFacesSolid(finalDM, set_gl_material);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glFrontFace(GL_CCW);
|
|
|
|
glDisable(GL_LIGHTING);
|
2005-07-14 12:44:33 +00:00
|
|
|
|
|
|
|
// Setup for drawing wire over, disable zbuffer
|
|
|
|
// write to show selected edge wires better
|
2005-03-26 17:29:37 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
|
|
|
|
|
|
|
bglPolygonOffset(1.0);
|
|
|
|
glDepthMask(0);
|
2005-07-14 12:44:33 +00:00
|
|
|
}
|
|
|
|
else {
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (cageDM!=finalDM) {
|
2005-03-26 17:29:37 +00:00
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
finalDM->drawEdges(finalDM);
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
2005-07-14 12:44:33 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if( (G.f & (G_FACESELECT+G_DRAWFACES))) { /* transp faces */
|
|
|
|
char col1[4], col2[4];
|
|
|
|
|
|
|
|
BIF_GetThemeColor4ubv(TH_FACE, col1);
|
|
|
|
BIF_GetThemeColor4ubv(TH_FACE_SELECT, col2);
|
|
|
|
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glDepthMask(0); // disable write in zbuffer, needed for nice transp
|
|
|
|
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_faces_sel(cageDM, col1, col2);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
glDepthMask(1); // restore write in zbuffer
|
2004-09-30 22:29:19 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* here starts all fancy draw-extra over */
|
|
|
|
|
|
|
|
if(G.f & G_DRAWSEAMS) {
|
|
|
|
BIF_ThemeColor(TH_EDGE_SEAM);
|
|
|
|
glLineWidth(2);
|
|
|
|
|
2005-03-30 00:32:10 +00:00
|
|
|
draw_dm_edges_seams(cageDM);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glColor3ub(0,0,0);
|
|
|
|
glLineWidth(1);
|
|
|
|
}
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
draw_em_fancy_edges(cageDM);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
if(G.f & G_DRAWCREASES) {
|
|
|
|
draw_em_creases(em);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(ob==G.obedit) {
|
2005-03-29 16:43:39 +00:00
|
|
|
calc_meshverts(cageDM);
|
2005-03-27 20:39:28 +00:00
|
|
|
draw_em_fancy_verts(em, cageDM);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
if(G.f & G_DRAWNORMALS) {
|
|
|
|
BIF_ThemeColor(TH_NORMAL);
|
2005-05-03 10:54:42 +00:00
|
|
|
draw_em_face_normals(em, G.scene->editbutsize);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(G.f & (G_DRAW_EDGELEN|G_DRAW_FACEAREA|G_DRAW_EDGEANG))
|
2005-04-29 18:43:17 +00:00
|
|
|
draw_em_measure_stats(ob, em);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(dt>OB_WIRE) {
|
|
|
|
glDepthMask(1);
|
|
|
|
bglPolygonOffset(0.0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
/* Mesh drawing routines */
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
static void draw_mesh_object_outline(Object *ob, DerivedMesh *dm)
|
2004-10-12 15:23:00 +00:00
|
|
|
{
|
2005-07-14 12:44:33 +00:00
|
|
|
|
|
|
|
if(G.vd->transp==0) { // not when we draw the transparent pass
|
|
|
|
glLineWidth(2.0);
|
|
|
|
glDepthMask(0);
|
|
|
|
|
|
|
|
/* if transparent, we cannot draw the edges for solid select... edges have no material info.
|
|
|
|
drawFacesSolid() doesn't draw the transparent faces */
|
|
|
|
if(ob->dtx & OB_DRAWTRANSP) {
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
|
|
dm->drawFacesSolid(dm, set_gl_material);
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
dm->drawEdges(dm);
|
|
|
|
|
|
|
|
glLineWidth(1.0);
|
|
|
|
glDepthMask(1);
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
2005-07-19 00:21:01 +00:00
|
|
|
static void draw_mesh_fancy(Object *ob, DerivedMesh *baseDM, DerivedMesh *dm, int dt)
|
2005-03-26 17:29:37 +00:00
|
|
|
{
|
|
|
|
Mesh *me = ob->data;
|
|
|
|
Material *ma= give_current_material(ob, 1);
|
|
|
|
int hasHaloMat = (ma && (ma->mode&MA_HALO));
|
|
|
|
int draw_wire = ob->dtx&OB_DRAWWIRE;
|
2005-03-31 15:57:18 +00:00
|
|
|
DispList *dl;
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-05-26 21:00:50 +00:00
|
|
|
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
// Unwanted combination.
|
|
|
|
if (G.f&G_FACESELECT) draw_wire = 0;
|
|
|
|
|
|
|
|
// This is only for objects from the decimator and
|
|
|
|
// is a temporal solution, a reconstruction of the
|
|
|
|
// displist system should take care of it (zr/ton)
|
2005-03-29 16:43:39 +00:00
|
|
|
if(me->decimated) {
|
|
|
|
DispListMesh *dlm = me->decimated;
|
2005-03-27 20:39:28 +00:00
|
|
|
MVert *mvert= dlm->mvert;
|
|
|
|
MFace *mface= dlm->mface;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; i<dlm->totface; i++, mface++) {
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3fv(mvert[mface->v1].co);
|
|
|
|
glVertex3fv(mvert[mface->v2].co);
|
|
|
|
if (mface->v3) {
|
|
|
|
glVertex3fv(mvert[mface->v3].co);
|
|
|
|
if (mface->v4)
|
|
|
|
glVertex3fv(mvert[mface->v4].co);
|
|
|
|
}
|
|
|
|
glEnd();
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(dt==OB_BOUNDBOX) {
|
|
|
|
draw_bounding_volume(ob);
|
|
|
|
}
|
2005-04-10 14:31:04 +00:00
|
|
|
else if(hasHaloMat || (me->totface==0 && (!me->medge || me->totedge==0))) {
|
2005-03-26 17:29:37 +00:00
|
|
|
glPointSize(1.5);
|
2005-03-27 20:39:28 +00:00
|
|
|
dm->drawVerts(dm);
|
2005-03-26 17:29:37 +00:00
|
|
|
glPointSize(1.0);
|
|
|
|
}
|
2005-04-10 14:31:04 +00:00
|
|
|
else if(dt==OB_WIRE || me->totface==0) {
|
2005-03-26 17:29:37 +00:00
|
|
|
draw_wire = 1;
|
|
|
|
}
|
|
|
|
else if( (ob==OBACT && (G.f & G_FACESELECT)) || (G.vd->drawtype==OB_TEXTURE && dt>OB_SOLID)) {
|
2005-07-14 12:44:33 +00:00
|
|
|
|
|
|
|
if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !(G.f&(G_FACESELECT|G_PICKSEL)) && !draw_wire) {
|
|
|
|
draw_mesh_object_outline(ob, dm);
|
2005-04-13 11:46:46 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
draw_tface_mesh(ob, ob->data, dt);
|
|
|
|
}
|
|
|
|
else if(dt==OB_SOLID ) {
|
2005-07-14 12:44:33 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !draw_wire) {
|
2005-07-14 12:44:33 +00:00
|
|
|
draw_mesh_object_outline(ob, dm);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
2004-10-12 15:23:00 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, me->flag & ME_TWOSIDED );
|
2004-10-12 15:23:00 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
glFrontFace((ob->transflag&OB_NEG_SCALE)?GL_CW:GL_CCW);
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
dm->drawFacesSolid(dm, set_gl_material);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glFrontFace(GL_CCW);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
|
|
|
dm->drawLooseEdges(dm);
|
2004-10-12 15:23:00 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else if(dt==OB_SHADED) {
|
|
|
|
if( (G.f & G_WEIGHTPAINT)) {
|
2005-03-27 20:39:28 +00:00
|
|
|
unsigned char *wtcol = calc_weightpaint_colors(ob);
|
|
|
|
baseDM->drawFacesColored(baseDM, me->flag&ME_TWOSIDED, wtcol, 0);
|
2005-03-26 17:29:37 +00:00
|
|
|
MEM_freeN (wtcol);
|
|
|
|
}
|
|
|
|
else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->mcol) {
|
2005-03-27 20:39:28 +00:00
|
|
|
baseDM->drawFacesColored(baseDM, me->flag&ME_TWOSIDED, (unsigned char*) me->mcol, 0);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
else if((G.f & (G_VERTEXPAINT+G_TEXTUREPAINT)) && me->tface) {
|
|
|
|
tface_to_mcol(me);
|
2005-03-27 20:39:28 +00:00
|
|
|
baseDM->drawFacesColored(baseDM, me->flag&ME_TWOSIDED, (unsigned char*) me->mcol, 0);
|
2005-03-26 17:29:37 +00:00
|
|
|
MEM_freeN(me->mcol);
|
|
|
|
me->mcol= 0;
|
|
|
|
}
|
|
|
|
else {
|
2005-03-27 20:39:28 +00:00
|
|
|
unsigned int *obCol1, *obCol2;
|
|
|
|
|
|
|
|
dl = ob->disp.first;
|
|
|
|
if (!dl || !dl->col1) {
|
|
|
|
shadeDispList(ob);
|
2005-04-10 00:00:34 +00:00
|
|
|
dl = find_displist(&ob->disp, DL_VERTCOL);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
2005-03-27 20:39:28 +00:00
|
|
|
obCol1 = dl->col1;
|
|
|
|
obCol2 = dl->col2;
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
if ((G.vd->flag&V3D_SELECT_OUTLINE) && (ob->flag&SELECT) && !draw_wire) {
|
2005-07-14 12:44:33 +00:00
|
|
|
draw_mesh_object_outline(ob, dm);
|
2004-10-12 15:23:00 +00:00
|
|
|
}
|
2005-03-27 20:39:28 +00:00
|
|
|
|
|
|
|
dm->drawFacesColored(dm, me->flag&ME_TWOSIDED, (unsigned char*) obCol1, (unsigned char*) obCol2);
|
2004-10-12 15:23:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if (draw_wire) {
|
|
|
|
/* If drawing wire and drawtype is not OB_WIRE then we are
|
|
|
|
* overlaying the wires.
|
|
|
|
*/
|
|
|
|
if (dt!=OB_WIRE) {
|
|
|
|
if(ob->flag & SELECT) {
|
|
|
|
BIF_ThemeColor((ob==OBACT)?TH_ACTIVE:TH_SELECT);
|
|
|
|
} else {
|
|
|
|
BIF_ThemeColor(TH_WIRE);
|
|
|
|
}
|
|
|
|
|
|
|
|
bglPolygonOffset(1.0);
|
|
|
|
glDepthMask(0); // disable write in zbuffer, selected edge wires show better
|
|
|
|
}
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
if (me->flag&ME_OPT_EDGES) {
|
|
|
|
dm->drawMappedEdges(dm);
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else {
|
2005-03-27 20:39:28 +00:00
|
|
|
dm->drawEdges(dm);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dt!=OB_WIRE) {
|
|
|
|
glDepthMask(1);
|
|
|
|
bglPolygonOffset(0.0);
|
|
|
|
}
|
|
|
|
}
|
2004-10-12 15:23:00 +00:00
|
|
|
}
|
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
static void draw_mesh_object(Base *base, int dt)
|
2005-01-08 21:16:24 +00:00
|
|
|
{
|
2005-07-14 12:44:33 +00:00
|
|
|
Object *ob= base->object;
|
2005-03-26 17:29:37 +00:00
|
|
|
Mesh *me= ob->data;
|
2005-07-14 12:44:33 +00:00
|
|
|
int has_alpha= 0;
|
|
|
|
|
2005-03-27 20:39:28 +00:00
|
|
|
if(G.obedit && ob->data==G.obedit->data) {
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
int cageNeedsFree, finalNeedsFree;
|
|
|
|
DerivedMesh *finalDM, *cageDM = editmesh_get_derived_cage_and_final(&finalDM, &cageNeedsFree, &finalNeedsFree);
|
2005-07-14 17:10:44 +00:00
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
if(dt>OB_WIRE) init_gl_materials(ob); // no transp in editmode, the fancy draw over goes bad then
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
draw_em_fancy(ob, G.editMesh, cageDM, finalDM, dt);
|
2005-07-14 17:10:44 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (cageNeedsFree) cageDM->release(cageDM);
|
|
|
|
if (finalNeedsFree) finalDM->release(finalDM);
|
2005-03-27 20:39:28 +00:00
|
|
|
}
|
|
|
|
else {
|
2005-07-14 18:04:27 +00:00
|
|
|
BoundBox *bb = mesh_get_bb(me);
|
|
|
|
|
|
|
|
if(me->totface<=4 || boundbox_clip(ob->obmat, bb)) {
|
2005-07-19 00:21:01 +00:00
|
|
|
int baseDMneedsFree, realDMneedsFree;
|
2005-07-17 17:41:03 +00:00
|
|
|
DerivedMesh *baseDM = mesh_get_derived_deform(ob, &baseDMneedsFree);
|
2005-07-19 00:21:01 +00:00
|
|
|
DerivedMesh *realDM = mesh_get_derived_final(ob, &realDMneedsFree);
|
2005-07-14 17:10:44 +00:00
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
if(dt==OB_SOLID) has_alpha= init_gl_materials(ob);
|
2005-03-27 20:39:28 +00:00
|
|
|
draw_mesh_fancy(ob, baseDM, realDM, dt);
|
2005-07-14 17:10:44 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if (baseDMneedsFree) baseDM->release(baseDM);
|
2005-07-19 00:21:01 +00:00
|
|
|
if (realDMneedsFree) realDM->release(realDM);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
}
|
2005-07-14 12:44:33 +00:00
|
|
|
|
|
|
|
/* init_gl_materials did the proper checking if this is needed */
|
|
|
|
if(has_alpha) add_view3d_after(G.vd, base, V3D_TRANSP);
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************** DRAW DISPLIST ****************** */
|
|
|
|
|
|
|
|
static int draw_index_wire= 1;
|
|
|
|
static int index3_nors_incr= 1;
|
|
|
|
|
|
|
|
static void drawDispListwire(ListBase *dlbase)
|
|
|
|
{
|
|
|
|
DispList *dl;
|
|
|
|
int parts, nr, ofs, *index;
|
|
|
|
float *data;
|
|
|
|
|
|
|
|
if(dlbase==0) return;
|
|
|
|
|
|
|
|
dl= dlbase->first;
|
|
|
|
while(dl) {
|
|
|
|
data= dl->verts;
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
switch(dl->type) {
|
|
|
|
case DL_SEGM:
|
|
|
|
parts= dl->parts;
|
|
|
|
while(parts--) {
|
|
|
|
nr= dl->nr;
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
while(nr--) {
|
|
|
|
glVertex3fv(data);
|
|
|
|
data+=3;
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DL_POLY:
|
|
|
|
parts= dl->parts;
|
|
|
|
while(parts--) {
|
|
|
|
nr= dl->nr;
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
while(nr--) {
|
|
|
|
glVertex3fv(data);
|
|
|
|
data+=3;
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case DL_SURF:
|
|
|
|
parts= dl->parts;
|
|
|
|
while(parts--) {
|
|
|
|
nr= dl->nr;
|
|
|
|
if(dl->flag & DL_CYCL_U) glBegin(GL_LINE_LOOP);
|
|
|
|
else glBegin(GL_LINE_STRIP);
|
|
|
|
|
|
|
|
while(nr--) {
|
|
|
|
glVertex3fv(data);
|
|
|
|
data+=3;
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
ofs= 3*dl->nr;
|
|
|
|
nr= dl->nr;
|
|
|
|
while(nr--) {
|
|
|
|
data= ( dl->verts )+3*nr;
|
|
|
|
parts= dl->parts;
|
|
|
|
if(dl->flag & DL_CYCL_V) glBegin(GL_LINE_LOOP);
|
|
|
|
else glBegin(GL_LINE_STRIP);
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
while(parts--) {
|
|
|
|
glVertex3fv(data);
|
|
|
|
data+=ofs;
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DL_INDEX3:
|
|
|
|
if(draw_index_wire) {
|
|
|
|
parts= dl->parts;
|
|
|
|
data= dl->verts;
|
|
|
|
index= dl->index;
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
glEnd();
|
|
|
|
index+= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DL_INDEX4:
|
|
|
|
if(draw_index_wire) {
|
|
|
|
parts= dl->parts;
|
|
|
|
data= dl->verts;
|
|
|
|
index= dl->index;
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
if(index[3]) glVertex3fv(data+3*index[3]);
|
|
|
|
glEnd();
|
|
|
|
index+= 4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dl= dl->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawDispListsolid(ListBase *lb, Object *ob)
|
|
|
|
{
|
|
|
|
DispList *dl;
|
|
|
|
int parts, ofs, p1, p2, p3, p4, a, b, *index;
|
|
|
|
float *data, *v1, *v2, *v3, *v4;
|
|
|
|
float *ndata, *n1, *n2, *n3, *n4;
|
|
|
|
|
|
|
|
if(lb==0) return;
|
|
|
|
|
|
|
|
glEnable(GL_LIGHTING);
|
|
|
|
|
|
|
|
if(ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
|
|
|
|
else glFrontFace(GL_CCW);
|
|
|
|
|
|
|
|
if(ob->type==OB_MBALL) { // mball always smooth shaded
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
}
|
|
|
|
|
|
|
|
dl= lb->first;
|
|
|
|
while(dl) {
|
|
|
|
data= dl->verts;
|
|
|
|
ndata= dl->nors;
|
|
|
|
|
|
|
|
switch(dl->type) {
|
|
|
|
case DL_SURF:
|
|
|
|
|
|
|
|
set_gl_material(dl->col+1);
|
|
|
|
|
|
|
|
if(dl->rt & CU_SMOOTH) glShadeModel(GL_SMOOTH);
|
|
|
|
else glShadeModel(GL_FLAT);
|
|
|
|
|
|
|
|
for(a=0; a<dl->parts; a++) {
|
|
|
|
|
|
|
|
DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
|
|
|
|
|
|
|
|
v1= data+ 3*p1;
|
|
|
|
v2= data+ 3*p2;
|
|
|
|
v3= data+ 3*p3;
|
|
|
|
v4= data+ 3*p4;
|
|
|
|
n1= ndata+ 3*p1;
|
|
|
|
n2= ndata+ 3*p2;
|
|
|
|
n3= ndata+ 3*p3;
|
|
|
|
n4= ndata+ 3*p4;
|
|
|
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
|
|
|
glNormal3fv(n2); glVertex3fv(v2);
|
|
|
|
glNormal3fv(n4); glVertex3fv(v4);
|
|
|
|
|
|
|
|
for(; b<dl->nr; b++) {
|
|
|
|
|
|
|
|
glNormal3fv(n1); glVertex3fv(v1);
|
|
|
|
glNormal3fv(n3); glVertex3fv(v3);
|
|
|
|
|
|
|
|
v2= v1; v1+= 3;
|
|
|
|
v4= v3; v3+= 3;
|
|
|
|
n2= n1; n1+= 3;
|
|
|
|
n4= n3; n3+= 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DL_INDEX3:
|
|
|
|
|
|
|
|
parts= dl->parts;
|
|
|
|
data= dl->verts;
|
|
|
|
ndata= dl->nors;
|
|
|
|
index= dl->index;
|
|
|
|
|
|
|
|
set_gl_material(dl->col+1);
|
|
|
|
|
|
|
|
/* voor polys only one normal needed */
|
|
|
|
if(index3_nors_incr==0) {
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
glNormal3fv(ndata);
|
|
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
glEnd();
|
|
|
|
index+= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
ofs= 3*index[0];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
ofs= 3*index[1];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
ofs= 3*index[2];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
glEnd();
|
|
|
|
index+= 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DL_INDEX4:
|
|
|
|
|
|
|
|
parts= dl->parts;
|
|
|
|
data= dl->verts;
|
|
|
|
ndata= dl->nors;
|
|
|
|
index= dl->index;
|
|
|
|
|
|
|
|
set_gl_material(dl->col+1);
|
|
|
|
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
|
|
|
|
ofs= 3*index[0];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
ofs= 3*index[1];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
ofs= 3*index[2];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
if(index[3]) {
|
|
|
|
ofs= 3*index[3];
|
|
|
|
glNormal3fv(ndata+ofs); glVertex3fv(data+ofs);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
index+= 4;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
dl= dl->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glFrontFace(GL_CCW);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawDispListshaded(ListBase *lb, Object *ob)
|
|
|
|
{
|
|
|
|
DispList *dl, *dlob;
|
|
|
|
int parts, p1, p2, p3, p4, a, b, *index;
|
2005-07-17 18:37:27 +00:00
|
|
|
float *data, *v1, *v2, *v3, *v4;
|
2005-03-26 17:29:37 +00:00
|
|
|
unsigned int *cdata, *c1, *c2, *c3, *c4;
|
|
|
|
char *cp;
|
|
|
|
|
|
|
|
if(lb==0) return;
|
|
|
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
|
|
|
dl= lb->first;
|
|
|
|
dlob= ob->disp.first;
|
|
|
|
while(dl && dlob) {
|
|
|
|
|
|
|
|
cdata= dlob->col1;
|
|
|
|
data= dl->verts;
|
|
|
|
if(cdata==0) break;
|
|
|
|
|
|
|
|
switch(dl->type) {
|
|
|
|
case DL_SURF:
|
|
|
|
|
|
|
|
for(a=0; a<dl->parts; a++) {
|
|
|
|
|
|
|
|
DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
|
|
|
|
|
|
|
|
v1= data+ 3*p1;
|
|
|
|
v2= data+ 3*p2;
|
|
|
|
v3= data+ 3*p3;
|
|
|
|
v4= data+ 3*p4;
|
|
|
|
c1= cdata+ p1;
|
|
|
|
c2= cdata+ p2;
|
|
|
|
c3= cdata+ p3;
|
|
|
|
c4= cdata+ p4;
|
|
|
|
|
|
|
|
for(; b<dl->nr; b++) {
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
cp= (char *)c1;
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(v1);
|
|
|
|
cp= (char *)c2;
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(v2);
|
|
|
|
cp= (char *)c4;
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(v4);
|
|
|
|
cp= (char *)c3;
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(v3);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
v2= v1; v1+= 3;
|
|
|
|
v4= v3; v3+= 3;
|
|
|
|
c2= c1; c1++;
|
|
|
|
c4= c3; c3++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DL_INDEX3:
|
|
|
|
|
|
|
|
parts= dl->parts;
|
|
|
|
index= dl->index;
|
|
|
|
|
|
|
|
while(parts--) {
|
|
|
|
|
|
|
|
glBegin(GL_TRIANGLES);
|
|
|
|
cp= (char *)(cdata+index[0]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[0]);
|
|
|
|
|
|
|
|
cp= (char *)(cdata+index[1]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[1]);
|
|
|
|
|
|
|
|
cp= (char *)(cdata+index[2]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
glEnd();
|
|
|
|
index+= 3;
|
2005-01-08 21:16:24 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
break;
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
case DL_INDEX4:
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
parts= dl->parts;
|
|
|
|
index= dl->index;
|
|
|
|
while(parts--) {
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glBegin(index[3]?GL_QUADS:GL_TRIANGLES);
|
|
|
|
cp= (char *)(cdata+index[0]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[0]);
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
cp= (char *)(cdata+index[1]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[1]);
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
cp= (char *)(cdata+index[2]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[2]);
|
|
|
|
|
|
|
|
if(index[3]) {
|
|
|
|
|
|
|
|
cp= (char *)(cdata+index[3]);
|
|
|
|
glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
glVertex3fv(data+3*index[3]);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
index+= 4;
|
2005-01-08 21:16:24 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
break;
|
|
|
|
|
2005-01-08 21:16:24 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
dl= dl->next;
|
|
|
|
dlob= dlob->next;
|
2005-01-08 21:16:24 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glShadeModel(GL_FLAT);
|
2005-01-08 21:16:24 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void drawDispList(Object *ob, int dt)
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2005-03-26 17:29:37 +00:00
|
|
|
ListBase *lb=0;
|
2002-10-12 11:37:38 +00:00
|
|
|
DispList *dl;
|
2005-03-26 17:29:37 +00:00
|
|
|
Curve *cu;
|
|
|
|
int solid;
|
|
|
|
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
solid= (dt > OB_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
switch(ob->type) {
|
|
|
|
case OB_FONT:
|
|
|
|
case OB_CURVE:
|
|
|
|
cu= ob->data;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
lb= &cu->disp;
|
2005-07-14 18:14:19 +00:00
|
|
|
if(lb->first==0) makeDispListCurveTypes(ob);
|
2003-10-21 16:41:28 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(solid) {
|
|
|
|
dl= lb->first;
|
|
|
|
if(dl==0) return;
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* rule: dl->type INDEX3 is always first in list */
|
|
|
|
if(dl->type!=DL_INDEX3) {
|
|
|
|
if(ob==G.obedit) curve_to_filledpoly(ob->data, &editNurb, lb);
|
|
|
|
else curve_to_filledpoly(ob->data, &cu->nurb, lb);
|
|
|
|
|
|
|
|
dl= lb->first;
|
|
|
|
}
|
|
|
|
if(dl->nors==0) addnormalsDispList(ob, lb);
|
2003-07-20 20:38:22 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
index3_nors_incr= 0;
|
2003-10-22 09:06:30 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if( displist_has_faces(lb)==0) {
|
|
|
|
draw_index_wire= 0;
|
|
|
|
drawDispListwire(lb);
|
|
|
|
draw_index_wire= 1;
|
2003-07-20 20:38:22 +00:00
|
|
|
}
|
2004-09-25 13:42:31 +00:00
|
|
|
else {
|
2005-03-26 17:29:37 +00:00
|
|
|
if(dt==OB_SHADED) {
|
|
|
|
if(ob->disp.first==0) shadeDispList(ob);
|
|
|
|
drawDispListshaded(lb, ob);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
init_gl_materials(ob);
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
|
|
|
drawDispListsolid(lb, ob);
|
|
|
|
}
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
cpack(0);
|
|
|
|
draw_index_wire= 0;
|
|
|
|
drawDispListwire(lb);
|
|
|
|
draw_index_wire= 1;
|
2004-09-25 13:42:31 +00:00
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
index3_nors_incr= 1;
|
2003-07-20 20:38:22 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else {
|
|
|
|
draw_index_wire= 0;
|
|
|
|
drawDispListwire(lb);
|
|
|
|
draw_index_wire= 1;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OB_SURF:
|
|
|
|
|
|
|
|
lb= &((Curve *)ob->data)->disp;
|
2005-07-14 18:14:19 +00:00
|
|
|
if(lb->first==0) makeDispListCurveTypes(ob);
|
2004-09-25 13:42:31 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(solid) {
|
|
|
|
dl= lb->first;
|
|
|
|
if(dl==0) return;
|
|
|
|
|
|
|
|
if(dl->nors==0) addnormalsDispList(ob, lb);
|
2004-09-25 13:42:31 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(dt==OB_SHADED) {
|
|
|
|
if(ob->disp.first==0) shadeDispList(ob);
|
|
|
|
drawDispListshaded(lb, ob);
|
|
|
|
}
|
2003-10-22 09:06:30 +00:00
|
|
|
else {
|
2005-03-26 17:29:37 +00:00
|
|
|
init_gl_materials(ob);
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
|
|
|
|
|
|
|
drawDispListsolid(lb, ob);
|
2003-10-22 09:06:30 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
else {
|
|
|
|
drawDispListwire(lb);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case OB_MBALL:
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if( is_basis_mball(ob)) {
|
|
|
|
lb= &ob->disp;
|
2005-07-14 18:14:19 +00:00
|
|
|
if(lb->first==0) makeDispListMBall(ob);
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
if(solid) {
|
|
|
|
|
|
|
|
if(dt==OB_SHADED) {
|
|
|
|
dl= lb->first;
|
|
|
|
if(dl && dl->col1==0) shadeDispList(ob);
|
|
|
|
drawDispListshaded(lb, ob);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
init_gl_materials(ob);
|
|
|
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
|
|
|
|
|
|
|
drawDispListsolid(lb, ob);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
/* MetaBalls use DL_INDEX4 type of DispList */
|
|
|
|
drawDispListwire(lb);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************************** */
|
|
|
|
|
|
|
|
|
|
|
|
static void draw_particle_system(Object *ob, PartEff *paf)
|
|
|
|
{
|
|
|
|
Particle *pa;
|
|
|
|
float ptime, ctime, vec[3], vec1[3];
|
|
|
|
int a;
|
|
|
|
|
|
|
|
pa= paf->keys;
|
|
|
|
if(pa==0) {
|
|
|
|
build_particle_system(ob);
|
|
|
|
pa= paf->keys;
|
|
|
|
if(pa==0) return;
|
|
|
|
}
|
|
|
|
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
|
|
|
|
if(ob->ipoflag & OB_OFFS_PARTICLE) ptime= ob->sf;
|
|
|
|
else ptime= 0.0;
|
|
|
|
ctime= bsystem_time(ob, 0, (float)(G.scene->r.cfra), ptime);
|
|
|
|
|
|
|
|
glPointSize(1.0);
|
|
|
|
if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
|
Added LSCM UV Unwrapping:
http://www.loria.fr/~levy/Galleries/LSCM/index.html
http://www.loria.fr/~levy/Papers/2002/s2002_lscm.pdf
Implementation Least Squares Conformal Maps parameterization, based on
chapter 2 of:
Bruno Levy, Sylvain Petitjean, Nicolas Ray, Jerome Maillot. Least Squares
Conformal Maps for Automatic Texture Atlas Generation. In Siggraph 2002,
July 2002.
Seams: Stored as a flag (ME_SEAM) in the new MEdge struct, these seams define
where a mesh will be cut when executing LSCM unwrapping. Seams can be marked
and cleared in Edit Mode. Ctrl+EKEY will pop up a menu allowing to Clear or Mark
the selected edges as seams.
Select Linked in Face Select Mode now only selects linked faces if no seams
separate them. So if seams are defined, this will now select the 'face group'
defined by the seams. Hotkey is still LKEY.
LSCM Unwrap: unwrap UV's by calculating a conformal mapping (preserving local
angles). Based on seams, the selected faces will be 'cut'. If multiple
'face groups' are selected, they will be unwrapped separately and packed in
the image rectangle in the UV Editor. Packing uses a simple and fast
algorithm, only designed to avoid having overlapping faces.
LSCM can be found in the Unwrap menu (UKEY), and the UV Calculation panel.
Pinning: UV's can be pinned in the UV Editor. When LSCM Unwrap is then
executed, these UV's will stay in place, allowing to tweak the solution.
PKEY and ALT+PKEY will respectively pin and unpin selected UV's.
Face Select Mode Drawing Changes:
- Draw Seams option to enable disable drawing of seams
- Draw Faces option to enable drawing of selected faces in transparent purple
- Draw Hidden Edges option to enable drawing of edges of hidden faces
- Draw Edges option to enable drawing of edges of visible faces
The colors for these seams, faces and edges are themeable.
2004-07-13 11:48:52 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(ctime > pa->time) {
|
|
|
|
if(ctime < pa->time+pa->lifetime) {
|
|
|
|
|
|
|
|
if(paf->stype==PAF_VECT) {
|
|
|
|
where_is_particle(paf, pa, ctime, vec);
|
|
|
|
where_is_particle(paf, pa, ctime+1.0, vec1);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glVertex3fv(vec1);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
where_is_particle(paf, pa, ctime, vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glVertex3fv(vec);
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
}
|
|
|
|
if(paf->stype!=PAF_VECT) glEnd();
|
|
|
|
|
|
|
|
mymultmatrix(ob->obmat); // bring back local matrix for dtx
|
|
|
|
}
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void draw_static_particle_system(Object *ob, PartEff *paf)
|
|
|
|
{
|
|
|
|
Particle *pa;
|
|
|
|
float ctime, mtime, vec[3], vec1[3];
|
|
|
|
int a;
|
|
|
|
|
|
|
|
pa= paf->keys;
|
|
|
|
if(pa==0) {
|
|
|
|
build_particle_system(ob);
|
|
|
|
pa= paf->keys;
|
|
|
|
if(pa==0) return;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
|
|
|
glPointSize(1.0);
|
|
|
|
if(paf->stype!=PAF_VECT) glBegin(GL_POINTS);
|
2005-01-08 21:16:24 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
for(a=0; a<paf->totpart; a++, pa+=paf->totkey) {
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
where_is_particle(paf, pa, pa->time, vec1);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
mtime= pa->time+pa->lifetime+paf->staticstep-1;
|
2004-07-03 18:39:19 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
for(ctime= pa->time; ctime<mtime; ctime+=paf->staticstep) {
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* make sure hair grows until the end.. */
|
|
|
|
if(ctime>pa->time+pa->lifetime) ctime= pa->time+pa->lifetime;
|
|
|
|
|
|
|
|
if(paf->stype==PAF_VECT) {
|
|
|
|
where_is_particle(paf, pa, ctime+1, vec);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glVertex3fv(vec1);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
VECCOPY(vec1, vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-07-03 18:39:19 +00:00
|
|
|
else {
|
2005-03-26 17:29:37 +00:00
|
|
|
where_is_particle(paf, pa, ctime, vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glVertex3fv(vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
if(paf->stype!=PAF_VECT) glEnd();
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
unsigned int nurbcol[8]= {
|
|
|
|
0, 0x9090, 0x409030, 0x603080, 0, 0x40fff0, 0x40c033, 0xA090F0 };
|
|
|
|
|
|
|
|
static void tekenhandlesN(Nurb *nu, short sel)
|
|
|
|
{
|
|
|
|
BezTriple *bezt;
|
|
|
|
float *fp;
|
|
|
|
unsigned int *col;
|
|
|
|
int a;
|
|
|
|
|
|
|
|
if(nu->hide) return;
|
|
|
|
if( (nu->type & 7)==1) {
|
|
|
|
if(sel) col= nurbcol+4;
|
|
|
|
else col= nurbcol;
|
|
|
|
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide==0) {
|
|
|
|
if( (bezt->f2 & 1)==sel) {
|
|
|
|
fp= bezt->vec[0];
|
|
|
|
cpack(col[bezt->h1]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(fp);
|
|
|
|
glVertex3fv(fp+3);
|
|
|
|
glEnd();
|
|
|
|
cpack(col[bezt->h2]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(fp+3);
|
|
|
|
glVertex3fv(fp+6);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else if( (bezt->f1 & 1)==sel) {
|
|
|
|
fp= bezt->vec[0];
|
|
|
|
cpack(col[bezt->h1]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(fp);
|
|
|
|
glVertex3fv(fp+3);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
else if( (bezt->f3 & 1)==sel) {
|
|
|
|
fp= bezt->vec[1];
|
|
|
|
cpack(col[bezt->h2]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(fp);
|
|
|
|
glVertex3fv(fp+3);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void tekenvertsN(Nurb *nu, short sel)
|
|
|
|
{
|
|
|
|
BezTriple *bezt;
|
|
|
|
BPoint *bp;
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
float size;
|
2002-10-12 11:37:38 +00:00
|
|
|
int a;
|
|
|
|
|
|
|
|
if(nu->hide) return;
|
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
if(sel) BIF_ThemeColor(TH_VERTEX_SELECT);
|
|
|
|
else BIF_ThemeColor(TH_VERTEX);
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
|
Another mega commit... loadsof restructure, and a pretty good one! :)
- changed the BIF_DrawString() function. it used to work different for
AA fonts as for default fonts. Now it's identical. Setting color for fonts
can just be done with OpenGL, for both font types.
Removed: BIF_DrawStringRGB()
- added theme color options for Buttons
- recoded DefButton, so it automatically chooses the right color.
- had to remove a 1000 uiBlockSetCol() calls for that reason...
- uiBlockSetCol() still works, to override automatic color
- removed entirely the silly old color system (BIFColorID). All color
calls can now be done with a BIF_ThemeColor() call, including fonts and
buttons and opengl stuff
- all buttons in button header have headercolor by default
- recoded drawing icons, it was a really bad & old loop doing manually
colorshading and blending... which was per pixel a load of code!
Now it uses a single OpenGL call to blend or colorize. Quite faster!
- (as test, for review) icons don't colorize anymore with button color,
but have a different alpha to blend in (when not active)
- recoded the entire interface_draw.c file...:
- drawing buttons is separated in three parts:
1. main drawing function for text and icons
2. free definable callback for button itself
3. free definable callback for slider
- removed a load of redundant code for this!
- coded a minimal theme, and adjusted Matt's buttons to match new
callback system
- adding new drawing themes is piece of cake now
- for coders, default 'themes' to be aware of:
UI_EMBOSS : the themable drawing style
UI_EMBOSSP: the pulldown menu system (apart from color not themable)
UI_EMBOSSN: draw nothing, only text and/or icon
UI_EMBOSSM: minimal theme, still in use for Logic and Constraintsa
this can be set with uiBlockSetEmboss(block) or in the uiNewBlock() call.
TODO: make UI API call for button alignment
(plus removed another series of warnings from code...)
Plus: fixed bug in Matts commit: he used a 'short' button for an 'int'
2003-10-20 15:40:20 +00:00
|
|
|
size= BIF_GetThemeValuef(TH_VERTEX_SIZE);
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
glPointSize(size);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-07-10 21:35:17 +00:00
|
|
|
bglBegin(GL_POINTS);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if((nu->type & 7)==1) {
|
|
|
|
|
|
|
|
bezt= nu->bezt;
|
|
|
|
a= nu->pntsu;
|
|
|
|
while(a--) {
|
|
|
|
if(bezt->hide==0) {
|
2004-07-10 21:35:17 +00:00
|
|
|
if((bezt->f1 & 1)==sel) bglVertex3fv(bezt->vec[0]);
|
|
|
|
if((bezt->f2 & 1)==sel) bglVertex3fv(bezt->vec[1]);
|
|
|
|
if((bezt->f3 & 1)==sel) bglVertex3fv(bezt->vec[2]);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
bezt++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
bp= nu->bp;
|
|
|
|
a= nu->pntsu*nu->pntsv;
|
|
|
|
while(a--) {
|
|
|
|
if(bp->hide==0) {
|
2004-07-10 21:35:17 +00:00
|
|
|
if((bp->f1 & 1)==sel) bglVertex3fv(bp->vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
bp++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-07-10 21:35:17 +00:00
|
|
|
bglEnd();
|
2002-10-12 11:37:38 +00:00
|
|
|
glPointSize(1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_editnurb(Object *ob, Nurb *nurb, int sel)
|
|
|
|
{
|
|
|
|
Nurb *nu;
|
|
|
|
BPoint *bp, *bp1;
|
|
|
|
int a, b, ofs;
|
|
|
|
|
|
|
|
nu= nurb;
|
|
|
|
while(nu) {
|
|
|
|
if(nu->hide==0) {
|
|
|
|
switch(nu->type & 7) {
|
|
|
|
case CU_POLY:
|
|
|
|
cpack(nurbcol[3]);
|
|
|
|
bp= nu->bp;
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
if(nu->flagu & 1) glBegin(GL_LINE_LOOP);
|
|
|
|
|
|
|
|
else glBegin(GL_LINE_STRIP);
|
|
|
|
|
|
|
|
for(a=0; a<nu->pntsu; a++, bp++) {
|
|
|
|
glVertex3fv(bp->vec);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(nu->flagu & 1) glEnd();
|
|
|
|
else glEnd();
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CU_NURBS:
|
|
|
|
|
|
|
|
bp= nu->bp;
|
|
|
|
for(b=0; b<nu->pntsv; b++) {
|
|
|
|
bp1= bp;
|
|
|
|
bp++;
|
|
|
|
for(a=nu->pntsu-1; a>0; a--, bp++) {
|
|
|
|
if(bp->hide==0 && bp1->hide==0) {
|
|
|
|
if(sel) {
|
|
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
|
|
|
|
cpack(nurbcol[5]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(bp->vec);
|
|
|
|
glVertex3fv(bp1->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) );
|
|
|
|
else {
|
|
|
|
cpack(nurbcol[1]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(bp->vec);
|
|
|
|
glVertex3fv(bp1->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bp1= bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(nu->pntsv > 1) { /* surface */
|
|
|
|
|
|
|
|
ofs= nu->pntsu;
|
|
|
|
for(b=0; b<nu->pntsu; b++) {
|
|
|
|
bp1= nu->bp+b;
|
|
|
|
bp= bp1+ofs;
|
|
|
|
for(a=nu->pntsv-1; a>0; a--, bp+=ofs) {
|
|
|
|
if(bp->hide==0 && bp1->hide==0) {
|
|
|
|
if(sel) {
|
|
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) ) {
|
|
|
|
cpack(nurbcol[7]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(bp->vec);
|
|
|
|
glVertex3fv(bp1->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if( (bp->f1 & 1) && ( bp1->f1 & 1) );
|
|
|
|
else {
|
|
|
|
cpack(nurbcol[3]);
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex3fv(bp->vec);
|
|
|
|
glVertex3fv(bp1->vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bp1= bp;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawnurb(Object *ob, Nurb *nurb, int dt)
|
|
|
|
{
|
|
|
|
Curve *cu;
|
|
|
|
Nurb *nu;
|
|
|
|
BevPoint *bevp;
|
|
|
|
BevList *bl;
|
|
|
|
float vec[3];
|
|
|
|
int a, nr, skip;
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* first non-selected handles */
|
2002-10-12 11:37:38 +00:00
|
|
|
nu= nurb;
|
|
|
|
while(nu) {
|
|
|
|
if((nu->type & 7)==CU_BEZIER) {
|
|
|
|
tekenhandlesN(nu, 0);
|
|
|
|
}
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* then DispList */
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-12-04 11:37:39 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
cu= ob->data;
|
|
|
|
drawDispList(ob, dt);
|
|
|
|
|
|
|
|
draw_editnurb(ob, nurb, 0);
|
|
|
|
draw_editnurb(ob, nurb, 1);
|
|
|
|
|
|
|
|
if(cu->flag & CU_3D) {
|
|
|
|
|
|
|
|
if(cu->bev.first==0) makeBevelList(ob);
|
|
|
|
|
2003-12-04 11:37:39 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
bl= cu->bev.first;
|
|
|
|
nu= nurb;
|
|
|
|
while(nu && bl) {
|
|
|
|
bevp= (BevPoint *)(bl+1);
|
|
|
|
nr= bl->nr;
|
|
|
|
|
|
|
|
skip= nu->resolu/16;
|
|
|
|
|
|
|
|
while(nr-- > 0) {
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2005-05-03 10:54:42 +00:00
|
|
|
vec[0]= bevp->x-G.scene->editbutsize*bevp->mat[0][0];
|
|
|
|
vec[1]= bevp->y-G.scene->editbutsize*bevp->mat[0][1];
|
|
|
|
vec[2]= bevp->z-G.scene->editbutsize*bevp->mat[0][2];
|
2002-10-12 11:37:38 +00:00
|
|
|
glVertex3fv(vec);
|
2005-05-03 10:54:42 +00:00
|
|
|
vec[0]= bevp->x+G.scene->editbutsize*bevp->mat[0][0];
|
|
|
|
vec[1]= bevp->y+G.scene->editbutsize*bevp->mat[0][1];
|
|
|
|
vec[2]= bevp->z+G.scene->editbutsize*bevp->mat[0][2];
|
2002-10-12 11:37:38 +00:00
|
|
|
glVertex3fv(vec);
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
bevp++;
|
|
|
|
|
|
|
|
a= skip;
|
|
|
|
while(a--) {
|
|
|
|
bevp++;
|
|
|
|
nr--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bl= bl->next;
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
calc_Nurbverts(nurb);
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
nu= nurb;
|
|
|
|
while(nu) {
|
|
|
|
if((nu->type & 7)==1) tekenhandlesN(nu, 1);
|
|
|
|
tekenvertsN(nu, 0);
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
nu= nurb;
|
|
|
|
while(nu) {
|
|
|
|
tekenvertsN(nu, 1);
|
|
|
|
nu= nu->next;
|
|
|
|
}
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void tekentextcurs(void)
|
|
|
|
{
|
|
|
|
cpack(0);
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glVertex2fv(G.textcurs[0]);
|
|
|
|
glVertex2fv(G.textcurs[1]);
|
|
|
|
glVertex2fv(G.textcurs[2]);
|
|
|
|
glVertex2fv(G.textcurs[3]);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
2005-03-09 19:45:59 +00:00
|
|
|
static void drawspiral(float *cent, float rad, float tmat[][4], int start)
|
2004-07-18 22:23:50 +00:00
|
|
|
{
|
|
|
|
float vec[3], vx[3], vy[3];
|
|
|
|
int a, tot=32;
|
2004-08-16 01:14:18 +00:00
|
|
|
char inverse=0;
|
2004-07-18 22:23:50 +00:00
|
|
|
/* 32 values of sin function (still same result!) */
|
|
|
|
static float si[32] = {0.00000000,
|
|
|
|
0.20129852,
|
|
|
|
0.39435585,
|
|
|
|
0.57126821,
|
|
|
|
0.72479278,
|
|
|
|
0.84864425,
|
|
|
|
0.93775213,
|
|
|
|
0.98846832,
|
|
|
|
0.99871650,
|
|
|
|
0.96807711,
|
|
|
|
0.89780453,
|
|
|
|
0.79077573,
|
|
|
|
0.65137248,
|
|
|
|
0.48530196,
|
|
|
|
0.29936312,
|
|
|
|
0.10116832,
|
|
|
|
-0.10116832,
|
|
|
|
-0.29936312,
|
|
|
|
-0.48530196,
|
|
|
|
-0.65137248,
|
|
|
|
-0.79077573,
|
|
|
|
-0.89780453,
|
|
|
|
-0.96807711,
|
|
|
|
-0.99871650,
|
|
|
|
-0.98846832,
|
|
|
|
-0.93775213,
|
|
|
|
-0.84864425,
|
|
|
|
-0.72479278,
|
|
|
|
-0.57126821,
|
|
|
|
-0.39435585,
|
|
|
|
-0.20129852,
|
|
|
|
0.00000000};
|
|
|
|
/* 32 values of cos function (still same result!) */
|
|
|
|
static float co[32] ={1.00000000,
|
|
|
|
0.97952994,
|
|
|
|
0.91895781,
|
|
|
|
0.82076344,
|
|
|
|
0.68896691,
|
|
|
|
0.52896401,
|
|
|
|
0.34730525,
|
|
|
|
0.15142777,
|
|
|
|
-0.05064916,
|
|
|
|
-0.25065253,
|
|
|
|
-0.44039415,
|
|
|
|
-0.61210598,
|
|
|
|
-0.75875812,
|
|
|
|
-0.87434661,
|
|
|
|
-0.95413925,
|
|
|
|
-0.99486932,
|
|
|
|
-0.99486932,
|
|
|
|
-0.95413925,
|
|
|
|
-0.87434661,
|
|
|
|
-0.75875812,
|
|
|
|
-0.61210598,
|
|
|
|
-0.44039415,
|
|
|
|
-0.25065253,
|
|
|
|
-0.05064916,
|
|
|
|
0.15142777,
|
|
|
|
0.34730525,
|
|
|
|
0.52896401,
|
|
|
|
0.68896691,
|
|
|
|
0.82076344,
|
|
|
|
0.91895781,
|
|
|
|
0.97952994,
|
|
|
|
1.00000000};
|
|
|
|
|
2004-08-16 01:14:18 +00:00
|
|
|
if (start < 0) {
|
|
|
|
inverse = 1;
|
|
|
|
start *= -1;
|
|
|
|
}
|
|
|
|
|
2004-07-18 22:23:50 +00:00
|
|
|
VECCOPY(vx, tmat[0]);
|
|
|
|
VECCOPY(vy, tmat[1]);
|
|
|
|
VecMulf(vx, rad);
|
|
|
|
VecMulf(vy, rad);
|
|
|
|
|
|
|
|
VECCOPY(vec, cent);
|
|
|
|
|
2004-08-16 01:14:18 +00:00
|
|
|
if (inverse==0) {
|
|
|
|
for(a=0; a<tot; a++) {
|
|
|
|
if (a+start>31)
|
|
|
|
start=-a + 1;
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)a/(float)tot) + *(co+a+start) * (vy[0] * (float)a/(float)tot);
|
|
|
|
vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)a/(float)tot) + *(co+a+start) * (vy[1] * (float)a/(float)tot);
|
|
|
|
vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)a/(float)tot) + *(co+a+start) * (vy[2] * (float)a/(float)tot);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
a=0;
|
|
|
|
vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
|
|
|
|
vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
|
|
|
|
vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
|
|
|
|
for(a=0; a<tot; a++) {
|
|
|
|
if (a+start>31)
|
|
|
|
start=-a + 1;
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
vec[0]= cent[0] + *(si+a+start) * (vx[0] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[0] * (float)(-a+31)/(float)tot);
|
|
|
|
vec[1]= cent[1] + *(si+a+start) * (vx[1] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[1] * (float)(-a+31)/(float)tot);
|
|
|
|
vec[2]= cent[2] + *(si+a+start) * (vx[2] * (float)(-a+31)/(float)tot) + *(co+a+start) * (vy[2] * (float)(-a+31)/(float)tot);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
}
|
2004-07-18 22:23:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-20 08:26:22 +00:00
|
|
|
void drawcircball(int mode, float *cent, float rad, float tmat[][4])
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
2003-09-08 12:13:54 +00:00
|
|
|
float vec[3], vx[3], vy[3];
|
2002-10-12 11:37:38 +00:00
|
|
|
int a, tot=32;
|
2003-09-08 12:13:54 +00:00
|
|
|
|
|
|
|
/* 32 values of sin function (still same result!) */
|
|
|
|
static float si[32] = {0.00000000,
|
|
|
|
0.20129852,
|
|
|
|
0.39435585,
|
|
|
|
0.57126821,
|
|
|
|
0.72479278,
|
|
|
|
0.84864425,
|
|
|
|
0.93775213,
|
|
|
|
0.98846832,
|
|
|
|
0.99871650,
|
|
|
|
0.96807711,
|
|
|
|
0.89780453,
|
|
|
|
0.79077573,
|
|
|
|
0.65137248,
|
|
|
|
0.48530196,
|
|
|
|
0.29936312,
|
|
|
|
0.10116832,
|
|
|
|
-0.10116832,
|
|
|
|
-0.29936312,
|
|
|
|
-0.48530196,
|
|
|
|
-0.65137248,
|
|
|
|
-0.79077573,
|
|
|
|
-0.89780453,
|
|
|
|
-0.96807711,
|
|
|
|
-0.99871650,
|
|
|
|
-0.98846832,
|
|
|
|
-0.93775213,
|
|
|
|
-0.84864425,
|
|
|
|
-0.72479278,
|
|
|
|
-0.57126821,
|
|
|
|
-0.39435585,
|
|
|
|
-0.20129852,
|
|
|
|
0.00000000};
|
|
|
|
/* 32 values of cos function (still same result!) */
|
|
|
|
static float co[32] ={1.00000000,
|
|
|
|
0.97952994,
|
|
|
|
0.91895781,
|
|
|
|
0.82076344,
|
|
|
|
0.68896691,
|
|
|
|
0.52896401,
|
|
|
|
0.34730525,
|
|
|
|
0.15142777,
|
|
|
|
-0.05064916,
|
|
|
|
-0.25065253,
|
|
|
|
-0.44039415,
|
|
|
|
-0.61210598,
|
|
|
|
-0.75875812,
|
|
|
|
-0.87434661,
|
|
|
|
-0.95413925,
|
|
|
|
-0.99486932,
|
|
|
|
-0.99486932,
|
|
|
|
-0.95413925,
|
|
|
|
-0.87434661,
|
|
|
|
-0.75875812,
|
|
|
|
-0.61210598,
|
|
|
|
-0.44039415,
|
|
|
|
-0.25065253,
|
|
|
|
-0.05064916,
|
|
|
|
0.15142777,
|
|
|
|
0.34730525,
|
|
|
|
0.52896401,
|
|
|
|
0.68896691,
|
|
|
|
0.82076344,
|
|
|
|
0.91895781,
|
|
|
|
0.97952994,
|
|
|
|
1.00000000};
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
VECCOPY(vx, tmat[0]);
|
|
|
|
VECCOPY(vy, tmat[1]);
|
|
|
|
VecMulf(vx, rad);
|
|
|
|
VecMulf(vy, rad);
|
|
|
|
|
2005-04-20 08:26:22 +00:00
|
|
|
glBegin(mode);
|
2003-09-08 12:13:54 +00:00
|
|
|
for(a=0; a<tot; a++) {
|
|
|
|
vec[0]= cent[0] + *(si+a) * vx[0] + *(co+a) * vy[0];
|
|
|
|
vec[1]= cent[1] + *(si+a) * vx[1] + *(co+a) * vy[1];
|
|
|
|
vec[2]= cent[2] + *(si+a) * vx[2] + *(co+a) * vy[2];
|
2002-10-12 11:37:38 +00:00
|
|
|
glVertex3fv(vec);
|
|
|
|
}
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawmball(Object *ob, int dt)
|
|
|
|
{
|
|
|
|
MetaBall *mb;
|
|
|
|
MetaElem *ml;
|
|
|
|
float imat[4][4], tmat[4][4];
|
|
|
|
int code= 1;
|
|
|
|
|
|
|
|
mb= ob->data;
|
|
|
|
|
|
|
|
if(ob==G.obedit) {
|
2003-12-04 11:37:39 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
if((G.f & G_PICKSEL)==0 ) drawDispList(ob, dt);
|
|
|
|
ml= editelems.first;
|
2004-06-19 17:35:37 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
drawDispList(ob, dt);
|
|
|
|
ml= mb->elems.first;
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-06-19 17:35:37 +00:00
|
|
|
/* in case solid draw, reset wire colors */
|
|
|
|
if(ob!=G.obedit && (ob->flag & SELECT)) {
|
|
|
|
if(ob==OBACT) BIF_ThemeColor(TH_ACTIVE);
|
|
|
|
else BIF_ThemeColor(TH_SELECT);
|
|
|
|
}
|
|
|
|
else BIF_ThemeColor(TH_WIRE);
|
|
|
|
|
|
|
|
mygetmatrix(tmat);
|
|
|
|
Mat4Invert(imat, tmat);
|
|
|
|
Normalise(imat[0]);
|
|
|
|
Normalise(imat[1]);
|
|
|
|
|
|
|
|
while(ml) {
|
2005-04-11 19:31:05 +00:00
|
|
|
|
|
|
|
/* draw radius */
|
2004-06-19 17:35:37 +00:00
|
|
|
if(ob==G.obedit) {
|
2005-04-11 19:31:05 +00:00
|
|
|
if((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) cpack(0xA0A0F0);
|
2004-06-19 17:35:37 +00:00
|
|
|
else cpack(0x3030A0);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-06-19 17:35:37 +00:00
|
|
|
if(G.f & G_PICKSEL) {
|
2005-04-11 19:31:05 +00:00
|
|
|
ml->selcol1= code;
|
2004-06-19 17:35:37 +00:00
|
|
|
glLoadName(code++);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad, imat);
|
2005-04-11 19:31:05 +00:00
|
|
|
|
|
|
|
/* draw stiffness */
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
if((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) cpack(0xA0F0A0);
|
|
|
|
else cpack(0x30A030);
|
|
|
|
|
|
|
|
if(G.f & G_PICKSEL) {
|
|
|
|
ml->selcol2= code;
|
|
|
|
glLoadName(code++);
|
|
|
|
}
|
2005-05-22 19:16:04 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, &(ml->x), ml->rad*atan(ml->s)/M_PI_2, imat);
|
2005-04-11 19:31:05 +00:00
|
|
|
}
|
2004-06-19 17:35:37 +00:00
|
|
|
|
|
|
|
ml= ml->next;
|
2004-06-19 09:35:23 +00:00
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2004-07-11 13:17:03 +00:00
|
|
|
static void draw_forcefield(Object *ob)
|
|
|
|
{
|
2005-04-04 18:09:47 +00:00
|
|
|
PartDeflect *pd= ob->pd;
|
2004-07-11 13:17:03 +00:00
|
|
|
float imat[4][4], tmat[4][4];
|
|
|
|
float vec[3]= {0.0, 0.0, 0.0};
|
|
|
|
|
2005-04-04 18:09:47 +00:00
|
|
|
/* calculus here, is reused in PFIELD_FORCE */
|
|
|
|
mygetmatrix(tmat);
|
|
|
|
Mat4Invert(imat, tmat);
|
|
|
|
// Normalise(imat[0]); // we don't do this because field doesnt scale either... apart from wind!
|
|
|
|
// Normalise(imat[1]);
|
|
|
|
|
|
|
|
if(pd->flag & PFIELD_USEMAX) {
|
|
|
|
setlinestyle(3);
|
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5);
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, pd->maxdist, imat);
|
2005-04-04 18:09:47 +00:00
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
if (pd->forcefield == PFIELD_WIND) {
|
|
|
|
float force_val;
|
|
|
|
|
|
|
|
Mat4One(tmat);
|
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5);
|
|
|
|
|
|
|
|
if (has_ipo_code(ob->ipo, OB_PD_FSTR))
|
|
|
|
force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, G.scene->r.cfra);
|
|
|
|
else
|
|
|
|
force_val = pd->f_strength;
|
|
|
|
force_val*= 0.1;
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.0, tmat);
|
2005-04-04 18:09:47 +00:00
|
|
|
vec[2]= 0.5*force_val;
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.0, tmat);
|
2005-04-04 18:09:47 +00:00
|
|
|
vec[2]= 1.0*force_val;
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.0, tmat);
|
2005-04-04 18:09:47 +00:00
|
|
|
vec[2]= 1.5*force_val;
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.0, tmat);
|
2005-04-04 18:09:47 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else if (pd->forcefield == PFIELD_FORCE) {
|
2004-07-18 22:23:50 +00:00
|
|
|
float ffall_val;
|
|
|
|
|
|
|
|
if (has_ipo_code(ob->ipo, OB_PD_FFALL))
|
|
|
|
ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, G.scene->r.cfra);
|
|
|
|
else
|
2005-04-04 18:09:47 +00:00
|
|
|
ffall_val = pd->f_power;
|
2004-07-18 22:23:50 +00:00
|
|
|
|
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.5);
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.0, imat);
|
2004-07-18 22:23:50 +00:00
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.9 - 0.4 / pow(1.5, (double)ffall_val));
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 1.5, imat);
|
2004-07-18 22:23:50 +00:00
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.9 - 0.4 / pow(2.0, (double)ffall_val));
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, 2.0, imat);
|
2004-07-18 22:23:50 +00:00
|
|
|
}
|
2005-04-04 18:09:47 +00:00
|
|
|
else if (pd->forcefield == PFIELD_VORTEX) {
|
2004-08-16 01:14:18 +00:00
|
|
|
float ffall_val, force_val;
|
2004-07-18 22:23:50 +00:00
|
|
|
|
2004-08-16 01:14:18 +00:00
|
|
|
Mat4One(imat);
|
2004-07-18 22:23:50 +00:00
|
|
|
if (has_ipo_code(ob->ipo, OB_PD_FFALL))
|
|
|
|
ffall_val = IPO_GetFloatValue(ob->ipo, OB_PD_FFALL, G.scene->r.cfra);
|
|
|
|
else
|
2005-04-04 18:09:47 +00:00
|
|
|
ffall_val = pd->f_power;
|
2004-07-18 22:23:50 +00:00
|
|
|
|
2004-08-16 01:14:18 +00:00
|
|
|
if (has_ipo_code(ob->ipo, OB_PD_FSTR))
|
|
|
|
force_val = IPO_GetFloatValue(ob->ipo, OB_PD_FSTR, G.scene->r.cfra);
|
|
|
|
else
|
2005-04-04 18:09:47 +00:00
|
|
|
force_val = pd->f_strength;
|
2004-08-16 01:14:18 +00:00
|
|
|
|
2004-07-18 22:23:50 +00:00
|
|
|
BIF_ThemeColorBlend(TH_WIRE, TH_BACK, 0.7);
|
2004-08-16 01:14:18 +00:00
|
|
|
if (force_val < 0) {
|
|
|
|
drawspiral(vec, 1.0, imat, 1);
|
|
|
|
drawspiral(vec, 1.0, imat, 16);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
drawspiral(vec, 1.0, imat, -1);
|
|
|
|
drawspiral(vec, 1.0, imat, -16);
|
|
|
|
}
|
2004-07-18 22:23:50 +00:00
|
|
|
}
|
|
|
|
|
2004-07-11 13:17:03 +00:00
|
|
|
}
|
|
|
|
|
2005-07-15 15:00:08 +00:00
|
|
|
static void draw_box(float vec[8][3])
|
2002-10-12 11:37:38 +00:00
|
|
|
{
|
|
|
|
glBegin(GL_LINE_STRIP);
|
2005-07-15 15:00:08 +00:00
|
|
|
glVertex3fv(vec[0]); glVertex3fv(vec[1]);glVertex3fv(vec[2]); glVertex3fv(vec[3]);
|
|
|
|
glVertex3fv(vec[0]); glVertex3fv(vec[4]);glVertex3fv(vec[5]); glVertex3fv(vec[6]);
|
|
|
|
glVertex3fv(vec[7]); glVertex3fv(vec[4]);
|
2002-10-12 11:37:38 +00:00
|
|
|
glEnd();
|
|
|
|
|
2005-07-15 15:00:08 +00:00
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(vec[1]); glVertex3fv(vec[5]);
|
|
|
|
glVertex3fv(vec[2]); glVertex3fv(vec[6]);
|
|
|
|
glVertex3fv(vec[3]); glVertex3fv(vec[7]);
|
2002-10-12 11:37:38 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
void get_local_bounds(Object *ob, float *centre, float *size)
|
|
|
|
{
|
|
|
|
BoundBox *bb= NULL;
|
|
|
|
/* uses boundbox, function used by Ketsji */
|
|
|
|
|
|
|
|
if(ob->type==OB_MESH) {
|
2005-07-14 18:04:27 +00:00
|
|
|
bb = mesh_get_bb(ob->data);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
|
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
|
|
}
|
|
|
|
else if(ob->type==OB_MBALL) {
|
|
|
|
bb= ob->bb;
|
|
|
|
}
|
|
|
|
if(bb==NULL) {
|
|
|
|
centre[0]= centre[1]= centre[2]= 0.0;
|
|
|
|
VECCOPY(size, ob->size);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
|
|
|
|
size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
|
|
|
|
size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
|
|
|
|
|
|
|
|
centre[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
|
|
|
|
centre[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
|
|
|
|
centre[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void draw_bb_quadric(BoundBox *bb, short type)
|
|
|
|
{
|
|
|
|
float size[3], cent[3];
|
|
|
|
GLUquadricObj *qobj = gluNewQuadric();
|
|
|
|
|
|
|
|
gluQuadricDrawStyle(qobj, GLU_SILHOUETTE);
|
|
|
|
|
|
|
|
size[0]= 0.5*fabs(bb->vec[0][0] - bb->vec[4][0]);
|
|
|
|
size[1]= 0.5*fabs(bb->vec[0][1] - bb->vec[2][1]);
|
|
|
|
size[2]= 0.5*fabs(bb->vec[0][2] - bb->vec[1][2]);
|
|
|
|
|
|
|
|
cent[0]= (bb->vec[0][0] + bb->vec[4][0])/2.0;
|
|
|
|
cent[1]= (bb->vec[0][1] + bb->vec[2][1])/2.0;
|
|
|
|
cent[2]= (bb->vec[0][2] + bb->vec[1][2])/2.0;
|
|
|
|
|
2004-04-06 14:37:25 +00:00
|
|
|
glPushMatrix();
|
2002-10-12 11:37:38 +00:00
|
|
|
if(type==OB_BOUND_SPHERE) {
|
|
|
|
glTranslatef(cent[0], cent[1], cent[2]);
|
|
|
|
glScalef(size[0], size[1], size[2]);
|
|
|
|
gluSphere(qobj, 1.0, 8, 5);
|
|
|
|
}
|
|
|
|
else if(type==OB_BOUND_CYLINDER) {
|
2004-05-16 13:23:59 +00:00
|
|
|
float radius = size[0] > size[1] ? size[0] : size[1];
|
2002-10-12 11:37:38 +00:00
|
|
|
glTranslatef(cent[0], cent[1], cent[2]-size[2]);
|
2004-05-16 13:23:59 +00:00
|
|
|
glScalef(radius, radius, 2.0*size[2]);
|
2002-10-12 11:37:38 +00:00
|
|
|
gluCylinder(qobj, 1.0, 1.0, 1.0, 8, 1);
|
|
|
|
}
|
|
|
|
else if(type==OB_BOUND_CONE) {
|
2004-05-16 13:23:59 +00:00
|
|
|
float radius = size[0] > size[1] ? size[0] : size[1];
|
|
|
|
glTranslatef(cent[0], cent[2]-size[2], cent[1]);
|
|
|
|
glScalef(radius, 2.0*size[2], radius);
|
|
|
|
glRotatef(-90., 1.0, 0.0, 0.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
gluCylinder(qobj, 1.0, 0.0, 1.0, 8, 1);
|
|
|
|
}
|
2004-04-06 14:37:25 +00:00
|
|
|
glPopMatrix();
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
gluDeleteQuadric(qobj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void draw_bounding_volume(Object *ob)
|
|
|
|
{
|
|
|
|
BoundBox *bb=0;
|
|
|
|
|
|
|
|
if(ob->type==OB_MESH) {
|
2005-07-14 18:04:27 +00:00
|
|
|
bb= mesh_get_bb(ob->data);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
|
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
|
|
if(bb==0) {
|
2005-07-14 18:14:19 +00:00
|
|
|
makeDispListCurveTypes(ob);
|
2002-10-12 11:37:38 +00:00
|
|
|
bb= ( (Curve *)ob->data )->bb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if(ob->type==OB_MBALL) {
|
|
|
|
bb= ob->bb;
|
|
|
|
if(bb==0) {
|
2005-07-14 18:14:19 +00:00
|
|
|
makeDispListMBall(ob);
|
2002-10-12 11:37:38 +00:00
|
|
|
bb= ob->bb;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
drawcube();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(bb==0) return;
|
|
|
|
|
2005-07-15 15:00:08 +00:00
|
|
|
if(ob->boundtype==OB_BOUND_BOX) draw_box(bb->vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
else draw_bb_quadric(bb, ob->boundtype);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void drawtexspace(Object *ob)
|
|
|
|
{
|
2005-07-14 21:57:18 +00:00
|
|
|
float vec[8][3], loc[3], size[3];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(ob->type==OB_MESH) {
|
2005-07-14 21:57:18 +00:00
|
|
|
mesh_get_texspace(ob->data, loc, NULL, size);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT) {
|
2005-07-14 21:57:18 +00:00
|
|
|
Curve *cu= ob->data;
|
|
|
|
VECCOPY(size, cu->size);
|
|
|
|
VECCOPY(loc, cu->loc);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else if(ob->type==OB_MBALL) {
|
2005-07-14 21:57:18 +00:00
|
|
|
MetaBall *mb= ob->data;
|
|
|
|
VECCOPY(size, mb->size);
|
|
|
|
VECCOPY(loc, mb->loc);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else return;
|
|
|
|
|
2005-07-14 21:57:18 +00:00
|
|
|
vec[0][0]=vec[1][0]=vec[2][0]=vec[3][0]= loc[0]-size[0];
|
|
|
|
vec[4][0]=vec[5][0]=vec[6][0]=vec[7][0]= loc[0]+size[0];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-07-14 21:57:18 +00:00
|
|
|
vec[0][1]=vec[1][1]=vec[4][1]=vec[5][1]= loc[1]-size[1];
|
|
|
|
vec[2][1]=vec[3][1]=vec[6][1]=vec[7][1]= loc[1]+size[1];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2005-07-14 21:57:18 +00:00
|
|
|
vec[0][2]=vec[3][2]=vec[4][2]=vec[7][2]= loc[2]-size[2];
|
|
|
|
vec[1][2]=vec[2][2]=vec[5][2]=vec[6][2]= loc[2]+size[2];
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
setlinestyle(2);
|
|
|
|
|
2005-07-15 15:00:08 +00:00
|
|
|
draw_box(vec);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
|
2004-06-17 18:31:42 +00:00
|
|
|
/* draws wire outline */
|
2005-03-26 17:29:37 +00:00
|
|
|
static void drawSolidSelect(Object *ob)
|
2004-06-17 18:31:42 +00:00
|
|
|
{
|
2005-03-26 17:29:37 +00:00
|
|
|
glLineWidth(2.0);
|
|
|
|
glDepthMask(0);
|
2005-07-14 12:44:33 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if(ELEM3(ob->type, OB_FONT,OB_CURVE, OB_SURF)) {
|
|
|
|
Curve *cu = ob->data;
|
|
|
|
if (displist_has_faces(&cu->disp) && boundbox_clip(ob->obmat, cu->bb)) {
|
|
|
|
drawDispListwire(&cu->disp);
|
2004-10-27 09:25:55 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
} else if (ob->type==OB_MBALL) {
|
|
|
|
drawDispListwire(&ob->disp);
|
2004-06-19 17:35:37 +00:00
|
|
|
}
|
2005-07-12 15:47:53 +00:00
|
|
|
else if(ob->type==OB_ARMATURE) {
|
|
|
|
if(ob!=G.obpose) {
|
2005-07-14 12:44:33 +00:00
|
|
|
draw_armature(ob, OB_WIRE);
|
2005-07-12 15:47:53 +00:00
|
|
|
}
|
|
|
|
}
|
2004-06-19 18:23:22 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
glLineWidth(1.0);
|
|
|
|
glDepthMask(1);
|
2004-06-17 18:31:42 +00:00
|
|
|
}
|
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
static void drawWireExtra(Object *ob)
|
2003-10-21 16:41:28 +00:00
|
|
|
{
|
|
|
|
if(ob!=G.obedit && (ob->flag & SELECT)) {
|
|
|
|
if(ob==OBACT) BIF_ThemeColor(TH_ACTIVE);
|
|
|
|
else BIF_ThemeColor(TH_SELECT);
|
|
|
|
}
|
|
|
|
else BIF_ThemeColor(TH_WIRE);
|
|
|
|
|
2004-09-27 10:12:45 +00:00
|
|
|
bglPolygonOffset(1.0);
|
EditMesh refactory + undo recode
The changelog is very long... it's on the web too:
http://www.blender3d.org/cms/Mesh_editing_rewrite.425.0.html
EditMesh refactor notes (user)
**** New selection modes
When entering Edit Mode for a Mesh, you now have the choice for three selection modes. These are shown as icons in the 3D header (hotkey is being searched for!).
- Vertex Select
Select vertices as usual, fully compatible with how previous version work
- Edge Select
Vertices are not drawn anymore, and selections happen by default on the edges. It is a true edge select, meaning that you can select three out of four edges in a face, without automatic having the 4th edge selected.
- Face Select
Instead of vertices, now selection 'points' are drawn in the face centers. Selected faces also get a colored outline, like for edges. This also is true face select, for each face individual regardless selection status of its vertices or edges.
While holding SHIFT, and press a selection mode, you can also combine the above choices. Now selection becomes mixed, and will behave as expected.
For example; in Edge+Face select mode, selecting the 4 edges of a face will select the face too.
The selection modes and optional drawing modes (like transparant faces, normals, or solid drawing) all work together. All of Blender's mesh editing tools now react to the correct selection mode as well.
Most noticeable it's in:
**** Extrude
Extruding in Edge or Face Select mode allows much more precise control over what's extruded and what should be excluded. Try for example a checker pattern selection, and extrude it.
New is the fixed translation when faces are extruded. This always follows the (averaged) face normal(s) of the old face(s), enabling much easier working in 3D views . A single 'G' (Grab) or 'R' (Rotate) or 'S' (Scale) will change transform modus as usual.
**** Other things to note
- Hiding edges/faces will also behave different based on Select Mode.
- while editing, normals of faces are updated always now
- Border select (BKEY) has 2 different rules for edges; when one edge is fully inside of the border, it will only select edges that are fully inside. Otherwise it selects each edge intersecting with the border.
- in face mode, adding vertices, edges or a circle is invisible...
- "Add monkey" now works as a normal primitive (rotated and on 3d cursor)
- Mesh undo was fully recoded, hopefully solving issues now with Vertex Keys and Groups
- Going in and out of editmode was fully recoded. Especially on larger models you'll notice substantial speed gain.
**** Todo
Add 'FaceSelect mode' functionality in EditMode, including zbuffered selection, display and editing of UV texture.
EditMesh refactor notes (coder)
**** Usage of flags in general
The "->f" flags are reserved for the editmesh.c and editmesh_lib.c core functions. Actually only selection status is there now.
The "->f1" and "->f2" flags are free to use. They're available in vertex/edge/face structs. Since they're free, check carefully when calling other functions that use these flags... for example extrude() or subdivide() use them.
**** Selection flags
EditVert: eve->f & SELECT
EditEdge: eed->f & SELECT
EditFace: efa->f & SELECT
- Selection is only possible when not-hidden!
- Selection flags are always up-to-date, BUT:
if selection mode >= SELECT_EDGE vertex selection flags can be incorrect
if selection mode == SELECT_FACE vertex/edge selection flags can be incorrect
This because of shared vertices or edges.
- use for selecting vertices:
eve->f &= SELECT
- use for selecting edges always:
void EM_select_edge(eed, 1) // 1 = select, 0 = deselect
- use for selecting faces always:
void EM_select_face(efa, 1) // 1 = select, 0 = deselect
- To set the 'f' flags in all of the data:
void EM_set_flag_all(int flag);
void EM_clear_flag_all(int flag);
- the old faceselectedOR() and faceselectedAND() are still there, but only
to be used for evaluating its vertices
**** Code hints for handling selection
If the selectmode is 'face'; vertex or edge selections need to be flushed upward. Same is true for 'edge' selection mode. This means that you'll have to keep track of all selections while coding... selecting the four vertices in a face doesn't automatically select the face anymore.
However, by using the above calls, at least selections flush downward (to vertex level). You then can call:
void EM_selectmode_flush(void);
Which flushes selections back upward, based on the selectmode setting. This function does the following:
- if selectmode 'vertex': select edges/faces based on its selected vertices
- if selectmode 'edge': select faces based its selected edges
This works fine in nice controlled situations.
However, only changing the vertex selections then still doesn't select a face in face mode! If you really can't avoid only working with vertex selections, you can use this call:
void EM_select_flush(void);
Now selection is flushed upward regardless current selectmode. That can be destructive for special cases however, like checkerboard selected faces. So use this only when you know everything else was deselected (or deselect it). Example: adding primitives.
**** Hide flags
EditVert: eve->h
EditEdge: eed->h
EditFace: efa->h
- all hide flags are always up-to-date
- hidden vertices/edges/faces are always deselected. so when you operate on selection only, there's no need to check for hide flag.
**** Unified undo for editmode
New file: editmode_undo.h
A pretty nice function pointer handler style undo. Just code three functions, and your undo will fly! The c file has a good reference.
Also note that the old undo system has been replaced. It currently uses minimal dependencies on Meshes themselves (no abuse of going in/out editmode), and is restricted nicely to editmode functions.
**** Going in/out editmode
As speedup now all vertices/faces/edges are allocated in three big chunks. In vertices/faces/edges now tags are set to denote such data cannot be freed.
ALso the hashtable (lookup) for edges uses no mallocs at all anymore, but is part of the EditEdge itself.
2004-09-23 20:52:51 +00:00
|
|
|
glDepthMask(0); // disable write in zbuffer, selected edge wires show better
|
2003-10-21 16:41:28 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
|
|
|
|
Curve *cu = ob->data;
|
|
|
|
if (boundbox_clip(ob->obmat, cu->bb)) {
|
|
|
|
if (ob->type==OB_CURVE)
|
|
|
|
draw_index_wire= 0;
|
|
|
|
drawDispListwire(&cu->disp);
|
|
|
|
if (ob->type==OB_CURVE)
|
|
|
|
draw_index_wire= 1;
|
|
|
|
}
|
|
|
|
} else if (ob->type==OB_MBALL) {
|
|
|
|
drawDispListwire(&ob->disp);
|
2004-09-30 14:27:20 +00:00
|
|
|
}
|
2003-10-21 16:41:28 +00:00
|
|
|
|
EditMesh refactory + undo recode
The changelog is very long... it's on the web too:
http://www.blender3d.org/cms/Mesh_editing_rewrite.425.0.html
EditMesh refactor notes (user)
**** New selection modes
When entering Edit Mode for a Mesh, you now have the choice for three selection modes. These are shown as icons in the 3D header (hotkey is being searched for!).
- Vertex Select
Select vertices as usual, fully compatible with how previous version work
- Edge Select
Vertices are not drawn anymore, and selections happen by default on the edges. It is a true edge select, meaning that you can select three out of four edges in a face, without automatic having the 4th edge selected.
- Face Select
Instead of vertices, now selection 'points' are drawn in the face centers. Selected faces also get a colored outline, like for edges. This also is true face select, for each face individual regardless selection status of its vertices or edges.
While holding SHIFT, and press a selection mode, you can also combine the above choices. Now selection becomes mixed, and will behave as expected.
For example; in Edge+Face select mode, selecting the 4 edges of a face will select the face too.
The selection modes and optional drawing modes (like transparant faces, normals, or solid drawing) all work together. All of Blender's mesh editing tools now react to the correct selection mode as well.
Most noticeable it's in:
**** Extrude
Extruding in Edge or Face Select mode allows much more precise control over what's extruded and what should be excluded. Try for example a checker pattern selection, and extrude it.
New is the fixed translation when faces are extruded. This always follows the (averaged) face normal(s) of the old face(s), enabling much easier working in 3D views . A single 'G' (Grab) or 'R' (Rotate) or 'S' (Scale) will change transform modus as usual.
**** Other things to note
- Hiding edges/faces will also behave different based on Select Mode.
- while editing, normals of faces are updated always now
- Border select (BKEY) has 2 different rules for edges; when one edge is fully inside of the border, it will only select edges that are fully inside. Otherwise it selects each edge intersecting with the border.
- in face mode, adding vertices, edges or a circle is invisible...
- "Add monkey" now works as a normal primitive (rotated and on 3d cursor)
- Mesh undo was fully recoded, hopefully solving issues now with Vertex Keys and Groups
- Going in and out of editmode was fully recoded. Especially on larger models you'll notice substantial speed gain.
**** Todo
Add 'FaceSelect mode' functionality in EditMode, including zbuffered selection, display and editing of UV texture.
EditMesh refactor notes (coder)
**** Usage of flags in general
The "->f" flags are reserved for the editmesh.c and editmesh_lib.c core functions. Actually only selection status is there now.
The "->f1" and "->f2" flags are free to use. They're available in vertex/edge/face structs. Since they're free, check carefully when calling other functions that use these flags... for example extrude() or subdivide() use them.
**** Selection flags
EditVert: eve->f & SELECT
EditEdge: eed->f & SELECT
EditFace: efa->f & SELECT
- Selection is only possible when not-hidden!
- Selection flags are always up-to-date, BUT:
if selection mode >= SELECT_EDGE vertex selection flags can be incorrect
if selection mode == SELECT_FACE vertex/edge selection flags can be incorrect
This because of shared vertices or edges.
- use for selecting vertices:
eve->f &= SELECT
- use for selecting edges always:
void EM_select_edge(eed, 1) // 1 = select, 0 = deselect
- use for selecting faces always:
void EM_select_face(efa, 1) // 1 = select, 0 = deselect
- To set the 'f' flags in all of the data:
void EM_set_flag_all(int flag);
void EM_clear_flag_all(int flag);
- the old faceselectedOR() and faceselectedAND() are still there, but only
to be used for evaluating its vertices
**** Code hints for handling selection
If the selectmode is 'face'; vertex or edge selections need to be flushed upward. Same is true for 'edge' selection mode. This means that you'll have to keep track of all selections while coding... selecting the four vertices in a face doesn't automatically select the face anymore.
However, by using the above calls, at least selections flush downward (to vertex level). You then can call:
void EM_selectmode_flush(void);
Which flushes selections back upward, based on the selectmode setting. This function does the following:
- if selectmode 'vertex': select edges/faces based on its selected vertices
- if selectmode 'edge': select faces based its selected edges
This works fine in nice controlled situations.
However, only changing the vertex selections then still doesn't select a face in face mode! If you really can't avoid only working with vertex selections, you can use this call:
void EM_select_flush(void);
Now selection is flushed upward regardless current selectmode. That can be destructive for special cases however, like checkerboard selected faces. So use this only when you know everything else was deselected (or deselect it). Example: adding primitives.
**** Hide flags
EditVert: eve->h
EditEdge: eed->h
EditFace: efa->h
- all hide flags are always up-to-date
- hidden vertices/edges/faces are always deselected. so when you operate on selection only, there's no need to check for hide flag.
**** Unified undo for editmode
New file: editmode_undo.h
A pretty nice function pointer handler style undo. Just code three functions, and your undo will fly! The c file has a good reference.
Also note that the old undo system has been replaced. It currently uses minimal dependencies on Meshes themselves (no abuse of going in/out editmode), and is restricted nicely to editmode functions.
**** Going in/out editmode
As speedup now all vertices/faces/edges are allocated in three big chunks. In vertices/faces/edges now tags are set to denote such data cannot be freed.
ALso the hashtable (lookup) for edges uses no mallocs at all anymore, but is part of the EditEdge itself.
2004-09-23 20:52:51 +00:00
|
|
|
glDepthMask(1);
|
2004-09-27 10:12:45 +00:00
|
|
|
bglPolygonOffset(0.0);
|
2003-10-21 16:41:28 +00:00
|
|
|
}
|
|
|
|
|
2004-09-14 19:03:11 +00:00
|
|
|
/* should be called in view space */
|
|
|
|
static void draw_hooks(Object *ob)
|
|
|
|
{
|
|
|
|
ObHook *hook;
|
|
|
|
float vec[3];
|
|
|
|
|
|
|
|
for(hook= ob->hooks.first; hook; hook= hook->next) {
|
|
|
|
|
|
|
|
VecMat4MulVecfl(vec, ob->obmat, hook->cent);
|
|
|
|
if(hook->parent) {
|
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(hook->parent->obmat[3]);
|
|
|
|
glVertex3fv(vec);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
glPointSize(3.0);
|
|
|
|
bglBegin(GL_POINTS);
|
|
|
|
bglVertex3fv(vec);
|
|
|
|
bglEnd();
|
|
|
|
glPointSize(1.0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
void draw_object(Base *base)
|
|
|
|
{
|
|
|
|
Object *ob;
|
|
|
|
Curve *cu;
|
|
|
|
ListBase elems;
|
|
|
|
CfraElem *ce;
|
|
|
|
float cfraont, axsize=1.0;
|
|
|
|
unsigned int *rect, col=0;
|
|
|
|
static int warning_recursive= 0;
|
|
|
|
int sel, drawtype, colindex= 0, ipoflag;
|
|
|
|
short dt, dtx, zbufoff= 0;
|
2005-06-17 21:04:27 +00:00
|
|
|
float vec1[3], vec2[3];
|
|
|
|
int i, selstart, selend;
|
|
|
|
SelBox *sb;
|
|
|
|
float selboxw;
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
ob= base->object;
|
|
|
|
|
2005-07-14 12:44:33 +00:00
|
|
|
/* xray delay? */
|
|
|
|
if(!(G.f & G_PICKSEL)) {
|
2005-07-14 15:49:31 +00:00
|
|
|
if(!G.vd->xray && !G.vd->transp && (ob->dtx & OB_DRAWXRAY)) {
|
2005-07-14 12:44:33 +00:00
|
|
|
add_view3d_after(G.vd, base, V3D_XRAY);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* draw keys? */
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(base==(G.scene->basact) || (base->flag & (SELECT+BA_WAS_SEL))) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(warning_recursive==0 && ob!=G.obedit) {
|
|
|
|
if(ob->ipo && ob->ipo->showkey && (ob->ipoflag & OB_DRAWKEY)) {
|
|
|
|
float temp[7][3];
|
|
|
|
|
|
|
|
warning_recursive= 1;
|
|
|
|
|
|
|
|
elems.first= elems.last= 0;
|
|
|
|
make_cfra_list(ob->ipo, &elems);
|
|
|
|
|
|
|
|
cfraont= (G.scene->r.cfra);
|
|
|
|
drawtype= G.vd->drawtype;
|
|
|
|
if(drawtype>OB_WIRE) G.vd->drawtype= OB_WIRE;
|
|
|
|
sel= base->flag;
|
|
|
|
memcpy(temp, &ob->loc, 7*3*sizeof(float));
|
|
|
|
|
|
|
|
ipoflag= ob->ipoflag;
|
|
|
|
ob->ipoflag &= ~OB_OFFS_OB;
|
|
|
|
|
|
|
|
set_no_parent_ipo(1);
|
|
|
|
disable_speed_curve(1);
|
|
|
|
|
|
|
|
if ((ob->ipoflag & OB_DRAWKEYSEL)==0) {
|
|
|
|
ce= elems.first;
|
|
|
|
while(ce) {
|
|
|
|
if(!ce->sel) {
|
|
|
|
(G.scene->r.cfra)= ce->cfra/G.scene->r.framelen;
|
|
|
|
|
|
|
|
base->flag= 0;
|
|
|
|
|
|
|
|
where_is_object_time(ob, (G.scene->r.cfra));
|
|
|
|
draw_object(base);
|
|
|
|
}
|
|
|
|
ce= ce->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ce= elems.first;
|
|
|
|
while(ce) {
|
|
|
|
if(ce->sel) {
|
|
|
|
(G.scene->r.cfra)= ce->cfra/G.scene->r.framelen;
|
|
|
|
|
|
|
|
base->flag= SELECT;
|
|
|
|
|
|
|
|
where_is_object_time(ob, (G.scene->r.cfra));
|
|
|
|
draw_object(base);
|
|
|
|
}
|
|
|
|
ce= ce->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_no_parent_ipo(0);
|
|
|
|
disable_speed_curve(0);
|
|
|
|
|
|
|
|
base->flag= sel;
|
|
|
|
ob->ipoflag= ipoflag;
|
|
|
|
|
|
|
|
/* restore icu->curval */
|
|
|
|
(G.scene->r.cfra)= cfraont;
|
|
|
|
|
|
|
|
memcpy(&ob->loc, temp, 7*3*sizeof(float));
|
|
|
|
where_is_object(ob);
|
|
|
|
G.vd->drawtype= drawtype;
|
|
|
|
|
|
|
|
BLI_freelistN(&elems);
|
|
|
|
|
|
|
|
warning_recursive= 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* patch? children objects with a timeoffs change the parents. How to solve! */
|
2002-10-12 11:37:38 +00:00
|
|
|
/* if( ((int)ob->ctime) != F_(G.scene->r.cfra)) where_is_object(ob); */
|
|
|
|
|
|
|
|
mymultmatrix(ob->obmat);
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* which wire color */
|
2004-09-27 10:12:45 +00:00
|
|
|
if((G.f & G_PICKSEL) == 0) {
|
2002-10-12 11:37:38 +00:00
|
|
|
project_short(ob->obmat[3], &base->sx);
|
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if((G.moving & G_TRANSFORM_OBJ) && (base->flag & (SELECT+BA_WAS_SEL))) BIF_ThemeColor(TH_TRANSFORM);
|
2002-10-12 11:37:38 +00:00
|
|
|
else {
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
|
2003-10-19 09:19:58 +00:00
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2002-10-12 11:37:38 +00:00
|
|
|
if((G.scene->basact)==base) {
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_ACTIVE);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
else {
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(base->flag & (SELECT+BA_WAS_SEL)) BIF_ThemeColor(TH_SELECT);
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// no theme yet
|
|
|
|
if(ob->id.lib) {
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 4;
|
2003-10-25 22:29:24 +00:00
|
|
|
else colindex = 3;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
else if(warning_recursive==1) {
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(base->flag & (SELECT+BA_WAS_SEL)) colindex = 7;
|
2003-10-25 22:29:24 +00:00
|
|
|
else colindex = 6;
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
- The basic layer for Themes in place!
- currently only implemented for 3d window
- create as many themes you like, and name them
- default theme is not editable, and always will be defined at startup
(initTheme)
- saves in .B.blend
- themes for spaces can become local too, so you can set individual
3d windows at theme 'Maya' or so. (to be implemented)
- it uses alpha as well...!
API:
This doesnt use the old method with BFCOLORID blahblah. The API is copied
from OpenGL conventions (naming) as much as possible:
- void BIF_ThemeColor(ScrArea *sa, int colorid)
sets a color... id's are in BIF_resources.h (TH_GRID, TH_WIRE, etc)
- void BIF_ThemeColorShade(ScrArea *sa, int colorid, int offset)
sets a color with offset, no more weird COLORSHADE_LGREY stuff
- void BIF_GetThemeColor3fv(ScrArea *sa, int colorid, float *col)
like opengl, this gives you in *col the three rgb values
- void BIF_GetThemeColor4ubv(ScrArea *sa, int colorid, char *col)
or the one to get 4 bytes
ThemeColor calls for globals (UI etc) can also call NULL for *sa... this
is to be implemented still.
Next step: cleaning up interface.c for all weird colorcalls.
2003-10-17 14:02:08 +00:00
|
|
|
if(colindex) {
|
|
|
|
col= colortab[colindex];
|
|
|
|
cpack(col);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* maximum drawtype */
|
|
|
|
dt= MIN2(G.vd->drawtype, ob->dt);
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf==0 && dt>OB_WIRE) dt= OB_WIRE;
|
2002-10-12 11:37:38 +00:00
|
|
|
dtx= 0;
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* faceselect exception: also draw solid when dt==wire, except in editmode */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(ob==((G.scene->basact) ? (G.scene->basact->object) : 0) && (G.f & (G_FACESELECT+G_VERTEXPAINT+G_TEXTUREPAINT+G_WEIGHTPAINT))) {
|
|
|
|
if(ob->type==OB_MESH) {
|
|
|
|
|
2004-09-27 20:19:16 +00:00
|
|
|
if(ob==G.obedit);
|
2002-10-12 11:37:38 +00:00
|
|
|
else {
|
2004-09-27 10:12:45 +00:00
|
|
|
dt= OB_SHADED;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
zbufoff= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(dt<OB_SOLID) {
|
|
|
|
dt= OB_SOLID;
|
|
|
|
glClearDepth(1.); glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
zbufoff= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2003-11-17 21:10:18 +00:00
|
|
|
if(dt>=OB_WIRE ) {
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
dtx= ob->dtx;
|
|
|
|
if(G.obedit==ob) {
|
2003-10-21 21:59:00 +00:00
|
|
|
// the only 2 extra drawtypes alowed in editmode
|
|
|
|
dtx= dtx & (OB_DRAWWIRE|OB_TEXSPACE);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(G.f & G_DRAW_EXT) {
|
|
|
|
if(ob->type==OB_EMPTY || ob->type==OB_CAMERA || ob->type==OB_LAMP) dt= OB_WIRE;
|
|
|
|
}
|
|
|
|
}
|
2004-09-14 19:03:11 +00:00
|
|
|
|
2005-03-26 17:29:37 +00:00
|
|
|
/* draw outline for selected solid objects, mesh does itself */
|
|
|
|
if((G.vd->flag & V3D_SELECT_OUTLINE) && ob->type!=OB_MESH) {
|
2004-09-27 10:12:45 +00:00
|
|
|
if(dt>OB_WIRE && dt<OB_TEXTURE && ob!=G.obedit) {
|
2005-07-14 12:44:33 +00:00
|
|
|
if (!(ob->dtx&OB_DRAWWIRE) && (ob->flag&SELECT) && !(G.f&G_PICKSEL)) {
|
2005-03-26 17:29:37 +00:00
|
|
|
drawSolidSelect(ob);
|
|
|
|
}
|
2004-07-28 13:21:27 +00:00
|
|
|
}
|
2004-07-06 16:32:44 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2004-06-19 09:35:23 +00:00
|
|
|
switch( ob->type) {
|
|
|
|
case OB_MESH:
|
2005-03-26 17:29:37 +00:00
|
|
|
if (!(base->flag&OB_RADIO)) {
|
2005-07-14 12:44:33 +00:00
|
|
|
draw_mesh_object(base, dt);
|
2005-03-26 17:29:37 +00:00
|
|
|
dtx &= ~OB_DRAWWIRE; // mesh draws wire itself
|
|
|
|
|
Result of 2 weeks of quiet coding work in Greece :)
Aim was to get a total refresh of the animation system. This
is needed because;
- we need to upgrade it with 21st century features
- current code is spaghetti/hack combo, and hides good design
- it should become lag-free with using dependency graphs
A full log, with complete code API/structure/design explanation
will follow, that's a load of work... so here below the list with
hot changes;
- The entire object update system (matrices, geometry) is now
centralized. Calls to where_is_object and makeDispList are
forbidden, instead we tag objects 'changed' and let the
depgraph code sort it out
- Removed all old "Ika" code
- Depgraph is aware of all relationships, including meta balls,
constraints, bevelcurve, and so on.
- Made depgraph aware of relation types and layers, to do smart
flushing of 'changed' events. Nothing gets calculated too often!
- Transform uses depgraph to detect changes
- On frame-advance, depgraph flushes animated changes
Armatures;
Almost all armature related code has been fully built from scratch.
It now reveils the original design much better, with a very clean
implementation, lag free without even calculating each Bone more than
once. Result is quite a speedup yes!
Important to note is;
1) Armature is data containing the 'rest position'
2) Pose is the changes of rest position, and always on object level.
That way more Objects can use same Pose. Also constraints are in Pose
3) Actions only contain the Ipos to change values in Poses.
- Bones draw unrotated now
- Drawing bones speedup enormously (10-20 times)
- Bone selecting in EditMode, selection state is saved for PoseMode,
and vice-versa
- Undo in editmode
- Bone renaming does vertexgroups, constraints, posechannels, actions,
for all users of Armature in entire file
- Added Bone renaming in NKey panel
- Nkey PoseMode shows eulers now
- EditMode and PoseMode now have 'active' bone too (last clicked)
- Parenting in EditMode' CTRL+P, ALT+P, with nice options!
- Pose is added in Outliner now, with showing that constraints are in
the Pose, not Armature
- Disconnected IK solving from constraints. It's a separate phase now,
on top of the full Pose calculations
- Pose itself has a dependency graph too, so evaluation order is lag free.
TODO NOW;
- Rotating in Posemode has incorrect inverse transform (Martin will fix)
- Python Bone/Armature/Pose API disabled... needs full recode too
(wait for my doc!)
- Game engine will need upgrade too
- Depgraph code needs revision, cleanup, can be much faster!
(But, compliments for Jean-Luc, it works like a charm!)
- IK changed, it now doesnt use previous position to advance to next
position anymore. That system looks nice (no flips) but is not well
suited for NLA and background render.
TODO LATER;
We now can do loadsa new nifty features as well; like:
- Kill PoseMode (can be option for armatures itself)
- Make B-Bones (Bezier, Bspline, like for spines)
- Move all silly button level edit to 3d window (like CTRL+I = add
IK)
- Much better & informative drawing
- Fix action/nla editors
- Put all ipos in Actions (object, mesh key, lamp color)
- Add hooks
- Null bones
- Much more advanced constraints...
Bugfixes;
- OGL render (view3d header) had wrong first frame on anim render
- Ipo 'recording' mode had wrong playback speed
- Vertex-key mode now sticks to show 'active key', until frame change
-Ton-
2005-07-03 17:35:38 +00:00
|
|
|
if(G.obedit!=ob && warning_recursive==0) {
|
2005-03-26 17:29:37 +00:00
|
|
|
PartEff *paf = give_parteff(ob);
|
|
|
|
|
|
|
|
if(paf) {
|
|
|
|
if(col) cpack(0xFFFFFF); /* for visibility */
|
|
|
|
if(paf->flag & PAF_STATIC) draw_static_particle_system(ob, paf);
|
|
|
|
else if((G.f & G_PICKSEL) == 0) draw_particle_system(ob, paf); // selection errors happen to easy
|
|
|
|
if(col) cpack(col);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
2004-06-19 09:35:23 +00:00
|
|
|
}
|
2005-03-26 17:29:37 +00:00
|
|
|
|
2004-06-19 09:35:23 +00:00
|
|
|
break;
|
|
|
|
case OB_FONT:
|
|
|
|
cu= ob->data;
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
tekentextcurs();
|
2005-06-17 21:04:27 +00:00
|
|
|
|
|
|
|
if (cu->flag & CU_FAST) {
|
|
|
|
cpack(0xFFFFFF);
|
|
|
|
set_inverted_drawing(1);
|
|
|
|
drawDispList(ob, OB_WIRE);
|
|
|
|
set_inverted_drawing(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cu->linewidth != 0.0) {
|
|
|
|
BIF_ThemeColor(TH_WIRE);
|
|
|
|
VECCOPY(vec1, ob->orig);
|
|
|
|
VECCOPY(vec2, ob->orig);
|
|
|
|
vec1[0] += cu->linewidth;
|
|
|
|
vec2[0] += cu->linewidth;
|
|
|
|
vec1[1] += cu->linedist * cu->fsize;
|
|
|
|
vec2[1] -= cu->lines * cu->linedist * cu->fsize;
|
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
glVertex2fv(vec1);
|
|
|
|
glVertex2fv(vec2);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
setlinestyle(3);
|
|
|
|
for (i=0; i<cu->totbox; i++) {
|
|
|
|
if (cu->tb[i].w != 0.0) {
|
|
|
|
if (i == (cu->actbox-1))
|
|
|
|
BIF_ThemeColor(TH_ACTIVE);
|
|
|
|
else
|
|
|
|
BIF_ThemeColor(TH_WIRE);
|
2005-06-17 23:30:39 +00:00
|
|
|
vec1[0] = cu->tb[i].x;
|
|
|
|
vec1[1] = cu->tb[i].y + cu->linedist*cu->fsize;
|
|
|
|
vec1[2] = 0.001;
|
2005-06-17 21:04:27 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
2005-06-17 23:30:39 +00:00
|
|
|
glVertex3fv(vec1);
|
2005-06-17 21:04:27 +00:00
|
|
|
vec1[0] += cu->tb[i].w;
|
2005-06-17 23:30:39 +00:00
|
|
|
glVertex3fv(vec1);
|
2005-06-17 21:04:27 +00:00
|
|
|
vec1[1] -= (cu->tb[i].h + cu->linedist*cu->fsize);
|
2005-06-17 23:30:39 +00:00
|
|
|
glVertex3fv(vec1);
|
2005-06-17 21:04:27 +00:00
|
|
|
vec1[0] -= cu->tb[i].w;
|
2005-06-17 23:30:39 +00:00
|
|
|
glVertex3fv(vec1);
|
2005-06-17 21:04:27 +00:00
|
|
|
vec1[1] += cu->tb[i].h + cu->linedist*cu->fsize;
|
2005-06-17 23:30:39 +00:00
|
|
|
glVertex3fv(vec1);
|
2005-06-17 21:04:27 +00:00
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
setlinestyle(0);
|
|
|
|
|
|
|
|
|
|
|
|
if (getselection(&selstart, &selend) && selboxes) {
|
|
|
|
cpack(0xffffff);
|
|
|
|
set_inverted_drawing(1);
|
|
|
|
for (i=0; i<(selend-selstart+1); i++) {
|
|
|
|
sb = &(selboxes[i]);
|
|
|
|
if (i<(selend-selstart)) {
|
|
|
|
if (selboxes[i+1].y == sb->y)
|
|
|
|
selboxw= selboxes[i+1].x - sb->x;
|
|
|
|
else
|
|
|
|
selboxw= sb->w;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
selboxw= sb->w;
|
|
|
|
}
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
glVertex3f(sb->x, sb->y, 0.001);
|
|
|
|
glVertex3f(sb->x+selboxw, sb->y, 0.001);
|
|
|
|
glVertex3f(sb->x+selboxw, sb->y+sb->h, 0.001);
|
|
|
|
glVertex3f(sb->x, sb->y+sb->h, 0.001);
|
|
|
|
glEnd();
|
|
|
|
}
|
|
|
|
set_inverted_drawing(0);
|
|
|
|
}
|
2004-06-19 09:35:23 +00:00
|
|
|
}
|
|
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
|
|
else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-06-19 09:35:23 +00:00
|
|
|
break;
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
|
|
|
cu= ob->data;
|
|
|
|
|
|
|
|
if(ob==G.obedit) {
|
|
|
|
drawnurb(ob, editNurb.first, dt);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-06-19 09:35:23 +00:00
|
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
|
|
else if(boundbox_clip(ob->obmat, cu->bb)) drawDispList(ob, dt);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case OB_MBALL:
|
|
|
|
if(ob==G.obedit) drawmball(ob, dt);
|
|
|
|
else if(dt==OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
|
|
else drawmball(ob, dt);
|
|
|
|
break;
|
|
|
|
case OB_EMPTY:
|
|
|
|
drawaxes(1.0);
|
|
|
|
break;
|
|
|
|
case OB_LAMP:
|
|
|
|
drawlamp(ob);
|
|
|
|
break;
|
|
|
|
case OB_CAMERA:
|
|
|
|
drawcamera(ob);
|
|
|
|
break;
|
|
|
|
case OB_LATTICE:
|
|
|
|
drawlattice(ob);
|
|
|
|
break;
|
|
|
|
case OB_ARMATURE:
|
2005-07-16 19:07:02 +00:00
|
|
|
if(dt>OB_WIRE) set_gl_material(0); // we use defmaterial
|
2005-07-14 12:44:33 +00:00
|
|
|
draw_armature(ob, dt);
|
2004-06-19 09:35:23 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
drawaxes(1.0);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-07-18 22:23:50 +00:00
|
|
|
if(ob->pd && ob->pd->forcefield) draw_forcefield(ob);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2004-06-19 09:35:23 +00:00
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* draw extra: after normal draw because of makeDispList */
|
2002-10-12 11:37:38 +00:00
|
|
|
if(dtx) {
|
|
|
|
if(G.f & G_SIMULATION);
|
|
|
|
else if(dtx & OB_AXIS) {
|
|
|
|
drawaxes(axsize);
|
|
|
|
}
|
|
|
|
if(dtx & OB_BOUNDBOX) draw_bounding_volume(ob);
|
|
|
|
if(dtx & OB_TEXSPACE) drawtexspace(ob);
|
|
|
|
if(dtx & OB_DRAWNAME) {
|
2004-05-10 20:14:21 +00:00
|
|
|
// patch for several 3d cards (IBM mostly) that crash on glSelect with text drawing
|
|
|
|
if((G.f & G_PICKSEL) == 0) {
|
|
|
|
glRasterPos3f(0.0, 0.0, 0.0);
|
|
|
|
|
|
|
|
BMF_DrawString(G.font, " ");
|
|
|
|
BMF_DrawString(G.font, ob->id.name+2);
|
|
|
|
}
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
if(dtx & OB_DRAWIMAGE) drawDispListwire(&ob->disp);
|
2005-03-26 17:29:37 +00:00
|
|
|
if((dtx & OB_DRAWWIRE) && dt>=OB_SOLID) drawWireExtra(ob);
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-09-14 19:03:11 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
if(dt<OB_SHADED) {
|
|
|
|
if((ob->gameflag & OB_ACTOR) && (ob->gameflag & OB_DYNAMIC)) {
|
|
|
|
float tmat[4][4], imat[4][4], vec[3];
|
|
|
|
|
|
|
|
vec[0]= vec[1]= vec[2]= 0.0;
|
|
|
|
mygetmatrix(tmat);
|
|
|
|
Mat4Invert(imat, tmat);
|
|
|
|
|
|
|
|
setlinestyle(2);
|
2005-04-20 08:26:22 +00:00
|
|
|
drawcircball(GL_LINE_LOOP, vec, ob->inertia, imat);
|
2002-10-12 11:37:38 +00:00
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
|
|
|
|
if(zbufoff) glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
if(warning_recursive) return;
|
|
|
|
if(base->flag & OB_FROMDUPLI) return;
|
|
|
|
if(base->flag & OB_RADIO) return;
|
|
|
|
if(G.f & G_SIMULATION) return;
|
|
|
|
|
2004-09-27 10:12:45 +00:00
|
|
|
if((G.f & (G_PICKSEL))==0) {
|
2003-11-11 16:56:51 +00:00
|
|
|
ListBase *list;
|
|
|
|
|
2004-09-14 19:03:11 +00:00
|
|
|
/* draw hook center and offset line */
|
|
|
|
if(ob->hooks.first && ob!=G.obedit) draw_hooks(ob);
|
|
|
|
|
2003-04-28 14:43:20 +00:00
|
|
|
/* help lines and so */
|
Version 1.0 of the new Outliner
The outliner is a hierarchical diagram displaying a list of data in Blender
and its dependencies. The 'databrowse' doesn't really show it, and Oops is
too chaotic still. And most of all, the former two don't offer much tools.
After discussions on irc, Matt came with this design proposal;
http://mke3.net/blender/interface/layout/outliner/
Which is closely followed for the implementation.
The current version only shows all 'library data' in Blender (objects,
meshes, ipos, etc) and not the 'direct data' such as vertex groups or NLA.
I decided to make it inside the Oopw window, as an option. You can find the
option in the "View" pulldown, or directly invoke it with ALT+SHIFT+F9
Here's a quick overview of the Outliner GUI:
- Header pulldown has options what it can show (Visible = in current layers)
- click on triangle arrow to open/close
- press AKEY to open/close all
- Leftmouse click on an item activates; and does based on type a couple of
extra things:
- activates a scene
- selects/activates the Object
- enters editmode (if clicked on Mesh, Curve, etc)
- shows the appropriate Shading buttons (Lamp, Material, Texture)
- sets the IpoWindow to the current IPO
- activates the Ipo-channel in an Action
- Selected and Active objects are drawn in its Theme selection color
- SHIFT+click on Object does extend-select
- Press DOTkey to get the current active data in center of view
TODO;
- rightmouse selection; for indicating operations like delete or duplicate
- showing more data types
- icon (re)design...
- lotsof options as described in Matts paper still...
2004-10-06 18:55:00 +00:00
|
|
|
if(ob!=G.obedit && ob->parent && (ob->parent->lay & G.vd->lay)) {
|
2002-10-12 11:37:38 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(ob->obmat[3]);
|
|
|
|
glVertex3fv(ob->orig);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
|
2003-11-11 16:56:51 +00:00
|
|
|
/* Drawing the constraint lines */
|
|
|
|
list = &ob->constraints;
|
|
|
|
if (list){
|
2005-03-09 19:45:59 +00:00
|
|
|
/*
|
2003-11-19 22:13:53 +00:00
|
|
|
extern void make_axis_color(char *col, char *col2, char axis); // drawview.c
|
2005-03-09 19:45:59 +00:00
|
|
|
*/
|
2003-11-11 16:56:51 +00:00
|
|
|
bConstraint *curcon;
|
|
|
|
float size[3], tmat[4][4];
|
2003-11-17 22:33:11 +00:00
|
|
|
char col[4], col2[4];
|
|
|
|
|
|
|
|
BIF_GetThemeColor3ubv(TH_GRID, col);
|
|
|
|
make_axis_color(col, col2, 'z');
|
|
|
|
glColor3ubv(col2);
|
|
|
|
|
2003-11-11 16:56:51 +00:00
|
|
|
for (curcon = list->first; curcon; curcon=curcon->next){
|
2003-11-23 20:28:35 +00:00
|
|
|
if ((curcon->flag & CONSTRAINT_EXPAND)&&(curcon->type!=CONSTRAINT_TYPE_NULL)&&(constraint_has_target(curcon))){
|
2004-08-16 01:14:18 +00:00
|
|
|
get_constraint_target_matrix(curcon, TARGET_OBJECT, NULL, tmat, size, bsystem_time(ob, 0, (float)(G.scene->r.cfra), ob->sf));
|
2003-11-11 16:56:51 +00:00
|
|
|
setlinestyle(3);
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
glVertex3fv(tmat[3]);
|
|
|
|
glVertex3fv(ob->obmat[3]);
|
|
|
|
glEnd();
|
|
|
|
setlinestyle(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
/* object centers */
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glDisable(GL_DEPTH_TEST);
|
2004-10-31 21:11:03 +00:00
|
|
|
if(ob->type == OB_LAMP) {
|
2002-10-12 11:37:38 +00:00
|
|
|
if(ob->id.lib) {
|
|
|
|
if(base->flag & SELECT) rect= rectllib_sel;
|
|
|
|
else rect= rectllib_desel;
|
|
|
|
}
|
|
|
|
else if(ob->id.us>1) {
|
|
|
|
if(base->flag & SELECT) rect= rectlus_sel;
|
|
|
|
else rect= rectlus_desel;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(base->flag & SELECT) rect= rectl_sel;
|
|
|
|
else rect= rectl_desel;
|
|
|
|
}
|
|
|
|
draw_icon_centered(ob->obmat[3], rect, 9);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(ob->id.lib || ob->id.us>1) {
|
|
|
|
if(base->flag & SELECT) rect= rectu_sel;
|
|
|
|
else rect= rectu_desel;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if(base->flag & SELECT) rect= rect_sel;
|
2003-02-16 00:12:06 +00:00
|
|
|
/* The center of the active object (which need not
|
|
|
|
* be selected) gets drawn as if it were selected
|
|
|
|
*/
|
2002-10-12 11:37:38 +00:00
|
|
|
else if(base==(G.scene->basact)) rect= rect_sel;
|
|
|
|
else rect= rect_desel;
|
|
|
|
}
|
|
|
|
draw_icon_centered(ob->obmat[3], rect, 4);
|
|
|
|
}
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) glEnable(GL_DEPTH_TEST);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else if((G.f & (G_VERTEXPAINT|G_FACESELECT|G_TEXTUREPAINT|G_WEIGHTPAINT))==0) {
|
|
|
|
|
|
|
|
glBegin(GL_POINTS);
|
|
|
|
glVertex3fv(ob->obmat[3]);
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
}
|
3D view orbit option: Around Active
This fixes the active object in place when orbiting the view.
Choppy 15fps demo can be seen there: http://www.elysiun.com/~theeth/bf/around_active.html
Image Memory Grabage Collection
This adds memory handling to the image code. An image is tagged each time it is used.
During a collection cycle (frequency of cycles is user defined), if an image is older
than a user defined limit, its buffer gets deallocated. This also applies to gl memory buffers.
Images that are loading in GL memory needs to go through two time outs before being fully deallocated: the first time out deallocated the gl memorry, the second the buffer in ram.
Notes:
Image buffer loaded from python gets tagged as permanent upon load. That tag is removed when python stops using the image.
I might have missed some tagging spots, especially in the rendering pipeline. Someone with more knowledge about this code should check to be careful.
Tagging is done on every access, for rendering, this will probably be a performance hit. A scheme should be developped to only tag when the rendering is completed.
Collecting is called in draw_object, most likely not the best place to do it.
Safe from undo, since using undo deallocates memory anyway (like when loading a blend file with one currently opened)
Userpref DNA changes:
I've changed a couple of flagging variables from short to int. Some because they needed more space, others to keep SDNA happy.
Info window changes:
I've grouped a couple of buttons in aligned blocks and changed the color of mutually exclusive options to make them clearer.
Matt didn't do any changes on that in tuhopuu, so hopefully I'm not stepping on anyone's feet with this.
Also changed double constants into floats with f in a couple of places (mostly space.c) to make compiler happier.
2005-07-06 00:33:41 +00:00
|
|
|
|
|
|
|
free_old_images();
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void draw_object_ext(Base *base)
|
|
|
|
{
|
|
|
|
|
2003-07-11 20:02:52 +00:00
|
|
|
if(G.vd==NULL || base==NULL) return;
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
if(G.vd->drawtype > OB_WIRE) {
|
2005-07-13 19:42:08 +00:00
|
|
|
G.vd->zbuf= 1;
|
2002-10-12 11:37:38 +00:00
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
}
|
|
|
|
|
|
|
|
G.f |= G_DRAW_EXT;
|
2003-07-21 17:46:55 +00:00
|
|
|
|
2002-10-12 11:37:38 +00:00
|
|
|
glDrawBuffer(GL_FRONT);
|
2003-11-08 17:51:32 +00:00
|
|
|
persp(PERSP_VIEW);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
2003-11-08 17:51:32 +00:00
|
|
|
draw_object(base);
|
2002-10-12 11:37:38 +00:00
|
|
|
|
|
|
|
G.f &= ~G_DRAW_EXT;
|
|
|
|
|
2004-06-16 11:34:45 +00:00
|
|
|
glFlush(); /* reveil frontbuffer drawing */
|
2002-10-12 11:37:38 +00:00
|
|
|
glDrawBuffer(GL_BACK);
|
|
|
|
|
2005-07-13 19:42:08 +00:00
|
|
|
if(G.vd->zbuf) {
|
|
|
|
G.vd->zbuf= 0;
|
2002-10-12 11:37:38 +00:00
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
}
|
2003-11-10 15:28:48 +00:00
|
|
|
curarea->win_swap= WIN_FRONT_OK;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
2004-09-27 10:12:45 +00:00
|
|
|
|
|
|
|
/* ***************** BACKBUF SEL (BBS) ********* */
|
|
|
|
|
2005-03-31 15:57:18 +00:00
|
|
|
static int bbs_mesh_verts__setDrawOptions(void *userData, EditVert *eve)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
if (eve->h==0) {
|
|
|
|
set_framebuffer_index_color((int) eve->prev);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2005-03-28 06:46:21 +00:00
|
|
|
static int bbs_mesh_verts(DerivedMesh *dm, int offset)
|
2004-09-27 10:12:45 +00:00
|
|
|
{
|
2005-03-30 00:32:10 +00:00
|
|
|
EditVert *eve, *preveve;
|
|
|
|
|
|
|
|
for (eve=G.editMesh->verts.first; eve; eve= eve->next)
|
|
|
|
eve->prev = (EditVert*) offset++;
|
|
|
|
|
2004-09-28 11:19:57 +00:00
|
|
|
glPointSize( BIF_GetThemeValuef(TH_VERTEX_SIZE) );
|
2005-03-30 00:32:10 +00:00
|
|
|
dm->drawMappedVertsEM(dm, bbs_mesh_verts__setDrawOptions, NULL);
|
2004-09-28 11:19:57 +00:00
|
|
|
glPointSize(1.0);
|
2005-03-28 06:46:21 +00:00
|
|
|
|
2005-03-30 00:32:10 +00:00
|
|
|
for (preveve=NULL, eve=G.editMesh->verts.first; eve; preveve=eve, eve= eve->next)
|
2005-03-30 10:12:05 +00:00
|
|
|
eve->prev = preveve;
|
2005-03-30 00:32:10 +00:00
|
|
|
|
|
|
|
return offset;
|
2004-09-28 09:43:37 +00:00
|
|
|
}
|
|
|
|
|
2005-03-31 15:57:18 +00:00
|
|
|
static int bbs_mesh_wire__setDrawOptions(void *userData, EditEdge *eed)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
if (eed->h==0) {
|
|
|
|
set_framebuffer_index_color((int) eed->vn);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2005-03-28 06:46:21 +00:00
|
|
|
static int bbs_mesh_wire(DerivedMesh *dm, int offset)
|
2004-09-28 09:43:37 +00:00
|
|
|
{
|
2005-03-30 00:32:10 +00:00
|
|
|
EditEdge *eed;
|
|
|
|
|
|
|
|
for(eed= G.editMesh->edges.first; eed; eed= eed->next)
|
|
|
|
eed->vn= (EditVert*) offset++;
|
|
|
|
|
|
|
|
dm->drawMappedEdgesEM(dm, bbs_mesh_wire__setDrawOptions, NULL);
|
|
|
|
|
|
|
|
return offset;
|
2004-09-28 09:43:37 +00:00
|
|
|
}
|
2005-03-30 00:32:10 +00:00
|
|
|
|
2005-03-31 15:57:18 +00:00
|
|
|
static int bbs_mesh_solid__setDrawOptions(void *userData, EditFace *efa)
|
2005-03-30 00:32:10 +00:00
|
|
|
{
|
|
|
|
if (efa->h==0) {
|
2005-04-02 18:21:50 +00:00
|
|
|
if (userData) {
|
|
|
|
set_framebuffer_index_color((int) efa->prev);
|
|
|
|
}
|
2005-03-30 00:32:10 +00:00
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2004-09-28 09:43:37 +00:00
|
|
|
/* two options, facecolors or black */
|
2005-07-17 17:41:03 +00:00
|
|
|
static int bbs_mesh_solid_EM(DerivedMesh *dm, int facecol)
|
2004-09-28 09:43:37 +00:00
|
|
|
{
|
|
|
|
cpack(0);
|
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if (facecol) {
|
|
|
|
EditFace *efa, *prevefa;
|
|
|
|
int a, b;
|
2005-03-28 06:46:21 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
// tuck original indices in efa->prev
|
|
|
|
for(b=1, efa= G.editMesh->faces.first; efa; efa= efa->next, b++)
|
|
|
|
efa->prev= (EditFace *)(b);
|
|
|
|
a = b;
|
2005-03-28 06:46:21 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
dm->drawMappedFacesEM(dm, bbs_mesh_solid__setDrawOptions, (void*) 1);
|
2005-03-30 00:32:10 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if(G.scene->selectmode & SCE_SELECT_FACE) {
|
|
|
|
glPointSize(BIF_GetThemeValuef(TH_FACEDOT_SIZE));
|
|
|
|
|
|
|
|
bglBegin(GL_POINTS);
|
|
|
|
for(efa= G.editMesh->faces.first; efa; efa= efa->next) {
|
|
|
|
if(efa->h==0 && efa->fgonf!=EM_FGON) {
|
|
|
|
set_framebuffer_index_color((int)efa->prev);
|
|
|
|
bglVertex3fv(efa->cent);
|
2004-12-02 16:01:15 +00:00
|
|
|
}
|
|
|
|
}
|
2005-07-17 17:41:03 +00:00
|
|
|
bglEnd();
|
2004-09-28 09:43:37 +00:00
|
|
|
}
|
2005-07-17 17:41:03 +00:00
|
|
|
|
|
|
|
for (prevefa= NULL, efa= G.editMesh->faces.first; efa; prevefa= efa, efa= efa->next)
|
|
|
|
efa->prev= prevefa;
|
|
|
|
return a;
|
|
|
|
} else {
|
|
|
|
dm->drawMappedFacesEM(dm, bbs_mesh_solid__setDrawOptions, (void*) 0);
|
|
|
|
return 1;
|
2004-09-28 09:43:37 +00:00
|
|
|
}
|
2005-07-17 17:41:03 +00:00
|
|
|
}
|
2004-11-05 12:58:12 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
static void bbs_mesh_solid(Object *ob)
|
|
|
|
{
|
|
|
|
Mesh *me= ob->data;
|
|
|
|
MFace *mface= me->mface;
|
|
|
|
TFace *tface= me->tface;
|
|
|
|
float co[3];
|
|
|
|
int a, glmode, dmNeedsFree;
|
|
|
|
DerivedMesh *dm = mesh_get_derived_deform(ob, &dmNeedsFree);
|
|
|
|
|
|
|
|
cpack(0);
|
2004-10-12 15:15:10 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
glBegin(glmode=GL_QUADS);
|
|
|
|
for(a=0; a<me->totface; a++, mface++, tface++) {
|
|
|
|
if(mface->v3 && (!me->tface || !(tface->flag&TF_HIDE))) {
|
|
|
|
int newmode = mface->v4?GL_QUADS:GL_TRIANGLES;
|
2005-07-17 03:48:29 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
set_framebuffer_index_color(a+1);
|
2005-07-17 03:48:29 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if (newmode!=glmode) {
|
|
|
|
glEnd();
|
|
|
|
glBegin(glmode=newmode);
|
|
|
|
}
|
|
|
|
|
|
|
|
glVertex3fv( (dm->getVertCo(dm, mface->v1, co),co) );
|
|
|
|
glVertex3fv( (dm->getVertCo(dm, mface->v2, co),co) );
|
|
|
|
glVertex3fv( (dm->getVertCo(dm, mface->v3, co),co) );
|
|
|
|
if(mface->v4) glVertex3fv( (dm->getVertCo(dm, mface->v4, co),co) );
|
2005-07-17 03:48:29 +00:00
|
|
|
}
|
2005-07-17 17:41:03 +00:00
|
|
|
}
|
|
|
|
glEnd();
|
2005-07-17 03:48:29 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if (dmNeedsFree) {
|
|
|
|
dm->release(dm);
|
2004-09-27 10:12:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void draw_object_backbufsel(Object *ob)
|
|
|
|
{
|
2005-03-28 06:46:21 +00:00
|
|
|
|
2004-09-27 10:12:45 +00:00
|
|
|
mymultmatrix(ob->obmat);
|
|
|
|
|
|
|
|
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2004-09-28 09:43:37 +00:00
|
|
|
|
2004-09-27 10:12:45 +00:00
|
|
|
switch( ob->type) {
|
|
|
|
case OB_MESH:
|
2005-07-17 17:41:03 +00:00
|
|
|
if(ob==G.obedit) {
|
|
|
|
int dmNeedsFree;
|
2005-07-19 00:21:01 +00:00
|
|
|
DerivedMesh *dm = editmesh_get_derived_cage(&dmNeedsFree);
|
2004-09-28 09:43:37 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
em_solidoffs= bbs_mesh_solid_EM(dm, G.scene->selectmode & SCE_SELECT_FACE);
|
2004-09-28 09:43:37 +00:00
|
|
|
|
|
|
|
bglPolygonOffset(1.0);
|
|
|
|
|
2004-10-10 19:41:43 +00:00
|
|
|
// we draw edges always, for loop (select) tools
|
2005-03-28 06:46:21 +00:00
|
|
|
em_wireoffs= bbs_mesh_wire(dm, em_solidoffs);
|
2004-09-28 09:43:37 +00:00
|
|
|
|
2004-09-28 22:05:16 +00:00
|
|
|
if(G.scene->selectmode & SCE_SELECT_VERTEX)
|
2005-03-28 06:46:21 +00:00
|
|
|
em_vertoffs= bbs_mesh_verts(dm, em_wireoffs);
|
2004-09-28 22:05:16 +00:00
|
|
|
else em_vertoffs= em_wireoffs;
|
|
|
|
|
2004-09-28 09:43:37 +00:00
|
|
|
bglPolygonOffset(0.0);
|
2005-03-28 06:46:21 +00:00
|
|
|
|
2005-07-17 17:41:03 +00:00
|
|
|
if (dmNeedsFree) {
|
|
|
|
dm->release(dm);
|
|
|
|
}
|
2005-03-29 16:43:39 +00:00
|
|
|
}
|
2005-07-17 17:41:03 +00:00
|
|
|
else bbs_mesh_solid(ob);
|
|
|
|
|
2004-09-27 10:12:45 +00:00
|
|
|
break;
|
|
|
|
case OB_CURVE:
|
|
|
|
case OB_SURF:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
myloadmatrix(G.vd->viewmat);
|
|
|
|
|
2004-09-29 22:22:51 +00:00
|
|
|
}
|