void EdgeRingSelect(int SelectedEdgeVert1, int SelectedEdgeVert2, int AdjEdgeVert1, int AdjEdgeVert2, Face* pFaces) { EditEdge* SelectedEdge = findedgelist(VertsList[SelectedEdgeVert1], VertsList[SelectedEdgeVert2]); EditEdge* StartEdge = findedgelist(VertsList[AdjEdgeVert1], VertsList[AdjEdgeVert2]); if(SelectedEdge == NULL || StartEdge == NULL) return; edgering_sel(StartEdge, SelectedEdge, 0, 0); EditFace *efa; for(efa= (EditFace*)gEditMesh.faces.first; efa; efa= efa->next) { // int VertIndex1, VertIndex2; if(efa->e1->f3 == 1) // efa->f1 { RKMesh::Get()->SelectEdge(efa->e1->v1->VertexIndex, efa->e1->v2->VertexIndex); // RKMesh::Get()->SelectAllEdges(efa->e1->v1->VertexIndex, efa->e1->v2->VertexIndex); } if(efa->e2->f3 == 1) { RKMesh::Get()->SelectEdge(efa->e2->v1->VertexIndex, efa->e2->v2->VertexIndex); // RKMesh::Get()->SelectAllEdges(efa->e2->v1->VertexIndex, efa->e2->v2->VertexIndex); } if(efa->e3->f3 == 1) { RKMesh::Get()->SelectEdge(efa->e3->v1->VertexIndex, efa->e3->v2->VertexIndex); // RKMesh::Get()->SelectAllEdges(efa->e3->v1->VertexIndex, efa->e3->v2->VertexIndex); } if(efa->e4 != NULL && efa->e4->f3 == 1) { RKMesh::Get()->SelectEdge(efa->e4->v1->VertexIndex, efa->e4->v2->VertexIndex); // RKMesh::Get()->SelectAllEdges(efa->e4->v1->VertexIndex, efa->e4->v2->VertexIndex); } pFaces++; } }
static void editMesh_set_hash(EditMesh *em) { EditEdge *eed; if(em->hashedgetab) MEM_freeN(em->hashedgetab); em->hashedgetab= NULL; for(eed=em->edges.first; eed; eed= eed->next) { if( findedgelist(em, eed->v1, eed->v2)==NULL ) insert_hashedge(em, eed); } }
EditEdge *addedgelist(EditMesh *em, EditVert *v1, EditVert *v2, EditEdge *example) { EditVert *v3; EditEdge *eed; int swap= 0; if(v1==v2) return NULL; if(v1==NULL || v2==NULL) return NULL; /* swap ? */ if(v1>v2) { v3= v2; v2= v1; v1= v3; swap= 1; } /* find in hashlist */ eed= findedgelist(em, v1, v2); if(eed==NULL) { eed= (EditEdge *)callocedge(em, sizeof(EditEdge), 1); eed->v1= v1; eed->v2= v2; BLI_addtail(&em->edges, eed); eed->dir= swap; insert_hashedge(em, eed); em->totedge++; /* copy edge data: rule is to do this with addedgelist call, before addfacelist */ if(example) { eed->crease= example->crease; eed->bweight= example->bweight; eed->sharp = example->sharp; eed->seam = example->seam; eed->h |= (example->h & EM_FGON); } } return eed; }
/* only adds quads or trias when there's edges already */ static void addfaces_from_edgenet(EditMesh *em) { EditVert *eve1, *eve2, *eve3, *eve4; for(eve1= em->verts.first; eve1; eve1= eve1->next) { for(eve2= em->verts.first; (eve1->f & 1) && eve2; eve2= eve2->next) { if(findedgelist(em, eve1,eve2)) { for(eve3= em->verts.first; (eve2->f & 1) && eve3; eve3= eve3->next) { if((eve2!=eve3 && (eve3->f & 1) && findedgelist(em, eve1,eve3))) { EditEdge *sh_edge= NULL; EditVert *sh_vert= NULL; sh_edge= findedgelist(em, eve2,eve3); if(sh_edge) { /* Add a triangle */ if(!exist_face_overlaps(em, eve1,eve2,eve3,NULL)) fix_new_face(em, addfacelist(em, eve1,eve2,eve3,NULL,NULL,NULL)); } else { /* Check for a shared vertex */ for(eve4= em->verts.first; eve4; eve4= eve4->next) { if(eve4!=eve1 && eve4!=eve2 && eve4!=eve3 && (eve4->f & 1) && !findedgelist(em, eve1,eve4) && findedgelist(em, eve2,eve4) && findedgelist(em, eve3,eve4)) { sh_vert= eve4; break; } } if(sh_vert) { if(sh_vert) { if(!exist_face_overlaps(em, eve1,eve2,eve4,eve3)) fix_new_face(em, addfacelist(em, eve1,eve2,eve4,eve3,NULL,NULL)); } } } } } } } } EM_select_flush(em); // XXX DAG_id_tag_update(obedit->data, 0); }
/* will be new face smooth or solid? depends on smoothness of face neighbours * of new face, if function return 1, then new face will be smooth, when functio * will return zero, then new face will be solid */ static void fix_new_face(EditMesh *em, EditFace *eface) { struct EditFace *efa; struct EditEdge *eed=NULL; struct EditVert *v1 = eface->v1, *v2 = eface->v2, *v3 = eface->v3, *v4 = eface->v4; struct EditVert *ev1=NULL, *ev2=NULL; short smooth=0; /* "total smoothnes" of faces in neighbourhood */ short coef; /* "weight" of smoothness */ short count=0; /* number of edges with same direction as eface */ short vi00=0, vi01=0, vi10=0, vi11=0; /* vertex indexes */ efa = em->faces.first; while(efa) { if(efa==eface) { efa = efa->next; continue; } coef = 0; ev1 = ev2 = NULL; eed = NULL; if(efa->v1==v1 || efa->v2==v1 || efa->v3==v1 || efa->v4==v1) { ev1 = v1; coef++; } if(efa->v1==v2 || efa->v2==v2 || efa->v3==v2 || efa->v4==v2) { if(ev1) ev2 = v2; else ev1 = v2; coef++; } if(efa->v1==v3 || efa->v2==v3 || efa->v3==v3 || efa->v4==v3) { if(coef<2) { if(ev1) ev2 = v3; else ev1 = v3; } coef++; } if((v4) && (efa->v1==v4 || efa->v2==v4 || efa->v3==v4 || efa->v4==v4)) { if(ev1 && coef<2) ev2 = v4; coef++; } /* "democracy" of smoothness */ if(efa->flag & ME_SMOOTH) smooth += coef; else smooth -= coef; /* try to find edge using vertexes ev1 and ev2 */ if((ev1) && (ev2) && (ev1!=ev2)) eed = findedgelist(em, ev1, ev2); /* has bordering edge of efa same direction as edge of eface ? */ if(eed) { if(eed->v1==v1) vi00 = 1; else if(eed->v1==v2) vi00 = 2; else if(eed->v1==v3) vi00 = 3; else if(v4 && eed->v1==v4) vi00 = 4; if(eed->v2==v1) vi01 = 1; else if(eed->v2==v2) vi01 = 2; else if(eed->v2==v3) vi01 = 3; else if(v4 && eed->v2==v4) vi01 = 4; if(v4) { if(vi01==1 && vi00==4) vi00 = 0; if(vi01==4 && vi00==1) vi01 = 0; } else { if(vi01==1 && vi00==3) vi00 = 0; if(vi01==3 && vi00==1) vi01 = 0; } if(eed->v1==efa->v1) vi10 = 1; else if(eed->v1==efa->v2) vi10 = 2; else if(eed->v1==efa->v3) vi10 = 3; else if(efa->v4 && eed->v1==efa->v4) vi10 = 4; if(eed->v2==efa->v1) vi11 = 1; else if(eed->v2==efa->v2) vi11 = 2; else if(eed->v2==efa->v3) vi11 = 3; else if(efa->v4 && eed->v2==efa->v4) vi11 = 4; if(efa->v4) { if(vi11==1 && vi10==4) vi10 = 0; if(vi11==4 && vi10==1) vi11 = 0; } else { if(vi11==1 && vi10==3) vi10 = 0; if(vi11==3 && vi10==1) vi11 = 0; } if(((vi00>vi01) && (vi10>vi11)) || ((vi00<vi01) && (vi10<vi11))) count++; else count--; } efa = efa->next; } /* set up smoothness according voting of face in neighbourhood */ if(smooth >= 0) eface->flag |= ME_SMOOTH; else eface->flag &= ~ME_SMOOTH; /* flip face, when too much "face normals" in neighbourhood is different */ if(count > 0) { flipface(em, eface); } }