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. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org http://lists.blender.org/mailman/listinfo/bf-blender-cvs