/*
- * $Id$
+ * $Id: GHOST_DisplayManagerSDL.cpp 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
/*
- * $Id$
+ * $Id: GHOST_DisplayManagerSDL.h 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
/*
- * $Id$
+ * $Id: GHOST_SystemSDL.cpp 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
/*
- * $Id$
+ * $Id: GHOST_SystemSDL.h 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
/*
- * $Id$
+ * $Id: GHOST_WindowSDL.cpp 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
/*
- * $Id$
+ * $Id: GHOST_WindowSDL.h 38349 2011-07-13 00:49:22Z gsrb3d $
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
+++ /dev/null
-#
-# $Id$
-#
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# 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
-# of the License, or (at your option) any later version.
-#
-# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-all: plugins
-
-plugins:
- @/bin/sh -c 'for i in *.c; do ../bmake $$i; done;'
-
-clean:
- rm -rf *.o *.so
# the mt.type enum is (ab)used for a lookup on function names
# ...to avoid lengthy if statements
# so each type must have a function here.
-
+
+ def NGONINTERP(self, layout, ob, md):
+ split = layout.split()
+ split.prop(md, "resolution")
+
def ARMATURE(self, layout, ob, md):
split = layout.split()
if hasattr(bpy.types, "WM_OT_collada_export"):
self.layout.operator("wm.collada_export", text="COLLADA (.dae)")
+ self.layout.operator("export_mesh.wavefront", text="Wavefront (.obj), BMesh")
+
class INFO_MT_file_external_data(bpy.types.Menu):
bl_label = "External Data"
layout.separator()
- layout.operator("mesh.select_by_number_vertices", text="Triangles").type = 'TRIANGLES'
- layout.operator("mesh.select_by_number_vertices", text="Quads").type = 'QUADS'
+ layout.operator("mesh.select_by_number_vertices", text = "By Number of Verts")
if context.scene.tool_settings.mesh_select_mode[2] == False:
layout.operator("mesh.select_non_manifold", text="Non Manifold")
- layout.operator("mesh.select_by_number_vertices", text="Loose Verts/Edges").type = 'OTHER'
+ layout.operator("mesh.select_loose_verts", text = "Loose Verts/Edges")
layout.operator("mesh.select_similar", text="Similar")
layout.separator()
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("mesh.subdivide", text="Subdivide")
- layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
layout.operator("mesh.merge", text="Merge...")
layout.operator("mesh.remove_doubles")
layout.operator("mesh.hide", text="Hide")
layout.operator("mesh.select_inverse")
layout.operator("mesh.flip_normals")
layout.operator("mesh.vertices_smooth", text="Smooth")
- # layout.operator("mesh.bevel", text="Bevel")
+ layout.operator("mesh.bevel", text="Bevel")
layout.operator("mesh.faces_shade_smooth")
layout.operator("mesh.faces_shade_flat")
layout.operator("mesh.blend_from_shape")
add_subdirectory(windowmanager)
add_subdirectory(blenkernel)
add_subdirectory(blenlib)
+add_subdirectory(bmesh)
add_subdirectory(render)
add_subdirectory(blenfont)
add_subdirectory(blenloader)
import sys
SConscript(['avi/SConscript',
+ 'bmesh/SConscript',
'blenkernel/SConscript',
'blenlib/SConscript',
'blenloader/SConscript',
#ifndef BKE_DERIVEDMESH_H
#define BKE_DERIVEDMESH_H
-/** \file BKE_DerivedMesh.h
- * \ingroup bke
- *
- * \todo
- * - Make drawMapped* functions take a predicate function that
- * determines whether to draw the edge (this predicate can
- * also set color, etc). This will be slightly more general
- * and allow some of the functions to be collapsed.
- * - Once accessor functions are added then single element draw
- * functions can be implemented using primitive accessors.
- * - Add function to dispatch to renderer instead of using
- * conversion to DLM.
+/*
+ Basic design of the DerivedMesh system:
+
+ DerivedMesh is a common set of interfaces for mesh systems.
+
+ There are three main mesh data structures in Blender: Mesh, CDDM, and BMesh.
+ These, and a few others, all implement DerivedMesh interfaces,
+ which contains unified drawing interfaces, a few utility interfaces,
+ and a bunch of read-only interfaces intended mostly for conversion from
+ one format to another.
+
+ All Mesh structures in blender make use of CustomData, which is used to store
+ per-element attributes and interpolate them (e.g. uvs, vcols, vgroups, etc).
+
+ Mesh is the "serialized" structure, used for storing object-mode mesh data
+ and also for saving stuff to disk. It's interfaces are also what DerivedMesh
+ uses to communicate with.
+
+ CDDM is a little mesh library, that uses Mesh data structures in the backend.
+ It's mostly used for modifiers, and has the advantages of not taking much
+ resources.
+
+ BMesh is a full-on brep, used for editmode, some modifiers, etc. It's much
+ more capable (if memory-intensive) then CDDM.
+
+ DerivedMesh is somewhat hackish. Many places assumes that a DerivedMesh is
+ a CDDM (most of the time by simply copying it and converting it to one).
+ CDDM is the original structure for modifiers, but has since been superseded
+ by BMesh, at least for the foreseeable future.
+*/
+
+/*
+ * Note: This sturcture is read-only, for all practical purposes.
+ * At some point in the future, we may want to consider
+ * creating a replacement structure that implements a proper
+ * abstract mesh kernel interface. Or, we can leave this
+ * as it is and stick with using BMesh and CDDM.
*/
+
#include "DNA_customdata_types.h"
+#include "DNA_meshdata_types.h"
+
#include "BKE_customdata.h"
#include "BKE_bvhutils.h"
struct Object;
struct Scene;
struct Mesh;
-struct EditMesh;
+struct BMEditMesh;
struct KeyBlock;
struct ModifierData;
struct MCol;
struct ColorBand;
struct GPUVertexAttribs;
struct GPUDrawObject;
+struct BMEditMesh;
struct ListBase;
struct PBVH;
/* number of sub-elements each mesh element has (for interpolation) */
#define SUB_ELEMS_VERT 0
#define SUB_ELEMS_EDGE 2
-#define SUB_ELEMS_FACE 4
+#define SUB_ELEMS_FACE 50
+
+/*
+Note: all mface interfaces now officially operate on tesselated data.
+ Also, the mface origindex layer indexes mpolys, not mfaces.
+*/
typedef struct DMGridData {
float co[3];
typedef enum DerivedMeshType {
DM_TYPE_CDDM,
- DM_TYPE_EDITMESH,
+ DM_TYPE_EDITBMESH,
DM_TYPE_CCGDM
} DerivedMeshType;
typedef struct DerivedMesh DerivedMesh;
struct DerivedMesh {
/* Private DerivedMesh data, only for internal DerivedMesh use */
- CustomData vertData, edgeData, faceData;
- int numVertData, numEdgeData, numFaceData;
+ CustomData vertData, edgeData, faceData, loopData, polyData;
+ int numVertData, numEdgeData, numFaceData, numLoopData, numPolyData;
int needsFree; /* checked on ->release, is set to 0 for cached results */
int deformedOnly; /* set by modifier stack if only deformed from original */
BVHCache bvhCache;
DerivedMeshType type;
/* Misc. Queries */
+
+ /*recalculates mesh tesselation*/
+ void (*recalcTesselation)(DerivedMesh *dm);
/* Also called in Editmode */
int (*getNumVerts)(DerivedMesh *dm);
- /* Also called in Editmode */
- int (*getNumFaces)(DerivedMesh *dm);
-
int (*getNumEdges)(DerivedMesh *dm);
+ int (*getNumTessFaces)(DerivedMesh *dm);
+ int (*getNumFaces) (DerivedMesh *dm);
- /* copy a single vert/edge/face from the derived mesh into
+ /* copy a single vert/edge/tesselated face from the derived mesh into
* *{vert/edge/face}_r. note that the current implementation
* of this function can be quite slow, iterating over all
* elements (editmesh)
*/
void (*getVert)(DerivedMesh *dm, int index, struct MVert *vert_r);
void (*getEdge)(DerivedMesh *dm, int index, struct MEdge *edge_r);
- void (*getFace)(DerivedMesh *dm, int index, struct MFace *face_r);
+ void (*getTessFace)(DerivedMesh *dm, int index, struct MFace *face_r);
/* return a pointer to the entire array of verts/edges/face from the
* derived mesh. if such an array does not exist yet, it will be created,
*/
struct MVert *(*getVertArray)(DerivedMesh *dm);
struct MEdge *(*getEdgeArray)(DerivedMesh *dm);
- struct MFace *(*getFaceArray)(DerivedMesh *dm);
+ struct MFace *(*getTessFaceArray)(DerivedMesh *dm);
+ struct MLoop *(*getLoopArray)(DerivedMesh *dm);
+ struct MPoly *(*getPolyArray)(DerivedMesh *dm);
/* copy all verts/edges/faces from the derived mesh into
* *{vert/edge/face}_r (must point to a buffer large enough)
*/
void (*copyVertArray)(DerivedMesh *dm, struct MVert *vert_r);
void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *edge_r);
- void (*copyFaceArray)(DerivedMesh *dm, struct MFace *face_r);
+ void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *face_r);
+ void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *loop_r);
+ void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *poly_r);
/* return a copy of all verts/edges/faces from the derived mesh
* it is the caller's responsibility to free the returned pointer
*/
struct MVert *(*dupVertArray)(DerivedMesh *dm);
struct MEdge *(*dupEdgeArray)(DerivedMesh *dm);
- struct MFace *(*dupFaceArray)(DerivedMesh *dm);
+ struct MFace *(*dupTessFaceArray)(DerivedMesh *dm);
+ struct MLoop *(*dupLoopArray)(DerivedMesh *dm);
+ struct MPoly *(*dupPolyArray)(DerivedMesh *dm);
/* return a pointer to a single element of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not
*/
void *(*getVertData)(DerivedMesh *dm, int index, int type);
void *(*getEdgeData)(DerivedMesh *dm, int index, int type);
- void *(*getFaceData)(DerivedMesh *dm, int index, int type);
+ void *(*getTessFaceData)(DerivedMesh *dm, int index, int type);
/* return a pointer to the entire array of vert/edge/face custom data
* from the derived mesh (this gives a pointer to the actual data, not
*/
void *(*getVertDataArray)(DerivedMesh *dm, int type);
void *(*getEdgeDataArray)(DerivedMesh *dm, int type);
- void *(*getFaceDataArray)(DerivedMesh *dm, int type);
-
+ void *(*getTessFaceDataArray)(DerivedMesh *dm, int type);
+
+ /*retrieves the base CustomData structures for
+ verts/edges/tessfaces/loops/facdes*/
+ CustomData *(*getVertDataLayout)(DerivedMesh *dm);
+ CustomData *(*getEdgeDataLayout)(DerivedMesh *dm);
+ CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm);
+ CustomData *(*getLoopDataLayout)(DerivedMesh *dm);
+ CustomData *(*getFaceDataLayout)(DerivedMesh *dm);
+
+ /*copies all customdata for an element source into dst at index dest*/
+ void (*copyFromVertCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
+ void (*copyFromEdgeCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
+ void (*copyFromFaceCData)(DerivedMesh *dm, int source, CustomData *dst, int dest);
+
/* optional grid access for subsurf */
int (*getNumGrids)(DerivedMesh *dm);
int (*getGridSize)(DerivedMesh *dm);
* o Drawing options too complicated to enumerate, look at code.
*/
void (*drawFacesTex)(DerivedMesh *dm,
- int (*setDrawOptions)(struct MTFace *tface,
- struct MCol *mcol, int matnr));
+ int (*setDrawOptions)(struct MTFace *tface,
+ int has_vcol, int matnr));
/* Draw all faces with GLSL materials
* o setMaterial is called for every different material nr
* of vertices, edges and faces (doesn't allocate memory for them, just
* sets up the custom data layers)
*/
-void DM_init(DerivedMesh *dm, DerivedMeshType type,
- int numVerts, int numEdges, int numFaces);
+void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges,
+ int numFaces, int numLoops, int numPolys);
/* utility function to initialise a DerivedMesh for the desired number
* of vertices, edges and faces, with a layer setup copied from source
*/
void DM_from_template(DerivedMesh *dm, DerivedMesh *source,
- DerivedMeshType type,
- int numVerts, int numEdges, int numFaces);
+ DerivedMeshType type,
+ int numVerts, int numEdges, int numFaces,
+ int numLoops, int numPolys);
/* utility function to release a DerivedMesh's layers
* returns 1 if DerivedMesh has to be released by the backend, 0 otherwise
/* utility function to convert a DerivedMesh to a Mesh
*/
-void DM_to_mesh(DerivedMesh *dm, struct Mesh *me);
+void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob);
/* utility function to convert a DerivedMesh to a shape key block
*/
void *layer);
void DM_add_edge_layer(struct DerivedMesh *dm, int type, int alloctype,
void *layer);
+void DM_add_tessface_layer(struct DerivedMesh *dm, int type, int alloctype,
+ void *layer);
void DM_add_face_layer(struct DerivedMesh *dm, int type, int alloctype,
void *layer);
*/
void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type);
+void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type);
void *DM_get_face_data_layer(struct DerivedMesh *dm, int type);
/* custom data setting functions
int source_index, int dest_index, int count);
void DM_copy_edge_data(struct DerivedMesh *source, struct DerivedMesh *dest,
int source_index, int dest_index, int count);
+void DM_copy_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+ int source_index, int dest_index, int count);
+void DM_copy_loop_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+ int source_index, int dest_index, int count);
void DM_copy_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
int source_index, int dest_index, int count);
*/
void DM_free_vert_data(struct DerivedMesh *dm, int index, int count);
void DM_free_edge_data(struct DerivedMesh *dm, int index, int count);
+void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count);
+void DM_free_loop_data(struct DerivedMesh *dm, int index, int count);
void DM_free_face_data(struct DerivedMesh *dm, int index, int count);
+/*sets up mpolys for a DM based on face iterators in source*/
+void DM_DupPolys(DerivedMesh *source, DerivedMesh *target);
+
/* interpolates vertex data from the vertices indexed by src_indices in the
* source mesh using the given weights and stores the result in the vertex
* indexed by dest_index in the dest mesh
* vert_weights[i] multiplied by weights[i].
*/
typedef float FaceVertWeight[SUB_ELEMS_FACE][SUB_ELEMS_FACE];
-void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+void DM_interp_tessface_data(struct DerivedMesh *source, struct DerivedMesh *dest,
int *src_indices,
float *weights, FaceVertWeight *vert_weights,
int count, int dest_index);
-void DM_swap_face_data(struct DerivedMesh *dm, int index, const int *corner_indices);
+void DM_swap_tessface_data(struct DerivedMesh *dm, int index, const int *corner_indices);
+
+void DM_interp_loop_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index);
+
+void DM_interp_face_data(struct DerivedMesh *source, struct DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index);
/* Temporary? A function to give a colorband to derivedmesh for vertexcolor ranges */
void vDM_ColorBand_store(struct ColorBand *coba);
DerivedMesh *mesh_get_derived_deform(struct Scene *scene, struct Object *ob,
CustomDataMask dataMask);
-DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob, struct ModifierData *md);
+DerivedMesh *mesh_create_derived_for_modifier(struct Scene *scene, struct Object *ob,
+ struct ModifierData *md, int build_shapekey_layers);
DerivedMesh *mesh_create_derived_render(struct Scene *scene, struct Object *ob,
CustomDataMask dataMask);
+DerivedMesh *getEditDerivedBMesh(struct BMEditMesh *em, struct Object *ob,
+ float (*vertexCos)[3]);
+
DerivedMesh *mesh_create_derived_index_render(struct Scene *scene, struct Object *ob, CustomDataMask dataMask, int index);
/* same as above but wont use render settings */
DerivedMesh *mesh_create_derived_physics(struct Scene *scene, struct Object *ob, float (*vertCos)[3],
CustomDataMask dataMask);
-DerivedMesh *editmesh_get_derived(struct EditMesh *em, float (*vertexCos)[3]);
-DerivedMesh *editmesh_get_derived_base(struct Object *, struct EditMesh *em);
-DerivedMesh *editmesh_get_derived_cage(struct Scene *scene, struct Object *,
- struct EditMesh *em, CustomDataMask dataMask);
-DerivedMesh *editmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *,
- struct EditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived(struct BMEditMesh *em, float (*vertexCos)[3]);
+DerivedMesh *editbmesh_get_derived_base(struct Object *, struct BMEditMesh *em);
+DerivedMesh *editbmesh_get_derived_cage(struct Scene *scene, struct Object *,
+ struct BMEditMesh *em, CustomDataMask dataMask);
+DerivedMesh *editbmesh_get_derived_cage_and_final(struct Scene *scene, struct Object *,
+ struct BMEditMesh *em, DerivedMesh **final_r,
CustomDataMask dataMask);
-float (*editmesh_get_vertex_cos(struct EditMesh *em, int *numVerts_r))[3];
-int editmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
-void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct EditMesh *em, CustomDataMask dataMask);
+float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *numVerts_r))[3];
+int editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
+void makeDerivedMesh(struct Scene *scene, struct Object *ob, struct BMEditMesh *em,
+ CustomDataMask dataMask, int build_shapekey_layers);
/* returns an array of deform matrices for crazyspace correction, and the
number of modifiers left */
-int editmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct EditMesh *em,
+int editbmesh_get_first_deform_matrices(struct Scene *, struct Object *, struct BMEditMesh *em,
float (**deformmats)[3][3], float (**deformcos)[3]);
/* returns an array of deform matrices for crazyspace correction when sculpting,
extern char *BKE_undo_menu_string(void);
extern void BKE_undo_number(struct bContext *C, int nr);
extern char *BKE_undo_get_name(int nr, int *active);
+void BKE_undo_save(char *fname);
extern void BKE_undo_save_quit(void);
extern struct Main *BKE_undo_get_main(struct Scene **scene);
struct BME_Poly;
struct BME_Loop;
+/*NOTE: this is the bmesh 1.0 code. it's completely outdated.*/
/*Notes on further structure Cleanup:
-Remove the tflags, they belong in custom data layers
#include "BKE_DerivedMesh.h"
struct DerivedMesh;
+struct BMEditMesh;
struct EditMesh;
struct Mesh;
struct Object;
/* creates a new CDDerivedMesh */
-struct DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces);
+struct DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces,
+ int numLoops, int numPolys);
+
+/*tests if a given DerivedMesh is a CDDM*/
+int CDDM_Check(struct DerivedMesh *dm);
/* creates a CDDerivedMesh from the given Mesh, this will reference the
original data in Mesh, but it is safe to apply vertex coordinates or
data to not overwrite the original */
struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob);
-/* creates a CDDerivedMesh from the given EditMesh */
-struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me);
+/* creates a CDDerivedMesh from the given BMEditMesh */
+DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int use_mdisps);
+
+/* merge verts */
+DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap);
/* creates a CDDerivedMesh from the given curve object */
struct DerivedMesh *CDDM_from_curve(struct Object *ob);
/* useful for OrcoDM creation for curves with constructive modifiers */
DerivedMesh *CDDM_from_curve_customDB(struct Object *ob, struct ListBase *dispbase);
+struct BMEditMesh *CDDM_To_BMesh(struct Object *ob, struct DerivedMesh *dm, struct BMEditMesh *existing);
+
+
/* Copies the given DerivedMesh with verts, faces & edges stored as
* custom element data.
*/
-struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm);
+struct DerivedMesh *CDDM_copy(struct DerivedMesh *dm, int faces_from_tessfaces);
/* creates a CDDerivedMesh with the same layer stack configuration as the
* given DerivedMesh and containing the requested numbers of elements.
* elements are initialised to all zeros
*/
struct DerivedMesh *CDDM_from_template(struct DerivedMesh *source,
- int numVerts, int numEdges, int numFaces);
+ int numVerts, int numEdges, int numFaces,
+ int numLoops, int numPolys);
+
+/*converts mfaces to mpolys. note things may break if there are not valid
+ *medges surrounding each mface.
+ */
+void CDDM_tessfaces_to_faces(struct DerivedMesh *dm);
/* applies vertex coordinates or normals to a CDDerivedMesh. if the MVert
* layer is a referenced layer, it will be duplicate to not overwrite the
/* calculates edges for a CDDerivedMesh (from face data)
* this completely replaces the current edge data in the DerivedMesh
+ * builds edges from the tesselated face data.
*/
void CDDM_calc_edges(struct DerivedMesh *dm);
+/* same as CDDM_calc_edges only makes edges from ngon faces instead of tesselation
+ faces*/
+void CDDM_calc_edges_poly(struct DerivedMesh *dm);
+
+/*reconstitute face triangulation. if orig_use_polyorig is nonzero, sets
+ the mface origindex layer to copy to the origindex values of the
+ parent mpolys; otherwise the mface origindex will point to the index of
+ the parent mpoly*/
+void CDDM_recalc_tesselation(struct DerivedMesh *dm, int orig_use_polyorig);
+
/* lowers the number of vertices/edges/faces in a CDDerivedMesh
* the layer data stays the same size
*/
*/
struct MVert *CDDM_get_vert(struct DerivedMesh *dm, int index);
struct MEdge *CDDM_get_edge(struct DerivedMesh *dm, int index);
-struct MFace *CDDM_get_face(struct DerivedMesh *dm, int index);
+struct MFace *CDDM_get_tessface(struct DerivedMesh *dm, int index);
+struct MLoop *CDDM_get_loop(struct DerivedMesh *dm, int index);
+struct MPoly *CDDM_get_face(struct DerivedMesh *dm, int index);
/* vertex/edge/face array access functions - return the array holding the
* desired data
*/
struct MVert *CDDM_get_verts(struct DerivedMesh *dm);
struct MEdge *CDDM_get_edges(struct DerivedMesh *dm);
-struct MFace *CDDM_get_faces(struct DerivedMesh *dm);
+struct MFace *CDDM_get_tessfaces(struct DerivedMesh *dm);
+struct MLoop *CDDM_get_loops(struct DerivedMesh *dm);
+struct MPoly *CDDM_get_polys(struct DerivedMesh *dm);
+
+/*Assigns news m*** layers to the cddm. Note that you must handle
+ freeing the old ones yourself. Also you must ensure dm->num****Data
+ is correct.*/
+void CDDM_set_mvert(struct DerivedMesh *dm, struct MVert *mvert);
+void CDDM_set_medge(struct DerivedMesh *dm, struct MEdge *medge);
+void CDDM_set_mface(struct DerivedMesh *dm, struct MFace *mface);
+void CDDM_set_mloop(struct DerivedMesh *dm, struct MLoop *mloop);
+void CDDM_set_mpoly(struct DerivedMesh *dm, struct MPoly *mpoly);
+
#endif
extern "C" {
#endif
+struct BMesh;
struct ID;
struct CustomData;
struct CustomDataLayer;
typedef unsigned int CustomDataMask;
+/*a data type large enough to hold 1 element from any customdata layer type*/
+typedef struct {unsigned char data[64];} CDBlockBytes;
+
extern const CustomDataMask CD_MASK_BAREMESH;
extern const CustomDataMask CD_MASK_MESH;
extern const CustomDataMask CD_MASK_EDITMESH;
#define CD_DUPLICATE 4 /* do a full copy of all layers, only allowed if source
has same number of elements */
+/* Checks if the layer at physical offset layern (in data->layers) support math
+ * the below operations.
+ */
+int CustomData_layer_has_math(struct CustomData *data, int layern);
+
+/*copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
+ another, while not overwriting anything else (e.g. flags). probably only
+ implemented for mloopuv/mloopcol, for now.*/
+void CustomData_data_copy_value(int type, void *source, void *dest);
+
+/* compares if data1 is equal to data2. type is a valid CustomData type
+ * enum (e.g. CD_MLOOPUV). the layer type's equal function is used to compare
+ * the data, if it exists, otherwise memcmp is used.*/
+int CustomData_data_equals(int type, void *data1, void *data2);
+void CustomData_data_initminmax(int type, void *min, void *max);
+void CustomData_data_dominmax(int type, void *data, void *min, void *max);
+void CustomData_data_multiply(int type, void *data, float fac);
+void CustomData_data_add(int type, void *data1, void *data2);
+
/* initialises a CustomData object with the same layer setup as source.
* mask is a bitfield where (mask & (1 << (layer type))) indicates
* if a layer should be copied or not. alloctype must be one of the above. */
void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
CustomDataMask mask, int alloctype, int totelem);
+/* TODO, not really a public function but readfile.c needs it */
+void CustomData_update_typemap(struct CustomData *data);
+
/* same as the above, except that this will preserve existing layers, and only
* add the layers that were not there yet */
void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
CustomDataMask mask, int alloctype, int totelem);
+/*bmesh version of CustomData_merge; merges the layouts of source and dest,
+ then goes through the mesh and makes sure all the customdata blocks are
+ consistent with the new layout.*/
+void CustomData_bmesh_merge(struct CustomData *source, struct CustomData *dest,
+ int mask, int alloctype, struct BMesh *bm, int type);
+
/* frees data associated with a CustomData object (doesn't free the object
* itself, though)
*/
void CustomData_copy_data(const struct CustomData *source,
struct CustomData *dest, int source_index,
int dest_index, int count);
+void CustomData_copy_elements(int type, void *source, void *dest, int count);
void CustomData_em_copy_data(const struct CustomData *source,
struct CustomData *dest, void *src_block,
void **dest_block);
void CustomData_bmesh_copy_data(const struct CustomData *source,
- struct CustomData *dest,void *src_block,
- void **dest_block);
+ struct CustomData *dest, void *src_block,
+ void **dest_block);
void CustomData_em_validate_data(struct CustomData *data, void *block, int sub_elements);
/* frees data in a CustomData object
* returns NULL if there is no layer of type
*/
void *CustomData_get(const struct CustomData *data, int index, int type);
+void *CustomData_get_n(const struct CustomData *data, int type, int index, int n);
void *CustomData_em_get(const struct CustomData *data, void *block, int type);
void *CustomData_em_get_n(const struct CustomData *data, void *block, int type, int n);
void *CustomData_bmesh_get(const struct CustomData *data, void *block, int type);
void *CustomData_bmesh_get_n(const struct CustomData *data, void *block, int type, int n);
+/* gets the layer at physical index n, with no type checking.
+ */
+void *CustomData_bmesh_get_layer_n(const struct CustomData *data, void *block, int n);
+
+int CustomData_set_layer_name(const struct CustomData *data, int type, int n, const char *name);
+
/* gets a pointer to the active or first layer of type
* returns NULL if there is no layer of type
*/
void *CustomData_get_layer_n(const struct CustomData *data, int type, int n);
void *CustomData_get_layer_named(const struct CustomData *data, int type,
const char *name);
-
int CustomData_get_layer_index(const struct CustomData *data, int type);
+int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n);
int CustomData_get_named_layer_index(const struct CustomData *data, int type, const char *name);
int CustomData_get_active_layer_index(const struct CustomData *data, int type);
int CustomData_get_render_layer_index(const struct CustomData *data, int type);
void CustomData_bmesh_set_n(struct CustomData *data, void *block, int type, int n,
void *source);
+/*sets the data of the block at physical layer n. no real type checking
+ *is performed.
+ */
+void CustomData_bmesh_set_layer_n(struct CustomData *data, void *block, int n,
+ void *source);
/* set the pointer of to the first layer of type. the old data is not freed.
* returns the value of ptr if the layer is found, NULL otherwise
int CustomData_verify_versions(struct CustomData *data, int index);
/*BMesh specific customdata stuff*/
-void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata);
+void CustomData_to_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata,
+ struct CustomData *ldata, int totloop, int totpoly);
void CustomData_from_bmeshpoly(struct CustomData *fdata, struct CustomData *pdata, struct CustomData *ldata, int total);
void CustomData_bmesh_init_pool(struct CustomData *data, int allocsize);
#endif
void free_key(struct Key *sc);
+void free_key_nolib(struct Key *key);
struct Key *add_key(struct ID *id);
struct Key *copy_key(struct Key *key);
+struct Key *copy_key_nolib(struct Key *key);
void make_local_key(struct Key *key);
void sort_keys(struct Key *key);
struct BoundBox;
struct DispList;
struct ListBase;
-struct EditMesh;
-struct MDeformVert;
+struct BMEditMesh;
+struct BMesh;
struct Mesh;
+struct MPoly;
+struct MLoop;
struct MFace;
struct MEdge;
struct MVert;
+struct MDeformVert;
struct MCol;
struct Object;
struct MTFace;
extern "C" {
#endif
-struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me);
-void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em);
+struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob);
+
+/*
+ this function recreates a tesselation.
+ returns number of tesselation faces.
+
+ use_poly_origindex sets whether or not the tesselation faces' origindex
+ layer should point to original poly indices or real poly indices.
+
+ use_face_origindex sets the tesselation faces' origindex layer
+ to point to the tesselation faces themselves, not the polys.
+
+ if both of the above are 0, it'll use the indices of the mpolys of the MPoly
+ data in pdata, and ignore the origindex layer altogether.
+ */
+int mesh_recalcTesselation(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, struct MVert *mvert, int totface,
+ int totloop, int totpoly, int use_poly_origindex, int use_face_origindex);
+
+/*calculates a face normal.*/
+void mesh_calc_poly_normal(struct MPoly *mpoly, struct MLoop *loopstart,
+ struct MVert *mvarray, float *no);
void unlink_mesh(struct Mesh *me);
-void free_mesh(struct Mesh *me);
+void free_mesh(struct Mesh *me, int unlink);
struct Mesh *add_mesh(const char *name);
struct Mesh *copy_mesh(struct Mesh *me);
void mesh_update_customdata_pointers(struct Mesh *me);
+
void make_local_mesh(struct Mesh *me);
void boundbox_mesh(struct Mesh *me, float *loc, float *size);
void tex_space_mesh(struct Mesh *me);
struct Mesh *get_mesh(struct Object *ob);
void set_mesh(struct Object *ob, struct Mesh *me);
void mball_to_mesh(struct ListBase *lb, struct Mesh *me);
-int nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *_totvert,
- struct MEdge **alledge, int *_totedge, struct MFace **allface, int *_totface);
-int nurbs_to_mdata_customdb(struct Object *ob, struct ListBase *dispbase,
- struct MVert **allvert, int *_totvert, struct MEdge **alledge, int *_totedge,
- struct MFace **allface, int *_totface);
+int nurbs_to_mdata(struct Object *ob, struct MVert **allvert, int *totvert,
+ struct MEdge **alledge, int *totedge, struct MFace **allface, struct MLoop **allloop, struct MPoly **allpoly,
+ int *totface, int *totloop, int *totpoly);
+int nurbs_to_mdata_customdb(struct Object *ob, struct ListBase *dispbase, struct MVert **allvert, int *_totvert,
+ struct MEdge **alledge, int *_totedge, struct MFace **allface, struct MLoop **allloop, struct MPoly **allpoly,
+ int *_totface, int *_totloop, int *_totpoly);
void nurbs_to_mesh(struct Object *ob);
void mesh_to_curve(struct Scene *scene, struct Object *ob);
void free_dverts(struct MDeformVert *dvert, int totvert);
void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */
void mesh_delete_material_index(struct Mesh *me, int index);
void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth);
+void convert_mfaces_to_mpolys(struct Mesh *mesh);
+void mesh_calc_tessface_normals(struct MVert *mverts, int numVerts,struct MFace *mfaces, int numFaces, float (*faceNors_r)[3]);
+
+/*used for unit testing; compares two meshes, checking only
+ differences we care about. should be usable with leaf's
+ testing framework I get RNA work done, will use hackish
+ testing code for now.*/
+const char *mesh_cmp(struct Mesh *me1, struct Mesh *me2, float thresh);
struct BoundBox *mesh_get_bb(struct Object *ob);
void mesh_get_texspace(struct Mesh *me, float *loc_r, float *rot_r, float *size_r);
/* Calculate vertex and face normals, face normals are returned in *faceNors_r if non-NULL
* and vertex normals are stored in actual mverts.
*/
-void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces, int numFaces, float (*faceNors_r)[3]);
+void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MLoop *mloop,
+ struct MPoly *mpolys, int numLoops, int numPolys, float (*polyNors_r)[3],
+ struct MFace *mfaces, int numFaces, int *origIndexFace, float (*faceNors_r)[3]);
/* Return a newly MEM_malloc'd array of all the mesh vertex locations
* (_numVerts_r_ may be NULL) */
void BKE_mesh_calc_edges(struct Mesh *mesh, int update);
+/*convert a triangle of loop facedata to mface facedata*/
+void mesh_loops_to_tri_corners(struct CustomData *fdata, struct CustomData *ldata,
+ struct CustomData *pdata, int lindex[3], int findex,
+ int polyindex);
+
#ifdef __cplusplus
}
#endif
struct LinkNode;
struct bArmature;
struct ModifierData;
+struct BMEditMesh;
typedef enum {
/* Should not be used, only for None modifier type */
*/
void (*deformVertsEM)(
struct ModifierData *md, struct Object *ob,
- struct EditMesh *editData, struct DerivedMesh *derivedData,
+ struct BMEditMesh *editData, struct DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts);
/* Set deform matrix per vertex for crazyspace correction */
void (*deformMatricesEM)(
struct ModifierData *md, struct Object *ob,
- struct EditMesh *editData, struct DerivedMesh *derivedData,
+ struct BMEditMesh *editData, struct DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
/********************* Non-deform modifier functions *********************/
*/
struct DerivedMesh *(*applyModifierEM)(
struct ModifierData *md, struct Object *ob,
- struct EditMesh *editData,
+ struct BMEditMesh *editData,
struct DerivedMesh *derivedData);
void multires_stitch_grids(struct Object *);
+/*switch mdisp data in dm between tangent and object space*/
+enum {
+ MULTIRES_SPACE_TANGENT,
+ MULTIRES_SPACE_OBJECT,
+ MULTIRES_SPACE_ABSOLUTE,
+};
+void multires_set_space(struct DerivedMesh *dm, struct Object *ob, int from, int to);
+
/* Related to the old multires */
void multires_free(struct Multires *mr);
void multires_load_old(struct Object *ob, struct Mesh *me);
/* Partial redraw */
int partial_redraw;
-
+
/* Used to cache the render of the active texture */
unsigned int texcache_side, *texcache, texcache_actual;
struct _CCGFace;
struct _CCGSubsurf;
struct _CCGVert;
+struct EdgeHash;
+struct PBVH;
+struct DMGridData;
+struct DMGridAdjacency;
/**************************** External *****************************/
short *edgeFlags;
char *faceFlags;
+ int *reverseFaceMap;
+
struct PBVH *pbvh;
struct ListBase *fmap;
struct IndexNode *fmap_mem;
void (*update)(DerivedMesh*);
} multires;
+
+ struct EdgeHash *ehash;
} CCGDerivedMesh;
#endif
--- /dev/null
+#ifndef _BKE_TESSMESH_H
+#define _BKE_TESSMESH_H
+
+#include "bmesh.h"
+
+struct BMesh;
+struct BMLoop;
+struct BMFace;
+struct Mesh;
+struct DerivedMesh;
+
+/*
+ok: the EDBM module is for editmode bmesh stuff. in contrast, the
+ BMEdit module is for code shared with blenkernel that concerns
+ the BMEditMesh structure.
+*/
+
+/*this structure replaces EditMesh.
+
+ through this, you get access to both the edit bmesh,
+ it's tesselation, and various stuff that doesn't belong in the BMesh
+ struct itself.
+
+ the entire derivedmesh and modifier system works with this structure,
+ and not BMesh. Mesh->edit_bmesh stores a pointer to this structure.*/
+typedef struct BMEditMesh {
+ struct BMesh *bm;
+
+ /*this is for undoing failed operations*/
+ struct BMEditMesh *emcopy;
+ int emcopyusers;
+
+ /*we store tesselations as triplets of three loops,
+ which each define a triangle.*/
+ struct BMLoop *(*looptris)[3];
+ int tottri;
+
+ /*derivedmesh stuff*/
+ struct DerivedMesh *derivedFinal, *derivedCage;
+ int lastDataMask;
+
+ /*retopo data pointer*/
+ struct RetopoPaintData *retopo_paint_data;
+
+ /*index tables, to map indices to elements via
+ EDBM_init_index_arrays and associated functions. don't
+ touch this or read it directly.*/
+ struct BMVert **vert_index;
+ struct BMEdge **edge_index;
+ struct BMFace **face_index;
+
+ /*selection mode*/
+ short selectmode;
+ short mat_nr;
+
+ /*Mesh structure this editmesh came from, if it came from one*/
+ struct Mesh *me;
+ struct Object *ob;
+
+ /*temp variables for x-mirror editing*/
+ int mirror_cdlayer;
+ int mirr_free_arrays;
+} BMEditMesh;
+
+void BMEdit_RecalcTesselation(BMEditMesh *tm);
+BMEditMesh *BMEdit_Create(BMesh *bm);
+BMEditMesh *BMEdit_Copy(BMEditMesh *tm);
+void BMEdit_Free(BMEditMesh *em);
+void BMEdit_UpdateLinkedCustomData(BMEditMesh *em);
+
+#endif /* _BKE_TESSMESH_H */
#ifndef BKE_UTILDEFINES_H
#define BKE_UTILDEFINES_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* these values need to be hardcoded in structs, dna does not recognize defines */
/* also defined in DNA_space_types.h */
#ifndef FILE_MAXDIR
#define BMEMSET(mem, val, size) {unsigned int _i; char *_c = (char*) mem; for (_i=0; _i<size; _i++) *_c++ = val;}
+#ifdef __cplusplus
+}
+#endif
+
#endif // BKE_UTILDEFINES_H
../imbuf
../makesdna
../makesrna
+ ../bmesh
../modifiers
../nodes
../render/extern/include
intern/depsgraph.c
intern/displist.c
intern/effect.c
+ intern/editderivedbmesh.c
intern/fcurve.c
intern/fluidsim.c
intern/fmodifier.c
intern/mesh.c
intern/mesh_validate.c
intern/modifier.c
+ intern/modifiers_bmesh.c
intern/multires.c
intern/nla.c
intern/node.c
incs += ' #/extern/bullet2/src'
incs += ' #/intern/opennl/extern #/intern/bsp/extern'
incs += ' ../gpu #/extern/glew/include'
+incs += ' ../bmesh'
incs += ' #/intern/smoke/extern'
incs += ' #/intern/mikktspace'
incs += ' #/intern/audaspace/intern'
-/*
+#if 0
+/**
* BME_customdata.c jan 2007
*
* Custom Data functions for Bmesh
if(data->totlayer){
/*alloc memory*/
data->layers = MEM_callocN(sizeof(BME_CustomDataLayer)*data->totlayer, "BMesh Custom Data Layers");
- data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 0);
+ data->pool = BLI_mempool_create(data->totsize, initalloc, initalloc, 1);
/*initialize layer data*/
for(i=0; i < BME_CD_NUMTYPES; i++){
if(init->layout[i]){
typeInfo->set_default((char*)*block + offset, 1);
}
}
+#endif
-/*
+#if 0
+/**
* BME_mesh.c jan 2007
*
* BMesh mesh level functions.
CustomData_copy(&em->fdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
/*copy face corner data*/
- CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata);
+ CustomData_to_bmeshpoly(&em->fdata, &bm->pdata, &bm->ldata, 0, 0);
/*initialize memory pools*/
CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
CustomData_copy(&dm->faceData, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
/*copy face corner data*/
- CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata);
+ CustomData_to_bmeshpoly(&dm->faceData, &bm->pdata, &bm->ldata, 0, 0);
/*initialize memory pools*/
CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
- totface = dm->getNumFaces(dm);
+ totface = dm->getNumTessFaces(dm);
mvert = dm->getVertArray(dm);
medge = dm->getEdgeArray(dm);
- mface = dm->getFaceArray(dm);
+ mface = dm->getTessFaceArray(dm);
vert_array = MEM_mallocN(sizeof(*vert_array)*totvert,"BME_derivedmesh_to_bmesh BME_Vert* array");
}
/*convert back to mesh*/
- result = CDDM_from_template(dm,totvert,totedge,totface);
+ /*BMESH_TODO this should add in mloops and mpolys as well*/
+ result = CDDM_from_template(dm,totvert,totedge,totface, 0, 0);
CustomData_merge(&bm->vdata, &result->vertData, CD_MASK_BMESH, CD_CALLOC, totvert);
CustomData_merge(&bm->edata, &result->edgeData, CD_MASK_BMESH, CD_CALLOC, totedge);
CustomData_merge(&bm->pdata, &result->faceData, CD_MASK_BMESH, CD_CALLOC, totface);
}
}
if(totface){
- mface = CDDM_get_faces(result);
+ mface = CDDM_get_tessfaces(result);
origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
/*make faces*/
for(i=0,f=bm->polys.first;f;f=f->next){
BLI_edgehash_free(edge_hash, NULL);
return result;
}
+#endif
-/*
+#if 0
+/**
* BME_eulers.c jan 2007
*
* BMesh Euler construction API.
#ifndef BME_FASTEULER
/*count valance of v1*/
- if(v1->edge){
- d1 = BME_disk_getpointer(v1->edge,v1);
+ if(v1->e){
+ d1 = BME_disk_getpointer(v1->e,v1);
if(d1) valance1 = BME_cycle_length(d1);
else BME_error();
}
- if(v2->edge){
- d2 = BME_disk_getpointer(v2->edge,v2);
+ if(v2->e){
+ d2 = BME_disk_getpointer(v2->e,v2);
if(d2) valance2 = BME_cycle_length(d2);
else BME_error();
}
elist[i]->eflag1 |= MF_CANDIDATE;
/*if elist[i] has a loop, count its radial length*/
- if(elist[i]->loop) elist[i]->eflag2 = BME_cycle_length(&(elist[i]->loop->radial));
+ if(elist[i]->loop) elist[i]->eflag2 = BME_cycle_length(&(elist[i]->l->radial));
else elist[i]->eflag2 = 0;
}
for(i=0;i<len;i++){
curvert = vlist[i];
l = BME_create_loop(bm,curvert,NULL,f,NULL);
- if(!(f->loopbase)) f->loopbase = l;
- BME_cycle_append(f->loopbase, l);
+ if(!(f->loopbase)) f->lbase = l;
+ BME_cycle_append(f->lbase, l);
}
/*take care of edge pointers and radial cycle*/
f->len = len;
/*Validation Loop cycle*/
- edok = BME_cycle_validate(len, f->loopbase);
+ edok = BME_cycle_validate(len, f->lbase);
if(!edok) BME_error();
for(i=0, l = f->loopbase; i<len; i++, l=l->next){
/*validate loop vert pointers*/
*/
int BME_KV(BME_Mesh *bm, BME_Vert *v){
- if(v->edge == NULL){
+ if(v->e == NULL){
BLI_remlink(&(bm->verts), v);
BME_free_vert(bm,v);
return 1;
int edok;
/*Make sure that no faces!*/
- if(e->loop == NULL){
+ if(e->l == NULL){
BME_disk_remove_edge(e, e->v1);
BME_disk_remove_edge(e, e->v2);
/*add validation to make sure that radial cycle is cleaned up ok*/
/*deal with radial cycle first*/
- len = BME_cycle_length(bply->loopbase);
+ len = BME_cycle_length(bply->lbase);
for(i=0, curloop=bply->loopbase; i < len; i++, curloop = curloop->next)
BME_radial_remove_loop(curloop, curloop->e);
/*now deallocate the editloops*/
for(i=0; i < len; i++){
- newbase = bply->loopbase->next;
- oldbase = bply->loopbase;
+ newbase = bply->lbase->next;
+ oldbase = bply->lbase;
BME_cycle_remove(oldbase, oldbase);
BME_free_loop(bm, oldbase);
bply->loopbase = newbase;
/*add ne to tv's disk cycle*/
BME_disk_append_edge(ne, tv);
/*verify disk cycles*/
- diskbase = BME_disk_getpointer(ov->edge,ov);
+ diskbase = BME_disk_getpointer(ov->e,ov);
edok = BME_cycle_validate(valance1, diskbase);
if(!edok) BME_error();
- diskbase = BME_disk_getpointer(tv->edge,tv);
+ diskbase = BME_disk_getpointer(tv->e,tv);
edok = BME_cycle_validate(valance2, diskbase);
if(!edok) BME_error();
- diskbase = BME_disk_getpointer(nv->edge,nv);
+ diskbase = BME_disk_getpointer(nv->e,nv);
edok = BME_cycle_validate(2, diskbase);
if(!edok) BME_error();
/*Split the radial cycle if present*/
- if(e->loop){
+ if(e->l){
BME_Loop *nl,*l;
BME_CycleNode *radEBase=NULL, *radNEBase=NULL;
- int radlen = BME_cycle_length(&(e->loop->radial));
+ int radlen = BME_cycle_length(&(e->l->radial));
/*Take the next loop. Remove it from radial. Split it. Append to appropriate radials.*/
- while(e->loop){
- l=e->loop;
+ while(e->l){
+ l=e->l;
l->f->len++;
BME_radial_remove_loop(l,e);
}
- e->loop = radEBase->data;
- ne->loop = radNEBase->data;
+ e->l = radEBase->data;
+ ne->l = radNEBase->data;
/*verify length of radial cycle*/
- edok = BME_cycle_validate(radlen,&(e->loop->radial));
+ edok = BME_cycle_validate(radlen,&(e->l->radial));
if(!edok) BME_error();
- edok = BME_cycle_validate(radlen,&(ne->loop->radial));
+ edok = BME_cycle_validate(radlen,&(ne->l->radial));
if(!edok) BME_error();
/*verify loop->v and loop->next->v pointers for e*/
- for(i=0,l=e->loop; i < radlen; i++, l = l->radial.next->data){
+ for(i=0,l=e->l; i < radlen; i++, l = l->radial_next){
if(!(l->e == e)) BME_error();
if(!(l->radial.data == l)) BME_error();
if(l->prev->e != ne && l->next->e != ne) BME_error();
if(l->v == l->next->v) BME_error();
if(l->e == l->next->e) BME_error();
/*verify loop cycle for kloop->f*/
- edok = BME_cycle_validate(l->f->len, l->f->loopbase);
+ edok = BME_cycle_validate(l->f->len, l->f->lbase);
if(!edok) BME_error();
}
/*verify loop->v and loop->next->v pointers for ne*/
- for(i=0,l=ne->loop; i < radlen; i++, l = l->radial.next->data){
+ for(i=0,l=ne->l; i < radlen; i++, l = l->radial_next){
if(!(l->e == ne)) BME_error();
if(!(l->radial.data == l)) BME_error();
if(l->prev->e != e && l->next->e != e) BME_error();
if(l->v == l->next->v) BME_error();
if(l->e == l->next->e) BME_error();
/*verify loop cycle for kloop->f. Redundant*/
- edok = BME_cycle_validate(l->f->len, l->f->loopbase);
+ edok = BME_cycle_validate(l->f->len, l->f->lbase);
if(!edok) BME_error();
}
}
/*verify that v1 and v2 are in face.*/
- len = BME_cycle_length(f->loopbase);
+ len = BME_cycle_length(f->lbase);
for(i = 0, curloop = f->loopbase; i < len; i++, curloop = curloop->next){
if(curloop->v == v1) v1loop = curloop;
else if(curloop->v == v2) v2loop = curloop;
/*I dont know how many loops are supposed to be in each face at this point! FIXME!*/
/*go through all of f2's loops and make sure they point to it properly.*/
- f2len = BME_cycle_length(f2->loopbase);
+ f2len = BME_cycle_length(f2->lbase);
for(i=0, curloop = f2->loopbase; i < f2len; i++, curloop = curloop->next) curloop->f = f2;
/*link up the new loops into the new edges radial*/
f2->len = f2len;
- f1len = BME_cycle_length(f->loopbase);
+ f1len = BME_cycle_length(f->lbase);
f->len = f1len;
if(rl) *rl = f2loop;
int len,radlen=0, halt = 0, i, valance1, valance2,edok;
if(BME_vert_in_edge(ke,kv) == 0) return 0;
- diskbase = BME_disk_getpointer(kv->edge, kv);
+ diskbase = BME_disk_getpointer(kv->e, kv);
len = BME_cycle_length(diskbase);
if(len == 2){
else{
/*For verification later, count valance of ov and tv*/
- diskbase = BME_disk_getpointer(ov->edge, ov);
+ diskbase = BME_disk_getpointer(ov->e, ov);
valance1 = BME_cycle_length(diskbase);
- diskbase = BME_disk_getpointer(tv->edge, tv);
+ diskbase = BME_disk_getpointer(tv->e, tv);
valance2 = BME_cycle_length(diskbase);
/*remove oe from kv's disk cycle*/
/*deal with radial cycle of ke*/
- if(ke->loop){
+ if(ke->l){
/*first step, fix the neighboring loops of all loops in ke's radial cycle*/
- radlen = BME_cycle_length(&(ke->loop->radial));
- for(i=0,killoop = ke->loop; i<radlen; i++, killoop = BME_radial_nextloop(killoop)){
+ radlen = BME_cycle_length(&(ke->l->radial));
+ for(i=0,killoop = ke->l; i<radlen; i++, killoop = BME_radial_nextloop(killoop)){
/*relink loops and fix vertex pointer*/
killoop->next->prev = killoop->prev;
killoop->prev->next = killoop->next;
/*fix len attribute of face*/
killoop->f->len--;
- if(killoop->f->loopbase == killoop) killoop->f->loopbase = killoop->next;
+ if(killoop->f->loopbase == killoop) killoop->f->lbase = killoop->next;
}
/*second step, remove all the hanging loops attached to ke*/
- killoop = ke->loop;
- radlen = BME_cycle_length(&(ke->loop->radial));
+ killoop = ke->l;
+ radlen = BME_cycle_length(&(ke->l->radial));
/*make sure we have enough room in bm->lpar*/
if(bm->lparlen < radlen){
MEM_freeN(bm->lpar);
i=0;
while(i<radlen){
bm->lpar[i] = killoop;
- killoop = killoop->radial.next->data;
+ killoop = killoop->radial_next;
i++;
}
i=0;
i++;
}
/*Validate radial cycle of oe*/
- edok = BME_cycle_validate(radlen,&(oe->loop->radial));
+ edok = BME_cycle_validate(radlen,&(oe->l->radial));
}
/*Validate disk cycles*/
- diskbase = BME_disk_getpointer(ov->edge,ov);
+ diskbase = BME_disk_getpointer(ov->e,ov);
edok = BME_cycle_validate(valance1, diskbase);
if(!edok) BME_error();
- diskbase = BME_disk_getpointer(tv->edge,tv);
+ diskbase = BME_disk_getpointer(tv->e,tv);
edok = BME_cycle_validate(valance2, diskbase);
if(!edok) BME_error();
/*Validate loop cycle of all faces attached to oe*/
- for(i=0,nextl = oe->loop; i<radlen; i++, nextl = BME_radial_nextloop(nextl)){
- edok = BME_cycle_validate(nextl->f->len,nextl->f->loopbase);
+ for(i=0,nextl = oe->l; i<radlen; i++, nextl = BME_radial_nextloop(nextl)){
+ edok = BME_cycle_validate(nextl->f->len,nextl->f->lbase);
if(!edok) BME_error();
}
/*deallocate edge*/
if(f1 == f2) return NULL; //can't join a face to itself
/*verify that e is in both f1 and f2*/
- f1len = BME_cycle_length(f1->loopbase);
- f2len = BME_cycle_length(f2->loopbase);
+ f1len = BME_cycle_length(f1->lbase);
+ f2len = BME_cycle_length(f2->lbase);
for(i=0, curloop = f1->loopbase; i < f1len; i++, curloop = curloop->next){
if(curloop->e == e){
f1loop = curloop;
f2loop->prev->next = f1loop->next;
/*if f1loop was baseloop, give f1loop->next the base.*/
- if(f1->loopbase == f1loop) f1->loopbase = f1loop->next;
+ if(f1->loopbase == f1loop) f1->lbase = f1loop->next;
/*validate the new loop*/
- loopok = BME_cycle_validate((f1len+f2len)-2, f1->loopbase);
+ loopok = BME_cycle_validate((f1len+f2len)-2, f1->lbase);
if(!loopok) BME_error();
/*make sure each loop points to the proper face*/
- newlen = BME_cycle_length(f1->loopbase);
+ newlen = BME_cycle_length(f1->lbase);
for(i = 0, curloop = f1->loopbase; i < newlen; i++, curloop = curloop->next) curloop->f = f1;
f1->len = newlen;
- edok = BME_cycle_validate(f1->len, f1->loopbase);
+ edok = BME_cycle_validate(f1->len, f1->lbase);
if(!edok) BME_error();
/*remove edge from the disk cycle of its two vertices.*/
BME_free_poly(bm, f2);
return f1;
}
+#endif
-/*
+#if 0
+/**
* BME_mesh.c jan 2007
*
* BMesh mesh level functions.
/*allocate the structure*/
BME_Mesh *bm = MEM_callocN(sizeof(BME_Mesh),"BMesh");
/*allocate the memory pools for the mesh elements*/
- bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], 0);
- bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], 0);
- bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], 0);
- bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], 0);
+ bm->vpool = BLI_mempool_create(sizeof(BME_Vert), allocsize[0], allocsize[0], 1, 0);
+ bm->epool = BLI_mempool_create(sizeof(BME_Edge), allocsize[1], allocsize[1], 1, 0);
+ bm->lpool = BLI_mempool_create(sizeof(BME_Loop), allocsize[2], allocsize[2], 1, 0);
+ bm->ppool = BLI_mempool_create(sizeof(BME_Poly), allocsize[3], allocsize[3], 1, 0);
return bm;
}
/*
do{
CustomData_bmesh_free_block(&bm->ldata, &l->data);
l = l->next;
- }while(l!=f->loopbase);
+ }while(l!=f->lbase);
}
/*Free custom data pools, This should probably go in CustomData_free?*/
if(e->v1 == e->v2) VHALT(halt);
/*validate e->d1.data and e->d2.data*/
if(e->d1.data != e || e->d2.data != e) VHALT(halt);
- /*validate e->loop->e*/
- if(e->loop){
- if(e->loop->e != e) VHALT(halt);
+ /*validate e->l->e*/
+ if(e->l){
+ if(e->l->e != e) VHALT(halt);
}
}
}
/*Validate vertices and disk cycle*/
for(v=bm->verts.first; v; v=v->next){
- /*validate v->edge pointer*/
+ /*validate v->e pointer*/
if(v->tflag1){
- if(v->edge){
- ok = BME_vert_in_edge(v->edge,v);
+ if(v->e){
+ ok = BME_vert_in_edge(v->e,v);
if(!ok) VHALT(halt);
/*validate length of disk cycle*/
- diskbase = BME_disk_getpointer(v->edge, v);
+ diskbase = BME_disk_getpointer(v->e, v);
ok = BME_cycle_validate(v->tflag1, diskbase);
if(!ok) VHALT(halt);
/*validate that each edge in disk cycle contains V*/
- for(i=0, e=v->edge; i < v->tflag1; i++, e = BME_disk_nextedge(e,v)){
+ for(i=0, e=v->e; i < v->tflag1; i++, e = BME_disk_nextedge(e,v)){
ok = BME_vert_in_edge(e, v);
if(!ok) VHALT(halt);
}
for(e=bm->edges.first; e; e=e->next) e->tflag2 = 0; //store incident faces
/*Validate the loop cycle integrity.*/
for(f=bm->polys.first; f; f=f->next){
- ok = BME_cycle_length(f->loopbase);
+ ok = BME_cycle_length(f->lbase);
if(ok > 1){
f->tflag1 = ok;
}
if(!ok) VHALT(halt);
/*verify radial node data pointer*/
if(l->radial.data != l) VHALT(halt);
- /*validate l->e->loop poitner*/
- if(l->e->loop == NULL) VHALT(halt);
+ /*validate l->e->l poitner*/
+ if(l->e->l == NULL) VHALT(halt);
/*validate l->f pointer*/
if(l->f != f) VHALT(halt);
- /*see if l->e->loop is actually in radial cycle*/
+ /*see if l->e->l is actually in radial cycle*/
l->e->tflag2++;
}
/*validate length of radial cycle*/
for(e=bm->edges.first; e; e=e->next){
- if(e->loop){
- ok = BME_cycle_validate(e->tflag2,&(e->loop->radial));
+ if(e->l){
+ ok = BME_cycle_validate(e->tflag2,&(e->l->radial));
if(!ok) VHALT(halt);
}
}
void BME_error(void){
printf("BME modelling error!");
}
+#endif
-/*
+#if 0
+/**
* BME_structure.c jan 2007
*
* Low level routines for manipulating the BMesh structure.
*
* ***** END GPL LICENSE BLOCK *****
*/
-
+#if 0
/** \file blender/blenkernel/intern/BME_structure.c
* \ingroup bke
*/
v->EID = bm->nextv;
v->co[0] = v->co[1] = v->co[2] = 0.0f;
v->no[0] = v->no[1] = v->no[2] = 0.0f;
- v->edge = NULL;
+ v->e = NULL;
v->data = NULL;
v->eflag1 = v->eflag2 = v->tflag1 = v->tflag2 = 0;
v->flag = v->h = 0;
e->d1.next = e->d1.prev = e->d2.next = e->d2.prev = NULL;
e->d1.data = e;
e->d2.data = e;
- e->loop = NULL;
+ e->l = NULL;
e->data = NULL;
e->eflag1 = e->eflag2 = e->tflag1 = e->tflag2 = 0;
e->flag = e->h = 0;
* BME_disk_getpointer
*
* 2: The Radial Cycle - A circle of face edges (BME_Loop) around an edge
- * Base: edge->loop->radial structure.
+ * Base: edge->l->radial structure.
*
* The radial cycle is similar to the radial cycle in the radial edge data structure.*
* Unlike the radial edge however, the radial cycle does not require a large amount of memory
*
*
* 3: The Loop Cycle - A circle of face edges around a polygon.
- * Base: polygon->loopbase.
+ * Base: polygon->lbase.
*
* The loop cycle keeps track of a faces vertices and edges. It should be noted that the
* direction of a loop cycle is either CW or CCW depending on the face normal, and is
if(BME_vert_in_edge(e, v) == 0) return 0; /*check to make sure v is in e*/
/*check for loose vert first*/
- if(v->edge == NULL){
- v->edge = e;
+ if(v->e == NULL){
+ v->e = e;
base = tail = BME_disk_getpointer(e, v);
BME_cycle_append(base, tail); /*circular reference is ok!*/
return 1;
}
- /*insert e at the end of disk cycle and make it the new v->edge*/
- base = BME_disk_getpointer(v->edge, v);
+ /*insert e at the end of disk cycle and make it the new v->e*/
+ base = BME_disk_getpointer(v->e, v);
tail = BME_disk_getpointer(e, v);
BME_cycle_append(base, tail);
return 1;
BME_Edge *newbase;
int len;
- base = BME_disk_getpointer(v->edge, v);
+ base = BME_disk_getpointer(v->e, v);
remnode = BME_disk_getpointer(e, v);
- /*first deal with v->edge pointer...*/
+ /*first deal with v->e pointer...*/
len = BME_cycle_length(base);
if(len == 1) newbase = NULL;
- else if(v->edge == e) newbase = base->next-> data;
- else newbase = v->edge;
+ else if(v->e == e) newbase = base->next-> data;
+ else newbase = v->e;
/*remove and rebase*/
BME_cycle_remove(base, remnode);
- v->edge = newbase;
+ v->e = newbase;
}
/**
BME_Edge *curedge;
int i, len=0, count=0;
- if(v->edge){
+ if(v->e){
if(eflag && tflag) return 0; /*tflag and eflag are reserved for different functions!*/
- diskbase = BME_disk_getpointer(v->edge, v);
+ diskbase = BME_disk_getpointer(v->e, v);
len = BME_cycle_length(diskbase);
- for(i = 0, curedge=v->edge; i<len; i++){
+ for(i = 0, curedge=v->e; i<len; i++){
if(tflag){
if(curedge->tflag1 == tflag) count++;
}
BME_Edge *curedge;
int i, len=0;
- if(v->edge){
- diskbase = BME_disk_getpointer(v->edge,v);
+ if(v->e){
+ diskbase = BME_disk_getpointer(v->e,v);
len = BME_cycle_length(diskbase);
- for(i = 0, curedge=v->edge; i<len; i++){
+ for(i = 0, curedge=v->e; i<len; i++){
if(curedge == e) return 1;
else curedge=BME_disk_nextedge(curedge, v);
}
/*end disk cycle routines*/
BME_Loop *BME_radial_nextloop(BME_Loop *l){
- return (BME_Loop*)(l->radial.next->data);
+ return (BME_Loop*)(l->radial_next);
}
void BME_radial_append(BME_Edge *e, BME_Loop *l){
- if(e->loop == NULL) e->loop = l;
- BME_cycle_append(&(e->loop->radial), &(l->radial));
+ if(e->l == NULL) e->l = l;
+ BME_cycle_append(&(e->l->radial), &(l->radial));
}
void BME_radial_remove_loop(BME_Loop *l, BME_Edge *e)
BME_Loop *newbase;
int len;
- /*deal with edge->loop pointer*/
- len = BME_cycle_length(&(e->loop->radial));
+ /*deal with edge->l pointer*/
+ len = BME_cycle_length(&(e->l->radial));
if(len == 1) newbase = NULL;
- else if(e->loop == l) newbase = e->loop->radial.next->data;
- else newbase = e->loop;
+ else if(e->l == l) newbase = e->l->radial_next;
+ else newbase = e->l;
/*remove and rebase*/
- BME_cycle_remove(&(e->loop->radial), &(l->radial));
- e->loop = newbase;
+ BME_cycle_remove(&(e->l->radial), &(l->radial));
+ e->l = newbase;
}
int BME_radial_find_face(BME_Edge *e,BME_Poly *f)
BME_Loop *curloop;
int i, len;
- len = BME_cycle_length(&(e->loop->radial));
- for(i = 0, curloop = e->loop; i < len; i++, curloop = curloop->radial.next->data){
+ len = BME_cycle_length(&(e->l->radial));
+ for(i = 0, curloop = e->l; i < len; i++, curloop = curloop->radial_next){
if(curloop->f == f) return 1;
}
return 0;
BME_Loop *l;
int i, len;
- len = BME_cycle_length(f->loopbase);
+ len = BME_cycle_length(f->lbase);
for (i = 0, l=f->loopbase; i < len; i++, l=l->next) {
if (l->v == v) return l;
}
return NULL;
}
+#endif
+#endif
-/*
+#if 0
+/**
* BME_tools.c jan 2007
*
* Functions for changing the topology of a mesh.
BME_Loop *l;
int len, count, flag;
- if (v->edge == NULL) {
+ if (v->e == NULL) {
/* loose vert */
return 1;
}
/* count edges while looking for non-manifold edges */
- oe = v->edge;
- for (len=0,e=v->edge; e != oe || (e == oe && len == 0); len++,e=BME_disk_nextedge(e,v)) {
- if (e->loop == NULL) {
+ oe = v->e;
+ for (len=0,e=v->e; e != oe || (e == oe && len == 0); len++,e=BME_disk_nextedge(e,v)) {
+ if (e->l == NULL) {
/* loose edge */
return 1;
}
- if (BME_cycle_length(&(e->loop->radial)) > 2) {
+ if (BME_cycle_length(&(e->l->radial)) > 2) {
/* edge shared by more than two faces */
return 1;
}
count = 1;
flag = 1;
e = NULL;
- oe = v->edge;
- l = oe->loop;
+ oe = v->e;
+ l = oe->l;
while(e != oe) {
if (l->v == v) l = l->prev;
else l = l->next;
e = l->e;
count++; /* count the edges */
- if (flag && l->radial.next->data == l) {
+ if (flag && l->radial_next == l) {
/* we've hit the edge of an open mesh, reset once */
flag = 0;
count = 1;
oe = e;
e = NULL;
- l = oe->loop;
+ l = oe->l;
}
- else if (l->radial.next->data == l) {
+ else if (l->radial_next == l) {
/* break the loop */
e = oe;
}
else {
- l = l->radial.next->data;
+ l = l->radial_next;
}
}
static BME_Poly *BME_JFKE_safe(BME_Mesh *bm, BME_Poly *f1, BME_Poly *f2, BME_Edge *e) {
BME_Loop *l1, *l2;
- l1 = e->loop;
- l2 = l1->radial.next->data;
+ l1 = e->l;
+ l2 = l1->radial_next;
if (l1->v == l2->v) {
BME_loop_reverse(bm, f2);
}
w[0] = 1.0f - fac;
w[1] = fac;
- if(!e1->loop) return;
- l = e1->loop;
+ if(!e1->l) return;
+ l = e1->l;
do{
if(l->v == v1){
v1loop = l;
src[1] = v2loop->data;
CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, vloop->data);
- l = l->radial.next->data;
- }while(l!=e1->loop);
+ l = l->radial_next;
+ }while(l!=e1->l);
}
w[0] = 1.0f - fac;
w[1] = fac;
- if(ke->loop){
- l = ke->loop;
+ if(ke->l){
+ l = ke->l;
do{
if(l->v == tv && l->next->v == kv){
tvloop = l;
src[1] = tvloop->data;
CustomData_bmesh_interp(&bm->ldata, src,w, NULL, 2, kvloop->data);
}
- l=l->radial.next->data;
- }while(l!=ke->loop);
+ l=l->radial_next;
+ }while(l!=ke->l);
}
BME_JEKV(bm,ke,kv);
}
* so... here we walk around edges to find the needed verts */
forward = 1;
is_split_vert = 0;
- if (v->edge == NULL) {
+ if (v->e == NULL) {
//printf("We can't split a loose vert's edge!\n");
return NULL;
}
- e1 = v->edge; /* we just use the first two edges */
- e2 = BME_disk_nextedge(v->edge, v);
+ e1 = v->e; /* we just use the first two edges */
+ e2 = BME_disk_nextedge(v->e, v);
if (e1 == e2) {
//printf("You need at least two edges to use BME_bevel_split_edge()\n");
return NULL;
static BME_Vert *BME_bevel_wire(BME_Mesh *bm, BME_Vert *v, float value, int res, int UNUSED(options), BME_TransData_Head *td) {
BME_Vert *ov1, *ov2, *v1, *v2;
- ov1 = BME_edge_getothervert(v->edge, v);
- ov2 = BME_edge_getothervert(BME_disk_nextedge(v->edge, v), v);
+ ov1 = BME_edge_getothervert(v->e, v);
+ ov2 = BME_edge_getothervert(BME_disk_nextedge(v->e, v), v);
/* split the edges */
v1 = BME_bevel_split_edge(bm,v,ov1,NULL,NULL,value,td);
/* remove the original vert */
if (res) {
- BME_JEKV(bm,v->edge,v);
+ BME_JEKV(bm,v->e,v);
}
return v1;
/* first, check to see if this edge was inset previously */
if ((l->prev->e->tflag1 & BME_BEVEL_ORIG) == 0
&& (l->v->tflag1 & BME_BEVEL_NONMAN) == 0) {
- kl = l->prev->radial.next->data;
+ kl = l->prev->radial_next;
if (kl->v == l->v) kl = kl->prev;
else kl = kl->next;
kv = l->v;
l = l->next;
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
- BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
+ BME_JFKE(bm,((BME_Loop*)kl->prev->radial_next)->f,kl->f,kl->prev->e);
BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
- BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
+ BME_JFKE(bm,((BME_Loop*)kl->next->radial_next)->f,kl->f,kl->next->e);
BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
}
/* first, check to see if this edge was inset previously */
if ((l->next->e->tflag1 & BME_BEVEL_ORIG) == 0
&& (l->next->v->tflag1 & BME_BEVEL_NONMAN) == 0) {
- kl = l->next->radial.next->data;
+ kl = l->next->radial_next;
if (kl->v == l->next->v) kl = kl->prev;
else kl = kl->next;
kv = l->next->v;
if (kv) {
if (kl->v == kv) {
BME_split_face(bm,kl->f,kl->prev->v,kl->next->v,&nl,kl->prev->e);
- BME_JFKE(bm,((BME_Loop*)kl->prev->radial.next->data)->f,kl->f,kl->prev->e);
+ BME_JFKE(bm,((BME_Loop*)kl->prev->radial_next)->f,kl->f,kl->prev->e);
BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
}
else {
BME_split_face(bm,kl->f,kl->next->next->v,kl->v,&nl,kl->next->e);
- BME_JFKE(bm,((BME_Loop*)kl->next->radial.next->data)->f,kl->f,kl->next->e);
+ BME_JFKE(bm,((BME_Loop*)kl->next->radial_next)->f,kl->f,kl->next->e);
BME_collapse_vert(bm, kl->e, kv, 1.0);
//BME_JEKV(bm,kl->e,kv);
}
if ((v1->tflag1 & BME_BEVEL_NONMAN)==0 || (v2->tflag1 & BME_BEVEL_NONMAN)==0) {
BME_split_face(bm,f,v2,v1,&l,e);
l->e->tflag1 = BME_BEVEL_BEVEL;
- l = l->radial.next->data;
+ l = l->radial_next;
}
if (l->f != f){
BME_Loop *l1, *l2;
float vec1[3], vec2[3], vec3[3], vec4[3];
- l1 = e->loop;
- l2 = e->loop->radial.next->data;
+ l1 = e->l;
+ l2 = e->l->radial_next;
if (l1->v == v) {
v1 = l1->prev->v;
v2 = l1->next->v;
do{
if(BME_radial_find_face(l->e,f2)) count++;
l = l->next;
- }while(l != f1->loopbase);
+ }while(l != f1->lbase);
return count;
}
*/
/* get disk cycle length */
- if (v->edge == NULL) {
+ if (v->e == NULL) {
len = 0;
}
else {
- len = BME_cycle_length(BME_disk_getpointer(v->edge,v));
+ len = BME_cycle_length(BME_disk_getpointer(v->e,v));
/* we'll assign a default transform data to every vert (except the loose ones) */
vtd = BME_assign_transdata(td, bm, v, v->co, v->co, NULL, NULL, 0, -1, -1, NULL);
}
* i.e. the vert's weight is the average of the weights of its weighted edges
*/
- if (e->loop == NULL) {
+ if (e->l == NULL) {
len = 0;
e->v1->tflag1 |= BME_BEVEL_NONMAN;
e->v2->tflag1 |= BME_BEVEL_NONMAN;
}
else {
- len = BME_cycle_length(&(e->loop->radial));
+ len = BME_cycle_length(&(e->l->radial));
}
if (len > 2) {
for (e=bm->edges.first; e; e=e->next){
if(e->tflag1 & BME_BEVEL_BEVEL){
int count = 0;
- count = BME_face_sharededges(e->loop->f, ((BME_Loop*)e->loop->radial.next->data)->f);
+ count = BME_face_sharededges(e->l->f, ((BME_Loop*)e->l->radial_next)->f);
if(count > 1){
e->tflag1 &= ~BME_BEVEL_BEVEL;
}
BME_Edge *e;
int done, len;
- if(v->edge){
+ if(v->e){
done = 0;
while(!done){
done = 1;
- e = v->edge; /*loop the edge looking for a edge to dissolve*/
+ e = v->e; /*loop the edge looking for a edge to dissolve*/
do{
f = NULL;
- len = BME_cycle_length(&(e->loop->radial));
+ len = BME_cycle_length(&(e->l->radial));
if(len == 2){
- f = BME_JFKE_safe(bm,e->loop->f, ((BME_Loop*)(e->loop->radial.next->data))->f, e);
+ f = BME_JFKE_safe(bm,e->l->f, ((BME_Loop*)(e->l->radial_next))->f, e);
}
if(f){
done = 0;
break;
}
e = BME_disk_nextedge(e,v);
- }while(e != v->edge);
+ }while(e != v->e);
}
- BME_collapse_vert(bm, v->edge, v, 1.0);
- //BME_JEKV(bm,v->edge,v);
+ BME_collapse_vert(bm, v->e, v, 1.0);
+ //BME_JEKV(bm,v->e,v);
}
}
static BME_Mesh *BME_bevel_mesh(BME_Mesh *bm, float value, int res, int options, int UNUSED(defgrp_index), BME_TransData_Head *td) {
else if (res && ((v->tflag1 & BME_BEVEL_BEVEL) && (v->tflag1 & BME_BEVEL_ORIG))) {
int count = 0;
/* first, make sure we're not sitting on an edge to be removed */
- oe = v->edge;
+ oe = v->e;
e = BME_disk_nextedge(oe,v);
while ((e->tflag1 & BME_BEVEL_BEVEL) && (e->tflag1 & BME_BEVEL_ORIG)) {
e = BME_disk_nextedge(e,v);
while ( (e = BME_disk_next_edgeflag(oe, v, 0, BME_BEVEL_ORIG | BME_BEVEL_BEVEL)) ) {
count++;
/* join the faces (we'll split them later) */
- f = BME_JFKE_safe(bm,e->loop->f,((BME_Loop*)e->loop->radial.next->data)->f,e);
+ f = BME_JFKE_safe(bm,e->l->f,((BME_Loop*)e->l->radial_next)->f,e);
if (!f){
//printf("Non-manifold geometry not getting tagged right?\n");
}
/* all original edges marked to be beveled have been removed;
* now we need to link up the edges for this "corner" */
- len = BME_cycle_length(BME_disk_getpointer(v->edge, v));
- for (i=0,e=v->edge; i < len; i++,e=BME_disk_nextedge(e,v)) {
- l = e->loop;
- l2 = l->radial.next->data;
+ len = BME_cycle_length(BME_disk_getpointer(v->e, v));
+ for (i=0,e=v->e; i < len; i++,e=BME_disk_nextedge(e,v)) {
+ l = e->l;
+ l2 = l->radial_next;
if (l->v != v) l = l->next;
if (l2->v != v) l2 = l2->next;
/* look for faces that have had the original edges removed via JFKE */
BME_free_transdata(td);
return bm;
}
+#endif
#include <string.h>
-
+#include "limits.h"
#include "MEM_guardedalloc.h"
#include "BLI_editVert.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
+#include "BLI_array.h"
#include "BLI_pbvh.h"
#include "BLI_utildefines.h"
#include "BKE_paint.h"
#include "BKE_texture.h"
#include "BKE_multires.h"
+#include "BKE_particle.h"
+#include "BKE_tessmesh.h"
+#include "BKE_bvhutils.h"
#include "BLO_sys_types.h" // for intptr_t support
#include "ED_sculpt.h" /* for ED_sculpt_modifiers_changed */
-///////////////////////////////////
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
+
+ ///////////////////////////////////
///////////////////////////////////
static MVert *dm_getVertArray(DerivedMesh *dm)
if (!mface) {
mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL,
- dm->getNumFaces(dm));
+ dm->getNumTessFaces(dm));
CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
- dm->copyFaceArray(dm, mface);
+ dm->copyTessFaceArray(dm, mface);
}
return mface;
}
+static MLoop *dm_getLoopArray(DerivedMesh *dm)
+{
+ MLoop *mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
+
+ if (!mloop) {
+ mloop = CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL,
+ dm->numLoopData);
+ CustomData_set_layer_flag(&dm->loopData, CD_MLOOP, CD_FLAG_TEMPORARY);
+ dm->copyLoopArray(dm, mloop);
+ }
+
+ return mloop;
+}
+
+static MPoly *dm_getPolyArray(DerivedMesh *dm)
+{
+ MPoly *mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
+
+ if (!mpoly) {
+ mpoly = CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL,
+ dm->getNumFaces(dm));
+ CustomData_set_layer_flag(&dm->polyData, CD_MPOLY, CD_FLAG_TEMPORARY);
+ dm->copyPolyArray(dm, mpoly);
+ }
+
+ return mpoly;
+}
+
static MVert *dm_dupVertArray(DerivedMesh *dm)
{
MVert *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumVerts(dm),
static MFace *dm_dupFaceArray(DerivedMesh *dm)
{
- MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
+ MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
"dm_dupFaceArray tmp");
- if(tmp) dm->copyFaceArray(dm, tmp);
+ if(tmp) dm->copyTessFaceArray(dm, tmp);
+
+ return tmp;
+}
+
+static MLoop *dm_dupLoopArray(DerivedMesh *dm)
+{
+ MLoop *tmp = MEM_callocN(sizeof(*tmp) * dm->numLoopData,
+ "dm_dupLoopArray tmp");
+
+ if(tmp) dm->copyLoopArray(dm, tmp);
return tmp;
}
+static MPoly *dm_dupPolyArray(DerivedMesh *dm)
+{
+ MPoly *tmp = MEM_callocN(sizeof(*tmp) * dm->numFaceData,
+ "dm_dupPolyArray tmp");
+
+ if(tmp) dm->copyPolyArray(dm, tmp);
+
+ return tmp;
+}
+
+static CustomData *dm_getVertCData(DerivedMesh *dm)
+{
+ return &dm->vertData;
+}
+
+static CustomData *dm_getEdgeCData(DerivedMesh *dm)
+{
+ return &dm->edgeData;
+}
+
+static CustomData *dm_getFaceCData(DerivedMesh *dm)
+{
+ return &dm->faceData;
+}
+
+static CustomData *dm_getLoopCData(DerivedMesh *dm)
+{
+ return &dm->loopData;
+}
+
+static CustomData *dm_getPolyCData(DerivedMesh *dm)
+{
+ return &dm->polyData;
+}
+
void DM_init_funcs(DerivedMesh *dm)
{
/* default function implementations */
dm->getVertArray = dm_getVertArray;
dm->getEdgeArray = dm_getEdgeArray;
- dm->getFaceArray = dm_getFaceArray;
+ dm->getTessFaceArray = dm_getFaceArray;
+ dm->getLoopArray = dm_getLoopArray;
+ dm->getPolyArray = dm_getPolyArray;
dm->dupVertArray = dm_dupVertArray;
dm->dupEdgeArray = dm_dupEdgeArray;
- dm->dupFaceArray = dm_dupFaceArray;
+ dm->dupTessFaceArray = dm_dupFaceArray;
+ dm->dupLoopArray = dm_dupLoopArray;
+ dm->dupPolyArray = dm_dupPolyArray;
+
+ dm->getVertDataLayout = dm_getVertCData;
+ dm->getEdgeDataLayout = dm_getEdgeCData;
+ dm->getTessFaceDataLayout = dm_getFaceCData;
+ dm->getLoopDataLayout = dm_getLoopCData;
+ dm->getFaceDataLayout = dm_getPolyCData;
dm->getVertData = DM_get_vert_data;
dm->getEdgeData = DM_get_edge_data;
- dm->getFaceData = DM_get_face_data;
+ dm->getTessFaceData = DM_get_face_data;
dm->getVertDataArray = DM_get_vert_data_layer;
dm->getEdgeDataArray = DM_get_edge_data_layer;
- dm->getFaceDataArray = DM_get_face_data_layer;
+ dm->getTessFaceDataArray = DM_get_tessface_data_layer;
bvhcache_init(&dm->bvhCache);
}
-void DM_init(DerivedMesh *dm, DerivedMeshType type,
- int numVerts, int numEdges, int numFaces)
+void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges,
+ int numFaces, int numLoops, int numPoly)
{
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
dm->numFaceData = numFaces;
+ dm->numLoopData = numLoops;
+ dm->numPolyData = numPoly;
DM_init_funcs(dm);
}
void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
- int numVerts, int numEdges, int numFaces)
+ int numVerts, int numEdges, int numFaces,
+ int numLoops, int numPolys)
{
CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numVerts);
CD_CALLOC, numEdges);
CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
CD_CALLOC, numFaces);
+ CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, numLoops);
+ CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
+ CD_CALLOC, numPolys);
dm->type = type;
dm->numVertData = numVerts;
dm->numEdgeData = numEdges;
dm->numFaceData = numFaces;
+ dm->numLoopData = numLoops;
+ dm->numPolyData = numPolys;
DM_init_funcs(dm);
CustomData_free(&dm->vertData, dm->numVertData);
CustomData_free(&dm->edgeData, dm->numEdgeData);
CustomData_free(&dm->faceData, dm->numFaceData);
+ CustomData_free(&dm->loopData, dm->numLoopData);
+ CustomData_free(&dm->polyData, dm->numPolyData);
return 1;
}
CustomData_free_temporary(&dm->vertData, dm->numVertData);
CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
CustomData_free_temporary(&dm->faceData, dm->numFaceData);
+ CustomData_free_temporary(&dm->loopData, dm->numLoopData);
+ CustomData_free_temporary(&dm->polyData, dm->numPolyData);
return 0;
}
}
-void DM_to_mesh(DerivedMesh *dm, Mesh *me)
+void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
+{
+ CustomData_copy(&source->loopData, &target->loopData, CD_MASK_DERIVEDMESH, CD_CALLOC, source->numLoopData);
+ CustomData_copy(&source->polyData, &target->polyData, CD_MASK_DERIVEDMESH, CD_CALLOC, source->numPolyData);
+
+ target->numLoopData = source->numLoopData;
+ target->numPolyData = source->numPolyData;
+
+ if (!CustomData_has_layer(&target->polyData, CD_MPOLY)) {
+ MPoly *mpoly;
+ MLoop *mloop;
+
+ mloop = source->dupLoopArray(source);
+ mpoly = source->dupPolyArray(source);
+ CustomData_add_layer(&target->loopData, CD_MLOOP, CD_ASSIGN, mloop, source->numLoopData);
+ CustomData_add_layer(&target->polyData, CD_MPOLY, CD_ASSIGN, mpoly, source->numPolyData);
+ }
+}
+
+void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
{
/* dm might depend on me, so we need to do everything with a local copy */
Mesh tmp = *me;
- int totvert, totedge, totface;
-
+ int totvert, totedge, totface, totloop, totpoly;
+ int did_shapekeys=0;
+
memset(&tmp.vdata, 0, sizeof(tmp.vdata));
memset(&tmp.edata, 0, sizeof(tmp.edata));
memset(&tmp.fdata, 0, sizeof(tmp.fdata));
+ memset(&tmp.ldata, 0, sizeof(tmp.ldata));
+ memset(&tmp.pdata, 0, sizeof(tmp.pdata));
totvert = tmp.totvert = dm->getNumVerts(dm);
totedge = tmp.totedge = dm->getNumEdges(dm);
- totface = tmp.totface = dm->getNumFaces(dm);
+ totface = tmp.totface = dm->getNumTessFaces(dm);
+ totpoly = tmp.totpoly = dm->getNumFaces(dm);
+ totloop = tmp.totloop = dm->numLoopData;
CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface);
+ CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
+ CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
+ if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) {
+ KeyBlock *kb;
+ int i=0;
+
+ if (ob) {
+ for (kb=me->key->block.first; kb; kb=kb->next, i++) {
+ if (i == ob->shapenr-1) {
+ i = kb->uid;
+ break;
+ }
+ }
+
+ if (!kb) {
+ printf("error in DM_to_mesh: could not find active shapekey! eek!!\n");
+ i = INT_MAX;
+ }
+ } else {
+ /*if no object, set to INT_MAX so we don't mess up any shapekey layers*/
+ i = INT_MAX;
+ }
+
+ shapekey_layers_to_keyblocks(dm, me, i);
+ did_shapekeys = 1;
+ }
+
/* not all DerivedMeshes store their verts/edges/faces in CustomData, so
we set them here in case they are missing */
if(!CustomData_has_layer(&tmp.vdata, CD_MVERT))
if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
- CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
+ CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupTessFaceArray(dm), totface);
+ if(!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
+ tmp.mloop = dm->dupLoopArray(dm);
+ tmp.mpoly = dm->dupPolyArray(dm);
+
+ CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
+ CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
+ }
/* object had got displacement layer, should copy this layer to save sculpted data */
/* NOTE: maybe some other layers should be copied? nazgul */
- if(CustomData_has_layer(&me->fdata, CD_MDISPS)) {
- if (totface == me->totface) {
- MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
- CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface);
+ if(CustomData_has_layer(&me->ldata, CD_MDISPS)) {
+ if (totloop == me->totloop) {
+ MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+ CustomData_add_layer(&tmp.ldata, CD_MDISPS, CD_DUPLICATE, mdisps, totloop);
}
}
CustomData_free(&me->vdata, me->totvert);
CustomData_free(&me->edata, me->totedge);
CustomData_free(&me->fdata, me->totface);
-
- /* if the number of verts has changed, remove invalid data */
- if(tmp.totvert != me->totvert) {
+ CustomData_free(&me->ldata, me->totloop);
+ CustomData_free(&me->pdata, me->totpoly);
+
+ /* ok, this should now use new CD shapekey data,
+ which shouuld be fed through the modifier
+ stack*/
+ if(tmp.totvert != me->totvert && !did_shapekeys && me->key) {
+ printf("YEEK! this should be recoded! Shape key loss!!!\n");
if(tmp.key) tmp.key->id.us--;
tmp.key = NULL;
}
CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
}
-void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+void DM_add_tessface_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
{
CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData);
}
+static void DM_add_loop_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+ CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData);
+}
+
+void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+ CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData);
+}
+
void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
{
return CustomData_get(&dm->vertData, index, type);
return CustomData_get_layer(&dm->edgeData, type);
}
-void *DM_get_face_data_layer(DerivedMesh *dm, int type)
+void *DM_get_tessface_data_layer(DerivedMesh *dm, int type)
{
if(type == CD_MFACE)
- return dm->getFaceArray(dm);
+ return dm->getTessFaceArray(dm);
return CustomData_get_layer(&dm->faceData, type);
}
+void *DM_get_face_data_layer(DerivedMesh *dm, int type)
+{
+ return CustomData_get_layer(&dm->polyData, type);
+}
+
void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
{
CustomData_set(&dm->vertData, index, type, data);
source_index, dest_index, count);
}
-void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_copy_tessface_data(DerivedMesh *source, DerivedMesh *dest,
int source_index, int dest_index, int count)
{
CustomData_copy_data(&source->faceData, &dest->faceData,
source_index, dest_index, count);
}
+void DM_copy_loop_data(DerivedMesh *source, DerivedMesh *dest,
+ int source_index, int dest_index, int count)
+{
+ CustomData_copy_data(&source->loopData, &dest->loopData,
+ source_index, dest_index, count);
+}
+
+void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
+ int source_index, int dest_index, int count)
+{
+ CustomData_copy_data(&source->polyData, &dest->polyData,
+ source_index, dest_index, count);
+}
+
void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
{
CustomData_free_elem(&dm->vertData, index, count);
CustomData_free_elem(&dm->edgeData, index, count);
}
-void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
+void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count)
{
CustomData_free_elem(&dm->faceData, index, count);
}
+void DM_free_loop_data(struct DerivedMesh *dm, int index, int count)
+{
+ CustomData_free_elem(&dm->loopData, index, count);
+}
+
+void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
+{
+ CustomData_free_elem(&dm->polyData, index, count);
+}
+
void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
int *src_indices, float *weights,
int count, int dest_index)
weights, (float*)vert_weights, count, dest_index);
}
-void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_interp_tessface_data(DerivedMesh *source, DerivedMesh *dest,
int *src_indices,
float *weights, FaceVertWeight *vert_weights,
int count, int dest_index)
weights, (float*)vert_weights, count, dest_index);
}
-void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices)
+void DM_swap_tessface_data(DerivedMesh *dm, int index, const int *corner_indices)
{
CustomData_swap(&dm->faceData, index, corner_indices);
}
-///
+void DM_interp_loop_data(DerivedMesh *source, DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index)
+{
+ CustomData_interp(&source->loopData, &dest->loopData, src_indices,
+ weights, NULL, count, dest_index);
+}
+void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
+ int *src_indices,
+ float *weights, int count, int dest_index)
+{
+ CustomData_interp(&source->polyData, &dest->polyData, src_indices,
+ weights, NULL, count, dest_index);
+}
+
+///
DerivedMesh *mesh_create_derived(Mesh *me, Object *ob, float (*vertCos)[3])
{
DerivedMesh *dm = CDDM_from_mesh(me, ob);
return dm;
}
-///
-
-typedef struct {
- DerivedMesh dm;
-
- EditMesh *em;
- float (*vertexCos)[3];
- float (*vertexNos)[3];
- float (*faceNos)[3];
-} EditMeshDerivedMesh;
-
-static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *eve;
- int i;
-
- for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
- if (emdm->vertexCos) {
- func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
- } else {
- func(userData, i, eve->co, eve->no, NULL);
- }
- }
-}
-static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditEdge *eed;
- int i;
-
- if (emdm->vertexCos) {
- EditVert *eve;
-
- for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
- func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
- } else {
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
- func(userData, i, eed->v1->co, eed->v2->co);
- }
-}
-static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditEdge *eed;
- int i;
-
- if (emdm->vertexCos) {
- EditVert *eve;
-
- for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
- glBegin(GL_LINES);
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
- }
- }
- glEnd();
- } else {
- glBegin(GL_LINES);
- for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- glVertex3fv(eed->v1->co);
- glVertex3fv(eed->v2->co);
- }
- }
- glEnd();
- }
-}
-static void emDM_drawEdges(DerivedMesh *dm, int UNUSED(drawLooseEdges), int UNUSED(drawAllEdges))
-{
- emDM_drawMappedEdges(dm, NULL, NULL);
-}
-static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditEdge *eed;
- int i;
-
- if (emdm->vertexCos) {
- EditVert *eve;
-
- for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
- glBegin(GL_LINES);
- for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- setDrawInterpOptions(userData, i, 0.0);
- glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
- setDrawInterpOptions(userData, i, 1.0);
- glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
- }
- }
- glEnd();
- } else {
- glBegin(GL_LINES);
- for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
- if(!setDrawOptions || setDrawOptions(userData, i)) {
- setDrawInterpOptions(userData, i, 0.0);
- glVertex3fv(eed->v1->co);
- setDrawInterpOptions(userData, i, 1.0);
- glVertex3fv(eed->v2->co);
- }
- }
- glEnd();
- }
-}
-
-static void emDM_drawUVEdges(DerivedMesh *dm)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditFace *efa;
- MTFace *tf;
-
- glBegin(GL_LINES);
- for(efa= emdm->em->faces.first; efa; efa= efa->next) {
- tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
-
- if(tf && !(efa->h)) {
- glVertex2fv(tf->uv[0]);
- glVertex2fv(tf->uv[1]);
-
- glVertex2fv(tf->uv[1]);
- glVertex2fv(tf->uv[2]);
-
- if (!efa->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]);
- }
- }
- }
- glEnd();
-}
-
-static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
-{
- if (vertexCos) {
- VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]);
- add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]);
- add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]);
- if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]);
- } else {
- VECCOPY(cent, efa->v1->co);
- add_v3_v3(cent, efa->v2->co);
- add_v3_v3(cent, efa->v3->co);
- if (efa->v4) add_v3_v3(cent, efa->v4->co);
- }
-
- if (efa->v4) {
- mul_v3_fl(cent, 0.25f);
- } else {
- mul_v3_fl(cent, 0.33333333333f);
- }
-}
-static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *eve;
- EditFace *efa;
- float cent[3];
- int i;
-
- if (emdm->vertexCos) {
- for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
- }
-
- for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
- emDM__calcFaceCent(efa, cent, emdm->vertexCos);
- func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
- }
-}
-
-/* note, material function is ignored for now. */
-static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs))
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditFace *efa;
- int i, draw;
-
- (void)setMaterial; /* unused */
-
- if (emdm->vertexCos) {
- EditVert *eve;
-
- for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
- for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
- if(draw) {
- if (draw==2) { /* enabled with stipple */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
-
- glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(emdm->faceNos[i]);
- glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
- if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
- } else {
- glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
- glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
- glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
- if(efa->v4) {
- glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]);
- glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
- }
- }
- glEnd();
-
- if (draw==2)
- glDisable(GL_POLYGON_STIPPLE);
- }
- }
- } else {
- for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth = (efa->flag & ME_SMOOTH);
- draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
- if(draw) {
- if (draw==2) { /* enabled with stipple */
- glEnable(GL_POLYGON_STIPPLE);
- glPolygonStipple(stipple_quarttone);
- }
- glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(efa->n);
- glVertex3fv(efa->v1->co);
- glVertex3fv(efa->v2->co);
- glVertex3fv(efa->v3->co);
- if(efa->v4) glVertex3fv(efa->v4->co);
- } else {
- glNormal3fv(efa->v1->no);
- glVertex3fv(efa->v1->co);
- glNormal3fv(efa->v2->no);
- glVertex3fv(efa->v2->co);
- glNormal3fv(efa->v3->no);
- glVertex3fv(efa->v3->co);
- if(efa->v4) {
- glNormal3fv(efa->v4->no);
- glVertex3fv(efa->v4->co);
- }
- }
- glEnd();
-
- if (draw==2)
- glDisable(GL_POLYGON_STIPPLE);
- }
- }
- }
-}
-
-static void emDM_drawFacesTex_common(DerivedMesh *dm,
- int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
- int (*drawParamsMapped)(void *userData, int index),
- void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditMesh *em= emdm->em;
- float (*vertexCos)[3]= emdm->vertexCos;
- float (*vertexNos)[3]= emdm->vertexNos;
- EditFace *efa;
- int i;
-
- /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
- glShadeModel(GL_SMOOTH);
-
- if (vertexCos) {
- EditVert *eve;
-
- for (i=0,eve=em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
- for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
- MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
- unsigned char *cp= NULL;
- int drawSmooth= (efa->flag & ME_SMOOTH);
- int flag;
-
- if(drawParams)
- flag= drawParams(tf, mcol, efa->mat_nr);
- else if(drawParamsMapped)
- flag= drawParamsMapped(userData, i);
- else
- flag= 1;
-
- if(flag != 0) { /* flag 0 == the face is hidden or invisible */
-
- /* we always want smooth here since otherwise vertex colors dont interpolate */
- if (mcol) {
- if (flag==1) {
- cp= (unsigned char*)mcol;
- }
- } else {
- glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
- }
-
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(emdm->faceNos[i]);
-
- if(tf) glTexCoord2fv(tf->uv[0]);
- if(cp) glColor3ub(cp[3], cp[2], cp[1]);
- glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-
- if(tf) glTexCoord2fv(tf->uv[1]);
- if(cp) glColor3ub(cp[7], cp[6], cp[5]);
- glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-
- if(tf) glTexCoord2fv(tf->uv[2]);
- if(cp) glColor3ub(cp[11], cp[10], cp[9]);
- glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-
- if(efa->v4) {
- if(tf) glTexCoord2fv(tf->uv[3]);
- if(cp) glColor3ub(cp[15], cp[14], cp[13]);
- glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
- }
- } else {
- if(tf) glTexCoord2fv(tf->uv[0]);
- if(cp) glColor3ub(cp[3], cp[2], cp[1]);
- glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-
- if(tf) glTexCoord2fv(tf->uv[1]);
- if(cp) glColor3ub(cp[7], cp[6], cp[5]);
- glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-
- if(tf) glTexCoord2fv(tf->uv[2]);
- if(cp) glColor3ub(cp[11], cp[10], cp[9]);
- glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-
- if(efa->v4) {
- if(tf) glTexCoord2fv(tf->uv[3]);
- if(cp) glColor3ub(cp[15], cp[14], cp[13]);
- glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
- }
- }
- glEnd();
- }
- }
- } else {
- for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
- MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
- MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
- unsigned char *cp= NULL;
- int drawSmooth= (efa->flag & ME_SMOOTH);
- int flag;
-
- if(drawParams)
- flag= drawParams(tf, mcol, efa->mat_nr);
- else if(drawParamsMapped)
- flag= drawParamsMapped(userData, i);
- else
- flag= 1;
-
- if(flag != 0) { /* flag 0 == the face is hidden or invisible */
- /* we always want smooth here since otherwise vertex colors dont interpolate */
- if (mcol) {
- if (flag==1) {
- cp= (unsigned char*)mcol;
- }
- } else {
- glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
- }
-
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- glNormal3fv(efa->n);
-
- if(tf) glTexCoord2fv(tf->uv[0]);
- if(cp) glColor3ub(cp[3], cp[2], cp[1]);
- glVertex3fv(efa->v1->co);
-
- if(tf) glTexCoord2fv(tf->uv[1]);
- if(cp) glColor3ub(cp[7], cp[6], cp[5]);
- glVertex3fv(efa->v2->co);
-
- if(tf) glTexCoord2fv(tf->uv[2]);
- if(cp) glColor3ub(cp[11], cp[10], cp[9]);
- glVertex3fv(efa->v3->co);
-
- if(efa->v4) {
- if(tf) glTexCoord2fv(tf->uv[3]);
- if(cp) glColor3ub(cp[15], cp[14], cp[13]);
- glVertex3fv(efa->v4->co);
- }
- } else {
- if(tf) glTexCoord2fv(tf->uv[0]);
- if(cp) glColor3ub(cp[3], cp[2], cp[1]);
- glNormal3fv(efa->v1->no);
- glVertex3fv(efa->v1->co);
-
- if(tf) glTexCoord2fv(tf->uv[1]);
- if(cp) glColor3ub(cp[7], cp[6], cp[5]);
- glNormal3fv(efa->v2->no);
- glVertex3fv(efa->v2->co);
-
- if(tf) glTexCoord2fv(tf->uv[2]);
- if(cp) glColor3ub(cp[11], cp[10], cp[9]);
- glNormal3fv(efa->v3->no);
- glVertex3fv(efa->v3->co);
-
- if(efa->v4) {
- if(tf) glTexCoord2fv(tf->uv[3]);
- if(cp) glColor3ub(cp[15], cp[14], cp[13]);
- glNormal3fv(efa->v4->no);
- glVertex3fv(efa->v4->co);
- }
- }
- glEnd();
- }
- }
- }
-}
-
-static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
-{
- emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
-}
-
-static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
-{
- emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
-}
-
-static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
- int (*setMaterial)(int, void *attribs),
- int (*setDrawOptions)(void *userData, int index), void *userData)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditMesh *em= emdm->em;
- float (*vertexCos)[3]= emdm->vertexCos;
- float (*vertexNos)[3]= emdm->vertexNos;
- EditVert *eve;
- EditFace *efa;
- DMVertexAttribs attribs= {{{0}}};
- GPUVertexAttribs gattribs;
- MTFace *tf;
- int transp, new_transp, orig_transp, tfoffset;
- int i, b, matnr, new_matnr, dodraw, layer;
-
- dodraw = 0;
- matnr = -1;
-
- transp = GPU_get_material_blend_mode();
- orig_transp = transp;
- layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE);
- tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset;
-
- /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
- glShadeModel(GL_SMOOTH);
-
- for (i=0,eve=em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
-#define PASSATTRIB(efa, eve, vert) { \
- if(attribs.totorco) { \
- float *orco = attribs.orco.array[eve->tmp.l]; \
- glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
- } \
- for(b = 0; b < attribs.tottface; b++) { \
- MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \
- glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \
- } \
- for(b = 0; b < attribs.totmcol; b++) { \
- MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
- 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[i*4 + vert]; \
- glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
- } \
-}
-
- for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
- int drawSmooth= (efa->flag & ME_SMOOTH);
-
- if(setDrawOptions && !setDrawOptions(userData, i))
- continue;
-
- new_matnr = efa->mat_nr + 1;
- if(new_matnr != matnr) {
- dodraw = setMaterial(matnr = new_matnr, &gattribs);
- if(dodraw)
- DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
- }
-
- if(tfoffset != -1) {
- tf = (MTFace*)((char*)efa->data)+tfoffset;
- new_transp = tf->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;
- }
- }
-
- if(dodraw) {
- glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
- if (!drawSmooth) {
- if(vertexCos) glNormal3fv(emdm->faceNos[i]);
- else glNormal3fv(efa->n);
-
- PASSATTRIB(efa, efa->v1, 0);
- if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
- else glVertex3fv(efa->v1->co);
-
- PASSATTRIB(efa, efa->v2, 1);
- if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
- else glVertex3fv(efa->v2->co);
-
- PASSATTRIB(efa, efa->v3, 2);
- if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
- else glVertex3fv(efa->v3->co);
-
- if(efa->v4) {
- PASSATTRIB(efa, efa->v4, 3);
- if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
- else glVertex3fv(efa->v4->co);
- }
- } else {
- PASSATTRIB(efa, efa->v1, 0);
- if(vertexCos) {
- glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
- }
- else {
- glNormal3fv(efa->v1->no);
- glVertex3fv(efa->v1->co);
- }
-
- PASSATTRIB(efa, efa->v2, 1);
- if(vertexCos) {
- glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
- }
- else {
- glNormal3fv(efa->v2->no);
- glVertex3fv(efa->v2->co);
- }
-
- PASSATTRIB(efa, efa->v3, 2);
- if(vertexCos) {
- glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
- }
- else {
- glNormal3fv(efa->v3->no);
- glVertex3fv(efa->v3->co);
- }
-
- if(efa->v4) {
- PASSATTRIB(efa, efa->v4, 3);
- if(vertexCos) {
- glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
- glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
- }
- else {
- glNormal3fv(efa->v4->no);
- glVertex3fv(efa->v4->co);
- }
- }
- }
- glEnd();
- }
- }
-}
-
-static void emDM_drawFacesGLSL(DerivedMesh *dm,
- int (*setMaterial)(int, void *attribs))
-{
- dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
-}
-
-static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *eve;
- int i;
-
- if (emdm->em->verts.first) {
- for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
- if (emdm->vertexCos) {
- DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
- } else {
- DO_MINMAX(eve->co, min_r, max_r);
- }
- }
- } else {
- min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
- }
-}
-static int emDM_getNumVerts(DerivedMesh *dm)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
- return BLI_countlist(&emdm->em->verts);
-}
-
-static int emDM_getNumEdges(DerivedMesh *dm)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
- return BLI_countlist(&emdm->em->edges);
-}
-
-static int emDM_getNumFaces(DerivedMesh *dm)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
- return BLI_countlist(&emdm->em->faces);
-}
-
-static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *eve;
- int i;
-
- for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
- if (emdm->vertexCos) {
- copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
- } else {
- copy_v3_v3(cos_r[i], eve->co);
- }
- }
-}
-
-static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
-{
- EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
- int i;
-
- for(i = 0; i < index; ++i) ev = ev->next;
-
- VECCOPY(vert_r->co, ev->co);
-
- normal_float_to_short_v3(vert_r->no, ev->no);
-
- /* TODO what to do with vert_r->flag? */
- vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
-}
-
-static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
-{
- EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
- EditEdge *ee = em->edges.first;
- EditVert *ev, *v1, *v2;
- int i;
-
- for(i = 0; i < index; ++i) ee = ee->next;
-
- edge_r->crease = (unsigned char) (ee->crease*255.0f);
- edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
- /* TODO what to do with edge_r->flag? */
- edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
- if (ee->seam) edge_r->flag |= ME_SEAM;
- if (ee->sharp) edge_r->flag |= ME_SHARP;
-#if 0
- /* this needs setup of f2 field */
- if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
-#endif
-
- /* goddamn, we have to search all verts to find indices */
- v1 = ee->v1;
- v2 = ee->v2;
- for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
- if(ev == v1) {
- edge_r->v1 = i;
- v1 = NULL;
- }
- if(ev == v2) {
- edge_r->v2 = i;
- v2 = NULL;
- }
- }
-}
-
-static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
-{
- EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
- EditFace *ef = em->faces.first;
- EditVert *ev, *v1, *v2, *v3, *v4;
- int i;
-
- for(i = 0; i < index; ++i) ef = ef->next;
-
- face_r->mat_nr = ef->mat_nr;
- face_r->flag = ef->flag;
-
- /* goddamn, we have to search all verts to find indices */
- v1 = ef->v1;
- v2 = ef->v2;
- v3 = ef->v3;
- v4 = ef->v4;
- if(!v4) face_r->v4 = 0;
-
- for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
- i++, ev = ev->next) {
- if(ev == v1) {
- face_r->v1 = i;
- v1 = NULL;
- }
- if(ev == v2) {
- face_r->v2 = i;
- v2 = NULL;
- }
- if(ev == v3) {
- face_r->v3 = i;
- v3 = NULL;
- }
- if(ev == v4) {
- face_r->v4 = i;
- v4 = NULL;
- }
- }
-
- test_index_face(face_r, NULL, 0, ef->v4?4:3);
-}
-
-static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditVert *ev = emdm->em->verts.first;
- int i;
-
- for(i=0; ev; ev = ev->next, ++vert_r, ++i) {
- if(emdm->vertexCos)
- copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
- else
- copy_v3_v3(vert_r->co, ev->co);
-
- normal_float_to_short_v3(vert_r->no, ev->no);
-
- /* TODO what to do with vert_r->flag? */
- vert_r->flag = 0;
- vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
- }
-}
-
-static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
- EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
- EditEdge *ee = em->edges.first;
- EditVert *ev;
- int i;
-
- /* store vertex indices in tmp union */
- for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (intptr_t) i;
-
- for( ; ee; ee = ee->next, ++edge_r) {
- edge_r->crease = (unsigned char) (ee->crease*255.0f);
- edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
- /* TODO what to do with edge_r->flag? */
- edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
- if (ee->seam) edge_r->flag |= ME_SEAM;
- if (ee->sharp) edge_r->flag |= ME_SHARP;
-#if 0
- /* this needs setup of f2 field */
- if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
-#endif
-
- edge_r->v1 = (int)ee->v1->tmp.l;
- edge_r->v2 = (int)ee->v2->tmp.l;
- }
-}
-
-static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
-{
- EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
- EditFace *ef = em->faces.first;
- EditVert *ev;
- int i;
-
- /* store vertexes indices in tmp union */
- for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
- ev->tmp.l = (intptr_t) i;
-
- for( ; ef; ef = ef->next, ++face_r) {
- face_r->mat_nr = ef->mat_nr;
- face_r->flag = ef->flag;
-
- face_r->v1 = (int)ef->v1->tmp.l;
- face_r->v2 = (int)ef->v2->tmp.l;
- face_r->v3 = (int)ef->v3->tmp.l;
- if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
- else face_r->v4 = 0;
-
- test_index_face(face_r, NULL, 0, ef->v4?4:3);
- }
-}
-
-static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
- EditMesh *em= emdm->em;
- EditFace *efa;
- char *data, *emdata;
- void *datalayer;
- int index, size;
-
- datalayer = DM_get_face_data_layer(dm, type);
- if(datalayer)
- return datalayer;
-
- /* layers are store per face for editmesh, we convert to a temporary
- * data layer array in the derivedmesh when these are requested */
- if(type == CD_MTFACE || type == CD_MCOL) {
- index = CustomData_get_layer_index(&em->fdata, type);
-
- if(index != -1) {
- /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
- size = CustomData_sizeof(type);
-
- DM_add_face_layer(dm, type, CD_CALLOC, NULL);
- index = CustomData_get_layer_index(&dm->faceData, type);
- dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
-
- data = datalayer = DM_get_face_data_layer(dm, type);
- for(efa=em->faces.first; efa; efa=efa->next, data+=size) {
- emdata = CustomData_em_get(&em->fdata, efa->data, type);
- memcpy(data, emdata, size);
- }
- }
- }
-
- return datalayer;
-}
-
-static void emDM_release(DerivedMesh *dm)
-{
- EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
- if (DM_release(dm)) {
- if (emdm->vertexCos) {
- MEM_freeN(emdm->vertexCos);
- MEM_freeN(emdm->vertexNos);
- MEM_freeN(emdm->faceNos);
- }
-
- MEM_freeN(emdm);
- }
-}
-
-DerivedMesh *editmesh_get_derived(EditMesh *em, float (*vertexCos)[3])
-{
- EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
-
- DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
- BLI_countlist(&em->edges), BLI_countlist(&em->faces));
-
- emdm->dm.getMinMax = emDM_getMinMax;
-
- emdm->dm.getNumVerts = emDM_getNumVerts;
- emdm->dm.getNumEdges = emDM_getNumEdges;
- emdm->dm.getNumFaces = emDM_getNumFaces;
-
- emdm->dm.getVertCos = emDM_getVertCos;
-
- emdm->dm.getVert = emDM_getVert;
- emdm->dm.getEdge = emDM_getEdge;
- emdm->dm.getFace = emDM_getFace;
- emdm->dm.copyVertArray = emDM_copyVertArray;
- emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
- emdm->dm.copyFaceArray = emDM_copyFaceArray;
- emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
-
- emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
- emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
- emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
-
- emdm->dm.drawEdges = emDM_drawEdges;
- emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
- emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
- emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
- emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
- emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
- emdm->dm.drawFacesTex = emDM_drawFacesTex;
- emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
- emdm->dm.drawUVEdges = emDM_drawUVEdges;
-
- emdm->dm.release = emDM_release;
-
- emdm->em = em;
- emdm->vertexCos = vertexCos;
-
- if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
- EditVert *eve;
- int i;
-
- DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
-
- for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
- DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
- CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
- }
-
- if(vertexCos) {
- EditVert *eve;
- EditFace *efa;
- int totface = BLI_countlist(&em->faces);
- int i;
-
- for (i=0,eve=em->verts.first; eve; eve= eve->next)
- eve->tmp.l = (intptr_t) i++;
-
- emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
- emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
-
- for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
- float *v1 = vertexCos[(int) efa->v1->tmp.l];
- float *v2 = vertexCos[(int) efa->v2->tmp.l];
- float *v3 = vertexCos[(int) efa->v3->tmp.l];
- float *no = emdm->faceNos[i];
-
- if(efa->v4) {
- float *v4 = vertexCos[(int) efa->v4->tmp.l];
-
- normal_quad_v3( no,v1, v2, v3, v4);
- add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
- }
- else {
- normal_tri_v3( no,v1, v2, v3);
- }
-
- add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
- add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
- add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
- }
-
- for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
- float *no = emdm->vertexNos[i];
- /* following Mesh convention; we use vertex coordinate itself
- * for normal in this case */
- if (normalize_v3(no) == 0.0f) {
- normalize_v3_v3(no, vertexCos[i]);
- }
- }
- }
-
- return (DerivedMesh*) emdm;
-}
-
/***/
-DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md)
+DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
+ ModifierData *md, int build_shapekey_layers)
{
Mesh *me = ob->data;
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if (!(md->mode&eModifierMode_Realtime)) return NULL;
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
-
+
+ if (build_shapekey_layers && me->key && ob->shapenr <= BLI_countlist(&me->key->block)) {
+ key_to_mesh(BLI_findlink(&me->key->block, ob->shapenr-1), me);
+ }
+
if (mti->type==eModifierTypeType_OnlyDeform) {
int numVerts;
float (*deformedVerts)[3] = mesh_getVertexCos(me, &numVerts);
mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, 0, 0);
dm = mesh_create_derived(me, ob, deformedVerts);
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
MEM_freeN(deformedVerts);
} else {
DerivedMesh *tdm = mesh_create_derived(me, ob, NULL);
+
+ if (build_shapekey_layers)
+ add_shapekey_layers(tdm, me, ob);
+
dm = mti->applyModifier(md, ob, tdm, 0, 0);
if(tdm != dm) tdm->release(tdm);
return dm;
}
-static float *get_editmesh_orco_verts(EditMesh *em)
+static float *get_editbmesh_orco_verts(BMEditMesh *em)
{
- EditVert *eve;
+ BMIter iter;
+ BMVert *eve;
float *orco;
int a, totvert;
/* these may not really be the orco's, but it's only for preview.
* could be solver better once, but isn't simple */
- totvert= 0;
- for(eve=em->verts.first; eve; eve=eve->next)
- totvert++;
+ totvert= em->bm->totvert;
orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
- for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3)
+ eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+ for (a=0; eve; eve=BMIter_Step(&iter), a+=3)
VECCOPY(orco+a, eve->co);
return orco;
}
/* orco custom data layer */
-
-static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
+static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
{
*free= 0;
*free= 1;
if(em)
- return (float(*)[3])get_editmesh_orco_verts(em);
+ return (float(*)[3])get_editbmesh_orco_verts(em);
else
return (float(*)[3])get_mesh_orco_verts(ob);
}
by a more flexible customdata system, but not simple */
if(!em) {
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
-
- if(kb->data)
- return kb->data;
+ if (clmd) {
+ KeyBlock *kb= key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
+
+ if(kb->data)
+ return kb->data;
+ }
}
return NULL;
return NULL;
}
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer)
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int layer)
{
DerivedMesh *dm;
float (*orco)[3];
int free;
- if(em) dm= CDDM_from_editmesh(em, me);
+ if(em) dm= CDDM_from_BMEditMesh(em, me, 0);
else dm= CDDM_from_mesh(me, ob);
orco= get_orco_coords_dm(ob, em, layer, &free);
return dm;
}
-static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer)
+static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm,
+ DerivedMesh *orcodm, int layer)
{
float (*orco)[3], (*layerorco)[3];
int totvert, free;
static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
{
- Mesh *me = ob->data;
- MFace *mf = me->mface;
+ // Mesh *me = ob->data; // UNUSED
+ MFace *mf = dm->getTessFaceArray(dm);
+ MLoop *mloop = dm->getLoopArray(dm), *ml;
+ MPoly *mp = dm->getPolyArray(dm);
ColorBand *coba= stored_cb; /* warning, not a local var */
unsigned char *wtcol;
- int i;
+ unsigned char(*wlcol)[4] = NULL;
+ BLI_array_declare(wlcol);
+ int i, j, totface=dm->getNumTessFaces(dm), totloop;
+ int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
- wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
+ wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
- memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
- for (i=0; i<me->totface; i++, mf++) {
- calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]);
- calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]);
+ /*first add colors to the tesselation faces*/
+ memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
+ for (i=0; i<totface; i++, mf++) {
+ /*origindex being NULL means we're operating on original mesh data*/
+ calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[mf->v1] : mf->v1, &wtcol[(i*4 + 0)*4]);
+ calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[mf->v2] : mf->v2, &wtcol[(i*4 + 1)*4]);
+ calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[mf->v3] : mf->v3, &wtcol[(i*4 + 2)*4]);
if (mf->v4)
- calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]);
+ calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[mf->v4] : mf->v4, &wtcol[(i*4 + 3)*4]);
+ }
+
+ CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
+
+ /*now add to loops, so the data can be passed through the modifier stack*/
+ totloop = 0;
+ for (i=0; i<dm->numPolyData; i++, mp++) {
+ ml = mloop + mp->loopstart;
+
+ for (j=0; j<mp->totloop; j++, ml++, totloop++) {
+ BLI_array_growone(wlcol);
+
+ calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[ml->v] : ml->v,
+ (unsigned char *)&wlcol[totloop]);
+ }
+ }
+
+ CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
+}
+
+
+static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
+{
+ KeyBlock *kb;
+ int i, j, tot;
+
+ if (!me->key)
+ return;
+
+ tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY);
+ for (i=0; i<tot; i++) {
+ CustomDataLayer *layer = &dm->vertData.layers[CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i)];
+ float (*cos)[3], (*kbcos)[3];
+
+ for (kb=me->key->block.first; kb; kb=kb->next) {
+ if (kb->uid == layer->uid)
+ break;
+ }
+
+ if (!kb) {
+ kb = add_keyblock(me->key, layer->name);
+ kb->uid = layer->uid;
+ }
+
+ if (kb->data)
+ MEM_freeN(kb->data);
+
+ cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
+ kb->totelem = dm->numVertData;
+
+ kb->data = kbcos = MEM_mallocN(sizeof(float)*3*kb->totelem, "kbcos DerivedMesh.c");
+ if (kb->uid == actshape_uid) {
+ MVert *mvert = dm->getVertArray(dm);
+
+ for (j=0; j<dm->numVertData; j++, kbcos++, mvert++) {
+ copy_v3_v3(*kbcos, mvert->co);
+ }
+ } else {
+ for (j=0; j<kb->totelem; j++, cos++, kbcos++) {
+ copy_v3_v3(*kbcos, *cos);
+ }
+ }
}
- CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
+ for (kb=me->key->block.first; kb; kb=kb->next) {
+ if (kb->totelem != dm->numVertData) {
+ if (kb->data)
+ MEM_freeN(kb->data);
+
+ kb->totelem = dm->numVertData;
+ kb->data = MEM_callocN(sizeof(float)*3*kb->totelem, "kb->data derivedmesh.c");
+ printf("eek! lost a shapekey layer!\n");
+ }
+ }
+}
+
+static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
+{
+ KeyBlock *kb;
+ Key *key = me->key;
+ int a, b;
+
+ if (!me->key)
+ return;
+
+ if (dm->numVertData != me->totvert) {
+ printf("error in add_shapekey_layers: dm isn't the same size as me\n");
+ return;
+ }
+
+ for (a=0, kb=key->block.first; kb; kb=kb->next, a++) {
+ float (*cos)[3] = CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_CALLOC, NULL, dm->numVertData, kb->name);
+ int ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, a);
+
+ dm->vertData.layers[ci].uid = kb->uid;
+ if (kb->totelem != dm->numVertData) {
+ printf("error in add_shapekey_layers: totelem and totvert don't match");
+ continue;
+ }
+
+ for (b=0; b<kb->totelem; b++, cos++) {
+ copy_v3_v3((float *)cos, ((float*)kb->data)+b*3);
+ }
+ }
}
/* new value for useDeform -1 (hack for the gameengine):
static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3],
DerivedMesh **deform_r, DerivedMesh **final_r,
int useRenderParams, int useDeform,
- int needMapping, CustomDataMask dataMask, int index, int useCache)
+ int needMapping, CustomDataMask dataMask,
+ int index, int useCache, int build_shapekey_layers)
{
Mesh *me = ob->data;
ModifierData *firstmd, *md;
LinkNode *datamasks, *curr;
CustomDataMask mask, nextmask;
float (*deformedVerts)[3] = NULL;
- DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
+ DerivedMesh *dm=NULL, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
int required_mode;
int isPrevDeform= FALSE;
*/
if (deform_r) {
*deform_r = CDDM_from_mesh(me, ob);
-
+
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(*deform_r, deformedVerts);
CDDM_calc_normals(*deform_r);
/* if this is not the last modifier in the stack then recalculate the normals
* to avoid giving bogus normals to the next modifier see: [#23673] */
- if(isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ if(dm && isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
/* XXX, this covers bug #23673, but we may need normal calc for other types */
if(dm && dm->type == DM_TYPE_CDDM) {
CDDM_apply_vert_coords(dm, deformedVerts);
/* apply vertex coordinates or build a DerivedMesh as necessary */
if(dm) {
if(deformedVerts) {
- DerivedMesh *tdm = CDDM_copy(dm);
+ DerivedMesh *tdm = CDDM_copy(dm, 0);
dm->release(dm);
dm = tdm;
} else {
dm = CDDM_from_mesh(me, ob);
+ if (build_shapekey_layers)
+ add_shapekey_layers(dm, me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(dm, deformedVerts);
CDDM_calc_normals(dm);
}
- if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
- add_weight_mcol_dm(ob, dm);
-
/* Constructive modifiers need to have an origindex
* otherwise they wont have anywhere to copy the data from.
*
* data by using generic DM_copy_vert_data() functions.
*/
if(needMapping || (nextmask & CD_MASK_ORIGINDEX)) {
+ int i, *orig;
+
/* calc */
DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL);
- range_vni(DM_get_vert_data_layer(dm, CD_ORIGINDEX), dm->numVertData, 0);
- range_vni(DM_get_edge_data_layer(dm, CD_ORIGINDEX), dm->numEdgeData, 0);
- range_vni(DM_get_face_data_layer(dm, CD_ORIGINDEX), dm->numFaceData, 0);
+ orig = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
+ for(i=0; i<dm->numVertData; i++) *orig++= i;
+ orig = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
+ for(i=0; i<dm->numEdgeData; i++) *orig++= i;
+ orig = DM_get_face_data_layer(dm, CD_ORIGINDEX);
+ for(i=0; i<dm->numPolyData; i++) *orig++= i;
}
+
+ if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
+ add_weight_mcol_dm(ob, dm);
+
}
/* add an origspace layer if needed */
if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache);
* DerivedMesh then we need to build one.
*/
if(dm && deformedVerts) {
- finaldm = CDDM_copy(dm);
+ finaldm = CDDM_copy(dm, 0);
dm->release(dm);
finaldm = dm;
} else {
finaldm = CDDM_from_mesh(me, ob);
-
+
+ if (build_shapekey_layers)
+ add_shapekey_layers(finaldm, me, ob);
+
if(deformedVerts) {
CDDM_apply_vert_coords(finaldm, deformedVerts);
- CDDM_calc_normals(finaldm);
}
+ CDDM_calc_normals(finaldm);
+
if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT))
add_weight_mcol_dm(ob, finaldm);
+
}
/* add an orco layer if needed */
BLI_linklist_free(datamasks, NULL);
}
-float (*editmesh_get_vertex_cos(EditMesh *em, int *numVerts_r))[3]
+float (*editbmesh_get_vertex_cos(BMEditMesh *em, int *numVerts_r))[3]
{
- int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
+ int i, numVerts = *numVerts_r = em->bm->totvert;
float (*cos)[3];
- EditVert *eve;
+ BMIter iter;
+ BMVert *eve;
- cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
- for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
+ cos = MEM_mallocN(sizeof(float)*3*numVerts, "vertexcos");
+
+ eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+ for (i=0; eve; eve=BMIter_Step(&iter), i++) {
VECCOPY(cos[i], eve->co);
}
return cos;
}
-int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
+int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
return 1;
}
-static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r,
+static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
DerivedMesh **final_r,
CustomDataMask dataMask)
{
modifiers_clearErrors(ob);
if(cage_r && cageIndex == -1) {
- *cage_r = editmesh_get_derived(em, NULL);
+ *cage_r = getEditDerivedBMesh(em, ob, NULL);
}
dm = NULL;
md->scene= scene;
- if(!editmesh_modifier_is_enabled(scene, md, dm))
+ if(!editbmesh_modifier_is_enabled(scene, md, dm))
continue;
/* add an orco layer if needed by this modifier */
MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
dm->getVertCos(dm, deformedVerts);
} else {
- deformedVerts = editmesh_get_vertex_cos(em, &numVerts);
+ deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
}
}
/* apply vertex coordinates or build a DerivedMesh as necessary */
if(dm) {
if(deformedVerts) {
- DerivedMesh *tdm = CDDM_copy(dm);
+ DerivedMesh *tdm = CDDM_copy(dm, 0);
if(!(cage_r && dm == *cage_r)) dm->release(dm);
dm = tdm;
} else if(cage_r && dm == *cage_r) {
/* dm may be changed by this modifier, so we need to copy it
*/
- dm = CDDM_copy(dm);
+ dm = CDDM_copy(dm, 0);
}
} else {
- dm = CDDM_from_editmesh(em, ob->data);
+ dm = CDDM_from_BMEditMesh(em, ob->data, 0);
if(deformedVerts) {
CDDM_apply_vert_coords(dm, deformedVerts);
if(mask & CD_MASK_ORIGSPACE)
if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
- DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+ DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
if (mti->applyModifierEM)
ndm = mti->applyModifierEM(md, ob, em, dm);
if(cage_r && i == cageIndex) {
if(dm && deformedVerts) {
- *cage_r = CDDM_copy(dm);
+ *cage_r = CDDM_copy(dm, 0);
CDDM_apply_vert_coords(*cage_r, deformedVerts);
} else if(dm) {
*cage_r = dm;
} else {
*cage_r =
- editmesh_get_derived(em,
+ getEditDerivedBMesh(em, ob,
deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
}
}
* then we need to build one.
*/
if(dm && deformedVerts) {
- *final_r = CDDM_copy(dm);
+ *final_r = CDDM_copy(dm, 0);
if(!(cage_r && dm == *cage_r)) dm->release(dm);
} else if (!deformedVerts && cage_r && *cage_r) {
*final_r = *cage_r;
} else {
- *final_r = editmesh_get_derived(em, deformedVerts);
+ *final_r = getEditDerivedBMesh(em, ob, deformedVerts);
deformedVerts = NULL;
}
}
}
-static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
+static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
+ int build_shapekey_layers)
{
Object *obact = scene->basact?scene->basact->object:NULL;
int editing = paint_facesel_test(ob);
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
&ob->derivedFinal, 0, 1,
- needMapping, dataMask, -1, 1);
+ needMapping, dataMask, -1, 1, build_shapekey_layers);
DM_set_object_boundbox (ob, ob->derivedFinal);
ob->lastDataMask = dataMask;
}
-static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
clear_mesh_caches(obedit);
em->derivedCage = NULL;
}
- editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
+ editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
DM_set_object_boundbox (obedit, em->derivedFinal);
em->lastDataMask = dataMask;