- removed USE_CCGSUBSURF define (always on now)

- added G.editMesh->derived pointer... idea is to use this
   for mesh derived from editmesh instead of Mesh->derived (as the
   derived mesh tends to vary depending on what it came from).

   This part could be cleaner, also there may problems with it not
   being invalidated correctly.

 - And most importantly: In case people were beginning to worry all
   these edits were just crazy zr stuff, the big point comes about:
   Incremental subsurf calculation is now enabled. This gives massive
   speed improvements when editing a large mesh.

   For the eye-candy happy: try setting G.rt==52 before entering editmode
   and the edges and vertices (in optimal mode) will switch to displaying
   visually the age since a region has last been calculated. Lots of
   fun!
This commit is contained in:
Daniel Dunbar
2005-03-31 15:44:05 +00:00
parent 0d35a1dd1e
commit f0a8a93292
11 changed files with 104 additions and 41 deletions

View File

@@ -36,13 +36,11 @@ struct Object;
struct DerivedMesh;
struct EditMesh;
struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type);
struct DerivedMesh *subsurf_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, short type, struct DerivedMesh *oldDerived);
struct DerivedMesh *subsurf_make_derived_from_mesh(struct Mesh *me, int subdivLevels);
#ifdef USE_CCGSUBSURFLIB
struct DerivedMesh *subsurf_ccg_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels);
struct DerivedMesh *subsurf_ccg_make_derived_from_editmesh(struct EditMesh *em, int subdivLevels, struct DerivedMesh *oldDerived);
struct DerivedMesh *subsurf_ccg_make_derived_from_mesh(struct Mesh *me, int subdivLevels);
#endif
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]);

View File

@@ -1,5 +1,3 @@
#ifdef USE_CCGSUBSURFLIB
/* $Id$ */
#include <stdlib.h>
@@ -2089,5 +2087,3 @@ int ccgSubSurf_getNumFinalFaces(CCGSubSurf *ss) {
int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1));
return numFinalFaces;
}
#endif

View File

@@ -985,7 +985,11 @@ DerivedMesh *mesh_get_derived(Object *ob)
if (mesh_uses_displist(me)) {
build_mesh_data(ob);
return me->derived;
if(G.obedit && me==G.obedit->data) {
return G.editMesh->derived;
} else {
return me->derived;
}
}
return NULL;
@@ -996,13 +1000,18 @@ DerivedMesh *mesh_get_derived_render(Object *ob, int *needsFree)
Mesh *me= ob->data;
if (mesh_uses_displist(me)) {
// XXX, assumes was created earlier... is this for sure?
if (me->subdiv==me->subdivr) {
*needsFree = 0;
return me->derived;
if(G.obedit && me==G.obedit->data) {
return G.editMesh->derived;
} else {
return me->derived;
}
} else {
*needsFree = 1;
if(G.obedit && me==G.obedit->data) {
return subsurf_make_derived_from_editmesh(G.editMesh, me->subdivr, me->subsurftype);
return subsurf_make_derived_from_editmesh(G.editMesh, me->subdivr, me->subsurftype, NULL);
} else {
return subsurf_make_derived_from_mesh(me, me->subdivr);
}

View File

@@ -1775,7 +1775,7 @@ void makeDispList(Object *ob)
if (mesh_uses_displist(me)) { /* subsurf */
if (ob==G.obedit) {
me->derived= subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype);
G.editMesh->derived= subsurf_make_derived_from_editmesh(em, me->subdiv, me->subsurftype, G.editMesh->derived);
} else {
me->derived= subsurf_make_derived_from_mesh(me, me->subdiv);
}

View File

@@ -1089,16 +1089,21 @@ static DispListMesh *subsurf_subdivide_to_displistmesh(HyperMesh *hme, short sub
return dlm;
}
DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels, short type) {
DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels, short type, DerivedMesh *oldDerived) {
if (subdivLevels<1) {
if (oldDerived) {
oldDerived->release(oldDerived);
}
return derivedmesh_from_displistmesh(em, displistmesh_from_editmesh(em));
#ifdef USE_CCGSUBSURFLIB
} else if (type==ME_CCG_SUBSURF) {
return subsurf_ccg_make_derived_from_editmesh(em, subdivLevels);
#endif
return subsurf_ccg_make_derived_from_editmesh(em, subdivLevels, oldDerived);
} else {
HyperMesh *hme= hypermesh_from_editmesh(em, subdivLevels);
if (oldDerived) {
oldDerived->release(oldDerived);
}
return derivedmesh_from_displistmesh(em, subsurf_subdivide_to_displistmesh(hme, subdivLevels, type));
}
}
@@ -1106,10 +1111,8 @@ DerivedMesh *subsurf_make_derived_from_editmesh(EditMesh *em, int subdivLevels,
DerivedMesh *subsurf_make_derived_from_mesh(Mesh *me, int subdivLevels) {
if (subdivLevels<1) {
return derivedmesh_from_displistmesh(NULL, displistmesh_from_mesh(me, NULL));
#ifdef USE_CCGSUBSURFLIB
} else if (me->subsurftype==ME_CCG_SUBSURF) {
return subsurf_ccg_make_derived_from_mesh(me, subdivLevels);
#endif
} else {
HyperMesh *hme= hypermesh_from_mesh(me, subdivLevels);

View File

@@ -30,8 +30,6 @@
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#ifdef USE_CCGSUBSURFLIB
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -64,6 +62,7 @@
typedef struct _SubSurf {
CCGSubSurf *subSurf;
int useAging;
int controlType;
#define SUBSURF_CONTROLTYPE_MESH 1
#define SUBSURF_CONTROLTYPE_EDITMESH 2
@@ -134,12 +133,19 @@ static void arena_release(CCGAllocatorHDL a) {
static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels) {
CCGMeshIFC ifc;
CCGSubSurf *ccgSS;
CCGAllocatorIFC allocatorIFC, *allocatorIFCp;
CCGAllocatorHDL allocator;
ifc.vertUserSize = 4;
ifc.edgeUserSize = 8;
ifc.faceUserSize = 4;
if (ss->useAging) {
ifc.vertUserSize = 8;
ifc.edgeUserSize = 12;
ifc.faceUserSize = 8;
} else {
ifc.vertUserSize = 4;
ifc.edgeUserSize = 8;
ifc.faceUserSize = 4;
}
ifc.vertDataSize= 12;
ifc.vertDataZero= _subsurfNew_meshIFC_vertDataZero;
ifc.vertDataEqual= _subsurfNew_meshIFC_vertDataEqual;
@@ -156,12 +162,19 @@ static CCGSubSurf *_getSubSurf(SubSurf *ss, int subdivLevels) {
allocatorIFCp = &allocatorIFC;
allocator = BLI_memarena_new((1<<16));
return ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
ccgSS = ccgSubSurf_new(&ifc, ss, subdivLevels, allocatorIFCp, allocator);
if (ss->useAging) {
ccgSubSurf_setUseAgeCounts(ccgSS, 1, 4, 8, 4);
}
return ccgSS;
}
static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels) {
static SubSurf *subSurf_fromEditmesh(EditMesh *em, int subdivLevels, int useAging) {
SubSurf *ss= MEM_mallocN(sizeof(*ss), "ss");
ss->useAging = useAging;
ss->controlType= SUBSURF_CONTROLTYPE_EDITMESH;
ss->subSurf= _getSubSurf(ss, subdivLevels);
ss->em = em;
@@ -826,8 +839,14 @@ static void ccgDM_drawMappedVertsEM(DerivedMesh *dm, int (*setDrawOptions)(void
CCGVert *v = ccgVertIterator_getCurrent(vi);
EditVert *vert = ccgSubSurf_getVertVertHandle(ss,v);
if (setDrawOptions(userData, vert))
if (setDrawOptions(userData, vert)) {
if (ccgdm->ss->useAging) {
int ageCol = 255-ccgSubSurf_getVertAge(ss, v)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
bglVertex3fv(ccgSubSurf_getVertData(ss, v));
}
}
bglEnd();
@@ -861,6 +880,11 @@ static void ccgDM_drawMappedEdgesEM(DerivedMesh *dm, int (*setDrawOptions)(void
glBegin(GL_LINE_STRIP);
if (!setDrawOptions || setDrawOptions(userData, edge)) {
if (ccgdm->ss->useAging) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
for (i=0; i<edgeSize-1; i++) {
glVertex3fv(edgeData[i]);
glVertex3fv(edgeData[i+1]);
@@ -886,6 +910,12 @@ static void ccgDM_drawMappedEdgesInterpEM(DerivedMesh *dm, int (*setDrawOptions)
if (!setDrawOptions || setDrawOptions(userData, edge)) {
for (i=0; i<edgeSize; i++) {
setDrawInterpOptions(userData, edge, (float) i/(edgeSize-1));
if (ccgdm->ss->useAging) {
int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4;
glColor3ub(0, ageCol>0?ageCol:0, 0);
}
glVertex3fv(edgeData[i]);
}
}
@@ -930,7 +960,7 @@ static void ccgDM_release(DerivedMesh *dm) {
MEM_freeN(ccgdm);
}
static DerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
static CCGDerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
CCGDerivedMesh *ccgdm = MEM_mallocN(sizeof(*ccgdm), "dm");
ccgdm->dm.getNumVerts = ccgDM_getNumVerts;
@@ -956,16 +986,20 @@ static DerivedMesh *getCCGDerivedMesh(SubSurf *ss) {
ccgdm->ss = ss;
return (DerivedMesh*) ccgdm;
return ccgdm;
}
/***/
DerivedMesh *subsurf_ccg_make_derived_from_editmesh(EditMesh *em, int subdivLevels) {
DerivedMesh *subsurf_ccg_make_derived_from_editmesh(EditMesh *em, int subdivLevels, DerivedMesh *oldDerived) {
#if 0
SubSurf *ss= subSurf_fromEditmesh(em, subdivLevels);
DispListMesh *dlm;
if (oldDerived) {
oldDerived->release(oldDerived);
}
subSurf_sync(ss);
dlm= subSurf_createDispListMesh(ss);
@@ -973,12 +1007,25 @@ DerivedMesh *subsurf_ccg_make_derived_from_editmesh(EditMesh *em, int subdivLeve
subSurf_free(ss);
return derivedmesh_from_displistmesh(em, dlm);
#else
#elif 0
SubSurf *ss= subSurf_fromEditmesh(em, subdivLevels);
subSurf_sync(ss);
return getCCGDerivedMesh(ss);
#else
CCGDerivedMesh *ccgdm;
if (oldDerived) {
ccgdm= (CCGDerivedMesh*) oldDerived;
} else {
SubSurf *ss= subSurf_fromEditmesh(em, subdivLevels, G.rt==52);
ccgdm= getCCGDerivedMesh(ss);
}
subSurf_sync(ccgdm->ss);
return (DerivedMesh*) ccgdm;
#endif
}
@@ -994,5 +1041,3 @@ DerivedMesh *subsurf_ccg_make_derived_from_mesh(Mesh *me, int subdivLevels) {
return derivedmesh_from_displistmesh(NULL, dlm);
}
#endif

View File

@@ -38,6 +38,8 @@
#ifndef BLI_EDITVERT_H
#define BLI_EDITVERT_H
struct DerivedMesh;
/* note; changing this also might affect the undo copy in editmesh.c */
typedef struct EditVert
{
@@ -99,6 +101,7 @@ typedef struct EditMesh
EditEdge *alledges, *curedge;
EditFace *allfaces, *curface;
struct DerivedMesh *derived;
} EditMesh;
#endif

View File

@@ -373,7 +373,7 @@ enum {
#define B_CU3D 2120
#define B_SETRESOLU 2121
#define B_SETW4 2122
#define B_SUBSURFTYPE 2123
/* *********************** */
#define B_FONTBUTS 2300

View File

@@ -125,10 +125,7 @@ typedef struct Mesh {
/* Subsurf Type */
#define ME_CC_SUBSURF 0
#define ME_SIMPLE_SUBSURF 1
#ifdef USE_CCGSUBSURFLIB
#define ME_CCG_SUBSURF 2
#endif
#define TF_DYNAMIC 1
/* #define TF_INVISIBLE 2 */

View File

@@ -116,6 +116,7 @@
#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_effect.h"
#include "BKE_font.h"
#include "BKE_ika.h"
@@ -655,11 +656,7 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
uiBlock *block;
float val;
/* Hope to support more than two subsurf algorithms */
#ifdef USE_CCGSUBSURFLIB
char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|CCGSubSurf%x2|Simple Subdiv.%x1";
#else
char subsurfmenu[]="Subsurf Type%t|Catmull-Clark%x0|Simple Subdiv.%x1";
#endif
block= uiNewBlock(&curarea->uiblocks, "editing_panel_mesh_type", UI_EMBOSS, UI_HELV, curarea->win);
if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
@@ -671,7 +668,7 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
uiBlockBeginAlign(block);
uiBlockSetCol(block, TH_BUT_SETTING1);
uiDefButS(block, TOG|BIT|7, B_MAKEDISP, "SubSurf", 10,134,70,19, &me->flag, 0, 0, 0, 0, "Treats the active object as a Subdivision Surface");
uiDefButS(block, MENU, B_MAKEDISP, subsurfmenu, 80,134,84,19, &(me->subsurftype), 0, 0, 0, 0, "Selects type of Subsurf algorithm.");
uiDefButS(block, MENU, B_SUBSURFTYPE, subsurfmenu, 80,134,84,19, &(me->subsurftype), 0, 0, 0, 0, "Selects type of Subsurf algorithm.");
uiBlockSetCol(block, TH_AUTO);
uiDefButS(block, NUM, B_MAKEDISP, "Subdiv:", 10, 114,110,19, &me->subdiv, 0, 6, 0, 0, "Defines the level of subdivision to display in real time interactively");
uiDefButS(block, NUM, B_DIFF, "", 120,114, 44, 19, &me->subdivr, 0, 6, 0, 0, "Defines the level of subdivision to apply during rendering");
@@ -1088,6 +1085,15 @@ void do_curvebuts(unsigned short event)
allqueue(REDRAWVIEW3D, 0);
}
break;
case B_SUBSURFTYPE:
/* Icky, find better system */
if(ob->type==OB_MESH && ob->data==G.obedit->data) {
if(G.editMesh->derived) {
G.editMesh->derived->release(G.editMesh->derived);
G.editMesh->derived= NULL;
}
}
/* fallthrough */
case B_MAKEDISP:
if(ob->type==OB_FONT) text_to_curve(ob, 0);
makeDispList(ob);

View File

@@ -63,6 +63,7 @@
#include "BKE_key.h"
#include "BKE_object.h"
#include "BKE_displist.h"
#include "BKE_DerivedMesh.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -449,6 +450,11 @@ void free_editMesh(EditMesh *em)
if(em->edges.first) free_edgelist(&em->edges);
if(em->faces.first) free_facelist(&em->faces);
if(em->derived) {
em->derived->release(em->derived);
em->derived= NULL;
}
/* DEBUG: hashtabs are slowest part of enter/exit editmode. here a testprint */
#if 0
if(em->hashedgetab) {