/* 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 undoMesh_to_editMesh(void *umv, void *emv) { EditMesh *em= (EditMesh *)emv; UndoMesh *um= (UndoMesh *)umv; EditVert *eve, **evar=NULL; EditEdge *eed; EditFace *efa; EditSelection *ese; EditVertC *evec; EditEdgeC *eedc; EditFaceC *efac; EditSelectionC *esec; int a=0; free_editMesh(em); /* malloc blocks */ memset(em, 0, sizeof(EditMesh)); em->selectmode = um->selectmode; em->shapenr = um->shapenr; init_editmesh_fastmalloc(em, um->totvert, um->totedge, um->totface); CustomData_free(&em->vdata, 0); CustomData_free(&em->edata, 0); CustomData_free(&em->fdata, 0); CustomData_copy(&um->vdata, &em->vdata, CD_MASK_EDITMESH, CD_CALLOC, 0); CustomData_copy(&um->edata, &em->edata, CD_MASK_EDITMESH, CD_CALLOC, 0); CustomData_copy(&um->fdata, &em->fdata, CD_MASK_EDITMESH, CD_CALLOC, 0); /* now copy vertices */ if(um->totvert) evar= MEM_mallocN(um->totvert*sizeof(EditVert *), "vertex ar"); for(a=0, evec= um->verts; a<um->totvert; a++, evec++) { eve= addvertlist(em, evec->co, NULL); evar[a]= eve; copy_v3_v3(eve->no, evec->no); eve->f= evec->f; eve->h= evec->h; eve->keyindex= evec->keyindex; eve->bweight= ((float)evec->bweight)/255.0f; CustomData_to_em_block(&um->vdata, &em->vdata, a, &eve->data); } /* copy edges */ for(a=0, eedc= um->edges; a<um->totedge; a++, eedc++) { eed= addedgelist(em, evar[eedc->v1], evar[eedc->v2], NULL); eed->f= eedc->f; eed->h= eedc->h; eed->seam= eedc->seam; eed->sharp= eedc->sharp; eed->fgoni= eedc->fgoni; eed->crease= ((float)eedc->crease)/255.0f; eed->bweight= ((float)eedc->bweight)/255.0f; CustomData_to_em_block(&um->edata, &em->edata, a, &eed->data); } /* copy faces */ for(a=0, efac= um->faces; a<um->totface; a++, efac++) { if(efac->v4 != -1) efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], evar[efac->v4], NULL, NULL); else efa= addfacelist(em, evar[efac->v1], evar[efac->v2], evar[efac->v3], NULL, NULL ,NULL); efa->mat_nr= efac->mat_nr; efa->flag= efac->flag; efa->f= efac->f; efa->h= efac->h; efa->fgonf= efac->fgonf; CustomData_to_em_block(&um->fdata, &em->fdata, a, &efa->data); } end_editmesh_fastmalloc(); if(evar) MEM_freeN(evar); em->totvert = um->totvert; em->totedge = um->totedge; em->totface = um->totface; /*restore stored editselections*/ if(um->totsel){ EM_init_index_arrays(em, 1,1,1); for(a=0, esec= um->selected; a<um->totsel; a++, esec++){ ese = MEM_callocN(sizeof(EditSelection), "Edit Selection"); ese->type = esec->type; if(ese->type == EDITVERT) ese->data = EM_get_vert_for_index(esec->index); else if(ese->type == EDITEDGE) ese->data = EM_get_edge_for_index(esec->index); else if(ese->type == EDITFACE) ese->data = EM_get_face_for_index(esec->index); BLI_addtail(&(em->selected),ese); } EM_free_index_arrays(); } /* restore total selections */ EM_nvertices_selected(em); EM_nedges_selected(em); EM_nfaces_selected(em); }
static void addedgeface_mesh(EditMesh *em, wmOperator *op) { EditVert *eve, *neweve[4]; EditEdge *eed; EditFace *efa; short amount=0; /* how many selected ? */ if(em->selectmode & SCE_SELECT_EDGE) { /* in edge mode finding selected vertices means flushing down edge codes... */ /* can't make face with only edge selection info... */ EM_selectmode_set(em); } for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & SELECT) { amount++; if(amount>4) break; neweve[amount-1]= eve; } } if(amount==2) { eed= addedgelist(em, neweve[0], neweve[1], NULL); EM_select_edge(eed, 1); // XXX DAG_id_tag_update(obedit->data, 0); return; } else if(amount > 4) { addfaces_from_edgenet(em); return; } else if(amount<2) { BKE_report(op->reports, RPT_WARNING, "More vertices are needed to make an edge/face"); return; } efa= NULL; // check later if(amount==3) { if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], NULL)==0) { efa= addfacelist(em, neweve[0], neweve[1], neweve[2], 0, NULL, NULL); EM_select_face(efa, 1); } else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); } else if(amount==4) { /* this test survives when theres 2 triangles */ if(exist_face(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) { int tria= 0; /* remove trias if they exist, 4 cases.... */ if(exist_face(em, neweve[0], neweve[1], neweve[2], NULL)) tria++; if(exist_face(em, neweve[0], neweve[1], neweve[3], NULL)) tria++; if(exist_face(em, neweve[0], neweve[2], neweve[3], NULL)) tria++; if(exist_face(em, neweve[1], neweve[2], neweve[3], NULL)) tria++; if(tria==2) join_triangles(em); else if(exist_face_overlaps(em, neweve[0], neweve[1], neweve[2], neweve[3])==0) { /* If there are 4 Verts, But more selected edges, we need to call addfaces_from_edgenet */ EditEdge *eedcheck; int count; count = 0; for(eedcheck= em->edges.first; eedcheck; eedcheck= eedcheck->next) { if(eedcheck->f & SELECT) { count++; } } if(count++ > 4){ addfaces_from_edgenet(em); return; } else { /* if 4 edges exist, we just create the face, convex or not */ efa= addface_from_edges(em); if(efa==NULL) { /* the order of vertices can be anything, 6 cases to check */ if( convex(neweve[0]->co, neweve[1]->co, neweve[2]->co, neweve[3]->co) ) { efa= addfacelist(em, neweve[0], neweve[1], neweve[2], neweve[3], NULL, NULL); } else if( convex(neweve[0]->co, neweve[2]->co, neweve[3]->co, neweve[1]->co) ) { efa= addfacelist(em, neweve[0], neweve[2], neweve[3], neweve[1], NULL, NULL); } else if( convex(neweve[0]->co, neweve[2]->co, neweve[1]->co, neweve[3]->co) ) { efa= addfacelist(em, neweve[0], neweve[2], neweve[1], neweve[3], NULL, NULL); } else if( convex(neweve[0]->co, neweve[1]->co, neweve[3]->co, neweve[2]->co) ) { efa= addfacelist(em, neweve[0], neweve[1], neweve[3], neweve[2], NULL, NULL); } else if( convex(neweve[0]->co, neweve[3]->co, neweve[2]->co, neweve[1]->co) ) { efa= addfacelist(em, neweve[0], neweve[3], neweve[2], neweve[1], NULL, NULL); } else if( convex(neweve[0]->co, neweve[3]->co, neweve[1]->co, neweve[2]->co) ) { efa= addfacelist(em, neweve[0], neweve[3], neweve[1], neweve[2], NULL, NULL); } else BKE_report(op->reports, RPT_WARNING, "cannot find nice quad from concave set of vertices"); } } } else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); } else BKE_report(op->reports, RPT_WARNING, "The selected vertices already form a face"); } if(efa) { EM_select_face(efa, 1); fix_new_face(em, efa); recalc_editnormals(em); } }
static void make_prim(Object *obedit, int type, float mat[4][4], int tot, int seg, int subdiv, float dia, float depth, int ext, int fill) { /* * type - for the type of shape * dia - the radius for cone,sphere cylinder etc. * depth - * ext - extrude * fill - end capping, and option to fill in circle * cent[3] - center of the data. * */ EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data)); EditVert *eve, *v1=NULL, *v2, *v3, *v4=NULL, *vtop, *vdown; float phi, phid, vec[3]; float q[4], cmat[3][3], nor[3]= {0.0, 0.0, 0.0}; short a, b; EM_clear_flag_all(em, SELECT); phid= 2.0f*(float)M_PI/tot; phi= .25f*(float)M_PI; switch(type) { case PRIM_GRID: /* grid */ /* clear flags */ eve= em->verts.first; while(eve) { eve->f= 0; eve= eve->next; } /* one segment first: the X axis */ phi = (2*dia)/(float)(tot-1); phid = (2*dia)/(float)(seg-1); for(a=tot-1;a>=0;a--) { vec[0] = (phi*a) - dia; vec[1]= - dia; vec[2]= 0.0f; eve= addvertlist(em, vec, NULL); eve->f= 1+2+4; if(a < tot -1) addedgelist(em, eve->prev, eve, NULL); } /* extrude and translate */ vec[0]= vec[2]= 0.0; vec[1]= phid; for(a=0;a<seg-1;a++) { extrudeflag_vert(obedit, em, 2, nor, 0); // nor unused translateflag(em, 2, vec); } /* and now do imat */ eve= em->verts.first; while(eve) { if(eve->f & SELECT) { mul_m4_v3(mat,eve->co); } eve= eve->next; } recalc_editnormals(em); break; case PRIM_UVSPHERE: /* UVsphere */ /* clear all flags */ eve= em->verts.first; while(eve) { eve->f= 0; eve= eve->next; } /* one segment first */ phi= 0; phid/=2; for(a=0; a<=tot; a++) { vec[0]= dia*sinf(phi); vec[1]= 0.0; vec[2]= dia*cosf(phi); eve= addvertlist(em, vec, NULL); eve->f= 1+2+4; if(a==0) v1= eve; else addedgelist(em, eve, eve->prev, NULL); phi+= phid; } /* extrude and rotate */ phi= M_PI/seg; q[0]= cos(phi); q[3]= sin(phi); q[1]=q[2]= 0; quat_to_mat3( cmat,q); for(a=0; a<seg; a++) { extrudeflag_vert(obedit, em, 2, nor, 0); // nor unused rotateflag(em, 2, v1->co, cmat); } removedoublesflag(em, 4, 0, 0.0001); /* and now do imat */ eve= em->verts.first; while(eve) { if(eve->f & SELECT) { mul_m4_v3(mat,eve->co); } eve= eve->next; } recalc_editnormals(em); break; case PRIM_ICOSPHERE: /* Icosphere */ { EditVert *eva[12]; EditEdge *eed; /* clear all flags */ eve= em->verts.first; while(eve) { eve->f= 0; eve= eve->next; } dia/=200; for(a=0;a<12;a++) { vec[0]= dia*icovert[a][0]; vec[1]= dia*icovert[a][1]; vec[2]= dia*icovert[a][2]; eva[a]= addvertlist(em, vec, NULL); eva[a]->f= 1+2; } for(a=0;a<20;a++) { EditFace *evtemp; v1= eva[ icoface[a][0] ]; v2= eva[ icoface[a][1] ]; v3= eva[ icoface[a][2] ]; evtemp = addfacelist(em, v1, v2, v3, 0, NULL, NULL); evtemp->e1->f = 1+2; evtemp->e2->f = 1+2; evtemp->e3->f = 1+2; } dia*=200; for(a=1; a<subdiv; a++) esubdivideflag(obedit, em, 2, dia, 0, B_SPHERE,1, SUBDIV_CORNER_PATH, 0); /* and now do imat */ eve= em->verts.first; while(eve) { if(eve->f & 2) { mul_m4_v3(mat,eve->co); } eve= eve->next; } // Clear the flag 2 from the edges for(eed=em->edges.first;eed;eed=eed->next){ if(eed->f & 2){ eed->f &= !2; } } } break; case PRIM_MONKEY: /* Monkey */ { //extern int monkeyo, monkeynv, monkeynf; //extern signed char monkeyf[][4]; //extern signed char monkeyv[][3]; EditVert **tv= MEM_mallocN(sizeof(*tv)*monkeynv*2, "tv"); int i; for (i=0; i<monkeynv; i++) { float v[3]; v[0]= (monkeyv[i][0]+127)/128.0, v[1]= monkeyv[i][1]/128.0, v[2]= monkeyv[i][2]/128.0; tv[i]= addvertlist(em, v, NULL); tv[i]->f |= SELECT; tv[monkeynv+i]= (fabs(v[0]= -v[0])<0.001)?tv[i]:addvertlist(em, v, NULL); tv[monkeynv+i]->f |= SELECT; } for (i=0; i<monkeynf; i++) { addfacelist(em, tv[monkeyf[i][0]+i-monkeyo], tv[monkeyf[i][1]+i-monkeyo], tv[monkeyf[i][2]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL); addfacelist(em, tv[monkeynv+monkeyf[i][2]+i-monkeyo], tv[monkeynv+monkeyf[i][1]+i-monkeyo], tv[monkeynv+monkeyf[i][0]+i-monkeyo], (monkeyf[i][3]!=monkeyf[i][2])?tv[monkeynv+monkeyf[i][3]+i-monkeyo]:NULL, NULL, NULL); } MEM_freeN(tv); /* and now do imat */ for(eve= em->verts.first; eve; eve= eve->next) { if(eve->f & SELECT) { mul_m4_v3(mat,eve->co); } } recalc_editnormals(em); } break; default: /* all types except grid, sphere... */ if(type==PRIM_CONE); else if(ext==0) depth= 0.0f; /* first vertex at 0° for circular objects */ if( ELEM3(type, PRIM_CIRCLE,PRIM_CYLINDER,PRIM_CONE) ) phi = 0.0f; vtop= vdown= v1= v2= 0; for(b=0; b<=ext; b++) { for(a=0; a<tot; a++) { vec[0]= dia*sinf(phi); vec[1]= dia*cosf(phi); vec[2]= b?depth:-depth; mul_m4_v3(mat, vec); eve= addvertlist(em, vec, NULL); eve->f= SELECT; if(a==0) { if(b==0) v1= eve; else v2= eve; } phi+=phid; } } /* center vertices */ /* type PRIM_CONE can only have 1 one side filled * if the cone has no capping, dont add vtop */ if(type == PRIM_CONE || (fill && !ELEM(type, PRIM_PLANE, PRIM_CUBE))) { vec[0]= vec[1]= 0.0f; vec[2]= type==PRIM_CONE ? depth : -depth; mul_m4_v3(mat, vec); vdown= addvertlist(em, vec, NULL); if((ext || type==PRIM_CONE) && fill) { vec[0]= vec[1]= 0.0f; vec[2]= type==PRIM_CONE ? -depth : depth; mul_m4_v3(mat,vec); vtop= addvertlist(em, vec, NULL); } } else { vdown= v1; vtop= v2; } if(vtop) vtop->f= SELECT; if(vdown) vdown->f= SELECT; /* top and bottom face */ if(fill || type==PRIM_CONE) { if(tot==4 && ELEM(type, PRIM_PLANE, PRIM_CUBE)) { v3= v1->next->next; if(ext) v4= v2->next->next; addfacelist(em, v3, v1->next, v1, v3->next, NULL, NULL); if(ext) addfacelist(em, v2, v2->next, v4, v4->next, NULL, NULL); } else { v3= v1; v4= v2; for(a=1; a<tot; a++) { addfacelist(em, vdown, v3, v3->next, 0, NULL, NULL); v3= v3->next; if(ext && fill) { addfacelist(em, vtop, v4, v4->next, 0, NULL, NULL); v4= v4->next; } } if(!ELEM(type, PRIM_PLANE, PRIM_CUBE)) { addfacelist(em, vdown, v3, v1, 0, NULL, NULL); if(ext) addfacelist(em, vtop, v4, v2, 0, NULL, NULL); } } } else if(type==PRIM_CIRCLE) { /* we need edges for a circle */ v3= v1; for(a=1;a<tot;a++) { addedgelist(em, v3, v3->next, NULL); v3= v3->next; } addedgelist(em, v3, v1, NULL); } /* side faces */ if(ext) { v3= v1; v4= v2; for(a=1; a<tot; a++) { addfacelist(em, v3, v3->next, v4->next, v4, NULL, NULL); v3= v3->next; v4= v4->next; } addfacelist(em, v3, v1, v2, v4, NULL, NULL); } else if(fill && type==PRIM_CONE) { /* add the bottom flat area of the cone * if capping is disabled dont bother */ v3= v1; for(a=1; a<tot; a++) { addfacelist(em, vtop, v3->next, v3, 0, NULL, NULL); v3= v3->next; } addfacelist(em, vtop, v1, v3, 0, NULL, NULL); } } EM_stats_update(em); /* simple selection flush OK, based on fact it's a single model */ EM_select_flush(em); /* flushes vertex -> edge -> face selection */ if(!ELEM5(type, PRIM_GRID, PRIM_PLANE, PRIM_ICOSPHERE, PRIM_UVSPHERE, PRIM_MONKEY)) EM_recalc_normal_direction(em, FALSE, TRUE); /* otherwise monkey has eyes in wrong direction */ BKE_mesh_end_editmesh(obedit->data, em); }
EditFace *addfacelist(EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4) //, EditFace *example, EditFace *exampleEdges) { EditMesh *em = &gEditMesh; EditFace *efa; EditEdge *e1, *e2=0, *e3=0, *e4=0; /* add face to list and do the edges */ // if(exampleEdges) { // e1= addedgelist(v1, v2, exampleEdges->e1); // e2= addedgelist(v2, v3, exampleEdges->e2); // if(v4) e3= addedgelist(v3, v4, exampleEdges->e3); // else e3= addedgelist(v3, v1, exampleEdges->e3); // if(v4) e4= addedgelist(v4, v1, exampleEdges->e4); // } // else { /* if(v4) { e1 = addedgelist(v4, v1); //, NULL); e2 = addedgelist(v1, v2); //, NULL); e3 = addedgelist(v2, v3); //, NULL); e4 = addedgelist(v3, v4); //, NULL); } else { e1 = addedgelist(v3, v1); //, NULL); e2 = addedgelist(v1, v2); //, NULL); e3 = addedgelist(v2, v3); //, NULL); } */ e1= addedgelist(v1, v2); //, NULL); e2= addedgelist(v2, v3); //, NULL); if(v4) e3= addedgelist(v3, v4); //, NULL); else e3= addedgelist(v3, v1); //, NULL); if(v4) e4= addedgelist(v4, v1); //, NULL); // } if(v1==v2 || v2==v3 || v1==v3) return NULL; if(e2==0) return NULL; efa= (EditFace *)calloc(sizeof(EditFace), 1); efa->v1= v1; efa->v2= v2; efa->v3= v3; efa->v4= v4; efa->e1= e1; efa->e2= e2; efa->e3= e3; efa->e4= e4; // if(example) { // efa->mat_nr= example->mat_nr; // efa->tf= example->tf; // efa->tf.flag &= ~TF_ACTIVE; // efa->flag= example->flag; // } // else { // if (G.obedit && G.obedit->actcol) // efa->mat_nr= G.obedit->actcol-1; // default_uv(efa->tf.uv, 1.0); /* Initialize colors */ // efa->tf.col[0]= efa->tf.col[1]= efa->tf.col[2]= efa->tf.col[3]= vpaint_get_current_col(); // } BLI_addtail(&em->faces, efa); if(efa->v4) { CalcNormFloat4(efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co, efa->n); CalcCent4f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co); } else { CalcNormFloat(efa->v1->co, efa->v2->co, efa->v3->co, efa->n); CalcCent3f(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co); } return efa; }
EditFace *addfacelist(EditMesh *em, EditVert *v1, EditVert *v2, EditVert *v3, EditVert *v4, EditFace *example, EditFace *exampleEdges) { EditFace *efa; EditEdge *e1, *e2=0, *e3=0, *e4=0; /* added sanity check... seems to happen for some tools, or for enter editmode for corrupted meshes */ if(v1==v4 || v2==v4 || v3==v4) v4= NULL; /* add face to list and do the edges */ if(exampleEdges) { e1= addedgelist(em, v1, v2, exampleEdges->e1); e2= addedgelist(em, v2, v3, exampleEdges->e2); if(v4) e3= addedgelist(em, v3, v4, exampleEdges->e3); else e3= addedgelist(em, v3, v1, exampleEdges->e3); if(v4) e4= addedgelist(em, v4, v1, exampleEdges->e4); } else { e1= addedgelist(em, v1, v2, NULL); e2= addedgelist(em, v2, v3, NULL); if(v4) e3= addedgelist(em, v3, v4, NULL); else e3= addedgelist(em, v3, v1, NULL); if(v4) e4= addedgelist(em, v4, v1, NULL); } if(v1==v2 || v2==v3 || v1==v3) return NULL; if(e2==0) return NULL; efa= (EditFace *)callocface(em, sizeof(EditFace), 1); efa->v1= v1; efa->v2= v2; efa->v3= v3; efa->v4= v4; efa->e1= e1; efa->e2= e2; efa->e3= e3; efa->e4= e4; if(example) { efa->mat_nr= example->mat_nr; efa->flag= example->flag; CustomData_em_copy_data(&em->fdata, &em->fdata, example->data, &efa->data); CustomData_em_validate_data(&em->fdata, efa->data, efa->v4 ? 4 : 3); } else { efa->mat_nr= em->mat_nr; CustomData_em_set_default(&em->fdata, &efa->data); } BLI_addtail(&em->faces, efa); em->totface++; if(efa->v4) { normal_quad_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co); cent_quad_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co, efa->v4->co); } else { normal_tri_v3( efa->n,efa->v1->co, efa->v2->co, efa->v3->co); cent_tri_v3(efa->cent, efa->v1->co, efa->v2->co, efa->v3->co); } return efa; }