MVertex_ptr MVs_Merge_R3R4(MVertex_ptr v1, MVertex_ptr v2, int topoflag) { int idx, gdim, gid, nsets; MFace_ptr face; Mesh_ptr mesh; List_ptr vfaces2; MSet_ptr mset; mesh = MV_Mesh(v1); gid = MV_GEntID(v1); gdim = MV_GEntDim(v1); if (mesh != MF_Mesh(v2)) { MSTK_Report("MVs_Join","Vertices not from same mesh",MSTK_ERROR); return 0; } else if (topoflag) { /* Make sure model topology is not violated */ if (gid != MV_GEntID(v2) || gdim != MV_GEntDim(v2)) { MSTK_Report("MFs_Join","Faces not from same geometric entity",MSTK_ERROR); return 0; } } vfaces2 = MV_Faces(v2); if (vfaces2) { idx = 0; while ((face = List_Next_Entry(vfaces2,&idx))) MF_Replace_Vertex(face,v2,v1); List_Delete(vfaces2); } nsets = MESH_Num_MSets(mesh); if(nsets) { idx = 0; while ((mset = (MSet_ptr) MESH_Next_MSet(mesh,&idx))) { if (MSet_Contains(mset, v2)) { if(MSet_Contains(mset, v1)) MSet_Rem(mset, v2); else MSet_Replace(mset, v2, v1); } } } MV_Delete(v2,1); return v1; }
MVertex_ptr MVs_Merge_R1R2(MVertex_ptr v1, MVertex_ptr v2, int topoflag) { int i, idx, gdim, gid; MFace_ptr face; MRegion_ptr region; Mesh_ptr mesh; List_ptr vfaces2, vregions2; mesh = MV_Mesh(v1); gid = MV_GEntID(v1); gdim = MV_GEntDim(v1); if (mesh != MF_Mesh(v2)) { MSTK_Report("MVs_Join","Vertices not from same mesh",MSTK_ERROR); return 0; } else if (topoflag) { /* make sure geometric model topology is not violated */ if (gid != MV_GEntID(v2) || gdim != MV_GEntDim(v2)) { MSTK_Report("MFs_Join","Faces not from same geometric entity",MSTK_ERROR); return 0; } } vfaces2 = MV_Faces(v2); if (vfaces2) { idx = 0; while ((face = List_Next_Entry(vfaces2,&idx))) MF_Replace_Vertex(face,v2,v1); List_Delete(vfaces2); } vregions2 = MV_Regions(v2); if (vregions2) { idx = 0; while ((region = List_Next_Entry(vregions2,&idx))) MR_Replace_Vertex(region,v2,v1); List_Delete(vregions2); } MV_Delete(v2,0); return v1; }
void MF_Insert_Vertex_i_R2(MFace_ptr f, MVertex_ptr nuv, int i) { MFace_Adj_R2 *adj; adj = (MFace_Adj_R2 *) f->adj; if (adj->fvertices == NULL) adj->fvertices = List_New(4); #ifdef DEBUG if (MF_Mesh(f) != MV_Mesh(nuv)) MSTK_Report("MF_Replace_Vertex_R2", "Face and Vertex are not from the same mesh", MSTK_FATAL); #endif List_Inserti(adj->fvertices,nuv,i); }
void MF_Replace_Vertex_R2(MFace_ptr f, MVertex_ptr v, MVertex_ptr nuv) { MFace_Adj_R2 *adj; adj = (MFace_Adj_R2 *) f->adj; if (adj->fvertices == NULL) MSTK_Report("MF_Replace_Vertex_R2", "No initial set of vertices for face",MSTK_ERROR); #ifdef DEBUG if (MF_Mesh(f) != MV_Mesh(v)) MSTK_Report("MF_Replace_Vertex_R2", "Face and Vertex are not from the same mesh", MSTK_FATAL); #endif List_Replace(adj->fvertices,v,nuv); }
void MF_Set_Vertices_R2(MFace_ptr f, int n, MVertex_ptr *v) { MFace_Adj_R2 *adj; int i; adj = (MFace_Adj_R2 *) f->adj; if (adj->fvertices) List_Delete(adj->fvertices); adj->fvertices = List_New(n); for (i = 0; i < n; i++) { #ifdef DEBUG if (MF_Mesh(f) != MV_Mesh(v[i])) MSTK_Report("MF_Set_Vertices_R2", "Face and Vertex are not from the same mesh", MSTK_FATAL); #endif List_Add(adj->fvertices,v[i]); } }
MVertex_ptr MF_Split(MFace_ptr fsplit, double *splitxyz) { Mesh_ptr mesh; MVertex_ptr vsplit, fv[3]; MEdge_ptr enew, *fedges0, *fedges1, fe; MFace_ptr fnew[MAXPV2]; MRegion_ptr fr; int gid, gdim, i, j, idx, nnew; int nfv, fnewdir[MAXPV2], rfdir; List_ptr fregs, fverts; gdim = MF_GEntDim(fsplit); gid = MF_GEntID(fsplit); /* Collect information */ mesh = MF_Mesh(fsplit); /* Regions connected to face */ fregs = MF_Regions(fsplit); /* Vertices of face */ fverts = MF_Vertices(fsplit,1,0); nfv = List_Num_Entries(fverts); /* Create the splitting vertex */ vsplit = MV_New(mesh); MV_Set_Coords(vsplit,splitxyz); MV_Set_GEntDim(vsplit,gdim); MV_Set_GEntID(vsplit,gid); /* Create the 'nfe' faces */ for (i = 0; i < nfv; i++) { fv[0] = vsplit; fv[1] = List_Entry(fverts,i); fv[2] = List_Entry(fverts,(i+1)%nfv); fnew[i] = MF_New(mesh); MF_Set_GEntDim(fnew[i],gdim); MF_Set_GEntID(fnew[i],gid); MF_Set_Vertices(fnew[i],3,fv); } List_Delete(fverts); nnew = nfv; if (fregs) { for (i = 0; i < List_Num_Entries(fregs); i++) { fr = List_Entry(fregs,i); rfdir = MR_FaceDir(fr,fsplit); for (j = 0; j < nnew; j++) fnewdir[j] = rfdir; MR_Replace_Faces(fr,1,&fsplit,nnew,fnew,fnewdir); } List_Delete(fregs); } MF_Delete(fsplit,0); return vsplit; }
MRegion_ptr MRs_Join(MRegion_ptr r1, MRegion_ptr r2, MFace_ptr f) { int i, j, nrf1, nrf2, gdim, gid, *rfdir2; MFace_ptr *rf2, fcmn=f; Mesh_ptr mesh; List_ptr rfaces2; mesh = MF_Mesh(r1); gid = MF_GEntID(r1); if (mesh != MF_Mesh(r2)) { MSTK_Report("MRs_Join","Regions not from same mesh",MSTK_ERROR); return 0; } else if (gid != MR_GEntID(r2)) { MSTK_Report("MRs_Join","Regions not from same geometric entity",MSTK_ERROR); return 0; } rfaces2 = MR_Faces(r2); nrf2 = List_Num_Entries(rfaces2); if (fcmn) { if (!MR_UsesEntity(r1,fcmn,MFACE)) { MSTK_Report("MRs_Join","Cannot find common face in region",MSTK_ERROR); return 0; } } else { /* find the common face */ List_ptr rfaces1 = MR_Faces(r1); int idx = 0; MFace_ptr rf; while ((rf = List_Next_Entry(rfaces2,&idx))) { if (List_Contains(rfaces1,rf)) { fcmn = rf; break; } } List_Delete(rfaces1); } rf2 = (MFace_ptr) malloc(nrf2*sizeof(MFace_ptr)); rfdir2 = (int *) malloc(nrf2*sizeof(int)); int found; for (i = 0, j = 0, found = 0; i < nrf2; i++) { MFace_ptr rface = List_Entry(rfaces2,i); if (rface == fcmn) found = 1; else { rf2[j] = rface; rfdir2[j] = MR_FaceDir_i(r2,i); j++; } } List_Delete(rfaces2); if (!found) { MSTK_Report("MRs_Join","Cannot find common face in region",MSTK_ERROR); return 0; } MR_Delete(r2,0); MR_Replace_Faces(r1,1,&fcmn,nrf2-1,rf2,rfdir2); MF_Delete(fcmn,0); free(rf2); free(rfdir2); return r1; }
MVertex_ptr MF_Split_SimplexMesh(MFace_ptr fsplit, double *splitxyz) { int i, j, k, rfdir=1, ntets=0, ntris=0, *rid=NULL, fgdim, fgid, found; MVertex_ptr vsplit, ev[2], (*tetverts)[4]=NULL, triverts[3], fv; MVertex_ptr fvarr[3], rvarr[4]; MFace_ptr f; MRegion_ptr r; List_ptr fedges, ftets, rfaces, fverts; Mesh_ptr mesh = MF_Mesh(fsplit); /* point is not on the boundary of the face */ ftets = MF_Regions(fsplit); if (ftets) { ntets = List_Num_Entries(ftets); tetverts = (MVertex_ptr (*)[4]) malloc(ntets*sizeof(MVertex_ptr [4])); rid = (int *) malloc(ntets*sizeof(int)); } for (i = 0; i < ntets; i++) { r = List_Entry(ftets,i); rfaces = MR_Faces(r); /* Find the face to be split and get the first three vertices in a suitable order from it. Also, find another face and get a vertex that is not in the face to be split. This vertex forms the fourth vertex of the tet */ for (j = 0; j < 4; j++) { f = List_Entry(rfaces,j); if (f == fsplit) { rfdir = MR_FaceDir_i(r,j); fverts = MF_Vertices(f,!rfdir,0); for (k = 0; k < 3; k++) { tetverts[i][0] = List_Entry(fverts,0); tetverts[i][1] = List_Entry(fverts,1); tetverts[i][2] = List_Entry(fverts,2); } List_Delete(fverts); break; } } found = 0; for (j = 0; j < 4; j++) { f = List_Entry(rfaces,j); if (f != fsplit) { fverts = MF_Vertices(f,!rfdir,0); for (k = 0; k < 3; k++) { fv = List_Entry(fverts,k); if (!MF_UsesEntity(fsplit,fv,MVERTEX)) { tetverts[i][3] = fv; found = 1; break; } } List_Delete(fverts); } if (found) break; } List_Delete(rfaces); } /* Now that we finished collecting info about the connected tets we can delete them */ if (ftets) { for (i = 0; i < ntets; i++) MR_Delete(List_Entry(ftets,i),0); List_Delete(ftets); } /* Delete the face itself */ fverts = MF_Vertices(fsplit,1,0); for (i = 0; i < 3; i++) triverts[i] = List_Entry(fverts,i); List_Delete(fverts); fgdim = MF_GEntDim(fsplit); fgid = MF_GEntID(fsplit); /* Split the face */ vsplit = MF_Split(fsplit, splitxyz); /* Create three tets for each tet that was deleted */ for (i = 0; i < ntets; i++) { for (j = 0; j < 3; j++) { r = MR_New(mesh); rvarr[0] = vsplit; rvarr[1] = tetverts[i][j]; rvarr[2] = tetverts[i][(j+1)%3]; rvarr[3] = tetverts[i][3]; MR_Set_Vertices(r, 4, rvarr, 0, NULL); MR_Set_GEntID(r,rid[i]); } } if (ntets) { free(tetverts); free(rid); } return vsplit; }