- 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:
@@ -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]);
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user