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.c106
1 files changed, 59 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index b3e702ceee9..ca81e216006 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -54,7 +54,7 @@
#include "MEM_guardedalloc.h"
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#include "GPU_draw.h"
#include "GPU_extensions.h"
#include "GPU_material.h"
@@ -74,6 +74,7 @@ typedef struct {
/* Cached */
struct PBVH *pbvh;
+ int pbvh_draw;
/* Mesh connectivity */
struct ListBase *fmap;
struct IndexNode *fmap_mem;
@@ -185,9 +186,20 @@ static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
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(!ob) {
cddm->pbvh= NULL;
@@ -196,13 +208,17 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
if(!ob->sculpt)
return NULL;
- if(ob->sculpt->pbvh)
+ 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) {
- Mesh *me= ob->data;
-
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);
}
@@ -225,7 +241,8 @@ static void cdDM_drawVerts(DerivedMesh *dm)
else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
GPU_vertex_setup(dm);
if( !GPU_buffer_legacy(dm) ) {
- glDrawArrays(GL_POINTS,0,dm->drawObject->nelements);
+ if(dm->drawObject->nelements) glDrawArrays(GL_POINTS,0, dm->drawObject->nelements);
+ else glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts);
}
GPU_buffer_unbind();
}
@@ -417,7 +434,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);
@@ -728,7 +745,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);
@@ -741,7 +758,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);
@@ -847,47 +864,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);
}
@@ -1347,12 +1358,12 @@ static void cdDM_foreachMappedFaceCenter(
orig = i;
VECCOPY(cent, mv[mf->v1].co);
- add_v3_v3v3(cent, cent, mv[mf->v2].co);
- add_v3_v3v3(cent, cent, mv[mf->v3].co);
+ add_v3_v3(cent, mv[mf->v2].co);
+ add_v3_v3(cent, mv[mf->v3].co);
if (mf->v4) {
normal_quad_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
- add_v3_v3v3(cent, cent, mv[mf->v4].co);
+ add_v3_v3(cent, mv[mf->v4].co);
mul_v3_fl(cent, 0.25f);
} else {
normal_tri_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
@@ -1663,6 +1674,11 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source,
CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
DerivedMesh *dm = &cddm->dm;
+ /* ensure these are created if they are made on demand */
+ source->getVertDataArray(source, CD_ORIGINDEX);
+ source->getEdgeDataArray(source, CD_ORIGINDEX);
+ source->getFaceDataArray(source, CD_ORIGINDEX);
+
/* this does a copy of all non mvert/medge/mface layers */
DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces);
@@ -1750,25 +1766,21 @@ void CDDM_calc_normals(DerivedMesh *dm)
else
normal_tri_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
- add_v3_v3v3(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
- add_v3_v3v3(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
- add_v3_v3v3(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
+ add_v3_v3(temp_nors[mf->v1], f_no);
+ add_v3_v3(temp_nors[mf->v2], f_no);
+ add_v3_v3(temp_nors[mf->v3], f_no);
if(mf->v4)
- add_v3_v3v3(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
+ add_v3_v3(temp_nors[mf->v4], f_no);
}
/* normalize vertex normals and assign */
for(i = 0; i < numVerts; i++, mv++) {
float *no = temp_nors[i];
- if (normalize_v3(no) == 0.0) {
- VECCOPY(no, mv->co);
- normalize_v3(no);
- }
+ if (normalize_v3(no) == 0.0)
+ normalize_v3_v3(no, mv->co);
- mv->no[0] = (short)(no[0] * 32767.0);
- mv->no[1] = (short)(no[1] * 32767.0);
- mv->no[2] = (short)(no[2] * 32767.0);
+ normal_float_to_short_v3(mv->no, no);
}
MEM_freeN(temp_nors);