diff options
author | Joseph Eagar <joeedh@gmail.com> | 2009-08-19 00:05:08 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2009-08-19 00:05:08 +0400 |
commit | f7cef59b3dff4c3094aaae0f54cd8fe35e011748 (patch) | |
tree | 802b2c66b22c37eafcbac2cd7631135cef5e2073 /source/blender | |
parent | 3c7b9347ec6f4cb506e5954433ae5f2a0cde5b3d (diff) |
rearranged some code a bit
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 94 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 10 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/editderivedbmesh.c | 82 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifiers_bmesh.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 212 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh.h | 27 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh_operator_api.h | 4 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_select.c | 553 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_mods.c | 646 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_snap.c | 4 |
12 files changed, 867 insertions, 782 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 2c7348873be..f11d7824db6 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -162,12 +162,13 @@ void CustomData_set_only_copy(const struct CustomData *data, void CustomData_copy_data(const struct CustomData *source, struct CustomData *dest, int source_index, int dest_index, int count); +void CustomData_copy_elements(int type, void *source, void *dest, int count); void CustomData_em_copy_data(const struct CustomData *source, struct CustomData *dest, void *src_block, void **dest_block); void CustomData_bmesh_copy_data(const struct CustomData *source, - struct CustomData *dest,void *src_block, - void **dest_block); + struct CustomData *dest, void *src_block, + void **dest_block); /* frees data in a CustomData object * return 1 on success, 0 on failure diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index eadb4e566ce..ca6dc9407ff 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -282,27 +282,75 @@ void dm_add_polys_from_iter(CustomData *ldata, CustomData *pdata, DerivedMesh *d { DMFaceIter *iter = dm->newFaceIter(dm); DMLoopIter *liter; + CustomData *oldata, *opdata; MPoly *mpoly; MLoop *mloop; - int i; + int l, i, j, lasttype; + + oldata = dm->getLoopDataLayout(dm); + opdata = dm->getFaceDataLayout(dm); + + CustomData_copy(oldata, ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, totloop); + CustomData_copy(opdata, pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, dm->getNumFaces(dm)); mloop = MEM_callocN(sizeof(MLoop)*totloop, "MLoop from dm_add_polys_from_iter"); - mpoly = MEM_callocN(sizeof(MPoly)*dm->getNumFaces(dm), "MPoly from dm_add_polys_from_iter"); - CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop); + mpoly = MEM_callocN(sizeof(MPoly)*dm->getNumFaces(dm), "MPoly from dm_add_polys_from_iter"); CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, dm->getNumFaces(dm)); - i = 0; + l = 0; for (; !iter->done; iter->step(iter), mpoly++) { mpoly->flag = iter->flags; - mpoly->loopstart = i; + mpoly->loopstart = l; mpoly->totloop = iter->len; mpoly->mat_nr = iter->mat_nr; + j = 0; + lasttype = -1; + for (i=0; i<opdata->totlayer; i++) { + void *e1, *e2; + + if (opdata->layers[i].type == CD_MPOLY) + continue; + + e1 = iter->getCDData(iter, opdata->layers[i].type, j); + e2 = CustomData_get_layer_n(pdata, opdata->layers[i].type, j); + + CustomData_copy_elements(opdata->layers[i].type, e1, e2, 1); + + if (opdata->layers[i].type == lasttype) + j++; + else + j = 0; + + lasttype = opdata->layers[i].type; + } + liter = iter->getLoopsIter(iter); - for (; !liter->done; liter->step(liter), mloop++, i++) { + for (; !liter->done; liter->step(liter), mloop++, l++) { mloop->v = liter->vindex; mloop->e = liter->eindex; + + j = 0; + lasttype = -1; + for (i=0; i<oldata->totlayer; i++) { + void *e1, *e2; + + if (oldata->layers[i].type == CD_MLOOP) + continue; + + e1 = liter->getLoopCDData(liter, oldata->layers[i].type, j); + e2 = CustomData_get_layer_n(ldata, oldata->layers[i].type, j); + + CustomData_copy_elements(oldata->layers[i].type, e1, e2, 1); + + if (oldata->layers[i].type == lasttype) + j++; + else + j = 0; + + lasttype = oldata->layers[i].type; + } } } iter->free(iter); @@ -312,33 +360,21 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target) { DMFaceIter *iter = source->newFaceIter(source); DMLoopIter *liter; - MPoly *mpoly; - MLoop *mloop; - int i; + int totloop = 0; - mloop = MEM_callocN(sizeof(MLoop)*source->numLoopData, "MLoop from dm_add_polys_from_iter"); - mpoly = MEM_callocN(sizeof(MPoly)*source->getNumFaces(source), "MPoly from dm_add_polys_from_iter"); - - CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData); - CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->getNumFaces(source)); - - target->numLoopData = source->numLoopData; - target->numPolyData = source->numPolyData; - - i = 0; - for (; !iter->done; iter->step(iter), mpoly++) { - mpoly->flag = iter->flags; - mpoly->loopstart = i; - mpoly->totloop = iter->len; - mpoly->mat_nr = iter->mat_nr; - + for (; !iter->done; iter->step(iter)) { liter = iter->getLoopsIter(iter); - for (; !liter->done; liter->step(liter), mloop++, i++) { - mloop->v = liter->vindex; - mloop->e = liter->eindex; + for (; !liter->done; liter->step(liter)) { + totloop++; } } + iter->free(iter); + + dm_add_polys_from_iter(&target->loopData, &target->polyData, source, totloop); + + target->numLoopData = totloop; + target->numPolyData = source->getNumFaces(source); } void DM_to_mesh(DerivedMesh *dm, Mesh *me) @@ -1044,7 +1080,7 @@ static void emDM_drawFacesTex_common(void *dm, } } -static void emDM_drawFacesTex(void *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) +static void emDM_drawFacesTex(void *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr)) { emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 61355c4265e..0f7ebc05558 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1311,7 +1311,7 @@ void *cddm_faceiter_getcddata(void *self, int type, int layer) void *cddm_loopiter_getcddata(void *self, int type, int layer) { - CDDM_FaceIter *iter = self; + CDDM_LoopIter *iter = self; if (layer == -1) return CustomData_get(&iter->cddm->dm.loopData, iter->head.index, type); @@ -1321,13 +1321,13 @@ void *cddm_loopiter_getcddata(void *self, int type, int layer) void *cddm_loopiter_getvertcddata(void *self, int type, int layer) { - CDDM_FaceIter *iter = self; + CDDM_LoopIter *iter = self; if (layer == -1) return CustomData_get(&iter->cddm->dm.vertData, - iter->cddm->mloop[iter->head.index].v, + iter->cddm->mloop[iter->head.vindex].v, type); else return CustomData_get_n(&iter->cddm->dm.vertData, type, - iter->cddm->mloop[iter->head.index].v, layer); + iter->cddm->mloop[iter->head.vindex].v, layer); } DMLoopIter *cddmiter_get_loopiter(void *self) @@ -1406,8 +1406,6 @@ DerivedMesh *CDDM_copy(DerivedMesh *source) CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges); CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces); - CustomData_copy_data(&source->loopData, &dm->loopData, 0, 0, numLoops); - CustomData_copy_data(&source->polyData, &dm->polyData, 0, 0, numPolys); /* now add mvert/medge/mface layers */ cddm->mvert = source->dupVertArray(source); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 17a822aaee0..72c3e3b0188 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -1465,6 +1465,16 @@ void CustomData_set_only_copy(const struct CustomData *data, data->layers[i].flag |= CD_FLAG_NOCOPY; } +void CustomData_copy_elements(int type, void *source, void *dest, int count) +{ + const LayerTypeInfo *typeInfo = layerType_getInfo(type); + + if (typeInfo->copy) + typeInfo->copy(source, dest, count); + else + memcpy(dest, source, typeInfo->size*count); +} + void CustomData_copy_data(const CustomData *source, CustomData *dest, int source_index, int dest_index, int count) { diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c index c34f5253a42..a17d16ce754 100644 --- a/source/blender/blenkernel/intern/editderivedbmesh.c +++ b/source/blender/blenkernel/intern/editderivedbmesh.c @@ -275,6 +275,9 @@ typedef struct EditDerivedBMesh { /*private variables, for number of verts/edges/faces within the above hash/table members*/ int tv, te, tf; + + /*customdata layout of the tesselated faces*/ + CustomData tessface_layout; } EditDerivedBMesh; static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm) @@ -1312,6 +1315,8 @@ void bmDM_faceIterStep(void *self) iter->head.flags = BMFlags_To_MEFlags(iter->f); iter->head.index++; + iter->head.len = iter->f->len; + iter->nextf = BMIter_Step(&iter->iter); if (!iter->nextf) iter->head.done = 1; @@ -1330,16 +1335,16 @@ void bmDM_loopIterStep(void *self) { bmDM_loopIter *iter = self; - iter->l = iter->nextl; + iter->l = BMIter_Step(&iter->iter); + if (!iter->l) { + iter->head.done = 1; + return; + } bmvert_to_mvert(iter->l->v, &iter->head.v); iter->head.index++; iter->head.vindex = BMINDEX_GET(iter->l->v); iter->head.eindex = BMINDEX_GET(iter->l->e); - - iter->nextl = BMIter_Step(&iter->iter); - - if (!iter->nextl) iter->head.done = 1; } void *bmDM_getLoopCDData(void *self, int type, int layer) @@ -1378,15 +1383,15 @@ DMLoopIter *bmDM_newLoopsIter(void *faceiter) iter->bm = fiter->bm; iter->f = fiter->f; - iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f); + iter->l = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f); iter->head.step = bmDM_loopIterStep; iter->head.getLoopCDData = bmDM_getLoopCDData; iter->head.getVertCDData = bmDM_getVertCDData; - bmvert_to_mvert(iter->nextl->v, &iter->head.v); - iter->head.vindex = BMINDEX_GET(iter->nextl->v); - iter->head.eindex = BMINDEX_GET(iter->nextl->e); + bmvert_to_mvert(iter->l->v, &iter->head.v); + iter->head.vindex = BMINDEX_GET(iter->l->v); + iter->head.eindex = BMINDEX_GET(iter->l->e); return (DMLoopIter*) iter; } @@ -1450,19 +1455,76 @@ static void bmDM_release(void *dm) } } +CustomData *bmDm_getVertDataLayout(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm; + + return &bmdm->tc->bm->vdata; +} + +CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm; + + return &bmdm->tc->bm->edata; +} + +CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm; + + return &bmdm->tessface_layout; +} + +CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm; + + return &bmdm->tc->bm->ldata; +} + +CustomData *bmDm_getFaceDataLayout(DerivedMesh *dm) +{ + EditDerivedBMesh *bmdm = (EditDerivedBMesh*)dm; + + return &bmdm->tc->bm->pdata; +} + + DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob, float (*vertexCos)[3]) { EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm"); BMesh *bm = em->bm; - + int i; + bmdm->tc = em; DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri, em->bm->totloop, em->bm->totface); + + for (i=0; i<bm->ldata.totlayer; i++) { + if (bm->ldata.layers[i].type == CD_MLOOPCOL) { + CustomData_add_layer(&bmdm->tessface_layout, CD_MCOL, CD_ASSIGN, NULL, 0); + } else if (bm->ldata.layers[i].type == CD_MLOOPUV) { + CustomData_add_layer(&bmdm->tessface_layout, CD_MTFACE, CD_ASSIGN, NULL, 0); + } + } + + bmdm->dm.numVertData = bm->totvert; + bmdm->dm.numEdgeData = bm->totedge; + bmdm->dm.numFaceData = em->tottri; + bmdm->dm.numLoopData = bm->totloop; + bmdm->dm.numPolyData = bm->totface; bmdm->dm.getMinMax = bmDM_getMinMax; + bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout; + bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout; + bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout; + bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout; + bmdm->dm.getFaceDataLayout = bmDm_getFaceDataLayout; + bmdm->dm.getNumVerts = bmDM_getNumVerts; bmdm->dm.getNumEdges = bmDM_getNumEdges; bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces; diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index 33ca50bfe85..f69e0efcea6 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -605,7 +605,7 @@ DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd, BMO_Finish_Op(bm, &op); BMEdit_RecalcTesselation(em); - result = CDDM_from_BMEditMesh(em, NULL); + result = CDDM_from_BMEditMesh(em, NULL); //CDDM_copy(getEditDerivedBMesh(em, ob, NULL)); BMEdit_Free(em); MEM_freeN(em); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 93efaf87c96..ba53bbe7767 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -91,6 +91,10 @@ typedef struct CCGDerivedMesh CCGDerivedMesh; static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v); static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e); static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f); +static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, + int drawInteriorEdges, + int useSubsurfUv, + DerivedMesh *dm); /// @@ -177,6 +181,7 @@ static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) { return edgeBase + x-1; } } + static int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) { int faceBase = *((int*) CCS_getFaceUserData(ss, f)); int numVerts = CCS_getFaceNumVerts(f); @@ -573,6 +578,15 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm, MultiresSubsurf *ms) { + DerivedMesh *cgdm, *result; + + cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); + result = CDDM_copy(cgdm); + cgdm->needsFree = 1; + cgdm->release(cgdm); + + return result; +#if 0 DerivedMesh *result; int edgeSize = CCS_getEdgeSize(ss); int gridSize = CCS_getGridSize(ss); @@ -948,6 +962,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, V_FREE(w); return result; +#endif } static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm, @@ -1455,6 +1470,7 @@ typedef struct cgdm_faceIter { MFace mface; cgdm_loopIter liter; + EdgeHash *ehash; /*edge map for populating loopiter->eindex*/ } cgdm_faceIter; void cgdm_faceIterStep(void *self) @@ -1494,7 +1510,7 @@ void cgdm_loopIterStep(void *self) { cgdm_loopIter *liter = self; MFace *mf = &liter->fiter->mface; - int i, in; + int i, v1, v2; if (liter->head.index >= liter->fiter->head.len) { liter->head.done = 1; @@ -1506,23 +1522,27 @@ void cgdm_loopIterStep(void *self) switch (i) { case 0: - in = liter->fiter->mface.v1; + v1 = liter->fiter->mface.v1; + v2 = liter->fiter->mface.v2; break; case 1: - in = liter->fiter->mface.v2; + v1 = liter->fiter->mface.v2; + v2 = liter->fiter->mface.v3; break; case 2: - in = liter->fiter->mface.v3; + v1 = liter->fiter->mface.v3; + v2 = liter->fiter->mface.v4; break; case 3: - in = liter->fiter->mface.v4; + v1 = liter->fiter->mface.v4; + v2 = liter->fiter->mface.v1; break; } - liter->head.vindex = in; - - /*we don't set .eindex*/ - cgdm_getFinalVert((DerivedMesh*)liter->cgdm, in, &liter->head.v); + liter->head.vindex = v1; + liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->ehash, v1, v2)); + + cgdm_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v); } void *cgdm_loopIterGetVCData(void *self, int type, int layer) @@ -1554,11 +1574,27 @@ DMLoopIter *cgdm_faceIterGetLIter(void *self) return (DMLoopIter*) &fiter->liter; } +void cgdm_faceIterFree(void *vfiter) +{ + cgdm_faceIter *fiter = vfiter; + BLI_edgehash_free(fiter->ehash, NULL); + MEM_freeN(fiter); +} + DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm) { cgdm_faceIter *fiter = MEM_callocN(sizeof(cgdm_faceIter), "cgdm_faceIter"); + MEdge medge; + int i, totedge = cgdm_getNumEdges(dm); + + fiter->ehash = BLI_edgehash_new(); - fiter->head.free = MEM_freeN; + for (i=0; i<totedge; i++) { + cgdm_getFinalEdge(dm, i, &medge); + BLI_edgehash_insert(fiter->ehash, medge.v1, medge.v2, SET_INT_IN_POINTER(i)); + } + + fiter->head.free = cgdm_faceIterFree; fiter->head.step = cgdm_faceIterStep; fiter->head.index = -1; fiter->head.getCDData = cgdm_faceIterCData; @@ -2174,7 +2210,7 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha } static void cgdm_drawFacesTex_common(DerivedMesh *dm, - int (*drawParams)(MTFace *tface, MCol *mcol, int matnr), + int (*drawParams)(MTFace *tface, int has_vcol, int matnr), int (*drawParamsMapped)(void *userData, int index), void *userData) { @@ -2205,7 +2241,7 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm, } if(drawParams) - flag = drawParams(tf, mcol, mat_nr); + flag = drawParams(tf, mcol!=NULL, mat_nr); else flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1; @@ -2305,7 +2341,7 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm, } } -static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr)) +static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr)) { cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL); } @@ -2578,8 +2614,9 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex; /* *edgeOrigIndex - as yet, unused */ int *edgeFlags; char *faceFlags, *polyFlags; - int *loopidx = NULL; + int *loopidx = NULL, *vertidx = NULL; V_DECLARE(loopidx); + V_DECLARE(vertidx); int loopindex, loopindex2; int edgeSize; int gridSize; @@ -2591,8 +2628,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, int gridInternalEdges; int index2; float *w = NULL; - DMFaceIter *dfiter, *dfiter2; - DMLoopIter *dliter, *dliter2; WeightTable wtable = {0}; V_DECLARE(w); /* MVert *mvert = NULL; - as yet unused */ @@ -2732,52 +2767,82 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, mcol = DM_get_tessface_data_layer(&cgdm->dm, CD_MCOL); index2 = 0; - dfiter = dm->newFaceIter(dm); - dfiter2 = cgdm->dm.newFaceIter(cgdm); loopindex = loopindex2 = 0; //current loop index - for (index = 0; index < totface; index++, dfiter->step(dfiter)) { + for (index = 0; index < totface; index++) { CCFace *f = cgdm->faceMap[index].face; int numVerts = CCS_getFaceNumVerts(f); int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges); int mapIndex = cgdm_getFaceMapIndex(ss, f); int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); int g2_wid = gridCuts+2; + float *w2; int s, x, y; + w = get_ss_weights(&wtable, gridCuts, numVerts); + cgdm->faceMap[index].startVert = vertNum; cgdm->faceMap[index].startEdge = edgeNum; - cgdm->faceMap[index].startFace = faceNum; - - V_RESET(w); + cgdm->faceMap[index].startFace = index2; + V_RESET(loopidx); - + for (s=0; s<numVerts; s++) { V_GROW(loopidx); loopidx[s] = loopindex++; } + + V_RESET(vertidx); + for(s = 0; s < numVerts; s++) { + CCVert *v = CCS_getFaceVert(ss, f, s); + + V_GROW(vertidx); + vertidx[s] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + } + - w = get_ss_weights(&wtable, gridCuts, numVerts); + w2 = w + s*numVerts*g2_wid*g2_wid; + DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, + numVerts, vertNum); + if (vertOrigIndex) + *vertOrigIndex = ORIGINDEX_NONE; + ++vertOrigIndex; + ++vertNum; - /* set the face base vert */ - *((int*)CCS_getFaceUserData(ss, f)) = vertNum; - for (s=0; s<numVerts; s++) { - int x1, y1; + /*interpolate per-vert data*/ + for(s = 0; s < numVerts; s++) { + for(x = 1; x < gridFaces; x++) { + w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts; + DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, + numVerts, vertNum); - for (y1=0; y1<gridFaces; y1++) { - for (x1=0; x1<gridFaces; x1++) { - float *w2; + if (vertOrigIndex) + *vertOrigIndex = ORIGINDEX_NONE; + ++vertOrigIndex; + ++vertNum; + } + } - x = x1; //gridFaces - x1 - 1; - y = y1; //gridFaces - y1 - 1; - //for (i=0; i<4; i++) { - /*float f1, f2; - f1 = (float)x / ((float)gridFaces-1.0f); - f2 = (float)y / ((float)gridFaces-1.0f); + for(s = 0; s < numVerts; s++) { + for(y = 1; y < gridFaces; y++) { + for(x = 1; x < gridFaces; x++) { + w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts; + DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, + numVerts, vertNum); - mcol->r = f1*255.0f; - mcol->g = f2*255.0f; - mcol->b = 0;*/ + if (vertOrigIndex) + *vertOrigIndex = ORIGINDEX_NONE; + ++vertOrigIndex; + ++vertNum; + } + } + } + /* set the face base vert */ + *((int*)CCS_getFaceUserData(ss, f)) = vertNum; + for (s=0; s<numVerts; s++) { + /*interpolate per-face data*/ + for (y=0; y<gridFaces; y++) { + for (x=0; x<gridFaces; x++) { w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts; CustomData_interp(&dm->loopData, &cgdm->dm.loopData, loopidx, w2, NULL, numVerts, loopindex2); @@ -2798,9 +2863,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, loopidx, w2, NULL, numVerts, loopindex2); loopindex2++; - //} + /*copy over poly data, e.g. mtexpoly*/ CustomData_interp(&dm->polyData, &cgdm->dm.polyData, &origIndex, w, NULL, 1, index2); + /*generate tesselated face data used for drawing*/ ccg_loops_to_corners(&cgdm->dm.faceData, &cgdm->dm.loopData, &cgdm->dm.polyData, loopindex2-4, index2, index2, numTex, numCol); @@ -2808,6 +2874,69 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, } } } + + edgeNum += numFinalEdges; + } + + for(index = 0; index < totvert; ++index) { + CCVert *v = cgdm->vertMap[index].vert; + int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v); + int vidx; + + vidx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + + cgdm->vertMap[index].startVert = vertNum; + + /* set the vert base vert */ + *((int*) CCS_getVertUserData(ss, v)) = vertNum; + + DM_copy_vert_data(dm, &cgdm->dm, vidx, vertNum, 1); + + *vertOrigIndex = mapIndex; + ++vertOrigIndex; + ++vertNum; + } + + edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS); + for(index = 0; index < totedge; ++index) { + CCEdge *e = cgdm->edgeMap[index].edge; + int numFinalEdges = edgeSize - 1; + int mapIndex = cgdm_getEdgeMapIndex(ss, e); + int x; + int vertIdx[2]; + int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e)); + + CCVert *v; + v = CCS_getEdgeVert0(e); + vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + v = CCS_getEdgeVert1(e); + vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + + cgdm->edgeMap[index].startVert = vertNum; + cgdm->edgeMap[index].startEdge = edgeNum; + + /* set the edge base vert */ + *((int*)CCS_getEdgeUserData(ss, e)) = vertNum; + + for(x = 1; x < edgeSize - 1; x++) { + float w[2]; + w[1] = (float) x / (edgeSize - 1); + w[0] = 1 - w[1]; + DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum); + *vertOrigIndex = ORIGINDEX_NONE; + ++vertOrigIndex; + ++vertNum; + } + + for(i = 0; i < numFinalEdges; ++i) { + if(edgeIdx >= 0 && edgeFlags) + edgeFlags[edgeNum + i] = medge[edgeIdx].flag; + + *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, + CD_ORIGINDEX) = mapIndex; + } + + edgeNum += numFinalEdges; } #if 0 for(index = 0; index < totface; ++index) { @@ -2838,7 +2967,6 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, ++vertOrigIndex; ++vertNum; - for(S = 0; S < numVerts; S++) { int prevS = (S - 1 + numVerts) % numVerts; int nextS = (S + 1) % numVerts; diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index f9fddac6e57..e3518e77477 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -95,9 +95,9 @@ struct EditMesh; /*BMHeader->type*/ #define BM_VERT 1 #define BM_EDGE 2 -#define BM_FACE 4 -#define BM_LOOP 8 -#define BM_ALL (BM_VERT | BM_EDGE | BM_FACE | BM_LOOP) +#define BM_LOOP 4 +#define BM_FACE 8 +#define BM_ALL (BM_VERT | BM_EDGE | BM_LOOP | BM_FACE) /*BMHeader->flag*/ #define BM_SELECT (1<<0) @@ -117,14 +117,15 @@ typedef struct BMHeader { /*don't confuse this with tool flags. this flag member is what "header flag" means.*/ int flag; - int type; + int type; /*the element type, can be BM_VERT, BM_EDGE, BM_LOOP, or BM_FACE*/ int eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/ - //this can only be used to store a temporary index. don't use it for anything else. - //use the BMINDEX_GET and BMINDEX_SET macros!! + /*this is only used to store temporary integers. + don't use it for anything else. + use the BMINDEX_GET and BMINDEX_SET macros to access it*/ int index; struct BMFlagLayer *flags; /*Dynamically allocated block of flag layers for operators to use*/ - void *data; /*customdata*/ + void *data; /*customdata block*/ } BMHeader; typedef struct BMFlagLayer { @@ -132,7 +133,7 @@ typedef struct BMFlagLayer { short mask, pflag; } BMFlagLayer; -#define BM_OVERLAP (1<<14) /*used by bmesh_verts_in_face*/ +#define BM_OVERLAP (1<<14) /*used by bmesh_verts_in_face*/ #define BM_EDGEVERT (1<<15) /*used by bmesh_make_ngon*/ /* @@ -182,8 +183,7 @@ typedef struct BMVert { float co[3]; float no[3]; struct BMEdge *edge; - void *tmp; /*what?*/ - float bweight; /*please, someone just get rid of me...*/ + float bweight; /*please, someone just get rid of me...*/ } BMVert; typedef struct BMEdge { @@ -254,12 +254,6 @@ void BM_Face_CopyShared(BMesh *bm, BMFace *f); to another of the same type.*/ void BM_Copy_Attributes(struct BMesh *source_mesh, struct BMesh *target_mesh, void *source, void *target); -/*remove tool flagged elements*/ -void BM_remove_tagged_faces(struct BMesh *bm, int flag); -void BM_remove_tagged_edges(struct BMesh *bm, int flag); -void BM_remove_tagged_verts(struct BMesh *bm, int flag); - - /*Modification*/ /*join two adjacent faces together along an edge. note that the faces must only be joined by on edge. e is the edge you @@ -323,6 +317,7 @@ void BM_free_data_layer(BMesh *em, CustomData *data, int type); /*computes the centroid of a face, using the center of the bounding box*/ int BM_Compute_Face_Center(BMesh *bm, BMFace *f, float center[3]); + void BM_SelectMode_Flush(BMesh *bm); /*convert an editmesh to a bmesh*/ diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h index ce81d2ddd57..de6bbdcdcdf 100644 --- a/source/blender/bmesh/bmesh_operator_api.h +++ b/source/blender/bmesh/bmesh_operator_api.h @@ -195,6 +195,10 @@ BMOpSlot *BMO_GetSlot(struct BMOperator *op, char *slotname); void BMO_CopySlot(struct BMOperator *source_op, struct BMOperator *dest_op, char *src, char *dst); +/*remove tool flagged elements*/ +void BM_remove_tagged_faces(struct BMesh *bm, int flag); +void BM_remove_tagged_edges(struct BMesh *bm, int flag); +void BM_remove_tagged_verts(struct BMesh *bm, int flag); void BMO_Set_Float(struct BMOperator *op, char *slotname, float f); float BMO_Get_Float(BMOperator *op, char *slotname); diff --git a/source/blender/editors/mesh/bmesh_select.c b/source/blender/editors/mesh/bmesh_select.c index 15c9cf68e8f..4a154eb3b6d 100644 --- a/source/blender/editors/mesh/bmesh_select.c +++ b/source/blender/editors/mesh/bmesh_select.c @@ -643,28 +643,26 @@ static int unified_findnearest(ViewContext *vc, BMVert **eve, BMEdge **eed, BMFa return (*eve || *eed || *efa); } - /* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */ -/* selects new faces/edges/verts based on the - existing selection +/* selects new faces/edges/verts based on the existing selection */ -FACES GROUP - mode 1: same material - mode 2: same image - mode 3: same area - mode 4: same perimeter - mode 5: same normal - mode 6: same co-planer -*/ +/* FACES GROUP */ + +#define SIMFACE_MATERIAL 201 +#define SIMFACE_IMAGE 202 +#define SIMFACE_AREA 203 +#define SIMFACE_PERIMETER 204 +#define SIMFACE_NORMAL 205 +#define SIMFACE_COPLANAR 206 static EnumPropertyItem prop_simface_types[] = { - {1, "MATERIAL", 0, "Material", ""}, - {2, "IMAGE", 0, "Image", ""}, - {3, "AREA", 0, "Area", ""}, - {4, "PERIMETER", 0, "Perimeter", ""}, - {5, "NORMAL", 0, "Normal", ""}, - {6, "COPLANAR", 0, "Co-planar", ""}, + {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, + {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, + {SIMFACE_AREA, "AREA", 0, "Area", ""}, + {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, + {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, + {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, {0, NULL, 0, NULL, NULL} }; @@ -673,10 +671,10 @@ static EnumPropertyItem prop_simface_types[] = { *0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */ #define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b)) -static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) +static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode) { -#if 0 //BMESH_TODO - BMFace *efa, *base_efa=NULL; +#if 0 + EditFace *efa, *base_efa=NULL; unsigned int selcount=0; /*count how many new faces we select*/ /*deselcount, count how many deselected faces are left, so we can bail out early @@ -700,12 +698,11 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) if (!ok || !deselcount) /* no data selected OR no more data to select */ return 0; - /*if mode is 3 then record face areas, 4 record perimeter */ - if (mode==3) { + if (mode==SIMFACE_AREA) { for(efa= em->faces.first; efa; efa= efa->next) { efa->tmp.fp= EM_face_area(efa); } - } else if (mode==4) { + } else if (mode==SIMFACE_PERIMETER) { for(efa= em->faces.first; efa; efa= efa->next) { efa->tmp.fp= EM_face_perimeter(efa); } @@ -713,7 +710,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) { if (base_efa->f1) { /* This was one of the faces originaly selected */ - if (mode==1) { /* same material */ + if (mode==SIMFACE_MATERIAL) { /* same material */ for(efa= em->faces.first; efa; efa= efa->next) { if ( !(efa->f & SELECT) && @@ -727,7 +724,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) return selcount; } } - } else if (mode==2) { /* same image */ + } else if (mode==SIMFACE_IMAGE) { /* same image */ MTFace *tf, *base_tf; base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data, @@ -750,7 +747,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) } } } - } else if (mode==3 || mode==4) { /* same area OR same perimeter, both use the same temp var */ + } else if (mode==SIMFACE_AREA || mode==SIMFACE_PERIMETER) { /* same area OR same perimeter, both use the same temp var */ for(efa= em->faces.first; efa; efa= efa->next) { if ( (!(efa->f & SELECT) && !efa->h) && @@ -763,7 +760,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) return selcount; } } - } else if (mode==5) { /* same normal */ + } else if (mode==SIMFACE_NORMAL) { float angle; for(efa= em->faces.first; efa; efa= efa->next) { if (!(efa->f & SELECT) && !efa->h) { @@ -777,7 +774,7 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) } } } - } else if (mode==6) { /* same planer */ + } else if (mode==SIMFACE_COPLANAR) { /* same planer */ float angle, base_dot, dot; base_dot= Inpf(base_efa->cent, base_efa->n); for(efa= em->faces.first; efa; efa= efa->next) { @@ -802,6 +799,506 @@ static int similar_face_select__internal(Scene *scene, BMEditMesh *em, int mode) #endif } +static int similar_face_select_exec(bContext *C, wmOperator *op) +{ +#if 0 + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + Mesh *me= obedit->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + + int selcount = similar_face_select__internal(scene, em, RNA_int_get(op->ptr, "type")); + + if (selcount) { + /* here was an edge-mode only select flush case, has to be generalized */ + EM_selectmode_flush(em); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + BKE_mesh_end_editmesh(me, em); + return OPERATOR_FINISHED; + } + + BKE_mesh_end_editmesh(me, em); +#endif + return OPERATOR_CANCELLED; +} + +/* ***************************************************** */ + +/* EDGE GROUP */ + +#define SIMEDGE_LENGTH 101 +#define SIMEDGE_DIR 102 +#define SIMEDGE_FACE 103 +#define SIMEDGE_FACE_ANGLE 104 +#define SIMEDGE_CREASE 105 +#define SIMEDGE_SEAM 106 +#define SIMEDGE_SHARP 107 + +static EnumPropertyItem prop_simedge_types[] = { + {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, + {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, + {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, + {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, + {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, + {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, + {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, + {0, NULL, 0, NULL, NULL} +}; + +static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode) +{ +#if 0 + EditEdge *eed, *base_eed=NULL; + unsigned int selcount=0; /* count how many new edges we select*/ + + /*count how many visible selected edges there are, + so we can return when there are none left */ + unsigned int deselcount=0; + + short ok=0; + float thresh= scene->toolsettings->select_thresh; + + for(eed= em->edges.first; eed; eed= eed->next) { + if (!eed->h) { + if (eed->f & SELECT) { + eed->f1=1; + ok=1; + } else { + eed->f1=0; + deselcount++; + } + /* set all eed->tmp.l to 0 we use it later. + for counting face users*/ + eed->tmp.l=0; + eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */ + } + } + + if (!ok || !deselcount) /* no data selected OR no more data to select*/ + return 0; + + if (mode==SIMEDGE_LENGTH) { /*store length*/ + for(eed= em->edges.first; eed; eed= eed->next) { + if (!eed->h) /* dont calc data for hidden edges*/ + eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co); + } + } else if (mode==SIMEDGE_FACE) { /*store face users*/ + EditFace *efa; + /* cound how many faces each edge uses use tmp->l */ + for(efa= em->faces.first; efa; efa= efa->next) { + efa->e1->tmp.l++; + efa->e2->tmp.l++; + efa->e3->tmp.l++; + if (efa->e4) efa->e4->tmp.l++; + } + } else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */ + EditFace *efa; + int j; + /* cound how many faces each edge uses use tmp.l */ + for(efa= em->faces.first; efa; efa= efa->next) { + /* here we use the edges temp data to assign a face + if a face has alredy been assigned (eed->f2==1) + we calculate the angle between the current face and + the edges previously found face. + store the angle in eed->tmp.fp (loosing the face eed->tmp.f) + but tagging eed->f2==2, so we know not to look at it again. + This only works for edges that connect to 2 faces. but its good enough + */ + + /* se we can loop through face edges*/ + j=0; + eed= efa->e1; + while (j<4) { + if (j==1) eed= efa->e2; + else if (j==2) eed= efa->e3; + else if (j==3) { + eed= efa->e4; + if (!eed) + break; + } /* done looping */ + + if (!eed->h) { /* dont calc data for hidden edges*/ + if (eed->f2==2) + break; + else if (eed->f2==0) /* first access, assign the face */ + eed->tmp.f= efa; + else if (eed->f2==1) /* second, we assign the angle*/ + eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180; + eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/ + } + j++; + } + } + } + + for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) { + if (base_eed->f1) { + if (mode==SIMEDGE_LENGTH) { /* same length */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp) + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } else if (mode==SIMEDGE_DIR) { /* same direction */ + float base_dir[3], dir[3], angle; + VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co); + for(eed= em->edges.first; eed; eed= eed->next) { + if (!(eed->f & SELECT) && !eed->h) { + VecSubf(dir, eed->v1->co, eed->v2->co); + angle= VecAngle2(base_dir, dir); + + if (angle>90) /* use the smallest angle between the edges */ + angle= fabs(angle-180.0f); + + if (angle/90.0<=thresh) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } + } else if (mode==SIMEDGE_FACE) { /* face users */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + base_eed->tmp.l==eed->tmp.l + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + eed->f2==2 && + (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh) + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } else if (mode==SIMEDGE_CREASE) { /* edge crease */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + (fabs(base_eed->crease-eed->crease) <= thresh) + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } else if (mode==SIMEDGE_SEAM) { /* edge seam */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + (eed->seam == base_eed->seam) + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } else if (mode==SIMEDGE_SHARP) { /* edge sharp */ + for(eed= em->edges.first; eed; eed= eed->next) { + if ( + !(eed->f & SELECT) && + !eed->h && + (eed->sharp == base_eed->sharp) + ) { + EM_select_edge(eed, 1); + selcount++; + deselcount--; + if (!deselcount) /*have we selected all posible faces?, if so return*/ + return selcount; + } + } + } + } + } + return selcount; +#endif +} +/* wrap the above function but do selection flushing edge to face */ +static int similar_edge_select_exec(bContext *C, wmOperator *op) +{ +#if 0 + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + Mesh *me= obedit->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + + int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type")); + + if (selcount) { + /* here was an edge-mode only select flush case, has to be generalized */ + EM_selectmode_flush(em); + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + BKE_mesh_end_editmesh(me, em); + return OPERATOR_FINISHED; + } + + BKE_mesh_end_editmesh(me, em); + return OPERATOR_CANCELLED; +#endif +} + +/* ********************************* */ + +/* +VERT GROUP + mode 1: same normal + mode 2: same number of face users + mode 3: same vertex groups +*/ + +#define SIMVERT_NORMAL 0 +#define SIMVERT_FACE 1 +#define SIMVERT_VGROUP 2 + +static EnumPropertyItem prop_simvertex_types[] = { + {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, + {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, + {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, + {0, NULL, 0, NULL, NULL} +}; + + +static int similar_vert_select_exec(bContext *C, wmOperator *op) +{ +#if 0 + Scene *scene= CTX_data_scene(C); + Object *obedit= CTX_data_edit_object(C); + Mesh *me= obedit->data; + EditMesh *em= BKE_mesh_get_editmesh(me); + EditVert *eve, *base_eve=NULL; + unsigned int selcount=0; /* count how many new edges we select*/ + + /*count how many visible selected edges there are, + so we can return when there are none left */ + unsigned int deselcount=0; + int mode= RNA_enum_get(op->ptr, "type"); + + short ok=0; + float thresh= scene->toolsettings->select_thresh; + + for(eve= em->verts.first; eve; eve= eve->next) { + if (!eve->h) { + if (eve->f & SELECT) { + eve->f1=1; + ok=1; + } else { + eve->f1=0; + deselcount++; + } + /* set all eve->tmp.l to 0 we use them later.*/ + eve->tmp.l=0; + } + + } + + if (!ok || !deselcount) { /* no data selected OR no more data to select*/ + BKE_mesh_end_editmesh(me, em); + return 0; + } + + if(mode == SIMVERT_FACE) { + /* store face users */ + EditFace *efa; + + /* count how many faces each edge uses use tmp->l */ + for(efa= em->faces.first; efa; efa= efa->next) { + efa->v1->tmp.l++; + efa->v2->tmp.l++; + efa->v3->tmp.l++; + if (efa->v4) efa->v4->tmp.l++; + } + } + + + for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) { + if (base_eve->f1) { + + if(mode == SIMVERT_NORMAL) { + float angle; + for(eve= em->verts.first; eve; eve= eve->next) { + if (!(eve->f & SELECT) && !eve->h) { + angle= VecAngle2(base_eve->no, eve->no); + if (angle/180.0<=thresh) { + eve->f |= SELECT; + selcount++; + deselcount--; + if (!deselcount) {/*have we selected all posible faces?, if so return*/ + BKE_mesh_end_editmesh(me, em); + return selcount; + } + } + } + } + } + else if(mode == SIMVERT_FACE) { + for(eve= em->verts.first; eve; eve= eve->next) { + if ( + !(eve->f & SELECT) && + !eve->h && + base_eve->tmp.l==eve->tmp.l + ) { + eve->f |= SELECT; + selcount++; + deselcount--; + if (!deselcount) {/*have we selected all posible faces?, if so return*/ + BKE_mesh_end_editmesh(me, em); + return selcount; + } + } + } + } + else if(mode == SIMVERT_VGROUP) { + MDeformVert *dvert, *base_dvert; + short i, j; /* weight index */ + + base_dvert= CustomData_em_get(&em->vdata, base_eve->data, + CD_MDEFORMVERT); + + if (!base_dvert || base_dvert->totweight == 0) { + BKE_mesh_end_editmesh(me, em); + return selcount; + } + + for(eve= em->verts.first; eve; eve= eve->next) { + dvert= CustomData_em_get(&em->vdata, eve->data, + CD_MDEFORMVERT); + + if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) { + /* do the extra check for selection in the following if, so were not + checking verts that may be alredy selected */ + for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) { + for (j=0; dvert->totweight >j; j++) { + if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) { + eve->f |= SELECT; + selcount++; + deselcount--; + if (!deselcount) { /*have we selected all posible faces?, if so return*/ + BKE_mesh_end_editmesh(me, em); + return selcount; + } + break; + } + } + } + } + } + } + } + } /* end basevert loop */ + + if(selcount) { + WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); + BKE_mesh_end_editmesh(me, em); + return OPERATOR_FINISHED; + } + + BKE_mesh_end_editmesh(me, em); +#endif + return OPERATOR_CANCELLED; +} + +static int select_similar_exec(bContext *C, wmOperator *op) +{ + int type= RNA_enum_get(op->ptr, "type"); + + if(type < 100) + return similar_vert_select_exec(C, op); + else if(type < 200) + return similar_edge_select_exec(C, op); + else + return similar_face_select_exec(C, op); +} + +static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free) +{ + Object *obedit; + EnumPropertyItem *item= NULL; + int totitem= 0; + + if(C==NULL) { + /* needed for doc generation */ + RNA_enum_items_add(&item, &totitem, prop_simvertex_types); + RNA_enum_items_add(&item, &totitem, prop_simedge_types); + RNA_enum_items_add(&item, &totitem, prop_simface_types); + RNA_enum_item_end(&item, &totitem); + *free= 1; + + return item; + } + + obedit= CTX_data_edit_object(C); + + if(obedit && obedit->type == OB_MESH) { + EditMesh *em= BKE_mesh_get_editmesh(obedit->data); + + if(em->selectmode & SCE_SELECT_VERTEX) + RNA_enum_items_add(&item, &totitem, prop_simvertex_types); + else if(em->selectmode & SCE_SELECT_EDGE) + RNA_enum_items_add(&item, &totitem, prop_simedge_types); + else if(em->selectmode & SCE_SELECT_FACE) + RNA_enum_items_add(&item, &totitem, prop_simface_types); + RNA_enum_item_end(&item, &totitem); + + *free= 1; + + return item; + } + + return NULL; +} + +void MESH_OT_select_similar(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name= "Select Similar"; + ot->idname= "MESH_OT_select_similar"; + + /* api callbacks */ + ot->invoke= WM_menu_invoke; + ot->exec= select_similar_exec; + ot->poll= ED_operator_editmesh; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", ""); + RNA_def_enum_funcs(prop, select_similar_type_itemf); +} + /* ***************************************************** */ /* **************** LOOP SELECTS *************** */ diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 225a85b2db0..06870915e1d 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -329,655 +329,9 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads) } -/* **************** SIMILAR "group" SELECTS. FACE, EDGE AND VERTEX ************** */ - -/* selects new faces/edges/verts based on the existing selection */ - -/* FACES GROUP */ - -#define SIMFACE_MATERIAL 201 -#define SIMFACE_IMAGE 202 -#define SIMFACE_AREA 203 -#define SIMFACE_PERIMETER 204 -#define SIMFACE_NORMAL 205 -#define SIMFACE_COPLANAR 206 - -static EnumPropertyItem prop_simface_types[] = { - {SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""}, - {SIMFACE_IMAGE, "IMAGE", 0, "Image", ""}, - {SIMFACE_AREA, "AREA", 0, "Area", ""}, - {SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""}, - {SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""}, - {SIMFACE_COPLANAR, "COPLANAR", 0, "Co-planar", ""}, - {0, NULL, 0, NULL, NULL} -}; - - -/* this as a way to compare the ares, perim of 2 faces thay will scale to different sizes -*0.5 so smaller faces arnt ALWAYS selected with a thresh of 1.0 */ -#define SCALE_CMP(a,b) ((a+a*thresh >= b) && (a-(a*thresh*0.5) <= b)) - -static int similar_face_select__internal(Scene *scene, EditMesh *em, int mode) -{ - EditFace *efa, *base_efa=NULL; - unsigned int selcount=0; /*count how many new faces we select*/ - - /*deselcount, count how many deselected faces are left, so we can bail out early - also means that if there are no deselected faces, we can avoid a lot of looping */ - unsigned int deselcount=0; - float thresh= scene->toolsettings->select_thresh; - short ok=0; - - for(efa= em->faces.first; efa; efa= efa->next) { - if (!efa->h) { - if (efa->f & SELECT) { - efa->f1=1; - ok=1; - } else { - efa->f1=0; - deselcount++; /* a deselected face we may select later */ - } - } - } - - if (!ok || !deselcount) /* no data selected OR no more data to select */ - return 0; - - if (mode==SIMFACE_AREA) { - for(efa= em->faces.first; efa; efa= efa->next) { - efa->tmp.fp= EM_face_area(efa); - } - } else if (mode==SIMFACE_PERIMETER) { - for(efa= em->faces.first; efa; efa= efa->next) { - efa->tmp.fp= EM_face_perimeter(efa); - } - } - - for(base_efa= em->faces.first; base_efa; base_efa= base_efa->next) { - if (base_efa->f1) { /* This was one of the faces originaly selected */ - if (mode==SIMFACE_MATERIAL) { /* same material */ - for(efa= em->faces.first; efa; efa= efa->next) { - if ( - !(efa->f & SELECT) && - !efa->h && - base_efa->mat_nr == efa->mat_nr - ) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMFACE_IMAGE) { /* same image */ - MTFace *tf, *base_tf; - - base_tf = (MTFace*)CustomData_em_get(&em->fdata, base_efa->data, - CD_MTFACE); - - if(!base_tf) - return selcount; - - for(efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->f & SELECT) && !efa->h) { - tf = (MTFace*)CustomData_em_get(&em->fdata, efa->data, - CD_MTFACE); - - if(base_tf->tpage == tf->tpage) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } - } else if (mode==SIMFACE_AREA || mode==SIMFACE_PERIMETER) { /* same area OR same perimeter, both use the same temp var */ - for(efa= em->faces.first; efa; efa= efa->next) { - if ( - (!(efa->f & SELECT) && !efa->h) && - SCALE_CMP(base_efa->tmp.fp, efa->tmp.fp) - ) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMFACE_NORMAL) { - float angle; - for(efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->f & SELECT) && !efa->h) { - angle= VecAngle2(base_efa->n, efa->n); - if (angle/180.0<=thresh) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } - } else if (mode==SIMFACE_COPLANAR) { /* same planer */ - float angle, base_dot, dot; - base_dot= Inpf(base_efa->cent, base_efa->n); - for(efa= em->faces.first; efa; efa= efa->next) { - if (!(efa->f & SELECT) && !efa->h) { - angle= VecAngle2(base_efa->n, efa->n); - if (angle/180.0<=thresh) { - dot=Inpf(efa->cent, base_efa->n); - if (fabs(base_dot-dot) <= thresh) { - EM_select_face(efa, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } - } - } - } - } /* end base_efa loop */ - return selcount; -} - -static int similar_face_select_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - Mesh *me= obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - - int selcount = similar_face_select__internal(scene, em, RNA_int_get(op->ptr, "type")); - - if (selcount) { - /* here was an edge-mode only select flush case, has to be generalized */ - EM_selectmode_flush(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(me, em); - return OPERATOR_FINISHED; - } - - BKE_mesh_end_editmesh(me, em); - return OPERATOR_CANCELLED; -} - -/* ***************************************************** */ - -/* EDGE GROUP */ - -#define SIMEDGE_LENGTH 101 -#define SIMEDGE_DIR 102 -#define SIMEDGE_FACE 103 -#define SIMEDGE_FACE_ANGLE 104 -#define SIMEDGE_CREASE 105 -#define SIMEDGE_SEAM 106 -#define SIMEDGE_SHARP 107 - -static EnumPropertyItem prop_simedge_types[] = { - {SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""}, - {SIMEDGE_DIR, "DIR", 0, "Direction", ""}, - {SIMEDGE_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, - {SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""}, - {SIMEDGE_CREASE, "CREASE", 0, "Crease", ""}, - {SIMEDGE_SEAM, "SEAM", 0, "Seam", ""}, - {SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""}, - {0, NULL, 0, NULL, NULL} -}; - -static int similar_edge_select__internal(Scene *scene, EditMesh *em, int mode) -{ - EditEdge *eed, *base_eed=NULL; - unsigned int selcount=0; /* count how many new edges we select*/ - - /*count how many visible selected edges there are, - so we can return when there are none left */ - unsigned int deselcount=0; - - short ok=0; - float thresh= scene->toolsettings->select_thresh; - - for(eed= em->edges.first; eed; eed= eed->next) { - if (!eed->h) { - if (eed->f & SELECT) { - eed->f1=1; - ok=1; - } else { - eed->f1=0; - deselcount++; - } - /* set all eed->tmp.l to 0 we use it later. - for counting face users*/ - eed->tmp.l=0; - eed->f2=0; /* only for mode SIMEDGE_FACE_ANGLE, edge animations */ - } - } - - if (!ok || !deselcount) /* no data selected OR no more data to select*/ - return 0; - - if (mode==SIMEDGE_LENGTH) { /*store length*/ - for(eed= em->edges.first; eed; eed= eed->next) { - if (!eed->h) /* dont calc data for hidden edges*/ - eed->tmp.fp= VecLenf(eed->v1->co, eed->v2->co); - } - } else if (mode==SIMEDGE_FACE) { /*store face users*/ - EditFace *efa; - /* cound how many faces each edge uses use tmp->l */ - for(efa= em->faces.first; efa; efa= efa->next) { - efa->e1->tmp.l++; - efa->e2->tmp.l++; - efa->e3->tmp.l++; - if (efa->e4) efa->e4->tmp.l++; - } - } else if (mode==SIMEDGE_FACE_ANGLE) { /*store edge angles */ - EditFace *efa; - int j; - /* cound how many faces each edge uses use tmp.l */ - for(efa= em->faces.first; efa; efa= efa->next) { - /* here we use the edges temp data to assign a face - if a face has alredy been assigned (eed->f2==1) - we calculate the angle between the current face and - the edges previously found face. - store the angle in eed->tmp.fp (loosing the face eed->tmp.f) - but tagging eed->f2==2, so we know not to look at it again. - This only works for edges that connect to 2 faces. but its good enough - */ - - /* se we can loop through face edges*/ - j=0; - eed= efa->e1; - while (j<4) { - if (j==1) eed= efa->e2; - else if (j==2) eed= efa->e3; - else if (j==3) { - eed= efa->e4; - if (!eed) - break; - } /* done looping */ - - if (!eed->h) { /* dont calc data for hidden edges*/ - if (eed->f2==2) - break; - else if (eed->f2==0) /* first access, assign the face */ - eed->tmp.f= efa; - else if (eed->f2==1) /* second, we assign the angle*/ - eed->tmp.fp= VecAngle2(eed->tmp.f->n, efa->n)/180; - eed->f2++; /* f2==0 no face assigned. f2==1 one face found. f2==2 angle calculated.*/ - } - j++; - } - } - } - - for(base_eed= em->edges.first; base_eed; base_eed= base_eed->next) { - if (base_eed->f1) { - if (mode==SIMEDGE_LENGTH) { /* same length */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - SCALE_CMP(base_eed->tmp.fp, eed->tmp.fp) - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMEDGE_DIR) { /* same direction */ - float base_dir[3], dir[3], angle; - VecSubf(base_dir, base_eed->v1->co, base_eed->v2->co); - for(eed= em->edges.first; eed; eed= eed->next) { - if (!(eed->f & SELECT) && !eed->h) { - VecSubf(dir, eed->v1->co, eed->v2->co); - angle= VecAngle2(base_dir, dir); - - if (angle>90) /* use the smallest angle between the edges */ - angle= fabs(angle-180.0f); - - if (angle/90.0<=thresh) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } - } else if (mode==SIMEDGE_FACE) { /* face users */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - base_eed->tmp.l==eed->tmp.l - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMEDGE_FACE_ANGLE && base_eed->f2==2) { /* edge angles, f2==2 means the edge has an angle. */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - eed->f2==2 && - (fabs(base_eed->tmp.fp-eed->tmp.fp)<=thresh) - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMEDGE_CREASE) { /* edge crease */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - (fabs(base_eed->crease-eed->crease) <= thresh) - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMEDGE_SEAM) { /* edge seam */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - (eed->seam == base_eed->seam) - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } else if (mode==SIMEDGE_SHARP) { /* edge sharp */ - for(eed= em->edges.first; eed; eed= eed->next) { - if ( - !(eed->f & SELECT) && - !eed->h && - (eed->sharp == base_eed->sharp) - ) { - EM_select_edge(eed, 1); - selcount++; - deselcount--; - if (!deselcount) /*have we selected all posible faces?, if so return*/ - return selcount; - } - } - } - } - } - return selcount; -} -/* wrap the above function but do selection flushing edge to face */ -static int similar_edge_select_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - Mesh *me= obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - - int selcount = similar_edge_select__internal(scene, em, RNA_int_get(op->ptr, "type")); - - if (selcount) { - /* here was an edge-mode only select flush case, has to be generalized */ - EM_selectmode_flush(em); - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(me, em); - return OPERATOR_FINISHED; - } - - BKE_mesh_end_editmesh(me, em); - return OPERATOR_CANCELLED; -} - -/* ********************************* */ - -/* -VERT GROUP - mode 1: same normal - mode 2: same number of face users - mode 3: same vertex groups -*/ - -#define SIMVERT_NORMAL 0 -#define SIMVERT_FACE 1 -#define SIMVERT_VGROUP 2 - -static EnumPropertyItem prop_simvertex_types[] = { - {SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""}, - {SIMVERT_FACE, "FACE", 0, "Amount of Vertices in Face", ""}, - {SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""}, - {0, NULL, 0, NULL, NULL} -}; - - -static int similar_vert_select_exec(bContext *C, wmOperator *op) -{ - Scene *scene= CTX_data_scene(C); - Object *obedit= CTX_data_edit_object(C); - Mesh *me= obedit->data; - EditMesh *em= BKE_mesh_get_editmesh(me); - EditVert *eve, *base_eve=NULL; - unsigned int selcount=0; /* count how many new edges we select*/ - - /*count how many visible selected edges there are, - so we can return when there are none left */ - unsigned int deselcount=0; - int mode= RNA_enum_get(op->ptr, "type"); - - short ok=0; - float thresh= scene->toolsettings->select_thresh; - - for(eve= em->verts.first; eve; eve= eve->next) { - if (!eve->h) { - if (eve->f & SELECT) { - eve->f1=1; - ok=1; - } else { - eve->f1=0; - deselcount++; - } - /* set all eve->tmp.l to 0 we use them later.*/ - eve->tmp.l=0; - } - - } - - if (!ok || !deselcount) { /* no data selected OR no more data to select*/ - BKE_mesh_end_editmesh(me, em); - return 0; - } - - if(mode == SIMVERT_FACE) { - /* store face users */ - EditFace *efa; - - /* count how many faces each edge uses use tmp->l */ - for(efa= em->faces.first; efa; efa= efa->next) { - efa->v1->tmp.l++; - efa->v2->tmp.l++; - efa->v3->tmp.l++; - if (efa->v4) efa->v4->tmp.l++; - } - } - - - for(base_eve= em->verts.first; base_eve; base_eve= base_eve->next) { - if (base_eve->f1) { - - if(mode == SIMVERT_NORMAL) { - float angle; - for(eve= em->verts.first; eve; eve= eve->next) { - if (!(eve->f & SELECT) && !eve->h) { - angle= VecAngle2(base_eve->no, eve->no); - if (angle/180.0<=thresh) { - eve->f |= SELECT; - selcount++; - deselcount--; - if (!deselcount) {/*have we selected all posible faces?, if so return*/ - BKE_mesh_end_editmesh(me, em); - return selcount; - } - } - } - } - } - else if(mode == SIMVERT_FACE) { - for(eve= em->verts.first; eve; eve= eve->next) { - if ( - !(eve->f & SELECT) && - !eve->h && - base_eve->tmp.l==eve->tmp.l - ) { - eve->f |= SELECT; - selcount++; - deselcount--; - if (!deselcount) {/*have we selected all posible faces?, if so return*/ - BKE_mesh_end_editmesh(me, em); - return selcount; - } - } - } - } - else if(mode == SIMVERT_VGROUP) { - MDeformVert *dvert, *base_dvert; - short i, j; /* weight index */ - - base_dvert= CustomData_em_get(&em->vdata, base_eve->data, - CD_MDEFORMVERT); - - if (!base_dvert || base_dvert->totweight == 0) { - BKE_mesh_end_editmesh(me, em); - return selcount; - } - - for(eve= em->verts.first; eve; eve= eve->next) { - dvert= CustomData_em_get(&em->vdata, eve->data, - CD_MDEFORMVERT); - - if (dvert && !(eve->f & SELECT) && !eve->h && dvert->totweight) { - /* do the extra check for selection in the following if, so were not - checking verts that may be alredy selected */ - for (i=0; base_dvert->totweight >i && !(eve->f & SELECT); i++) { - for (j=0; dvert->totweight >j; j++) { - if (base_dvert->dw[i].def_nr==dvert->dw[j].def_nr) { - eve->f |= SELECT; - selcount++; - deselcount--; - if (!deselcount) { /*have we selected all posible faces?, if so return*/ - BKE_mesh_end_editmesh(me, em); - return selcount; - } - break; - } - } - } - } - } - } - } - } /* end basevert loop */ - - if(selcount) { - WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit); - BKE_mesh_end_editmesh(me, em); - return OPERATOR_FINISHED; - } - - BKE_mesh_end_editmesh(me, em); - return OPERATOR_CANCELLED; -} - -static int select_similar_exec(bContext *C, wmOperator *op) -{ - int type= RNA_enum_get(op->ptr, "type"); - - if(type < 100) - return similar_vert_select_exec(C, op); - else if(type < 200) - return similar_edge_select_exec(C, op); - else - return similar_face_select_exec(C, op); -} - -static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *ptr, int *free) -{ - Object *obedit; - EnumPropertyItem *item= NULL; - int totitem= 0; - - if(C==NULL) { - /* needed for doc generation */ - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); - *free= 1; - - return item; - } - - obedit= CTX_data_edit_object(C); - - if(obedit && obedit->type == OB_MESH) { - EditMesh *em= BKE_mesh_get_editmesh(obedit->data); - - if(em->selectmode & SCE_SELECT_VERTEX) - RNA_enum_items_add(&item, &totitem, prop_simvertex_types); - else if(em->selectmode & SCE_SELECT_EDGE) - RNA_enum_items_add(&item, &totitem, prop_simedge_types); - else if(em->selectmode & SCE_SELECT_FACE) - RNA_enum_items_add(&item, &totitem, prop_simface_types); - RNA_enum_item_end(&item, &totitem); - - *free= 1; - - return item; - } - - return NULL; -} - -void MESH_OT_select_similar(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name= "Select Similar"; - ot->idname= "MESH_OT_select_similar"; - - /* api callbacks */ - ot->invoke= WM_menu_invoke; - ot->exec= select_similar_exec; - ot->poll= ED_operator_editmesh; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; - - /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_simvertex_types, 0, "Type", ""); - RNA_def_enum_funcs(prop, select_similar_type_itemf); -} /* ******************************************* */ - int mesh_layers_menu_charlen(CustomData *data, int type) { int i, len = 0; diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 98980548b86..5ec34d35d45 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -217,7 +217,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL); for (; eed; eed=BMIter_Step(&iter)) { - if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT)) + if(!BM_TestHFlag(eed, BM_HIDDEN) && BM_TestHFlag(eed, BM_SELECT)) BMINDEX_SET(eed->v1, 0), BMINDEX_SET(eed->v2, 0); } eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL); @@ -233,7 +233,7 @@ static void make_trans_verts(Object *obedit, float *min, float *max, int mode) efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL); for (; efa; efa=BMIter_Step(&iter)) { - if(!BM_TestHFlag(eve, BM_HIDDEN) && BM_TestHFlag(eve, BM_SELECT)) { + if(!BM_TestHFlag(efa, BM_HIDDEN) && BM_TestHFlag(efa, BM_SELECT)) { BMIter liter; BMLoop *l; |