2005-03-29 16:43:39 +00:00
|
|
|
/**
|
|
|
|
|
* $Id$
|
|
|
|
|
*
|
2008-01-07 19:13:47 +00:00
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
2005-03-29 16:43:39 +00:00
|
|
|
*
|
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
2008-01-07 19:13:47 +00:00
|
|
|
* of the License, or (at your option) any later version.
|
2005-03-29 16:43:39 +00:00
|
|
|
*
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
|
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is Copyright (C) 2005 Blender Foundation.
|
|
|
|
|
* All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
|
*
|
|
|
|
|
* Contributor(s): none yet.
|
|
|
|
|
*
|
2008-01-07 19:13:47 +00:00
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
2005-03-29 16:43:39 +00:00
|
|
|
*/
|
|
|
|
|
|
2005-03-21 01:37:14 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <math.h>
|
2005-08-03 04:04:05 +00:00
|
|
|
#include <float.h>
|
|
|
|
|
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
|
|
#include "DNA_mesh_types.h"
|
|
|
|
|
#include "DNA_meshdata_types.h"
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
#include "DNA_modifier_types.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "DNA_object_types.h"
|
2008-02-13 11:18:08 +00:00
|
|
|
#include "DNA_scene_types.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
#include "BKE_cdderivedmesh.h"
|
2006-11-11 16:38:37 +00:00
|
|
|
#include "BKE_customdata.h"
|
2008-02-13 11:18:08 +00:00
|
|
|
#include "BKE_DerivedMesh.h"
|
|
|
|
|
#include "BKE_displist.h"
|
2005-07-17 04:17:33 +00:00
|
|
|
#include "BKE_utildefines.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "BKE_global.h"
|
|
|
|
|
#include "BKE_mesh.h"
|
2009-01-06 18:59:03 +00:00
|
|
|
#include "BKE_multires.h"
|
2008-02-13 11:18:08 +00:00
|
|
|
#include "BKE_scene.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "BKE_subsurf.h"
|
2009-07-26 13:12:55 +00:00
|
|
|
#include "BKE_tessmesh.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
|
#include "BLI_editVert.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "BLI_linklist.h"
|
|
|
|
|
#include "BLI_memarena.h"
|
2006-01-10 11:36:57 +00:00
|
|
|
#include "BLI_edgehash.h"
|
2009-09-15 15:32:09 +00:00
|
|
|
#include "PIL_time.h"
|
2009-09-17 23:05:33 +00:00
|
|
|
#include "BLI_array.h"
|
2005-03-21 01:37:14 +00:00
|
|
|
|
2005-03-30 08:12:27 +00:00
|
|
|
#include "BIF_gl.h"
|
2009-07-08 16:17:47 +00:00
|
|
|
#include "BIF_glutil.h"
|
2005-03-30 08:12:27 +00:00
|
|
|
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
#include "GPU_draw.h"
|
|
|
|
|
#include "GPU_extensions.h"
|
|
|
|
|
#include "GPU_material.h"
|
|
|
|
|
|
2005-03-21 01:37:14 +00:00
|
|
|
#include "CCGSubSurf.h"
|
|
|
|
|
|
2005-04-03 21:52:10 +00:00
|
|
|
typedef struct _VertData {
|
|
|
|
|
float co[3];
|
|
|
|
|
float no[3];
|
|
|
|
|
} VertData;
|
|
|
|
|
|
2006-01-10 11:36:57 +00:00
|
|
|
struct CCGDerivedMesh {
|
|
|
|
|
DerivedMesh dm;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *ss;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
int drawInteriorEdges, useSubsurfUv;
|
2006-01-10 11:36:57 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
struct {int startVert; CCVert *vert;} *vertMap;
|
|
|
|
|
struct {int startVert; int startEdge; CCEdge *edge;} *edgeMap;
|
2006-08-28 01:12:36 +00:00
|
|
|
struct {int startVert; int startEdge;
|
2009-08-15 17:31:28 +00:00
|
|
|
int startFace; CCFace *face;} *faceMap;
|
2009-09-15 15:32:09 +00:00
|
|
|
/*maps final faces to faceMap faces*/
|
|
|
|
|
int *reverseFaceMap;
|
|
|
|
|
|
|
|
|
|
EdgeHash *ehash;
|
2006-01-10 11:36:57 +00:00
|
|
|
};
|
|
|
|
|
|
2005-08-07 05:42:03 +00:00
|
|
|
typedef struct CCGDerivedMesh CCGDerivedMesh;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v);
|
|
|
|
|
static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e);
|
|
|
|
|
static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f);
|
2009-08-18 20:05:08 +00:00
|
|
|
static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
|
|
|
|
|
int drawInteriorEdges,
|
|
|
|
|
int useSubsurfUv,
|
|
|
|
|
DerivedMesh *dm);
|
2005-08-07 05:42:03 +00:00
|
|
|
|
2005-03-21 01:37:14 +00:00
|
|
|
///
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void *arena_alloc(CCAllocHDL a, int numBytes) {
|
2005-03-21 01:37:14 +00:00
|
|
|
return BLI_memarena_alloc(a, numBytes);
|
|
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void *arena_realloc(CCAllocHDL a, void *ptr, int newSize, int oldSize) {
|
2005-03-21 01:37:14 +00:00
|
|
|
void *p2 = BLI_memarena_alloc(a, newSize);
|
|
|
|
|
if (ptr) {
|
|
|
|
|
memcpy(p2, ptr, oldSize);
|
|
|
|
|
}
|
|
|
|
|
return p2;
|
|
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void arena_free(CCAllocHDL a, void *ptr) {
|
2005-03-21 01:37:14 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void arena_release(CCAllocHDL a) {
|
2005-03-21 01:37:14 +00:00
|
|
|
BLI_memarena_free(a);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static CSubSurf *_getSubSurf(CSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) {
|
2005-03-21 01:37:14 +00:00
|
|
|
CCGMeshIFC ifc;
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *ccgSS;
|
2005-03-21 01:37:14 +00:00
|
|
|
|
2005-07-22 15:09:54 +00:00
|
|
|
/* subdivLevels==0 is not allowed */
|
|
|
|
|
subdivLevels = MAX2(subdivLevels, 1);
|
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (prevSS) {
|
|
|
|
|
int oldUseAging;
|
|
|
|
|
|
2005-07-23 19:15:08 +00:00
|
|
|
useAging = !!useAging;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
|
|
|
|
if (oldUseAging!=useAging) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(prevSS);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
} else {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_setSubdivisionLevels(prevSS, subdivLevels);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
|
|
|
|
return prevSS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (useAging) {
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 12;
|
2005-03-31 15:44:05 +00:00
|
|
|
} else {
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8;
|
2005-03-31 15:44:05 +00:00
|
|
|
}
|
2005-04-04 02:55:56 +00:00
|
|
|
ifc.vertDataSize = sizeof(VertData);
|
2005-03-21 01:37:14 +00:00
|
|
|
|
2005-03-31 16:54:47 +00:00
|
|
|
if (useArena) {
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
CCGAllocatorIFC allocatorIFC;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCAllocHDL allocator = BLI_memarena_new((1<<16));
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
2005-03-31 16:54:47 +00:00
|
|
|
allocatorIFC.alloc = arena_alloc;
|
|
|
|
|
allocatorIFC.realloc = arena_realloc;
|
|
|
|
|
allocatorIFC.free = arena_free;
|
|
|
|
|
allocatorIFC.release = arena_release;
|
2005-03-21 01:37:14 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
ccgSS = CCS_new(&ifc, subdivLevels, &allocatorIFC, allocator);
|
2005-03-31 16:54:47 +00:00
|
|
|
} else {
|
2009-08-15 17:31:28 +00:00
|
|
|
ccgSS = CCS_new(&ifc, subdivLevels, NULL, NULL);
|
2005-03-31 16:54:47 +00:00
|
|
|
}
|
2005-03-31 15:44:05 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (useAging) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_setUseAgeCounts(ccgSS, 1, 8, 8, 8);
|
2005-03-31 15:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no));
|
2005-04-03 21:52:10 +00:00
|
|
|
|
2005-03-31 15:44:05 +00:00
|
|
|
return ccgSS;
|
2005-03-21 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) {
|
|
|
|
|
CCVert *v0 = CCS_getEdgeVert0(e);
|
|
|
|
|
CCVert *v1 = CCS_getEdgeVert1(e);
|
|
|
|
|
int v0idx = *((int*) CCS_getVertUserData(ss, v0));
|
|
|
|
|
int v1idx = *((int*) CCS_getVertUserData(ss, v1));
|
|
|
|
|
int edgeBase = *((int*) CCS_getEdgeUserData(ss, e));
|
2005-03-21 01:37:14 +00:00
|
|
|
|
|
|
|
|
if (x==0) {
|
|
|
|
|
return v0idx;
|
|
|
|
|
} else if (x==edgeSize-1) {
|
|
|
|
|
return v1idx;
|
|
|
|
|
} else {
|
|
|
|
|
return edgeBase + x-1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-18 20:05:08 +00:00
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
BM_INLINE int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) {
|
2009-08-15 17:31:28 +00:00
|
|
|
int faceBase = *((int*) CCS_getFaceUserData(ss, f));
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
2005-03-21 01:37:14 +00:00
|
|
|
|
|
|
|
|
if (x==gridSize-1 && y==gridSize-1) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, S);
|
|
|
|
|
return *((int*) CCS_getVertUserData(ss, v));
|
2005-03-21 01:37:14 +00:00
|
|
|
} else if (x==gridSize-1) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, S);
|
|
|
|
|
CCEdge *e = CCS_getFaceEdge(ss, f, S);
|
|
|
|
|
int edgeBase = *((int*) CCS_getEdgeUserData(ss, e));
|
|
|
|
|
if (v==CCS_getEdgeVert0(e)) {
|
2005-03-21 01:37:14 +00:00
|
|
|
return edgeBase + (gridSize-1-y)-1;
|
|
|
|
|
} else {
|
|
|
|
|
return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1);
|
|
|
|
|
}
|
|
|
|
|
} else if (y==gridSize-1) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, S);
|
|
|
|
|
CCEdge *e = CCS_getFaceEdge(ss, f, (S+numVerts-1)%numVerts);
|
|
|
|
|
int edgeBase = *((int*) CCS_getEdgeUserData(ss, e));
|
|
|
|
|
if (v==CCS_getEdgeVert0(e)) {
|
2005-03-21 01:37:14 +00:00
|
|
|
return edgeBase + (gridSize-1-x)-1;
|
|
|
|
|
} else {
|
|
|
|
|
return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1);
|
|
|
|
|
}
|
|
|
|
|
} else if (x==0 && y==0) {
|
|
|
|
|
return faceBase;
|
|
|
|
|
} else if (x==0) {
|
|
|
|
|
S = (S+numVerts-1)%numVerts;
|
|
|
|
|
return faceBase + 1 + (gridSize-2)*S + (y-1);
|
|
|
|
|
} else if (y==0) {
|
|
|
|
|
return faceBase + 1 + (gridSize-2)*S + (x-1);
|
|
|
|
|
} else {
|
|
|
|
|
return faceBase + 1 + (gridSize-2)*numVerts + S*(gridSize-2)*(gridSize-2) + (y-1)*(gridSize-2) + (x-1);
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-18 11:31:20 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCVertHDL *fverts) {
|
2006-01-10 11:36:57 +00:00
|
|
|
unsigned int *fv = &mf->v1;
|
2006-02-19 11:37:50 +00:00
|
|
|
UvMapVert *v, *nv;
|
2006-01-10 11:36:57 +00:00
|
|
|
int j, nverts= mf->v4? 4: 3;
|
|
|
|
|
|
|
|
|
|
for (j=0; j<nverts; j++, fv++) {
|
|
|
|
|
for (nv=v=get_uv_map_vert(vmap, *fv); v; v=v->next) {
|
|
|
|
|
if (v->separate)
|
|
|
|
|
nv= v;
|
|
|
|
|
if (v->f == fi)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2008-02-18 10:49:46 +00:00
|
|
|
fverts[j]= SET_INT_IN_POINTER(nv->f*4 + nv->tfindex);
|
2006-01-10 11:36:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFace *tface) {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
#if 0
|
|
|
|
|
MFace *mface = dm->getTessFaceArray(dm);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
MVert *mvert = dm->getVertArray(dm);
|
|
|
|
|
int totvert = dm->getNumVerts(dm);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
int totface = dm->getNumTessFaces(dm);
|
2006-01-10 11:36:57 +00:00
|
|
|
int i, j, seam;
|
2006-02-19 11:37:50 +00:00
|
|
|
UvMapVert *v;
|
2006-01-10 11:36:57 +00:00
|
|
|
UvVertMap *vmap;
|
|
|
|
|
float limit[2];
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVertHDL fverts[4];
|
2006-01-10 11:36:57 +00:00
|
|
|
EdgeHash *ehash;
|
2009-08-15 17:31:28 +00:00
|
|
|
float creaseFactor = (float)CCS_getSubdivisionLevels(ss);
|
2006-01-10 11:36:57 +00:00
|
|
|
|
2008-03-07 15:38:56 +00:00
|
|
|
limit[0]= limit[1]= STD_UV_CONNECT_LIMIT;
|
2006-01-10 11:36:57 +00:00
|
|
|
vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit);
|
|
|
|
|
if (!vmap)
|
|
|
|
|
return 0;
|
2006-01-13 06:56:32 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_initFullSync(ss);
|
2006-01-10 11:36:57 +00:00
|
|
|
|
|
|
|
|
/* create vertices */
|
|
|
|
|
for (i=0; i<totvert; i++) {
|
2006-01-13 06:56:32 +00:00
|
|
|
if (!get_uv_map_vert(vmap, i))
|
|
|
|
|
continue;
|
|
|
|
|
|
2006-01-10 11:36:57 +00:00
|
|
|
for (v=get_uv_map_vert(vmap, i)->next; v; v=v->next)
|
|
|
|
|
if (v->separate)
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
seam = (v != NULL) || ((mvert+i)->flag & ME_VERT_MERGED);
|
|
|
|
|
|
|
|
|
|
for (v=get_uv_map_vert(vmap, i); v; v=v->next) {
|
|
|
|
|
if (v->separate) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *ssv;
|
|
|
|
|
CCVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex);
|
2006-01-10 11:36:57 +00:00
|
|
|
float uv[3];
|
|
|
|
|
|
|
|
|
|
uv[0]= (tface+v->f)->uv[v->tfindex][0];
|
|
|
|
|
uv[1]= (tface+v->f)->uv[v->tfindex][1];
|
|
|
|
|
uv[2]= 0.0f;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncVert(ss, vhdl, uv, seam, &ssv);
|
2006-01-10 11:36:57 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* create edges */
|
|
|
|
|
ehash = BLI_edgehash_new();
|
|
|
|
|
|
|
|
|
|
for (i=0; i<totface; i++) {
|
|
|
|
|
MFace *mf = &((MFace*) mface)[i];
|
|
|
|
|
int nverts= mf->v4? 4: 3;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *origf= CCS_getFace(origss, SET_INT_IN_POINTER(i));
|
2006-01-10 11:36:57 +00:00
|
|
|
unsigned int *fv = &mf->v1;
|
|
|
|
|
|
|
|
|
|
get_face_uv_map_vert(vmap, mf, i, fverts);
|
|
|
|
|
|
|
|
|
|
for (j=0; j<nverts; j++) {
|
2008-02-18 10:49:46 +00:00
|
|
|
int v0 = GET_INT_FROM_POINTER(fverts[j]);
|
|
|
|
|
int v1 = GET_INT_FROM_POINTER(fverts[(j+1)%nverts]);
|
2006-01-10 11:36:57 +00:00
|
|
|
MVert *mv0 = mvert + *(fv+j);
|
|
|
|
|
MVert *mv1 = mvert + *(fv+((j+1)%nverts));
|
|
|
|
|
|
|
|
|
|
if (!BLI_edgehash_haskey(ehash, v0, v1)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e, *orige= CCS_getFaceEdge(origss, origf, j);
|
|
|
|
|
CCEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j);
|
2006-02-19 11:37:50 +00:00
|
|
|
float crease;
|
2006-01-10 11:36:57 +00:00
|
|
|
|
|
|
|
|
if ((mv0->flag&mv1->flag) & ME_VERT_MERGED)
|
2006-02-19 11:37:50 +00:00
|
|
|
crease = creaseFactor;
|
|
|
|
|
else
|
2009-08-15 17:31:28 +00:00
|
|
|
crease = CCS_getEdgeCrease(orige);
|
2006-01-10 11:36:57 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e);
|
2006-01-10 11:36:57 +00:00
|
|
|
BLI_edgehash_insert(ehash, v0, v1, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_edgehash_free(ehash, NULL);
|
|
|
|
|
|
|
|
|
|
/* create faces */
|
|
|
|
|
for (i=0; i<totface; i++) {
|
|
|
|
|
MFace *mf = &((MFace*) mface)[i];
|
|
|
|
|
int nverts= mf->v4? 4: 3;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f;
|
2006-01-10 11:36:57 +00:00
|
|
|
|
|
|
|
|
get_face_uv_map_vert(vmap, mf, i, fverts);
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f);
|
2006-01-10 11:36:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free_uv_vert_map(vmap);
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_processSync(ss);
|
2006-01-10 11:36:57 +00:00
|
|
|
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
#endif
|
2006-01-10 11:36:57 +00:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void set_subsurf_uv(CSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n)
|
2006-12-12 21:29:09 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *uvss;
|
|
|
|
|
CCFace **faceMap;
|
2006-12-12 21:29:09 +00:00
|
|
|
MTFace *tf;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFaceIterator *fi;
|
2006-12-12 21:29:09 +00:00
|
|
|
int index, gridSize, gridFaces, edgeSize, totface, x, y, S;
|
|
|
|
|
MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n);
|
|
|
|
|
MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n);
|
|
|
|
|
|
|
|
|
|
if(!dmtface || !tface)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* create a CCGSubsurf from uv's */
|
2009-08-15 17:31:28 +00:00
|
|
|
uvss = _getSubSurf(NULL, CCS_getSubdivisionLevels(ss), 0, 1, 0);
|
2006-12-12 21:29:09 +00:00
|
|
|
|
|
|
|
|
if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(uvss);
|
2006-12-12 21:29:09 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* get some info from CCGSubsurf */
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(uvss);
|
|
|
|
|
edgeSize = CCS_getEdgeSize(uvss);
|
|
|
|
|
gridSize = CCS_getGridSize(uvss);
|
2006-12-12 21:29:09 +00:00
|
|
|
gridFaces = gridSize - 1;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
/* make a map from original faces to CCFaces */
|
2006-12-12 21:29:09 +00:00
|
|
|
faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv");
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
fi = CCS_getFaceIterator(uvss);
|
|
|
|
|
for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
faceMap[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(uvss, f))] = f;
|
2006-12-12 21:29:09 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2006-12-12 21:29:09 +00:00
|
|
|
|
|
|
|
|
/* load coordinates from uvss into tface */
|
|
|
|
|
tf= tface;
|
|
|
|
|
|
|
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = faceMap[index];
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
2006-12-12 21:29:09 +00:00
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData= CCS_getFaceGridDataArray(uvss, f, S);
|
2006-12-12 21:29:09 +00:00
|
|
|
|
|
|
|
|
for(y = 0; y < gridFaces; y++) {
|
|
|
|
|
for(x = 0; x < gridFaces; x++) {
|
|
|
|
|
float *a = faceGridData[(y + 0)*gridSize + x + 0].co;
|
|
|
|
|
float *b = faceGridData[(y + 0)*gridSize + x + 1].co;
|
|
|
|
|
float *c = faceGridData[(y + 1)*gridSize + x + 1].co;
|
|
|
|
|
float *d = faceGridData[(y + 1)*gridSize + x + 0].co;
|
|
|
|
|
|
|
|
|
|
tf->uv[0][0] = a[0]; tf->uv[0][1] = a[1];
|
|
|
|
|
tf->uv[1][0] = d[0]; tf->uv[1][1] = d[1];
|
|
|
|
|
tf->uv[2][0] = c[0]; tf->uv[2][1] = c[1];
|
|
|
|
|
tf->uv[3][0] = b[0]; tf->uv[3][1] = b[1];
|
|
|
|
|
|
|
|
|
|
tf++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(uvss);
|
2006-12-12 21:29:09 +00:00
|
|
|
MEM_freeN(faceMap);
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-24 20:26:28 +00:00
|
|
|
#if 0
|
2009-08-15 17:31:28 +00:00
|
|
|
static unsigned int ss_getEdgeFlags(CSubSurf *ss, CCEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, MTFace *tface)
|
2005-08-18 11:31:20 +00:00
|
|
|
{
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
unsigned int flags = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
int N = CCS_getEdgeNumFaces(e);
|
2005-08-18 11:31:20 +00:00
|
|
|
|
|
|
|
|
if (!N) flags |= ME_LOOSEEDGE;
|
|
|
|
|
|
|
|
|
|
if (ssFromEditmesh) {
|
2009-08-15 17:31:28 +00:00
|
|
|
EditEdge *eed = CCS_getEdgeEdgeHandle(e);
|
2005-08-18 11:31:20 +00:00
|
|
|
|
2005-08-21 20:48:45 +00:00
|
|
|
flags |= ME_EDGEDRAW|ME_EDGERENDER;
|
2005-08-18 11:31:20 +00:00
|
|
|
if (eed->seam) {
|
|
|
|
|
flags |= ME_SEAM;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2005-08-21 20:48:45 +00:00
|
|
|
if (edgeIdx!=-1) {
|
2005-08-18 11:31:20 +00:00
|
|
|
MEdge *origMed = &medge[edgeIdx];
|
|
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (dlm) {
|
|
|
|
|
flags |= origMed->flag&~ME_EDGE_STEPINDEX;
|
|
|
|
|
} else {
|
2005-08-21 20:48:45 +00:00
|
|
|
flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER;
|
2005-08-18 11:31:20 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return flags;
|
|
|
|
|
}
|
2005-08-24 20:26:28 +00:00
|
|
|
#endif
|
2005-08-18 11:31:20 +00:00
|
|
|
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
static void calc_ss_weights(int gridFaces,
|
|
|
|
|
FaceVertWeight **qweight, FaceVertWeight **tweight)
|
|
|
|
|
{
|
|
|
|
|
FaceVertWeight *qw, *tw;
|
|
|
|
|
int x, y, j;
|
|
|
|
|
int numWeights = gridFaces * gridFaces;
|
|
|
|
|
|
|
|
|
|
*tweight = MEM_mallocN(sizeof(**tweight) * numWeights, "ssTriWeight");
|
|
|
|
|
*qweight = MEM_mallocN(sizeof(**qweight) * numWeights, "ssQuadWeight");
|
|
|
|
|
|
|
|
|
|
qw = *qweight;
|
|
|
|
|
tw = *tweight;
|
|
|
|
|
|
|
|
|
|
for (y = 0; y < gridFaces; y++) {
|
|
|
|
|
for (x = 0; x < gridFaces; x++) {
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
|
|
|
int fx = x + (j == 2 || j == 3);
|
|
|
|
|
int fy = y + (j == 1 || j == 2);
|
|
|
|
|
float x_v = (float) fx / gridFaces;
|
|
|
|
|
float y_v = (float) fy / gridFaces;
|
|
|
|
|
float tx_v = (1.0f - x_v), ty_v = (1.0f - y_v);
|
|
|
|
|
float center = (1.0f / 3.0f) * tx_v * ty_v;
|
|
|
|
|
|
|
|
|
|
(*tw)[j][0] = center + 0.5f * tx_v * y_v;
|
|
|
|
|
(*tw)[j][2] = center + 0.5f * x_v * ty_v;
|
|
|
|
|
(*tw)[j][1] = 1.0f - (*tw)[j][0] - (*tw)[j][2];
|
|
|
|
|
(*tw)[j][3] = 0.0f;
|
|
|
|
|
|
|
|
|
|
tx_v *= 0.5f;
|
|
|
|
|
ty_v *= 0.5f;
|
|
|
|
|
|
|
|
|
|
(*qw)[j][3] = tx_v * ty_v;
|
|
|
|
|
(*qw)[j][0] = (*qw)[j][3] + tx_v * y_v;
|
|
|
|
|
(*qw)[j][2] = (*qw)[j][3] + x_v * ty_v;
|
|
|
|
|
(*qw)[j][1] = 1.0f - (*qw)[j][0] - (*qw)[j][2] - (*qw)[j][3];
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
tw++;
|
|
|
|
|
qw++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-06-16 20:08:40 +00:00
|
|
|
/* face weighting */
|
|
|
|
|
typedef struct FaceVertWeightEntry {
|
|
|
|
|
FaceVertWeight *weight;
|
2009-08-16 19:55:05 +00:00
|
|
|
float *w;
|
2009-06-16 20:08:40 +00:00
|
|
|
int valid;
|
|
|
|
|
} FaceVertWeightEntry;
|
|
|
|
|
|
|
|
|
|
typedef struct WeightTable {
|
|
|
|
|
FaceVertWeightEntry *weight_table;
|
|
|
|
|
int len;
|
|
|
|
|
} WeightTable;
|
|
|
|
|
|
2009-08-16 19:55:05 +00:00
|
|
|
static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
|
2009-06-16 20:08:40 +00:00
|
|
|
{
|
2009-08-16 19:55:05 +00:00
|
|
|
int x, y, i, j;
|
|
|
|
|
float *w, w1, w2, w4, fac, fac2, fx, fy;
|
|
|
|
|
|
|
|
|
|
if (wtable->len <= faceLen) {
|
|
|
|
|
void *tmp = MEM_callocN(sizeof(FaceVertWeightEntry)*(faceLen+1), "weight table alloc 2");
|
|
|
|
|
|
|
|
|
|
if (wtable->len) {
|
|
|
|
|
memcpy(tmp, wtable->weight_table, sizeof(FaceVertWeightEntry)*wtable->len);
|
|
|
|
|
MEM_freeN(wtable->weight_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
wtable->weight_table = tmp;
|
|
|
|
|
wtable->len = faceLen+1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!wtable->weight_table[faceLen].valid) {
|
|
|
|
|
wtable->weight_table[faceLen].valid = 1;
|
|
|
|
|
wtable->weight_table[faceLen].w = w = MEM_callocN(sizeof(float)*faceLen*faceLen*(gridCuts+2)*(gridCuts+2), "weight table alloc");
|
|
|
|
|
fac = 1.0 / (float)faceLen;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<faceLen; i++) {
|
|
|
|
|
for (x=0; x<gridCuts+2; x++) {
|
|
|
|
|
for (y=0; y<gridCuts+2; y++) {
|
|
|
|
|
fx = 0.5f - (float)x / (float)(gridCuts+1) / 2.0f;
|
|
|
|
|
fy = 0.5f - (float)y / (float)(gridCuts+1) / 2.0f;
|
|
|
|
|
|
|
|
|
|
fac2 = faceLen - 4;
|
|
|
|
|
w1 = (1.0f - fx) * (1.0f - fy) + (-fac2*fx*fy*fac);
|
|
|
|
|
w2 = (1.0f - fx + fac2*fx*-fac) * (fy);
|
|
|
|
|
w4 = (fx) * (1.0 - fy + -fac2*fy*fac);
|
|
|
|
|
|
|
|
|
|
fac2 = 1.0 - (w1+w2+w4);
|
|
|
|
|
fac2 = fac2 / (float)(faceLen-3);
|
|
|
|
|
for (j=0; j<faceLen; j++)
|
|
|
|
|
w[j] = fac2;
|
|
|
|
|
|
|
|
|
|
w[i] = w1;
|
|
|
|
|
w[(i-1+faceLen)%faceLen] = w2;
|
|
|
|
|
w[(i+1)%faceLen] = w4;
|
|
|
|
|
|
|
|
|
|
w += faceLen;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2009-08-16 19:55:05 +00:00
|
|
|
return wtable->weight_table[faceLen].w;
|
2009-06-16 20:08:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void free_ss_weights(WeightTable *wtable)
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<wtable->len; i++) {
|
|
|
|
|
if (wtable->weight_table[i].valid)
|
2009-08-16 19:55:05 +00:00
|
|
|
MEM_freeN(wtable->weight_table[i].w);
|
2009-06-16 20:08:40 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh,
|
2006-08-28 01:12:36 +00:00
|
|
|
int drawInteriorEdges, int useSubsurfUv,
|
2009-01-06 18:59:03 +00:00
|
|
|
DerivedMesh *dm, MultiresSubsurf *ms)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-18 20:05:08 +00:00
|
|
|
DerivedMesh *cgdm, *result;
|
2009-09-15 15:32:09 +00:00
|
|
|
double curt = PIL_check_seconds_timer();
|
2009-08-18 20:05:08 +00:00
|
|
|
|
|
|
|
|
cgdm = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm);
|
2009-09-15 18:51:33 +00:00
|
|
|
result = CDDM_copy(cgdm, 1);
|
2009-09-15 15:32:09 +00:00
|
|
|
|
|
|
|
|
printf("subsurf conversion time: %.6lf\n", PIL_check_seconds_timer() - curt);
|
2009-08-30 21:36:16 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
cgdm->needsFree = 1;
|
|
|
|
|
cgdm->release(cgdm);
|
|
|
|
|
|
2009-08-30 21:36:16 +00:00
|
|
|
CDDM_calc_normals(result);
|
|
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
return result;
|
|
|
|
|
#if 0
|
2006-08-28 01:12:36 +00:00
|
|
|
DerivedMesh *result;
|
2009-08-15 17:31:28 +00:00
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridFaces = gridSize - 1;
|
|
|
|
|
int edgeBase, faceBase;
|
|
|
|
|
int i, j, k, S, x, y, index;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
int *vertIdx = NULL;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(vertIdx);
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVertIterator *vi;
|
|
|
|
|
CCEdgeIterator *ei;
|
|
|
|
|
CCFaceIterator *fi;
|
|
|
|
|
CCFace **faceMap2;
|
|
|
|
|
CCEdge **edgeMap2;
|
|
|
|
|
CCVert **vertMap2;
|
2006-08-28 01:12:36 +00:00
|
|
|
int totvert, totedge, totface;
|
|
|
|
|
MVert *mvert;
|
|
|
|
|
MEdge *med;
|
2009-06-16 20:08:40 +00:00
|
|
|
float *w = NULL;
|
|
|
|
|
WeightTable wtable;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(w);
|
2006-08-28 01:12:36 +00:00
|
|
|
MFace *mf;
|
|
|
|
|
int *origIndex;
|
|
|
|
|
|
2009-06-16 20:08:40 +00:00
|
|
|
memset(&wtable, 0, sizeof(wtable));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
/* vert map */
|
2009-08-15 17:31:28 +00:00
|
|
|
totvert = CCS_getNumVerts(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
|
2009-08-15 17:31:28 +00:00
|
|
|
vi = CCS_getVertIterator(ss);
|
|
|
|
|
for(; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertMap2[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))] = v;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totedge = CCS_getNumEdges(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
|
2009-08-15 17:31:28 +00:00
|
|
|
ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
for(; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
edgeMap2[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))] = e;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
|
2009-08-15 17:31:28 +00:00
|
|
|
fi = CCS_getFaceIterator(ss);
|
|
|
|
|
for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
faceMap2[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))] = f;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-01-06 18:59:03 +00:00
|
|
|
if(ms) {
|
2009-08-15 17:31:28 +00:00
|
|
|
result = MultiresDM_new(ms, dm, CCS_getNumFinalVerts(ss),
|
|
|
|
|
CCS_getNumFinalEdges(ss),
|
|
|
|
|
CCS_getNumFinalFaces(ss), 0, 0);
|
2009-01-06 18:59:03 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if(dm) {
|
2009-08-15 17:31:28 +00:00
|
|
|
result = CDDM_from_template(dm, CCS_getNumFinalVerts(ss),
|
|
|
|
|
CCS_getNumFinalEdges(ss),
|
|
|
|
|
CCS_getNumFinalFaces(ss), 0, 0);
|
2009-01-06 18:59:03 +00:00
|
|
|
} else {
|
2009-08-15 17:31:28 +00:00
|
|
|
result = CDDM_new(CCS_getNumFinalVerts(ss),
|
|
|
|
|
CCS_getNumFinalEdges(ss),
|
|
|
|
|
CCS_getNumFinalFaces(ss), 0, 0);
|
2009-01-06 18:59:03 +00:00
|
|
|
}
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// load verts
|
|
|
|
|
faceBase = i = 0;
|
|
|
|
|
mvert = CDDM_get_verts(result);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
origIndex = result->getVertData(result, 0, CD_ORIGINDEX);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = faceMap2[index];
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
2009-08-16 19:55:05 +00:00
|
|
|
FaceVertWeight *weight = 0;//get_ss_weights(&wtable, gridFaces-1, numVerts);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(vertIdx);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, S);
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(vertIdx);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertIdx[S] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-16 19:55:05 +00:00
|
|
|
#if 0
|
2006-08-28 01:12:36 +00:00
|
|
|
DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i);
|
2009-08-16 19:55:05 +00:00
|
|
|
#endif
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert->co, CCS_getFaceCenterData(f));
|
2006-08-28 01:12:36 +00:00
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++mvert;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
2009-01-06 18:59:03 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(w);
|
2009-06-16 20:08:40 +00:00
|
|
|
for (x=0; x<numVerts; x++) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(w);
|
2009-06-16 20:08:40 +00:00
|
|
|
}
|
2009-06-10 19:15:27 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
2009-06-16 20:08:40 +00:00
|
|
|
int otherS = (numVerts >= 4) ? (S + 2) % numVerts : 3;
|
2009-01-06 18:59:03 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(x = 1; x < gridFaces; x++) {
|
2009-08-16 19:55:05 +00:00
|
|
|
#if 0
|
2006-08-28 01:12:36 +00:00
|
|
|
w[prevS] = weight[x][0][0];
|
|
|
|
|
w[S] = weight[x][0][1];
|
|
|
|
|
w[nextS] = weight[x][0][2];
|
|
|
|
|
w[otherS] = weight[x][0][3];
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
|
2009-08-16 19:55:05 +00:00
|
|
|
#endif
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_v3_v3(mvert->co,
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getFaceGridEdgeData(ss, f, S, x));
|
2009-01-06 18:59:03 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++mvert;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(w);
|
2009-06-16 20:08:40 +00:00
|
|
|
for (x=0; x<numVerts; x++) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(w);
|
2009-06-16 20:08:40 +00:00
|
|
|
}
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
|
|
|
|
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(y = 1; y < gridFaces; y++) {
|
|
|
|
|
for(x = 1; x < gridFaces; x++) {
|
2009-08-16 19:55:05 +00:00
|
|
|
#if 0
|
2006-08-28 01:12:36 +00:00
|
|
|
w[prevS] = weight[y * gridFaces + x][0][0];
|
|
|
|
|
w[S] = weight[y * gridFaces + x][0][1];
|
|
|
|
|
w[nextS] = weight[y * gridFaces + x][0][2];
|
|
|
|
|
w[otherS] = weight[y * gridFaces + x][0][3];
|
|
|
|
|
DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i);
|
2009-08-16 19:55:05 +00:00
|
|
|
#endif
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_v3_v3(mvert->co,
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getFaceGridData(ss, f, S, x, y));
|
2006-08-28 01:12:36 +00:00
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++mvert;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*)CCS_getFaceUserData(ss, f)) = faceBase;
|
2006-08-28 01:12:36 +00:00
|
|
|
faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
edgeBase = i;
|
|
|
|
|
for(index = 0; index < totedge; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = edgeMap2[index];
|
2006-08-28 01:12:36 +00:00
|
|
|
int x;
|
|
|
|
|
int vertIdx[2];
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v;
|
|
|
|
|
v = CCS_getEdgeVert0(e);
|
|
|
|
|
vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
v = CCS_getEdgeVert1(e);
|
|
|
|
|
vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(x = 1; x < edgeSize - 1; x++) {
|
2009-06-16 20:08:40 +00:00
|
|
|
float w2[2];
|
|
|
|
|
|
|
|
|
|
w2[1] = (float) x / (edgeSize - 1);
|
|
|
|
|
w2[0] = 1 - w2[1];
|
|
|
|
|
DM_interp_vert_data(dm, result, vertIdx, w2, 2, i);
|
|
|
|
|
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert->co, CCS_getEdgeData(ss, e, x));
|
2006-08-28 01:12:36 +00:00
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++mvert;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*)CCS_getEdgeUserData(ss, e)) = edgeBase;
|
2006-08-28 01:12:36 +00:00
|
|
|
edgeBase += edgeSize-2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(index = 0; index < totvert; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = vertMap2[index];
|
2006-08-28 01:12:36 +00:00
|
|
|
int vertIdx;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertIdx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
DM_copy_vert_data(dm, result, vertIdx, i, 1);
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert->co, CCS_getVertData(ss, v));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*)CCS_getVertUserData(ss, v)) = i;
|
|
|
|
|
*origIndex = cgdm_getVertMapIndex(ss, v);
|
2006-08-28 01:12:36 +00:00
|
|
|
++mvert;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// load edges
|
|
|
|
|
i = 0;
|
|
|
|
|
med = CDDM_get_edges(result);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
origIndex = result->getEdgeData(result, 0, CD_ORIGINDEX);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = faceMap2[index];
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(k = 0; k < numVerts; k++) {
|
|
|
|
|
for(x = 0; x < gridFaces; x++) {
|
|
|
|
|
if(drawInteriorEdges) med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, k, x, 0, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, k, x+1, 0, edgeSize, gridSize);
|
|
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++med;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(x = 1; x < gridFaces; x++) {
|
|
|
|
|
for(y = 0; y < gridFaces; y++) {
|
|
|
|
|
if(drawInteriorEdges)
|
|
|
|
|
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, k, x, y, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, k, x, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++med;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
|
|
if(drawInteriorEdges)
|
|
|
|
|
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, k, y, x, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, k, y + 1, x,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
*origIndex = ORIGINDEX_NONE;
|
|
|
|
|
++med;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(index = 0; index < totedge; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = edgeMap2[index];
|
2006-08-28 01:12:36 +00:00
|
|
|
unsigned int flags = 0;
|
2008-09-09 18:44:10 +00:00
|
|
|
char bweight = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
if(edgeIdx != -1 && dm) {
|
|
|
|
|
MEdge origMed;
|
|
|
|
|
dm->getEdge(dm, edgeIdx, &origMed);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
flags |= origMed.flag;
|
2008-09-09 18:44:10 +00:00
|
|
|
bweight = origMed.bweight;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(x = 0; x < edgeSize - 1; x++) {
|
|
|
|
|
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
|
|
|
|
|
med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
|
|
|
|
|
med->flag = flags;
|
2008-09-09 18:44:10 +00:00
|
|
|
med->bweight = bweight;
|
2009-08-15 17:31:28 +00:00
|
|
|
*origIndex = cgdm_getEdgeMapIndex(ss, e);
|
2006-08-28 01:12:36 +00:00
|
|
|
++med;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// load faces
|
|
|
|
|
i = 0;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
mf = CDDM_get_tessfaces(result);
|
|
|
|
|
origIndex = result->getTessFaceData(result, 0, CD_ORIGINDEX);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = faceMap2[index];
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
int mat_nr;
|
|
|
|
|
int flag;
|
2009-08-15 17:31:28 +00:00
|
|
|
int mapIndex = cgdm_getFaceMapIndex(ss, f);
|
|
|
|
|
int faceIdx = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
if(!ssFromEditmesh) {
|
|
|
|
|
MFace origMFace;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
dm->getTessFace(dm, faceIdx, &origMFace);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
mat_nr = origMFace.mat_nr;
|
|
|
|
|
flag = origMFace.flag;
|
|
|
|
|
} else {
|
2009-08-15 17:31:28 +00:00
|
|
|
BMFace *ef = CCS_getFaceFaceHandle(ss, f);
|
2006-08-28 01:12:36 +00:00
|
|
|
mat_nr = ef->mat_nr;
|
2009-07-26 13:12:55 +00:00
|
|
|
flag = BMFlags_To_MEFlags(ef);
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
2009-08-16 19:55:05 +00:00
|
|
|
FaceVertWeight *weight = 0;//get_ss_weights(&wtable, gridFaces-1, numVerts);
|
2009-06-16 20:08:40 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(y = 0; y < gridFaces; y++) {
|
|
|
|
|
for(x = 0; x < gridFaces; x++) {
|
|
|
|
|
mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->mat_nr = mat_nr;
|
|
|
|
|
mf->flag = flag;
|
2009-08-16 19:55:05 +00:00
|
|
|
#if 0 //BMESH_TODO
|
2006-08-28 01:12:36 +00:00
|
|
|
if(dm) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
|
|
|
|
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
|
|
|
|
|
FaceVertWeight w;
|
|
|
|
|
|
|
|
|
|
for(j = 0; j < 4; ++j) {
|
|
|
|
|
w[j][prevS] = (*weight)[j][0];
|
|
|
|
|
w[j][S] = (*weight)[j][1];
|
|
|
|
|
w[j][nextS] = (*weight)[j][2];
|
|
|
|
|
w[j][otherS] = (*weight)[j][3];
|
|
|
|
|
}
|
2009-07-26 13:12:55 +00:00
|
|
|
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
DM_interp_tessface_data(dm, result, &faceIdx, NULL,
|
2006-08-28 01:12:36 +00:00
|
|
|
&w, 1, i);
|
|
|
|
|
weight++;
|
|
|
|
|
}
|
2009-06-10 19:15:27 +00:00
|
|
|
#endif
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
*origIndex = mapIndex;
|
|
|
|
|
++mf;
|
|
|
|
|
++origIndex;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(faceMap2);
|
|
|
|
|
MEM_freeN(edgeMap2);
|
|
|
|
|
MEM_freeN(vertMap2);
|
|
|
|
|
|
2009-06-16 20:08:40 +00:00
|
|
|
free_ss_weights(&wtable);
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(vertIdx);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2006-12-12 21:29:09 +00:00
|
|
|
if(useSubsurfUv) {
|
|
|
|
|
CustomData *fdata = &result->faceData;
|
|
|
|
|
CustomData *dmfdata = &dm->faceData;
|
|
|
|
|
int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
|
|
|
|
|
int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
|
|
|
|
|
|
|
|
|
|
for (i=0; i<numlayer && i<dmnumlayer; i++)
|
|
|
|
|
set_subsurf_uv(ss, dm, result, i);
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDDM_calc_normals(result);
|
2009-06-16 20:08:40 +00:00
|
|
|
CDDM_tessfaces_to_faces(result);
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(w);
|
2006-08-28 01:12:36 +00:00
|
|
|
return result;
|
2009-08-18 20:05:08 +00:00
|
|
|
#endif
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm,
|
2006-08-28 01:12:36 +00:00
|
|
|
float (*vertexCos)[3], int useFlatSubdiv)
|
|
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
float creaseFactor = (float) CCS_getSubdivisionLevels(ss);
|
|
|
|
|
CCVertHDL *fVerts = NULL;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(fVerts);
|
2006-08-28 01:12:36 +00:00
|
|
|
int totvert = dm->getNumVerts(dm);
|
|
|
|
|
int totedge = dm->getNumEdges(dm);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
int totface = dm->getNumTessFaces(dm);
|
|
|
|
|
int totpoly = dm->getNumFaces(dm);
|
2006-08-28 01:12:36 +00:00
|
|
|
int i;
|
|
|
|
|
int *index;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
MVert *mvert = dm->getVertArray(dm);
|
|
|
|
|
MEdge *medge = dm->getEdgeArray(dm);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
MFace *mface = dm->getTessFaceArray(dm);
|
2006-08-28 01:12:36 +00:00
|
|
|
MVert *mv;
|
|
|
|
|
MEdge *me;
|
|
|
|
|
MFace *mf;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
DMFaceIter *fiter;
|
|
|
|
|
DMLoopIter *liter;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_initFullSync(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
mv = mvert;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(i = 0; i < totvert; i++, mv++, index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
if(vertexCos) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v);
|
2006-08-28 01:12:36 +00:00
|
|
|
} else {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v);
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
((int*)CCS_getVertUserData(ss, v))[1] = *index;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
me = medge;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(i = 0; i < totedge; i++, me++, index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e;
|
2006-08-28 01:12:36 +00:00
|
|
|
float crease;
|
|
|
|
|
|
|
|
|
|
crease = useFlatSubdiv ? creaseFactor :
|
|
|
|
|
me->crease * creaseFactor / 255.0f;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1),
|
2008-02-18 10:49:46 +00:00
|
|
|
SET_INT_IN_POINTER(me->v2), crease, &e);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
((int*)CCS_getEdgeUserData(ss, e))[1] = *index;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
fiter = dm->newFaceIter(dm);
|
|
|
|
|
for (i=0; !fiter->done; fiter->step(fiter), i++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(fVerts);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
index = (int*) fiter->getCDData(fiter, CD_ORIGINDEX, -1);
|
|
|
|
|
liter = fiter->getLoopsIter(fiter);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
for (; !liter->done; liter->step(liter)) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(fVerts);
|
|
|
|
|
fVerts[BLI_array_count(fVerts)-1] = SET_INT_IN_POINTER(liter->vindex);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* this is very bad, means mesh is internally inconsistent.
|
|
|
|
|
* it is not really possible to continue without modifying
|
|
|
|
|
* other parts of code significantly to handle missing faces.
|
|
|
|
|
* since this really shouldn't even be possible we just bail.*/
|
2009-08-15 17:31:28 +00:00
|
|
|
if(CCS_syncFace(ss, SET_INT_IN_POINTER(i), fiter->len,
|
2006-08-28 01:12:36 +00:00
|
|
|
fVerts, &f) == eCCGError_InvalidValue) {
|
|
|
|
|
static int hasGivenError = 0;
|
|
|
|
|
|
|
|
|
|
if(!hasGivenError) {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
printf("Unrecoverable error in SubSurf calculation,"
|
|
|
|
|
" mesh is inconsistent.\n");
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
hasGivenError = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
((int*)CCS_getFaceUserData(ss, f))[1] = *index;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-29 23:55:35 +00:00
|
|
|
fiter->free(fiter);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_processSync(ss);
|
2009-08-29 23:55:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(fVerts);
|
2005-03-21 01:37:14 +00:00
|
|
|
}
|
|
|
|
|
|
2005-03-30 08:12:27 +00:00
|
|
|
/***/
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v) {
|
|
|
|
|
return ((int*) CCS_getVertUserData(ss, v))[1];
|
2005-08-07 05:42:03 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e) {
|
|
|
|
|
return ((int*) CCS_getEdgeUserData(ss, e))[1];
|
2005-08-07 05:42:03 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f) {
|
|
|
|
|
return ((int*) CCS_getFaceUserData(ss, f))[1];
|
2005-08-07 05:42:03 +00:00
|
|
|
}
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCVertIterator *vi = CCS_getVertIterator(ss);
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
|
|
|
|
int i, edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if (!CCS_getNumVerts(ss))
|
2005-07-18 17:33:51 +00:00
|
|
|
min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
|
|
|
|
float *co = CCS_getVertData(ss, v);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
|
|
|
|
DO_MINMAX(co, min_r, max_r);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
for (i=0; i<edgeSize; i++)
|
2005-07-17 04:17:33 +00:00
|
|
|
DO_MINMAX(edgeData[i].co, min_r, max_r);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
2005-07-17 04:17:33 +00:00
|
|
|
|
|
|
|
|
for (y=0; y<gridSize; y++)
|
|
|
|
|
for (x=0; x<gridSize; x++)
|
|
|
|
|
DO_MINMAX(faceGridData[y*gridSize + x].co, min_r, max_r);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
|
|
|
|
CCEIter_free(ei);
|
|
|
|
|
CCVIter_free(vi);
|
2005-07-17 04:17:33 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getNumVerts(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
return CCS_getNumFinalVerts(cgdm->ss);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getNumEdges(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
return CCS_getNumFinalEdges(cgdm->ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static int cgdm_getNumTessFaces(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
return CCS_getNumFinalFaces(cgdm->ss);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
int i;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
memset(mv, 0, sizeof(*mv));
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if((vertNum < cgdm->edgeMap[0].startVert) && (CCS_getNumFaces(ss) > 0)) {
|
2006-08-28 01:12:36 +00:00
|
|
|
/* this vert comes from face data */
|
2009-08-15 17:31:28 +00:00
|
|
|
int lastface = CCS_getNumFaces(ss) - 1;
|
|
|
|
|
CCFace *f;
|
2006-08-28 01:12:36 +00:00
|
|
|
int x, y, grid, numVerts;
|
|
|
|
|
int offset;
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridSideVerts;
|
|
|
|
|
int gridInternalVerts;
|
|
|
|
|
int gridSideEnd;
|
|
|
|
|
int gridInternalEnd;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
while(i < lastface && vertNum >= cgdm->faceMap[i + 1].startVert)
|
2006-08-28 01:12:36 +00:00
|
|
|
++i;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
f = cgdm->faceMap[i].face;
|
|
|
|
|
numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
gridSideVerts = gridSize - 2;
|
|
|
|
|
gridInternalVerts = gridSideVerts * gridSideVerts;
|
|
|
|
|
|
|
|
|
|
gridSideEnd = 1 + numVerts * gridSideVerts;
|
|
|
|
|
gridInternalEnd = gridSideEnd + numVerts * gridInternalVerts;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
offset = vertNum - cgdm->faceMap[i].startVert;
|
2006-08-28 01:12:36 +00:00
|
|
|
if(offset < 1) {
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mv->co, CCS_getFaceCenterData(f));
|
2006-08-28 01:12:36 +00:00
|
|
|
} else if(offset < gridSideEnd) {
|
|
|
|
|
offset -= 1;
|
|
|
|
|
grid = offset / gridSideVerts;
|
|
|
|
|
x = offset % gridSideVerts + 1;
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mv->co, CCS_getFaceGridEdgeData(ss, f, grid, x));
|
2006-08-28 01:12:36 +00:00
|
|
|
} else if(offset < gridInternalEnd) {
|
|
|
|
|
offset -= gridSideEnd;
|
|
|
|
|
grid = offset / gridInternalVerts;
|
|
|
|
|
offset %= gridInternalVerts;
|
|
|
|
|
y = offset / gridSideVerts + 1;
|
|
|
|
|
x = offset % gridSideVerts + 1;
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mv->co, CCS_getFaceGridData(ss, f, grid, x, y));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
} else if((vertNum < cgdm->vertMap[0].startVert) && (CCS_getNumEdges(ss) > 0)) {
|
2006-08-28 01:12:36 +00:00
|
|
|
/* this vert comes from edge data */
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e;
|
|
|
|
|
int lastedge = CCS_getNumEdges(ss) - 1;
|
2006-08-28 01:12:36 +00:00
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
while(i < lastedge && vertNum >= cgdm->edgeMap[i + 1].startVert)
|
2006-08-28 01:12:36 +00:00
|
|
|
++i;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
e = cgdm->edgeMap[i].edge;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
x = vertNum - cgdm->edgeMap[i].startVert + 1;
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mv->co, CCS_getEdgeData(ss, e, x));
|
2006-08-28 01:12:36 +00:00
|
|
|
} else {
|
|
|
|
|
/* this vert comes from vert data */
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v;
|
|
|
|
|
i = vertNum - cgdm->vertMap[0].startVert;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
v = cgdm->vertMap[i].vert;
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mv->co, CCS_getVertData(ss, v));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
2006-08-28 01:12:36 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
memset(med, 0, sizeof(*med));
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if(edgeNum < cgdm->edgeMap[0].startEdge) {
|
2006-08-28 01:12:36 +00:00
|
|
|
/* this edge comes from face data */
|
2009-08-15 17:31:28 +00:00
|
|
|
int lastface = CCS_getNumFaces(ss) - 1;
|
|
|
|
|
CCFace *f;
|
2006-08-28 01:12:36 +00:00
|
|
|
int x, y, grid, numVerts;
|
|
|
|
|
int offset;
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridSideEdges;
|
|
|
|
|
int gridInternalEdges;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
while(i < lastface && edgeNum >= cgdm->faceMap[i + 1].startEdge)
|
2006-08-28 01:12:36 +00:00
|
|
|
++i;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
f = cgdm->faceMap[i].face;
|
|
|
|
|
numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
gridSideEdges = gridSize - 1;
|
|
|
|
|
gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
offset = edgeNum - cgdm->faceMap[i].startEdge;
|
2006-08-28 01:12:36 +00:00
|
|
|
grid = offset / (gridSideEdges + gridInternalEdges);
|
|
|
|
|
offset %= (gridSideEdges + gridInternalEdges);
|
|
|
|
|
|
|
|
|
|
if(offset < gridSideEdges) {
|
|
|
|
|
x = offset;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, grid, x, 0, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, grid, x+1, 0, edgeSize, gridSize);
|
|
|
|
|
} else {
|
|
|
|
|
offset -= gridSideEdges;
|
|
|
|
|
x = (offset / 2) / gridSideEdges + 1;
|
|
|
|
|
y = (offset / 2) % gridSideEdges;
|
|
|
|
|
if(offset % 2 == 0) {
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, grid, x, y, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, grid, x, y+1, edgeSize, gridSize);
|
|
|
|
|
} else {
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, grid, y, x, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, grid, y+1, x, edgeSize, gridSize);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* this vert comes from edge data */
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e;
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2007-08-28 08:53:36 +00:00
|
|
|
int x, *edgeFlag;
|
2006-08-28 01:12:36 +00:00
|
|
|
unsigned int flags = 0;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
e = cgdm->edgeMap[i].edge;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
x = edgeNum - cgdm->edgeMap[i].startEdge;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
|
|
|
|
|
med->v2 = getEdgeIndex(ss, e, x+1, edgeSize);
|
|
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS);
|
|
|
|
|
if(edgeFlag)
|
|
|
|
|
flags |= (*edgeFlag & (ME_SEAM | ME_SHARP))
|
|
|
|
|
| ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
else
|
|
|
|
|
flags |= ME_EDGEDRAW | ME_EDGERENDER;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
med->flag = flags;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridSideEdges = gridSize - 1;
|
|
|
|
|
int gridFaces = gridSideEdges * gridSideEdges;
|
|
|
|
|
int i;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f;
|
2006-08-28 01:12:36 +00:00
|
|
|
int numVerts;
|
|
|
|
|
int offset;
|
|
|
|
|
int grid;
|
|
|
|
|
int x, y;
|
2009-08-15 17:31:28 +00:00
|
|
|
int lastface = CCS_getNumFaces(ss) - 1;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
memset(mf, 0, sizeof(*mf));
|
2009-09-15 15:32:09 +00:00
|
|
|
if (faceNum >= cgdm->dm.numFaceData)
|
|
|
|
|
return;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
i = cgdm->reverseFaceMap[faceNum];
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
f = cgdm->faceMap[i].face;
|
|
|
|
|
numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
offset = faceNum - cgdm->faceMap[i].startFace;
|
2006-08-28 01:12:36 +00:00
|
|
|
grid = offset / gridFaces;
|
|
|
|
|
offset %= gridFaces;
|
|
|
|
|
y = offset / gridSideEdges;
|
|
|
|
|
x = offset % gridSideEdges;
|
|
|
|
|
|
|
|
|
|
mf->v1 = getFaceIndex(ss, f, grid, x+0, y+0, edgeSize, gridSize);
|
|
|
|
|
mf->v2 = getFaceIndex(ss, f, grid, x+0, y+1, edgeSize, gridSize);
|
|
|
|
|
mf->v3 = getFaceIndex(ss, f, grid, x+1, y+1, edgeSize, gridSize);
|
|
|
|
|
mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize);
|
|
|
|
|
|
2009-08-30 21:30:07 +00:00
|
|
|
if(faceFlags) {
|
|
|
|
|
mf->flag = faceFlags[i*4];
|
|
|
|
|
mf->mat_nr = faceFlags[i*4+1];
|
|
|
|
|
} else
|
|
|
|
|
mf->flag = ME_SMOOTH;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
2006-08-28 01:12:36 +00:00
|
|
|
int index;
|
|
|
|
|
int totvert, totedge, totface;
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int i = 0;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[index].face;
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert[i++].co, CCS_getFaceCenterData(f));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
for(x = 1; x < gridSize - 1; x++) {
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_v3_v3(mvert[i++].co,
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getFaceGridEdgeData(ss, f, S, x));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
for(y = 1; y < gridSize - 1; y++) {
|
|
|
|
|
for(x = 1; x < gridSize - 1; x++) {
|
2009-11-10 20:43:45 +00:00
|
|
|
copy_v3_v3(mvert[i++].co,
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getFaceGridData(ss, f, S, x, y));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totedge = CCS_getNumEdges(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totedge; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = cgdm->edgeMap[index].edge;
|
2006-08-28 01:12:36 +00:00
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for(x = 1; x < edgeSize - 1; x++) {
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert[i++].co, CCS_getEdgeData(ss, e, x));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totvert = CCS_getNumVerts(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totvert; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = cgdm->vertMap[index].vert;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(mvert[i].co, CCS_getVertData(ss, v));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
2006-08-28 01:12:36 +00:00
|
|
|
int index;
|
|
|
|
|
int totedge, totface;
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int i = 0;
|
2006-12-07 18:30:00 +00:00
|
|
|
int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[index].face;
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
for(x = 0; x < gridSize - 1; x++) {
|
|
|
|
|
MEdge *med = &medge[i];
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if(cgdm->drawInteriorEdges)
|
2006-08-28 01:12:36 +00:00
|
|
|
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, S, x, 0, edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, S, x + 1, 0, edgeSize, gridSize);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(x = 1; x < gridSize - 1; x++) {
|
|
|
|
|
for(y = 0; y < gridSize - 1; y++) {
|
|
|
|
|
MEdge *med;
|
|
|
|
|
|
|
|
|
|
med = &medge[i];
|
2009-08-15 17:31:28 +00:00
|
|
|
if(cgdm->drawInteriorEdges)
|
2006-08-28 01:12:36 +00:00
|
|
|
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, S, x, y,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, S, x, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
i++;
|
|
|
|
|
|
|
|
|
|
med = &medge[i];
|
2009-08-15 17:31:28 +00:00
|
|
|
if(cgdm->drawInteriorEdges)
|
2006-08-28 01:12:36 +00:00
|
|
|
med->flag = ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
med->v1 = getFaceIndex(ss, f, S, y, x,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
med->v2 = getFaceIndex(ss, f, S, y + 1, x,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totedge = CCS_getNumEdges(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totedge; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = cgdm->edgeMap[index].edge;
|
2006-08-28 01:12:36 +00:00
|
|
|
unsigned int flags = 0;
|
|
|
|
|
int x;
|
2009-08-15 17:31:28 +00:00
|
|
|
int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(edgeFlags) {
|
2006-12-07 18:30:00 +00:00
|
|
|
if(edgeIdx != -1) {
|
|
|
|
|
flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP))
|
|
|
|
|
| ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
}
|
2006-08-28 01:12:36 +00:00
|
|
|
} else {
|
|
|
|
|
flags |= ME_EDGEDRAW | ME_EDGERENDER;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(x = 0; x < edgeSize - 1; x++) {
|
|
|
|
|
MEdge *med = &medge[i];
|
|
|
|
|
med->v1 = getEdgeIndex(ss, e, x, edgeSize);
|
|
|
|
|
med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize);
|
|
|
|
|
med->flag = flags;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
struct cgdm_faceIter;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
typedef struct cgdm_loopIter {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
DMLoopIter head;
|
|
|
|
|
int curloop;
|
2009-08-22 04:45:19 +00:00
|
|
|
int lindex; //loop index within the mesh, not the face
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm;
|
|
|
|
|
struct cgdm_faceIter *fiter;
|
|
|
|
|
} cgdm_loopIter;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
typedef struct cgdm_faceIter {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
DMFaceIter head;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm;
|
2009-09-15 15:32:09 +00:00
|
|
|
MFace *mface, *mf;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_loopIter liter;
|
2009-08-18 20:05:08 +00:00
|
|
|
EdgeHash *ehash; /*edge map for populating loopiter->eindex*/
|
2009-08-15 17:31:28 +00:00
|
|
|
} cgdm_faceIter;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
void cgdm_faceIterStep(void *self)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_faceIter *fiter = self;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if (!fiter->cgdm || !fiter->cgdm->ss) {
|
2009-06-12 14:02:37 +00:00
|
|
|
fiter->head.done = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-26 05:59:12 +00:00
|
|
|
fiter->head.index++;
|
|
|
|
|
|
|
|
|
|
if (fiter->head.index >= CCS_getNumFinalFaces(fiter->cgdm->ss)) {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
fiter->head.done = 1;
|
|
|
|
|
return;
|
|
|
|
|
};
|
|
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
fiter->mf++;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
fiter->head.flags = fiter->mface->flag;
|
|
|
|
|
fiter->head.mat_nr = fiter->mface->mat_nr;
|
2009-08-22 04:45:19 +00:00
|
|
|
fiter->head.len = 4;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
void *cgdm_faceIterCData(void *self, int type, int layer)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_faceIter *fiter = self;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
if (layer == -1)
|
2009-08-22 04:45:19 +00:00
|
|
|
return CustomData_get(&fiter->cgdm->dm.polyData, fiter->head.index, type);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
else
|
2009-08-22 04:45:19 +00:00
|
|
|
return CustomData_get_n(&fiter->cgdm->dm.polyData, type, fiter->head.index, layer);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
void cgdm_loopIterStep(void *self)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_loopIter *liter = self;
|
2009-11-16 08:26:47 +00:00
|
|
|
MFace *mf = liter->fiter->mface;
|
2009-08-18 20:05:08 +00:00
|
|
|
int i, v1, v2;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
2009-08-22 04:45:19 +00:00
|
|
|
liter->head.index++;
|
|
|
|
|
i = liter->head.index;
|
|
|
|
|
|
|
|
|
|
if (liter->head.index >= 4) {
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
liter->head.done = 1;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (i) {
|
|
|
|
|
case 0:
|
2009-09-15 15:32:09 +00:00
|
|
|
v1 = liter->fiter->mf->v1;
|
|
|
|
|
v2 = liter->fiter->mf->v2;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
break;
|
|
|
|
|
case 1:
|
2009-09-15 15:32:09 +00:00
|
|
|
v1 = liter->fiter->mf->v2;
|
|
|
|
|
v2 = liter->fiter->mf->v3;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
break;
|
|
|
|
|
case 2:
|
2009-09-15 15:32:09 +00:00
|
|
|
v1 = liter->fiter->mf->v3;
|
|
|
|
|
v2 = liter->fiter->mf->v4;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
break;
|
|
|
|
|
case 3:
|
2009-09-15 15:32:09 +00:00
|
|
|
v1 = liter->fiter->mf->v4;
|
|
|
|
|
v2 = liter->fiter->mf->v1;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
liter->head.vindex = v1;
|
2009-09-15 15:32:09 +00:00
|
|
|
liter->head.eindex = GET_INT_FROM_POINTER(BLI_edgehash_lookup(liter->fiter->cgdm->ehash, v1, v2));
|
2009-08-22 04:45:19 +00:00
|
|
|
liter->lindex += 1;
|
2009-08-18 20:05:08 +00:00
|
|
|
|
|
|
|
|
cgdm_getFinalVert((DerivedMesh*)liter->cgdm, v1, &liter->head.v);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
void *cgdm_loopIterGetVCData(void *self, int type, int layer)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_loopIter *liter = self;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
if (layer == -1)
|
2009-08-15 17:31:28 +00:00
|
|
|
return CustomData_get(&liter->cgdm->dm.vertData, liter->head.vindex, type);
|
|
|
|
|
else return CustomData_get_n(&liter->cgdm->dm.vertData, type, liter->head.vindex, layer);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
void *cgdm_loopIterGetCData(void *self, int type, int layer)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_loopIter *liter = self;
|
2009-08-22 04:45:19 +00:00
|
|
|
|
|
|
|
|
if (layer == -1)
|
|
|
|
|
return CustomData_get(&liter->cgdm->dm.loopData, liter->lindex, type);
|
|
|
|
|
else return CustomData_get_n(&liter->cgdm->dm.loopData, type, liter->lindex, layer);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DMLoopIter *cgdm_faceIterGetLIter(void *self)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_faceIter *fiter = self;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
fiter->liter.head.index = -1;
|
|
|
|
|
fiter->liter.head.done = 0;
|
|
|
|
|
fiter->liter.head.step(&fiter->liter);
|
|
|
|
|
|
|
|
|
|
return (DMLoopIter*) &fiter->liter;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
void cgdm_faceIterFree(void *vfiter)
|
|
|
|
|
{
|
|
|
|
|
cgdm_faceIter *fiter = vfiter;
|
2009-09-15 15:32:09 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(fiter->mface);
|
2009-08-18 20:05:08 +00:00
|
|
|
MEM_freeN(fiter);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm)
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_faceIter *fiter = MEM_callocN(sizeof(cgdm_faceIter), "cgdm_faceIter");
|
2009-08-18 20:05:08 +00:00
|
|
|
MEdge medge;
|
|
|
|
|
int i, totedge = cgdm_getNumEdges(dm);
|
|
|
|
|
|
2009-08-22 04:45:19 +00:00
|
|
|
fiter->cgdm = dm;
|
|
|
|
|
fiter->liter.cgdm = dm;
|
2009-09-15 15:32:09 +00:00
|
|
|
fiter->mface = fiter->mf = dm->dupTessFaceArray(dm);
|
|
|
|
|
fiter->mf--;
|
2009-08-18 20:05:08 +00:00
|
|
|
|
|
|
|
|
fiter->head.free = cgdm_faceIterFree;
|
2009-08-15 17:31:28 +00:00
|
|
|
fiter->head.step = cgdm_faceIterStep;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
fiter->head.index = -1;
|
2009-08-15 17:31:28 +00:00
|
|
|
fiter->head.getCDData = cgdm_faceIterCData;
|
|
|
|
|
fiter->head.getLoopsIter = cgdm_faceIterGetLIter;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
fiter->liter.fiter = fiter;
|
2009-08-15 17:31:28 +00:00
|
|
|
fiter->liter.head.getLoopCDData = cgdm_loopIterGetCData;
|
|
|
|
|
fiter->liter.head.getVertCDData = cgdm_loopIterGetVCData;
|
|
|
|
|
fiter->liter.head.step = cgdm_loopIterStep;
|
2009-08-22 04:45:19 +00:00
|
|
|
fiter->liter.lindex = -1;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
|
|
|
|
|
fiter->head.step(fiter);
|
2009-08-30 21:30:07 +00:00
|
|
|
|
|
|
|
|
return fiter;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
2006-08-28 01:12:36 +00:00
|
|
|
int index;
|
|
|
|
|
int totface;
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int i = 0;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[index].face;
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
int mat_nr = 0;
|
|
|
|
|
int flag = ME_SMOOTH; /* assume face is smooth by default */
|
|
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
for(y = 0; y < gridSize - 1; y++) {
|
|
|
|
|
for(x = 0; x < gridSize - 1; x++) {
|
|
|
|
|
MFace *mf = &mface[i];
|
|
|
|
|
mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1,
|
|
|
|
|
edgeSize, gridSize);
|
|
|
|
|
mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0,
|
|
|
|
|
edgeSize, gridSize);
|
2009-11-16 08:26:47 +00:00
|
|
|
if (faceFlags) {
|
|
|
|
|
mat_nr = faceFlags[index*4+1];
|
|
|
|
|
mf->flag = faceFlags[index*4];
|
|
|
|
|
} else mf->flag = flag;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-11-16 08:26:47 +00:00
|
|
|
mf->mat_nr = mat_nr;
|
2006-08-28 01:12:36 +00:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
int i;
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVertIterator *vi;
|
|
|
|
|
CCEdgeIterator *ei;
|
|
|
|
|
CCFaceIterator *fi;
|
|
|
|
|
CCFace **faceMap2;
|
|
|
|
|
CCEdge **edgeMap2;
|
|
|
|
|
CCVert **vertMap2;
|
2005-08-23 02:05:45 +00:00
|
|
|
int index, totvert, totedge, totface;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totvert = CCS_getNumVerts(ss);
|
2005-08-23 02:05:45 +00:00
|
|
|
vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap");
|
2009-08-15 17:31:28 +00:00
|
|
|
vi = CCS_getVertIterator(ss);
|
|
|
|
|
for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
2005-08-23 02:05:45 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertMap2[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))] = v;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totedge = CCS_getNumEdges(ss);
|
2005-08-23 02:05:45 +00:00
|
|
|
edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap");
|
2009-08-15 17:31:28 +00:00
|
|
|
ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
for (i=0; !CCEIter_isStopped(ei); i++,CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
edgeMap2[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))] = e;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2005-08-23 02:05:45 +00:00
|
|
|
faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap");
|
2009-08-15 17:31:28 +00:00
|
|
|
fi = CCS_getFaceIterator(ss);
|
|
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
2005-08-23 02:05:45 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
faceMap2[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))] = f;
|
2005-08-23 02:05:45 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2005-08-23 02:05:45 +00:00
|
|
|
|
|
|
|
|
i = 0;
|
|
|
|
|
for (index=0; index<totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = faceMap2[index];
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(cos[i++], CCS_getFaceCenterData(f));
|
2005-08-23 02:05:45 +00:00
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
|
|
|
|
for (x=1; x<gridSize-1; x++) {
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(cos[i++], CCS_getFaceGridEdgeData(ss, f, S, x));
|
2005-08-23 02:05:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
|
|
|
|
for (y=1; y<gridSize-1; y++) {
|
|
|
|
|
for (x=1; x<gridSize-1; x++) {
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(cos[i++], CCS_getFaceGridData(ss, f, S, x, y));
|
2005-08-23 02:05:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2005-08-23 02:05:45 +00:00
|
|
|
|
|
|
|
|
for (index=0; index<totedge; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e= edgeMap2[index];
|
2005-08-23 02:05:45 +00:00
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x=1; x<edgeSize-1; x++) {
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(cos[i++], CCS_getEdgeData(ss, e, x));
|
2005-08-23 02:05:45 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (index=0; index<totvert; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = vertMap2[index];
|
2009-11-23 14:41:22 +00:00
|
|
|
copy_v3_v3(cos[i++], CCS_getVertData(ss, v));
|
2005-08-23 02:05:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(vertMap2);
|
|
|
|
|
MEM_freeN(edgeMap2);
|
|
|
|
|
MEM_freeN(faceMap2);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CCVertIterator *vi = CCS_getVertIterator(cgdm->ss);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
|
|
|
|
VertData *vd = CCS_getVertData(cgdm->ss, v);
|
|
|
|
|
int index = cgdm_getVertMapIndex(cgdm->ss, v);
|
2005-08-07 05:42:03 +00:00
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (index!=-1)
|
|
|
|
|
func(userData, index, vd->co, vd->no, NULL);
|
Big commit, had to rework lots of selection stuff so that things
worked properly with modifiers. Needs more testing I am sure.
No, honestly, I wasn't just cleaning for the hell of it, it
was *necessary* (I would never do such a thing). Selection should
work completely with cage options of modifiers now.
- added DerivedMesh foreach functions to iterate over mapped
verts/edges/face centers. These replaced some of the drawing
functions and are more general anyway. Special edge drawing
functions remain for performance reasons.
- removed EditFace xs, ys fields
- added general functions to iterate over screen coordinates of
mesh/curve/lattice objects
- removed all calc_*verts* functions that were used for storing
screen coordinates in objects. they were recalc'd on the fly
for most situations anyway, so now we just always do that.
calc_*verts_ext was one of those calls that did dirty things
deep down in the callstack (changing curarea and poking at
matrices)
- rewrote all vertex level selection routines (circle, lasso, bbox)
and closest vertex routines (rightmouse select) to use the new
system. This cleaned up the selection code a lot and the structure
of selection is much easier to see now. This is good for future
work on allowing modifiers to completely override the selection
system. It also points out some discrepancies in the way selection
is handled that might be nice to resolve (mesh vertex selection has
fancy stuff to try to help with selecting overlapping, but it only
works w/o bbuf select, and curves/lattices don't have at all).
- had to remove ton's code to move Manipulator to cage location, this
is not reliable (can come up with a different method if requested)
- as it happens BezTriple.s and BPoint.s are basically available to
be removed, just need to rewrite editipo code that still does
background calc of screen coordinates
- MVert.{xs,ys} are still around because they are abused in some places
for other info (not sure if this is safe actually, since they are
short's and the mvert limit went up).
And did I mention this commit is comes out to -305 lines? Well it does.
2005-08-09 08:12:36 +00:00
|
|
|
}
|
2005-08-07 05:42:03 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
Big commit, had to rework lots of selection stuff so that things
worked properly with modifiers. Needs more testing I am sure.
No, honestly, I wasn't just cleaning for the hell of it, it
was *necessary* (I would never do such a thing). Selection should
work completely with cage options of modifiers now.
- added DerivedMesh foreach functions to iterate over mapped
verts/edges/face centers. These replaced some of the drawing
functions and are more general anyway. Special edge drawing
functions remain for performance reasons.
- removed EditFace xs, ys fields
- added general functions to iterate over screen coordinates of
mesh/curve/lattice objects
- removed all calc_*verts* functions that were used for storing
screen coordinates in objects. they were recalc'd on the fly
for most situations anyway, so now we just always do that.
calc_*verts_ext was one of those calls that did dirty things
deep down in the callstack (changing curarea and poking at
matrices)
- rewrote all vertex level selection routines (circle, lasso, bbox)
and closest vertex routines (rightmouse select) to use the new
system. This cleaned up the selection code a lot and the structure
of selection is much easier to see now. This is good for future
work on allowing modifiers to completely override the selection
system. It also points out some discrepancies in the way selection
is handled that might be nice to resolve (mesh vertex selection has
fancy stuff to try to help with selecting overlapping, but it only
works w/o bbuf select, and curves/lattices don't have at all).
- had to remove ton's code to move Manipulator to cage location, this
is not reliable (can come up with a different method if requested)
- as it happens BezTriple.s and BPoint.s are basically available to
be removed, just need to rewrite editipo code that still does
background calc of screen coordinates
- MVert.{xs,ys} are still around because they are abused in some places
for other info (not sure if this is safe actually, since they are
short's and the mvert limit went up).
And did I mention this commit is comes out to -305 lines? Well it does.
2005-08-09 08:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
int i, edgeSize = CCS_getEdgeSize(ss);
|
2005-08-07 05:42:03 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
|
|
|
|
int index = cgdm_getEdgeMapIndex(ss, e);
|
2005-08-07 05:42:03 +00:00
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (index!=-1) {
|
|
|
|
|
for (i=0; i<edgeSize-1; i++)
|
|
|
|
|
func(userData, index, edgeData[i].co, edgeData[i+1].co);
|
|
|
|
|
}
|
2005-08-07 05:42:03 +00:00
|
|
|
}
|
Big commit, had to rework lots of selection stuff so that things
worked properly with modifiers. Needs more testing I am sure.
No, honestly, I wasn't just cleaning for the hell of it, it
was *necessary* (I would never do such a thing). Selection should
work completely with cage options of modifiers now.
- added DerivedMesh foreach functions to iterate over mapped
verts/edges/face centers. These replaced some of the drawing
functions and are more general anyway. Special edge drawing
functions remain for performance reasons.
- removed EditFace xs, ys fields
- added general functions to iterate over screen coordinates of
mesh/curve/lattice objects
- removed all calc_*verts* functions that were used for storing
screen coordinates in objects. they were recalc'd on the fly
for most situations anyway, so now we just always do that.
calc_*verts_ext was one of those calls that did dirty things
deep down in the callstack (changing curarea and poking at
matrices)
- rewrote all vertex level selection routines (circle, lasso, bbox)
and closest vertex routines (rightmouse select) to use the new
system. This cleaned up the selection code a lot and the structure
of selection is much easier to see now. This is good for future
work on allowing modifiers to completely override the selection
system. It also points out some discrepancies in the way selection
is handled that might be nice to resolve (mesh vertex selection has
fancy stuff to try to help with selecting overlapping, but it only
works w/o bbuf select, and curves/lattices don't have at all).
- had to remove ton's code to move Manipulator to cage location, this
is not reliable (can come up with a different method if requested)
- as it happens BezTriple.s and BPoint.s are basically available to
be removed, just need to rewrite editipo code that still does
background calc of screen coordinates
- MVert.{xs,ys} are still around because they are abused in some places
for other info (not sure if this is safe actually, since they are
short's and the mvert limit went up).
And did I mention this commit is comes out to -305 lines? Well it does.
2005-08-09 08:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEIter_free(ei);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawVerts(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
CCVertIterator *vi;
|
|
|
|
|
CCEdgeIterator *ei;
|
|
|
|
|
CCFaceIterator *fi;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_POINTS);
|
2009-08-15 17:31:28 +00:00
|
|
|
vi = CCS_getVertIterator(ss);
|
|
|
|
|
for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
|
|
|
|
glVertex3fv(CCS_getVertData(ss, v));
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
int x;
|
|
|
|
|
|
|
|
|
|
for (x=1; x<edgeSize-1; x++)
|
2009-08-15 17:31:28 +00:00
|
|
|
glVertex3fv(CCS_getEdgeData(ss, e, x));
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEIter_free(ei);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
fi = CCS_getFaceIterator(ss);
|
|
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int x, y, S, numVerts = CCS_getFaceNumVerts(f);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
glVertex3fv(CCS_getFaceCenterData(f));
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
for (S=0; S<numVerts; S++)
|
|
|
|
|
for (x=1; x<gridSize-1; x++)
|
2009-08-15 17:31:28 +00:00
|
|
|
glVertex3fv(CCS_getFaceGridEdgeData(ss, f, S, x));
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
for (S=0; S<numVerts; S++)
|
|
|
|
|
for (y=1; y<gridSize-1; y++)
|
|
|
|
|
for (x=1; x<gridSize-1; x++)
|
2009-08-15 17:31:28 +00:00
|
|
|
glVertex3fv(CCS_getFaceGridData(ss, f, S, x, y));
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
glEnd();
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
|
|
|
|
int i, edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
int useAging;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if (!drawLooseEdges && !CCS_getEdgeNumFaces(e))
|
2005-08-14 10:35:58 +00:00
|
|
|
continue;
|
2005-04-02 18:37:18 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (useAging && !(G.f&G_BACKBUFSEL)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
int ageCol = 255-CCS_getEdgeAge(ss, e)*4;
|
2005-03-31 16:54:47 +00:00
|
|
|
glColor3ub(0, ageCol>0?ageCol:0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-30 08:12:27 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
for (i=0; i<edgeSize-1; i++) {
|
2005-04-03 21:52:10 +00:00
|
|
|
glVertex3fv(edgeData[i].co);
|
|
|
|
|
glVertex3fv(edgeData[i+1].co);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (useAging && !(G.f&G_BACKBUFSEL)) {
|
2005-03-31 16:54:47 +00:00
|
|
|
glColor3ub(0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if (cgdm->drawInteriorEdges) {
|
|
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2005-08-12 21:55:50 +00:00
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
for (x=0; x<gridSize; x++)
|
2005-08-12 21:55:50 +00:00
|
|
|
glVertex3fv(faceGridData[x].co);
|
2005-03-30 08:12:27 +00:00
|
|
|
glEnd();
|
2005-08-12 21:55:50 +00:00
|
|
|
for (y=1; y<gridSize-1; y++) {
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
for (x=0; x<gridSize; x++)
|
|
|
|
|
glVertex3fv(faceGridData[y*gridSize + x].co);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
for (x=1; x<gridSize-1; x++) {
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
for (y=0; y<gridSize; y++)
|
|
|
|
|
glVertex3fv(faceGridData[y*gridSize + x].co);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
|
|
|
|
CCEIter_free(ei);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawLooseEdges(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
int i, edgeSize = CCS_getEdgeSize(ss);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
if (!CCS_getEdgeNumFaces(e)) {
|
2005-03-30 08:12:27 +00:00
|
|
|
glBegin(GL_LINE_STRIP);
|
|
|
|
|
for (i=0; i<edgeSize-1; i++) {
|
2005-04-03 21:52:10 +00:00
|
|
|
glVertex3fv(edgeData[i].co);
|
|
|
|
|
glVertex3fv(edgeData[i+1].co);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEIter_free(ei);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_glNormalFast(float *a, float *b, float *c, float *d)
|
2007-08-28 08:53:36 +00:00
|
|
|
{
|
|
|
|
|
float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
|
|
|
|
|
float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
|
|
|
|
|
float no[3];
|
|
|
|
|
|
|
|
|
|
no[0] = b_dY*a_cZ - b_dZ*a_cY;
|
|
|
|
|
no[1] = b_dZ*a_cX - b_dX*a_cZ;
|
|
|
|
|
no[2] = b_dX*a_cY - b_dY*a_cX;
|
|
|
|
|
|
|
|
|
|
/* don't normalize, GL_NORMALIZE is be enabled */
|
|
|
|
|
glNormal3fv(no);
|
|
|
|
|
}
|
|
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
/* Only used by non-editmesh types */
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
|
|
|
|
char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS);
|
|
|
|
|
|
|
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
|
|
|
|
int index = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
2007-08-28 08:53:36 +00:00
|
|
|
int drawSmooth, mat_nr;
|
|
|
|
|
|
|
|
|
|
if(faceFlags) {
|
|
|
|
|
drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
|
|
|
|
|
mat_nr= faceFlags[index*4 + 1];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
drawSmooth = 1;
|
|
|
|
|
mat_nr= 0;
|
|
|
|
|
}
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
if (!setMaterial(mat_nr+1, NULL))
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
continue;
|
2005-07-14 15:30:30 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
|
2005-03-30 08:12:27 +00:00
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if (drawSmooth) {
|
2005-04-03 21:52:10 +00:00
|
|
|
for (y=0; y<gridSize-1; y++) {
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
for (x=0; x<gridSize; x++) {
|
|
|
|
|
VertData *a = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
VertData *b = &faceGridData[(y+1)*gridSize + x];
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2005-04-03 21:52:10 +00:00
|
|
|
glNormal3fv(a->no);
|
|
|
|
|
glVertex3fv(a->co);
|
|
|
|
|
glNormal3fv(b->no);
|
|
|
|
|
glVertex3fv(b->co);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2005-04-03 21:52:10 +00:00
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
for (y=0; y<gridSize-1; y++) {
|
|
|
|
|
for (x=0; x<gridSize-1; x++) {
|
|
|
|
|
float *a = faceGridData[(y+0)*gridSize + x].co;
|
|
|
|
|
float *b = faceGridData[(y+0)*gridSize + x + 1].co;
|
|
|
|
|
float *c = faceGridData[(y+1)*gridSize + x + 1].co;
|
|
|
|
|
float *d = faceGridData[(y+1)*gridSize + x].co;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_glNormalFast(a, b, c, d);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2005-04-03 21:52:10 +00:00
|
|
|
glVertex3fv(d);
|
|
|
|
|
glVertex3fv(c);
|
|
|
|
|
glVertex3fv(b);
|
|
|
|
|
glVertex3fv(a);
|
|
|
|
|
}
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
|
|
|
|
|
/* Only used by non-editmesh types */
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
GPUVertexAttribs gattribs;
|
|
|
|
|
DMVertexAttribs attribs;
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE);
|
2009-08-15 17:31:28 +00:00
|
|
|
int gridSize = CCS_getGridSize(ss);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
int gridFaces = gridSize - 1;
|
2009-08-15 17:31:28 +00:00
|
|
|
int edgeSize = CCS_getEdgeSize(ss);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
int transp, orig_transp, new_transp;
|
2009-08-15 17:31:28 +00:00
|
|
|
char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
int a, b, i, doDraw, numVerts, matnr, new_matnr, totface;
|
|
|
|
|
|
|
|
|
|
doDraw = 0;
|
|
|
|
|
numVerts = 0;
|
|
|
|
|
matnr = -1;
|
|
|
|
|
transp = GPU_get_material_blend_mode();
|
|
|
|
|
orig_transp = transp;
|
|
|
|
|
|
|
|
|
|
memset(&attribs, 0, sizeof(attribs));
|
|
|
|
|
|
|
|
|
|
#define PASSATTRIB(dx, dy, vert) { \
|
|
|
|
|
if(attribs.totorco) { \
|
|
|
|
|
index = getFaceIndex(ss, f, S, x+dx, y+dy, edgeSize, gridSize); \
|
|
|
|
|
glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]); \
|
|
|
|
|
} \
|
|
|
|
|
for(b = 0; b < attribs.tottface; b++) { \
|
|
|
|
|
MTFace *tf = &attribs.tface[b].array[a]; \
|
|
|
|
|
glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]); \
|
|
|
|
|
} \
|
|
|
|
|
for(b = 0; b < attribs.totmcol; b++) { \
|
|
|
|
|
MCol *cp = &attribs.mcol[b].array[a*4 + vert]; \
|
|
|
|
|
GLubyte col[4]; \
|
|
|
|
|
col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
|
|
|
|
|
glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
|
|
|
|
|
} \
|
|
|
|
|
if(attribs.tottang) { \
|
|
|
|
|
float *tang = attribs.tang.array[a*4 + vert]; \
|
|
|
|
|
glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \
|
|
|
|
|
} \
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
for(a = 0, i = 0; i < totface; i++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[i].face;
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
int S, x, y, drawSmooth;
|
2009-08-15 17:31:28 +00:00
|
|
|
int index = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
|
|
|
|
int origIndex = cgdm_getFaceMapIndex(ss, f);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
numVerts = CCS_getFaceNumVerts(f);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
|
|
|
|
|
if(faceFlags) {
|
|
|
|
|
drawSmooth = (faceFlags[index*4] & ME_SMOOTH);
|
|
|
|
|
new_matnr= faceFlags[index*4 + 1] + 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
drawSmooth = 1;
|
|
|
|
|
new_matnr= 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(new_matnr != matnr) {
|
|
|
|
|
doDraw = setMaterial(matnr = new_matnr, &gattribs);
|
|
|
|
|
if(doDraw)
|
|
|
|
|
DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!doDraw || (setDrawOptions && !setDrawOptions(userData, origIndex))) {
|
|
|
|
|
a += gridFaces*gridFaces*numVerts;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(tf) {
|
|
|
|
|
new_transp = tf[i].transp;
|
|
|
|
|
|
|
|
|
|
if(new_transp != transp) {
|
|
|
|
|
if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
|
|
|
|
|
GPU_set_material_blend_mode(orig_transp);
|
|
|
|
|
else
|
|
|
|
|
GPU_set_material_blend_mode(new_transp);
|
|
|
|
|
transp = new_transp;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT);
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
VertData *vda, *vdb;
|
|
|
|
|
|
|
|
|
|
if (drawSmooth) {
|
|
|
|
|
for (y=0; y<gridFaces; y++) {
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
for (x=0; x<gridFaces; x++) {
|
|
|
|
|
vda = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
vdb = &faceGridData[(y+1)*gridSize + x];
|
|
|
|
|
|
|
|
|
|
PASSATTRIB(0, 0, 0);
|
|
|
|
|
glNormal3fv(vda->no);
|
|
|
|
|
glVertex3fv(vda->co);
|
|
|
|
|
|
|
|
|
|
PASSATTRIB(0, 1, 1);
|
|
|
|
|
glNormal3fv(vdb->no);
|
|
|
|
|
glVertex3fv(vdb->co);
|
|
|
|
|
|
|
|
|
|
if(x != gridFaces-1)
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
vda = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
vdb = &faceGridData[(y+1)*gridSize + x];
|
|
|
|
|
|
|
|
|
|
PASSATTRIB(0, 0, 3);
|
|
|
|
|
glNormal3fv(vda->no);
|
|
|
|
|
glVertex3fv(vda->co);
|
|
|
|
|
|
|
|
|
|
PASSATTRIB(0, 1, 2);
|
|
|
|
|
glNormal3fv(vdb->no);
|
|
|
|
|
glVertex3fv(vdb->co);
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
for (y=0; y<gridFaces; y++) {
|
|
|
|
|
for (x=0; x<gridFaces; x++) {
|
|
|
|
|
float *aco = faceGridData[(y+0)*gridSize + x].co;
|
|
|
|
|
float *bco = faceGridData[(y+0)*gridSize + x + 1].co;
|
|
|
|
|
float *cco = faceGridData[(y+1)*gridSize + x + 1].co;
|
|
|
|
|
float *dco = faceGridData[(y+1)*gridSize + x].co;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_glNormalFast(aco, bco, cco, dco);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
|
|
|
|
|
PASSATTRIB(0, 1, 1);
|
|
|
|
|
glVertex3fv(dco);
|
|
|
|
|
PASSATTRIB(1, 1, 2);
|
|
|
|
|
glVertex3fv(cco);
|
|
|
|
|
PASSATTRIB(1, 0, 3);
|
|
|
|
|
glVertex3fv(bco);
|
|
|
|
|
PASSATTRIB(0, 0, 0);
|
|
|
|
|
glVertex3fv(aco);
|
|
|
|
|
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#undef PASSATTRIB
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) {
|
Merge of first part of changes from the apricot branch, especially
the features that are needed to run the game. Compile tested with
scons, make, but not cmake, that seems to have an issue not related
to these changes. The changes include:
* GLSL support in the viewport and game engine, enable in the game
menu in textured draw mode.
* Synced and merged part of the duplicated blender and gameengine/
gameplayer drawing code.
* Further refactoring of game engine drawing code, especially mesh
storage changed a lot.
* Optimizations in game engine armatures to avoid recomputations.
* A python function to get the framerate estimate in game.
* An option take object color into account in materials.
* An option to restrict shadow casters to a lamp's layers.
* Increase from 10 to 18 texture slots for materials, lamps, word.
An extra texture slot shows up once the last slot is used.
* Memory limit for undo, not enabled by default yet because it
needs the .B.blend to be changed.
* Multiple undo for image painting.
* An offset for dupligroups, so not all objects in a group have to
be at the origin.
2008-09-04 20:51:28 +00:00
|
|
|
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
|
|
|
|
int gridSize = CCS_getGridSize(ss);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
unsigned char *cp1, *cp2;
|
|
|
|
|
int useTwoSide=1;
|
|
|
|
|
|
|
|
|
|
cp1= col1;
|
|
|
|
|
if(col2) {
|
|
|
|
|
cp2= col2;
|
|
|
|
|
} else {
|
|
|
|
|
cp2= NULL;
|
|
|
|
|
useTwoSide= 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
if(col1 && col2)
|
|
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
|
|
|
|
|
|
|
glBegin(GL_QUADS);
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
for (y=0; y<gridSize-1; y++) {
|
|
|
|
|
for (x=0; x<gridSize-1; x++) {
|
|
|
|
|
float *a = faceGridData[(y+0)*gridSize + x].co;
|
|
|
|
|
float *b = faceGridData[(y+0)*gridSize + x + 1].co;
|
|
|
|
|
float *c = faceGridData[(y+1)*gridSize + x + 1].co;
|
|
|
|
|
float *d = faceGridData[(y+1)*gridSize + x].co;
|
|
|
|
|
|
|
|
|
|
glColor3ub(cp1[3], cp1[2], cp1[1]);
|
|
|
|
|
glVertex3fv(d);
|
|
|
|
|
glColor3ub(cp1[7], cp1[6], cp1[5]);
|
|
|
|
|
glVertex3fv(c);
|
|
|
|
|
glColor3ub(cp1[11], cp1[10], cp1[9]);
|
|
|
|
|
glVertex3fv(b);
|
|
|
|
|
glColor3ub(cp1[15], cp1[14], cp1[13]);
|
|
|
|
|
glVertex3fv(a);
|
|
|
|
|
|
|
|
|
|
if (useTwoSide) {
|
|
|
|
|
glColor3ub(cp2[15], cp2[14], cp2[13]);
|
|
|
|
|
glVertex3fv(a);
|
|
|
|
|
glColor3ub(cp2[11], cp2[10], cp2[9]);
|
|
|
|
|
glVertex3fv(b);
|
|
|
|
|
glColor3ub(cp2[7], cp2[6], cp2[5]);
|
|
|
|
|
glVertex3fv(c);
|
|
|
|
|
glColor3ub(cp2[3], cp2[2], cp2[1]);
|
|
|
|
|
glVertex3fv(d);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cp2) cp2+=16;
|
|
|
|
|
cp1+=16;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2006-03-11 16:13:10 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawFacesTex_common(DerivedMesh *dm,
|
2009-08-18 20:05:08 +00:00
|
|
|
int (*drawParams)(MTFace *tface, int has_vcol, int matnr),
|
2007-08-28 08:53:36 +00:00
|
|
|
int (*drawParamsMapped)(void *userData, int index),
|
|
|
|
|
void *userData)
|
2006-03-11 16:13:10 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
MCol *mcol = DM_get_tessface_data_layer(dm, CD_MCOL);
|
|
|
|
|
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
|
|
|
|
char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS);
|
|
|
|
|
int i, totface, flag, gridSize = CCS_getGridSize(ss);
|
2007-08-28 08:53:36 +00:00
|
|
|
int gridFaces = gridSize - 1;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
2007-08-28 08:53:36 +00:00
|
|
|
for(i = 0; i < totface; i++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[i].face;
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
|
|
|
|
int drawSmooth, index = cgdm_getFaceMapIndex(ss, f);
|
|
|
|
|
int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
2007-08-28 09:30:46 +00:00
|
|
|
unsigned char *cp= NULL;
|
2007-08-28 08:53:36 +00:00
|
|
|
int mat_nr;
|
|
|
|
|
|
|
|
|
|
if(faceFlags) {
|
|
|
|
|
drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
|
|
|
|
|
mat_nr= faceFlags[origIndex*4 + 1];
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
drawSmooth = 1;
|
|
|
|
|
mat_nr= 0;
|
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(drawParams)
|
2009-08-18 20:05:08 +00:00
|
|
|
flag = drawParams(tf, mcol!=NULL, mat_nr);
|
2007-08-28 08:53:36 +00:00
|
|
|
else
|
|
|
|
|
flag= (drawParamsMapped)? drawParamsMapped(userData, index): 1;
|
|
|
|
|
|
|
|
|
|
if (flag == 0) { /* flag 0 == the face is hidden or invisible */
|
|
|
|
|
if(tf) tf += gridFaces*gridFaces*numVerts;
|
|
|
|
|
if(mcol) mcol += gridFaces*gridFaces*numVerts*4;
|
2005-08-18 11:31:20 +00:00
|
|
|
continue;
|
2007-08-28 08:53:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* flag 1 == use vertex colors */
|
2007-08-28 09:30:46 +00:00
|
|
|
if(mcol) {
|
|
|
|
|
if(flag==1) cp= (unsigned char*)mcol;
|
|
|
|
|
mcol += gridFaces*gridFaces*numVerts*4;
|
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
2007-08-28 08:53:36 +00:00
|
|
|
VertData *a, *b;
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if (drawSmooth) {
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
for (y=0; y<gridFaces; y++) {
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
for (x=0; x<gridFaces; x++) {
|
|
|
|
|
a = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
b = &faceGridData[(y+1)*gridSize + x];
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(tf) glTexCoord2fv(tf->uv[0]);
|
|
|
|
|
if(cp) glColor3ub(cp[3], cp[2], cp[1]);
|
|
|
|
|
glNormal3fv(a->no);
|
|
|
|
|
glVertex3fv(a->co);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(tf) glTexCoord2fv(tf->uv[1]);
|
|
|
|
|
if(cp) glColor3ub(cp[7], cp[6], cp[5]);
|
|
|
|
|
glNormal3fv(b->no);
|
|
|
|
|
glVertex3fv(b->co);
|
|
|
|
|
|
|
|
|
|
if(x != gridFaces-1) {
|
|
|
|
|
if(tf) tf++;
|
|
|
|
|
if(cp) cp += 16;
|
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
|
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
a = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
b = &faceGridData[(y+1)*gridSize + x];
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(tf) glTexCoord2fv(tf->uv[3]);
|
|
|
|
|
if(cp) glColor3ub(cp[15], cp[14], cp[13]);
|
|
|
|
|
glNormal3fv(a->no);
|
|
|
|
|
glVertex3fv(a->co);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(tf) glTexCoord2fv(tf->uv[2]);
|
|
|
|
|
if(cp) glColor3ub(cp[11], cp[10], cp[9]);
|
|
|
|
|
glNormal3fv(b->no);
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
glVertex3fv(b->co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) tf++;
|
|
|
|
|
if(cp) cp += 16;
|
|
|
|
|
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
for (y=0; y<gridFaces; y++) {
|
|
|
|
|
for (x=0; x<gridFaces; x++) {
|
2008-09-29 17:08:11 +00:00
|
|
|
float *a_co = faceGridData[(y+0)*gridSize + x].co;
|
|
|
|
|
float *b_co = faceGridData[(y+0)*gridSize + x + 1].co;
|
|
|
|
|
float *c_co = faceGridData[(y+1)*gridSize + x + 1].co;
|
|
|
|
|
float *d_co = faceGridData[(y+1)*gridSize + x].co;
|
2007-08-28 08:53:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_glNormalFast(a_co, b_co, c_co, d_co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) glTexCoord2fv(tf->uv[1]);
|
|
|
|
|
if(cp) glColor3ub(cp[7], cp[6], cp[5]);
|
2008-09-29 17:08:11 +00:00
|
|
|
glVertex3fv(d_co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) glTexCoord2fv(tf->uv[2]);
|
|
|
|
|
if(cp) glColor3ub(cp[11], cp[10], cp[9]);
|
2008-09-29 17:08:11 +00:00
|
|
|
glVertex3fv(c_co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) glTexCoord2fv(tf->uv[3]);
|
|
|
|
|
if(cp) glColor3ub(cp[15], cp[14], cp[13]);
|
2008-09-29 17:08:11 +00:00
|
|
|
glVertex3fv(b_co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) glTexCoord2fv(tf->uv[0]);
|
|
|
|
|
if(cp) glColor3ub(cp[3], cp[2], cp[1]);
|
2008-09-29 17:08:11 +00:00
|
|
|
glVertex3fv(a_co);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
if(tf) tf++;
|
|
|
|
|
if(cp) cp += 16;
|
|
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
2007-08-28 08:53:36 +00:00
|
|
|
glEnd();
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2007-08-28 08:53:36 +00:00
|
|
|
}
|
- added data arguments to deformer modifiers, in case someone wants
to write one that is based on geometry (and not just vertex position)
- added editmode versions of modifier deform/apply calls and flag
to tag modifiers that support editmode
- added isFinalCalc param to applyModifier, basically a switch to let
subsurf know if it is calc'ng orco or not (so it can deal with cache
appropriately). This is kinda hacky and perhaps I can come up with
a better solution (its also a waste to do a complete subdivide just
to get vertex locations).
- changed ccgsubsurf to not preallocate hash's to be approximately correct
size... this was probably not a big performance savings but means that
the order of faces returned by the iterator can vary after the first
call, this messes up orco calculation so dropped for time being.
- minor bug fix, meshes with only key didn't get vertex normals correctly
calc'd
- updated editmesh derivedmesh to support auxiliary locations
- changed mesh_calc_modifiers to alloc deformVerts on demand
- added editmesh_calc_modifiers for calculating editmesh cage and final
derivedmesh's
- bug fix, update shadedisplist to always calc colors (even if totvert==0)
- changed load_editMesh and make_edge to build me->medge even if totedge==0
(incremental subsurf checks this)
todo: add drawFacesTex for ccgderivedmesh
So, modifiers in editmode are back (which means auto-mirror
in edit mode works now) although still not finished. Currently
no cage is computed, the cage is always the base mesh (in
other words, Optimal edge style editing is off), and the final
mesh currently includes all modifiers that work in edit mode
(including lattice and curve). At some point there will be toggles
for which modifiers affect the final/cage editmode derivedmesh's.
Also, very nice new feature is that incremental subsurf in object
mode returns a ccgderivedmesh object instead of copying to a new
displistmesh. This can make a *huge* speed difference, and is very
nice for working with deformed armatures (esp. with only small
per frame changes).
2005-07-22 07:37:15 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
static void cgdm_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_vcol, int matnr))
|
2007-08-28 08:53:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
|
2007-08-28 08:53:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
|
2007-08-28 08:53:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2007-08-28 08:53:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawUVEdges(DerivedMesh *dm)
|
2007-09-22 15:32:08 +00:00
|
|
|
{
|
|
|
|
|
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
MFace *mf = dm->getTessFaceArray(dm);
|
2009-08-15 17:31:28 +00:00
|
|
|
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
|
2007-09-22 15:32:08 +00:00
|
|
|
int i;
|
|
|
|
|
|
2007-09-22 17:54:13 +00:00
|
|
|
if (tf) {
|
|
|
|
|
glBegin(GL_LINES);
|
|
|
|
|
for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
|
|
|
|
|
if(!(mf->flag&ME_HIDE)) {
|
2007-09-22 15:32:08 +00:00
|
|
|
glVertex2fv(tf->uv[0]);
|
2007-09-22 17:54:13 +00:00
|
|
|
glVertex2fv(tf->uv[1]);
|
|
|
|
|
|
|
|
|
|
glVertex2fv(tf->uv[1]);
|
2007-09-22 15:32:08 +00:00
|
|
|
glVertex2fv(tf->uv[2]);
|
2007-09-22 17:54:13 +00:00
|
|
|
|
|
|
|
|
if(!mf->v4) {
|
|
|
|
|
glVertex2fv(tf->uv[2]);
|
|
|
|
|
glVertex2fv(tf->uv[0]);
|
|
|
|
|
} else {
|
|
|
|
|
glVertex2fv(tf->uv[2]);
|
|
|
|
|
glVertex2fv(tf->uv[3]);
|
|
|
|
|
|
|
|
|
|
glVertex2fv(tf->uv[3]);
|
|
|
|
|
glVertex2fv(tf->uv[0]);
|
|
|
|
|
}
|
2007-09-22 15:32:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-09-22 17:54:13 +00:00
|
|
|
glEnd();
|
2007-09-22 15:32:08 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
|
|
|
|
int i, gridSize = CCS_getGridSize(ss);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS);
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (i=0; !CCFIter_isStopped(fi); i++,CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int S, x, y, numVerts = CCS_getFaceNumVerts(f);
|
|
|
|
|
int drawSmooth, index = cgdm_getFaceMapIndex(ss, f);
|
2006-08-28 01:12:36 +00:00
|
|
|
int origIndex;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH);
|
2006-08-28 01:12:36 +00:00
|
|
|
else drawSmooth = 1;
|
2007-09-25 03:31:12 +00:00
|
|
|
|
|
|
|
|
if (index!=-1) {
|
|
|
|
|
int draw;
|
|
|
|
|
draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth);
|
|
|
|
|
|
|
|
|
|
if (draw) {
|
|
|
|
|
if (draw==2) {
|
|
|
|
|
glEnable(GL_POLYGON_STIPPLE);
|
2009-01-07 14:46:50 +00:00
|
|
|
glPolygonStipple(stipple_quarttone);
|
2007-09-25 03:31:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (S=0; S<numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S);
|
2007-09-25 03:31:12 +00:00
|
|
|
if (drawSmooth) {
|
|
|
|
|
glShadeModel(GL_SMOOTH);
|
|
|
|
|
for (y=0; y<gridSize-1; y++) {
|
|
|
|
|
glBegin(GL_QUAD_STRIP);
|
|
|
|
|
for (x=0; x<gridSize; x++) {
|
|
|
|
|
VertData *a = &faceGridData[(y+0)*gridSize + x];
|
|
|
|
|
VertData *b = &faceGridData[(y+1)*gridSize + x];
|
|
|
|
|
|
|
|
|
|
glNormal3fv(a->no);
|
|
|
|
|
glVertex3fv(a->co);
|
|
|
|
|
glNormal3fv(b->no);
|
|
|
|
|
glVertex3fv(b->co);
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
}
|
2007-09-25 03:31:12 +00:00
|
|
|
} else {
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
for (y=0; y<gridSize-1; y++) {
|
|
|
|
|
for (x=0; x<gridSize-1; x++) {
|
|
|
|
|
float *a = faceGridData[(y+0)*gridSize + x].co;
|
|
|
|
|
float *b = faceGridData[(y+0)*gridSize + x + 1].co;
|
|
|
|
|
float *c = faceGridData[(y+1)*gridSize + x + 1].co;
|
|
|
|
|
float *d = faceGridData[(y+1)*gridSize + x].co;
|
|
|
|
|
float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2];
|
|
|
|
|
float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2];
|
|
|
|
|
float no[3];
|
|
|
|
|
|
|
|
|
|
no[0] = b_dY*a_cZ - b_dZ*a_cY;
|
|
|
|
|
no[1] = b_dZ*a_cX - b_dX*a_cZ;
|
|
|
|
|
no[2] = b_dX*a_cY - b_dY*a_cX;
|
|
|
|
|
glNormal3fv(no);
|
|
|
|
|
|
|
|
|
|
glVertex3fv(d);
|
|
|
|
|
glVertex3fv(c);
|
|
|
|
|
glVertex3fv(b);
|
|
|
|
|
glVertex3fv(a);
|
|
|
|
|
}
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
}
|
2007-09-25 03:31:12 +00:00
|
|
|
glEnd();
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2007-09-25 03:31:12 +00:00
|
|
|
if (draw==2)
|
|
|
|
|
glDisable(GL_POLYGON_STIPPLE);
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
int i, useAging, edgeSize = CCS_getEdgeSize(ss);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
|
|
|
|
int index = cgdm_getEdgeMapIndex(ss, e);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (useAging && !(G.f&G_BACKBUFSEL)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
int ageCol = 255-CCS_getEdgeAge(ss, e)*4;
|
2005-03-31 15:44:05 +00:00
|
|
|
glColor3ub(0, ageCol>0?ageCol:0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-30 08:12:27 +00:00
|
|
|
for (i=0; i<edgeSize-1; i++) {
|
2005-04-03 21:52:10 +00:00
|
|
|
glVertex3fv(edgeData[i].co);
|
|
|
|
|
glVertex3fv(edgeData[i+1].co);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEIter_free(ei);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCEdgeIterator *ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
int i, useAging, edgeSize = CCS_getEdgeSize(ss);
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
|
|
|
|
VertData *edgeData = CCS_getEdgeDataArray(ss, e);
|
|
|
|
|
int index = cgdm_getEdgeMapIndex(ss, e);
|
2005-03-30 08:12:27 +00:00
|
|
|
|
|
|
|
|
glBegin(GL_LINE_STRIP);
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) {
|
2005-03-30 08:12:27 +00:00
|
|
|
for (i=0; i<edgeSize; i++) {
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
setDrawInterpOptions(userData, index, (float) i/(edgeSize-1));
|
2005-03-31 15:44:05 +00:00
|
|
|
|
- shuffled editmesh derived function name/function
- added ModifierTypeInfo.freeData function
- added modifier_{new,free] utility function
- added ccgSubSurf_getUseAgeCounts to query info
- removed subsurf modifier faking (ME_SUBSURF flag is no
longer valid). subsurf modifier gets converted on file load
although there is obscure linked mesh situation where this
can go wrong, will fix shortly. this also means that some
places in the code that test/copy subsurf settings are broken
for the time being.
- shuffled modifier calculation to be simpler. note that
all modifiers are currently disabled in editmode (including
subsurf). don't worry, will return shortly.
- bug fix, build modifier didn't randomize meshes with only verts
- cleaned up subsurf_ccg and adapted for future editmode modifier
work
- added editmesh.derived{Cage,Final}, not used yet
- added SubsurfModifierData.{mCache,emCache}, will be used to cache
subsurf instead of caching in derivedmesh itself
- removed old subsurf buttons
- added do_modifiers_buttons to handle modifier events
- removed count_object counting of modifier (subsurfed) objects...
this would be nice to add back at some point but requires care.
probably requires rewrite of counting system.
New feature: Incremental Subsurf in Object Mode
The previous release introduce incremental subsurf calculation during
editmode but it was not turned on during object mode. In general it
does not make sense to have it always enabled during object mode because
it requires caching a fair amount of information about the mesh which
is a waste of memory unless the mesh is often recalculated.
However, for mesh's that have subsurfed armatures for example, or that
have other modifiers so that the mesh is essentially changing on every
frame, it makes a lot of sense to keep the subsurf'd object around and
that is what the new incremental subsurf modifier toggle is for. The
intent is that the user will enable this option for (a) a mesh that is
currently under active editing or (b) a mesh that is heavily updated
in the scene, such as a character.
I will try to write more about this feature for release, because it
has advantages and disadvantages that are not immediately obvious (the
first user reaction will be to turn it on for ever object, which is
probably not correct).
2005-07-21 20:30:33 +00:00
|
|
|
if (useAging && !(G.f&G_BACKBUFSEL)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
int ageCol = 255-CCS_getEdgeAge(ss, e)*4;
|
2005-03-31 15:44:05 +00:00
|
|
|
glColor3ub(0, ageCol>0?ageCol:0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-03 21:52:10 +00:00
|
|
|
glVertex3fv(edgeData[i].co);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEIter_free(ei);
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
|
|
|
|
CSubSurf *ss = cgdm->ss;
|
|
|
|
|
CCFaceIterator *fi = CCS_getFaceIterator(ss);
|
2005-08-03 04:04:05 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
|
|
|
|
int index = cgdm_getFaceMapIndex(ss, f);
|
Big commit, had to rework lots of selection stuff so that things
worked properly with modifiers. Needs more testing I am sure.
No, honestly, I wasn't just cleaning for the hell of it, it
was *necessary* (I would never do such a thing). Selection should
work completely with cage options of modifiers now.
- added DerivedMesh foreach functions to iterate over mapped
verts/edges/face centers. These replaced some of the drawing
functions and are more general anyway. Special edge drawing
functions remain for performance reasons.
- removed EditFace xs, ys fields
- added general functions to iterate over screen coordinates of
mesh/curve/lattice objects
- removed all calc_*verts* functions that were used for storing
screen coordinates in objects. they were recalc'd on the fly
for most situations anyway, so now we just always do that.
calc_*verts_ext was one of those calls that did dirty things
deep down in the callstack (changing curarea and poking at
matrices)
- rewrote all vertex level selection routines (circle, lasso, bbox)
and closest vertex routines (rightmouse select) to use the new
system. This cleaned up the selection code a lot and the structure
of selection is much easier to see now. This is good for future
work on allowing modifiers to completely override the selection
system. It also points out some discrepancies in the way selection
is handled that might be nice to resolve (mesh vertex selection has
fancy stuff to try to help with selecting overlapping, but it only
works w/o bbuf select, and curves/lattices don't have at all).
- had to remove ton's code to move Manipulator to cage location, this
is not reliable (can come up with a different method if requested)
- as it happens BezTriple.s and BPoint.s are basically available to
be removed, just need to rewrite editipo code that still does
background calc of screen coordinates
- MVert.{xs,ys} are still around because they are abused in some places
for other info (not sure if this is safe actually, since they are
short's and the mvert limit went up).
And did I mention this commit is comes out to -305 lines? Well it does.
2005-08-09 08:12:36 +00:00
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
if (index!=-1) {
|
2005-08-03 04:04:05 +00:00
|
|
|
/* Face center data normal isn't updated atm. */
|
2009-08-15 17:31:28 +00:00
|
|
|
VertData *vd = CCS_getFaceGridData(ss, f, 0, 0, 0);
|
2005-08-03 04:04:05 +00:00
|
|
|
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
func(userData, index, vd->co, vd->no);
|
2005-08-08 18:50:47 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2005-08-08 18:50:47 +00:00
|
|
|
}
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
static void cgdm_release(DerivedMesh *dm) {
|
|
|
|
|
CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm;
|
2005-03-30 08:12:27 +00:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
if (DM_release(dm)) {
|
2009-08-15 17:31:28 +00:00
|
|
|
MEM_freeN(cgdm->vertMap);
|
|
|
|
|
MEM_freeN(cgdm->edgeMap);
|
|
|
|
|
MEM_freeN(cgdm->faceMap);
|
2009-09-15 15:32:09 +00:00
|
|
|
MEM_freeN(cgdm->reverseFaceMap);
|
|
|
|
|
BLI_edgehash_free(cgdm->ehash, NULL);
|
2009-08-15 17:31:28 +00:00
|
|
|
MEM_freeN(cgdm);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
}
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-16 19:55:05 +00:00
|
|
|
|
|
|
|
|
void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata,
|
|
|
|
|
CustomData *pdata, int loopstart, int findex,
|
|
|
|
|
int polyindex, int numTex, int numCol)
|
|
|
|
|
{
|
|
|
|
|
MTFace *texface;
|
|
|
|
|
MTexPoly *texpoly;
|
|
|
|
|
MCol *mcol;
|
|
|
|
|
MLoopCol *mloopcol;
|
|
|
|
|
MLoopUV *mloopuv;
|
2009-08-31 15:57:13 +00:00
|
|
|
int i, j, hasWCol = CustomData_has_layer(ldata, CD_WEIGHT_MLOOPCOL);
|
2009-08-16 19:55:05 +00:00
|
|
|
|
|
|
|
|
for(i=0; i < numTex; i++){
|
|
|
|
|
texface = CustomData_get_n(fdata, CD_MTFACE, findex, i);
|
|
|
|
|
texpoly = CustomData_get_n(pdata, CD_MTEXPOLY, polyindex, i);
|
|
|
|
|
|
|
|
|
|
texface->tpage = texpoly->tpage;
|
|
|
|
|
texface->flag = texpoly->flag;
|
|
|
|
|
texface->transp = texpoly->transp;
|
|
|
|
|
texface->mode = texpoly->mode;
|
|
|
|
|
texface->tile = texpoly->tile;
|
|
|
|
|
texface->unwrap = texpoly->unwrap;
|
|
|
|
|
|
|
|
|
|
mloopuv = CustomData_get_n(ldata, CD_MLOOPUV, loopstart, i);
|
|
|
|
|
for (j=0; j<4; j++, mloopuv++) {
|
|
|
|
|
texface->uv[j][0] = mloopuv->uv[0];
|
|
|
|
|
texface->uv[j][1] = mloopuv->uv[1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i=0; i < numCol; i++){
|
|
|
|
|
mloopcol = CustomData_get_n(ldata, CD_MLOOPCOL, loopstart, i);
|
|
|
|
|
mcol = CustomData_get_n(fdata, CD_MCOL, findex, i);
|
|
|
|
|
|
|
|
|
|
for (j=0; j<4; j++, mloopcol++) {
|
|
|
|
|
mcol[j].r = mloopcol->r;
|
|
|
|
|
mcol[j].g = mloopcol->g;
|
|
|
|
|
mcol[j].b = mloopcol->b;
|
|
|
|
|
mcol[j].a = mloopcol->a;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-31 15:57:13 +00:00
|
|
|
|
|
|
|
|
if (hasWCol) {
|
|
|
|
|
mloopcol = CustomData_get(ldata, loopstart, CD_WEIGHT_MLOOPCOL);
|
|
|
|
|
mcol = CustomData_get(fdata, findex, CD_WEIGHT_MCOL);
|
|
|
|
|
|
|
|
|
|
for (j=0; j<4; j++, mloopcol++) {
|
|
|
|
|
mcol[j].r = mloopcol->r;
|
|
|
|
|
mcol[j].g = mloopcol->g;
|
|
|
|
|
mcol[j].b = mloopcol->b;
|
|
|
|
|
mcol[j].a = mloopcol->a;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-16 19:55:05 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-30 21:30:07 +00:00
|
|
|
/*this function requires dm to be a CDDM*/
|
2009-08-15 17:31:28 +00:00
|
|
|
static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss,
|
2006-08-28 01:12:36 +00:00
|
|
|
int drawInteriorEdges,
|
2007-08-28 08:53:36 +00:00
|
|
|
int useSubsurfUv,
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
DerivedMesh *dm)
|
2006-08-28 01:12:36 +00:00
|
|
|
{
|
2009-08-15 17:31:28 +00:00
|
|
|
CCGDerivedMesh *cgdm = MEM_callocN(sizeof(*cgdm), "cgdm");
|
|
|
|
|
CCVertIterator *vi;
|
|
|
|
|
CCEdgeIterator *ei;
|
|
|
|
|
CCFaceIterator *fi;
|
2006-08-28 01:12:36 +00:00
|
|
|
int index, totvert, totedge, totface;
|
|
|
|
|
int i;
|
|
|
|
|
int vertNum, edgeNum, faceNum;
|
2009-08-15 17:31:28 +00:00
|
|
|
int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex; /* *edgeOrigIndex - as yet, unused */
|
2007-08-28 08:53:36 +00:00
|
|
|
int *edgeFlags;
|
2009-08-15 17:31:28 +00:00
|
|
|
char *faceFlags, *polyFlags;
|
2009-08-18 20:05:08 +00:00
|
|
|
int *loopidx = NULL, *vertidx = NULL;
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_declare(loopidx);
|
|
|
|
|
BLI_array_declare(vertidx);
|
2009-08-15 17:31:28 +00:00
|
|
|
int loopindex, loopindex2;
|
2006-08-28 01:12:36 +00:00
|
|
|
int edgeSize;
|
|
|
|
|
int gridSize;
|
2009-08-16 19:55:05 +00:00
|
|
|
int gridFaces, gridCuts;
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridSideVerts;
|
2008-09-29 17:08:11 +00:00
|
|
|
/*int gridInternalVerts; - as yet unused */
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridSideEdges;
|
2009-08-16 19:55:05 +00:00
|
|
|
int numTex, numCol;
|
2006-08-28 01:12:36 +00:00
|
|
|
int gridInternalEdges;
|
2009-08-22 04:45:19 +00:00
|
|
|
float *w = NULL, one = 1.0f;
|
2009-08-16 19:55:05 +00:00
|
|
|
WeightTable wtable = {0};
|
2008-09-29 17:08:11 +00:00
|
|
|
/* MVert *mvert = NULL; - as yet unused */
|
2009-08-16 19:55:05 +00:00
|
|
|
MCol *mcol;
|
2009-09-15 15:32:09 +00:00
|
|
|
MEdge *medge = NULL, medge2;
|
2006-08-28 01:12:36 +00:00
|
|
|
MFace *mface = NULL;
|
2009-08-30 21:30:07 +00:00
|
|
|
MPoly *mpoly = NULL;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_from_template(&cgdm->dm, dm, CCS_getNumFinalVerts(ss),
|
|
|
|
|
CCS_getNumFinalEdges(ss),
|
|
|
|
|
CCS_getNumFinalFaces(ss),
|
2009-09-15 15:32:09 +00:00
|
|
|
CCS_getNumFinalFaces(ss)*4,
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_getNumFinalFaces(ss));
|
|
|
|
|
DM_add_tessface_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
|
|
|
|
|
DM_add_face_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
|
|
|
|
|
DM_add_edge_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL);
|
2009-08-16 19:55:05 +00:00
|
|
|
|
|
|
|
|
numTex = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPUV);
|
|
|
|
|
numCol = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPCOL);
|
|
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
if (numTex && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MTFACE) != numTex)
|
2009-08-16 19:55:05 +00:00
|
|
|
CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, CCS_getNumFinalFaces(ss));
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
else if (numCol && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MCOL) != numCol)
|
2009-08-16 19:55:05 +00:00
|
|
|
CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, CCS_getNumFinalFaces(ss));
|
2009-08-15 17:31:28 +00:00
|
|
|
|
|
|
|
|
CustomData_set_layer_flag(&cgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY);
|
|
|
|
|
CustomData_set_layer_flag(&cgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY);
|
|
|
|
|
|
|
|
|
|
cgdm->dm.getMinMax = cgdm_getMinMax;
|
|
|
|
|
cgdm->dm.getNumVerts = cgdm_getNumVerts;
|
|
|
|
|
cgdm->dm.getNumTessFaces = cgdm_getNumTessFaces;
|
|
|
|
|
cgdm->dm.getNumFaces = cgdm_getNumTessFaces;
|
|
|
|
|
|
|
|
|
|
cgdm->dm.newFaceIter = cgdm_newFaceIter;
|
|
|
|
|
|
|
|
|
|
cgdm->dm.getNumEdges = cgdm_getNumEdges;
|
|
|
|
|
cgdm->dm.getVert = cgdm_getFinalVert;
|
|
|
|
|
cgdm->dm.getEdge = cgdm_getFinalEdge;
|
|
|
|
|
cgdm->dm.getTessFace = cgdm_getFinalFace;
|
|
|
|
|
cgdm->dm.copyVertArray = cgdm_copyFinalVertArray;
|
|
|
|
|
cgdm->dm.copyEdgeArray = cgdm_copyFinalEdgeArray;
|
|
|
|
|
cgdm->dm.copyTessFaceArray = cgdm_copyFinalFaceArray;
|
|
|
|
|
cgdm->dm.getVertData = DM_get_vert_data;
|
|
|
|
|
cgdm->dm.getEdgeData = DM_get_edge_data;
|
|
|
|
|
cgdm->dm.getTessFaceData = DM_get_face_data;
|
|
|
|
|
cgdm->dm.getVertDataArray = DM_get_vert_data_layer;
|
|
|
|
|
cgdm->dm.getEdgeDataArray = DM_get_edge_data_layer;
|
|
|
|
|
cgdm->dm.getTessFaceDataArray = DM_get_tessface_data_layer;
|
|
|
|
|
|
|
|
|
|
cgdm->dm.getVertCos = cgdm_getVertCos;
|
|
|
|
|
cgdm->dm.foreachMappedVert = cgdm_foreachMappedVert;
|
|
|
|
|
cgdm->dm.foreachMappedEdge = cgdm_foreachMappedEdge;
|
|
|
|
|
cgdm->dm.foreachMappedFaceCenter = cgdm_foreachMappedFaceCenter;
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->dm.drawVerts = cgdm_drawVerts;
|
|
|
|
|
cgdm->dm.drawEdges = cgdm_drawEdges;
|
|
|
|
|
cgdm->dm.drawLooseEdges = cgdm_drawLooseEdges;
|
|
|
|
|
cgdm->dm.drawFacesSolid = cgdm_drawFacesSolid;
|
|
|
|
|
cgdm->dm.drawFacesColored = cgdm_drawFacesColored;
|
|
|
|
|
cgdm->dm.drawFacesTex = cgdm_drawFacesTex;
|
|
|
|
|
cgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL;
|
|
|
|
|
cgdm->dm.drawMappedFaces = cgdm_drawMappedFaces;
|
|
|
|
|
cgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex;
|
|
|
|
|
cgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL;
|
|
|
|
|
cgdm->dm.drawUVEdges = cgdm_drawUVEdges;
|
|
|
|
|
|
|
|
|
|
cgdm->dm.drawMappedEdgesInterp = cgdm_drawMappedEdgesInterp;
|
|
|
|
|
cgdm->dm.drawMappedEdges = cgdm_drawMappedEdges;
|
- convert all DerivedMesh map functions to use index based
mapping (instead of Edit{Vert,Edge,Face} pointers)
- dropped convertToDispListMeshMapped (whew, glad of it too)
- added DerivedMesh drawMappedFaces function
- dropped EM suffix for DerivedMesh functions, it was neither
particularly correct nor descriptive
- converted test_index_mface to test_index_face that also corrects
MCol and TFace. Good thing we had three versions of this routine,
you never know when one might burn down.
- removed flipnorm_mesh, not used anymore (and was incorrect to
boot)
- Getting face select to work with modifiers turned out to be much
more complicated than expected. Reworked mapping architecture for
modifiers - basically elements in a DispListMesh are now required
to be stored in an order that corresponds exactly to original
ordering. MVert/MEdge/MFace all have a new flag ME_XXX_STEPINDEX
that is set on each element that is set on the first derived element
of each original element. I can't say the code to follow these
requirements for subsurf is particularly transparent, but on the
upside it is a reasonably consistent and simple system that is memory
efficient and allows keeping the DispListMesh structure.
- rewrote mirror modifier to be simpler/conform to new requirements
for mapped DispListMesh structure. This also means that mirror interacts
much better with incremental subsurf calculation (it used to recalc
one entire side on any topology change, now it generally avoids that).
- added EM_{init,free}_index_arrays and EM_get_{vert,edge,face}_for_index
functions to handle mapping indices back into appropriate EditMesh
structures.
- bug fix, make edges didn't recalc object data
- bug fix, initial image assignment to TFace's didn't recalc object data
- new feature, added circle select support for FACESELECT
- bug fix, creating new faces in editmode duplicated the TFACE active
flag - but there should only be one active tface
- bug fix, possible crash when deleting all faces in faceselect mode
on mesh with tfaces...
Still todo: TFace edge drawing is still not always correct in face
mode, in particular with a mirror modifier when mesh has edges (and
no preceeding subsurf). Have not yet decided how to deal with this.
Best solution is probably to do switch to meshes all having MEdge's,
in which case I can get rid of TFace edge flags (and need to recalc
modifiers on tface selection change).
2005-08-20 03:08:23 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->dm.release = cgdm_release;
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->ss = ss;
|
|
|
|
|
cgdm->drawInteriorEdges = drawInteriorEdges;
|
|
|
|
|
cgdm->useSubsurfUv = useSubsurfUv;
|
2005-03-30 08:12:27 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totvert = CCS_getNumVerts(ss);
|
|
|
|
|
cgdm->vertMap = MEM_mallocN(totvert * sizeof(*cgdm->vertMap), "vertMap");
|
|
|
|
|
vi = CCS_getVertIterator(ss);
|
|
|
|
|
for(; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->vertMap[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))].vert = v;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totedge = CCS_getNumEdges(ss);
|
|
|
|
|
cgdm->edgeMap = MEM_mallocN(totedge * sizeof(*cgdm->edgeMap), "edgeMap");
|
|
|
|
|
ei = CCS_getEdgeIterator(ss);
|
|
|
|
|
for(; !CCEIter_isStopped(ei); CCEIter_next(ei)) {
|
|
|
|
|
CCEdge *e = CCEIter_getCurrent(ei);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->edgeMap[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))].edge = e;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
totface = CCS_getNumFaces(ss);
|
|
|
|
|
cgdm->faceMap = MEM_mallocN(totface * sizeof(*cgdm->faceMap), "faceMap");
|
|
|
|
|
fi = CCS_getFaceIterator(ss);
|
|
|
|
|
for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) {
|
|
|
|
|
CCFace *f = CCFIter_getCurrent(fi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->faceMap[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))].face = f;
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFIter_free(fi);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
cgdm->reverseFaceMap = MEM_callocN(sizeof(int)*CCS_getNumFinalFaces(ss), "reverseFaceMap");
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
edgeSize = CCS_getEdgeSize(ss);
|
|
|
|
|
gridSize = CCS_getGridSize(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
gridFaces = gridSize - 1;
|
|
|
|
|
gridSideVerts = gridSize - 2;
|
2009-08-16 19:55:05 +00:00
|
|
|
gridCuts = gridSize - 2;
|
2008-09-29 17:08:11 +00:00
|
|
|
/*gridInternalVerts = gridSideVerts * gridSideVerts; - as yet, unused */
|
2006-08-28 01:12:36 +00:00
|
|
|
gridSideEdges = gridSize - 1;
|
|
|
|
|
gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2;
|
|
|
|
|
|
|
|
|
|
vertNum = 0;
|
|
|
|
|
edgeNum = 0;
|
|
|
|
|
faceNum = 0;
|
|
|
|
|
|
2008-09-29 17:08:11 +00:00
|
|
|
/* mvert = dm->getVertArray(dm); - as yet unused */
|
2007-08-28 08:53:36 +00:00
|
|
|
medge = dm->getEdgeArray(dm);
|
(NOTE: DO NOT TEST)
Start of planned DerivedMesh refactoring. The mface
interfaces in DerivedMesh have been renamed to reflect
their new status as tesselated face interfaces (rather
then the primary ones, which are now stored in mpolys).
short review: mpolys store "primary" face data, while
mfaces store the tesselated form of the mesh (generally
as triangles). mpolys are defined by mloops, and each
mpoly defines a range of loops it "owns" in the main
mloop array.
I've also added basic read-only face iterators, which
are implemented for CDDM, ccgsubsurf, and the bmeditmesh
derivedmesh. Since faces are now variable-length things,
trying to implement the same interface as mfaces would not
have worked well (especially since faces are stored as
an mpoly + a range of mloops).
I figure first we can evaluate these simple read-only
face iterators, then decide if a) we like using iterators
in DerivedMesh, b) how much of it should use them, and c)
if we want write-capable iterators.
I plan to write official docs on this design after I get
it more stable; I'm committing now because there's a rather
lot of changes, and I might do a merge soon.
2009-06-10 10:06:25 +00:00
|
|
|
mface = dm->getTessFaceArray(dm);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-30 21:30:07 +00:00
|
|
|
/*CDDM hack*/
|
|
|
|
|
mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertOrigIndex = DM_get_vert_data_layer(&cgdm->dm, CD_ORIGINDEX);
|
|
|
|
|
/*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/
|
|
|
|
|
faceOrigIndex = DM_get_tessface_data_layer(&cgdm->dm, CD_ORIGINDEX);
|
|
|
|
|
faceFlags = DM_get_tessface_data_layer(&cgdm->dm, CD_FLAGS);
|
|
|
|
|
|
|
|
|
|
polyOrigIndex = DM_get_face_data_layer(&cgdm->dm, CD_ORIGINDEX);
|
|
|
|
|
polyFlags = DM_get_face_data_layer(&cgdm->dm, CD_FLAGS);
|
|
|
|
|
|
2009-08-16 19:55:05 +00:00
|
|
|
if (!CustomData_has_layer(&cgdm->dm.faceData, CD_MCOL))
|
|
|
|
|
DM_add_tessface_layer(&cgdm->dm, CD_MCOL, CD_CALLOC, NULL);
|
|
|
|
|
|
|
|
|
|
mcol = DM_get_tessface_data_layer(&cgdm->dm, CD_MCOL);
|
|
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
faceNum = 0;
|
2009-08-15 17:31:28 +00:00
|
|
|
loopindex = loopindex2 = 0; //current loop index
|
2009-08-18 20:05:08 +00:00
|
|
|
for (index = 0; index < totface; index++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[index].face;
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
|
|
|
|
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
|
|
|
|
|
int mapIndex = cgdm_getFaceMapIndex(ss, f);
|
|
|
|
|
int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
2009-08-16 19:55:05 +00:00
|
|
|
int g2_wid = gridCuts+2;
|
2009-08-18 20:05:08 +00:00
|
|
|
float *w2;
|
2009-08-15 17:31:28 +00:00
|
|
|
int s, x, y;
|
|
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
w = get_ss_weights(&wtable, gridCuts, numVerts);
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->faceMap[index].startVert = vertNum;
|
|
|
|
|
cgdm->faceMap[index].startEdge = edgeNum;
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
cgdm->faceMap[index].startFace = faceNum;
|
2009-08-18 20:05:08 +00:00
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
/* set the face base vert */
|
|
|
|
|
*((int*)CCS_getFaceUserData(ss, f)) = vertNum;
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(loopidx);
|
2009-08-15 17:31:28 +00:00
|
|
|
for (s=0; s<numVerts; s++) {
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(loopidx);
|
2009-08-16 19:55:05 +00:00
|
|
|
loopidx[s] = loopindex++;
|
2009-08-15 17:31:28 +00:00
|
|
|
}
|
2009-08-18 20:05:08 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_empty(vertidx);
|
2009-08-18 20:05:08 +00:00
|
|
|
for(s = 0; s < numVerts; s++) {
|
|
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, s);
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(vertidx);
|
2009-08-18 20:05:08 +00:00
|
|
|
vertidx[s] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
/*I think this is for interpolating the center vert?*/
|
|
|
|
|
w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1);
|
2009-08-18 20:05:08 +00:00
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
|
|
|
|
|
numVerts, vertNum);
|
|
|
|
|
if (vertOrigIndex)
|
|
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
2009-08-16 19:55:05 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
/*interpolate per-vert data*/
|
|
|
|
|
for(s = 0; s < numVerts; s++) {
|
|
|
|
|
for(x = 1; x < gridFaces; x++) {
|
|
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + x*numVerts;
|
|
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
|
|
|
|
|
numVerts, vertNum);
|
|
|
|
|
|
|
|
|
|
if (vertOrigIndex)
|
|
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-16 19:55:05 +00:00
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
/*interpolate per-vert data*/
|
2009-08-18 20:05:08 +00:00
|
|
|
for(s = 0; s < numVerts; s++) {
|
|
|
|
|
for(y = 1; y < gridFaces; y++) {
|
|
|
|
|
for(x = 1; x < gridFaces; x++) {
|
|
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
|
|
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2,
|
|
|
|
|
numVerts, vertNum);
|
2009-08-16 19:55:05 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
if (vertOrigIndex)
|
|
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-16 19:55:05 +00:00
|
|
|
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
for(i = 0; i < numFinalEdges; ++i)
|
|
|
|
|
*(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
|
|
|
|
|
CD_ORIGINDEX) = ORIGINDEX_NONE;
|
2009-08-18 20:05:08 +00:00
|
|
|
for (s=0; s<numVerts; s++) {
|
|
|
|
|
/*interpolate per-face data*/
|
|
|
|
|
for (y=0; y<gridFaces; y++) {
|
|
|
|
|
for (x=0; x<gridFaces; x++) {
|
2009-08-16 19:55:05 +00:00
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + (y*g2_wid+x)*numVerts;
|
|
|
|
|
CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
|
|
|
|
|
loopidx, w2, NULL, numVerts, loopindex2);
|
|
|
|
|
loopindex2++;
|
|
|
|
|
|
|
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x))*numVerts;
|
|
|
|
|
CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
|
|
|
|
|
loopidx, w2, NULL, numVerts, loopindex2);
|
|
|
|
|
loopindex2++;
|
|
|
|
|
|
|
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + ((y+1)*g2_wid+(x+1))*numVerts;
|
|
|
|
|
CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
|
|
|
|
|
loopidx, w2, NULL, numVerts, loopindex2);
|
|
|
|
|
loopindex2++;
|
|
|
|
|
|
|
|
|
|
w2 = w + s*numVerts*g2_wid*g2_wid + ((y)*g2_wid+(x+1))*numVerts;
|
|
|
|
|
CustomData_interp(&dm->loopData, &cgdm->dm.loopData,
|
|
|
|
|
loopidx, w2, NULL, numVerts, loopindex2);
|
|
|
|
|
loopindex2++;
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
/*copy over poly data, e.g. mtexpoly*/
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
CustomData_copy_data(&dm->polyData, &cgdm->dm.polyData, origIndex, faceNum, 1);
|
2009-08-16 19:55:05 +00:00
|
|
|
|
2009-08-18 20:05:08 +00:00
|
|
|
/*generate tesselated face data used for drawing*/
|
2009-08-16 19:55:05 +00:00
|
|
|
ccg_loops_to_corners(&cgdm->dm.faceData, &cgdm->dm.loopData,
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
&cgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol);
|
2009-08-16 19:55:05 +00:00
|
|
|
|
2009-08-30 21:52:13 +00:00
|
|
|
/*set original index data*/
|
|
|
|
|
*faceOrigIndex = origIndex;
|
|
|
|
|
*polyOrigIndex = origIndex;
|
|
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
cgdm->reverseFaceMap[faceNum] = index;
|
|
|
|
|
|
2009-08-30 21:52:13 +00:00
|
|
|
faceOrigIndex++;
|
|
|
|
|
polyOrigIndex++;
|
2009-08-22 04:45:19 +00:00
|
|
|
faceNum++;
|
2009-08-15 17:31:28 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-08-18 20:05:08 +00:00
|
|
|
|
2009-08-30 21:30:07 +00:00
|
|
|
polyFlags[0] = mpoly[origIndex].flag;
|
|
|
|
|
polyFlags[1] = mpoly[origIndex].mat_nr;
|
|
|
|
|
faceFlags[0] = polyFlags[0];
|
|
|
|
|
faceFlags[1] = polyFlags[1];
|
|
|
|
|
|
|
|
|
|
faceFlags += 4;
|
|
|
|
|
polyFlags += 4;
|
2009-08-18 20:05:08 +00:00
|
|
|
edgeNum += numFinalEdges;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS);
|
|
|
|
|
for(index = 0; index < totedge; ++index) {
|
|
|
|
|
CCEdge *e = cgdm->edgeMap[index].edge;
|
|
|
|
|
int numFinalEdges = edgeSize - 1;
|
|
|
|
|
int mapIndex = cgdm_getEdgeMapIndex(ss, e);
|
|
|
|
|
int x;
|
|
|
|
|
int vertIdx[2];
|
|
|
|
|
int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e));
|
|
|
|
|
|
|
|
|
|
CCVert *v;
|
|
|
|
|
v = CCS_getEdgeVert0(e);
|
|
|
|
|
vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
v = CCS_getEdgeVert1(e);
|
|
|
|
|
vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
|
|
|
|
|
cgdm->edgeMap[index].startVert = vertNum;
|
|
|
|
|
cgdm->edgeMap[index].startEdge = edgeNum;
|
|
|
|
|
|
|
|
|
|
/* set the edge base vert */
|
|
|
|
|
*((int*)CCS_getEdgeUserData(ss, e)) = vertNum;
|
|
|
|
|
|
|
|
|
|
for(x = 1; x < edgeSize - 1; x++) {
|
|
|
|
|
float w[2];
|
|
|
|
|
w[1] = (float) x / (edgeSize - 1);
|
|
|
|
|
w[0] = 1 - w[1];
|
|
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum);
|
|
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(i = 0; i < numFinalEdges; ++i) {
|
|
|
|
|
if(edgeIdx >= 0 && edgeFlags)
|
|
|
|
|
edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
|
|
|
|
|
|
|
|
|
|
*(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
|
|
|
|
|
CD_ORIGINDEX) = mapIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
edgeNum += numFinalEdges;
|
2009-08-15 17:31:28 +00:00
|
|
|
}
|
2009-08-22 04:45:19 +00:00
|
|
|
|
|
|
|
|
for(index = 0; index < totvert; ++index) {
|
|
|
|
|
CCVert *v = cgdm->vertMap[index].vert;
|
|
|
|
|
int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v);
|
|
|
|
|
int vidx;
|
|
|
|
|
|
|
|
|
|
vidx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
|
|
|
|
|
cgdm->vertMap[index].startVert = vertNum;
|
|
|
|
|
|
|
|
|
|
/* set the vert base vert */
|
|
|
|
|
*((int*) CCS_getVertUserData(ss, v)) = vertNum;
|
|
|
|
|
|
|
|
|
|
DM_copy_vert_data(dm, &cgdm->dm, vidx, vertNum, 1);
|
|
|
|
|
|
|
|
|
|
*vertOrigIndex = mapIndex;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
|
|
|
|
|
cgdm->dm.numVertData = vertNum;
|
|
|
|
|
cgdm->dm.numEdgeData = edgeNum;
|
|
|
|
|
cgdm->dm.numFaceData = faceNum;
|
|
|
|
|
cgdm->dm.numLoopData = loopindex2;
|
|
|
|
|
cgdm->dm.numPolyData = faceNum;
|
2009-08-29 23:55:35 +00:00
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(vertidx);
|
|
|
|
|
BLI_array_free(loopidx);
|
2009-08-29 23:55:35 +00:00
|
|
|
free_ss_weights(&wtable);
|
|
|
|
|
|
2009-09-15 15:32:09 +00:00
|
|
|
cgdm->ehash = BLI_edgehash_new();
|
|
|
|
|
for (i=0; i<cgdm->dm.numEdgeData; i++) {
|
|
|
|
|
cgdm_getFinalEdge((DerivedMesh*)cgdm, i, &medge2);
|
|
|
|
|
BLI_edgehash_insert(cgdm->ehash, medge2.v1, medge2.v2, SET_INT_IN_POINTER(i));
|
|
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
#if 0
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totface; ++index) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = cgdm->faceMap[index].face;
|
|
|
|
|
int numVerts = CCS_getFaceNumVerts(f);
|
2006-08-28 01:12:36 +00:00
|
|
|
int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges);
|
2009-08-15 17:31:28 +00:00
|
|
|
int mapIndex = cgdm_getFaceMapIndex(ss, f);
|
|
|
|
|
int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f));
|
2006-08-28 01:12:36 +00:00
|
|
|
FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight;
|
|
|
|
|
int S, x, y;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->faceMap[index].startVert = vertNum;
|
|
|
|
|
cgdm->faceMap[index].startEdge = edgeNum;
|
|
|
|
|
cgdm->faceMap[index].startFace = faceNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
/* set the face base vert */
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*)CCS_getFaceUserData(ss, f)) = vertNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
for(S = 0; S < numVerts; S++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = CCS_getFaceVert(ss, f, S);
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_growone(vertIdx);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertIdx[S] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertIdx, weight[0][0],
|
2006-08-28 01:12:36 +00:00
|
|
|
numVerts, vertNum);
|
|
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
|
|
|
|
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
|
2009-06-12 14:02:37 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(x = 1; x < gridFaces; x++) {
|
|
|
|
|
float w[4];
|
2009-07-26 13:26:59 +00:00
|
|
|
#if 0 //BMESH_TODO
|
2006-08-28 01:12:36 +00:00
|
|
|
w[prevS] = weight[x][0][0];
|
|
|
|
|
w[S] = weight[x][0][1];
|
|
|
|
|
w[nextS] = weight[x][0][2];
|
|
|
|
|
w[otherS] = weight[x][0][3];
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w,
|
2006-08-28 01:12:36 +00:00
|
|
|
numVerts, vertNum);
|
2009-06-12 14:02:37 +00:00
|
|
|
#endif
|
2006-08-28 01:12:36 +00:00
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
|
|
|
|
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
|
|
|
|
|
for(y = 1; y < gridFaces; y++) {
|
|
|
|
|
for(x = 1; x < gridFaces; x++) {
|
|
|
|
|
float w[4];
|
2009-07-26 13:26:59 +00:00
|
|
|
#if 0 //BMESH_TODO
|
2006-08-28 01:12:36 +00:00
|
|
|
w[prevS] = weight[y * gridFaces + x][0][0];
|
|
|
|
|
w[S] = weight[y * gridFaces + x][0][1];
|
|
|
|
|
w[nextS] = weight[y * gridFaces + x][0][2];
|
|
|
|
|
w[otherS] = weight[y * gridFaces + x][0][3];
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w,
|
2006-08-28 01:12:36 +00:00
|
|
|
numVerts, vertNum);
|
2009-06-12 14:02:37 +00:00
|
|
|
#endif
|
2006-08-28 01:12:36 +00:00
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-06-12 14:02:37 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(i = 0; i < numFinalEdges; ++i)
|
2009-08-15 17:31:28 +00:00
|
|
|
*(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
CD_ORIGINDEX) = ORIGINDEX_NONE;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(S = 0; S < numVerts; S++) {
|
|
|
|
|
int prevS = (S - 1 + numVerts) % numVerts;
|
|
|
|
|
int nextS = (S + 1) % numVerts;
|
|
|
|
|
int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3;
|
|
|
|
|
|
|
|
|
|
weight = (numVerts == 4) ? qweight : tweight;
|
|
|
|
|
|
|
|
|
|
for(y = 0; y < gridFaces; y++) {
|
|
|
|
|
for(x = 0; x < gridFaces; x++) {
|
|
|
|
|
FaceVertWeight w;
|
|
|
|
|
int j;
|
|
|
|
|
|
2009-07-26 13:12:55 +00:00
|
|
|
#if 1 //BMESH_TODO
|
2006-08-28 01:12:36 +00:00
|
|
|
for(j = 0; j < 4; ++j) {
|
|
|
|
|
w[j][prevS] = (*weight)[j][0];
|
|
|
|
|
w[j][S] = (*weight)[j][1];
|
|
|
|
|
w[j][nextS] = (*weight)[j][2];
|
|
|
|
|
w[j][otherS] = (*weight)[j][3];
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_interp_tessface_data(dm, &cgdm->dm, &origIndex, NULL,
|
2006-08-28 01:12:36 +00:00
|
|
|
&w, 1, faceNum);
|
|
|
|
|
weight++;
|
2009-06-12 14:02:37 +00:00
|
|
|
#endif
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
*faceOrigIndex = mapIndex;
|
|
|
|
|
|
|
|
|
|
++faceOrigIndex;
|
|
|
|
|
++faceNum;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
faceFlags[index*4] = mface[origIndex].flag;
|
|
|
|
|
faceFlags[index*4 + 1] = mface[origIndex].mat_nr;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
edgeNum += numFinalEdges;
|
|
|
|
|
}
|
|
|
|
|
|
2006-12-12 21:29:09 +00:00
|
|
|
if(useSubsurfUv) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CustomData *fdata = &cgdm->dm.faceData;
|
2006-12-12 21:29:09 +00:00
|
|
|
CustomData *dmfdata = &dm->faceData;
|
|
|
|
|
int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE);
|
|
|
|
|
int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE);
|
|
|
|
|
|
|
|
|
|
for (i=0; i<numlayer && i<dmnumlayer; i++)
|
2009-08-15 17:31:28 +00:00
|
|
|
set_subsurf_uv(ss, dm, &cgdm->dm, i);
|
2006-08-28 01:12:36 +00:00
|
|
|
}
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS);
|
2006-12-07 18:30:00 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
for(index = 0; index < totedge; ++index) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = cgdm->edgeMap[index].edge;
|
2006-08-28 01:12:36 +00:00
|
|
|
int numFinalEdges = edgeSize - 1;
|
2009-08-15 17:31:28 +00:00
|
|
|
int mapIndex = cgdm_getEdgeMapIndex(ss, e);
|
2006-08-28 01:12:36 +00:00
|
|
|
int x;
|
|
|
|
|
int vertIdx[2];
|
2009-08-15 17:31:28 +00:00
|
|
|
int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v;
|
|
|
|
|
v = CCS_getEdgeVert0(e);
|
|
|
|
|
vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
v = CCS_getEdgeVert1(e);
|
|
|
|
|
vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->edgeMap[index].startVert = vertNum;
|
|
|
|
|
cgdm->edgeMap[index].startEdge = edgeNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
/* set the edge base vert */
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*)CCS_getEdgeUserData(ss, e)) = vertNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
for(x = 1; x < edgeSize - 1; x++) {
|
|
|
|
|
float w[2];
|
|
|
|
|
w[1] = (float) x / (edgeSize - 1);
|
|
|
|
|
w[0] = 1 - w[1];
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum);
|
2006-08-28 01:12:36 +00:00
|
|
|
*vertOrigIndex = ORIGINDEX_NONE;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
|
2006-12-07 18:30:00 +00:00
|
|
|
for(i = 0; i < numFinalEdges; ++i) {
|
|
|
|
|
if(edgeIdx >= 0 && edgeFlags)
|
|
|
|
|
edgeFlags[edgeNum + i] = medge[edgeIdx].flag;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
*(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i,
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
CD_ORIGINDEX) = mapIndex;
|
2006-12-07 18:30:00 +00:00
|
|
|
}
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
edgeNum += numFinalEdges;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(index = 0; index < totvert; ++index) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVert *v = cgdm->vertMap[index].vert;
|
|
|
|
|
int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v);
|
2006-08-28 01:12:36 +00:00
|
|
|
int vertIdx;
|
|
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vertIdx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
cgdm->vertMap[index].startVert = vertNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
/* set the vert base vert */
|
2009-08-15 17:31:28 +00:00
|
|
|
*((int*) CCS_getVertUserData(ss, v)) = vertNum;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
DM_copy_vert_data(dm, &cgdm->dm, vertIdx, vertNum, 1);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
*vertOrigIndex = mapIndex;
|
|
|
|
|
++vertOrigIndex;
|
|
|
|
|
++vertNum;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(qweight);
|
|
|
|
|
MEM_freeN(tweight);
|
|
|
|
|
|
2009-09-17 23:05:33 +00:00
|
|
|
BLI_array_free(vertIdx);
|
2009-08-15 17:31:28 +00:00
|
|
|
#endif
|
|
|
|
|
return cgdm;
|
2005-03-30 08:12:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/***/
|
|
|
|
|
|
2009-01-06 18:59:03 +00:00
|
|
|
struct DerivedMesh *subsurf_make_derived_from_derived_with_multires(
|
2006-08-28 01:12:36 +00:00
|
|
|
struct DerivedMesh *dm,
|
|
|
|
|
struct SubsurfModifierData *smd,
|
2009-01-06 18:59:03 +00:00
|
|
|
struct MultiresSubsurf *ms,
|
2006-08-28 01:12:36 +00:00
|
|
|
int useRenderParams, float (*vertCos)[3],
|
|
|
|
|
int isFinalCalc, int editMode)
|
|
|
|
|
{
|
|
|
|
|
int useSimple = smd->subdivType == ME_SIMPLE_SUBSURF;
|
|
|
|
|
int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
|
|
|
|
|
int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv;
|
|
|
|
|
int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges);
|
|
|
|
|
DerivedMesh *result;
|
|
|
|
|
|
|
|
|
|
if(editMode) {
|
|
|
|
|
smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0,
|
|
|
|
|
useSimple);
|
|
|
|
|
ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple);
|
|
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
return (DerivedMesh *)getCCGDerivedMesh(smd->emCache,
|
2006-08-28 01:12:36 +00:00
|
|
|
drawInteriorEdges,
|
2007-08-28 08:53:36 +00:00
|
|
|
useSubsurfUv, dm);
|
2006-08-28 01:12:36 +00:00
|
|
|
} else if(useRenderParams) {
|
|
|
|
|
/* Do not use cache in render mode. */
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *ss;
|
2008-02-13 11:18:08 +00:00
|
|
|
int levels;
|
|
|
|
|
|
2009-01-04 14:14:06 +00:00
|
|
|
levels= smd->renderLevels; // XXX get_render_subsurf_level(&scene->r, smd->renderLevels);
|
2008-02-13 11:18:08 +00:00
|
|
|
if(levels == 0)
|
|
|
|
|
return dm;
|
|
|
|
|
|
|
|
|
|
ss = _getSubSurf(NULL, levels, 0, 1, useSimple);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
|
|
|
|
|
|
|
|
|
result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
|
2009-01-06 18:59:03 +00:00
|
|
|
useSubsurfUv, dm, ms);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
} else {
|
subsurf works now! YES! take *that* subsurf_ccg.cscons/scons.py BF_QUICK=bf_python,bf_blenkernel,bf_blenlib,bf_blenloader,bf_editors_mesh,bf_bmesh,bf_editors_space_view3d,bf_editors_transform,bf_makesdna,bf_makesrna,bf_dna,bf_rn,bf_bmesh,bf_editors_object,editors_uvedit,editors_space_image,editors_screen,editors_space_screen,editors_space_api,bf_windowmanager,bf_wm still an issue with some modifier combinations though, and I think there's some memory corruption going on, need to valgrind it.
2009-08-25 10:21:10 +00:00
|
|
|
int useIncremental = 1; //(smd->flags & eSubsurfModifierFlag_Incremental);
|
2006-08-28 01:12:36 +00:00
|
|
|
int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr;
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *ss;
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
/* It is quite possible there is a much better place to do this. It
|
|
|
|
|
* depends a bit on how rigourously we expect this function to never
|
|
|
|
|
* be called in editmode. In semi-theory we could share a single
|
|
|
|
|
* cache, but the handles used inside and outside editmode are not
|
|
|
|
|
* the same so we would need some way of converting them. Its probably
|
|
|
|
|
* not worth the effort. But then why am I even writing this long
|
|
|
|
|
* comment that no one will read? Hmmm. - zr
|
|
|
|
|
*/
|
|
|
|
|
if(smd->emCache) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(smd->emCache);
|
2006-08-28 01:12:36 +00:00
|
|
|
smd->emCache = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(useIncremental && isFinalCalc) {
|
|
|
|
|
smd->mCache = ss = _getSubSurf(smd->mCache, smd->levels,
|
|
|
|
|
useAging, 0, useSimple);
|
|
|
|
|
|
|
|
|
|
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
|
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
|
2009-01-06 18:59:03 +00:00
|
|
|
useSubsurfUv, dm, ms);
|
2007-08-28 08:53:36 +00:00
|
|
|
|
|
|
|
|
/*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
|
|
|
|
|
drawInteriorEdges,
|
|
|
|
|
useSubsurfUv, dm);*/
|
2006-08-28 01:12:36 +00:00
|
|
|
} else {
|
|
|
|
|
if (smd->mCache && isFinalCalc) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(smd->mCache);
|
2006-08-28 01:12:36 +00:00
|
|
|
smd->mCache = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple);
|
|
|
|
|
ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple);
|
|
|
|
|
|
2007-08-28 08:53:36 +00:00
|
|
|
/*smd->mCache = ss;
|
|
|
|
|
result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache,
|
|
|
|
|
drawInteriorEdges,
|
|
|
|
|
useSubsurfUv, dm);*/
|
|
|
|
|
|
2006-08-28 01:12:36 +00:00
|
|
|
result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges,
|
2009-01-06 18:59:03 +00:00
|
|
|
useSubsurfUv, dm, ms);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(ss);
|
2006-08-28 01:12:36 +00:00
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-01-06 18:59:03 +00:00
|
|
|
struct DerivedMesh *subsurf_make_derived_from_derived(
|
|
|
|
|
struct DerivedMesh *dm,
|
|
|
|
|
struct SubsurfModifierData *smd,
|
|
|
|
|
int useRenderParams, float (*vertCos)[3],
|
|
|
|
|
int isFinalCalc, int editMode)
|
|
|
|
|
{
|
2009-09-06 06:47:59 +00:00
|
|
|
DerivedMesh *cddm = NULL, *result;
|
|
|
|
|
|
|
|
|
|
if (!CDDM_Check(dm)) {
|
2009-09-15 15:32:09 +00:00
|
|
|
cddm = CDDM_copy(dm, 0);
|
2009-09-06 06:47:59 +00:00
|
|
|
dm = cddm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result = subsurf_make_derived_from_derived_with_multires(dm, smd, NULL, useRenderParams, vertCos, isFinalCalc, editMode);
|
|
|
|
|
|
|
|
|
|
if (cddm) {
|
|
|
|
|
cddm->needsFree = 1;
|
|
|
|
|
cddm->release(cddm);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
2009-01-06 18:59:03 +00:00
|
|
|
}
|
|
|
|
|
|
2005-04-04 04:20:32 +00:00
|
|
|
void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3])
|
|
|
|
|
{
|
2007-07-28 14:04:02 +00:00
|
|
|
/* Finds the subsurf limit positions for the verts in a mesh
|
|
|
|
|
* and puts them in an array of floats. Please note that the
|
|
|
|
|
* calculated vert positions is incorrect for the verts
|
|
|
|
|
* on the boundary of the mesh.
|
|
|
|
|
*/
|
2009-08-15 17:31:28 +00:00
|
|
|
CSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0);
|
2005-04-04 04:20:32 +00:00
|
|
|
float edge_sum[3], face_sum[3];
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVertIterator *vi;
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
DerivedMesh *dm = CDDM_from_mesh(me, NULL);
|
2005-04-04 04:20:32 +00:00
|
|
|
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
ss_sync_from_derivedmesh(ss, dm, NULL, 0);
|
2005-04-04 04:20:32 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
vi = CCS_getVertIterator(ss);
|
|
|
|
|
for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) {
|
|
|
|
|
CCVert *v = CCVIter_getCurrent(vi);
|
|
|
|
|
int idx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v));
|
|
|
|
|
int N = CCS_getVertNumEdges(v);
|
|
|
|
|
int numFaces = CCS_getVertNumFaces(v);
|
2005-04-04 04:20:32 +00:00
|
|
|
float *co;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0;
|
|
|
|
|
face_sum[0]= face_sum[1]= face_sum[2]= 0.0;
|
|
|
|
|
|
|
|
|
|
for (i=0; i<N; i++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCEdge *e = CCS_getVertEdge(v, i);
|
2009-11-23 14:41:22 +00:00
|
|
|
add_v3_v3v3(edge_sum, edge_sum, CCS_getEdgeData(ss, e, 1));
|
2005-04-04 04:20:32 +00:00
|
|
|
}
|
|
|
|
|
for (i=0; i<numFaces; i++) {
|
2009-08-15 17:31:28 +00:00
|
|
|
CCFace *f = CCS_getVertFace(v, i);
|
2009-11-23 14:41:22 +00:00
|
|
|
add_v3_v3v3(face_sum, face_sum, CCS_getFaceCenterData(f));
|
2005-04-04 04:20:32 +00:00
|
|
|
}
|
|
|
|
|
|
2007-07-28 14:04:02 +00:00
|
|
|
/* ad-hoc correction for boundary vertices, to at least avoid them
|
|
|
|
|
moving completely out of place (brecht) */
|
|
|
|
|
if(numFaces && numFaces != N)
|
2009-11-10 20:43:45 +00:00
|
|
|
mul_v3_fl(face_sum, (float)N/(float)numFaces);
|
2007-07-28 14:04:02 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
co = CCS_getVertData(ss, v);
|
2005-04-04 04:20:32 +00:00
|
|
|
positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5));
|
|
|
|
|
positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5));
|
|
|
|
|
positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5));
|
|
|
|
|
}
|
2009-08-15 17:31:28 +00:00
|
|
|
CCVIter_free(vi);
|
2005-04-04 04:20:32 +00:00
|
|
|
|
2009-08-15 17:31:28 +00:00
|
|
|
CCS_free(ss);
|
Added custom vertex/edge/face data for meshes:
All data layers, including MVert/MEdge/MFace, are now managed as custom
data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are
still used of course, but allocating, copying or freeing these arrays
should be done through the CustomData API.
Work in progress documentation on this is here:
http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData
Replaced TFace by MTFace:
This is the same struct, except that it does not contain color, that now
always stays separated in MCol. This was not a good design decision to
begin with, and it is needed for adding multiple color layers later. Note
that this does mean older Blender versions will not be able to read UV
coordinates from the next release, due to an SDNA limitation.
Removed DispListMesh:
This now fully replaced by DerivedMesh. To provide access to arrays of
vertices, edges and faces, like DispListMesh does. The semantics of the
DerivedMesh.getVertArray() and similar functions were changed to return
a pointer to an array if one exists, or otherwise allocate a temporary
one. On releasing the DerivedMesh, this temporary array will be removed
automatically.
Removed ssDM and meshDM DerivedMesh backends:
The ssDM backend was for DispListMesh, so that became obsolete automatically.
The meshDM backend was replaced by the custom data backend, that now figures
out which layers need to be modified, and only duplicates those.
This changes code in many places, and overall removes 2514 lines of code.
So, there's a good chance this might break some stuff, although I've been
testing it for a few days now. The good news is, adding multiple color and
uv layers should now become easy.
2006-11-20 04:28:02 +00:00
|
|
|
|
|
|
|
|
dm->release(dm);
|
2005-04-04 04:20:32 +00:00
|
|
|
}
|
|
|
|
|
|