Add DNA/RNA/BKE infrastructure for dynamic-topology sculpt mode

* Add a detail_size field to the Sculpt struct, two new sculpt flags,
  and a Mesh flag for dynamic-topology mode; that's it for file-level
  changes needed by dynamic topology

* Add RNA for the new DNA field and flags

* Add a new icon for dynamic-topology created by Julio Iglesias. TODO:
  update the icon for the new SVG icon format

* Add a SculptSession function for converting from BMesh to Mesh,
  handles reordering mesh elements and setting face shading
This commit is contained in:
Nicholas Bishop 2012-12-30 18:27:33 +00:00
parent 31f978c8ef
commit fc442dbd51
10 changed files with 697 additions and 594 deletions

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 3.9 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 225 KiB

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

After

Width:  |  Height:  |  Size: 563 KiB

@ -33,6 +33,7 @@
*/
struct bContext;
struct BMesh;
struct Brush;
struct MDisps;
struct MeshElemMap;
@ -92,6 +93,12 @@ typedef struct SculptSession {
/* Mesh connectivity */
const struct MeshElemMap *pmap;
/* BMesh for dynamic topology sculpting */
struct BMesh *bm;
int bm_smooth_shading;
/* Undo/redo log for dynamic topology sculpting */
struct BMLog *bm_log;
/* PBVH acceleration structure */
struct PBVH *pbvh;
int show_diffuse_color;
@ -121,5 +128,6 @@ typedef struct SculptSession {
void free_sculptsession(struct Object *ob);
void free_sculptsession_deformMats(struct SculptSession *ss);
void sculptsession_bm_to_me(struct Object *ob, int reorder);
#endif

@ -264,14 +264,44 @@ void free_sculptsession_deformMats(SculptSession *ss)
ss->deform_imats = NULL;
}
/* Write out the sculpt dynamic-topology BMesh to the Mesh */
void sculptsession_bm_to_me(struct Object *ob, int reorder)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
if (ss->bm) {
if (ob->data) {
BMIter iter;
BMFace *efa;
BM_ITER_MESH (efa, &iter, ss->bm, BM_FACES_OF_MESH) {
BM_elem_flag_set(efa, BM_ELEM_SMOOTH,
ss->bm_smooth_shading);
}
if (reorder)
BM_log_mesh_elems_reorder(ss->bm, ss->bm_log);
BM_mesh_bm_to_me(ss->bm, ob->data, FALSE);
}
}
}
}
void free_sculptsession(Object *ob)
{
if (ob && ob->sculpt) {
SculptSession *ss = ob->sculpt;
DerivedMesh *dm = ob->derivedFinal;
if (ss->bm) {
sculptsession_bm_to_me(ob, TRUE);
BM_mesh_free(ss->bm);
}
if (ss->pbvh)
BLI_pbvh_free(ss->pbvh);
if (ss->bm_log)
BM_log_free(ss->bm_log);
if (dm && dm->getPBVH)
dm->getPBVH(NULL, dm); /* signal to clear */

@ -699,9 +699,7 @@ DEF_ICON(RNDCURVE)
DEF_ICON(PROP_OFF)
DEF_ICON(PROP_ON)
DEF_ICON(PROP_CON)
#ifndef DEF_ICON_BLANK_SKIP
DEF_ICON(BLANK212)
#endif
DEF_ICON(SCULPT_DYNTOPO)
DEF_ICON(PARTICLE_POINT)
DEF_ICON(PARTICLE_TIP)
DEF_ICON(PARTICLE_PATH)

@ -170,6 +170,7 @@ typedef struct TFace {
#define ME_SUBSURF 128
#define ME_OPT_EDGES 256
#define ME_DS_EXPAND 512
#define ME_SCULPT_DYNAMIC_TOPOLOGY 1024
/* me->drawflag, short */
#define ME_DRAWEDGES (1 << 0)

@ -830,7 +830,8 @@ typedef struct Sculpt {
float special_rotation;
int pad;
/* Maximum edge length for dynamic topology sculpting (in pixels) */
int detail_size;
} Sculpt;
typedef struct UvSculpt {
@ -1479,6 +1480,14 @@ typedef enum SculptFlags {
SCULPT_USE_OPENMP = (1<<7),
SCULPT_ONLY_DEFORM = (1<<8),
SCULPT_SHOW_DIFFUSE = (1<<9),
/* If set, the mesh will be drawn with smooth-shading in
dynamic-topology mode */
SCULPT_DYNTOPO_SMOOTH_SHADING = (1<<10),
/* If set, dynamic-topology brushes will collapse short edges in
addition to subdividing long ones */
SCULPT_DYNTOPO_COLLAPSE = (1<<11)
} SculptFlags;
/* ImagePaintSettings.flag */

@ -48,6 +48,7 @@
#include "BLI_utildefines.h"
#include "BKE_paint.h"
#include "BKE_tessmesh.h"
#include "BKE_group.h" /* needed for object_in_group() */
@ -1436,6 +1437,12 @@ int rna_DupliObject_index_get(PointerRNA *ptr)
return dob->persistent_id[0];
}
int rna_Object_use_dynamic_topology_sculpting_get(PointerRNA *ptr)
{
SculptSession *ss = ((Object*)ptr->id.data)->sculpt;
return (ss && ss->bm);
}
#else
static int rna_matrix_dimsize_4x4[] = {4, 4};
@ -2629,6 +2636,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Active Shape Key Index", "Current shape key index");
RNA_def_property_update(prop, 0, "rna_Object_active_shape_update");
/* sculpt */
prop = RNA_def_property(srna, "use_dynamic_topology_sculpting", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Object_use_dynamic_topology_sculpting_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dynamic Topology Sculpting", NULL);
RNA_api_object(srna);
}

@ -204,6 +204,11 @@ static void rna_Sculpt_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNU
if (ob) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob);
if (ob->sculpt) {
ob->sculpt->bm_smooth_shading = (scene->toolsettings->sculpt->flags &
SCULPT_DYNTOPO_SMOOTH_SHADING);
}
}
}
@ -319,6 +324,23 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Diffuse Color",
"Show diffuse color of object and overlay sculpt mask on top of it");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_ShowDiffuseColor_update");
prop = RNA_def_property(srna, "detail_size", PROP_INT, PROP_DISTANCE);
RNA_def_property_ui_range(prop, 2, 100, 0, 0);
RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (in pixels)");
prop = RNA_def_property(srna, "use_smooth_shading", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_SMOOTH_SHADING);
RNA_def_property_ui_text(prop, "Smooth Shading",
"Show faces in dynamic-topology mode with smooth "
"shading rather than flat shaded");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
prop = RNA_def_property(srna, "use_edge_collapse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_DYNTOPO_COLLAPSE);
RNA_def_property_ui_text(prop, "Collapse Short Edges",
"In dynamic-topology mode, collapse short edges "
"in addition to subdividing long ones");
}