[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