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:
Diffstat (limited to 'source/blender/blenkernel/intern/cdderivedmesh.c')
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c195
1 files changed, 123 insertions, 72 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 9ee4b66b194..7b6da4dd811 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -37,12 +37,9 @@
#include "BIF_gl.h"
#include "BKE_cdderivedmesh.h"
-#include "BKE_customdata.h"
-#include "BKE_DerivedMesh.h"
-#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_mesh.h"
-#include "BKE_multires.h"
+#include "BKE_paint.h"
#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
@@ -52,18 +49,16 @@
#include "BLI_blenlib.h"
#include "BLI_edgehash.h"
#include "BLI_editVert.h"
+#include "BLI_math.h"
#include "BLI_pbvh.h"
-#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_fluidsim.h"
#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
+#include "DNA_curve_types.h" /* for Curve */
#include "MEM_guardedalloc.h"
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -85,6 +80,7 @@ typedef struct {
/* Cached */
struct PBVH *pbvh;
+ int pbvh_draw;
/* Mesh connectivity */
struct ListBase *fmap;
struct IndexNode *fmap_mem;
@@ -197,22 +193,47 @@ static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
Mesh *me= ob->data;
create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
- me->totvert, me->totface);
+ me->totvert, me->totface);
}
return cddm->fmap;
}
+static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
+{
+ CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+ Mesh *me= (ob)? ob->data: NULL;
+
+ if(ob->sculpt->modifiers_active) return 0;
+
+ return (cddm->mvert == me->mvert) || ob->sculpt->kb;
+}
+
static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
+ Mesh *me= (ob)? ob->data: NULL;
- if(!cddm->pbvh && ob->type == OB_MESH) {
- Mesh *me= ob->data;
+ if(!ob) {
+ cddm->pbvh= NULL;
+ return NULL;
+ }
+
+ if(!ob->sculpt)
+ return NULL;
+ if(ob->sculpt->pbvh) {
+ cddm->pbvh= ob->sculpt->pbvh;
+ cddm->pbvh_draw = can_pbvh_draw(ob, dm);
+ }
+ /* always build pbvh from original mesh, and only use it for drawing if
+ this derivedmesh is just original mesh. it's the multires subsurf dm
+ that this is actually for, to support a pbvh on a modified mesh */
+ if(!cddm->pbvh && ob->type == OB_MESH) {
cddm->pbvh = BLI_pbvh_new();
+ cddm->pbvh_draw = can_pbvh_draw(ob, dm);
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
- me->totface, me->totvert);
+ me->totface, me->totvert);
}
return cddm->pbvh;
@@ -309,7 +330,7 @@ static void cdDM_drawUVEdges(DerivedMesh *dm)
}
}
-static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
+static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mvert = cddm->mvert;
@@ -320,7 +341,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
glBegin(GL_LINES);
for(i = 0; i < dm->numEdgeData; i++, medge++) {
- if((medge->flag&ME_EDGEDRAW)
+ if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
glVertex3fv(mvert[medge->v1].co);
glVertex3fv(mvert[medge->v2].co);
@@ -336,7 +357,7 @@ static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
GPU_edge_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
for(i = 0; i < dm->numEdgeData; i++, medge++) {
- if((medge->flag&ME_EDGEDRAW)
+ if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
&& (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
draw = 1;
}
@@ -425,7 +446,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
glVertex3fv(mvert[index].co); \
}
- if(cddm->pbvh) {
+ if(cddm->pbvh && cddm->pbvh_draw) {
if(dm->numFaceData) {
float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
@@ -434,7 +455,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
return;
glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
- BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors);
+ BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
glShadeModel(GL_FLAT);
}
@@ -736,7 +757,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
if( flag != lastFlag ) {
if( startFace < i ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
- if (lastFlag==1 && mcol)
+ if (lastFlag==1 && col)
GPU_color_switch(1);
else
GPU_color_switch(0);
@@ -749,7 +770,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
}
if( startFace < dm->drawObject->nelements/3 ) {
if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
- if (lastFlag==1 && mcol)
+ if (lastFlag==1 && col)
GPU_color_switch(1);
else
GPU_color_switch(0);
@@ -855,47 +876,41 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
}
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
- int state = 1;
- int prevstate = 1;
int prevstart = 0;
GPU_vertex_setup(dm);
GPU_normal_setup(dm);
if( useColors && mc )
GPU_color_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
+ int tottri = dm->drawObject->nelements/3;
glShadeModel(GL_SMOOTH);
- for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
+
+ for( i = 0; i < tottri; i++ ) {
int actualFace = dm->drawObject->faceRemap[i];
int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
- int dontdraw = 0;
+ int draw = 1;
+
if(index) {
orig = index[actualFace];
if(setDrawOptions && orig == ORIGINDEX_NONE)
- dontdraw = 1;
+ draw = 0;
}
else
orig = actualFace;
- if( dontdraw ) {
- state = 0;
- }
- else {
- if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
- state = 1;
- }
- else {
- state = 0;
- }
- }
- if( prevstate != state && prevstate == 1 ) {
- if( i-prevstart > 0 ) {
- glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
- }
- prevstart = i;
+
+ if(draw && setDrawOptions && !setDrawOptions(userData, orig, &drawSmooth))
+ draw = 0;
+
+ /* Goal is to draw as long of a contiguous triangle
+ array as possible, so draw when we hit either an
+ invisible triangle or at the end of the array */
+ if(!draw || i == tottri - 1) {
+ if(prevstart != i)
+ /* Add one to the length (via `draw')
+ if we're drawing at the end of the array */
+ glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3);
+ prevstart = i + 1;
}
- prevstate = state;
- }
- if(state==1) {
- glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
}
glShadeModel(GL_FLAT);
}
@@ -1291,10 +1306,10 @@ static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us
}
static void cdDM_foreachMappedVert(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, float *co,
- float *no_f, short *no_s),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, float *co,
+ float *no_f, short *no_s),
+ void *userData)
{
MVert *mv = CDDM_get_verts(dm);
int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
@@ -1311,10 +1326,10 @@ static void cdDM_foreachMappedVert(
}
static void cdDM_foreachMappedEdge(
- DerivedMesh *dm,
- void (*func)(void *userData, int index,
- float *v0co, float *v1co),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index,
+ float *v0co, float *v1co),
+ void *userData)
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mv = cddm->mvert;
@@ -1333,17 +1348,16 @@ static void cdDM_foreachMappedEdge(
}
static void cdDM_foreachMappedFaceCenter(
- DerivedMesh *dm,
- void (*func)(void *userData, int index,
- float *cent, float *no),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index,
+ float *cent, float *no),
+ void *userData)
{
CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
MVert *mv = cddm->mvert;
MPoly *mf = cddm->mpoly;
MLoop *ml = cddm->mloop;
int i, j, orig, *index;
- int maxf=0;
index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
mf = cddm->mpoly;
@@ -1403,7 +1417,6 @@ static void cdDM_recalcTesselation2(DerivedMesh *dm)
static void cdDM_free_internal(CDDerivedMesh *cddm)
{
- if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh);
if(cddm->fmap) MEM_freeN(cddm->fmap);
if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
}
@@ -1532,11 +1545,11 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
alloctype= CD_REFERENCE;
CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
- mesh->totvert);
+ mesh->totvert);
CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
- mesh->totedge);
+ mesh->totedge);
CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_ORIGINDEX, alloctype,
- mesh->totface);
+ mesh->totface);
CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
mesh->totloop);
CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
@@ -1571,11 +1584,11 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
dm->deformedOnly = 1;
CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numVertData);
+ CD_CALLOC, dm->numVertData);
/* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numEdgeData); */
+ CD_CALLOC, dm->numEdgeData); */
CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
- CD_CALLOC, dm->numFaceData);
+ CD_CALLOC, dm->numFaceData);
CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
CD_CALLOC, dm->numFaceData);
@@ -1596,7 +1609,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getVertDataArray(dm, CD_ORIGINDEX);
for(i = 0, eve = em->verts.first; i < dm->numVertData;
- i++, eve = eve->next, index++) {
+ i++, eve = eve->next, index++) {
MVert *mv = &mvert[i];
VECCOPY(mv->co, eve->co);
@@ -1616,7 +1629,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
- i++, eed = eed->next, index++) {
+ i++, eed = eed->next, index++) {
MEdge *med = &medge[i];
med->v1 = eed->v1->tmp.l;
@@ -1636,7 +1649,7 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
for(i = 0, efa = em->faces.first; i < dm->numFaceData;
- i++, efa = efa->next, index++) {
+ i++, efa = efa->next, index++) {
MFace *mf = &mface[i];
mf->v1 = efa->v1->tmp.l;
@@ -1655,10 +1668,45 @@ DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
return dm;
}
+DerivedMesh *CDDM_from_curve(Object *ob)
+{
+ return CDDM_from_curve_customDB(ob, &((Curve *)ob->data)->disp);
+}
+
+DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
+{
+ DerivedMesh *dm;
+ CDDerivedMesh *cddm;
+ MVert *allvert;
+ MEdge *alledge;
+ MFace *allface;
+ int totvert, totedge, totface;
+
+ if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
+ &totedge, &allface, &totface) != 0) {
+ /* Error initializing mdata. This often happens when curve is empty */
+ return CDDM_new(0, 0, 0, 0, 0);
+ }
+
+ dm = CDDM_new(totvert, totedge, totface, totface*4, 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;
+}
static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
- int cdindex, BMLoop *l3[3],
- int numCol, int numTex)
+ int cdindex, BMLoop *l3[3],
+ int numCol, int numTex)
{
BMLoop *l;
BMFace *f = l3[0]->f;
@@ -2029,7 +2077,7 @@ DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
DerivedMesh *CDDM_from_template(DerivedMesh *source,
int numVerts, int numEdges, int numFaces,
- int numLoops, int numPolys)
+ int numLoops, int numPolys)
{
CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
DerivedMesh *dm = &cddm->dm;
@@ -2107,6 +2155,9 @@ void CDDM_calc_normals(DerivedMesh *dm)
if (CustomData_has_layer(&dm->faceData, CD_NORMAL))
CustomData_free_layer(&dm->faceData, CD_NORMAL, dm->numFaceData, 0);
+ temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
+ "CDDM_calc_normals temp_nors");
+
/*recalc tesselation to ensure we have valid origindex values
for mface->mpoly lookups.*/
cdDM_recalcTesselation2(dm);
@@ -2202,7 +2253,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
med = CustomData_get_layer(&edgeData, CD_MEDGE);
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
for(i = 0; !BLI_edgehashIterator_isDone(ehi);
- BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
+ BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
med->flag = ME_EDGEDRAW|ME_EDGERENDER;