Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2010-03-05 19:47:52 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2010-03-05 19:47:52 +0300
commitd0c70ad1d581d69f650d604293c006b2e0023310 (patch)
treeb0fdfd5063ed11dd875ca602f8bbf09f5c4cdb8f /source/blender/blenkernel/intern/mesh.c
parentbf4d8ffe3ab8a85a8e3071d54a1eaf84960ddae3 (diff)
Constructive modifiers for curves and surfaces
Used approach with creating DerivedMesh for curves whet they've got such modifiers. Available modifiers are: array, edge split, mirror, solidify, subsurf.
Diffstat (limited to 'source/blender/blenkernel/intern/mesh.c')
-rw-r--r--source/blender/blenkernel/intern/mesh.c166
1 files changed, 117 insertions, 49 deletions
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index d629acf8747..c0dd3c7e43a 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -563,31 +563,49 @@ static int vergedgesort(const void *v1, const void *v2)
return 0;
}
-void make_edges(Mesh *me, int old)
+static void mfaces_strip_loose(MFace *mface, int *totface)
+{
+ int a,b;
+
+ for (a=b=0; a<*totface; a++) {
+ if (mface[a].v3) {
+ if (a!=b) {
+ memcpy(&mface[b],&mface[a],sizeof(mface[b]));
+ }
+ b++;
+ }
+ }
+
+ *totface= b;
+}
+
+/* Create edges based on known verts and faces */
+static void make_edges_mdata(MVert *allvert, MFace *allface, int totvert, int totface,
+ int old, MEdge **alledge, int *_totedge)
{
MFace *mface;
MEdge *medge;
struct edgesort *edsort, *ed;
int a, totedge=0, final=0;
-
+
/* we put all edges in array, sort them, and detect doubles that way */
-
- for(a= me->totface, mface= me->mface; a>0; a--, mface++) {
+
+ for(a= totface, mface= allface; a>0; a--, mface++) {
if(mface->v4) totedge+=4;
else if(mface->v3) totedge+=3;
else totedge+=1;
}
-
+
if(totedge==0) {
/* flag that mesh has edges */
- me->medge = MEM_callocN(0, "make mesh edges");
- me->totedge = 0;
+ (*alledge)= MEM_callocN(0, "make mesh edges");
+ (*_totedge) = 0;
return;
}
-
+
ed= edsort= MEM_mallocN(totedge*sizeof(struct edgesort), "edgesort");
-
- for(a= me->totface, mface= me->mface; a>0; a--, mface++) {
+
+ for(a= totface, mface= allface; a>0; a--, mface++) {
to_edgesort(ed++, mface->v1, mface->v2, !mface->v3, mface->edcode & ME_V1V2);
if(mface->v4) {
to_edgesort(ed++, mface->v2, mface->v3, 0, mface->edcode & ME_V2V3);
@@ -599,21 +617,19 @@ void make_edges(Mesh *me, int old)
to_edgesort(ed++, mface->v3, mface->v1, 0, mface->edcode & ME_V3V1);
}
}
-
+
qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
-
+
/* count final amount */
for(a=totedge, ed=edsort; a>1; a--, ed++) {
/* edge is unique when it differs from next edge, or is last */
if(ed->v1 != (ed+1)->v1 || ed->v2 != (ed+1)->v2) final++;
}
final++;
-
- medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, final);
- me->medge= medge;
- me->totedge= final;
-
+ (*alledge)= medge= MEM_callocN(sizeof (MEdge) * final, "make_edges mdge");
+ (*_totedge)= final;
+
for(a=totedge, ed=edsort; a>1; a--, ed++) {
/* edge is unique when it differs from next edge, or is last */
if(ed->v1 != (ed+1)->v1 || ed->v2 != (ed+1)->v2) {
@@ -636,6 +652,24 @@ void make_edges(Mesh *me, int old)
medge->flag |= ME_EDGERENDER;
MEM_freeN(edsort);
+}
+
+void make_edges(Mesh *me, int old)
+{
+ MEdge *medge;
+ int totedge=0;
+
+ make_edges_mdata(me->mvert, me->mface, me->totvert, me->totface, old, &medge, &totedge);
+ if(totedge==0) {
+ /* flag that mesh has edges */
+ me->medge = medge;
+ me->totedge = 0;
+ return;
+ }
+
+ medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge);
+ me->medge= medge;
+ me->totedge= totedge;
mesh_strip_loose_faces(me);
}
@@ -657,7 +691,6 @@ void mesh_strip_loose_faces(Mesh *me)
me->totface = b;
}
-
void mball_to_mesh(ListBase *lb, Mesh *me)
{
DispList *dl;
@@ -711,12 +744,12 @@ void mball_to_mesh(ListBase *lb, Mesh *me)
}
}
-/* this may fail replacing ob->data, be sure to check ob->type */
-void nurbs_to_mesh(Object *ob)
+/* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
+/* return non-zero on error */
+int nurbs_to_mdata(Object *ob, MVert **allvert, int *_totvert,
+ MEdge **alledge, int *_totedge, MFace **allface, int *_totface)
{
- Object *ob1;
DispList *dl;
- Mesh *me;
Curve *cu;
MVert *mvert;
MFace *mface;
@@ -750,26 +783,15 @@ void nurbs_to_mesh(Object *ob)
}
dl= dl->next;
}
+
if(totvert==0) {
/* error("can't convert"); */
/* Make Sure you check ob->data is a curve */
- return;
+ return -1;
}
- /* make mesh */
- me= add_mesh("Mesh");
- me->totvert= totvert;
- me->totface= totvlak;
-
- me->totcol= cu->totcol;
- me->mat= cu->mat;
- cu->mat= 0;
- cu->totcol= 0;
-
- mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
- mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
- me->mvert= mvert;
- me->mface= mface;
+ *allvert= mvert= MEM_callocN(sizeof (MVert) * totvert, "nurbs_init mvert");
+ *allface= mface= MEM_callocN(sizeof (MVert) * totvert, "nurbs_init mface");
/* verts and faces */
vertcount= 0;
@@ -777,7 +799,7 @@ void nurbs_to_mesh(Object *ob)
dl= cu->disp.first;
while(dl) {
int smooth= dl->rt & CU_SMOOTH ? 1 : 0;
-
+
if(dl->type==DL_SEGM) {
startvert= vertcount;
a= dl->parts*dl->nr;
@@ -812,7 +834,7 @@ void nurbs_to_mesh(Object *ob)
vertcount++;
mvert++;
}
-
+
for(a=0; a<dl->parts; a++) {
ofs= a*dl->nr;
for(b=0; b<dl->nr; b++) {
@@ -844,13 +866,13 @@ void nurbs_to_mesh(Object *ob)
mface->v3= startvert+index[1];
mface->v4= 0;
test_index_face(mface, NULL, 0, 3);
-
+
if(smooth) mface->flag |= ME_SMOOTH;
mface++;
index+= 3;
}
-
-
+
+
}
else if(dl->type==DL_SURF) {
startvert= vertcount;
@@ -893,13 +915,13 @@ void nurbs_to_mesh(Object *ob)
mface->v4= p2;
mface->mat_nr= (unsigned char)dl->col;
test_index_face(mface, NULL, 0, 4);
-
+
if(smooth) mface->flag |= ME_SMOOTH;
mface++;
- p4= p3;
+ p4= p3;
p3++;
- p2= p1;
+ p2= p1;
p1++;
}
}
@@ -909,15 +931,62 @@ void nurbs_to_mesh(Object *ob)
dl= dl->next;
}
- make_edges(me, 0); // all edges
- mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+ *_totvert= totvert;
+ *_totface= totvlak;
+
+ make_edges_mdata(*allvert, *allface, totvert, totvlak, 0, alledge, _totedge);
+ mfaces_strip_loose(*allface, _totface);
+
+ return 0;
+}
+
+/* this may fail replacing ob->data, be sure to check ob->type */
+void nurbs_to_mesh(Object *ob)
+{
+ Object *ob1;
+ DerivedMesh *dm= ob->derivedFinal;
+ Mesh *me;
+ Curve *cu;
+ MVert *allvert= NULL;
+ MEdge *alledge= NULL;
+ MFace *allface= NULL;
+ int totvert, totedge, totface;
+
+ cu= ob->data;
+
+ if (dm == NULL) {
+ if (nurbs_to_mdata (ob, &allvert, &totvert, &alledge, &totedge, &allface, &totface) != 0) {
+ /* Error initializing */
+ return;
+ }
+
+ /* make mesh */
+ me= add_mesh("Mesh");
+ me->totvert= totvert;
+ me->totface= totface;
+ me->totedge= totedge;
+
+ me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_REFERENCE, allvert, me->totvert);
+ me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_REFERENCE, allface, me->totface);
+ me->medge= CustomData_add_layer(&me->edata, CD_MEDGE, CD_REFERENCE, alledge, me->totedge);
+
+ mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL);
+ } else {
+ me= add_mesh("Mesh");
+ DM_to_mesh(dm, me);
+ }
+
+ me->totcol= cu->totcol;
+ me->mat= cu->mat;
+ cu->mat= 0;
+ cu->totcol= 0;
if(ob->data) {
free_libblock(&G.main->curve, ob->data);
}
ob->data= me;
ob->type= OB_MESH;
-
+
/* other users */
ob1= G.main->object.first;
while(ob1) {
@@ -929,7 +998,6 @@ void nurbs_to_mesh(Object *ob)
}
ob1= ob1->id.next;
}
-
}
typedef struct EdgeLink {