updated files from meshfrac_alt
[meshfrac] / src / cmesh.c
index 3492ef2..f686b5c 100644 (file)
@@ -11,7 +11,7 @@
 struct cmesh_vattrib {
        int nelem;      /* num elements per attribute [1, 4] */
        float *data;
-       unsigned int count;
+       unsigned int count;     /* number of floats in data */
        unsigned int vbo;
        int vbo_valid, data_valid;
 };
@@ -33,7 +33,7 @@ struct cmesh {
        char *name;
        unsigned int nverts, nfaces;
 
-       struct submesh *sublist;
+       struct submesh *sublist, *subtail;
        int subcount;
 
        /* current value for each attribute for the immediate mode interface */
@@ -246,7 +246,7 @@ static int clone(struct cmesh *cmdest, const struct cmesh *cmsrc, struct submesh
                        nelem = cmsrc->vattr[i].nelem;
                        cmdest->vattr[i].nelem = nelem;
                        cmdest->vattr[i].data = varr[i];
-                       cmdest->vattr[i].count = vcount;
+                       cmdest->vattr[i].count = vcount * nelem;
                        vptr = cmsrc->vattr[i].data + vstart * nelem;
                        memcpy(cmdest->vattr[i].data, vptr, vcount * nelem * sizeof(float));
                        cmdest->vattr[i].data_valid = 1;
@@ -319,6 +319,7 @@ static int clone(struct cmesh *cmdest, const struct cmesh *cmsrc, struct submesh
                }
 
                cmdest->sublist = head;
+               cmdest->subtail = tail;
                cmdest->subcount = cmsrc->subcount;
        }
 
@@ -669,7 +670,7 @@ int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc)
                        assert(cmdest->vattr[i].nelem == cmsrc->vattr[i].nelem);
                        nelem = cmdest->vattr[i].nelem;
                        origsz = cmdest->nverts * nelem;
-                       newsz = cmdest->nverts + cmsrc->nverts * nelem;
+                       newsz = (cmdest->nverts + cmsrc->nverts) * nelem;
 
                        if(!(vptr = realloc(cmdest->vattr[i].data, newsz * sizeof *vptr))) {
                                return -1;
@@ -704,6 +705,9 @@ int cmesh_append(struct cmesh *cmdest, const struct cmesh *cmsrc)
                }
        }
 
+       cmdest->nverts += cmsrc->nverts;
+       cmdest->nfaces += cmsrc->nfaces;
+
        cmdest->wire_ibo_valid = 0;
        cmdest->aabb_valid = 0;
        cmdest->bsph_valid = 0;
@@ -721,6 +725,7 @@ void cmesh_clear_submeshes(struct cmesh *cm)
                free(sm);
        }
        cm->subcount = 0;
+       cm->subtail = 0;
 }
 
 int cmesh_submesh(struct cmesh *cm, const char *name, int fstart, int fcount)
@@ -760,8 +765,13 @@ int cmesh_submesh(struct cmesh *cm, const char *name, int fstart, int fcount)
                sm->vcount = fcount * 3;
        }
 
-       sm->next = cm->sublist;
-       cm->sublist = sm;
+       sm->next = 0;
+       if(cm->sublist) {
+               cm->subtail->next = sm;
+               cm->subtail = sm;
+       } else {
+               cm->sublist = cm->subtail = sm;
+       }
        cm->subcount++;
        return 0;
 }
@@ -788,10 +798,18 @@ int cmesh_remove_submesh(struct cmesh *cm, int idx)
        free(sm->name);
        free(sm);
 
+       if(cm->subtail == sm) {
+               cm->subtail = prev;
+       }
+
        cm->subcount--;
        assert(cm->subcount >= 0);
 
-       cm->sublist = dummy.next;
+       if(!dummy.next) {
+               cm->sublist = cm->subtail = 0;
+       } else {
+               cm->sublist = dummy.next;
+       }
        return 0;
 }
 
@@ -930,6 +948,10 @@ void cmesh_apply_xform(struct cmesh *cm, float *xform, float *dir_xform)
        cgm_vec3 n, t;
        float *vptr;
 
+       if(!dir_xform) {
+               dir_xform = xform;
+       }
+
        for(i=0; i<cm->nverts; i++) {
                if(!(vptr = get_vec4(cm, CMESH_ATTR_VERTEX, i, &v))) {
                        return;
@@ -1561,6 +1583,7 @@ int cmesh_dump_obj_file(const struct cmesh *cm, FILE *fp, int voffs)
        static const char *fmtstr[] = {" %u", " %u//%u", " %u/%u", " %u/%u/%u"};
        int i, j, num, nelem;
        unsigned int aflags = 0;
+       const struct submesh *sub = cm->sublist;
 
        if(!cmesh_has_attrib(cm, CMESH_ATTR_VERTEX)) {
                return -1;
@@ -1607,6 +1630,11 @@ int cmesh_dump_obj_file(const struct cmesh *cm, FILE *fp, int voffs)
                assert(numidx % 3 == 0);
 
                for(i=0; i<numtri; i++) {
+                       if(sub && sub->istart <= *idxptr) {
+                               fprintf(fp, "o %s\n", sub->name);
+                               sub = sub->next;
+                       }
+
                        fputc('f', fp);
                        for(j=0; j<3; j++) {
                                unsigned int idx = *idxptr++ + 1 + voffs;
@@ -1618,6 +1646,11 @@ int cmesh_dump_obj_file(const struct cmesh *cm, FILE *fp, int voffs)
                int numtri = cm->nverts / 3;
                unsigned int idx = 1 + voffs;
                for(i=0; i<numtri; i++) {
+                       if(sub && sub->vstart == idx - 1) {
+                               fprintf(fp, "o %s\n", sub->name);
+                               sub = sub->next;
+                       }
+
                        fputc('f', fp);
                        for(j=0; j<3; j++) {
                                fprintf(fp, fmtstr[aflags], idx, idx, idx);