[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [36901] branches/soc-2010-jwilkins/source/ blender/editors/sculpt_paint/sculpt.c: Hand merged sculpt.c with trunk.
Jason Wilkins
Jason.A.Wilkins at gmail.com
Thu May 26 04:25:06 CEST 2011
Revision: 36901
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=36901
Author: jwilkins
Date: 2011-05-26 02:25:05 +0000 (Thu, 26 May 2011)
Log Message:
-----------
Hand merged sculpt.c with trunk. Revisions: 31364-36811
Previous commit of paint_stroke.c was actually revisions: 30860-36797
Untested, as before this is a starting point and I'm just saving it so I can continue merging.
Modified Paths:
--------------
branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c
Modified: branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c 2011-05-25 23:29:38 UTC (rev 36900)
+++ branches/soc-2010-jwilkins/source/blender/editors/sculpt_paint/sculpt.c 2011-05-26 02:25:05 UTC (rev 36901)
@@ -30,10 +30,15 @@
*
*/
+/** \file blender/editors/sculpt_paint/sculpt.c
+ * \ingroup edsculpt
+ */
+
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_utildefines.h"
#include "BLI_dynstr.h"
#include "BLI_ghash.h"
#include "BLI_pbvh.h"
@@ -57,23 +62,25 @@
#include "BKE_multires.h"
#include "BKE_paint.h"
#include "BKE_report.h"
+#include "BKE_lattice.h" /* for armature_deform_verts */
+#include "BKE_node.h"
-#include "BIF_gl.h"
#include "BIF_glutil.h"
#include "WM_api.h"
#include "WM_types.h"
+
+#include "ED_sculpt.h"
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "ED_util.h" /* for crazyspace correction */
#include "paint_intern.h"
#include "sculpt_intern.h"
#include "RNA_access.h"
#include "RNA_define.h"
-
#include "RE_render_ext.h"
-#include "RE_shader_ext.h"
#include "GPU_buffers.h"
@@ -85,14 +92,8 @@
#include <omp.h>
#endif
-/* ==== FORWARD DEFINITIONS =====
- *
- */
-
static void calc_sculpt_normal(const Sculpt *sd, const SculptSession *ss, float an[3], PBVHNode **nodes, int totnode, float range);
-
-
void ED_sculpt_force_update(bContext *C)
{
Object *ob= CTX_data_active_object(C);
@@ -101,12 +102,39 @@
multires_force_update(ob);
}
+void ED_sculpt_modifiers_changed(Object *ob)
+{
+ SculptSession *ss= ob->sculpt;
+
+ if(!ss->cache) {
+ /* we free pbvh on changes, except during sculpt since it can't deal with
+ changing PVBH node organization, we hope topology does not change in
+ the meantime .. weak */
+ if(ss->pbvh) {
+ BLI_pbvh_free(ss->pbvh);
+ ss->pbvh= NULL;
+ }
+
+ sculpt_free_deformMats(ob->sculpt);
+ } else {
+ PBVHNode **nodes;
+ int n, totnode;
+
+ BLI_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode);
+
+ for(n = 0; n < totnode; n++)
+ BLI_pbvh_node_mark_update(nodes[n]);
+
+ MEM_freeN(nodes);
+ }
+}
+
/* Sculpt mode handles multires differently from regular meshes, but only if
it's the last modifier on the stack and it is not on the first level */
struct MultiresModifierData *sculpt_multires_active(Scene *scene, Object *ob)
{
Mesh *me= (Mesh*)ob->data;
- ModifierData *md, *nmd;
+ ModifierData *md;
if(!CustomData_get_layer(&me->fdata, CD_MDISPS)) {
/* multires can't work without displacement layer */
@@ -117,49 +145,71 @@
if(md->type == eModifierType_Multires) {
MultiresModifierData *mmd= (MultiresModifierData*)md;
- /* Check if any of the modifiers after multires are active
- * if not it can use the multires struct */
- for(nmd= md->next; nmd; nmd= nmd->next)
- if(modifier_isEnabled(scene, nmd, eModifierMode_Realtime))
- break;
+ if(!modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ continue;
- if(!nmd && mmd->sculptlvl > 0)
+ if (mmd->sculptlvl > 0)
return mmd;
+ else
+ return NULL;
}
}
return NULL;
}
-/* Checks whether full update mode (slower) needs to be used to work with modifiers */
-int sculpt_modifiers_active(Scene *scene, Object *ob)
+/* Check if there are any active modifiers in stack (used for flushing updates at enter/exit sculpt mode) */
+static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
{
ModifierData *md;
+
+ md= modifiers_getVirtualModifierList(ob);
+
+ /* exception for shape keys because we can edit those */
+ for(; md; md= md->next) {
+ if(modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Checks if there are any supported deformation modifiers active */
+static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
+{
+ ModifierData *md;
+ Mesh *me= (Mesh*)ob->data;
MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
- /* check if there are any modifiers after what we are sculpting,
- for a multires modifier with a deform modifier in front, we
- do no need to recalculate the modifier stack. note that this
- needs to be in sync with ccgDM_use_grid_pbvh! */
- if(mmd)
- md= mmd->modifier.next;
- else
- md= modifiers_getVirtualModifierList(ob);
+ if (mmd)
+ return 0;
+
+ /* non-locked shape keys could be handled in the same way as deformed mesh */
+ if ((ob->shapeflag&OB_SHAPE_LOCK)==0 && me->key && ob->shapenr)
+ return 1;
+
+ md= modifiers_getVirtualModifierList(ob);
/* exception for shape keys because we can edit those */
for(; md; md= md->next) {
- if(modifier_isEnabled(scene, md, eModifierMode_Realtime))
- if(md->type != eModifierType_ShapeKey)
- return 1;
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ if (!modifier_isEnabled(scene, md, eModifierMode_Realtime))
+ continue;
+
+ if (md->type==eModifierType_ShapeKey)
+ continue;
+
+ if (mti->type==eModifierTypeType_OnlyDeform)
+ return 1;
+
+ if (!(sd->flags & SCULPT_ONLY_DEFORM))
+ return 1;
}
return 0;
}
-/* ===== STRUCTS =====
- *
- */
-
typedef enum StrokeFlags {
CLIP_X = 1,
CLIP_Y = 2,
@@ -239,49 +289,28 @@
float plane_trim_squared;
float frontface_start, frontface_range;
+
+ rcti previous_r; /* previous redraw rectangle */
} StrokeCache;
/* rotation direction is flipped in different symmetrical passes */
static const int rotation_flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 };
-/* ===== OPENGL =====
- *
- * Simple functions to get data from the GL
- */
-
-/* Convert a point in model coordinates to 2D screen coordinates. */
-static void projectf(bglMats *mats, const float v[3], float p[2])
-{
- double ux, uy, uz;
-
- gluProject(v[0],v[1],v[2], mats->modelview, mats->projection,
- (GLint *)mats->viewport, &ux, &uy, &uz);
- p[0]= ux;
- p[1]= uy;
-}
-
-/*XXX: static void project(bglMats *mats, const float v[3], short p[2])
-{
- float f[2];
- projectf(mats, v, f);
-
- p[0]= f[0];
- p[1]= f[1];
-}
-*/
-
/*** BVH Tree ***/
/* Get a screen-space rectangle of the modified area */
-int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d,
- Object *ob, rcti *rect)
+static int sculpt_get_redraw_rect(
+ ARegion *ar,
+ RegionView3D *rv3d,
+ Object *ob,
+ rcti *rect)
{
PBVH *pbvh= ob->sculpt->pbvh;
float bb_min[3], bb_max[3], pmat[4][4];
int i, j, k;
- view3d_get_object_project_mat(rv3d, ob, pmat);
+ ED_view3d_ob_project_mat_get(rv3d, ob, pmat);
if(!pbvh)
return 0;
@@ -301,7 +330,7 @@
vec[0] = i ? bb_min[0] : bb_max[0];
vec[1] = j ? bb_min[1] : bb_max[1];
vec[2] = k ? bb_min[2] : bb_max[2];
- view3d_project_float(ar, vec, proj, pmat);
+ ED_view3d_project_float(ar, vec, proj, pmat);
rect->xmin = MIN2(rect->xmin, proj[0]);
rect->xmax = MAX2(rect->xmax, proj[0]);
rect->ymin = MIN2(rect->ymin, proj[1]);
@@ -309,8 +338,26 @@
}
}
}
-
- return rect->xmin < rect->xmax && rect->ymin < rect->ymax;
+
+ if (rect->xmin < rect->xmax && rect->ymin < rect->ymax) {
+ /* expand redraw rect with redraw rect from previous step to prevent
+ partial-redraw issues caused by fast strokes. This is needed here (not in sculpt_flush_update)
+ as it was before because redraw rectangle should be the same in both of
+ optimized PBVH draw function and 3d view redraw (if not -- some mesh parts could
+ disapper from screen (sergey) */
+
+ if (ob->sculpt->cache) {
+ rcti* previous_r = &(ob->sculpt->cache->previous_r);
+
+ if (!BLI_rcti_is_empty(previous_r))
+ BLI_union_rcti(rect, previous_r);
+ }
+
+ return 1;
+ }
+ else {
+ return rect->xmin < rect->xmax && rect->ymin < rect->ymax;
+ }
}
void sculpt_get_redraw_planes(float planes[4][4], ARegion *ar,
@@ -341,7 +388,7 @@
rect.ymax -= 2;
#endif
- view3d_calculate_clipping(&bb, planes, &mats, &rect);
+ ED_view3d_calc_clipping(&bb, planes, &mats, &rect);
mul_m4_fl(planes, -1.0f);
/* clear redraw flag from nodes */
@@ -351,6 +398,7 @@
/************************ Brush Testing *******************/
+// XXX: consider rewriting not to use struct
typedef struct SculptBrushTest {
float radius_squared;
float location[3];
@@ -361,6 +409,10 @@
{
test->radius_squared= ss->cache->radius_squared;
copy_v3_v3(test->location, ss->cache->location);
+
+ /* XXX: no need to initialize, consider not using struct at all and
+ trusting compiler to properly inline arguments */
+ //test->dist = -1;
}
static void sculpt_brush_range_test_init(const SculptSession *ss, SculptBrushTest *test, float range)
@@ -560,7 +612,7 @@
out[2]= in[2];
}
-float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle)
+static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle)
{
float mirror[3];
float distsq;
@@ -568,17 +620,17 @@
//flip_coord(mirror, cache->traced_location, symm);
flip_coord(mirror, cache->true_location, symm);
- if(axis != 0) {
+ if(axis >= 'X' && axis <= 'Z') {
float mat[4][4]= MAT4_UNITY;
- rotate_m4(mat, axis, angle);
- mul_m4_v3(mat, mirror);
+ rotate_m4(mat, axis, angle);
+ mul_m4_v3(mat, mirror);
}
//distsq = len_squared_v3v3(mirror, cache->traced_location);
distsq = len_squared_v3v3(mirror, cache->true_location);
- if (distsq <= 4*(cache->radius_squared))
- return (2*(cache->radius) - sqrt(distsq)) / (2*(cache->radius));
+ if (distsq <= 4.0f*(cache->radius_squared))
+ return (2.0f*(cache->radius) - sqrt(distsq)) / (2.0f*(cache->radius));
else
return 0;
}
@@ -754,25 +806,6 @@
}
}
-float get_tex_pixel(Brush* br, float u, float v)
-{
- TexResult texres;
- float co[3];
- int hasrgb;
-
- co[0] = u;
- co[1] = v;
- co[2] = 0;
-
- memset(&texres, 0, sizeof(TexResult));
- hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 1, &texres);
-
- if (hasrgb & TEX_RGB)
- texres.tin = (0.35*texres.tr + 0.45*texres.tg + 0.2*texres.tb)*texres.ta;
-
- return texres.tin;
-}
-
#if 0
/* Get a pixel from the texcache at (px, py) */
@@ -815,6 +848,7 @@
#endif
/* Return a multiplier for brush strength on a particular vertex. */
+/* XXX: a lot of this code is the same as code in paint_stroke for loading the overlay */
static float tex_strength(SculptSession *ss, Brush *br, float *point, const float len)
{
MTex *mtex = &br->mtex;
@@ -829,7 +863,7 @@
/* Get strength by feeding the vertex
location directly into a texture */
externtex(mtex, point, &avg,
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list