/* turns Mesh into editmesh */ void make_editMesh(Scene *scene, Object *ob) { Mesh *me= ob->data; MFace *mface; MVert *mvert; MSelect *mselect; KeyBlock *actkey; EditMesh *em; EditVert *eve, **evlist, *eve1, *eve2, *eve3, *eve4; EditFace *efa, *efa_last_sel= NULL; EditEdge *eed; EditSelection *ese; float *co, (*keyco)[3]= NULL; int tot, a, eekadoodle= 0; const short is_paint_face_sel= paint_facesel_test(ob); const short is_paint_vert_sel= is_paint_face_sel ? FALSE : paint_vertsel_test(ob); if(me->edit_mesh==NULL) me->edit_mesh= MEM_callocN(sizeof(EditMesh), "editmesh"); else /* because of reload */ free_editMesh(me->edit_mesh); em= me->edit_mesh; em->selectmode= scene->toolsettings->selectmode; // warning needs to be synced em->act_face = NULL; em->totvert= tot= me->totvert; em->totedge= me->totedge; em->totface= me->totface; if(tot==0) { return; } if(ob->actcol > 0) em->mat_nr= ob->actcol-1; /* initialize fastmalloc for editmesh */ init_editmesh_fastmalloc(em, me->totvert, me->totedge, me->totface); actkey = ob_get_keyblock(ob); if(actkey) { /* undo-ing in past for previous editmode sessions gives corrupt 'keyindex' values */ undo_editmode_clear(); keyco= actkey->data; em->shapenr= ob->shapenr; } /* make editverts */ CustomData_copy(&me->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); mvert= me->mvert; evlist= (EditVert **)MEM_mallocN(tot*sizeof(void *),"evlist"); for(a=0; a<tot; a++, mvert++) { co= mvert->co; /* edit the shape key coordinate if available */ if(keyco && a < actkey->totelem) co= keyco[a]; eve= addvertlist(em, co, NULL); evlist[a]= eve; /* face select sets selection in next loop */ if(!is_paint_face_sel) eve->f |= (mvert->flag & SELECT); if (mvert->flag & ME_HIDE) eve->h= 1; normal_short_to_float_v3(eve->no, mvert->no); eve->bweight= ((float)mvert->bweight)/255.0f; /* lets overwrite the keyindex of the editvert * with the order it used to be in before * editmode */ eve->keyindex = a; CustomData_to_em_block(&me->vdata, &em->vdata, a, &eve->data); } if(actkey && actkey->totelem!=me->totvert); else { MEdge *medge= me->medge; CustomData_copy(&me->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0); /* make edges */ for(a=0; a<me->totedge; a++, medge++) { eed= addedgelist(em, evlist[medge->v1], evlist[medge->v2], NULL); /* eed can be zero when v1 and v2 are identical, dxf import does this... */ if(eed) { int is_sel; if (is_paint_vert_sel) { /* when from vertex select, flush flags to edges, * allow selection, code below handles editmode selection conversion */ is_sel= (eed->v1->f & SELECT) && (eed->v2->f & SELECT); } else { is_sel= (medge->flag & SELECT); } eed->crease= ((float)medge->crease)/255.0f; eed->bweight= ((float)medge->bweight)/255.0f; if(medge->flag & ME_SEAM) eed->seam= 1; if(medge->flag & ME_SHARP) eed->sharp = 1; if(medge->flag & ME_FGON) eed->h= EM_FGON; // 2 different defines! if(medge->flag & ME_HIDE) eed->h |= 1; if(is_sel) eed->f |= SELECT; if(em->selectmode==SCE_SELECT_EDGE) EM_select_edge(eed, eed->f & SELECT); // force edge selection to vertices, seems to be needed ... CustomData_to_em_block(&me->edata,&em->edata, a, &eed->data); } } CustomData_copy(&me->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0); /* make faces */ mface= me->mface; for(a=0; a<me->totface; a++, mface++) { eve1= evlist[mface->v1]; eve2= evlist[mface->v2]; if(!mface->v3) eekadoodle= 1; eve3= evlist[mface->v3]; if(mface->v4) eve4= evlist[mface->v4]; else eve4= NULL; efa= addfacelist(em, eve1, eve2, eve3, eve4, NULL, NULL); if(efa) { CustomData_to_em_block(&me->fdata, &em->fdata, a, &efa->data); efa->mat_nr= mface->mat_nr; efa->flag= mface->flag & ~ME_HIDE; /* select and hide face flag */ if(mface->flag & ME_HIDE) { efa->h= 1; } else { int is_sel; if (!is_paint_vert_sel) { is_sel= (mface->flag & ME_FACE_SEL); } else { /* when from vertex select, flush flags to edges, * allow selection, code below handles editmode selection conversion */ is_sel= ( (efa->v1->f & SELECT) && (efa->v2->f & SELECT) && (efa->v3->f & SELECT) && (efa->v4 == NULL || efa->v4->f & SELECT) ); } if (a==me->act_face) { EM_set_actFace(em, efa); } /* dont allow hidden and selected */ if(is_sel) { efa->f |= SELECT; if(is_paint_face_sel) { EM_select_face(efa, 1); /* flush down */ } efa_last_sel= efa; } } } } } if(EM_get_actFace(em, 0)==NULL && efa_last_sel) { EM_set_actFace(em, efa_last_sel); } if(eekadoodle) error("This Mesh has old style edgecodes, please put it in the bugtracker!"); MEM_freeN(evlist); end_editmesh_fastmalloc(); // resets global function pointers if(me->mselect){ //restore editselections EM_init_index_arrays(em, 1,1,1); mselect = me->mselect; for(a=0; a<me->totselect; a++, mselect++){ /*check if recorded selection is still valid, if so copy into editmesh*/ if ( (mselect->type == EDITVERT && me->mvert[mselect->index].flag & SELECT) || (mselect->type == EDITEDGE && me->medge[mselect->index].flag & SELECT) || (mselect->type == EDITFACE && me->mface[mselect->index].flag & ME_FACE_SEL) ) { ese = MEM_callocN(sizeof(EditSelection), "Edit Selection"); ese->type = mselect->type; if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(mselect->index); else if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(mselect->index); else if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(mselect->index); BLI_addtail(&(em->selected),ese); } } EM_free_index_arrays(); } /* this creates coherent selections. also needed for older files */ EM_selectmode_set(em); /* paranoia check to enforce hide rules */ EM_hide_reset(em); /* sets helper flags which arent saved */ EM_fgon_flags(em); if (EM_get_actFace(em, 0)==NULL) { EM_set_actFace(em, em->faces.first ); /* will use the first face, this is so we alwats have an active face */ } }
static void draw_mesh_text(Scene *scene, Object *ob, int glsl) { Mesh *me = ob->data; DerivedMesh *ddm; MPoly *mp, *mface = me->mpoly; MTexPoly *mtpoly = me->mtpoly; MLoopUV *mloopuv = me->mloopuv; MLoopUV *luv; MLoopCol *mloopcol = me->mloopcol; /* why does mcol exist? */ MLoopCol *lcol; bProperty *prop = BKE_bproperty_object_get(ob, "Text"); GPUVertexAttribs gattribs; int a, totpoly = me->totpoly; /* fake values to pass to GPU_render_text() */ MCol tmp_mcol[4] = {{0}}; MCol *tmp_mcol_pt = mloopcol ? tmp_mcol : NULL; MTFace tmp_tf = {{{0}}}; /* don't draw without tfaces */ if (!mtpoly || !mloopuv) return; /* don't draw when editing */ if (ob->mode & OB_MODE_EDIT) return; else if (ob == OBACT) if (paint_facesel_test(ob) || paint_vertsel_test(ob)) return; ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); for (a = 0, mp = mface; a < totpoly; a++, mtpoly++, mp++) { short matnr = mp->mat_nr; int mf_smooth = mp->flag & ME_SMOOTH; Material *mat = (me->mat) ? me->mat[matnr] : NULL; int mode = mat ? mat->game.flag : GEMAT_INVISIBLE; if (!(mode & GEMAT_INVISIBLE) && (mode & GEMAT_TEXT) && mp->totloop >= 3) { /* get the polygon as a tri/quad */ int mp_vi[4]; float v1[3], v2[3], v3[3], v4[3]; char string[MAX_PROPSTRING]; int characters, i, glattrib = -1, badtex = 0; /* TEXFACE */ ME_MTEXFACE_CPY(&tmp_tf, mtpoly); if (glsl) { GPU_enable_material(matnr + 1, &gattribs); for (i = 0; i < gattribs.totlayer; i++) { if (gattribs.layer[i].type == CD_MTFACE) { glattrib = gattribs.layer[i].glindex; break; } } } else { badtex = set_draw_settings_cached(0, &tmp_tf, mat, Gtexdraw); if (badtex) { continue; } } mp_vi[0] = me->mloop[mp->loopstart + 0].v; mp_vi[1] = me->mloop[mp->loopstart + 1].v; mp_vi[2] = me->mloop[mp->loopstart + 2].v; mp_vi[3] = (mp->totloop >= 4) ? me->mloop[mp->loopstart + 3].v : 0; /* UV */ luv = &mloopuv[mp->loopstart]; copy_v2_v2(tmp_tf.uv[0], luv->uv); luv++; copy_v2_v2(tmp_tf.uv[1], luv->uv); luv++; copy_v2_v2(tmp_tf.uv[2], luv->uv); luv++; if (mp->totloop >= 4) { copy_v2_v2(tmp_tf.uv[3], luv->uv); } /* COLOR */ if (mloopcol) { unsigned int totloop_clamp = min_ii(4, mp->totloop); unsigned int j; lcol = &mloopcol[mp->loopstart]; for (j = 0; j < totloop_clamp; j++, lcol++) { MESH_MLOOPCOL_TO_MCOL(lcol, &tmp_mcol[j]); } } /* LOCATION */ ddm->getVertCo(ddm, mp_vi[0], v1); ddm->getVertCo(ddm, mp_vi[1], v2); ddm->getVertCo(ddm, mp_vi[2], v3); if (mp->totloop >= 4) { ddm->getVertCo(ddm, mp_vi[3], v4); } /* The BM_FONT handling is in the gpu module, shared with the * game engine, was duplicated previously */ BKE_bproperty_set_valstr(prop, string); characters = strlen(string); if (!BKE_image_has_ibuf(mtpoly->tpage, NULL)) characters = 0; if (!mf_smooth) { float nor[3]; normal_tri_v3(nor, v1, v2, v3); glNormal3fv(nor); } GPU_render_text(&tmp_tf, mode, string, characters, (unsigned int *)tmp_mcol_pt, v1, v2, v3, (mp->totloop >= 4 ? v4 : NULL), glattrib); } } ddm->release(ddm); }