[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [29968] branches/soc-2010-nicolasbishop: Experimental feature, multires apply base, as suggested by renderdemon
Nicholas Bishop
nicholasbishop at gmail.com
Mon Jul 5 08:28:53 CEST 2010
Revision: 29968
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=29968
Author: nicholasbishop
Date: 2010-07-05 08:28:53 +0200 (Mon, 05 Jul 2010)
Log Message:
-----------
Experimental feature, multires apply base, as suggested by renderdemon
* Attempts to fix the "spike" problem with multires
* For example, take the grab brush and pulling a large chunk of the mesh around will create ugly spikes at lower levels
* Another problem is that a multires mesh heavily changed in sculpt mode will still have the original shape in editmode, which might not be very useful
* Solution here is a new operator "Apply Base" that modifies the mesh to conform better to the sculpt multires mesh.
* Like applying the modifier, this changes actual mesh data, not disps
* Some attempt is made to avoid shrinking the base mesh too much, but the algorithm used is just my guess based on how catmull clark behaves
* So far as I know there are no published algorithms for correctly reversing catmull clark when the subdivided mesh has been deformed
Modified Paths:
--------------
branches/soc-2010-nicolasbishop/release/scripts/ui/properties_data_modifier.py
branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_multires.h
branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/multires.c
branches/soc-2010-nicolasbishop/source/blender/editors/object/object_intern.h
branches/soc-2010-nicolasbishop/source/blender/editors/object/object_modifier.c
branches/soc-2010-nicolasbishop/source/blender/editors/object/object_ops.c
Modified: branches/soc-2010-nicolasbishop/release/scripts/ui/properties_data_modifier.py
===================================================================
--- branches/soc-2010-nicolasbishop/release/scripts/ui/properties_data_modifier.py 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/release/scripts/ui/properties_data_modifier.py 2010-07-05 06:28:53 UTC (rev 29968)
@@ -445,6 +445,7 @@
col.operator("object.multires_subdivide", text="Subdivide")
col.operator("object.multires_higher_levels_delete", text="Delete Higher")
col.operator("object.multires_reshape", text="Reshape")
+ col.operator("object.multires_base_apply", text="Apply Base")
col.prop(md, "optimal_display")
layout.separator()
Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_multires.h
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_multires.h 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/BKE_multires.h 2010-07-05 06:28:53 UTC (rev 29968)
@@ -60,6 +60,7 @@
struct Object *ob, struct DerivedMesh *srcdm);
int multiresModifier_reshapeFromDeformMod(struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob, struct ModifierData *md);
+void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob);
void multires_stitch_grids(struct Object *);
Modified: branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/multires.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/multires.c 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/source/blender/blenkernel/intern/multires.c 2010-07-05 06:28:53 UTC (rev 29968)
@@ -479,6 +479,120 @@
return subsurf_make_derived_from_derived(dm, &smd, &gridkey, 0, NULL, 0, 0);
}
+/* assumes no is normalized; return value's sign is negative if v is on
+ the other side of the plane */
+static float v3_dist_from_plane(float v[3], float center[3], float no[3])
+{
+ float s[3];
+ sub_v3_v3v3(s, v, center);
+ return dot_v3v3(s, no);
+}
+
+void multiresModifier_base_apply(MultiresModifierData *mmd, Object *ob)
+{
+ DerivedMesh *cddm, *dispdm, *origdm;
+ Mesh *me;
+ ListBase *fmap;
+ float (*origco)[3];
+ int i, j, offset, totlvl;
+
+ multires_force_update(ob);
+
+ me = get_mesh(ob);
+ totlvl = mmd->totlvl;
+
+ /* XXX - probably not necessary to regenerate the cddm so much? */
+
+ /* generate highest level with displacements */
+ cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+ dispdm = multires_dm_create_local(ob, cddm, totlvl, totlvl, 0);
+ cddm->release(cddm);
+
+ /* copy the new locations of the base verts into the mesh */
+ offset = dispdm->getNumVerts(dispdm) - me->totvert;
+ for(i = 0; i < me->totvert; ++i) {
+ dispdm->getVertCo(dispdm, offset + i, me->mvert[i].co);
+ }
+
+ /* heuristic to produce a better-fitting base mesh */
+ cddm = CDDM_from_mesh(me, NULL);
+ fmap = cddm->getFaceMap(ob, cddm);
+ origco = MEM_callocN(sizeof(float)*3*me->totvert, "multires apply base origco");
+ for(i = 0; i < me->totvert ;++i)
+ copy_v3_v3(origco[i], me->mvert[i].co);
+
+ for(i = 0; i < me->totvert; ++i) {
+ IndexNode *n;
+ float avg_no[3] = {0,0,0}, center[3] = {0,0,0}, push[3];
+ float dist;
+ int tot;
+
+ /* Don't adjust verts not used by at least one face */
+ if(!fmap[i].first)
+ continue;
+
+ /* find center */
+ for(n = fmap[i].first, tot = 0; n; n = n->next) {
+ MFace *f = &me->mface[n->index];
+ int S = f->v4 ? 4 : 3;
+
+ /* this double counts, not sure if that's bad or good */
+ for(j = 0; j < S; ++j) {
+ int vndx = (&f->v1)[j];
+ if(vndx != i) {
+ add_v3_v3(center, origco[vndx]);
+ ++tot;
+ }
+ }
+ }
+ mul_v3_fl(center, 1.0f / tot);
+
+ /* find normal */
+ for(n = fmap[i].first; n; n = n->next) {
+ MFace *f = &me->mface[n->index];
+ int S = f->v4 ? 4 : 3;
+ float v[4][3], no[3];
+
+ for(j = 0; j < S; ++j) {
+ int vndx = (&f->v1)[j];
+ if(vndx == i)
+ copy_v3_v3(v[j], center);
+ else
+ copy_v3_v3(v[j], origco[vndx]);
+ }
+
+ if(S == 4)
+ normal_quad_v3(no, v[0], v[1], v[2], v[3]);
+ else
+ normal_tri_v3(no, v[0], v[1], v[2]);
+ add_v3_v3(avg_no, no);
+ }
+ normalize_v3(avg_no);
+
+ /* push vertex away from the plane */
+ dist = v3_dist_from_plane(me->mvert[i].co, center, avg_no);
+ copy_v3_v3(push, avg_no);
+ mul_v3_fl(push, dist);
+ add_v3_v3(me->mvert[i].co, push);
+
+ }
+
+ MEM_freeN(origco);
+ cddm->release(cddm);
+
+ /* subdivide the mesh to highest level without displacements */
+ cddm = CDDM_from_mesh(me, NULL);
+ DM_set_only_copy(cddm, CD_MASK_BAREMESH);
+ origdm = subsurf_dm_create_local(ob, cddm, totlvl, 0, 0);
+ cddm->release(cddm);
+
+ multiresModifier_disp_run(dispdm, me, CALC_DISPS, origdm->getGridData(origdm), totlvl);
+
+ origdm->release(origdm);
+ dispdm->release(dispdm);
+}
+
static DMGridData **copy_grids(DMGridData **grids, int totgrid, int gridsize, GridKey *gridkey)
{
DMGridData **grids_copy = MEM_callocN(sizeof(DMGridData*) * totgrid, "subgrids");
Modified: branches/soc-2010-nicolasbishop/source/blender/editors/object/object_intern.h
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/editors/object/object_intern.h 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/source/blender/editors/object/object_intern.h 2010-07-05 06:28:53 UTC (rev 29968)
@@ -158,6 +158,7 @@
void OBJECT_OT_multires_higher_levels_delete(struct wmOperatorType *ot);
void OBJECT_OT_multires_external_save(struct wmOperatorType *ot);
void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot);
+void OBJECT_OT_multires_base_apply(struct wmOperatorType *ot);
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
Modified: branches/soc-2010-nicolasbishop/source/blender/editors/object/object_modifier.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/editors/object/object_modifier.c 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/source/blender/editors/object/object_modifier.c 2010-07-05 06:28:53 UTC (rev 29968)
@@ -1114,6 +1114,47 @@
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/********************* multires apply base ***********************/
+static int multires_base_apply_exec(bContext *C, wmOperator *op)
+{
+ Object *ob = ED_object_active_context(C);
+ MultiresModifierData *mmd = (MultiresModifierData *)edit_modifier_property_get(C, op, ob, eModifierType_Multires);
+
+ if (!mmd)
+ return OPERATOR_CANCELLED;
+
+ multiresModifier_base_apply(mmd, ob);
+
+ DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int multires_base_apply_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ if (edit_modifier_invoke_properties(C, op))
+ return multires_base_apply_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+
+void OBJECT_OT_multires_base_apply(wmOperatorType *ot)
+{
+ ot->name= "Multires Apply Base";
+ ot->description= "Modify the base mesh to conform to the displaced mesh";
+ ot->idname= "OBJECT_OT_multires_base_apply";
+
+ ot->poll= multires_poll;
+ ot->invoke= multires_base_apply_invoke;
+ ot->exec= multires_base_apply_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ edit_modifier_properties(ot);
+}
+
/************************ mdef bind operator *********************/
static int meshdeform_poll(bContext *C)
Modified: branches/soc-2010-nicolasbishop/source/blender/editors/object/object_ops.c
===================================================================
--- branches/soc-2010-nicolasbishop/source/blender/editors/object/object_ops.c 2010-07-05 06:04:24 UTC (rev 29967)
+++ branches/soc-2010-nicolasbishop/source/blender/editors/object/object_ops.c 2010-07-05 06:28:53 UTC (rev 29968)
@@ -139,6 +139,7 @@
WM_operatortype_append(OBJECT_OT_multires_higher_levels_delete);
WM_operatortype_append(OBJECT_OT_multires_external_save);
WM_operatortype_append(OBJECT_OT_multires_external_pack);
+ WM_operatortype_append(OBJECT_OT_multires_base_apply);
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
More information about the Bf-blender-cvs
mailing list