/* * NAME: node->delete() * DESCRIPTION: remove a record from a node */ int n_delete(node *np, byte *record, int *flag) { byte *rec; rec = HFS_NODEREC(*np, np->rnum); HFS_SETKEYLEN(rec, 0); compact(np); if (np->nd.ndNRecs == 0) { if (n_free(np) == -1) goto fail; HFS_SETKEYLEN(record, 0); *flag = 1; return 0; } /* see if we can join with our left sibling */ if (np->nd.ndBLink > 0) { node left; if (bt_getnode(&left, np->bt, np->nd.ndBLink) == -1) goto fail; if (np->nd.ndNRecs + left.nd.ndNRecs <= HFS_MAX_NRECS && NODEUSED(*np) + 2 * np->nd.ndNRecs <= NODEFREE(left)) return join(&left, np, record, flag); } if (np->rnum == 0) { /* special case: first record changed; update parent record key */ n_index(np, record, 0); *flag = 1; } return bt_putnode(np); fail: return -1; }
/* * NAME: node->delete() * DESCRIPTION: remove a record from a node */ int n_delete(node *np, unsigned char *record, int *flag) { node left; unsigned char *rec; rec = HFS_NODEREC(*np, np->rnum); HFS_RECKEYLEN(rec) = 0; n_compact(np); /* see if we can merge with our left sibling */ left.bt = np->bt; left.nnum = np->nd.ndBLink; if (left.nnum > 0) { if (bt_getnode(&left) < 0) return -1; if ((int)(np->nd.ndNRecs + left.nd.ndNRecs) <= HFS_MAXRECS && (int)(np->roff[np->nd.ndNRecs] - np->roff[0] + 2 * np->nd.ndNRecs) <= (int)NODESPACE(left)) return n_merge(np, &left, record, flag); } if (np->rnum == 0) { /* special case: first record changed; update parent record key */ n_index(np->bt, HFS_NODEREC(*np, 0), np->nnum, record, 0); *flag = 1; } return bt_putnode(np); }
/* * NAME: split() * DESCRIPTION: divide a node into two and insert a record */ static int split(node *left, byte *record, unsigned int *reclen) { btree *bt = left->bt; node n, *right = &n, *side = 0; int mark, i; /* create a second node by cloning the first */ *right = *left; if (n_new(right) == -1) goto fail; left->nd.ndFLink = right->nnum; right->nd.ndBLink = left->nnum; /* divide all records evenly between the two nodes */ mark = (NODEUSED(*left) + 2 * left->nd.ndNRecs + *reclen + 2) >> 1; if (left->rnum == -1) { side = left; mark -= *reclen + 2; } for (i = 0; i < left->nd.ndNRecs; ++i) { node *np; byte *rec; np = (mark > 0) ? right : left; rec = HFS_NODEREC(*np, i); mark -= HFS_RECLEN(*np, i) + 2; HFS_SETKEYLEN(rec, 0); if (left->rnum == i) { side = (mark > 0) ? left : right; mark -= *reclen + 2; } } compact(left); compact(right); /* insert the new record and store the modified nodes */ ASSERT(side); n_search(side, record); n_insertx(side, record, *reclen); if (bt_putnode(left) == -1 || bt_putnode(right) == -1) goto fail; /* create an index record in the parent for the new node */ n_index(right, record, reclen); /* update link pointers */ if (bt->hdr.bthLNode == left->nnum) { bt->hdr.bthLNode = right->nnum; bt->flags |= HFS_BT_UPDATE_HDR; } if (right->nd.ndFLink > 0) { node sib; if (bt_getnode(&sib, right->bt, right->nd.ndFLink) == -1) goto fail; sib.nd.ndBLink = right->nnum; if (bt_putnode(&sib) == -1) goto fail; } return 0; fail: return -1; }
//read vertices, normals and vertex indices from CG1 atoff files bool read_atoff_object(string& filename, std::vector<float>& vertices_out, std::vector<float>& normals_out, std::vector<unsigned int>& indices_out) { std::ifstream fp_in; fp_in.open(filename.c_str(), std::ios::in); string header; fp_in >> header; //"ATOFF" int num_vertices, num_normals, num_colors, num_edges, num_faces; fp_in >> num_vertices >> num_normals >> num_colors >> num_edges >> num_faces; //setup normals_out to be the same size as indices_out normals_out = std::vector<float>(num_vertices*4); std::vector<float> normals_temp; //read vertices float x,y,z; for (int i=0; i < num_vertices; i++) { fp_in >> x >> y >> z; vertices_out.push_back(x); vertices_out.push_back(y); vertices_out.push_back(z); vertices_out.push_back(1.0f); //homogenous coordinate } //read normals (into temporary vector) for (int i=0; i < num_normals; i++) { fp_in >> x >> y >> z; normals_temp.push_back(x); normals_temp.push_back(y); normals_temp.push_back(z); } //read colors (and discard them) int discard; for (int i=0; i < num_colors*3; i++) { fp_in >> discard; } //read faces, i.e., indices int face; //for each face for (face=0; face < num_faces;face++) { int verts_per_face; fp_in >> verts_per_face; std::vector<int> v_index(4); for (int vert=0; vert < verts_per_face; vert++) { fp_in >> v_index[vert]; } //read normal indices and fill normals_out to match vertex indices std::vector<int> n_index(4); if (num_normals > 0) { for (int norm=0; norm < verts_per_face; norm++) { fp_in >> n_index[norm]; } for (int norm=0; norm < verts_per_face; norm++) { //put the normals at the same index as the corresponding vertex normals_out[3*v_index[norm]] = normals_temp[3*n_index[norm]]; normals_out[3*v_index[norm]+1] = normals_temp[3*n_index[norm]+1]; normals_out[3*v_index[norm]+2] = normals_temp[3*n_index[norm]+2]; } } else { fp_in >> discard; //discard "-1" } //discard color index fp_in >> discard; //append indices to output if (verts_per_face == 3) { indices_out.push_back(v_index[0]); indices_out.push_back(v_index[1]); indices_out.push_back(v_index[2]); } //split quads into 2 triangles else if (verts_per_face == 4) { //triangle 1 indices_out.push_back(v_index[0]); indices_out.push_back(v_index[1]); indices_out.push_back(v_index[2]); //triangle 2 indices_out.push_back(v_index[2]); indices_out.push_back(v_index[3]); indices_out.push_back(v_index[0]); } else { std::cout << "error: file contains faces > QUAD!\n";} }
/* * NAME: node->split() * DESCRIPTION: divide a node into two and insert a record */ int n_split(node *left, unsigned char *record, int *reclen) { node right; int nrecs, i, mid; unsigned char *rec; right = *left; right.nd.ndBLink = left->nnum; if (n_new(&right) < 0) return -1; left->nd.ndFLink = right.nnum; nrecs = left->nd.ndNRecs; /* * Ensure node split leaves enough room for new record. * The size calculations used are based on the NODESPACE() macro, but * I don't know what the extra 2's and 1's are needed for. * John Witford <*****@*****.**> */ n_search(&right, record); mid = nrecs/2; for(;;) { if (right.rnum < mid) { if ( mid > 0 && (int)left->roff[mid] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1)) { --mid; if (mid > 0) continue; } } else { if ( mid < nrecs && (int)right.roff[nrecs] - (int)right.roff[mid] + (int)left->roff[0] + *reclen + 2 > HFS_BLOCKSZ - 2 * (mid + 1)) { ++mid; if (mid < nrecs) continue; } } break; } for (i = 0; i < nrecs; ++i) { if (i < mid) rec = HFS_NODEREC(right, i); else rec = HFS_NODEREC(*left, i); HFS_RECKEYLEN(rec) = 0; } /* original code ... for (i = 0; i < nrecs; ++i) { if (i < nrecs / 2) rec = HFS_NODEREC(right, i); else rec = HFS_NODEREC(*left, i); HFS_RECKEYLEN(rec) = 0; } */ n_compact(left); n_compact(&right); n_search(&right, record); if (right.rnum >= 0) n_insertx(&right, record, *reclen); else { n_search(left, record); n_insertx(left, record, *reclen); } /* store the new/modified nodes */ if (bt_putnode(left) < 0 || bt_putnode(&right) < 0) return -1; /* create an index record for the new node in the parent */ n_index(right.bt, HFS_NODEREC(right, 0), right.nnum, record, reclen); /* update link pointers */ if (left->bt->hdr.bthLNode == left->nnum) { left->bt->hdr.bthLNode = right.nnum; left->bt->flags |= HFS_UPDATE_BTHDR; } if (right.nd.ndFLink) { node n; n.bt = right.bt; n.nnum = right.nd.ndFLink; if (bt_getnode(&n) < 0) return -1; n.nd.ndBLink = right.nnum; if (bt_putnode(&n) < 0) return -1; } return 0; }
/* * NAME: node->split() * DESCRIPTION: divide a node into two and insert a record */ int n_split(node *left, unsigned char *record, int *reclen) { node right; int nrecs, i; unsigned char *rec; right = *left; right.nd.ndBLink = left->nnum; if (n_new(&right) < 0) return -1; left->nd.ndFLink = right.nnum; nrecs = left->nd.ndNRecs; for (i = 0; i < nrecs; ++i) { if (i < nrecs / 2) rec = HFS_NODEREC(right, i); else rec = HFS_NODEREC(*left, i); HFS_RECKEYLEN(rec) = 0; } n_compact(left); n_compact(&right); n_search(&right, record); if (right.rnum >= 0) n_insertx(&right, record, *reclen); else { n_search(left, record); n_insertx(left, record, *reclen); } /* store the new/modified nodes */ if (bt_putnode(left) < 0 || bt_putnode(&right) < 0) return -1; /* create an index record for the new node in the parent */ n_index(right.bt, HFS_NODEREC(right, 0), right.nnum, record, reclen); /* update link pointers */ if (left->bt->hdr.bthLNode == left->nnum) { left->bt->hdr.bthLNode = right.nnum; left->bt->flags |= HFS_UPDATE_BTHDR; } if (right.nd.ndFLink) { node n; n.bt = right.bt; n.nnum = right.nd.ndFLink; if (bt_getnode(&n) < 0) return -1; n.nd.ndBLink = right.nnum; if (bt_putnode(&n) < 0) return -1; } return 0; }