From d88bb9115f836d8c6516104378683480a2cc64dc Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Fri, 25 Mar 2011 00:32:38 +0000 Subject: =bmesh= Coded a new modifier, "Precision UV Interpolation", that triangulates, subdivides, then uses brecht's mean value interpolation to interpolate face data. Textures on ngon faces get interpolated a bit nicer, in other words (though concave cases, e.g. 'N', don't work very well). --- source/blender/blenkernel/BKE_cdderivedmesh.h | 7 +- source/blender/blenkernel/BKE_mesh.h | 5 + source/blender/blenkernel/intern/cdderivedmesh.c | 15 +- source/blender/blenkernel/intern/mesh.c | 20 +- source/blender/blenkernel/intern/subsurf_ccg.c | 377 --------------------- source/blender/bmesh/intern/bmesh_interp.c | 2 +- source/blender/bmesh/operators/mesh_conv.c | 3 +- source/blender/editors/mesh/editbmesh_add.c | 18 +- source/blender/editors/sculpt_paint/paint_image.c | 6 +- .../editors/transform/transform_conversions.c | 2 + source/blender/makesdna/DNA_modifier_types.h | 7 + source/blender/makesrna/intern/rna_modifier.c | 23 ++ source/blender/modifiers/CMakeLists.txt | 1 + source/blender/modifiers/MOD_modifiertypes.h | 1 + source/blender/modifiers/intern/MOD_mirror.c | 2 +- source/blender/modifiers/intern/MOD_ngoninterp.c | 322 ++++++++++++++++++ source/blender/modifiers/intern/MOD_util.c | 1 + 17 files changed, 404 insertions(+), 408 deletions(-) create mode 100644 source/blender/modifiers/intern/MOD_ngoninterp.c (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index c1161e7c65b..1d99d9c388b 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -116,8 +116,11 @@ void CDDM_calc_edges(struct DerivedMesh *dm); faces*/ void CDDM_calc_edges_poly(struct DerivedMesh *dm); -/*reconstitute face triangulation*/ -void CDDM_recalc_tesselation(struct DerivedMesh *dm); +/*reconstitute face triangulation. if orig_use_polyorig is nonzero, sets + the mface origindex layer to copy to the origindex values of the + parent mpolys; otherwise the mface origindex will point to the index of + the parent mpoly*/ +void CDDM_recalc_tesselation(struct DerivedMesh *dm, int orig_use_polyorig); /* lowers the number of vertices/edges/faces in a CDDerivedMesh * the layer data stays the same size diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 7dc1172d32e..151bb45f663 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -198,6 +198,11 @@ int BKE_mesh_validate_dm(struct DerivedMesh *dm); void BKE_mesh_calc_edges(struct Mesh *mesh, int update); +/*convert a triangle of loop facedata to mface facedata*/ +void mesh_loops_to_tri_corners(struct CustomData *fdata, struct CustomData *ldata, + struct CustomData *pdata, int lindex[3], int findex, + int polyindex); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index aa1d3907907..3ea09a40ef5 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1465,11 +1465,6 @@ static void cdDM_recalcTesselation(DerivedMesh *dm) cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); } -void CDDM_recalc_tesselation(DerivedMesh *dm) -{ - cdDM_recalcTesselation(dm); -} - /*ignores original poly origindex layer*/ static void cdDM_recalcTesselation2(DerivedMesh *dm) { @@ -1482,6 +1477,14 @@ static void cdDM_recalcTesselation2(DerivedMesh *dm) cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); } +void CDDM_recalc_tesselation(DerivedMesh *dm, int orig_use_polyorig) +{ + if (orig_use_polyorig) + cdDM_recalcTesselation(dm); + else + cdDM_recalcTesselation2(dm); +} + static void cdDM_free_internal(CDDerivedMesh *cddm) { if(cddm->fmap) MEM_freeN(cddm->fmap); @@ -2458,7 +2461,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap) memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly)); BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly); - CDDM_recalc_tesselation(cddm2); + CDDM_recalc_tesselation(cddm2, 1); if (newv) MEM_freeN(newv); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index f6679315606..b7c300ffe22 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1890,9 +1890,9 @@ void mesh_pmv_off(Mesh *me) } } -static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, - CustomData *pdata, int lindex[4], int findex, - int polyindex, int numTex, int numCol, int tot) +void mesh_loops_to_tri_corners(CustomData *fdata, CustomData *ldata, + CustomData *pdata, int lindex[3], int findex, + int polyindex) { MTFace *texface; MTexPoly *texpoly; @@ -1900,7 +1900,9 @@ static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, MLoopCol *mloopcol; MLoopUV *mloopuv; int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL); - + int numTex = CustomData_number_of_layers(pdata, CD_MTEXPOLY); + int numCol = CustomData_number_of_layers(ldata, CD_MLOOPCOL); + for(i=0; i < numTex; i++){ texface = CustomData_get_n(fdata, CD_MTFACE, findex, i); texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i); @@ -1912,7 +1914,7 @@ static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, texface->tile = texpoly->tile; texface->unwrap = texpoly->unwrap; - for (j=0; juv[j][0] = mloopuv->uv[0]; texface->uv[j][1] = mloopuv->uv[1]; @@ -1922,7 +1924,7 @@ static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, for(i=0; i < numCol; i++){ mcol = CustomData_get_n(fdata, CD_MCOL, findex, i); - for (j=0; jr; mcol[j].g = mloopcol->g; @@ -1934,7 +1936,7 @@ static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, if (hasWCol) { mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL); - for (j=0; jr; mcol[j].g = mloopcol->g; @@ -2059,8 +2061,8 @@ int mesh_recalcTesselation(CustomData *fdata, mf->v2 = mloop[mf->v2].v; mf->v3 = mloop[mf->v3].v; - mesh_loops_to_corners(fdata, ldata, pdata, - lindex, i, mf->v4, numTex, numCol, 3); + mesh_loops_to_tri_corners(fdata, ldata, pdata, + lindex, i, mf->v4); mf->v4 = 0; } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index c1689474c7b..67e09cde3cd 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -517,383 +517,6 @@ static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh, CDDM_calc_normals(result); return result; -#if 0 - DerivedMesh *result; - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int gridSize = ccgSubSurf_getGridSize(ss); - int gridFaces = gridSize - 1; - int edgeBase, faceBase; - int i, j, k, S, x, y, index; - int *vertIdx = NULL; - BLI_array_declare(vertIdx); - CCGVertIterator *vi; - CCGEdgeIterator *ei; - CCGFaceIterator *fi; - CCGFace **faceMap2; - CCGEdge **edgeMap2; - CCGVert **vertMap2; - int totvert, totedge, totface; - MVert *mvert; - MEdge *med; - float *w = NULL; - WeightTable wtable; - BLI_array_declare(w); - MFace *mf; - int *origIndex; - - memset(&wtable, 0, sizeof(wtable)); - - /* vert map */ - totvert = ccgSubSurf_getNumVerts(ss); - vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); - vi = ccgSubSurf_getVertIterator(ss); - for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { - CCGVert *v = ccgVertIterator_getCurrent(vi); - - vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v; - } - ccgVertIterator_free(vi); - - totedge = ccgSubSurf_getNumEdges(ss); - edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap"); - ei = ccgSubSurf_getEdgeIterator(ss); - for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { - CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - - edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e; - } - - totface = ccgSubSurf_getNumFaces(ss); - faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap"); - fi = ccgSubSurf_getFaceIterator(ss); - for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { - CCGFace *f = ccgFaceIterator_getCurrent(fi); - - faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f; - } - ccgFaceIterator_free(fi); - - if(ms) { - result = MultiresDM_new(ms, dm, ccgSubSurf_getNumFinalVerts(ss), - ccgSubSurf_getNumFinalEdges(ss), - ccgSubSurf_getNumFinalFaces(ss), 0, 0); - } - else { - if(dm) { - result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss), - ccgSubSurf_getNumFinalEdges(ss), - ccgSubSurf_getNumFinalFaces(ss), 0, 0); - } else { - result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss), - ccgSubSurf_getNumFinalEdges(ss), - ccgSubSurf_getNumFinalFaces(ss), 0, 0); - } - } - - // load verts - faceBase = i = 0; - mvert = CDDM_get_verts(result); - origIndex = result->getVertData(result, 0, CD_ORIGINDEX); - - for(index = 0; index < totface; index++) { - CCGFace *f = faceMap2[index]; - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - FaceVertWeight *weight = 0;//get_ss_weights(&wtable, gridFaces-1, numVerts); - - BLI_array_empty(vertIdx); - - for(S = 0; S < numVerts; S++) { - CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); - BLI_array_growone(vertIdx); - - vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); - } - -#if 0 - DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i); -#endif - copy_v3_v3(mvert->co, ccgSubSurf_getFaceCenterData(f)); - *origIndex = ORIGINDEX_NONE; - ++mvert; - ++origIndex; - i++; - - BLI_array_empty(w); - for (x=0; x= 4) ? (S + 2) % numVerts : 3; - - for(x = 1; x < gridFaces; x++) { -#if 0 - w[prevS] = weight[x][0][0]; - w[S] = weight[x][0][1]; - w[nextS] = weight[x][0][2]; - w[otherS] = weight[x][0][3]; - - DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i); -#endif - copy_v3_v3(mvert->co, - ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); - - *origIndex = ORIGINDEX_NONE; - ++mvert; - ++origIndex; - i++; - } - } - - BLI_array_empty(w); - for (x=0; xco, - ccgSubSurf_getFaceGridData(ss, f, S, x, y)); - *origIndex = ORIGINDEX_NONE; - ++mvert; - ++origIndex; - i++; - } - } - } - *((int*)ccgSubSurf_getFaceUserData(ss, f)) = faceBase; - faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2)); - } - - edgeBase = i; - for(index = 0; index < totedge; index++) { - CCGEdge *e = edgeMap2[index]; - int x; - int vertIdx[2]; - - CCGVert *v; - v = ccgSubSurf_getEdgeVert0(e); - vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); - v = ccgSubSurf_getEdgeVert1(e); - vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); - - for(x = 1; x < edgeSize - 1; x++) { - float w2[2]; - - w2[1] = (float) x / (edgeSize - 1); - w2[0] = 1 - w2[1]; - DM_interp_vert_data(dm, result, vertIdx, w2, 2, i); - - copy_v3_v3(mvert->co, ccgSubSurf_getEdgeData(ss, e, x)); - *origIndex = ORIGINDEX_NONE; - ++mvert; - ++origIndex; - i++; - } - - *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase; - edgeBase += edgeSize-2; - } - - for(index = 0; index < totvert; index++) { - CCGVert *v = vertMap2[index]; - int vertIdx; - - vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); - - DM_copy_vert_data(dm, result, vertIdx, i, 1); - copy_v3_v3(mvert->co, ccgSubSurf_getVertData(ss, v)); - - *((int*)ccgSubSurf_getVertUserData(ss, v)) = i; - *origIndex = ccgDM_getVertMapIndex(ss, v); - ++mvert; - ++origIndex; - i++; - } - - // load edges - i = 0; - med = CDDM_get_edges(result); - origIndex = result->getEdgeData(result, 0, CD_ORIGINDEX); - - for(index = 0; index < totface; index++) { - CCGFace *f = faceMap2[index]; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - - for(k = 0; k < numVerts; k++) { - for(x = 0; x < gridFaces; x++) { - if(drawInteriorEdges) med->flag = ME_EDGEDRAW | ME_EDGERENDER; - med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize); - med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize); - *origIndex = ORIGINDEX_NONE; - ++med; - ++origIndex; - i++; - } - - for(x = 1; x < gridFaces; x++) { - for(y = 0; y < gridFaces; y++) { - if(drawInteriorEdges) - med->flag = ME_EDGEDRAW | ME_EDGERENDER; - med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize); - med->v2 = getFaceIndex(ss, f, k, x, y + 1, - edgeSize, gridSize); - *origIndex = ORIGINDEX_NONE; - ++med; - ++origIndex; - i++; - - if(drawInteriorEdges) - med->flag = ME_EDGEDRAW | ME_EDGERENDER; - med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize); - med->v2 = getFaceIndex(ss, f, k, y + 1, x, - edgeSize, gridSize); - *origIndex = ORIGINDEX_NONE; - ++med; - ++origIndex; - i++; - } - } - } - } - - for(index = 0; index < totedge; index++) { - CCGEdge *e = edgeMap2[index]; - unsigned int flags = 0; - char bweight = 0; - int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); - - if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; - - - if(edgeIdx != -1 && dm) { - MEdge origMed; - dm->getEdge(dm, edgeIdx, &origMed); - - flags |= origMed.flag; - bweight = origMed.bweight; - } - - for(x = 0; x < edgeSize - 1; x++) { - med->v1 = getEdgeIndex(ss, e, x, edgeSize); - med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize); - med->flag = flags; - med->bweight = bweight; - *origIndex = ccgDM_getEdgeMapIndex(ss, e); - ++med; - ++origIndex; - i++; - } - } - - // load faces - i = 0; - mf = CDDM_get_tessfaces(result); - origIndex = result->getTessFaceData(result, 0, CD_ORIGINDEX); - - for(index = 0; index < totface; index++) { - CCGFace *f = faceMap2[index]; - int numVerts = ccgSubSurf_getFaceNumVerts(f); - int mat_nr; - int flag; - int mapIndex = ccgDM_getFaceMapIndex(ss, f); - int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); - - if(!ssFromEditmesh) { - MFace origMFace; - dm->getTessFace(dm, faceIdx, &origMFace); - - mat_nr = origMFace.mat_nr; - flag = origMFace.flag; - } else { - BMFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f); - mat_nr = ef->mat_nr; - flag = BMFlags_To_MEFlags(ef); - } - - for(S = 0; S < numVerts; S++) { - FaceVertWeight *weight = 0;//get_ss_weights(&wtable, gridFaces-1, numVerts); - - for(y = 0; y < gridFaces; y++) { - for(x = 0; x < gridFaces; x++) { - mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, - edgeSize, gridSize); - mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, - edgeSize, gridSize); - mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, - edgeSize, gridSize); - mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, - edgeSize, gridSize); - mf->mat_nr = mat_nr; - mf->flag = flag; -#if 0 //BMESH_TODO - if(dm) { - int prevS = (S - 1 + numVerts) % numVerts; - int nextS = (S + 1) % numVerts; - int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; - FaceVertWeight w; - - for(j = 0; j < 4; ++j) { - w[j][prevS] = (*weight)[j][0]; - w[j][S] = (*weight)[j][1]; - w[j][nextS] = (*weight)[j][2]; - w[j][otherS] = (*weight)[j][3]; - } - - DM_interp_tessface_data(dm, result, &faceIdx, NULL, - &w, 1, i); - weight++; - } -#endif - - *origIndex = mapIndex; - ++mf; - ++origIndex; - i++; - } - } - } - } - - MEM_freeN(faceMap2); - MEM_freeN(edgeMap2); - MEM_freeN(vertMap2); - - free_ss_weights(&wtable); - - BLI_array_free(vertIdx); - - if(useSubsurfUv) { - CustomData *fdata = &result->faceData; - CustomData *dmfdata = &dm->faceData; - int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE); - int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE); - - for (i=0; ilen); + mul_v3_fl(cent, 1.0f/(float)source->len); for (i=0; ilen; i++) { float vec[3]; sub_v3_v3v3(vec, cent, cos[i]); diff --git a/source/blender/bmesh/operators/mesh_conv.c b/source/blender/bmesh/operators/mesh_conv.c index a137cf8394a..999da40a845 100644 --- a/source/blender/bmesh/operators/mesh_conv.c +++ b/source/blender/bmesh/operators/mesh_conv.c @@ -240,7 +240,8 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) { } BLI_array_free(fedges); - + BLI_array_free(verts); + MEM_freeN(vt); MEM_freeN(et); } diff --git a/source/blender/editors/mesh/editbmesh_add.c b/source/blender/editors/mesh/editbmesh_add.c index de4be3b72dd..5c53d8fc391 100644 --- a/source/blender/editors/mesh/editbmesh_add.c +++ b/source/blender/editors/mesh/editbmesh_add.c @@ -125,7 +125,7 @@ static float new_primitive_matrix(bContext *C, float *loc, float *rot, float pri /* ********* add primitive operators ************* */ static void make_prim_init(bContext *C, float *dia, float mat[][4], - int *state, float *loc, float *rot, int layer) + int *state, float *loc, float *rot, unsigned int layer) { Object *obedit= CTX_data_edit_object(C); @@ -164,7 +164,7 @@ static int add_primitive_plane_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -209,7 +209,7 @@ static int add_primitive_cube_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -292,7 +292,7 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -344,7 +344,7 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -396,7 +396,7 @@ static int add_primitive_grid_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -449,7 +449,7 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -493,7 +493,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); @@ -544,7 +544,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state; - int layer; + unsigned int layer; ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer); make_prim_init(C, &dia, mat, &state, loc, rot, layer); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 72eb72e19f0..44c14e2db85 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -2889,7 +2889,8 @@ static void project_paint_begin(ProjPaintState *ps) } /* when using subsurf or multires, mface arrays are thrown away, we need to keep a copy */ - if(ps->dm->type != DM_TYPE_CDDM) { + // this seems like a bad check, since some constructive modifiers use cddm? - joeedh + if(1) { //ps->dm->type != DM_TYPE_CDDM) { ps->dm_mvert= MEM_dupallocN(ps->dm_mvert); ps->dm_mface= MEM_dupallocN(ps->dm_mface); /* looks like these are ok for now.*/ @@ -3375,7 +3376,8 @@ static void project_paint_end(ProjPaintState *ps) } /* copy for subsurf/multires, so throw away */ - if(ps->dm->type != DM_TYPE_CDDM) { + // this seems like a bad check, since some constructive modifiers use cddm? - joeedh + if(1) { //ps->dm->type != DM_TYPE_CDDM) { if(ps->dm_mvert) MEM_freeN(ps->dm_mvert); if(ps->dm_mface) MEM_freeN(ps->dm_mface); /* looks like these dont need copying */ diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index e55e6ba33e9..ca486d60be3 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2637,6 +2637,8 @@ void flushTransUVs(TransInfo *t) /* flush to 2d vector from internally used 3d vector */ for(a=0, td= t->data2d; atotal; a++, td++) { + if (!td->loc2d) continue; + td->loc2d[0]= td->loc[0]*invx; td->loc2d[1]= td->loc[1]*invy; diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h index 28840d55efc..e5d37c5e43e 100644 --- a/source/blender/makesdna/DNA_modifier_types.h +++ b/source/blender/makesdna/DNA_modifier_types.h @@ -73,6 +73,7 @@ typedef enum ModifierType { /* placeholder, keep this so durian files load in * trunk with the correct modifier once its merged */ eModifierType_Warp, + eModifierType_NgonInterp, NUM_MODIFIER_TYPES } ModifierType; @@ -731,4 +732,10 @@ typedef struct ScrewModifierData { // #define MOD_SCREW_OBJECT_ANGLE (1<<4) +typedef struct NgonInterpModifierData { + ModifierData modifier; + int resolution, pad0; +} NgonInterpModifierData; + + #endif diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 03e5b744bc5..f37598743c1 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -85,6 +85,7 @@ EnumPropertyItem modifier_type_items[] ={ {eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""}, {eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""}, {eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""}, + {eModifierType_NgonInterp, "NGONINTERP", ICON_MOD_LATTICE, "Precision UV Interpolation", ""}, {0, NULL, 0, NULL, NULL}}; #ifdef RNA_RUNTIME @@ -169,6 +170,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr) return &RNA_MultiresModifier; case eModifierType_Surface: return &RNA_SurfaceModifier; + case eModifierType_NgonInterp: + return &RNA_NgonInterpModifier; case eModifierType_Smoke: return &RNA_SmokeModifier; case eModifierType_Solidify: @@ -2269,6 +2272,25 @@ static void rna_def_modifier_screw(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Modifier_update");*/ } + + +static void rna_def_modifier_ngoninterp(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna= RNA_def_struct(brna, "NgonInterpModifier", "Modifier"); + RNA_def_struct_ui_text(srna, "Precision UV Modifier", "Precision UV interpolation"); + RNA_def_struct_sdna(srna, "NgonInterpModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_SCREW); + + prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED); + RNA_def_property_range(prop, 1, 10000); + RNA_def_property_ui_range(prop, 1, 100, 1, 0); + RNA_def_property_ui_text(prop, "Resolution", "Size of interpolation grids"); + RNA_def_property_update(prop, 0, "rna_Modifier_update"); + +} void RNA_def_modifier(BlenderRNA *brna) { StructRNA *srna; @@ -2365,6 +2387,7 @@ void RNA_def_modifier(BlenderRNA *brna) rna_def_modifier_smoke(brna); rna_def_modifier_solidify(brna); rna_def_modifier_screw(brna); + rna_def_modifier_ngoninterp(brna); } #endif diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index 0352aa8c05f..4a02306b443 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRC intern/MOD_meshdeform.c intern/MOD_mirror.c intern/MOD_multires.c + intern/MOD_ngoninterp.c intern/MOD_none.c intern/MOD_particleinstance.c intern/MOD_particlesystem.c diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index 8486e2b5d29..44d06e3ef47 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -71,6 +71,7 @@ extern ModifierTypeInfo modifierType_Smoke; extern ModifierTypeInfo modifierType_ShapeKey; extern ModifierTypeInfo modifierType_Solidify; extern ModifierTypeInfo modifierType_Screw; +extern ModifierTypeInfo modifierType_NgonInterp; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index eceb1e356dc..31c7bd684b7 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -193,7 +193,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, ml->e += dm->numEdgeData; } - CDDM_recalc_tesselation(cddm); + CDDM_recalc_tesselation(cddm, 1); /*handle vgroup stuff*/ if ((mmd->flag & MOD_MIR_VGROUP) && CustomData_has_layer(&cddm->vertData, CD_MDEFORMVERT)) { diff --git a/source/blender/modifiers/intern/MOD_ngoninterp.c b/source/blender/modifiers/intern/MOD_ngoninterp.c new file mode 100644 index 00000000000..cdb6f2e7eda --- /dev/null +++ b/source/blender/modifiers/intern/MOD_ngoninterp.c @@ -0,0 +1,322 @@ +/* +* $Id: MOD_mask.c 35213 2011-02-27 06:19:40Z joeedh $ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2005 by the Blender Foundation. +* All rights reserved. +* +* Contributor(s): Daniel Dunbar +* Ton Roosendaal, +* Ben Batt, +* Brecht Van Lommel, +* Campbell Barton +* +* ***** END GPL LICENSE BLOCK ***** +* +*/ + +/** \file blender/modifiers/intern/MOD_mask.c + * \ingroup modifiers + */ + + +#include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_array.h" +#include "BLI_smallhash.h" +#include "BLI_edgehash.h" +#include "BLI_math.h" + +#include "DNA_armature_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BKE_cdderivedmesh.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_deform.h" + +#include "depsgraph_private.h" + +#include "MOD_util.h" + +static void copyData(ModifierData *md, ModifierData *target) +{ + NgonInterpModifierData *mmd = (NgonInterpModifierData*) md; + NgonInterpModifierData *tmmd = (NgonInterpModifierData*) target; + + tmmd->resolution = mmd->resolution; +} + +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *derivedData, + int UNUSED(useRenderParams), + int UNUSED(isFinalCalc)) +{ + NgonInterpModifierData *nmd= (MaskModifierData *)md; + DerivedMesh *dm= derivedData, *result= NULL; + DerivedMesh *cddm, *dummy; + MFace *mf; + MPoly *mpoly; + MLoop *mloop; + MFace *mface = NULL, *mf2; + MVert *mvert = NULL, *mv2, *omvert; + BLI_array_declare(mface); + BLI_array_declare(mvert); + int *verts=NULL, *loops=NULL; + BLI_array_declare(verts); + BLI_array_declare(loops); + float *w = NULL, (*cos)[3] = NULL; + BLI_array_declare(w); + BLI_array_declare(cos); + int *origv = NULL, *origf = NULL, *of, *ov; + BLI_array_declare(origv); + BLI_array_declare(origf); + int i; + + if (nmd->resolution <= 0) + return dm; + + CDDM_recalc_tesselation(dm, 0); + + mf = dm->getTessFaceArray(dm); + of = dm->getTessFaceDataArray(dm, CD_ORIGINDEX); + mpoly = CDDM_get_polys(dm); + mloop = CDDM_get_loops(dm); + + /*eek!*/ + if (!of) + return dm; + + /*create a dummy mesh to compute interpolated loops on*/ + dummy = CDDM_from_template(dm, 0, 0, 0, 3, 0); + + /*copy original verts here, so indices stay correct*/ + omvert = dm->getVertArray(dm); + ov = dm->getVertDataArray(dm, CD_ORIGINDEX); + for (i=0; inumVertData; i++) { + BLI_array_append(mvert, omvert[i]); + BLI_array_append(origv, ov ? ov[i] : i); + } + + for (i=0; inumFaceData; i++, mf++, of++) { + int x, y, x2; + float fac; + + BLI_array_empty(verts); + +#define NG_MAKE_VERT(orig)\ + BLI_array_append(mvert, omvert[orig]);\ + BLI_array_append(origv, ov ? ov[orig] : orig);\ + BLI_array_append(verts, BLI_array_count(mvert)-1); + +#define NG_MAKE_VERTCO(orig, coord) NG_MAKE_VERT(orig); copy_v3_v3(mvert[BLI_array_count(mvert)-1].co, coord) + + y = 0; + fac = 1.0f / (float)(nmd->resolution + 1); + for (x=0; xresolution+2; x++) { + float co1[3], co2[3], co3[3]; + + sub_v3_v3v3(co1, omvert[mf->v1].co, omvert[mf->v3].co); + sub_v3_v3v3(co2, omvert[mf->v2].co, omvert[mf->v3].co); + + mul_v3_fl(co1, 1.0 - fac*x); + mul_v3_fl(co2, 1.0 - fac*x); + + add_v3_v3(co1, omvert[mf->v3].co); + add_v3_v3(co2, omvert[mf->v3].co); + + if (x == 0) { + BLI_array_append(verts, mf->v1); + } else if (x == nmd->resolution+1) { + BLI_array_append(verts, mf->v3); + } else { + NG_MAKE_VERTCO(mf->v1, co1); + } + + for (x2=0; x2<(nmd->resolution-x); x2++) { + sub_v3_v3v3(co3, co1, co2); + mul_v3_fl(co3, 1.0 - (1.0f/(float)(nmd->resolution-x+1))*(x2+1)); + add_v3_v3(co3, co2); + + NG_MAKE_VERTCO(mf->v2, co3); + } + + if (x == 0) { + BLI_array_append(verts, mf->v2); + } else if (x != nmd->resolution+1) { + NG_MAKE_VERTCO(mf->v1, co2); + } + } + + y = 0; + for (x=0; xresolution-y+1) { + x2 = 0; + y++; + continue; + } else { + float co[3]; + int lindex[3] = {0, 1, 2}; + + v1 = verts[x]; + v2 = verts[x+1]; + v3 = verts[x+(nmd->resolution-y)+2]; + + BLI_array_growone(mface); + BLI_array_growone(origf); + + /*make first face*/ + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = v1; + mf2->v2 = v2; + mf2->v3 = v3; + mf2->v4 = 0; + + if (x2 != nmd->resolution-y) { + /*make second face*/ + BLI_array_growone(mface); + BLI_array_growone(origf); + + origf[BLI_array_count(origf)-1] = *of; + mf2 = mface + BLI_array_count(mface)-1; + *mf2 = *mf; + + mf2->v1 = verts[x+(nmd->resolution-y)+3]; + mf2->v2 = v3; + mf2->v3 = v2; + mf2->v4 = 0; + } + } + + x2++; + } + } + + cddm = CDDM_from_template(dm, BLI_array_count(mvert), dm->numEdgeData, BLI_array_count(mface), 0, 0); + + mf2 = mface; + for (i=0; iloopstart; + for (j=0; jtotloop; j++, ml++) { + BLI_array_growone(cos); + BLI_array_growone(w); + BLI_array_append(loops, j+mp->loopstart); + copy_v3_v3(cos[j], mvert[ml->v].co); + } + + /*scale source face coordinates a bit, so points sitting directly on an + edge will work.*/ + mul_v3_fl(cent, 1.0/(float)(mp->totloop)); + for (j=0; jtotloop; j++) { + float vec[3]; + + sub_v3_v3v3(vec, cent, cos[j]); + mul_v3_fl(vec, 0.000001); + add_v3_v3(cos[j], vec); + } + + copy_v3_v3(co, mvert + mf2->v1); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 0); + + copy_v3_v3(co, mvert + mf2->v2); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 1); + + copy_v3_v3(co, mvert + mf2->v3); + interp_weights_poly_v3(w, cos, mp->totloop, co); + CustomData_interp(&dm->loopData, &dummy->loopData, loops, w, NULL, mp->totloop, 2); + + mesh_loops_to_tri_corners(&cddm->faceData, &dummy->loopData, &dm->polyData, lindex, i, origf[i]); + } + + CustomData_copy_data(&dm->vertData, &cddm->vertData, 0, 0, dm->numVertData); + CustomData_copy_data(&dm->edgeData, &cddm->edgeData, 0, 0, dm->numEdgeData); + + CDDM_set_mface(cddm, mface); + CDDM_set_mvert(cddm, mvert); + + /*set origindex pointer*/ + MEM_freeN(CustomData_get_layer(&cddm->faceData, CD_ORIGINDEX)); + CustomData_set_layer(&cddm->faceData, CD_MFACE, mface); + + if (CustomData_has_layer(&cddm->vertData, CD_ORIGINDEX)) + CustomData_set_layer(&cddm->vertData, CD_ORIGINDEX, origv); + + CustomData_set_layer(&cddm->faceData, CD_ORIGINDEX, origf); + + BLI_array_free(cos); + BLI_array_free(w); + + dummy->needsFree = 1; + dummy->release(dummy); + + /*create polys from mface triangles*/ + dummy = cddm; + cddm = CDDM_copy(cddm, 1); + dummy->needsFree = 1; + dummy->release(dummy); + + return cddm; +} + + +ModifierTypeInfo modifierType_NgonInterp = { + /* name */ "NgonInterp", + /* structName */ "NgonInterpModifierData", + /* structSize */ sizeof(NgonInterpModifierData), + /* type */ eModifierTypeType_Constructive, + /* flags */ eModifierTypeFlag_AcceptsMesh|eModifierTypeFlag_SupportsMapping|eModifierTypeFlag_SupportsEditmode, + + /* copyData */ copyData, + /* deformVerts */ 0, + /* deformMatrices */ 0, + /* deformVertsEM */ 0, + /* deformMatricesEM */ 0, + /* applyModifier */ applyModifier, + /* applyModifierEM */ 0, + /* initData */ 0, + /* requiredDataMask */ 0, + /* freeData */ 0, + /* isDisabled */ 0, + /* updateDepgraph */ 0, + /* dependsOnTime */ 0, + /* dependsOnNormals */ 0, + /* foreachObjectLink */ 0, + /* foreachIDLink */ 0, +}; + diff --git a/source/blender/modifiers/intern/MOD_util.c b/source/blender/modifiers/intern/MOD_util.c index 35571cd8e76..b3baf15ae29 100644 --- a/source/blender/modifiers/intern/MOD_util.c +++ b/source/blender/modifiers/intern/MOD_util.c @@ -189,5 +189,6 @@ void modifier_type_init(ModifierTypeInfo *types[]) INIT_TYPE(ShapeKey); INIT_TYPE(Solidify); INIT_TYPE(Screw); + INIT_TYPE(NgonInterp); #undef INIT_TYPE } -- cgit v1.2.3