forked from bartvdbraak/blender
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.
This commit is contained in:
parent
bf4d8ffe3a
commit
d0c70ad1d5
@ -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
|
||||
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
DM_set_object_boundbox (obedit, em->derivedFinal);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -418,24 +418,29 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
|
||||
}
|
||||
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
Curve *cu = ob->data;
|
||||
Curve *cu;
|
||||
int numVerts;
|
||||
float (*vertexCos)[3];
|
||||
|
||||
|
||||
|
||||
if (mti->type==eModifierTypeType_Constructive) {
|
||||
BKE_report(reports, RPT_ERROR, "Cannot apply constructive modifiers on curve");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cu = ob->data;
|
||||
BKE_report(reports, RPT_INFO, "Applied modifier only changed CV points, not tesselated/bevel vertices");
|
||||
|
||||
|
||||
if (!(md->mode&eModifierMode_Realtime) || (mti->isDisabled && mti->isDisabled(md, 0))) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
vertexCos = curve_getVertexCos(cu, &cu->nurb, &numVerts);
|
||||
mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0, 0);
|
||||
curve_applyVertexCos(cu, &cu->nurb, vertexCos);
|
||||
|
||||
MEM_freeN(vertexCos);
|
||||
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else {
|
||||
|
@ -2977,6 +2977,41 @@ static void drawDispListshaded(ListBase *lb, Object *ob)
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
static void drawCurveDMWired(Object *ob)
|
||||
{
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
dm->drawEdges (dm, 1);
|
||||
}
|
||||
|
||||
/* return 1 when nothing was drawn */
|
||||
static int drawCurveDerivedMesh(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
|
||||
{
|
||||
Object *ob= base->object;
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
Curve *cu= ob->data;
|
||||
|
||||
if (!dm) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(dt>OB_WIRE && displist_has_faces(&cu->disp)!=0) {
|
||||
int glsl = draw_glsl_material(scene, ob, v3d, dt);
|
||||
GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);
|
||||
|
||||
if (!glsl)
|
||||
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 0);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
dm->drawFacesSolid(dm, NULL, 0, GPU_enable_material);
|
||||
glDisable(GL_LIGHTING);
|
||||
GPU_end_object_materials();
|
||||
} else {
|
||||
drawCurveDMWired (ob);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* returns 1 when nothing was drawn */
|
||||
static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, int dt)
|
||||
{
|
||||
@ -2988,6 +3023,10 @@ static int drawDispList(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *bas
|
||||
|
||||
solid= (dt > OB_WIRE);
|
||||
|
||||
if (drawCurveDerivedMesh(scene, v3d, rv3d, base, dt) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(ob->type) {
|
||||
case OB_FONT:
|
||||
case OB_CURVE:
|
||||
@ -5037,7 +5076,7 @@ static void draw_bounding_volume(Scene *scene, 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;
|
||||
@ -5104,9 +5143,15 @@ static void drawSolidSelect(Scene *scene, View3D *v3d, ARegion *ar, Base *base)
|
||||
|
||||
if(ELEM3(ob->type, OB_FONT,OB_CURVE, OB_SURF)) {
|
||||
Curve *cu = ob->data;
|
||||
if (displist_has_faces(&cu->disp) && boundbox_clip(rv3d, ob->obmat, cu->bb)) {
|
||||
DerivedMesh *dm = ob->derivedFinal;
|
||||
|
||||
if (displist_has_faces(&cu->disp) && boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
|
||||
draw_index_wire= 0;
|
||||
drawDispListwire(&cu->disp);
|
||||
if (dm) {
|
||||
draw_mesh_object_outline(v3d, ob, dm);
|
||||
} else {
|
||||
drawDispListwire(&cu->disp);
|
||||
}
|
||||
draw_index_wire= 1;
|
||||
}
|
||||
} else if (ob->type==OB_MBALL) {
|
||||
@ -5151,10 +5196,16 @@ static void drawWireExtra(Scene *scene, RegionView3D *rv3d, Object *ob)
|
||||
|
||||
if (ELEM3(ob->type, OB_FONT, OB_CURVE, OB_SURF)) {
|
||||
Curve *cu = ob->data;
|
||||
if (boundbox_clip(rv3d, ob->obmat, cu->bb)) {
|
||||
if (boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
|
||||
if (ob->type==OB_CURVE)
|
||||
draw_index_wire= 0;
|
||||
drawDispListwire(&cu->disp);
|
||||
|
||||
if (ob->derivedFinal) {
|
||||
drawCurveDMWired(ob);
|
||||
} else {
|
||||
drawDispListwire(&cu->disp);
|
||||
}
|
||||
|
||||
if (ob->type==OB_CURVE)
|
||||
draw_index_wire= 1;
|
||||
}
|
||||
@ -5574,7 +5625,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
|
||||
}
|
||||
else if(dt==OB_BOUNDBOX)
|
||||
draw_bounding_volume(scene, ob);
|
||||
else if(boundbox_clip(rv3d, ob->obmat, cu->bb))
|
||||
else if(boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb))
|
||||
empty_object= drawDispList(scene, v3d, rv3d, base, dt);
|
||||
|
||||
break;
|
||||
@ -5587,12 +5638,12 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag)
|
||||
}
|
||||
else if(dt==OB_BOUNDBOX)
|
||||
draw_bounding_volume(scene, ob);
|
||||
else if(boundbox_clip(rv3d, ob->obmat, cu->bb)) {
|
||||
else if(boundbox_clip(rv3d, ob->obmat, ob->bb ? ob->bb : cu->bb)) {
|
||||
empty_object= drawDispList(scene, v3d, rv3d, base, dt);
|
||||
|
||||
if(cu->path)
|
||||
curve_draw_speed(scene, ob);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OB_MBALL:
|
||||
{
|
||||
|
@ -2620,7 +2620,117 @@ static int dl_surf_to_renderdata(ObjectRen *obr, DispList *dl, Material **matar,
|
||||
return orcoret;
|
||||
}
|
||||
|
||||
static void init_render_surf(Render *re, ObjectRen *obr)
|
||||
static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr,
|
||||
int timeoffset, float *orco, float mat[4][4])
|
||||
{
|
||||
Object *ob= obr->ob;
|
||||
int a, a1, end, totvert, vertofs;
|
||||
VertRen *ver;
|
||||
VlakRen *vlr;
|
||||
Curve *cu;
|
||||
MVert *mvert = NULL;
|
||||
MFace *mface;
|
||||
Material *ma;
|
||||
|
||||
mvert= dm->getVertArray(dm);
|
||||
totvert= dm->getNumVerts(dm);
|
||||
|
||||
if ELEM(ob->type, OB_FONT, OB_CURVE) {
|
||||
cu= ob->data;
|
||||
}
|
||||
|
||||
for(a=0; a<totvert; a++, mvert++) {
|
||||
ver= RE_findOrAddVert(obr, obr->totvert++);
|
||||
VECCOPY(ver->co, mvert->co);
|
||||
mul_m4_v3(mat, ver->co);
|
||||
|
||||
if(orco) {
|
||||
ver->orco= orco;
|
||||
orco+=3;
|
||||
}
|
||||
}
|
||||
|
||||
if(!timeoffset) {
|
||||
/* store customdata names, because DerivedMesh is freed */
|
||||
RE_set_customdata_names(obr, &dm->faceData);
|
||||
|
||||
/* still to do for keys: the correct local texture coordinate */
|
||||
|
||||
/* faces in order of color blocks */
|
||||
vertofs= obr->totvert - totvert;
|
||||
for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) {
|
||||
|
||||
ma= give_render_material(re, ob, a1+1);
|
||||
end= dm->getNumFaces(dm);
|
||||
mface= dm->getFaceArray(dm);
|
||||
|
||||
for(a=0; a<end; a++, mface++) {
|
||||
int v1, v2, v3, v4, flag;
|
||||
|
||||
if( mface->mat_nr==a1 ) {
|
||||
float len;
|
||||
|
||||
v1= mface->v1;
|
||||
v2= mface->v2;
|
||||
v3= mface->v3;
|
||||
v4= mface->v4;
|
||||
flag= mface->flag & ME_SMOOTH;
|
||||
|
||||
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
|
||||
vlr->v1= RE_findOrAddVert(obr, vertofs+v1);
|
||||
vlr->v2= RE_findOrAddVert(obr, vertofs+v2);
|
||||
vlr->v3= RE_findOrAddVert(obr, vertofs+v3);
|
||||
if(v4) vlr->v4= RE_findOrAddVert(obr, vertofs+v4);
|
||||
else vlr->v4= 0;
|
||||
|
||||
/* render normals are inverted in render */
|
||||
if(vlr->v4)
|
||||
len= normal_quad_v3( vlr->n,vlr->v4->co, vlr->v3->co, vlr->v2->co, vlr->v1->co);
|
||||
else
|
||||
len= normal_tri_v3( vlr->n,vlr->v3->co, vlr->v2->co, vlr->v1->co);
|
||||
|
||||
vlr->mat= ma;
|
||||
vlr->flag= flag;
|
||||
if(cu &&(cu->flag & ME_NOPUNOFLIP)) {
|
||||
vlr->flag |= R_NOPUNOFLIP;
|
||||
}
|
||||
vlr->ec= 0; /* mesh edges rendered separately */
|
||||
|
||||
if(len==0) obr->totvlak--;
|
||||
else {
|
||||
CustomDataLayer *layer;
|
||||
MTFace *mtface, *mtf;
|
||||
MCol *mcol, *mc;
|
||||
int index, mtfn= 0, mcn= 0;
|
||||
char *name;
|
||||
|
||||
for(index=0; index<dm->faceData.totlayer; index++) {
|
||||
layer= &dm->faceData.layers[index];
|
||||
name= layer->name;
|
||||
|
||||
if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
|
||||
mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
|
||||
mtface= (MTFace*)layer->data;
|
||||
*mtf= mtface[a];
|
||||
}
|
||||
else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
|
||||
mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
|
||||
mcol= (MCol*)layer->data;
|
||||
memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Normals */
|
||||
calc_vertexnormals(re, obr, 0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset)
|
||||
{
|
||||
Object *ob= obr->ob;
|
||||
Nurb *nu=0;
|
||||
@ -2630,6 +2740,7 @@ static void init_render_surf(Render *re, ObjectRen *obr)
|
||||
Material **matar;
|
||||
float *orco=NULL, *orcobase=NULL, mat[4][4];
|
||||
int a, totmat, need_orco=0;
|
||||
DerivedMesh *dm;
|
||||
|
||||
cu= ob->data;
|
||||
nu= cu->nurb.first;
|
||||
@ -2651,19 +2762,34 @@ static void init_render_surf(Render *re, ObjectRen *obr)
|
||||
|
||||
if(ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1;
|
||||
|
||||
if(need_orco) orcobase= orco= get_object_orco(re, ob);
|
||||
dm= ob->derivedFinal;
|
||||
if (ob->derivedFinal) {
|
||||
if(need_orco) {
|
||||
orco= makeOrcoDispList(re->scene, ob, 1);
|
||||
if(orco) {
|
||||
set_object_orco(re, ob, orco);
|
||||
}
|
||||
}
|
||||
|
||||
displist.first= displist.last= 0;
|
||||
makeDispListSurf(re->scene, ob, &displist, 1, 0);
|
||||
init_render_dm(dm, re, obr, timeoffset, orco, mat);
|
||||
} else {
|
||||
if(need_orco) {
|
||||
orcobase= orco= get_object_orco(re, ob);
|
||||
}
|
||||
|
||||
/* walk along displaylist and create rendervertices/-faces */
|
||||
for(dl=displist.first; dl; dl=dl->next) {
|
||||
/* watch out: u ^= y, v ^= x !! */
|
||||
if(dl->type==DL_SURF)
|
||||
orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
|
||||
displist.first= displist.last= 0;
|
||||
makeDispListSurf(re->scene, ob, &displist, 1, 0);
|
||||
|
||||
/* walk along displaylist and create rendervertices/-faces */
|
||||
for(dl=displist.first; dl; dl=dl->next) {
|
||||
/* watch out: u ^= y, v ^= x !! */
|
||||
if(dl->type==DL_SURF)
|
||||
orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
|
||||
}
|
||||
|
||||
freedisplist(&displist);
|
||||
}
|
||||
|
||||
freedisplist(&displist);
|
||||
MEM_freeN(matar);
|
||||
}
|
||||
|
||||
@ -2674,6 +2800,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
||||
VertRen *ver;
|
||||
VlakRen *vlr;
|
||||
DispList *dl;
|
||||
DerivedMesh *dm;
|
||||
ListBase olddl={NULL, NULL};
|
||||
Material **matar;
|
||||
float len, *data, *fp, *orco=NULL, *orcobase= NULL;
|
||||
@ -2687,11 +2814,11 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
||||
|
||||
/* no modifier call here, is in makedisp */
|
||||
|
||||
if(cu->resolu_ren)
|
||||
if(cu->resolu_ren)
|
||||
SWAP(ListBase, olddl, cu->disp);
|
||||
|
||||
/* test displist */
|
||||
if(cu->disp.first==NULL)
|
||||
if(cu->disp.first==NULL)
|
||||
makeDispListCurveTypes(re->scene, ob, 0);
|
||||
dl= cu->disp.first;
|
||||
if(cu->disp.first==NULL) return;
|
||||
@ -2710,89 +2837,49 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
||||
need_orco= 1;
|
||||
}
|
||||
|
||||
if(need_orco) orcobase=orco= get_object_orco(re, ob);
|
||||
|
||||
dl= cu->disp.first;
|
||||
while(dl) {
|
||||
if(dl->type==DL_INDEX3) {
|
||||
int *index;
|
||||
|
||||
startvert= obr->totvert;
|
||||
data= dl->verts;
|
||||
|
||||
n[0]= ob->imat[0][2];
|
||||
n[1]= ob->imat[1][2];
|
||||
n[2]= ob->imat[2][2];
|
||||
normalize_v3(n);
|
||||
|
||||
for(a=0; a<dl->nr; a++, data+=3) {
|
||||
ver= RE_findOrAddVert(obr, obr->totvert++);
|
||||
VECCOPY(ver->co, data);
|
||||
|
||||
/* flip normal if face is backfacing, also used in face loop below */
|
||||
if(ver->co[2] < 0.0) {
|
||||
VECCOPY(ver->n, n);
|
||||
ver->flag = 1;
|
||||
}
|
||||
else {
|
||||
ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
|
||||
ver->flag = 0;
|
||||
}
|
||||
|
||||
mul_m4_v3(mat, ver->co);
|
||||
|
||||
if (orco) {
|
||||
ver->orco = orco;
|
||||
orco += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(timeoffset==0) {
|
||||
startvlak= obr->totvlak;
|
||||
index= dl->index;
|
||||
for(a=0; a<dl->parts; a++, index+=3) {
|
||||
|
||||
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
|
||||
vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
|
||||
vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
|
||||
vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
|
||||
vlr->v4= NULL;
|
||||
|
||||
if(vlr->v1->flag) {
|
||||
VECCOPY(vlr->n, n);
|
||||
}
|
||||
else {
|
||||
vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
|
||||
}
|
||||
|
||||
vlr->mat= matar[ dl->col ];
|
||||
vlr->flag= 0;
|
||||
if( (cu->flag & CU_NOPUNOFLIP) ) {
|
||||
vlr->flag |= R_NOPUNOFLIP;
|
||||
}
|
||||
vlr->ec= 0;
|
||||
}
|
||||
dm= ob->derivedFinal;
|
||||
if (dm) {
|
||||
if(need_orco) {
|
||||
orco= makeOrcoDispList(re->scene, ob, 1);
|
||||
if(orco) {
|
||||
set_object_orco(re, ob, orco);
|
||||
}
|
||||
}
|
||||
else if (dl->type==DL_SURF) {
|
||||
|
||||
/* cyclic U means an extruded full circular curve, we skip bevel splitting then */
|
||||
if (dl->flag & DL_CYCL_U) {
|
||||
orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
|
||||
}
|
||||
else {
|
||||
int p1,p2,p3,p4;
|
||||
|
||||
fp= dl->verts;
|
||||
init_render_dm(dm, re, obr, timeoffset, orco, mat);
|
||||
} else {
|
||||
if(need_orco) {
|
||||
orcobase=orco= get_object_orco(re, ob);
|
||||
}
|
||||
|
||||
dl= cu->disp.first;
|
||||
while(dl) {
|
||||
if(dl->type==DL_INDEX3) {
|
||||
int *index;
|
||||
|
||||
startvert= obr->totvert;
|
||||
nr= dl->nr*dl->parts;
|
||||
data= dl->verts;
|
||||
|
||||
while(nr--) {
|
||||
n[0]= ob->imat[0][2];
|
||||
n[1]= ob->imat[1][2];
|
||||
n[2]= ob->imat[2][2];
|
||||
normalize_v3(n);
|
||||
|
||||
for(a=0; a<dl->nr; a++, data+=3) {
|
||||
ver= RE_findOrAddVert(obr, obr->totvert++);
|
||||
|
||||
VECCOPY(ver->co, fp);
|
||||
VECCOPY(ver->co, data);
|
||||
|
||||
/* flip normal if face is backfacing, also used in face loop below */
|
||||
if(ver->co[2] < 0.0) {
|
||||
VECCOPY(ver->n, n);
|
||||
ver->flag = 1;
|
||||
}
|
||||
else {
|
||||
ver->n[0]= -n[0]; ver->n[1]= -n[1]; ver->n[2]= -n[2];
|
||||
ver->flag = 0;
|
||||
}
|
||||
|
||||
mul_m4_v3(mat, ver->co);
|
||||
fp+= 3;
|
||||
|
||||
if (orco) {
|
||||
ver->orco = orco;
|
||||
@ -2800,86 +2887,140 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset)
|
||||
}
|
||||
}
|
||||
|
||||
if(dl->bevelSplitFlag || timeoffset==0) {
|
||||
if(timeoffset==0) {
|
||||
startvlak= obr->totvlak;
|
||||
index= dl->index;
|
||||
for(a=0; a<dl->parts; a++, index+=3) {
|
||||
|
||||
for(a=0; a<dl->parts; a++) {
|
||||
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
|
||||
vlr->v1= RE_findOrAddVert(obr, startvert+index[0]);
|
||||
vlr->v2= RE_findOrAddVert(obr, startvert+index[1]);
|
||||
vlr->v3= RE_findOrAddVert(obr, startvert+index[2]);
|
||||
vlr->v4= NULL;
|
||||
|
||||
frontside= (a >= dl->nr/2);
|
||||
|
||||
if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
|
||||
break;
|
||||
|
||||
p1+= startvert;
|
||||
p2+= startvert;
|
||||
p3+= startvert;
|
||||
p4+= startvert;
|
||||
|
||||
for(; b<dl->nr; b++) {
|
||||
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
|
||||
vlr->v1= RE_findOrAddVert(obr, p2);
|
||||
vlr->v2= RE_findOrAddVert(obr, p1);
|
||||
vlr->v3= RE_findOrAddVert(obr, p3);
|
||||
vlr->v4= RE_findOrAddVert(obr, p4);
|
||||
vlr->ec= ME_V2V3+ME_V3V4;
|
||||
if(a==0) vlr->ec+= ME_V1V2;
|
||||
|
||||
vlr->flag= dl->rt;
|
||||
|
||||
/* this is not really scientific: the vertices
|
||||
* 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
|
||||
* front and backside treated different!!
|
||||
*/
|
||||
|
||||
if(frontside)
|
||||
normal_tri_v3( vlr->n,vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
else
|
||||
normal_tri_v3( vlr->n,vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
|
||||
vlr->mat= matar[ dl->col ];
|
||||
|
||||
p4= p3;
|
||||
p3++;
|
||||
p2= p1;
|
||||
p1++;
|
||||
if(vlr->v1->flag) {
|
||||
VECCOPY(vlr->n, n);
|
||||
}
|
||||
else {
|
||||
vlr->n[0]= -n[0]; vlr->n[1]= -n[1]; vlr->n[2]= -n[2];
|
||||
}
|
||||
}
|
||||
|
||||
if (dl->bevelSplitFlag) {
|
||||
for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
|
||||
if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
|
||||
split_v_renderfaces(obr, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
|
||||
}
|
||||
|
||||
/* vertex normals */
|
||||
for(a= startvlak; a<obr->totvlak; a++) {
|
||||
vlr= RE_findOrAddVlak(obr, a);
|
||||
|
||||
add_v3_v3v3(vlr->v1->n, vlr->v1->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v3->n, vlr->v3->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v2->n, vlr->v2->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v4->n, vlr->v4->n, vlr->n);
|
||||
}
|
||||
for(a=startvert; a<obr->totvert; a++) {
|
||||
ver= RE_findOrAddVert(obr, a);
|
||||
len= normalize_v3(ver->n);
|
||||
if(len==0.0) ver->flag= 1; /* flag abuse, its only used in zbuf now */
|
||||
else ver->flag= 0;
|
||||
}
|
||||
for(a= startvlak; a<obr->totvlak; a++) {
|
||||
vlr= RE_findOrAddVlak(obr, a);
|
||||
if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
|
||||
if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
|
||||
if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
|
||||
if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
|
||||
vlr->mat= matar[ dl->col ];
|
||||
vlr->flag= 0;
|
||||
if( (cu->flag & CU_NOPUNOFLIP) ) {
|
||||
vlr->flag |= R_NOPUNOFLIP;
|
||||
}
|
||||
vlr->ec= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dl->type==DL_SURF) {
|
||||
|
||||
dl= dl->next;
|
||||
/* cyclic U means an extruded full circular curve, we skip bevel splitting then */
|
||||
if (dl->flag & DL_CYCL_U) {
|
||||
orco+= 3*dl_surf_to_renderdata(obr, dl, matar, orco, mat);
|
||||
}
|
||||
else {
|
||||
int p1,p2,p3,p4;
|
||||
|
||||
fp= dl->verts;
|
||||
startvert= obr->totvert;
|
||||
nr= dl->nr*dl->parts;
|
||||
|
||||
while(nr--) {
|
||||
ver= RE_findOrAddVert(obr, obr->totvert++);
|
||||
|
||||
VECCOPY(ver->co, fp);
|
||||
mul_m4_v3(mat, ver->co);
|
||||
fp+= 3;
|
||||
|
||||
if (orco) {
|
||||
ver->orco = orco;
|
||||
orco += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(dl->bevelSplitFlag || timeoffset==0) {
|
||||
startvlak= obr->totvlak;
|
||||
|
||||
for(a=0; a<dl->parts; a++) {
|
||||
|
||||
frontside= (a >= dl->nr/2);
|
||||
|
||||
if (surfindex_displist(dl, a, &b, &p1, &p2, &p3, &p4)==0)
|
||||
break;
|
||||
|
||||
p1+= startvert;
|
||||
p2+= startvert;
|
||||
p3+= startvert;
|
||||
p4+= startvert;
|
||||
|
||||
for(; b<dl->nr; b++) {
|
||||
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
|
||||
vlr->v1= RE_findOrAddVert(obr, p2);
|
||||
vlr->v2= RE_findOrAddVert(obr, p1);
|
||||
vlr->v3= RE_findOrAddVert(obr, p3);
|
||||
vlr->v4= RE_findOrAddVert(obr, p4);
|
||||
vlr->ec= ME_V2V3+ME_V3V4;
|
||||
if(a==0) vlr->ec+= ME_V1V2;
|
||||
|
||||
vlr->flag= dl->rt;
|
||||
|
||||
/* this is not really scientific: the vertices
|
||||
* 2, 3 en 4 seem to give better vertexnormals than 1 2 3:
|
||||
* front and backside treated different!!
|
||||
*/
|
||||
|
||||
if(frontside)
|
||||
normal_tri_v3( vlr->n,vlr->v2->co, vlr->v3->co, vlr->v4->co);
|
||||
else
|
||||
normal_tri_v3( vlr->n,vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
|
||||
vlr->mat= matar[ dl->col ];
|
||||
|
||||
p4= p3;
|
||||
p3++;
|
||||
p2= p1;
|
||||
p1++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dl->bevelSplitFlag) {
|
||||
for(a=0; a<dl->parts-1+!!(dl->flag&DL_CYCL_V); a++)
|
||||
if(dl->bevelSplitFlag[a>>5]&(1<<(a&0x1F)))
|
||||
split_v_renderfaces(obr, startvlak, startvert, dl->parts, dl->nr, a, dl->flag&DL_CYCL_V, dl->flag&DL_CYCL_U);
|
||||
}
|
||||
|
||||
/* vertex normals */
|
||||
for(a= startvlak; a<obr->totvlak; a++) {
|
||||
vlr= RE_findOrAddVlak(obr, a);
|
||||
|
||||
add_v3_v3v3(vlr->v1->n, vlr->v1->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v3->n, vlr->v3->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v2->n, vlr->v2->n, vlr->n);
|
||||
add_v3_v3v3(vlr->v4->n, vlr->v4->n, vlr->n);
|
||||
}
|
||||
for(a=startvert; a<obr->totvert; a++) {
|
||||
ver= RE_findOrAddVert(obr, a);
|
||||
len= normalize_v3(ver->n);
|
||||
if(len==0.0) ver->flag= 1; /* flag abuse, its only used in zbuf now */
|
||||
else ver->flag= 0;
|
||||
}
|
||||
for(a= startvlak; a<obr->totvlak; a++) {
|
||||
vlr= RE_findOrAddVlak(obr, a);
|
||||
if(vlr->v1->flag) VECCOPY(vlr->v1->n, vlr->n);
|
||||
if(vlr->v2->flag) VECCOPY(vlr->v2->n, vlr->n);
|
||||
if(vlr->v3->flag) VECCOPY(vlr->v3->n, vlr->n);
|
||||
if(vlr->v4->flag) VECCOPY(vlr->v4->n, vlr->n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dl= dl->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* not very elegant... but we want original displist in UI */
|
||||
if(cu->resolu_ren) {
|
||||
freedisplist(&cu->disp);
|
||||
@ -2917,12 +3058,12 @@ static void to_edgesort(struct edgesort *ed, int i1, int i2, int v1, int v2, int
|
||||
static int vergedgesort(const void *v1, const void *v2)
|
||||
{
|
||||
const struct edgesort *x1=v1, *x2=v2;
|
||||
|
||||
|
||||
if( x1->v1 > x2->v1) return 1;
|
||||
else if( x1->v1 < x2->v1) return -1;
|
||||
else if( x1->v2 > x2->v2) return 1;
|
||||
else if( x1->v2 < x2->v2) return -1;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2933,14 +3074,14 @@ static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
|
||||
struct edgesort *edsort, *ed;
|
||||
unsigned int *mcol=NULL;
|
||||
int a, totedge=0, totface;
|
||||
|
||||
|
||||
mface= dm->getFaceArray(dm);
|
||||
totface= dm->getNumFaces(dm);
|
||||
tface= dm->getFaceDataArray(dm, CD_MTFACE);
|
||||
mcol= dm->getFaceDataArray(dm, CD_MCOL);
|
||||
|
||||
|
||||
if(mcol==NULL && tface==NULL) return NULL;
|
||||
|
||||
|
||||
/* make sorted table with edges and face indices in it */
|
||||
for(a= totface, mf= mface; a>0; a--, mf++) {
|
||||
if(mf->v4) totedge+=4;
|
||||
@ -2949,9 +3090,9 @@ static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
|
||||
|
||||
if(totedge==0)
|
||||
return NULL;
|
||||
|
||||
|
||||
ed= edsort= MEM_callocN(totedge*sizeof(struct edgesort), "edgesort");
|
||||
|
||||
|
||||
for(a=0, mf=mface; a<totface; a++, mf++) {
|
||||
to_edgesort(ed++, 0, 1, mf->v1, mf->v2, a);
|
||||
to_edgesort(ed++, 1, 2, mf->v2, mf->v3, a);
|
||||
@ -2962,9 +3103,9 @@ static struct edgesort *make_mesh_edge_lookup(DerivedMesh *dm, int *totedgesort)
|
||||
else if(mf->v3)
|
||||
to_edgesort(ed++, 2, 3, mf->v3, mf->v1, a);
|
||||
}
|
||||
|
||||
|
||||
qsort(edsort, totedge, sizeof(struct edgesort), vergedgesort);
|
||||
|
||||
|
||||
*totedgesort= totedge;
|
||||
|
||||
return edsort;
|
||||
@ -2978,7 +3119,7 @@ static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge,
|
||||
MCol *mcol, *mc;
|
||||
int index, mtfn, mcn;
|
||||
char *name;
|
||||
|
||||
|
||||
if(medge->v1 < medge->v2) {
|
||||
ed.v1= medge->v1;
|
||||
ed.v2= medge->v2;
|
||||
@ -2987,7 +3128,7 @@ static void use_mesh_edge_lookup(ObjectRen *obr, DerivedMesh *dm, MEdge *medge,
|
||||
ed.v1= medge->v2;
|
||||
ed.v2= medge->v1;
|
||||
}
|
||||
|
||||
|
||||
edp= bsearch(&ed, edgetable, totedge, sizeof(struct edgesort), vergedgesort);
|
||||
|
||||
/* since edges have different index ordering, we have to duplicate mcol and tface */
|
||||
@ -3036,17 +3177,17 @@ static void init_camera_inside_volumes(Render *re)
|
||||
if (obi->obr == vo->obr) {
|
||||
if (point_inside_volume_objectinstance(re, obi, co)) {
|
||||
MatInside *mi;
|
||||
|
||||
|
||||
mi = MEM_mallocN(sizeof(MatInside), "camera inside material");
|
||||
mi->ma = vo->ma;
|
||||
mi->obi = obi;
|
||||
|
||||
|
||||
BLI_addtail(&(re->render_volumes_inside), mi);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* debug {
|
||||
MatInside *m;
|
||||
for (m=re->render_volumes_inside.first; m; m=m->next) {
|
||||
@ -3058,12 +3199,12 @@ static void init_camera_inside_volumes(Render *re)
|
||||
static void add_volume(Render *re, ObjectRen *obr, Material *ma)
|
||||
{
|
||||
struct VolumeOb *vo;
|
||||
|
||||
|
||||
vo = MEM_mallocN(sizeof(VolumeOb), "volume object");
|
||||
|
||||
|
||||
vo->ma = ma;
|
||||
vo->obr = obr;
|
||||
|
||||
|
||||
BLI_addtail(&re->volumes, vo);
|
||||
}
|
||||
|
||||
@ -4291,7 +4432,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
|
||||
if ELEM(ob->type, OB_FONT, OB_CURVE)
|
||||
init_render_curve(re, obr, timeoffset);
|
||||
else if(ob->type==OB_SURF)
|
||||
init_render_surf(re, obr);
|
||||
init_render_surf(re, obr, timeoffset);
|
||||
else if(ob->type==OB_MESH)
|
||||
init_render_mesh(re, obr, timeoffset);
|
||||
else if(ob->type==OB_MBALL)
|
||||
@ -4299,7 +4440,7 @@ static void init_render_object_data(Render *re, ObjectRen *obr, int timeoffset)
|
||||
}
|
||||
|
||||
finalize_render_object(re, obr, timeoffset);
|
||||
|
||||
|
||||
re->totvert += obr->totvert;
|
||||
re->totvlak += obr->totvlak;
|
||||
re->tothalo += obr->tothalo;
|
||||
|
Loading…
Reference in New Issue
Block a user