[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37464] branches/soc-2011-onion/source/ blender/editors/uvedit: subsurf-aware UV solver mark II implemented.

Ryakiotakis Antonis kalast at gmail.com
Tue Jun 14 05:36:53 CEST 2011


Revision: 37464
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37464
Author:   psy-fi
Date:     2011-06-14 03:36:53 +0000 (Tue, 14 Jun 2011)
Log Message:
-----------
subsurf-aware UV solver mark II implemented.
At last it works! This commit should make subsurfed area be correctly taken into account + avoid crashes that were there in the previous commit.
Better testing needed but initial results are very promising.

Modified Paths:
--------------
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.c
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.h
    branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_unwrap_ops.c

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.c	2011-06-14 03:16:08 UTC (rev 37463)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.c	2011-06-14 03:36:53 UTC (rev 37464)
@@ -11,8 +11,8 @@
 #include "BLI_boxpack2d.h"
 #include "BLI_utildefines.h"
 
+#include "BKE_DerivedMesh.h"
 
-
 #include "ONL_opennl.h"
 
 #include "uvedit_intern.h"
@@ -215,6 +215,7 @@
 
 	RNG *rng;
 	float blend;
+	DerivedMesh *derivedMesh;
 } PHandle;
 
 
@@ -4057,6 +4058,7 @@
 	handle->hash_verts = phash_new((PHashLink**)&handle->construction_chart->verts, 1);
 	handle->hash_edges = phash_new((PHashLink**)&handle->construction_chart->edges, 1);
 	handle->hash_faces = phash_new((PHashLink**)&handle->construction_chart->faces, 1);
+	handle->derivedMesh = NULL;
 
 	return (ParamHandle*)handle;
 }
@@ -4091,6 +4093,9 @@
 		phash_delete(phandle->hash_faces);
 	}
 
+	if(phandle->derivedMesh != NULL)
+		phandle->derivedMesh->release(phandle->derivedMesh);
+
 	BLI_memarena_free(phandle->arena);
 	MEM_freeN(phandle);
 }
@@ -4510,3 +4515,8 @@
 	}
 }
 
+void param_set_subsurfed_mesh(ParamHandle *handle, DerivedMesh *dm)
+{
+	PHandle *phandle = (PHandle*)handle;
+	phandle->derivedMesh = dm;
+}

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.h
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.h	2011-06-14 03:16:08 UTC (rev 37463)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_parametrizer.h	2011-06-14 03:36:53 UTC (rev 37464)
@@ -45,6 +45,9 @@
 void param_edge_set_seam(ParamHandle *handle,
 						 ParamKey *vkeys);
 
+void param_set_subsurfed_mesh(ParamHandle *handle,
+		 DerivedMesh *dm);
+
 void param_construct_end(ParamHandle *handle, ParamBool fill, ParamBool impl);
 void param_delete(ParamHandle *chart);
 

Modified: branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_unwrap_ops.c
===================================================================
--- branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_unwrap_ops.c	2011-06-14 03:16:08 UTC (rev 37463)
+++ branches/soc-2011-onion/source/blender/editors/uvedit/uvedit_unwrap_ops.c	2011-06-14 03:36:53 UTC (rev 37464)
@@ -137,7 +137,7 @@
 
 /****************** Parametrizer Conversion ***************/
 
-static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel, short correct_aspect, short use_subsurf)
+static ParamHandle *construct_param_handle(Scene *scene, EditMesh *em, short implicit, short fill, short sel, short correct_aspect)
 {
 	ParamHandle *handle;
 	EditFace *efa;
@@ -145,17 +145,6 @@
 	EditVert *ev;
 	MTFace *tf;
 	int a;
-
-	/* modifier initialization data, will  control what type of subdivision will happen*/
-	SubsurfModifierData smd;
-	/* Used to hold subsurfed Mesh */
-	DerivedMesh *derivedMesh, *initialDerived;
-	/* holds original indices for subsurfed mesh */
-	int *origIndices;
-	/* Holds vertices of subdivided mesh */
-	MVert *subsurfedVerts;
-	/* holds a map from mesh indices to subsurfedMesh indices */
-	int *indexMap = NULL;
 	
 	handle = param_construct_begin();
 
@@ -173,44 +162,6 @@
 		}
 	}
 	
-	if(use_subsurf)
-	{
-		int numOfVerts;
-		
-		/* number of subdivisions to perform */
-		smd.levels = scene->toolsettings->uv_subsurf_level;
-		/* no cache here */
-		smd.emCache = NULL;
-		smd.mCache = NULL;
-		/* will not be used here I think */
-		smd.renderLevels = 0;
-		/* catmull clark subdiv(simple makes no difference, apart from roasting the CPU) */
-		smd.subdivType = ME_CC_SUBSURF;
-		//smd.flags = ;
-		
-		initialDerived = CDDM_from_editmesh(em, NULL);
-
-		derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, NULL,
-			0, NULL, 1, 1, 0);
-
-		initialDerived->release(initialDerived);
-
-		subsurfedVerts = derivedMesh->getVertArray(derivedMesh);
-		origIndices = derivedMesh->getVertDataArray(derivedMesh, CD_ORIGINDEX);
-		
-		numOfVerts = derivedMesh->getNumVerts(derivedMesh);
-		
-		indexMap = MEM_mallocN(em->totvert*sizeof(int), "mesh_to_subsurfed_index_map");
-		
-		/* remap indices. DerivedMesh vertices that do not correspond to
-		   original mesh have -1 index on ORIGINDEX layer */
-		for(a = 0; a < numOfVerts; a++)
-		{
-			if(origIndices[a] != -1)
-				indexMap[origIndices[a]] = a;
-		}
-	}
-
 	/* we need the vert indices */
 	for(ev= em->verts.first, a=0; ev; ev= ev->next, a++)
 		ev->tmp.l = a;
@@ -249,15 +200,9 @@
 		vkeys[1] = (ParamKey)efa->v2->tmp.l;
 		vkeys[2] = (ParamKey)efa->v3->tmp.l;
 
-		if(use_subsurf){
-			co[0] = subsurfedVerts[indexMap[efa->v1->tmp.l]].co;
-			co[1] = subsurfedVerts[indexMap[efa->v2->tmp.l]].co;
-			co[2] = subsurfedVerts[indexMap[efa->v3->tmp.l]].co;
-		} else {
-			co[0] = efa->v1->co;
-			co[1] = efa->v2->co;
-			co[2] = efa->v3->co;
-		}
+		co[0] = efa->v1->co;
+		co[1] = efa->v2->co;
+		co[2] = efa->v3->co;
 		
 		uv[0] = tf->uv[0];
 		uv[1] = tf->uv[1];
@@ -273,11 +218,7 @@
 
 		if(efa->v4) {
 			vkeys[3] = (ParamKey)efa->v4->tmp.l;
-			if(use_subsurf){
-				co[3] = subsurfedVerts[indexMap[efa->v4->tmp.l]].co;
-			} else {
-				co[3] = efa->v4->co;
-			}
+			co[3] = efa->v4->co;
 			uv[3] = tf->uv[3];
 			pin[3] = ((tf->unwrap & TF_PIN4) != 0);
 			select[3] = (uvedit_uv_selected(scene, efa, tf, 3) != 0);
@@ -302,12 +243,252 @@
 
 	param_construct_end(handle, fill, implicit);
 
+	return handle;
+}
+
+
+static float *get_TexFace_UV_from_Index(EditFace *editFace, MTFace *texFace, int index)
+{
+	if(editFace->v1->tmp.t == index)
+		return texFace->uv[0];
+	else if(editFace->v2->tmp.t == index)
+		return texFace->uv[1];
+	else if(editFace->v3->tmp.t == index)
+			return texFace->uv[2];
+	else if(editFace->v4 && editFace->v4->tmp.t == index)
+			return texFace->uv[3];
+	return NULL;
+}
+
+
+
+/* unwrap handle initialization for subsurf aware-unwrapper. The many modifications required to make the original function(see above)
+ * work justified the existence of a new function. */
+static ParamHandle *construct_param_handle_subsurfed(Scene *scene, EditMesh *editMesh, short implicit, short fill, short sel, short correct_aspect)
+{
+	ParamHandle *handle;
+	/* index pointers */
+	MFace *face;
+	MEdge *edge;
+	EditVert *editVert;
+	MTFace *texface;
+	EditFace *editFace, **editFaceTmp;
+	EditEdge *editEdge, **editEdgeTmp;
+	int i;
+
+	/* modifier initialization data, will  control what type of subdivision will happen*/
+	SubsurfModifierData smd;
+	/* Used to hold subsurfed Mesh */
+	DerivedMesh *derivedMesh, *initialDerived;
+	/* holds original indices for subsurfed mesh */
+	int *origVertIndices, *origFaceIndices, *origEdgeIndices;
+	/* Holds vertices of subsurfed mesh */
+	MVert *subsurfedVerts;
+	MEdge *subsurfedEdges;
+	MFace *subsurfedFaces;
+	MTFace *subsurfedTexfaces;
+	/* number of vertices and faces for subsurfed mesh*/
+	int numOfVerts, numOfEdges, numOfFaces;
+
+	/* holds a map to editfaces for every subsurfed MFace. These will be used to get hidden/ selected flags etc. */
+	EditFace **faceMap;
+	/* Mini container to hold all EditFaces so that they may be indexed easily and fast. */
+	EditFace **editFaceArray;
+	/* similar to the above, we need a way to map edges to their original ones */
+	EditEdge **edgeMap;
+	EditEdge **editEdgeArray;
+
+	handle = param_construct_begin();
+
+	if(correct_aspect) {
+		EditFace *eface = EM_get_actFace(editMesh, 1);
+
+		if(eface) {
+			float aspx, aspy;
+			texface= CustomData_em_get(&editMesh->fdata, eface->data, CD_MTFACE);
+
+			ED_image_uv_aspect(texface->tpage, &aspx, &aspy);
+		
+			if(aspx!=aspy)
+				param_aspect_ratio(handle, aspx, aspy);
+		}
+	}
+
+	/* number of subdivisions to perform */
+	smd.levels = scene->toolsettings->uv_subsurf_level;
+	/* no cache here */
+	smd.emCache = NULL;
+	smd.mCache = NULL;
+	/* will not be used here I think */
+	smd.renderLevels = 0;
+	/* Catmull-Clark subdiv(simple makes no difference, apart from roasting the CPU) */
+	smd.subdivType = ME_CC_SUBSURF;
+	//smd.flags = ;
+		
+	initialDerived = CDDM_from_editmesh(editMesh, NULL);
+
+	derivedMesh = subsurf_make_derived_from_derived(initialDerived, &smd, NULL,
+		0, NULL, 1, 1, 0);
+
+	initialDerived->release(initialDerived);
+
+	/* Store the derived Mesh in the handle to cleanup later. This avoids freed memory access and crashes */
+	param_set_subsurfed_mesh(handle, derivedMesh);
+
+	/* get the derived data */
+	subsurfedVerts = derivedMesh->getVertArray(derivedMesh);
+	subsurfedEdges = derivedMesh->getEdgeArray(derivedMesh);
+	subsurfedFaces = derivedMesh->getFaceArray(derivedMesh);
+
+	origVertIndices = derivedMesh->getVertDataArray(derivedMesh, CD_ORIGINDEX);
+	origEdgeIndices = derivedMesh->getEdgeDataArray(derivedMesh, CD_ORIGINDEX);
+	origFaceIndices = derivedMesh->getFaceDataArray(derivedMesh, CD_ORIGINDEX);
+
+	subsurfedTexfaces = derivedMesh->getFaceDataArray(derivedMesh, CD_MTFACE);
+
+	numOfVerts = derivedMesh->getNumVerts(derivedMesh);
+	numOfEdges = derivedMesh->getNumEdges(derivedMesh);
+	numOfFaces = derivedMesh->getNumFaces(derivedMesh);
+
+	faceMap = MEM_mallocN(numOfFaces*sizeof(EditFace *), "unwrap_edit_face_map");
+	editFaceArray = MEM_mallocN(editMesh->totface*sizeof(EditFace *), "unwrap_editFaceArray");
+
+	/* fill edit face array with edit faces */
+	for(editFace = editMesh->faces.first, editFaceTmp = editFaceArray; editFace; editFace= editFace->next, editFaceTmp++) {
+		*editFaceTmp = editFace;
+	}
+	/* map subsurfed faces to original editFaces */
+	for(i = 0; i < numOfFaces; i++){
+		faceMap[i] = editFaceArray[origFaceIndices[i]];
+	}
+	MEM_freeN(editFaceArray);
+
+	edgeMap = MEM_mallocN(numOfEdges*sizeof(EditEdge *), "unwrap_edit_edge_map");
+	editEdgeArray = MEM_mallocN(editMesh->totedge*sizeof(EditEdge *), "unwrap_editEdgeArray");
+
+	/* fill edit edge array with edit edges */
+	for(editEdge = editMesh->edges.first, editEdgeTmp = editEdgeArray; editEdge; editEdge= editEdge->next, editEdgeTmp++) {
+		*editEdgeTmp = editEdge;
+	}
+	/* map subsurfed edges to original editEdges */
+	for(i = 0; i < numOfEdges; i++){
+		/* not all edges correspond to an old edge */
+		edgeMap[i] = (origEdgeIndices[i] != -1)?
+			editEdgeArray[origEdgeIndices[i]] : NULL;
+	}
+	MEM_freeN(editEdgeArray);
+
+	/* we need the editvert indices too */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list