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
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')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_cdderivedmesh.h3
-rw-r--r--source/blender/blenkernel/BKE_displist.h3
-rw-r--r--source/blender/blenkernel/BKE_mesh.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c36
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c30
-rw-r--r--source/blender/blenkernel/intern/displist.c239
-rw-r--r--source/blender/blenkernel/intern/mesh.c166
-rw-r--r--source/blender/blenkernel/intern/modifier.c30
-rw-r--r--source/blender/blenkernel/intern/object.c2
10 files changed, 391 insertions, 123 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 883a3809b30..154c6347f50 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -538,5 +538,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm,
void DM_add_tangent_layer(DerivedMesh *dm);
+/* Set object's bounding box based on DerivedMesh min/max data */
+void DM_set_object_boundbox(struct Object *ob, DerivedMesh *dm);
+
#endif
diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h
index 269dcbb4141..77a8ef518e9 100644
--- a/source/blender/blenkernel/BKE_cdderivedmesh.h
+++ b/source/blender/blenkernel/BKE_cdderivedmesh.h
@@ -54,6 +54,9 @@ struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob);
/* creates a CDDerivedMesh from the given EditMesh */
struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me);
+/* creates a CDDerivedMesh from the given curve object */
+struct DerivedMesh *CDDM_from_curve(struct Object *ob);
+
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
*/
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index a250456f5c1..2baefc83678 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -102,5 +102,8 @@ void fastshade_free_render(void);
float calc_taper(struct Scene *scene, struct Object *taperobj, int cur, int tot);
+/* add Orco layer to the displist object which has got derived mesh and return orco */
+float *makeOrcoDispList(struct Scene *scene, struct Object *ob, int forRender);
+
#endif
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 0952871e28a..a82e3ffe45b 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -70,6 +70,8 @@ int test_index_face(struct MFace *mface, struct CustomData *mfdata, int mfindex,
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);
void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
+int nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *_totvert,
+ struct MEdge **alledge, int *_totedge, struct MFace **allface, int *_totface);
void nurbs_to_mesh(struct Object *ob);
void mesh_to_curve(struct Scene *scene, struct Object *ob);
void free_dverts(struct MDeformVert *dvert, int totvert);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index fa6c2f333ee..28b093cd693 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2126,7 +2126,6 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
int editing = paint_facesel_test(ob);
/* weight paint and face select need original indicies because of selection buffer drawing */
int needMapping = (ob==obact) && (editing || (ob->mode & OB_MODE_WEIGHT_PAINT) || editing);
- float min[3], max[3];
clear_mesh_caches(ob);
@@ -2134,13 +2133,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
&ob->derivedFinal, 0, 1,
needMapping, dataMask, -1, 1);
- INIT_MINMAX(min, max);
-
- ob->derivedFinal->getMinMax(ob->derivedFinal, min, max);
-
- if(!ob->bb)
- ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
- boundbox_set_from_min_max(ob->bb, min, max);
+ DM_set_object_boundbox (ob, ob->derivedFinal);
ob->derivedFinal->needsFree = 0;
ob->derivedDeform->needsFree = 0;
@@ -2149,8 +2142,6 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
{
- float min[3], max[3];
-
clear_mesh_caches(obedit);
if (em->derivedFinal) {
@@ -2167,16 +2158,9 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
}
editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
- em->lastDataMask = dataMask;
-
- INIT_MINMAX(min, max);
-
- em->derivedFinal->getMinMax(em->derivedFinal, min, max);
-
- if(!obedit->bb)
- obedit->bb= MEM_callocN(sizeof(BoundBox), "bb");
- boundbox_set_from_min_max(obedit->bb, min, max);
+ DM_set_object_boundbox (obedit, em->derivedFinal);
+ em->lastDataMask = dataMask;
em->derivedFinal->needsFree = 0;
em->derivedCage->needsFree = 0;
}
@@ -2624,3 +2608,17 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
}
}
+/* Set object's bounding box based on DerivedMesh min/max data */
+void DM_set_object_boundbox(Object *ob, DerivedMesh *dm)
+{
+ float min[3], max[3];
+
+ INIT_MINMAX(min, max);
+
+ dm->getMinMax(dm, min, max);
+
+ if(!ob->bb)
+ ob->bb= MEM_callocN(sizeof(BoundBox), "bb");
+
+ boundbox_set_from_min_max(ob->bb, min, max);
+}
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index a3924e6c1ed..d0e50dc97a8 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1585,6 +1585,36 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
return dm;
}
+DerivedMesh *CDDM_from_curve(Object *ob)
+{
+ DerivedMesh *dm;
+ CDDerivedMesh *cddm;
+ MVert *allvert;
+ MEdge *alledge;
+ MFace *allface;
+ int totvert, totedge, totface;
+
+ if (nurbs_to_mdata (ob, &allvert, &totvert, &alledge, &totedge, &allface, &totface) != 0) {
+ /* Error initializing mdata. This often happens when curve is empty */
+ return CDDM_new(0, 0, 0);
+ }
+
+ dm = CDDM_new(totvert, totedge, totface);
+ dm->deformedOnly = 1;
+
+ cddm = (CDDerivedMesh*)dm;
+
+ memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
+ memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
+ memcpy(cddm->mface, allface, totface*sizeof(MFace));
+
+ MEM_freeN(allvert);
+ MEM_freeN(alledge);
+ MEM_freeN(allface);
+
+ return dm;
+}
+
DerivedMesh *CDDM_copy(DerivedMesh *source)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 91716ce7266..b8b5ae300d9 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -65,6 +65,7 @@
#include "BKE_displist.h"
#include "BKE_deform.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_object.h"
#include "BKE_world.h"
#include "BKE_mesh.h"
@@ -1209,7 +1210,7 @@ void makeDispListMBall(Scene *scene, Object *ob)
boundbox_displist(ob);
}
-static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int editmode)
+static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
{
ModifierData *md = modifiers_getVirtualModifierList(ob);
ModifierData *preTesselatePoint;
@@ -1222,10 +1223,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed
preTesselatePoint = NULL;
for (; md; md=md->next) {
- ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
- if ((md->mode & required_mode) != required_mode) continue;
- if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+ if (!modifier_isEnabled(scene, md, required_mode)) continue;
if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
preTesselatePoint = md;
@@ -1251,7 +1249,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
if(forRender) required_mode = eModifierMode_Render;
else required_mode = eModifierMode_Realtime;
- preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
if(editmode) required_mode |= eModifierMode_Editmode;
@@ -1312,11 +1310,12 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
DispList *dl;
int required_mode;
int editmode = (!forRender && cu->editnurb);
+ DerivedMesh *dm= NULL, *ndm;
if(forRender) required_mode = eModifierMode_Render;
else required_mode = eModifierMode_Realtime;
- preTesselatePoint = curve_get_tesselate_point(ob, forRender, editmode);
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
if(editmode) required_mode |= eModifierMode_Editmode;
@@ -1324,6 +1323,10 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
md = preTesselatePoint->next;
}
+ if (ob->derivedFinal) {
+ ob->derivedFinal->release (ob->derivedFinal);
+ }
+
for (; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -1331,40 +1334,84 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba
if ((md->mode & required_mode) != required_mode) continue;
if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
- if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue;
+ if (mti->type!=eModifierTypeType_OnlyDeform &&
+ mti->type!=eModifierTypeType_DeformOrConstruct &&
+ mti->type!=eModifierTypeType_Constructive) continue;
/* need to put all verts in 1 block for curve deform */
- if(md->type==eModifierType_Curve) {
- float *allverts, *fp;
+ /* we also need all verts in 1 block for derived mesh creation when handling constructive modifiers */
+ if(md->type==eModifierType_Curve || mti->type==eModifierTypeType_Constructive) {
+ float *allverts = NULL, *fp;
int totvert= 0;
-
- for (dl=dispbase->first; dl; dl=dl->next)
- totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
-
- fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert");
- for (dl=dispbase->first; dl; dl=dl->next) {
- int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
- memcpy(fp, dl->verts, sizeof(float) * offs);
- fp+= offs;
+
+ if (md->type==eModifierType_Curve ||
+ (mti->type==eModifierTypeType_Constructive && !dm)) {
+ for (dl=dispbase->first; dl; dl=dl->next)
+ totvert+= (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr;
+
+ fp= allverts= MEM_mallocN(totvert*sizeof(float)*3, "temp vert");
+ for (dl=dispbase->first; dl; dl=dl->next) {
+ int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+ memcpy(fp, dl->verts, sizeof(float) * offs);
+ fp+= offs;
+ }
}
-
- mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode);
-
- fp= allverts;
- for (dl=dispbase->first; dl; dl=dl->next) {
- int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
- memcpy(dl->verts, fp, sizeof(float) * offs);
- fp+= offs;
+
+ if (mti->type==eModifierTypeType_Constructive) {
+ if (!dm) {
+ dm= CDDM_from_curve(ob);
+ /*
+ * TODO: Maybe we should apply deformedVerts?
+ * But for now it causes invalid working of SoftBody modifier
+ */
+ CDDM_apply_vert_coords(dm, (float(*)[3]) allverts);
+ CDDM_calc_normals(dm);
+ }
+
+ ndm = mti->applyModifier(md, ob, dm, forRender, editmode);
+
+ if (dm && dm != ndm) /* Modifier */
+ dm->release (dm);
+ dm = ndm;
+ } else {
+ mti->deformVerts(md, ob, NULL, (float(*)[3]) allverts, totvert, forRender, editmode);
+ }
+
+ if (allverts) {
+ fp= allverts;
+ for (dl=dispbase->first; dl; dl=dl->next) {
+ int offs= 3 * ((dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr);
+ memcpy(dl->verts, fp, sizeof(float) * offs);
+ fp+= offs;
+ }
+ MEM_freeN(allverts);
}
- MEM_freeN(allverts);
}
else {
- for (dl=dispbase->first; dl; dl=dl->next) {
- mti->deformVerts(md, ob, NULL, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode);
+ if (dm) {
+ float (*deformedVerts)[3] = NULL;
+ int numVerts;
+
+ numVerts = dm->getNumVerts(dm);
+ deformedVerts =
+ MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
+ dm->getVertCos(dm, deformedVerts);
+
+ mti->deformVerts(md, ob, dm, deformedVerts, numVerts, forRender, editmode);
+
+ CDDM_apply_vert_coords(dm, deformedVerts);
+
+ MEM_freeN(deformedVerts);
+ } else {
+ for (dl=dispbase->first; dl; dl=dl->next) {
+ mti->deformVerts(md, ob, dm, (float(*)[3]) dl->verts, (dl->type==DL_INDEX3)?dl->nr:dl->parts*dl->nr, forRender, editmode);
+ }
}
}
}
+ ob->derivedFinal = dm;
+
if (deformedVerts) {
curve_applyVertexCos(ob->data, nurb, originalVerts);
MEM_freeN(originalVerts);
@@ -1402,6 +1449,109 @@ static void displist_surf_indices(DispList *dl)
}
+static DerivedMesh *create_orco_dm(Scene *scene, Object *ob)
+{
+ DerivedMesh *dm;
+ float (*orco)[3];
+
+ dm= CDDM_from_curve(ob);
+ orco= (float(*)[3])make_orco_curve(scene, ob);
+
+ CDDM_apply_vert_coords(dm, orco);
+ CDDM_calc_normals(dm);
+ MEM_freeN(orco);
+
+ return dm;
+}
+
+static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
+{
+ float (*orco)[3], (*layerorco)[3];
+ int totvert, a;
+ Curve *cu= ob->data;
+
+ totvert= dm->getNumVerts(dm);
+
+ if(orcodm) {
+ orco= MEM_callocN(sizeof(float)*3*totvert, "dm orco");
+
+ if(orcodm->getNumVerts(orcodm) == totvert)
+ orcodm->getVertCos(orcodm, orco);
+ else
+ dm->getVertCos(dm, orco);
+ }
+ else {
+ orco= (float(*)[3])make_orco_curve(scene, ob);
+ }
+
+ for(a=0; a<totvert; a++) {
+ float *co = orco[a];
+ co[0] = (co[0]-cu->loc[0])/cu->size[0];
+ co[1] = (co[1]-cu->loc[1])/cu->size[1];
+ co[2] = (co[2]-cu->loc[2])/cu->size[2];
+ }
+
+ if((layerorco = DM_get_vert_data_layer(dm, CD_ORCO))) {
+ memcpy(layerorco, orco, sizeof(float)*totvert);
+ MEM_freeN(orco);
+ }
+ else
+ DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
+}
+
+static void curve_calc_orcodm(Scene *scene, Object *ob, int forRender)
+{
+ /* this function represents logic of mesh's orcodm calculation */
+ /* for displist-based objects */
+
+ ModifierData *md = modifiers_getVirtualModifierList(ob);
+ ModifierData *preTesselatePoint;
+ Curve *cu= ob->data;
+ int required_mode;
+ int editmode = (!forRender && cu->editnurb);
+ DerivedMesh *dm= ob->derivedFinal, *ndm, *orcodm= NULL;
+
+ if(forRender) required_mode = eModifierMode_Render;
+ else required_mode = eModifierMode_Realtime;
+
+ preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
+
+ if(editmode) required_mode |= eModifierMode_Editmode;
+
+ if (preTesselatePoint) {
+ md = preTesselatePoint->next;
+ }
+
+ for (; md; md=md->next) {
+ ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+
+ md->scene= scene;
+
+ if ((md->mode & required_mode) != required_mode) continue;
+ if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
+ if (mti->type!=eModifierTypeType_Constructive) continue;
+
+ if(!orcodm)
+ orcodm= create_orco_dm(scene, ob);
+
+ ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);
+
+ if(ndm) {
+ /* if the modifier returned a new dm, release the old one */
+ if(orcodm && orcodm != ndm) {
+ orcodm->release(orcodm);
+ }
+ orcodm = ndm;
+ }
+ }
+
+ /* add an orco layer if needed */
+ add_orco_dm(scene, ob, dm, orcodm);
+
+ if(orcodm)
+ orcodm->release(orcodm);
+}
+
void makeDispListSurf(Scene *scene, Object *ob, ListBase *dispbase, int forRender, int forOrco)
{
ListBase *nubase;
@@ -1643,8 +1793,31 @@ void makeDispListCurveTypes(Scene *scene, Object *ob, int forOrco)
if(!forOrco) curve_calc_modifiers_post(scene, ob, &cu->disp, 0, originalVerts, deformedVerts);
tex_space_curve(cu);
}
-
- boundbox_displist(ob);
+
+ if (ob->derivedFinal) {
+ DM_set_object_boundbox (ob, ob->derivedFinal);
+ } else {
+ boundbox_displist (ob);
+ }
+}
+
+/* add Orco layer to the displist object which has got derived mesh and return orco */
+/* XXX: is it good place to keep this function here? */
+float *makeOrcoDispList(Scene *scene, Object *ob, int forRender) {
+ float *orco;
+ DerivedMesh *dm= ob->derivedFinal;
+
+ if (!dm->getVertDataArray(dm, CD_ORCO)) {
+ curve_calc_orcodm(scene, ob, forRender);
+ }
+
+ orco= dm->getVertDataArray(dm, CD_ORCO);
+
+ if(orco) {
+ orco= MEM_dupallocN(orco);
+ }
+
+ return orco;
}
void imagestodisplist(void)
@@ -1667,7 +1840,7 @@ static void boundbox_displist(Object *ob)
Curve *cu= ob->data;
int doit= 0;
- if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
+ if(cu->bb==0) cu->bb= MEM_callocN(sizeof(BoundBox), "boundbox");
bb= cu->bb;
dl= cu->disp.first;
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 {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 146701f2976..0c3c1e2e041 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -163,25 +163,8 @@ static DerivedMesh *get_dm(Scene *scene, Object *ob, EditMesh *em, DerivedMesh *
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, get_mesh_orco_verts(ob));
}
else if(ELEM3(ob->type,OB_FONT,OB_CURVE,OB_SURF)) {
- Object *tmpobj;
- Curve *tmpcu;
-
if(is_last_displist(ob)) {
- /* copies object and modifiers (but not the data) */
- tmpobj= copy_object(ob);
- tmpcu = (Curve *)tmpobj->data;
- tmpcu->id.us--;
-
- /* copies the data */
- tmpobj->data = copy_curve((Curve *) ob->data);
-
- makeDispListCurveTypes(scene, tmpobj, 1);
- nurbs_to_mesh(tmpobj);
-
- dm = CDDM_from_mesh((Mesh*)(tmpobj->data), tmpobj);
- //CDDM_calc_normals(dm);
-
- free_libblock_us(&G.main->object, tmpobj);
+ dm= CDDM_from_curve(ob);
}
}
@@ -8605,7 +8588,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
+ | eModifierTypeFlag_EnableInEditmode
+ | eModifierTypeFlag_AcceptsCVs;
mti->initData = subsurfModifier_initData;
mti->copyData = subsurfModifier_copyData;
mti->freeData = subsurfModifier_freeData;
@@ -8635,7 +8619,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
+ | eModifierTypeFlag_EnableInEditmode
+ | eModifierTypeFlag_AcceptsCVs;
mti->initData = arrayModifier_initData;
mti->copyData = arrayModifier_copyData;
mti->foreachObjectLink = arrayModifier_foreachObjectLink;
@@ -8648,7 +8633,8 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->flags = eModifierTypeFlag_AcceptsMesh
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
- | eModifierTypeFlag_EnableInEditmode;
+ | eModifierTypeFlag_EnableInEditmode
+ | eModifierTypeFlag_AcceptsCVs;
mti->initData = mirrorModifier_initData;
mti->copyData = mirrorModifier_copyData;
mti->foreachObjectLink = mirrorModifier_foreachObjectLink;
@@ -8659,6 +8645,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti = INIT_TYPE(EdgeSplit);
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_AcceptsCVs
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
| eModifierTypeFlag_EnableInEditmode;
@@ -8956,6 +8943,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti = INIT_TYPE(Solidify);
mti->type = eModifierTypeType_Constructive;
mti->flags = eModifierTypeFlag_AcceptsMesh
+ | eModifierTypeFlag_AcceptsCVs
| eModifierTypeFlag_SupportsMapping
| eModifierTypeFlag_SupportsEditmode
| eModifierTypeFlag_EnableInEditmode;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 2d7fc08aa74..cfebe91365e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -2289,7 +2289,7 @@ BoundBox *object_get_boundbox(Object *ob)
bb = mesh_get_bb(ob);
}
else if (ELEM3(ob->type, OB_CURVE, OB_SURF, OB_FONT)) {
- bb= ( (Curve *)ob->data )->bb;
+ bb= ob->bb ? ob->bb : ( (Curve *)ob->data )->bb;
}
else if(ob->type==OB_MBALL) {
bb= ob->bb;