diff options
Diffstat (limited to 'source/blender/blenkernel')
76 files changed, 5710 insertions, 4022 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index c1fe8f0452e..c97e3d2798d 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -102,6 +102,8 @@ 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 @@ -160,6 +162,16 @@ typedef struct DMFaceIter { void *(*getCDData)(void *self, int type, int layer); } DMFaceIter; +typedef struct DMGridData { + float co[3]; + float no[3]; +} DMGridData; + +typedef struct DMGridAdjacency { + int index[4]; + int rotation[4]; +} DMGridAdjacency; + typedef struct DerivedMesh DerivedMesh; struct DerivedMesh { /* Private DerivedMesh data, only for internal DerivedMesh use */ @@ -245,6 +257,13 @@ struct DerivedMesh { 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); + DMGridData **(*getGridData)(DerivedMesh *dm); + DMGridAdjacency *(*getGridAdjacency)(DerivedMesh *dm); + int *(*getGridOffset)(DerivedMesh *dm); + /* Iterate over each mapped vertex in the derived mesh, calling the * given function with the original vert and the mapped vert's new * coordinate and normal. For historical reasons the normal can be @@ -293,6 +312,14 @@ struct DerivedMesh { /* Get vertex normal, undefined if index is not valid */ void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]); + /* Get a map of vertices to faces + */ + struct ListBase *(*getFaceMap)(DerivedMesh *dm); + + /* Get the BVH used for paint modes + */ + struct PBVH *(*getPBVH)(struct Object *ob, DerivedMesh *dm); + /* Drawing Operations */ /* Draw all vertices as bgl points (no options) */ @@ -317,8 +344,8 @@ struct DerivedMesh { * * Also called for *final* editmode DerivedMeshes */ - void (*drawFacesSolid)(DerivedMesh *dm, - int (*setMaterial)(int, void *attribs)); + void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4], + int fast, int (*setMaterial)(int, void *attribs)); /* Draw all faces * o If useTwoSided, draw front and back using col arrays diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h index e0b65c1996f..6029ce01794 100644 --- a/source/blender/blenkernel/BKE_action.h +++ b/source/blender/blenkernel/BKE_action.h @@ -140,7 +140,11 @@ void free_pose(struct bPose *pose); */ void copy_pose(struct bPose **dst, struct bPose *src, int copyconstraints); - +/** + * Copy the internal members of each pose channel including constraints + * and ID-Props, used when duplicating bones in editmode. + */ +void duplicate_pose_channel_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from); /** * Return a pointer to the pose channel of the given name diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index e4a763a25d0..973e70b6f51 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -43,7 +43,7 @@ struct bContext; struct ReportList; #define BLENDER_VERSION 250 -#define BLENDER_SUBVERSION 7 +#define BLENDER_SUBVERSION 11 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index c83a260690b..c571688737a 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -34,12 +34,6 @@ struct CurveMap; struct ImBuf; struct rctf; -void gamma_correct_rec709(float *c, float gamma); -void gamma_correct(float *c, float gamma); -float srgb_to_linearrgb(float c); -float linearrgb_to_srgb(float c); -void color_manage_linearize(float *col_to, float *col_from); - void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); void floatbuf_to_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w); diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h index a8ccc84a7c3..e9110b99098 100644 --- a/source/blender/blenkernel/BKE_constraint.h +++ b/source/blender/blenkernel/BKE_constraint.h @@ -114,7 +114,7 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type); void unique_constraint_name(struct bConstraint *con, struct ListBase *list); void free_constraints(struct ListBase *list); -void copy_constraints(struct ListBase *dst, struct ListBase *src); +void copy_constraints(struct ListBase *dst, const struct ListBase *src); void relink_constraints(struct ListBase *list); void free_constraint_data(struct bConstraint *con); diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h index 7f64538b10d..2c013a5231a 100644 --- a/source/blender/blenkernel/BKE_context.h +++ b/source/blender/blenkernel/BKE_context.h @@ -248,9 +248,9 @@ int CTX_data_selected_editable_bones(const bContext *C, ListBase *list); int CTX_data_visible_bones(const bContext *C, ListBase *list); int CTX_data_editable_bones(const bContext *C, ListBase *list); -struct bPoseChannel *CTX_data_active_pchan(const bContext *C); -int CTX_data_selected_pchans(const bContext *C, ListBase *list); -int CTX_data_visible_pchans(const bContext *C, ListBase *list); +struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C); +int CTX_data_selected_pose_bones(const bContext *C, ListBase *list); +int CTX_data_visible_pose_bones(const bContext *C, ListBase *list); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index a253d18486f..6c4df250061 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -33,6 +33,7 @@ #define BKE_CUSTOMDATA_H struct BMesh; +struct ID; struct CustomData; struct CustomDataLayer; typedef unsigned int CustomDataMask; @@ -232,11 +233,11 @@ int CustomData_get_named_layer_index(const struct CustomData *data, int type, ch int CustomData_get_active_layer_index(const struct CustomData *data, int type); int CustomData_get_render_layer_index(const struct CustomData *data, int type); int CustomData_get_clone_layer_index(const struct CustomData *data, int type); -int CustomData_get_mask_layer_index(const struct CustomData *data, int type); +int CustomData_get_stencil_layer_index(const struct CustomData *data, int type); int CustomData_get_active_layer(const struct CustomData *data, int type); int CustomData_get_render_layer(const struct CustomData *data, int type); int CustomData_get_clone_layer(const struct CustomData *data, int type); -int CustomData_get_mask_layer(const struct CustomData *data, int type); +int CustomData_get_stencil_layer(const struct CustomData *data, int type); /* copies the data from source to the data element at index in the first * layer of type @@ -270,13 +271,13 @@ void *CustomData_set_layer_n(const struct CustomData *data, int type, int n, voi void CustomData_set_layer_active(struct CustomData *data, int type, int n); void CustomData_set_layer_render(struct CustomData *data, int type, int n); void CustomData_set_layer_clone(struct CustomData *data, int type, int n); -void CustomData_set_layer_mask(struct CustomData *data, int type, int n); +void CustomData_set_layer_stencil(struct CustomData *data, int type, int n); /* same as above but works with an index from CustomData_get_layer_index */ void CustomData_set_layer_active_index(struct CustomData *data, int type, int n); void CustomData_set_layer_render_index(struct CustomData *data, int type, int n); void CustomData_set_layer_clone_index(struct CustomData *data, int type, int n); -void CustomData_set_layer_mask_index(struct CustomData *data, int type, int n); +void CustomData_set_layer_stencil_index(struct CustomData *data, int type, int n); /* adds flag to the layer flags */ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag); @@ -319,4 +320,19 @@ 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); + +/* External file storage */ + +void CustomData_external_add(struct CustomData *data, + struct ID *id, int type, int totelem, const char *filename); +void CustomData_external_remove(struct CustomData *data, + struct ID *id, int type, int totelem); +int CustomData_external_test(struct CustomData *data, int type); + +void CustomData_external_write(struct CustomData *data, + struct ID *id, CustomDataMask mask, int totelem, int free); +void CustomData_external_read(struct CustomData *data, + struct ID *id, CustomDataMask mask, int totelem); + #endif + diff --git a/source/blender/blenkernel/BKE_customdata_file.h b/source/blender/blenkernel/BKE_customdata_file.h new file mode 100644 index 00000000000..5cbff193cd3 --- /dev/null +++ b/source/blender/blenkernel/BKE_customdata_file.h @@ -0,0 +1,59 @@ +/* + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BKE_CUSTOMDATA_FILE_H +#define BKE_CUSTOMDATA_FILE_H + +#define CDF_TYPE_IMAGE 0 +#define CDF_TYPE_MESH 1 + +#define CDF_LAYER_NAME_MAX 64 + +typedef struct CDataFile CDataFile; +typedef struct CDataFileLayer CDataFileLayer; + +/* Create/Free */ + +CDataFile *cdf_create(int type); +void cdf_free(CDataFile *cdf); + +/* File read/write/remove */ + +int cdf_read_open(CDataFile *cdf, char *filename); +int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay); +int cdf_read_data(CDataFile *cdf, int size, void *data); +void cdf_read_close(CDataFile *cdf); + +int cdf_write_open(CDataFile *cdf, char *filename); +int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay); +int cdf_write_data(CDataFile *cdf, int size, void *data); +void cdf_write_close(CDataFile *cdf); + +void cdf_remove(char *filename); + +/* Layers */ + +CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name); +CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize); + +#endif /* BKE_CUSTOMDATA_FILE_H */ + diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index 5888c6d7530..fa6b8969edb 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -158,7 +158,12 @@ void copy_fcurves(ListBase *dst, ListBase *src); struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int array_index); /* high level function to get an fcurve from C without having the rna */ -struct FCurve *id_data_find_fcurve(ID* id, void *data, struct StructRNA *type, char *prop_name, int index); +struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, char *prop_name, int index); + +/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated + * e.g. numMatches = list_find_data_fcurves(matches, &act->curves, "pose.bones[", "MyFancyBone"); + */ +int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName); /* Binary search algorithm for finding where to 'insert' BezTriple with given frame number. * Returns the index to insert at (data already at that index will be offset if replace is 0) diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 75814261104..f1ab1d61fdf 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -63,10 +63,13 @@ struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob); 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. */ 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 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, diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index a05df810ca4..c9dbac1cf5d 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -229,7 +229,7 @@ typedef struct ModifierTypeInfo { * * This function is optional (assumes never disabled if not present). */ - int (*isDisabled)(struct ModifierData *md); + int (*isDisabled)(struct ModifierData *md, int userRenderParams); /* Add the appropriate relations to the DEP graph depending on the * modifier data. @@ -281,7 +281,7 @@ void modifier_copyData(struct ModifierData *md, struct ModifierData *ta int modifier_dependsOnTime(struct ModifierData *md); int modifier_supportsMapping(struct ModifierData *md); int modifier_couldBeCage(struct ModifierData *md); -int modifier_isDeformer(struct ModifierData *md); +int modifier_isCorrectableDeformed(struct ModifierData *md); int modifier_sameTopology(ModifierData *md); int modifier_isEnabled(struct ModifierData *md, int required_mode); void modifier_setError(struct ModifierData *md, char *format, ...); @@ -304,7 +304,7 @@ int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); -int modifiers_isDeformed(struct Scene *scene, struct Object *ob); +int modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); int modifiers_indexInObject(struct Object *ob, struct ModifierData *md); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index d20a00cbfff..2f372f80957 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -27,52 +27,36 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef BKE_MULTIRES_H +#define BKE_MULTIRES_H + struct DerivedMesh; struct Mesh; struct MFace; +struct Multires; struct MultiresModifierData; struct Object; -typedef struct MultiresSubsurf { - struct MultiresModifierData *mmd; - struct Object *ob; - int local_mmd; -} MultiresSubsurf; - -/* MultiresDM */ -struct Object *MultiresDM_get_object(struct DerivedMesh *dm); -struct Mesh *MultiresDM_get_mesh(struct DerivedMesh *dm); -struct DerivedMesh *MultiresDM_new(struct MultiresSubsurf *, struct DerivedMesh*, - int, int, int, int, int); -void *MultiresDM_get_vertnorm(struct DerivedMesh *); -void *MultiresDM_get_orco(struct DerivedMesh *); -struct MVert *MultiresDM_get_subco(struct DerivedMesh *); -struct ListBase *MultiresDM_get_vert_face_map(struct DerivedMesh *); -struct ListBase *MultiresDM_get_vert_edge_map(struct DerivedMesh *); -int *MultiresDM_get_face_offsets(struct DerivedMesh *); -int MultiresDM_get_totlvl(struct DerivedMesh *); -int MultiresDM_get_lvl(struct DerivedMesh *); -void MultiresDM_set_update(struct DerivedMesh *, void (*)(struct DerivedMesh*)); - -/* The displacements will only be updated when - the MultiresDM has been marked as modified */ -void MultiresDM_mark_as_modified(struct DerivedMesh *); void multires_mark_as_modified(struct Object *ob); void multires_force_update(struct Object *ob); -struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, int local_mmd, struct DerivedMesh*, - struct Object *, int, int); +struct DerivedMesh *multires_dm_create_from_derived(struct MultiresModifierData*, + int local_mmd, struct DerivedMesh*, struct Object *, int, int); struct MultiresModifierData *find_multires_modifier(struct Object *ob); -int multiresModifier_switch_level(struct Object *, const int); void multiresModifier_join(struct Object *); void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction); -void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int distance, +void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple); int multiresModifier_reshape(struct MultiresModifierData *mmd, struct Object *dst, struct Object *src); +void multires_stitch_grids(struct Object *); + /* Related to the old multires */ -struct Multires; -void multires_load_old(struct DerivedMesh *, struct Multires *); -void multires_free(struct Multires*); +void multires_free(struct Multires *mr); +void multires_load_old(struct Object *ob, struct Mesh *me); +void multires_load_old_250(struct Mesh *); + +#endif + diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index f9130e24a08..3ed9ab8778e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -175,6 +175,7 @@ struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node, int inte struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock); void nodeRemLink(struct bNodeTree *ntree, struct bNodeLink *link); +struct bNode *nodeFindNodebyName(struct bNodeTree *ntree, const char *name); int nodeFindNode(struct bNodeTree *ntree, struct bNodeSocket *sock, struct bNode **nodep, int *sockindex); struct bNodeLink *nodeFindLink(struct bNodeTree *ntree, struct bNodeSocket *from, struct bNodeSocket *to); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index aeb33cd3628..3e239e91453 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -93,8 +93,10 @@ void disable_speed_curve(int val); float bsystem_time(struct Scene *scene, struct Object *ob, float cfra, float ofs); void object_scale_to_mat3(struct Object *ob, float mat[][3]); void object_rot_to_mat3(struct Object *ob, float mat[][3]); +void object_mat3_to_rot(struct Object *ob, float mat[][3], int use_compat); void object_to_mat3(struct Object *ob, float mat[][3]); void object_to_mat4(struct Object *ob, float mat[][4]); +void object_apply_mat4(struct Object *ob, float mat[][4]); void set_no_parent_ipo(int val); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index b532b0820d7..161ae2c3c5c 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -34,6 +34,7 @@ struct MultireModifierData; struct MVert; struct Object; struct Paint; +struct PBVH; struct Scene; struct StrokeCache; @@ -68,25 +69,24 @@ typedef struct SculptSession { struct MFace *mface; int totvert, totface; float *face_normals; - + struct PBVH *tree; struct Object *ob; struct KeyBlock *kb, *refkb; /* Mesh connectivity */ struct ListBase *fmap; - struct IndexNode *fmap_mem; - int fmap_size; /* Used temporarily per-stroke */ float *vertexcosnos; - ListBase damaged_rects; - ListBase damaged_verts; - + + /* Partial redraw */ + int partial_redraw; + /* Used to cache the render of the active texture */ unsigned int texcache_side, *texcache, texcache_actual; /* Layer brush persistence between strokes */ - float (*mesh_co_orig)[3]; /* Copy of the mesh vertices' locations */ + float (*layer_co)[3]; /* Copy of the mesh vertices' locations */ float *layer_disps; /* Displacements for each vertex */ struct SculptStroke *stroke; diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index 2291601bd47..2199240d77b 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -222,7 +222,7 @@ void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int tim void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); -void object_add_particle_system(struct Scene *scene, struct Object *ob); +struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, char *name); void object_remove_particle_system(struct Scene *scene, struct Object *ob); struct ParticleSettings *psys_new_settings(char *name, struct Main *main); struct ParticleSettings *psys_copy_settings(struct ParticleSettings *part); diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h index 5ae10d736fd..4b26eaa6d76 100644 --- a/source/blender/blenkernel/BKE_pointcache.h +++ b/source/blender/blenkernel/BKE_pointcache.h @@ -151,6 +151,7 @@ typedef struct PTCacheBaker { int (*break_test)(void *data); void *break_data; void (*progressbar)(void *data, int num); + void (*progressend)(void *data); void *progresscontext; } PTCacheBaker; diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index 686fc265de0..c372004bd19 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -66,6 +66,7 @@ void unlink_scene(struct Main *bmain, struct Scene *sce, struct Scene *newsce); int next_object(struct Scene *scene, int val, struct Base **base, struct Object **ob); struct Object *scene_find_camera(struct Scene *sc); +struct Object *scene_find_camera_switch(struct Scene *scene); // DURIAN_CAMERA_SWITCH struct Base *scene_add_base(struct Scene *sce, struct Object *ob); void scene_deselect_all(struct Scene *sce); @@ -74,6 +75,7 @@ void scene_select_base(struct Scene *sce, struct Base *selbase); /* checks for cycle, returns 1 if it's all OK */ int scene_check_setscene(struct Scene *sce); +void scene_update_tagged(struct Scene *sce); void scene_update_for_newframe(struct Scene *sce, unsigned int lay); void scene_add_render_layer(struct Scene *sce); diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 39a90fe3074..c9d1caa1cfe 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -41,6 +41,7 @@ struct Header; struct Menu; struct ScrArea; struct SpaceType; +struct Scene; struct wmNotifier; struct wmWindow; struct wmWindowManager; @@ -54,7 +55,7 @@ struct uiMenuItem; ED_spacetypes_init() in editors/area/spacetypes.c */ /* an editor in Blender is a combined ScrArea + SpaceType + SpaceData */ -#define BKE_ST_MAXNAME 32 +#define BKE_ST_MAXNAME 64 typedef struct SpaceType { struct SpaceType *next, *prev; @@ -233,7 +234,7 @@ void BKE_screen_area_free(struct ScrArea *sa); /* screen */ void free_screen(struct bScreen *sc); -unsigned int BKE_screen_visible_layers(struct bScreen *screen); +unsigned int BKE_screen_visible_layers(struct bScreen *screen, struct Scene *scene); #endif diff --git a/source/blender/blenkernel/BKE_sequence.h b/source/blender/blenkernel/BKE_sequencer.h index 2f7526d524c..dc7b6d3ad9b 100644 --- a/source/blender/blenkernel/BKE_sequence.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -60,17 +60,17 @@ void seq_next(SeqIterator *iter); void seq_end(SeqIterator *iter); void seq_array(struct Editing *ed, struct Sequence ***seqarray, int *tot, int use_pointer); -#define SEQP_BEGIN(ed, seq) \ +#define SEQP_BEGIN(ed, _seq) \ { \ SeqIterator iter;\ for(seq_begin(ed, &iter, 1); iter.valid; seq_next(&iter)) { \ - seq= iter.seq; + _seq= iter.seq; -#define SEQ_BEGIN(ed, seq) \ +#define SEQ_BEGIN(ed, _seq) \ { \ SeqIterator iter;\ for(seq_begin(ed, &iter, 0); iter.valid; seq_next(&iter)) { \ - seq= iter.seq; + _seq= iter.seq; #define SEQ_END \ } \ @@ -125,7 +125,7 @@ struct SeqEffectHandle { float-rects or byte-rects (mixed cases are handled one layer up...) */ - void (*execute)(struct Sequence *seq, int cfra, + void (*execute)(struct Scene *scene, struct Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, @@ -137,10 +137,15 @@ struct SeqEffectHandle { /* sequence.c */ void printf_strip(struct Sequence *seq); +/* apply functions recursively */ +void seqbase_recursive_apply(struct ListBase *seqbase, int (*apply_func)(struct Sequence *seq, void *), void *arg); +void seq_recursive_apply(struct Sequence *seq, int (*apply_func)(struct Sequence *, void *), void *arg); + // extern void seq_free_sequence(struct Scene *scene, struct Sequence *seq); void seq_free_strip(struct Strip *strip); void seq_free_editing(struct Scene *scene); +void seq_free_clipboard(void); struct Editing *seq_give_editing(struct Scene *scene, int alloc); char *give_seqname(struct Sequence *seq); struct ImBuf *give_ibuf_seq(struct Scene *scene, int rectx, int recty, int cfra, int chanshown, int render_size); @@ -178,17 +183,23 @@ void seq_tx_set_final_left(struct Sequence *seq, int val); void seq_tx_set_final_right(struct Sequence *seq, int val); void seq_tx_handle_xlimits(struct Sequence *seq, int leftflag, int rightflag); int seq_tx_test(struct Sequence * seq); -int check_single_seq(struct Sequence *seq); -void fix_single_seq(struct Sequence *seq); +int seq_single_check(struct Sequence *seq); +void seq_single_fix(struct Sequence *seq); int seq_test_overlap(struct ListBase * seqbasep, struct Sequence *test); -int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test); -int shuffle_seq_time(ListBase * seqbasep); +struct ListBase *seq_seqbase(struct ListBase *seqbase, struct Sequence *seq); +void seq_offset_animdata(struct Scene *scene, struct Sequence *seq, int ofs); +int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test, struct Scene *evil_scene); +int shuffle_seq_time(ListBase * seqbasep, struct Scene *evil_scene); +int seqbase_isolated_sel_check(struct ListBase *seqbase); void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_mem_usage); void seq_update_sound(struct Sequence *seq); - +void seq_update_muting(struct Editing *ed); +void seqbase_sound_reload(Scene *scene, ListBase *seqbase); void clear_scene_in_allseqs(struct Scene *sce); +struct Sequence *get_seq_by_name(struct ListBase *seqbase, const char *name, int recursive); + struct Sequence *active_seq_get(struct Scene *scene); void active_seq_set(struct Scene *scene, struct Sequence *seq); @@ -224,3 +235,6 @@ struct Sequence *sequencer_add_image_strip(struct bContext *C, ListBase *seqbase struct Sequence *sequencer_add_sound_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); +/* copy/paste */ +extern ListBase seqbase_clipboard; +extern int seqbase_clipboard_frame; diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h index cbce4663d6f..64ce1983e7d 100644 --- a/source/blender/blenkernel/BKE_sound.h +++ b/source/blender/blenkernel/BKE_sound.h @@ -41,6 +41,8 @@ void sound_init(); void sound_exit(); +void sound_disable(); + struct bSound* sound_new_file(struct Main *main, char* filename); // XXX unused currently diff --git a/source/blender/blenkernel/BKE_subsurf.h b/source/blender/blenkernel/BKE_subsurf.h index f6dc22f650a..a0db944530e 100644 --- a/source/blender/blenkernel/BKE_subsurf.h +++ b/source/blender/blenkernel/BKE_subsurf.h @@ -34,21 +34,66 @@ struct DerivedMesh; struct EditMesh; struct MultiresSubsurf; struct SubsurfModifierData; +struct _CCGSubsurf; +struct _CCGVert; +struct _CCGEdge; +struct _CCGFace; +struct EdgeHash; +struct PBVH; +struct DMGridData; +struct DMGridAdjacency; -struct DerivedMesh *subsurf_make_derived_from_derived( - struct DerivedMesh *dm, - struct SubsurfModifierData *smd, - int useRenderParams, float (*vertCos)[3], - int isFinalCalc, int editMode); +/**************************** External *****************************/ -struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( +struct DerivedMesh *subsurf_make_derived_from_derived( struct DerivedMesh *dm, struct SubsurfModifierData *smd, - struct MultiresSubsurf *ms, int useRenderParams, float (*vertCos)[3], int isFinalCalc, int editMode); void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]); +/**************************** Internal *****************************/ + +typedef struct CCGDerivedMesh { + DerivedMesh dm; + + struct _CCGSubSurf *ss; + int freeSS; + int drawInteriorEdges, useSubsurfUv; + + struct {int startVert; struct _CCGVert *vert;} *vertMap; + struct {int startVert; int startEdge; struct _CCGEdge *edge;} *edgeMap; + struct {int startVert; int startEdge; + int startFace; struct _CCGFace *face;} *faceMap; + + short *edgeFlags; + char *faceFlags; + + int *reverseFaceMap; + + struct PBVH *pbvh; + + struct DMGridData **gridData; + struct DMGridAdjacency *gridAdjacency; + int *gridOffset; + struct _CCGFace **gridFaces; + + struct { + struct MultiresModifierData *mmd; + int local_mmd; + + int lvl, totlvl; + float (*orco)[3]; + + Object *ob; + int modified; + + void (*update)(DerivedMesh*); + } multires; + + struct EdgeHash *ehash; +} CCGDerivedMesh; + #endif diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h index b9dc5916e69..95ada45f5d8 100644 --- a/source/blender/blenkernel/BKE_texture.h +++ b/source/blender/blenkernel/BKE_texture.h @@ -62,7 +62,7 @@ int do_colorband(struct ColorBand *coba, float in, float out[4]); void colorband_table_RGBA(struct ColorBand *coba, float **array, int *size); void default_tex(struct Tex *tex); -struct Tex *add_texture(char *name); +struct Tex *add_texture(const char *name); void default_mtex(struct MTex *mtex); struct MTex *add_mtex(void); struct Tex *copy_texture(struct Tex *tex); diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 2b03531a071..102f0f73326 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -174,7 +174,15 @@ extern "C" { #define ENDB MAKE_ID('E','N','D','B') -/* This one rotates the bytes in an int */ +/* This one rotates the bytes in an int64, int (32) and short (16) */ +#define SWITCH_INT64(a) { \ + char s_i, *p_i; \ + p_i= (char *)&(a); \ + s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \ + s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \ + s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \ + s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; } + #define SWITCH_INT(a) { \ char s_i, *p_i; \ p_i= (char *)&(a); \ diff --git a/source/blender/blenkernel/BKE_writeavi.h b/source/blender/blenkernel/BKE_writeavi.h index 4ef63b069c2..a8d38dda103 100644 --- a/source/blender/blenkernel/BKE_writeavi.h +++ b/source/blender/blenkernel/BKE_writeavi.h @@ -37,17 +37,19 @@ extern "C" { /* generic blender movie support, could move to own module */ struct RenderData; +struct ReportList; struct Scene; -void start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty); + +int start_avi(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); void end_avi(void); -void append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty); +int append_avi(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); void makeavistring (struct RenderData *rd, char *string); typedef struct bMovieHandle { - void (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty); - void (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty); + int (*start_movie)(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); + int (*append_movie)(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); void (*end_movie)(void); - int (*get_next_frame)(struct RenderData *rd); /* optional */ + int (*get_next_frame)(struct RenderData *rd, struct ReportList *reports); /* optional */ } bMovieHandle; bMovieHandle *BKE_get_movie_handle(int imtype); diff --git a/source/blender/blenkernel/BKE_writeffmpeg.h b/source/blender/blenkernel/BKE_writeffmpeg.h index 07e0e01ef7e..6ec8320f026 100644 --- a/source/blender/blenkernel/BKE_writeffmpeg.h +++ b/source/blender/blenkernel/BKE_writeffmpeg.h @@ -57,11 +57,12 @@ extern "C" { struct IDProperty; struct RenderData; +struct ReportList; struct Scene; -extern void start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty); +extern int start_ffmpeg(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); extern void end_ffmpeg(void); -extern void append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty); +extern int append_ffmpeg(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); extern void ffmpeg_set_preset(struct RenderData *rd, int preset); extern void ffmpeg_verify_image_type(struct RenderData *rd); diff --git a/source/blender/blenkernel/BKE_writeframeserver.h b/source/blender/blenkernel/BKE_writeframeserver.h index 6a38abe977f..50b905cfd75 100644 --- a/source/blender/blenkernel/BKE_writeframeserver.h +++ b/source/blender/blenkernel/BKE_writeframeserver.h @@ -33,12 +33,13 @@ extern "C" { #endif struct RenderData; +struct ReportList; struct Scene; -extern void start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty); +extern int start_frameserver(struct Scene *scene, struct RenderData *rd, int rectx, int recty, struct ReportList *reports); extern void end_frameserver(void); -extern void append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty); -extern int frameserver_loop(struct RenderData *rd); +extern int append_frameserver(struct RenderData *rd, int frame, int *pixels, int rectx, int recty, struct ReportList *reports); +extern int frameserver_loop(struct RenderData *rd, struct ReportList *reports); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 7bd6314097b..b1cbd16512e 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -34,6 +34,7 @@ SET(INC ../nodes ../../../extern/glew/include ../gpu ../makesrna ../../../intern/smoke/extern ../../../intern/bsp/extern ../blenfont ../../../intern/audaspace/intern + ../../../source/blender/windowmanager # XXX - BAD LEVEL CALL WM_api.h ${ZLIB_INC} ) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 38f541ff7e8..602a1234f95 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -3,7 +3,8 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include ../blenlib ../blenfont ../makesdna' +incs = '. #/intern/guardedalloc #/intern/memutil ../editors/include' +incs += ' ../blenlib ../blenfont ../makesdna ../windowmanager' incs += ' ../render/extern/include #/intern/decimation/extern ../makesrna' incs += ' ../imbuf ../ikplugin ../avi #/intern/elbeem/extern ../nodes' incs += ' #/intern/iksolver/extern ../blenloader' diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c index cda035046f6..dc863869ad8 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.c +++ b/source/blender/blenkernel/intern/CCGSubSurf.c @@ -8,6 +8,12 @@ #include "BLO_sys_types.h" // for intptr_t support +#ifdef _MSC_VER +#define CCG_INLINE __inline +#else +#define CCG_INLINE inline +#endif + /* used for normalize_v3 in BLI_math_vector * float.h's FLT_EPSILON causes trouble with subsurf normals - campbell */ #define EPSILON (1.0e-35f) @@ -34,7 +40,7 @@ typedef struct _EHash { int numEntries, curSize, curSizeIdx; CCGAllocatorIFC allocatorIFC; - CCAllocHDL allocator; + CCGAllocatorHDL allocator; } EHash; #define EHASH_alloc(eh, nb) ((eh)->allocatorIFC.alloc((eh)->allocator, nb)) @@ -42,7 +48,7 @@ typedef struct _EHash { #define EHASH_hash(eh, item) (((uintptr_t) (item))%((unsigned int) (eh)->curSize)) -static EHash *_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCAllocHDL allocator) { +static EHash *_ehash_new(int estimatedNumEntries, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) { EHash *eh = allocatorIFC->alloc(allocator, sizeof(*eh)); eh->allocatorIFC = *allocatorIFC; eh->allocator = allocator; @@ -178,13 +184,13 @@ static int _ehashIterator_isStopped(EHashIterator *ehi) { /***/ -static void *_stdAllocator_alloc(CCAllocHDL a, int numBytes) { +static void *_stdAllocator_alloc(CCGAllocatorHDL a, int numBytes) { return malloc(numBytes); } -static void *_stdAllocator_realloc(CCAllocHDL a, void *ptr, int newSize, int oldSize) { +static void *_stdAllocator_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) { return realloc(ptr, newSize); } -static void _stdAllocator_free(CCAllocHDL a, void *ptr) { +static void _stdAllocator_free(CCGAllocatorHDL a, void *ptr) { free(ptr); } @@ -221,7 +227,7 @@ static int VertDataEqual(float *a, float *b) { #define NormAdd(av, bv) { float *_a = (float*) av, *_b = (float*) bv; _a[0]+=_b[0]; _a[1]+=_b[1]; _a[2]+=_b[2]; } -static int _edge_isBoundary(CCEdge *e); +static int _edge_isBoundary(CCGEdge *e); /***/ @@ -232,53 +238,53 @@ enum { } VertFlags; enum { Edge_eEffected= (1<<0), -} CCEdgeFlags; +} CCGEdgeFlags; enum { Face_eEffected= (1<<0), } FaceFlags; -struct _CCVert { - CCVert *next; /* EHData.next */ - CCVertHDL vHDL; /* EHData.key */ +struct _CCGVert { + CCGVert *next; /* EHData.next */ + CCGVertHDL vHDL; /* EHData.key */ short numEdges, numFaces, flags, pad; - CCEdge **edges; - CCFace **faces; + CCGEdge **edges; + CCGFace **faces; // byte *levelData; // byte *userData; }; #define VERT_getLevelData(v) ((byte*) &(v)[1]) -struct _CCEdge { - CCEdge *next; /* EHData.next */ - CCEdgeHDL eHDL; /* EHData.key */ +struct _CCGEdge { + CCGEdge *next; /* EHData.next */ + CCGEdgeHDL eHDL; /* EHData.key */ short numFaces, flags; float crease; - CCVert *v0,*v1; - CCFace **faces; + CCGVert *v0,*v1; + CCGFace **faces; // byte *levelData; // byte *userData; }; #define EDGE_getLevelData(e) ((byte*) &(e)[1]) -struct _CCFace { - CCFace *next; /* EHData.next */ - CCFaceHDL fHDL; /* EHData.key */ +struct _CCGFace { + CCGFace *next; /* EHData.next */ + CCGFaceHDL fHDL; /* EHData.key */ short numVerts, flags, pad1, pad2; -// CCVert **verts; -// CCEdge **edges; +// CCGVert **verts; +// CCGEdge **edges; // byte *centerData; // byte **gridData; // byte *userData; }; -#define FACE_getVerts(f) ((CCVert**) &(f)[1]) -#define FACE_getEdges(f) ((CCEdge**) &(FACE_getVerts(f)[(f)->numVerts])) +#define FACE_getVerts(f) ((CCGVert**) &(f)[1]) +#define FACE_getEdges(f) ((CCGEdge**) &(FACE_getVerts(f)[(f)->numVerts])) #define FACE_getCenterData(f) ((byte*) &(FACE_getEdges(f)[(f)->numVerts])) typedef enum { @@ -289,15 +295,15 @@ typedef enum { eSyncState_Partial, } SyncState; -struct _CSubSurf { - EHash *vMap; /* map of CCVertHDL -> Vert */ - EHash *eMap; /* map of CCEdgeHDL -> Edge */ - EHash *fMap; /* map of CCFaceHDL -> Face */ +struct _CCGSubSurf { + EHash *vMap; /* map of CCGVertHDL -> Vert */ + EHash *eMap; /* map of CCGEdgeHDL -> Edge */ + EHash *fMap; /* map of CCGFaceHDL -> Face */ CCGMeshIFC meshIFC; CCGAllocatorIFC allocatorIFC; - CCAllocHDL allocator; + CCGAllocatorHDL allocator; int subdivLevels; int numGrids; @@ -323,8 +329,8 @@ struct _CSubSurf { EHash *oldVMap, *oldEMap, *oldFMap; int lenTempArrays; - CCVert **tempVerts; - CCEdge **tempEdges; + CCGVert **tempVerts; + CCGEdge **tempEdges; }; #define CCGSUBSURF_alloc(ss, nb) ((ss)->allocatorIFC.alloc((ss)->allocator, nb)) @@ -333,8 +339,8 @@ struct _CSubSurf { /***/ -static CCVert *_vert_new(CCVertHDL vHDL, CSubSurf *ss) { - CCVert *v = CCGSUBSURF_alloc(ss, sizeof(CCVert) + ss->meshIFC.vertDataSize * (ss->subdivLevels+1) + ss->meshIFC.vertUserSize); +static CCGVert *_vert_new(CCGVertHDL vHDL, CCGSubSurf *ss) { + CCGVert *v = CCGSUBSURF_alloc(ss, sizeof(CCGVert) + ss->meshIFC.vertDataSize * (ss->subdivLevels+1) + ss->meshIFC.vertUserSize); byte *userData; v->vHDL = vHDL; @@ -343,13 +349,13 @@ static CCVert *_vert_new(CCVertHDL vHDL, CSubSurf *ss) { v->numEdges = v->numFaces = 0; v->flags = 0; - userData = CCS_getVertUserData(ss, v); + userData = ccgSubSurf_getVertUserData(ss, v); memset(userData, 0, ss->meshIFC.vertUserSize); if (ss->useAgeCounts) *((int*) &userData[ss->vertUserAgeOffset]) = ss->currentAge; return v; } -static void _vert_remEdge(CCVert *v, CCEdge *e) { +static void _vert_remEdge(CCGVert *v, CCGEdge *e) { int i; for (i=0; i<v->numEdges; i++) { if (v->edges[i]==e) { @@ -358,7 +364,7 @@ static void _vert_remEdge(CCVert *v, CCEdge *e) { } } } -static void _vert_remFace(CCVert *v, CCFace *f) { +static void _vert_remFace(CCGVert *v, CCGFace *f) { int i; for (i=0; i<v->numFaces; i++) { if (v->faces[i]==f) { @@ -367,25 +373,25 @@ static void _vert_remFace(CCVert *v, CCFace *f) { } } } -static void _vert_addEdge(CCVert *v, CCEdge *e, CSubSurf *ss) { +static void _vert_addEdge(CCGVert *v, CCGEdge *e, CCGSubSurf *ss) { v->edges = CCGSUBSURF_realloc(ss, v->edges, (v->numEdges+1)*sizeof(*v->edges), v->numEdges*sizeof(*v->edges)); v->edges[v->numEdges++] = e; } -static void _vert_addFace(CCVert *v, CCFace *f, CSubSurf *ss) { +static void _vert_addFace(CCGVert *v, CCGFace *f, CCGSubSurf *ss) { v->faces = CCGSUBSURF_realloc(ss, v->faces, (v->numFaces+1)*sizeof(*v->faces), v->numFaces*sizeof(*v->faces)); v->faces[v->numFaces++] = f; } -static CCEdge *_vert_findEdgeTo(CCVert *v, CCVert *vQ) { +static CCGEdge *_vert_findEdgeTo(CCGVert *v, CCGVert *vQ) { int i; for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse + CCGEdge *e = v->edges[v->numEdges-1-i]; // XXX, note reverse if ( (e->v0==v && e->v1==vQ) || (e->v1==v && e->v0==vQ)) return e; } return 0; } -static int _vert_isBoundary(CCVert *v) { +static int _vert_isBoundary(CCGVert *v) { int i; for (i=0; i<v->numEdges; i++) if (_edge_isBoundary(v->edges[i])) @@ -393,27 +399,27 @@ static int _vert_isBoundary(CCVert *v) { return 0; } -static void *_vert_getCo(CCVert *v, int lvl, int dataSize) { +static void *_vert_getCo(CCGVert *v, int lvl, int dataSize) { return &VERT_getLevelData(v)[lvl*dataSize]; } -static float *_vert_getNo(CCVert *v, int lvl, int dataSize, int normalDataOffset) { +static float *_vert_getNo(CCGVert *v, int lvl, int dataSize, int normalDataOffset) { return (float*) &VERT_getLevelData(v)[lvl*dataSize + normalDataOffset]; } -static void _vert_free(CCVert *v, CSubSurf *ss) { +static void _vert_free(CCGVert *v, CCGSubSurf *ss) { CCGSUBSURF_free(ss, v->edges); CCGSUBSURF_free(ss, v->faces); CCGSUBSURF_free(ss, v); } -static int VERT_seam(CCVert *v) { +static int VERT_seam(CCGVert *v) { return ((v->flags & Vert_eSeam) != 0); } /***/ -static CCEdge *_edge_new(CCEdgeHDL eHDL, CCVert *v0, CCVert *v1, float crease, CSubSurf *ss) { - CCEdge *e = CCGSUBSURF_alloc(ss, sizeof(CCEdge) + ss->meshIFC.vertDataSize *((ss->subdivLevels+1) + (1<<(ss->subdivLevels+1))-1) + ss->meshIFC.edgeUserSize); +static CCGEdge *_edge_new(CCGEdgeHDL eHDL, CCGVert *v0, CCGVert *v1, float crease, CCGSubSurf *ss) { + CCGEdge *e = CCGSUBSURF_alloc(ss, sizeof(CCGEdge) + ss->meshIFC.vertDataSize *((ss->subdivLevels+1) + (1<<(ss->subdivLevels+1))-1) + ss->meshIFC.edgeUserSize); byte *userData; e->eHDL = eHDL; @@ -426,13 +432,13 @@ static CCEdge *_edge_new(CCEdgeHDL eHDL, CCVert *v0, CCVert *v1, float crease, C _vert_addEdge(v0, e, ss); _vert_addEdge(v1, e, ss); - userData = CCS_getEdgeUserData(ss, e); + userData = ccgSubSurf_getEdgeUserData(ss, e); memset(userData, 0, ss->meshIFC.edgeUserSize); if (ss->useAgeCounts) *((int*) &userData[ss->edgeUserAgeOffset]) = ss->currentAge; return e; } -static void _edge_remFace(CCEdge *e, CCFace *f) { +static void _edge_remFace(CCGEdge *e, CCGFace *f) { int i; for (i=0; i<e->numFaces; i++) { if (e->faces[i]==f) { @@ -441,15 +447,15 @@ static void _edge_remFace(CCEdge *e, CCFace *f) { } } } -static void _edge_addFace(CCEdge *e, CCFace *f, CSubSurf *ss) { +static void _edge_addFace(CCGEdge *e, CCGFace *f, CCGSubSurf *ss) { e->faces = CCGSUBSURF_realloc(ss, e->faces, (e->numFaces+1)*sizeof(*e->faces), e->numFaces*sizeof(*e->faces)); e->faces[e->numFaces++] = f; } -static int _edge_isBoundary(CCEdge *e) { +static int _edge_isBoundary(CCGEdge *e) { return e->numFaces<2; } -static CCVert *_edge_getOtherVert(CCEdge *e, CCVert *vQ) { +static CCGVert *_edge_getOtherVert(CCGEdge *e, CCGVert *vQ) { if (vQ==e->v0) { return e->v1; } else { @@ -457,17 +463,17 @@ static CCVert *_edge_getOtherVert(CCEdge *e, CCVert *vQ) { } } -static void *_edge_getCo(CCEdge *e, int lvl, int x, int dataSize) { +static void *_edge_getCo(CCGEdge *e, int lvl, int x, int dataSize) { int levelBase = lvl + (1<<lvl) - 1; return &EDGE_getLevelData(e)[dataSize*(levelBase + x)]; } #if 0 -static float *_edge_getNo(CCEdge *e, int lvl, int x, int dataSize, int normalDataOffset) { +static float *_edge_getNo(CCGEdge *e, int lvl, int x, int dataSize, int normalDataOffset) { int levelBase = lvl + (1<<lvl) - 1; return (float*) &EDGE_getLevelData(e)[dataSize*(levelBase + x) + normalDataOffset]; } #endif -static void *_edge_getCoVert(CCEdge *e, CCVert *v, int lvl, int x, int dataSize) { +static void *_edge_getCoVert(CCGEdge *e, CCGVert *v, int lvl, int x, int dataSize) { int levelBase = lvl + (1<<lvl) - 1; if (v==e->v0) { return &EDGE_getLevelData(e)[dataSize*(levelBase + x)]; @@ -476,11 +482,11 @@ static void *_edge_getCoVert(CCEdge *e, CCVert *v, int lvl, int x, int dataSize) } } -static void _edge_free(CCEdge *e, CSubSurf *ss) { +static void _edge_free(CCGEdge *e, CCGSubSurf *ss) { CCGSUBSURF_free(ss, e->faces); CCGSUBSURF_free(ss, e); } -static void _edge_unlinkMarkAndFree(CCEdge *e, CSubSurf *ss) { +static void _edge_unlinkMarkAndFree(CCGEdge *e, CCGSubSurf *ss) { _vert_remEdge(e->v0, e); _vert_remEdge(e->v1, e); e->v0->flags |= Vert_eEffected; @@ -488,7 +494,7 @@ static void _edge_unlinkMarkAndFree(CCEdge *e, CSubSurf *ss) { _edge_free(e, ss); } -static float EDGE_getSharpness(CCEdge *e, int lvl) { +static float EDGE_getSharpness(CCGEdge *e, int lvl) { if (!lvl) return e->crease; else if (!e->crease) @@ -499,9 +505,9 @@ static float EDGE_getSharpness(CCEdge *e, int lvl) { return e->crease - lvl; } -static CCFace *_face_new(CCFaceHDL fHDL, CCVert **verts, CCEdge **edges, int numVerts, CSubSurf *ss) { +static CCGFace *_face_new(CCGFaceHDL fHDL, CCGVert **verts, CCGEdge **edges, int numVerts, CCGSubSurf *ss) { int maxGridSize = 1 + (1<<(ss->subdivLevels-1)); - CCFace *f = CCGSUBSURF_alloc(ss, sizeof(CCFace) + sizeof(CCVert*)*numVerts + sizeof(CCEdge*)*numVerts + ss->meshIFC.vertDataSize *(1 + numVerts*maxGridSize + numVerts*maxGridSize*maxGridSize) + ss->meshIFC.faceUserSize); + CCGFace *f = CCGSUBSURF_alloc(ss, sizeof(CCGFace) + sizeof(CCGVert*)*numVerts + sizeof(CCGEdge*)*numVerts + ss->meshIFC.vertDataSize *(1 + numVerts*maxGridSize + numVerts*maxGridSize*maxGridSize) + ss->meshIFC.faceUserSize); byte *userData; int i; @@ -516,39 +522,39 @@ static CCFace *_face_new(CCFaceHDL fHDL, CCVert **verts, CCEdge **edges, int num _edge_addFace(edges[i], f, ss); } - userData = CCS_getFaceUserData(ss, f); + userData = ccgSubSurf_getFaceUserData(ss, f); memset(userData, 0, ss->meshIFC.faceUserSize); if (ss->useAgeCounts) *((int*) &userData[ss->faceUserAgeOffset]) = ss->currentAge; return f; } -static void *_face_getIECo(CCFace *f, int lvl, int S, int x, int levels, int dataSize) { +static CCG_INLINE void *_face_getIECo(CCGFace *f, int lvl, int S, int x, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return &gridBase[dataSize*x*spacing]; } -static void *_face_getIFCo(CCFace *f, int lvl, int S, int x, int y, int levels, int dataSize) { +static CCG_INLINE void *_face_getIFCo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing)]; } -static float *_face_getIFNo(CCFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) { +static CCG_INLINE float *_face_getIFNo(CCGFace *f, int lvl, int S, int x, int y, int levels, int dataSize, int normalDataOffset) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); byte *gridBase = FACE_getCenterData(f) + dataSize*(1 + S*(maxGridSize + maxGridSize*maxGridSize)); return (float*) &gridBase[dataSize*(maxGridSize + (y*maxGridSize + x)*spacing) + normalDataOffset]; } -static int _face_getVertIndex(CCFace *f, CCVert *v) { +static int _face_getVertIndex(CCGFace *f, CCGVert *v) { int i; for (i=0; i<f->numVerts; i++) if (FACE_getVerts(f)[i]==v) return i; return -1; } -static void *_face_getIFCoEdge(CCFace *f, CCEdge *e, int lvl, int eX, int eY, int levels, int dataSize) { +static CCG_INLINE void *_face_getIFCoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize) { int maxGridSize = 1 + (1<<(levels-1)); int spacing = 1<<(levels-lvl); int S, x, y, cx, cy; @@ -578,10 +584,10 @@ static void *_face_getIFCoEdge(CCFace *f, CCEdge *e, int lvl, int eX, int eY, in } return _face_getIFCo(f, levels, S, cx, cy, levels, dataSize); } -static float *_face_getIFNoEdge(CCFace *f, CCEdge *e, int lvl, int eX, int eY, int levels, int dataSize, int normalDataOffset) { +static float *_face_getIFNoEdge(CCGFace *f, CCGEdge *e, int lvl, int eX, int eY, int levels, int dataSize, int normalDataOffset) { return (float*) ((byte*) _face_getIFCoEdge(f, e, lvl, eX, eY, levels, dataSize) + normalDataOffset); } -void _face_calcIFNo(CCFace *f, int lvl, int S, int x, int y, float *no, int levels, int dataSize) { +void _face_calcIFNo(CCGFace *f, int lvl, int S, int x, int y, float *no, int levels, int dataSize) { float *a = _face_getIFCo(f, lvl, S, x+0, y+0, levels, dataSize); float *b = _face_getIFCo(f, lvl, S, x+1, y+0, levels, dataSize); float *c = _face_getIFCo(f, lvl, S, x+1, y+1, levels, dataSize); @@ -607,10 +613,10 @@ void _face_calcIFNo(CCFace *f, int lvl, int S, int x, int y, float *no, int leve } } -static void _face_free(CCFace *f, CSubSurf *ss) { +static void _face_free(CCGFace *f, CCGSubSurf *ss) { CCGSUBSURF_free(ss, f); } -static void _face_unlinkMarkAndFree(CCFace *f, CSubSurf *ss) { +static void _face_unlinkMarkAndFree(CCGFace *f, CCGSubSurf *ss) { int j; for (j=0; j<f->numVerts; j++) { _vert_remFace(FACE_getVerts(f)[j], f); @@ -622,7 +628,7 @@ static void _face_unlinkMarkAndFree(CCFace *f, CSubSurf *ss) { /***/ -CSubSurf *CCS_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCAllocHDL allocator) { +CCGSubSurf *ccgSubSurf_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator) { if (!allocatorIFC) { allocatorIFC = _getStandardAllocatorIFC(); allocator = NULL; @@ -631,7 +637,7 @@ CSubSurf *CCS_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorI if (subdivLevels<1) { return NULL; } else { - CSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss)); + CCGSubSurf *ss = allocatorIFC->alloc(allocator, sizeof(*ss)); ss->allocatorIFC = *allocatorIFC; ss->allocator = allocator; @@ -670,9 +676,9 @@ CSubSurf *CCS_new(CCGMeshIFC *ifc, int subdivLevels, CCGAllocatorIFC *allocatorI } } -void CCS_free(CSubSurf *ss) { +void ccgSubSurf_free(CCGSubSurf *ss) { CCGAllocatorIFC allocatorIFC = ss->allocatorIFC; - CCAllocHDL allocator = ss->allocator; + CCGAllocatorHDL allocator = ss->allocator; if (ss->syncState) { _ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_free, ss); @@ -698,7 +704,7 @@ void CCS_free(CSubSurf *ss) { } } -CCGError CCS_setAllowEdgeCreation(CSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData) { +CCGError ccgSubSurf_setAllowEdgeCreation(CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData) { if (ss->defaultEdgeUserData) { CCGSUBSURF_free(ss, ss->defaultEdgeUserData); } @@ -715,7 +721,7 @@ CCGError CCS_setAllowEdgeCreation(CSubSurf *ss, int allowEdgeCreation, float def return eCCGError_None; } -void CCS_getAllowEdgeCreation(CSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r) { +void ccgSubSurf_getAllowEdgeCreation(CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r) { if (allowEdgeCreation_r) *allowEdgeCreation_r = ss->allowEdgeCreation; if (ss->allowEdgeCreation) { if (defaultCreaseValue_r) *defaultCreaseValue_r = ss->defaultCreaseValue; @@ -723,7 +729,7 @@ void CCS_getAllowEdgeCreation(CSubSurf *ss, int *allowEdgeCreation_r, float *def } } -CCGError CCS_setSubdivisionLevels(CSubSurf *ss, int subdivisionLevels) { +CCGError ccgSubSurf_setSubdivisionLevels(CCGSubSurf *ss, int subdivisionLevels) { if (subdivisionLevels<=0) { return eCCGError_InvalidValue; } else if (subdivisionLevels!=ss->subdivLevels) { @@ -740,7 +746,7 @@ CCGError CCS_setSubdivisionLevels(CSubSurf *ss, int subdivisionLevels) { return eCCGError_None; } -void CCS_getUseAgeCounts(CSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r) +void ccgSubSurf_getUseAgeCounts(CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r) { *useAgeCounts_r = ss->useAgeCounts; @@ -749,7 +755,7 @@ void CCS_getUseAgeCounts(CSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_ if (faceUserOffset_r) *faceUserOffset_r = ss->faceUserAgeOffset; } -CCGError CCS_setUseAgeCounts(CSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) { +CCGError ccgSubSurf_setUseAgeCounts(CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset) { if (useAgeCounts) { if ( (vertUserOffset+4>ss->meshIFC.vertUserSize) || (edgeUserOffset+4>ss->meshIFC.edgeUserSize) || @@ -769,7 +775,7 @@ CCGError CCS_setUseAgeCounts(CSubSurf *ss, int useAgeCounts, int vertUserOffset, return eCCGError_None; } -CCGError CCS_setCalcVertexNormals(CSubSurf *ss, int useVertNormals, int normalDataOffset) { +CCGError ccgSubSurf_setCalcVertexNormals(CCGSubSurf *ss, int useVertNormals, int normalDataOffset) { if (useVertNormals) { if (normalDataOffset<0 || normalDataOffset+12>ss->meshIFC.vertDataSize) { return eCCGError_InvalidValue; @@ -787,7 +793,7 @@ CCGError CCS_setCalcVertexNormals(CSubSurf *ss, int useVertNormals, int normalDa /***/ -CCGError CCS_initFullSync(CSubSurf *ss) { +CCGError ccgSubSurf_initFullSync(CCGSubSurf *ss) { if (ss->syncState!=eSyncState_None) { return eCCGError_InvalidSyncState; } @@ -813,7 +819,7 @@ CCGError CCS_initFullSync(CSubSurf *ss) { return eCCGError_None; } -CCGError CCS_initPartialSync(CSubSurf *ss) { +CCGError ccgSubSurf_initPartialSync(CCGSubSurf *ss) { if (ss->syncState!=eSyncState_None) { return eCCGError_InvalidSyncState; } @@ -825,12 +831,12 @@ CCGError CCS_initPartialSync(CSubSurf *ss) { return eCCGError_None; } -CCGError CCS_syncVertDel(CSubSurf *ss, CCVertHDL vHDL) { +CCGError ccgSubSurf_syncVertDel(CCGSubSurf *ss, CCGVertHDL vHDL) { if (ss->syncState!=eSyncState_Partial) { return eCCGError_InvalidSyncState; } else { void **prevp; - CCVert *v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); + CCGVert *v = _ehash_lookupWithPrev(ss->vMap, vHDL, &prevp); if (!v || v->numFaces || v->numEdges) { return eCCGError_InvalidValue; @@ -843,12 +849,12 @@ CCGError CCS_syncVertDel(CSubSurf *ss, CCVertHDL vHDL) { return eCCGError_None; } -CCGError CCS_syncEdgeDel(CSubSurf *ss, CCEdgeHDL eHDL) { +CCGError ccgSubSurf_syncEdgeDel(CCGSubSurf *ss, CCGEdgeHDL eHDL) { if (ss->syncState!=eSyncState_Partial) { return eCCGError_InvalidSyncState; } else { void **prevp; - CCEdge *e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); + CCGEdge *e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); if (!e || e->numFaces) { return eCCGError_InvalidValue; @@ -861,12 +867,12 @@ CCGError CCS_syncEdgeDel(CSubSurf *ss, CCEdgeHDL eHDL) { return eCCGError_None; } -CCGError CCS_syncFaceDel(CSubSurf *ss, CCFaceHDL fHDL) { +CCGError ccgSubSurf_syncFaceDel(CCGSubSurf *ss, CCGFaceHDL fHDL) { if (ss->syncState!=eSyncState_Partial) { return eCCGError_InvalidSyncState; } else { void **prevp; - CCFace *f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); + CCGFace *f = _ehash_lookupWithPrev(ss->fMap, fHDL, &prevp); if (!f) { return eCCGError_InvalidValue; @@ -879,9 +885,9 @@ CCGError CCS_syncFaceDel(CSubSurf *ss, CCFaceHDL fHDL) { return eCCGError_None; } -CCGError CCS_syncVert(CSubSurf *ss, CCVertHDL vHDL, void *vertData, int seam, CCVert **v_r) { +CCGError ccgSubSurf_syncVert(CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r) { void **prevp; - CCVert *v = NULL; + CCGVert *v = NULL; short seamflag = (seam)? Vert_eSeam: 0; if (ss->syncState==eSyncState_Partial) { @@ -898,12 +904,12 @@ CCGError CCS_syncVert(CSubSurf *ss, CCVertHDL vHDL, void *vertData, int seam, CC v->flags = Vert_eEffected|seamflag; for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; + CCGEdge *e = v->edges[i]; e->v0->flags |= Vert_eEffected; e->v1->flags |= Vert_eEffected; } for (i=0; i<v->numFaces; i++) { - CCFace *f = v->faces[i]; + CCGFace *f = v->faces[i]; for (j=0; j<f->numVerts; j++) { FACE_getVerts(f)[j]->flags |= Vert_eEffected; } @@ -936,15 +942,15 @@ CCGError CCS_syncVert(CSubSurf *ss, CCVertHDL vHDL, void *vertData, int seam, CC return eCCGError_None; } -CCGError CCS_syncEdge(CSubSurf *ss, CCEdgeHDL eHDL, CCVertHDL e_vHDL0, CCVertHDL e_vHDL1, float crease, CCEdge **e_r) { +CCGError ccgSubSurf_syncEdge(CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r) { void **prevp; - CCEdge *e = NULL, *eNew; + CCGEdge *e = NULL, *eNew; if (ss->syncState==eSyncState_Partial) { e = _ehash_lookupWithPrev(ss->eMap, eHDL, &prevp); if (!e || e->v0->vHDL!=e_vHDL0 || e->v1->vHDL!=e_vHDL1 || crease!=e->crease) { - CCVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); - CCVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); + CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); + CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); eNew = _edge_new(eHDL, v0, v1, crease, ss); @@ -969,8 +975,8 @@ CCGError CCS_syncEdge(CSubSurf *ss, CCEdgeHDL eHDL, CCVertHDL e_vHDL0, CCVertHDL e = _ehash_lookupWithPrev(ss->oldEMap, eHDL, &prevp); if (!e || e->v0->vHDL!=e_vHDL0 || e->v1->vHDL!=e_vHDL1|| e->crease!=crease) { - CCVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); - CCVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); + CCGVert *v0 = _ehash_lookup(ss->vMap, e_vHDL0); + CCGVert *v1 = _ehash_lookup(ss->vMap, e_vHDL1); e = _edge_new(eHDL, v0, v1, crease, ss); _ehash_insert(ss->eMap, (EHEntry*) e); e->v0->flags |= Vert_eEffected; @@ -990,9 +996,9 @@ CCGError CCS_syncEdge(CSubSurf *ss, CCEdgeHDL eHDL, CCVertHDL e_vHDL0, CCVertHDL return eCCGError_None; } -CCGError CCS_syncFace(CSubSurf *ss, CCFaceHDL fHDL, int numVerts, CCVertHDL *vHDLs, CCFace **f_r) { +CCGError ccgSubSurf_syncFace(CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r) { void **prevp; - CCFace *f = NULL, *fNew; + CCGFace *f = NULL, *fNew; int j, k, topologyChanged = 0; if (numVerts>ss->lenTempArrays) { @@ -1057,12 +1063,12 @@ CCGError CCS_syncFace(CSubSurf *ss, CCFaceHDL fHDL, int numVerts, CCVertHDL *vHD if (!ss->tempEdges[k]) { if (ss->allowEdgeCreation) { - CCEdge *e = ss->tempEdges[k] = _edge_new((CCEdgeHDL) -1, ss->tempVerts[k], ss->tempVerts[(k+1)%numVerts], ss->defaultCreaseValue, ss); + CCGEdge *e = ss->tempEdges[k] = _edge_new((CCGEdgeHDL) -1, ss->tempVerts[k], ss->tempVerts[(k+1)%numVerts], ss->defaultCreaseValue, ss); _ehash_insert(ss->eMap, (EHEntry*) e); e->v0->flags |= Vert_eEffected; e->v1->flags |= Vert_eEffected; if (ss->meshIFC.edgeUserSize) { - memcpy(CCS_getEdgeUserData(ss, e), ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize); + memcpy(ccgSubSurf_getEdgeUserData(ss, e), ss->defaultEdgeUserData, ss->meshIFC.edgeUserSize); } } else { return eCCGError_InvalidValue; @@ -1104,12 +1110,12 @@ CCGError CCS_syncFace(CSubSurf *ss, CCFaceHDL fHDL, int numVerts, CCVertHDL *vHD return eCCGError_None; } -static void CCS__sync(CSubSurf *ss); -CCGError CCS_processSync(CSubSurf *ss) { +static void ccgSubSurf__sync(CCGSubSurf *ss); +CCGError ccgSubSurf_processSync(CCGSubSurf *ss) { if (ss->syncState==eSyncState_Partial) { ss->syncState = eSyncState_None; - CCS__sync(ss); + ccgSubSurf__sync(ss); } else if (ss->syncState) { _ehash_free(ss->oldFMap, (EHEntryFreeFP) _face_unlinkMarkAndFree, ss); _ehash_free(ss->oldEMap, (EHEntryFreeFP) _edge_unlinkMarkAndFree, ss); @@ -1125,7 +1131,7 @@ CCGError CCS_processSync(CSubSurf *ss) { ss->syncState = eSyncState_None; - CCS__sync(ss); + ccgSubSurf__sync(ss); } else { return eCCGError_InvalidSyncState; } @@ -1133,31 +1139,689 @@ CCGError CCS_processSync(CSubSurf *ss) { return eCCGError_None; } -static void CCS__sync(CSubSurf *ss) { - CCVert **effectedV; - CCEdge **effectedE; - CCFace **effectedF; - int numEffectedV, numEffectedE, numEffectedF; +#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) +#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize) +static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss, + CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF, + int numEffectedV, int numEffectedE, int numEffectedF) { + int i,ptrIdx; int subdivLevels = ss->subdivLevels; + int lvl = ss->subdivLevels; + int edgeSize = 1 + (1<<lvl); + int gridSize = 1 + (1<<(lvl-1)); + int normalDataOffset = ss->normalDataOffset; + int vertDataSize = ss->meshIFC.vertDataSize; + + #pragma omp parallel for private(ptrIdx) schedule(static) + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + float no[3]; + + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize-1; y++) + for (x=0; x<gridSize-1; x++) + NormZero(FACE_getIFNo(f, lvl, S, x, y)); + + if (FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected) + for (x=0; x<gridSize-1; x++) + NormZero(FACE_getIFNo(f, lvl, S, x, gridSize-1)); + if (FACE_getEdges(f)[S]->flags&Edge_eEffected) + for (y=0; y<gridSize-1; y++) + NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, y)); + if (FACE_getVerts(f)[S]->flags&Vert_eEffected) + NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, gridSize-1)); + } + + for (S=0; S<f->numVerts; S++) { + int yLimit = !(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected); + int xLimit = !(FACE_getEdges(f)[S]->flags&Edge_eEffected); + int yLimitNext = xLimit; + int xLimitPrev = yLimit; + + for (y=0; y<gridSize - 1; y++) { + for (x=0; x<gridSize - 1; x++) { + int xPlusOk = (!xLimit || x<gridSize-2); + int yPlusOk = (!yLimit || y<gridSize-2); + + FACE_calcIFNo(f, lvl, S, x, y, no); + + NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+0), no); + if (xPlusOk) + NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+0), no); + if (yPlusOk) + NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+1), no); + if (xPlusOk && yPlusOk) { + if (x<gridSize-2 || y<gridSize-2 || FACE_getVerts(f)[S]->flags&Vert_eEffected) { + NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+1), no); + } + } + + if (x==0 && y==0) { + int K; + + if (!yLimitNext || 1<gridSize-1) + NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, 1), no); + if (!xLimitPrev || 1<gridSize-1) + NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, 1, 0), no); + + for (K=0; K<f->numVerts; K++) { + if (K!=S) { + NormAdd(FACE_getIFNo(f, lvl, K, 0, 0), no); + } + } + } else if (y==0) { + NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x), no); + if (!yLimitNext || x<gridSize-2) + NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x+1), no); + } else if (x==0) { + NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y, 0), no); + if (!xLimitPrev || y<gridSize-2) + NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y+1, 0), no); + } + } + } + } + } + // XXX can I reduce the number of normalisations here? + for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { + CCGVert *v = (CCGVert*) effectedV[ptrIdx]; + float length, *no = _vert_getNo(v, lvl, vertDataSize, normalDataOffset); + + NormZero(no); + + for (i=0; i<v->numFaces; i++) { + CCGFace *f = v->faces[i]; + NormAdd(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1)); + } + + length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]); + + if (length>EPSILON) { + float invLength = 1.0f/length; + no[0] *= invLength; + no[1] *= invLength; + no[2] *= invLength; + } else { + NormZero(no); + } + + for (i=0; i<v->numFaces; i++) { + CCGFace *f = v->faces[i]; + NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1), no); + } + } + for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { + CCGEdge *e = (CCGEdge*) effectedE[ptrIdx]; + + if (e->numFaces) { + CCGFace *fLast = e->faces[e->numFaces-1]; + int x; + + for (i=0; i<e->numFaces-1; i++) { + CCGFace *f = e->faces[i]; + + for (x=1; x<edgeSize-1; x++) { + NormAdd(_face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), + _face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); + } + } + + for (i=0; i<e->numFaces-1; i++) { + CCGFace *f = e->faces[i]; + + for (x=1; x<edgeSize-1; x++) { + NormCopy(_face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), + _face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); + } + } + } + } + + #pragma omp parallel for private(ptrIdx) schedule(static) + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + for (S=0; S<f->numVerts; S++) { + NormCopy(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1), + FACE_getIFNo(f, lvl, S, gridSize-1, 0)); + } + + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize; y++) { + for (x=0; x<gridSize; x++) { + float *no = FACE_getIFNo(f, lvl, S, x, y); + float length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]); + + if (length>EPSILON) { + float invLength = 1.0f/length; + no[0] *= invLength; + no[1] *= invLength; + no[2] *= invLength; + } else { + NormZero(no); + } + } + } + } + } +} +#undef FACE_getIFNo + +#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize) +#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize) +#define FACE_getIECo(f, lvl, S, x) _face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize) +#define FACE_getIFCo(f, lvl, S, x, y) _face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize) +static void ccgSubSurf__calcSubdivLevel(CCGSubSurf *ss, + CCGVert **effectedV, CCGEdge **effectedE, CCGFace **effectedF, + int numEffectedV, int numEffectedE, int numEffectedF, int curLvl) { + int subdivLevels = ss->subdivLevels; + int edgeSize = 1 + (1<<curLvl); + int gridSize = 1 + (1<<(curLvl-1)); + int nextLvl = curLvl+1; + int ptrIdx, cornerIdx, i; int vertDataSize = ss->meshIFC.vertDataSize; - int i,ptrIdx,cornerIdx; - int S,x,y; void *q = ss->q, *r = ss->r; + + #pragma omp parallel for private(ptrIdx) schedule(static) + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + /* interior face midpoints + * o old interior face points + */ + for (S=0; S<f->numVerts; S++) { + for (y=0; y<gridSize-1; y++) { + for (x=0; x<gridSize-1; x++) { + int fx = 1 + 2*x; + int fy = 1 + 2*y; + void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y+0); + void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y+0); + void *co2 = FACE_getIFCo(f, curLvl, S, x+1, y+1); + void *co3 = FACE_getIFCo(f, curLvl, S, x+0, y+1); + void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); + + VertDataAvg4(co, co0, co1, co2, co3); + } + } + } + + /* interior edge midpoints + * o old interior edge points + * o new interior face midpoints + */ + for (S=0; S<f->numVerts; S++) { + for (x=0; x<gridSize-1; x++) { + int fx = x*2 + 1; + void *co0 = FACE_getIECo(f, curLvl, S, x+0); + void *co1 = FACE_getIECo(f, curLvl, S, x+1); + void *co2 = FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx); + void *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1); + void *co = FACE_getIECo(f, nextLvl, S, fx); + + VertDataAvg4(co, co0, co1, co2, co3); + } + + /* interior face interior edge midpoints + * o old interior face points + * o new interior face midpoints + */ + + /* vertical */ + for (x=1; x<gridSize-1; x++) { + for (y=0; y<gridSize-1; y++) { + int fx = x*2; + int fy = y*2+1; + void *co0 = FACE_getIFCo(f, curLvl, S, x, y+0); + void *co1 = FACE_getIFCo(f, curLvl, S, x, y+1); + void *co2 = FACE_getIFCo(f, nextLvl, S, fx-1, fy); + void *co3 = FACE_getIFCo(f, nextLvl, S, fx+1, fy); + void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); + + VertDataAvg4(co, co0, co1, co2, co3); + } + } + + /* horizontal */ + for (y=1; y<gridSize-1; y++) { + for (x=0; x<gridSize-1; x++) { + int fx = x*2+1; + int fy = y*2; + void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y); + void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y); + void *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy-1); + void *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy+1); + void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); + + VertDataAvg4(co, co0, co1, co2, co3); + } + } + } + } + + /* exterior edge midpoints + * o old exterior edge points + * o new interior face midpoints + */ + for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { + CCGEdge *e = (CCGEdge*) effectedE[ptrIdx]; + float sharpness = EDGE_getSharpness(e, curLvl); + int x, j; + + if (_edge_isBoundary(e) || sharpness>1.0) { + for (x=0; x<edgeSize-1; x++) { + int fx = x*2 + 1; + void *co0 = EDGE_getCo(e, curLvl, x+0); + void *co1 = EDGE_getCo(e, curLvl, x+1); + void *co = EDGE_getCo(e, nextLvl, fx); + + VertDataCopy(co, co0); + VertDataAdd(co, co1); + VertDataMulN(co, 0.5); + } + } else { + for (x=0; x<edgeSize-1; x++) { + int fx = x*2 + 1; + void *co0 = EDGE_getCo(e, curLvl, x+0); + void *co1 = EDGE_getCo(e, curLvl, x+1); + void *co = EDGE_getCo(e, nextLvl, fx); + int numFaces = 0; + + VertDataCopy(q, co0); + VertDataAdd(q, co1); + + for (j=0; j<e->numFaces; j++) { + CCGFace *f = e->faces[j]; + VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize)); + numFaces++; + } + + VertDataMulN(q, 1.0f/(2.0f+numFaces)); + + VertDataCopy(r, co0); + VertDataAdd(r, co1); + VertDataMulN(r, 0.5); + + VertDataCopy(co, q); + VertDataSub(r, q); + VertDataMulN(r, sharpness); + VertDataAdd(co, r); + } + } + } + + /* exterior vertex shift + * o old vertex points (shifting) + * o old exterior edge points + * o new interior face midpoints + */ + for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { + CCGVert *v = (CCGVert*) effectedV[ptrIdx]; + void *co = VERT_getCo(v, curLvl); + void *nCo = VERT_getCo(v, nextLvl); + int sharpCount = 0, allSharp = 1; + float avgSharpness = 0.0; + int j, seam = VERT_seam(v), seamEdges = 0; + + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; + float sharpness = EDGE_getSharpness(e, curLvl); + + if (seam && _edge_isBoundary(e)) + seamEdges++; + + if (sharpness!=0.0f) { + sharpCount++; + avgSharpness += sharpness; + } else { + allSharp = 0; + } + } + + if(sharpCount) { + avgSharpness /= sharpCount; + if (avgSharpness>1.0) { + avgSharpness = 1.0; + } + } + + if (seam && seamEdges < 2) + seam = 0; + + if (!v->numEdges) { + VertDataCopy(nCo, co); + } else if (_vert_isBoundary(v)) { + int numBoundary = 0; + + VertDataZero(r); + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; + if (_edge_isBoundary(e)) { + VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); + numBoundary++; + } + } + + VertDataCopy(nCo, co); + VertDataMulN(nCo, 0.75); + VertDataMulN(r, 0.25f/numBoundary); + VertDataAdd(nCo, r); + } else { + int cornerIdx = (1 + (1<<(curLvl))) - 2; + int numEdges = 0, numFaces = 0; + + VertDataZero(q); + for (j=0; j<v->numFaces; j++) { + CCGFace *f = v->faces[j]; + VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx)); + numFaces++; + } + VertDataMulN(q, 1.0f/numFaces); + VertDataZero(r); + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; + VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize)); + numEdges++; + } + VertDataMulN(r, 1.0f/numEdges); + + VertDataCopy(nCo, co); + VertDataMulN(nCo, numEdges-2.0f); + VertDataAdd(nCo, q); + VertDataAdd(nCo, r); + VertDataMulN(nCo, 1.0f/numEdges); + } + + if ((sharpCount>1 && v->numFaces) || seam) { + VertDataZero(q); + + if (seam) { + avgSharpness = 1.0f; + sharpCount = seamEdges; + allSharp = 1; + } + + for (j=0; j<v->numEdges; j++) { + CCGEdge *e = v->edges[j]; + float sharpness = EDGE_getSharpness(e, curLvl); + + if (seam) { + if (_edge_isBoundary(e)) + VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); + } else if (sharpness != 0.0) { + VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); + } + } + + VertDataMulN(q, (float) 1/sharpCount); + + if (sharpCount!=2 || allSharp) { + // q = q + (co-q)*avgSharpness + VertDataCopy(r, co); + VertDataSub(r, q); + VertDataMulN(r, avgSharpness); + VertDataAdd(q, r); + } + + // r = co*.75 + q*.25 + VertDataCopy(r, co); + VertDataMulN(r, .75); + VertDataMulN(q, .25); + VertDataAdd(r, q); + + // nCo = nCo + (r-nCo)*avgSharpness + VertDataSub(r, nCo); + VertDataMulN(r, avgSharpness); + VertDataAdd(nCo, r); + } + } + + /* exterior edge interior shift + * o old exterior edge midpoints (shifting) + * o old exterior edge midpoints + * o new interior face midpoints + */ + for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { + CCGEdge *e = (CCGEdge*) effectedE[ptrIdx]; + float sharpness = EDGE_getSharpness(e, curLvl); + int sharpCount = 0; + float avgSharpness = 0.0; + int x, j; + + if (sharpness!=0.0f) { + sharpCount = 2; + avgSharpness += sharpness; + + if (avgSharpness>1.0) { + avgSharpness = 1.0; + } + } else { + sharpCount = 0; + avgSharpness = 0; + } + + if (_edge_isBoundary(e) && (!e->numFaces || sharpCount<2)) { + for (x=1; x<edgeSize-1; x++) { + int fx = x*2; + void *co = EDGE_getCo(e, curLvl, x); + void *nCo = EDGE_getCo(e, nextLvl, fx); + VertDataCopy(r, EDGE_getCo(e, curLvl, x-1)); + VertDataAdd(r, EDGE_getCo(e, curLvl, x+1)); + VertDataMulN(r, 0.5); + VertDataCopy(nCo, co); + VertDataMulN(nCo, 0.75); + VertDataMulN(r, 0.25); + VertDataAdd(nCo, r); + } + } else { + for (x=1; x<edgeSize-1; x++) { + int fx = x*2; + void *co = EDGE_getCo(e, curLvl, x); + void *nCo = EDGE_getCo(e, nextLvl, fx); + int numFaces = 0; + + VertDataZero(q); + VertDataZero(r); + VertDataAdd(r, EDGE_getCo(e, curLvl, x-1)); + VertDataAdd(r, EDGE_getCo(e, curLvl, x+1)); + for (j=0; j<e->numFaces; j++) { + CCGFace *f = e->faces[j]; + VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize)); + VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize)); + + VertDataAdd(r, _face_getIFCoEdge(f, e, curLvl, x, 1, subdivLevels, vertDataSize)); + numFaces++; + } + VertDataMulN(q, 1.0/(numFaces*2.0f)); + VertDataMulN(r, 1.0/(2.0f + numFaces)); + + VertDataCopy(nCo, co); + VertDataMulN(nCo, (float) numFaces); + VertDataAdd(nCo, q); + VertDataAdd(nCo, r); + VertDataMulN(nCo, 1.0f/(2+numFaces)); + + if (sharpCount==2) { + VertDataCopy(q, co); + VertDataMulN(q, 6.0f); + VertDataAdd(q, EDGE_getCo(e, curLvl, x-1)); + VertDataAdd(q, EDGE_getCo(e, curLvl, x+1)); + VertDataMulN(q, 1/8.0f); + + VertDataSub(q, nCo); + VertDataMulN(q, avgSharpness); + VertDataAdd(nCo, q); + } + } + } + } + + #pragma omp parallel private(ptrIdx) + { + void *q, *r; + + #pragma omp critical + { + q = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); + r = CCGSUBSURF_alloc(ss, ss->meshIFC.vertDataSize); + } + + #pragma omp for schedule(static) + for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { + CCGFace *f = (CCGFace*) effectedF[ptrIdx]; + int S, x, y; + + /* interior center point shift + * o old face center point (shifting) + * o old interior edge points + * o new interior face midpoints + */ + VertDataZero(q); + for (S=0; S<f->numVerts; S++) { + VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1)); + } + VertDataMulN(q, 1.0f/f->numVerts); + VertDataZero(r); + for (S=0; S<f->numVerts; S++) { + VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1)); + } + VertDataMulN(r, 1.0f/f->numVerts); + + VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f); + VertDataAdd(FACE_getCenterData(f), q); + VertDataAdd(FACE_getCenterData(f), r); + VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); + + for (S=0; S<f->numVerts; S++) { + /* interior face shift + * o old interior face point (shifting) + * o new interior edge midpoints + * o new interior face midpoints + */ + for (x=1; x<gridSize-1; x++) { + for (y=1; y<gridSize-1; y++) { + int fx = x*2; + int fy = y*2; + void *co = FACE_getIFCo(f, curLvl, S, x, y); + void *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy); + + VertDataAvg4(q, FACE_getIFCo(f, nextLvl, S, fx-1, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+1, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+1, fy+1), + FACE_getIFCo(f, nextLvl, S, fx-1, fy+1)); + + VertDataAvg4(r, FACE_getIFCo(f, nextLvl, S, fx-1, fy+0), + FACE_getIFCo(f, nextLvl, S, fx+1, fy+0), + FACE_getIFCo(f, nextLvl, S, fx+0, fy-1), + FACE_getIFCo(f, nextLvl, S, fx+0, fy+1)); + + VertDataCopy(nCo, co); + VertDataSub(nCo, q); + VertDataMulN(nCo, 0.25f); + VertDataAdd(nCo, r); + } + } + + /* interior edge interior shift + * o old interior edge point (shifting) + * o new interior edge midpoints + * o new interior face midpoints + */ + for (x=1; x<gridSize-1; x++) { + int fx = x*2; + void *co = FACE_getIECo(f, curLvl, S, x); + void *nCo = FACE_getIECo(f, nextLvl, S, fx); + + VertDataAvg4(q, FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx-1), + FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx+1), + FACE_getIFCo(f, nextLvl, S, fx+1, +1), + FACE_getIFCo(f, nextLvl, S, fx-1, +1)); + + VertDataAvg4(r, FACE_getIECo(f, nextLvl, S, fx-1), + FACE_getIECo(f, nextLvl, S, fx+1), + FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx), + FACE_getIFCo(f, nextLvl, S, fx, 1)); + + VertDataCopy(nCo, co); + VertDataSub(nCo, q); + VertDataMulN(nCo, 0.25f); + VertDataAdd(nCo, r); + } + } + } + + #pragma omp critical + { + CCGSUBSURF_free(ss, q); + CCGSUBSURF_free(ss, r); + } + } + + /* copy down */ + edgeSize = 1 + (1<<(nextLvl)); + gridSize = 1 + (1<<((nextLvl)-1)); + cornerIdx = gridSize-1; + + #pragma omp parallel for private(i) schedule(static) + for (i=0; i<numEffectedE; i++) { + CCGEdge *e = effectedE[i]; + VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl)); + VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl)); + } + + #pragma omp parallel for private(i) schedule(static) + for (i=0; i<numEffectedF; i++) { + CCGFace *f = effectedF[i]; + int S, x; + + for (S=0; S<f->numVerts; S++) { + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; + + VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f)); + VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f)); + VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl)); + VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx)); + for (x=1; x<gridSize-1; x++) { + void *co = FACE_getIECo(f, nextLvl, S, x); + VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co); + VertDataCopy(FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 0, x), co); + } + for (x=0; x<gridSize-1; x++) { + int eI = gridSize-1-x; + VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize)); + VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize)); + } + } + } +} + + +static void ccgSubSurf__sync(CCGSubSurf *ss) { + CCGVert **effectedV; + CCGEdge **effectedE; + CCGFace **effectedF; + int numEffectedV, numEffectedE, numEffectedF; + int subdivLevels = ss->subdivLevels; + int vertDataSize = ss->meshIFC.vertDataSize; + int i, j, ptrIdx, S; int curLvl, nextLvl; - int j; + void *q = ss->q, *r = ss->r; effectedV = CCGSUBSURF_alloc(ss, sizeof(*effectedV)*ss->vMap->numEntries); effectedE = CCGSUBSURF_alloc(ss, sizeof(*effectedE)*ss->eMap->numEntries); effectedF = CCGSUBSURF_alloc(ss, sizeof(*effectedF)*ss->fMap->numEntries); numEffectedV = numEffectedE = numEffectedF = 0; for (i=0; i<ss->vMap->curSize; i++) { - CCVert *v = (CCVert*) ss->vMap->buckets[i]; + CCGVert *v = (CCGVert*) ss->vMap->buckets[i]; for (; v; v = v->next) { if (v->flags&Vert_eEffected) { effectedV[numEffectedV++] = v; for (j=0; j<v->numEdges; j++) { - CCEdge *e = v->edges[j]; + CCGEdge *e = v->edges[j]; if (!(e->flags&Edge_eEffected)) { effectedE[numEffectedE++] = e; e->flags |= Edge_eEffected; @@ -1165,7 +1829,7 @@ static void CCS__sync(CSubSurf *ss) { } for (j=0; j<v->numFaces; j++) { - CCFace *f = v->faces[j]; + CCGFace *f = v->faces[j]; if (!(f->flags&Face_eEffected)) { effectedF[numEffectedF++] = f; f->flags |= Face_eEffected; @@ -1175,15 +1839,11 @@ static void CCS__sync(CSubSurf *ss) { } } -#define VERT_getCo(v, lvl) _vert_getCo(v, lvl, vertDataSize) -#define EDGE_getCo(e, lvl, x) _edge_getCo(e, lvl, x, vertDataSize) -#define FACE_getIECo(f, lvl, S, x) _face_getIECo(f, lvl, S, x, subdivLevels, vertDataSize) -#define FACE_getIFCo(f, lvl, S, x, y) _face_getIFCo(f, lvl, S, x, y, subdivLevels, vertDataSize) curLvl = 0; nextLvl = curLvl+1; for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = effectedF[ptrIdx]; + CCGFace *f = effectedF[ptrIdx]; void *co = FACE_getCenterData(f); VertDataZero(co); for (i=0; i<f->numVerts; i++) { @@ -1194,7 +1854,7 @@ static void CCS__sync(CSubSurf *ss) { f->flags = 0; } for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { - CCEdge *e = effectedE[ptrIdx]; + CCGEdge *e = effectedE[ptrIdx]; void *co = EDGE_getCo(e, nextLvl, 1); float sharpness = EDGE_getSharpness(e, curLvl); @@ -1207,7 +1867,7 @@ static void CCS__sync(CSubSurf *ss) { VertDataCopy(q, VERT_getCo(e->v0, curLvl)); VertDataAdd(q, VERT_getCo(e->v1, curLvl)); for (i=0; i<e->numFaces; i++) { - CCFace *f = e->faces[i]; + CCGFace *f = e->faces[i]; VertDataAdd(q, FACE_getCenterData(f)); numFaces++; } @@ -1226,7 +1886,7 @@ static void CCS__sync(CSubSurf *ss) { // edge flags cleared later } for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { - CCVert *v = effectedV[ptrIdx]; + CCGVert *v = effectedV[ptrIdx]; void *co = VERT_getCo(v, curLvl); void *nCo = VERT_getCo(v, nextLvl); int sharpCount = 0, allSharp = 1; @@ -1234,7 +1894,7 @@ static void CCS__sync(CSubSurf *ss) { int seam = VERT_seam(v), seamEdges = 0; for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; + CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl); if (seam && _edge_isBoundary(e)) @@ -1265,7 +1925,7 @@ static void CCS__sync(CSubSurf *ss) { VertDataZero(r); for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; + CCGEdge *e = v->edges[i]; if (_edge_isBoundary(e)) { VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl)); numBoundary++; @@ -1280,14 +1940,14 @@ static void CCS__sync(CSubSurf *ss) { VertDataZero(q); for (i=0; i<v->numFaces; i++) { - CCFace *f = v->faces[i]; + CCGFace *f = v->faces[i]; VertDataAdd(q, FACE_getCenterData(f)); numFaces++; } VertDataMulN(q, 1.0f/numFaces); VertDataZero(r); for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; + CCGEdge *e = v->edges[i]; VertDataAdd(r, VERT_getCo(_edge_getOtherVert(e, v), curLvl)); numEdges++; } @@ -1310,16 +1970,16 @@ static void CCS__sync(CSubSurf *ss) { } for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; + CCGEdge *e = v->edges[i]; float sharpness = EDGE_getSharpness(e, curLvl); if (seam) { if (_edge_isBoundary(e)) { - CCVert *oV = _edge_getOtherVert(e, v); + CCGVert *oV = _edge_getOtherVert(e, v); VertDataAdd(q, VERT_getCo(oV, curLvl)); } } else if (sharpness != 0.0) { - CCVert *oV = _edge_getOtherVert(e, v); + CCGVert *oV = _edge_getOtherVert(e, v); VertDataAdd(q, VERT_getCo(oV, curLvl)); } } @@ -1351,34 +2011,34 @@ static void CCS__sync(CSubSurf *ss) { if (ss->useAgeCounts) { for (i=0; i<numEffectedV; i++) { - CCVert *v = effectedV[i]; - byte *userData = CCS_getVertUserData(ss, v); + CCGVert *v = effectedV[i]; + byte *userData = ccgSubSurf_getVertUserData(ss, v); *((int*) &userData[ss->vertUserAgeOffset]) = ss->currentAge; } for (i=0; i<numEffectedE; i++) { - CCEdge *e = effectedE[i]; - byte *userData = CCS_getEdgeUserData(ss, e); + CCGEdge *e = effectedE[i]; + byte *userData = ccgSubSurf_getEdgeUserData(ss, e); *((int*) &userData[ss->edgeUserAgeOffset]) = ss->currentAge; } for (i=0; i<numEffectedF; i++) { - CCFace *f = effectedF[i]; - byte *userData = CCS_getFaceUserData(ss, f); + CCGFace *f = effectedF[i]; + byte *userData = ccgSubSurf_getFaceUserData(ss, f); *((int*) &userData[ss->faceUserAgeOffset]) = ss->currentAge; } } for (i=0; i<numEffectedE; i++) { - CCEdge *e = effectedE[i]; + CCGEdge *e = effectedE[i]; VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl)); VertDataCopy(EDGE_getCo(e, nextLvl, 2), VERT_getCo(e->v1, nextLvl)); } for (i=0; i<numEffectedF; i++) { - CCFace *f = effectedF[i]; + CCGFace *f = effectedF[i]; for (S=0; S<f->numVerts; S++) { - CCEdge *e = FACE_getEdges(f)[S]; - CCEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f)); VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f)); @@ -1391,684 +2051,428 @@ static void CCS__sync(CSubSurf *ss) { } for (curLvl=1; curLvl<subdivLevels; curLvl++) { - int edgeSize = 1 + (1<<curLvl); - int gridSize = 1 + (1<<(curLvl-1)); - nextLvl = curLvl+1; + ccgSubSurf__calcSubdivLevel(ss, + effectedV, effectedE, effectedF, + numEffectedV, numEffectedE, numEffectedF, curLvl); + } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; + if (ss->calcVertNormals) + ccgSubSurf__calcVertNormals(ss, + effectedV, effectedE, effectedF, + numEffectedV, numEffectedE, numEffectedF); - /* interior face midpoints - * o old interior face points - */ - for (S=0; S<f->numVerts; S++) { - for (y=0; y<gridSize-1; y++) { - for (x=0; x<gridSize-1; x++) { - int fx = 1 + 2*x; - int fy = 1 + 2*y; - void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y+0); - void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y+0); - void *co2 = FACE_getIFCo(f, curLvl, S, x+1, y+1); - void *co3 = FACE_getIFCo(f, curLvl, S, x+0, y+1); - void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(co, co0, co1, co2, co3); - } - } - } - - /* interior edge midpoints - * o old interior edge points - * o new interior face midpoints - */ - for (S=0; S<f->numVerts; S++) { - for (x=0; x<gridSize-1; x++) { - int fx = x*2 + 1; - void *co0 = FACE_getIECo(f, curLvl, S, x+0); - void *co1 = FACE_getIECo(f, curLvl, S, x+1); - void *co2 = FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx); - void *co3 = FACE_getIFCo(f, nextLvl, S, fx, 1); - void *co = FACE_getIECo(f, nextLvl, S, fx); - - VertDataAvg4(co, co0, co1, co2, co3); - } + for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { + CCGVert *v = effectedV[ptrIdx]; + v->flags = 0; + } + for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { + CCGEdge *e = effectedE[ptrIdx]; + e->flags = 0; + } - /* interior face interior edge midpoints - * o old interior face points - * o new interior face midpoints - */ + CCGSUBSURF_free(ss, effectedF); + CCGSUBSURF_free(ss, effectedE); + CCGSUBSURF_free(ss, effectedV); +} - /* vertical */ - for (x=1; x<gridSize-1; x++) { - for (y=0; y<gridSize-1; y++) { - int fx = x*2; - int fy = y*2+1; - void *co0 = FACE_getIFCo(f, curLvl, S, x, y+0); - void *co1 = FACE_getIFCo(f, curLvl, S, x, y+1); - void *co2 = FACE_getIFCo(f, nextLvl, S, fx-1, fy); - void *co3 = FACE_getIFCo(f, nextLvl, S, fx+1, fy); - void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(co, co0, co1, co2, co3); - } - } +static void ccgSubSurf__allFaces(CCGSubSurf *ss, CCGFace ***faces, int *numFaces, int *freeFaces) +{ + CCGFace **array; + int i, num; - /* horizontal */ - for (y=1; y<gridSize-1; y++) { - for (x=0; x<gridSize-1; x++) { - int fx = x*2+1; - int fy = y*2; - void *co0 = FACE_getIFCo(f, curLvl, S, x+0, y); - void *co1 = FACE_getIFCo(f, curLvl, S, x+1, y); - void *co2 = FACE_getIFCo(f, nextLvl, S, fx, fy-1); - void *co3 = FACE_getIFCo(f, nextLvl, S, fx, fy+1); - void *co = FACE_getIFCo(f, nextLvl, S, fx, fy); + if(!*faces) { + array = CCGSUBSURF_alloc(ss, sizeof(*array)*ss->fMap->numEntries); + num = 0; + for (i=0; i<ss->fMap->curSize; i++) { + CCGFace *f = (CCGFace*) ss->fMap->buckets[i]; - VertDataAvg4(co, co0, co1, co2, co3); - } - } - } + for (; f; f = f->next) + array[num++] = f; } - /* exterior edge midpoints - * o old exterior edge points - * o new interior face midpoints - */ - for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { - CCEdge *e = (CCEdge*) effectedE[ptrIdx]; - float sharpness = EDGE_getSharpness(e, curLvl); + *faces = array; + *numFaces = num; + *freeFaces= 1; + } + else + *freeFaces= 0; +} - if (_edge_isBoundary(e) || sharpness>1.0) { - for (x=0; x<edgeSize-1; x++) { - int fx = x*2 + 1; - void *co0 = EDGE_getCo(e, curLvl, x+0); - void *co1 = EDGE_getCo(e, curLvl, x+1); - void *co = EDGE_getCo(e, nextLvl, fx); +static void ccgSubSurf__effectedFaceNeighbours(CCGSubSurf *ss, CCGFace **faces, int numFaces, CCGVert ***verts, int *numVerts, CCGEdge ***edges, int *numEdges) +{ + CCGVert **arrayV; + CCGEdge **arrayE; + int numV, numE, i, j; - VertDataCopy(co, co0); - VertDataAdd(co, co1); - VertDataMulN(co, 0.5); - } - } else { - for (x=0; x<edgeSize-1; x++) { - int fx = x*2 + 1; - void *co0 = EDGE_getCo(e, curLvl, x+0); - void *co1 = EDGE_getCo(e, curLvl, x+1); - void *co = EDGE_getCo(e, nextLvl, fx); - int numFaces = 0; - - VertDataCopy(q, co0); - VertDataAdd(q, co1); - - for (i=0; i<e->numFaces; i++) { - CCFace *f = e->faces[i]; - VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx, 1, subdivLevels, vertDataSize)); - numFaces++; - } + arrayV = CCGSUBSURF_alloc(ss, sizeof(*arrayV)*ss->vMap->numEntries); + arrayE = CCGSUBSURF_alloc(ss, sizeof(*arrayE)*ss->eMap->numEntries); + numV = numE = 0; - VertDataMulN(q, 1.0f/(2.0f+numFaces)); + for (i=0; i<numFaces; i++) { + CCGFace *f = faces[i]; + f->flags |= Face_eEffected; + } - VertDataCopy(r, co0); - VertDataAdd(r, co1); - VertDataMulN(r, 0.5); + for (i=0; i<ss->vMap->curSize; i++) { + CCGVert *v = (CCGVert*) ss->vMap->buckets[i]; - VertDataCopy(co, q); - VertDataSub(r, q); - VertDataMulN(r, sharpness); - VertDataAdd(co, r); - } + for (; v; v = v->next) { + for(j=0; j<v->numFaces; j++) + if(!(v->faces[j]->flags & Face_eEffected)) + break; + + if(j == v->numFaces) { + arrayV[numV++] = v; + v->flags |= Vert_eEffected; } } + } - /* exterior vertex shift - * o old vertex points (shifting) - * o old exterior edge points - * o new interior face midpoints - */ - for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { - CCVert *v = (CCVert*) effectedV[ptrIdx]; - void *co = VERT_getCo(v, curLvl); - void *nCo = VERT_getCo(v, nextLvl); - int sharpCount = 0, allSharp = 1; - float avgSharpness = 0.0; - int seam = VERT_seam(v), seamEdges = 0; + for (i=0; i<ss->eMap->curSize; i++) { + CCGEdge *e = (CCGEdge*) ss->eMap->buckets[i]; - for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; - float sharpness = EDGE_getSharpness(e, curLvl); + for (; e; e = e->next) { + for(j=0; j<e->numFaces; j++) + if(!(e->faces[j]->flags & Face_eEffected)) + break; + + if(j == e->numFaces) { + e->flags |= Edge_eEffected; + arrayE[numE++] = e; + } + } + } - if (seam && _edge_isBoundary(e)) - seamEdges++; + *verts = arrayV; + *numVerts = numV; + *edges = arrayE; + *numEdges = numE; +} - if (sharpness!=0.0f) { - sharpCount++; - avgSharpness += sharpness; - } else { - allSharp = 0; - } - } +/* copy face grid coordinates to other places */ +CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) +{ + int i, S, x, gridSize, cornerIdx, subdivLevels; + int vertDataSize = ss->meshIFC.vertDataSize, freeF; - if(sharpCount) { - avgSharpness /= sharpCount; - if (avgSharpness>1.0) { - avgSharpness = 1.0; - } - } + subdivLevels = ss->subdivLevels; + lvl = (lvl)? lvl: subdivLevels; + gridSize = 1 + (1<<(lvl-1)); + cornerIdx = gridSize-1; - if (seam && seamEdges < 2) - seam = 0; + ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); - if (!v->numEdges) { - VertDataCopy(nCo, co); - } else if (_vert_isBoundary(v)) { - int numBoundary = 0; + for (i=0; i<numEffectedF; i++) { + CCGFace *f = effectedF[i]; - VertDataZero(r); - for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; - if (_edge_isBoundary(e)) { - VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); - numBoundary++; - } - } + for (S=0; S<f->numVerts; S++) { + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; - VertDataCopy(nCo, co); - VertDataMulN(nCo, 0.75); - VertDataMulN(r, 0.25f/numBoundary); - VertDataAdd(nCo, r); - } else { - int cornerIdx = (1 + (1<<(curLvl))) - 2; - int numEdges = 0, numFaces = 0; + VertDataCopy(FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0)); + VertDataCopy(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx)); - VertDataZero(q); - for (i=0; i<v->numFaces; i++) { - CCFace *f = v->faces[i]; - VertDataAdd(q, FACE_getIFCo(f, nextLvl, _face_getVertIndex(f,v), cornerIdx, cornerIdx)); - numFaces++; - } - VertDataMulN(q, 1.0f/numFaces); - VertDataZero(r); - for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; - VertDataAdd(r, _edge_getCoVert(e, v, curLvl, 1,vertDataSize)); - numEdges++; - } - VertDataMulN(r, 1.0f/numEdges); + for (x=0; x<gridSize; x++) + VertDataCopy(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0)); - VertDataCopy(nCo, co); - VertDataMulN(nCo, numEdges-2.0f); - VertDataAdd(nCo, q); - VertDataAdd(nCo, r); - VertDataMulN(nCo, 1.0f/numEdges); + for (x=0; x<gridSize; x++) { + int eI = gridSize-1-x; + VertDataCopy(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x)); + VertDataCopy(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx)); } + } + } - if ((sharpCount>1 && v->numFaces) || seam) { - VertDataZero(q); + if(freeF) CCGSUBSURF_free(ss, effectedF); - if (seam) { - avgSharpness = 1.0f; - sharpCount = seamEdges; - allSharp = 1; - } + return eCCGError_None; +} - for (i=0; i<v->numEdges; i++) { - CCEdge *e = v->edges[i]; - float sharpness = EDGE_getSharpness(e, curLvl); +/* copy other places to face grid coordinates */ +CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) +{ + int i, S, x, gridSize, cornerIdx, subdivLevels; + int vertDataSize = ss->meshIFC.vertDataSize, freeF; - if (seam) { - if (_edge_isBoundary(e)) - VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); - } else if (sharpness != 0.0) { - VertDataAdd(q, _edge_getCoVert(e, v, curLvl, 1, vertDataSize)); - } - } + subdivLevels = ss->subdivLevels; + lvl = (lvl)? lvl: subdivLevels; + gridSize = 1 + (1<<(lvl-1)); + cornerIdx = gridSize-1; - VertDataMulN(q, (float) 1/sharpCount); + ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); - if (sharpCount!=2 || allSharp) { - // q = q + (co-q)*avgSharpness - VertDataCopy(r, co); - VertDataSub(r, q); - VertDataMulN(r, avgSharpness); - VertDataAdd(q, r); - } + for (i=0; i<numEffectedF; i++) { + CCGFace *f = effectedF[i]; - // r = co*.75 + q*.25 - VertDataCopy(r, co); - VertDataMulN(r, .75); - VertDataMulN(q, .25); - VertDataAdd(r, q); + for (S=0; S<f->numVerts; S++) { + int prevS = (S+f->numVerts-1)%f->numVerts; + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[prevS]; + + for (x=0; x<gridSize; x++) { + int eI = gridSize-1-x; + VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize)); + VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize)); + } - // nCo = nCo + (r-nCo)*avgSharpness - VertDataSub(r, nCo); - VertDataMulN(r, avgSharpness); - VertDataAdd(nCo, r); + for (x=1; x<gridSize-1; x++) { + VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x)); + VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x)); } + + VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), FACE_getCenterData(f)); + VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl)); } + } - /* exterior edge interior shift - * o old exterior edge midpoints (shifting) - * o old exterior edge midpoints - * o new interior face midpoints - */ - for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { - CCEdge *e = (CCEdge*) effectedE[ptrIdx]; - float sharpness = EDGE_getSharpness(e, curLvl); - int sharpCount = 0; - float avgSharpness = 0.0; + if(freeF) CCGSUBSURF_free(ss, effectedF); - if (sharpness!=0.0f) { - sharpCount = 2; - avgSharpness += sharpness; + return eCCGError_None; +} - if (avgSharpness>1.0) { - avgSharpness = 1.0; - } - } else { - sharpCount = 0; - avgSharpness = 0; - } +/* stitch together face grids, averaging coordinates at edges + and vertices, for multires displacements */ +CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) +{ + CCGVert **effectedV; + CCGEdge **effectedE; + int numEffectedV, numEffectedE, freeF; + int i, S, x, gridSize, cornerIdx, subdivLevels, edgeSize; + int vertDataSize = ss->meshIFC.vertDataSize; - if (_edge_isBoundary(e) && (!e->numFaces || sharpCount<2)) { - for (x=1; x<edgeSize-1; x++) { - int fx = x*2; - void *co = EDGE_getCo(e, curLvl, x); - void *nCo = EDGE_getCo(e, nextLvl, fx); - VertDataCopy(r, EDGE_getCo(e, curLvl, x-1)); - VertDataAdd(r, EDGE_getCo(e, curLvl, x+1)); - VertDataMulN(r, 0.5); - VertDataCopy(nCo, co); - VertDataMulN(nCo, 0.75); - VertDataMulN(r, 0.25); - VertDataAdd(nCo, r); - } - } else { - for (x=1; x<edgeSize-1; x++) { - int fx = x*2; - void *co = EDGE_getCo(e, curLvl, x); - void *nCo = EDGE_getCo(e, nextLvl, fx); - int numFaces = 0; - - VertDataZero(q); - VertDataZero(r); - VertDataAdd(r, EDGE_getCo(e, curLvl, x-1)); - VertDataAdd(r, EDGE_getCo(e, curLvl, x+1)); - for (i=0; i<e->numFaces; i++) { - CCFace *f = e->faces[i]; - VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx-1, 1, subdivLevels, vertDataSize)); - VertDataAdd(q, _face_getIFCoEdge(f, e, nextLvl, fx+1, 1, subdivLevels, vertDataSize)); - - VertDataAdd(r, _face_getIFCoEdge(f, e, curLvl, x, 1, subdivLevels, vertDataSize)); - numFaces++; - } - VertDataMulN(q, 1.0/(numFaces*2.0f)); - VertDataMulN(r, 1.0/(2.0f + numFaces)); + subdivLevels = ss->subdivLevels; + lvl = (lvl)? lvl: subdivLevels; + gridSize = 1 + (1<<(lvl-1)); + edgeSize = 1 + (1<<lvl); + cornerIdx = gridSize-1; - VertDataCopy(nCo, co); - VertDataMulN(nCo, (float) numFaces); - VertDataAdd(nCo, q); - VertDataAdd(nCo, r); - VertDataMulN(nCo, 1.0f/(2+numFaces)); - - if (sharpCount==2) { - VertDataCopy(q, co); - VertDataMulN(q, 6.0f); - VertDataAdd(q, EDGE_getCo(e, curLvl, x-1)); - VertDataAdd(q, EDGE_getCo(e, curLvl, x+1)); - VertDataMulN(q, 1/8.0f); - - VertDataSub(q, nCo); - VertDataMulN(q, avgSharpness); - VertDataAdd(nCo, q); - } - } - } - } + ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); + ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, + &effectedV, &numEffectedV, &effectedE, &numEffectedE); - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; + /* zero */ + for (i=0; i<numEffectedV; i++) { + CCGVert *v = effectedV[i]; + VertDataZero(VERT_getCo(v, lvl)); + } - /* interior center point shift - * o old face center point (shifting) - * o old interior edge points - * o new interior face midpoints - */ - VertDataZero(q); - for (S=0; S<f->numVerts; S++) { - VertDataAdd(q, FACE_getIFCo(f, nextLvl, S, 1, 1)); - } - VertDataMulN(q, 1.0f/f->numVerts); - VertDataZero(r); - for (S=0; S<f->numVerts; S++) { - VertDataAdd(r, FACE_getIECo(f, curLvl, S, 1)); - } - VertDataMulN(r, 1.0f/f->numVerts); + for (i=0; i<numEffectedE; i++) { + CCGEdge *e = effectedE[i]; - VertDataMulN(FACE_getCenterData(f), f->numVerts-2.0f); - VertDataAdd(FACE_getCenterData(f), q); - VertDataAdd(FACE_getCenterData(f), r); - VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); + for (x=0; x<edgeSize; x++) + VertDataZero(EDGE_getCo(e, lvl, x)); + } - for (S=0; S<f->numVerts; S++) { - /* interior face shift - * o old interior face point (shifting) - * o new interior edge midpoints - * o new interior face midpoints - */ - for (x=1; x<gridSize-1; x++) { - for (y=1; y<gridSize-1; y++) { - int fx = x*2; - int fy = y*2; - void *co = FACE_getIFCo(f, curLvl, S, x, y); - void *nCo = FACE_getIFCo(f, nextLvl, S, fx, fy); - - VertDataAvg4(q, FACE_getIFCo(f, nextLvl, S, fx-1, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+1, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+1, fy+1), - FACE_getIFCo(f, nextLvl, S, fx-1, fy+1)); + /* add */ + for (i=0; i<numEffectedF; i++) { + CCGFace *f = effectedF[i]; - VertDataAvg4(r, FACE_getIFCo(f, nextLvl, S, fx-1, fy+0), - FACE_getIFCo(f, nextLvl, S, fx+1, fy+0), - FACE_getIFCo(f, nextLvl, S, fx+0, fy-1), - FACE_getIFCo(f, nextLvl, S, fx+0, fy+1)); + VertDataZero(FACE_getCenterData(f)); - VertDataCopy(nCo, co); - VertDataSub(nCo, q); - VertDataMulN(nCo, 0.25f); - VertDataAdd(nCo, r); - } - } + for (S=0; S<f->numVerts; S++) + if (FACE_getEdges(f)[S]->flags&Edge_eEffected) + for (x=0; x<gridSize; x++) + VertDataZero(FACE_getIECo(f, lvl, S, x)); - /* interior edge interior shift - * o old interior edge point (shifting) - * o new interior edge midpoints - * o new interior face midpoints - */ - for (x=1; x<gridSize-1; x++) { - int fx = x*2; - void *co = FACE_getIECo(f, curLvl, S, x); - void *nCo = FACE_getIECo(f, nextLvl, S, fx); - - VertDataAvg4(q, FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx-1), - FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx+1), - FACE_getIFCo(f, nextLvl, S, fx+1, +1), - FACE_getIFCo(f, nextLvl, S, fx-1, +1)); + for (S=0; S<f->numVerts; S++) { + int prevS = (S+f->numVerts-1)%f->numVerts; + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[prevS]; - VertDataAvg4(r, FACE_getIECo(f, nextLvl, S, fx-1), - FACE_getIECo(f, nextLvl, S, fx+1), - FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 1, fx), - FACE_getIFCo(f, nextLvl, S, fx, 1)); + VertDataAdd(FACE_getCenterData(f), FACE_getIFCo(f, lvl, S, 0, 0)); + if (FACE_getVerts(f)[S]->flags&Vert_eEffected) + VertDataAdd(VERT_getCo(FACE_getVerts(f)[S], lvl), FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx)); - VertDataCopy(nCo, co); - VertDataSub(nCo, q); - VertDataMulN(nCo, 0.25f); - VertDataAdd(nCo, r); - } + for (x=1; x<gridSize-1; x++) { + if (FACE_getEdges(f)[S]->flags&Edge_eEffected) + VertDataAdd(FACE_getIECo(f, lvl, S, x), FACE_getIFCo(f, lvl, S, x, 0)); + if (FACE_getEdges(f)[prevS]->flags&Edge_eEffected) + VertDataAdd(FACE_getIECo(f, lvl, prevS, x), FACE_getIFCo(f, lvl, S, 0, x)); } - } - - /* copy down */ - edgeSize = 1 + (1<<(nextLvl)); - gridSize = 1 + (1<<((nextLvl)-1)); - cornerIdx = gridSize-1; - for (i=0; i<numEffectedE; i++) { - CCEdge *e = effectedE[i]; - VertDataCopy(EDGE_getCo(e, nextLvl, 0), VERT_getCo(e->v0, nextLvl)); - VertDataCopy(EDGE_getCo(e, nextLvl, edgeSize-1), VERT_getCo(e->v1, nextLvl)); - } - for (i=0; i<numEffectedF; i++) { - CCFace *f = effectedF[i]; - for (S=0; S<f->numVerts; S++) { - CCEdge *e = FACE_getEdges(f)[S]; - CCEdge *prevE = FACE_getEdges(f)[(S+f->numVerts-1)%f->numVerts]; - VertDataCopy(FACE_getIFCo(f, nextLvl, S, 0, 0), FACE_getCenterData(f)); - VertDataCopy(FACE_getIECo(f, nextLvl, S, 0), FACE_getCenterData(f)); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], nextLvl)); - VertDataCopy(FACE_getIECo(f, nextLvl, S, cornerIdx), EDGE_getCo(FACE_getEdges(f)[S], nextLvl, cornerIdx)); - for (x=1; x<gridSize-1; x++) { - void *co = FACE_getIECo(f, nextLvl, S, x); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, 0), co); - VertDataCopy(FACE_getIFCo(f, nextLvl, (S+1)%f->numVerts, 0, x), co); - } - for (x=0; x<gridSize-1; x++) { - int eI = gridSize-1-x; - VertDataCopy(FACE_getIFCo(f, nextLvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize)); - VertDataCopy(FACE_getIFCo(f, nextLvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], nextLvl, eI,vertDataSize)); - } + for (x=0; x<gridSize-1; x++) { + int eI = gridSize-1-x; + if (FACE_getEdges(f)[S]->flags&Edge_eEffected) + VertDataAdd(_edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, cornerIdx, x)); + if (FACE_getEdges(f)[prevS]->flags&Edge_eEffected) + if(x != 0) + VertDataAdd(_edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize), FACE_getIFCo(f, lvl, S, x, cornerIdx)); } } } -#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset) -#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize) - if (ss->calcVertNormals) { - int lvl = ss->subdivLevels; - int edgeSize = 1 + (1<<lvl); - int gridSize = 1 + (1<<(lvl-1)); - int normalDataOffset = ss->normalDataOffset; + /* average */ + for (i=0; i<numEffectedV; i++) { + CCGVert *v = effectedV[i]; + VertDataMulN(VERT_getCo(v, lvl), 1.0f/v->numFaces); + } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; - int S, x, y; + for (i=0; i<numEffectedE; i++) { + CCGEdge *e = effectedE[i]; - for (S=0; S<f->numVerts; S++) { - for (y=0; y<gridSize-1; y++) - for (x=0; x<gridSize-1; x++) - NormZero(FACE_getIFNo(f, lvl, S, x, y)); + VertDataCopy(EDGE_getCo(e, lvl, 0), VERT_getCo(e->v0, lvl)); + VertDataCopy(EDGE_getCo(e, lvl, edgeSize-1), VERT_getCo(e->v1, lvl)); - if (FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected) - for (x=0; x<gridSize-1; x++) - NormZero(FACE_getIFNo(f, lvl, S, x, gridSize-1)); - if (FACE_getEdges(f)[S]->flags&Edge_eEffected) - for (y=0; y<gridSize-1; y++) - NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, y)); - if (FACE_getVerts(f)[S]->flags&Vert_eEffected) - NormZero(FACE_getIFNo(f, lvl, S, gridSize-1, gridSize-1)); - } - } - - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; - int S, x, y; - float no[3]; + for (x=1; x<edgeSize-1; x++) + VertDataMulN(EDGE_getCo(e, lvl, x), 1.0f/e->numFaces); + } - for (S=0; S<f->numVerts; S++) { - int yLimit = !(FACE_getEdges(f)[(S-1+f->numVerts)%f->numVerts]->flags&Edge_eEffected); - int xLimit = !(FACE_getEdges(f)[S]->flags&Edge_eEffected); - int yLimitNext = xLimit; - int xLimitPrev = yLimit; - - for (y=0; y<gridSize - 1; y++) { - for (x=0; x<gridSize - 1; x++) { - int xPlusOk = (!xLimit || x<gridSize-2); - int yPlusOk = (!yLimit || y<gridSize-2); - - FACE_calcIFNo(f, lvl, S, x, y, no); - - NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+0), no); - if (xPlusOk) - NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+0), no); - if (yPlusOk) - NormAdd(FACE_getIFNo(f, lvl, S, x+0, y+1), no); - if (xPlusOk && yPlusOk) { - if (x<gridSize-2 || y<gridSize-2 || FACE_getVerts(f)[S]->flags&Vert_eEffected) { - NormAdd(FACE_getIFNo(f, lvl, S, x+1, y+1), no); - } - } + /* copy */ + for (i=0; i<numEffectedF; i++) { + CCGFace *f = effectedF[i]; - if (x==0 && y==0) { - int K; + VertDataMulN(FACE_getCenterData(f), 1.0f/f->numVerts); - if (!yLimitNext || 1<gridSize-1) - NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, 1), no); - if (!xLimitPrev || 1<gridSize-1) - NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, 1, 0), no); + for (S=0; S<f->numVerts; S++) + if (FACE_getEdges(f)[S]->flags&Edge_eEffected) + for (x=1; x<gridSize-1; x++) + VertDataMulN(FACE_getIECo(f, lvl, S, x), 0.5f); - for (K=0; K<f->numVerts; K++) { - if (K!=S) { - NormAdd(FACE_getIFNo(f, lvl, K, 0, 0), no); - } - } - } else if (y==0) { - NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x), no); - if (!yLimitNext || x<gridSize-2) - NormAdd(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, x+1), no); - } else if (x==0) { - NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y, 0), no); - if (!xLimitPrev || y<gridSize-2) - NormAdd(FACE_getIFNo(f, lvl, (S-1+f->numVerts)%f->numVerts, y+1, 0), no); - } - } - } - } - } - // XXX can I reduce the number of normalisations here? - for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { - CCVert *v = (CCVert*) effectedV[ptrIdx]; - float length, *no = _vert_getNo(v, lvl, vertDataSize, normalDataOffset); + for (S=0; S<f->numVerts; S++) { + int prevS = (S+f->numVerts-1)%f->numVerts; + CCGEdge *e = FACE_getEdges(f)[S]; + CCGEdge *prevE = FACE_getEdges(f)[prevS]; - NormZero(no); + VertDataCopy(FACE_getIFCo(f, lvl, S, 0, 0), FACE_getCenterData(f)); + VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, cornerIdx), VERT_getCo(FACE_getVerts(f)[S], lvl)); - for (i=0; i<v->numFaces; i++) { - CCFace *f = v->faces[i]; - NormAdd(no, FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1)); + for (x=1; x<gridSize-1; x++) { + VertDataCopy(FACE_getIFCo(f, lvl, S, x, 0), FACE_getIECo(f, lvl, S, x)); + VertDataCopy(FACE_getIFCo(f, lvl, S, 0, x), FACE_getIECo(f, lvl, prevS, x)); } - length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]); - - if (length>EPSILON) { - float invLength = 1.0f/length; - no[0] *= invLength; - no[1] *= invLength; - no[2] *= invLength; - } else { - NormZero(no); + for (x=0; x<gridSize-1; x++) { + int eI = gridSize-1-x; + VertDataCopy(FACE_getIFCo(f, lvl, S, cornerIdx, x), _edge_getCoVert(e, FACE_getVerts(f)[S], lvl, eI,vertDataSize)); + VertDataCopy(FACE_getIFCo(f, lvl, S, x, cornerIdx), _edge_getCoVert(prevE, FACE_getVerts(f)[S], lvl, eI,vertDataSize)); } - for (i=0; i<v->numFaces; i++) { - CCFace *f = v->faces[i]; - NormCopy(FACE_getIFNo(f, lvl, _face_getVertIndex(f,v), gridSize-1, gridSize-1), no); - } + VertDataCopy(FACE_getIECo(f, lvl, S, 0), FACE_getCenterData(f)); + VertDataCopy(FACE_getIECo(f, lvl, S, gridSize-1), FACE_getIFCo(f, lvl, S, gridSize-1, 0)); } - for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { - CCEdge *e = (CCEdge*) effectedE[ptrIdx]; + } - if (e->numFaces) { - CCFace *fLast = e->faces[e->numFaces-1]; - int x; + for (i=0; i<numEffectedV; i++) + effectedV[i]->flags = 0; + for (i=0; i<numEffectedE; i++) + effectedE[i]->flags = 0; + for (i=0; i<numEffectedF; i++) + effectedF[i]->flags = 0; - for (i=0; i<e->numFaces-1; i++) { - CCFace *f = e->faces[i]; + CCGSUBSURF_free(ss, effectedE); + CCGSUBSURF_free(ss, effectedV); + if(freeF) CCGSUBSURF_free(ss, effectedF); - for (x=1; x<edgeSize-1; x++) { - NormAdd(_face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), - _face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); - } - } + return eCCGError_None; +} - for (i=0; i<e->numFaces-1; i++) { - CCFace *f = e->faces[i]; +/* update normals for specified faces */ +CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **effectedF, int numEffectedF) { + CCGVert **effectedV; + CCGEdge **effectedE; + int i, numEffectedV, numEffectedE, freeF; - for (x=1; x<edgeSize-1; x++) { - NormCopy(_face_getIFNoEdge(f, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset), - _face_getIFNoEdge(fLast, e, lvl, x, 0, subdivLevels, vertDataSize, normalDataOffset)); - } - } - } - } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; - int S; + ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); + ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, + &effectedV, &numEffectedV, &effectedE, &numEffectedE); - for (S=0; S<f->numVerts; S++) { - NormCopy(FACE_getIFNo(f, lvl, (S+1)%f->numVerts, 0, gridSize-1), - FACE_getIFNo(f, lvl, S, gridSize-1, 0)); - } - } - for (ptrIdx=0; ptrIdx<numEffectedF; ptrIdx++) { - CCFace *f = (CCFace*) effectedF[ptrIdx]; - int S, x, y; + if (ss->calcVertNormals) + ccgSubSurf__calcVertNormals(ss, + effectedV, effectedE, effectedF, + numEffectedV, numEffectedE, numEffectedF); - for (S=0; S<f->numVerts; S++) { - for (y=0; y<gridSize; y++) { - for (x=0; x<gridSize; x++) { - float *no = FACE_getIFNo(f, lvl, S, x, y); - float length = sqrt(no[0]*no[0] + no[1]*no[1] + no[2]*no[2]); - - if (length>EPSILON) { - float invLength = 1.0f/length; - no[0] *= invLength; - no[1] *= invLength; - no[2] *= invLength; - } else { - NormZero(no); - } - } - } - } - } - } -#undef FACE_getIFNo + for (i=0; i<numEffectedV; i++) + effectedV[i]->flags = 0; + for (i=0; i<numEffectedE; i++) + effectedE[i]->flags = 0; + for (i=0; i<numEffectedF; i++) + effectedF[i]->flags = 0; - for (ptrIdx=0; ptrIdx<numEffectedV; ptrIdx++) { - CCVert *v = effectedV[ptrIdx]; - v->flags = 0; - } - for (ptrIdx=0; ptrIdx<numEffectedE; ptrIdx++) { - CCEdge *e = effectedE[ptrIdx]; - e->flags = 0; + CCGSUBSURF_free(ss, effectedE); + CCGSUBSURF_free(ss, effectedV); + if(freeF) CCGSUBSURF_free(ss, effectedF); + + return eCCGError_None; +} + +/* compute subdivision levels from a given starting point, used by + multires subdivide/propagate, by filling in coordinates at a + certain level, and then subdividing that up to the highest level */ +CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **effectedF, int numEffectedF) +{ + CCGVert **effectedV; + CCGEdge **effectedE; + int numEffectedV, numEffectedE, freeF, i; + int curLvl, subdivLevels = ss->subdivLevels; + + ccgSubSurf__allFaces(ss, &effectedF, &numEffectedF, &freeF); + ccgSubSurf__effectedFaceNeighbours(ss, effectedF, numEffectedF, + &effectedV, &numEffectedV, &effectedE, &numEffectedE); + + for (curLvl=lvl; curLvl<subdivLevels; curLvl++) { + ccgSubSurf__calcSubdivLevel(ss, + effectedV, effectedE, effectedF, + numEffectedV, numEffectedE, numEffectedF, curLvl); } -#undef VERT_getCo -#undef EDGE_getCo -#undef FACE_getIECo -#undef FACE_getIFCo + for (i=0; i<numEffectedV; i++) + effectedV[i]->flags = 0; + for (i=0; i<numEffectedE; i++) + effectedE[i]->flags = 0; + for (i=0; i<numEffectedF; i++) + effectedF[i]->flags = 0; - CCGSUBSURF_free(ss, effectedF); CCGSUBSURF_free(ss, effectedE); CCGSUBSURF_free(ss, effectedV); + if(freeF) CCGSUBSURF_free(ss, effectedF); + + return eCCGError_None; } +#undef VERT_getCo +#undef EDGE_getCo +#undef FACE_getIECo +#undef FACE_getIFCo + /*** External API accessor functions ***/ -int CCS_getNumVerts(CSubSurf *ss) { +int ccgSubSurf_getNumVerts(CCGSubSurf *ss) { return ss->vMap->numEntries; } -int CCS_getNumEdges(CSubSurf *ss) { +int ccgSubSurf_getNumEdges(CCGSubSurf *ss) { return ss->eMap->numEntries; } -int CCS_getNumFaces(CSubSurf *ss) { +int ccgSubSurf_getNumFaces(CCGSubSurf *ss) { return ss->fMap->numEntries; } -CCVert *CCS_getVert(CSubSurf *ss, CCVertHDL v) { - return (CCVert*) _ehash_lookup(ss->vMap, v); +CCGVert *ccgSubSurf_getVert(CCGSubSurf *ss, CCGVertHDL v) { + return (CCGVert*) _ehash_lookup(ss->vMap, v); } -CCEdge *CCS_getEdge(CSubSurf *ss, CCEdgeHDL e) { - return (CCEdge*) _ehash_lookup(ss->eMap, e); +CCGEdge *ccgSubSurf_getEdge(CCGSubSurf *ss, CCGEdgeHDL e) { + return (CCGEdge*) _ehash_lookup(ss->eMap, e); } -CCFace *CCS_getFace(CSubSurf *ss, CCFaceHDL f) { - return (CCFace*) _ehash_lookup(ss->fMap, f); +CCGFace *ccgSubSurf_getFace(CCGSubSurf *ss, CCGFaceHDL f) { + return (CCGFace*) _ehash_lookup(ss->fMap, f); } -int CCS_getSubdivisionLevels(CSubSurf *ss) { +int ccgSubSurf_getSubdivisionLevels(CCGSubSurf *ss) { return ss->subdivLevels; } -int CCS_getEdgeSize(CSubSurf *ss) { - return CCS_getEdgeLevelSize(ss, ss->subdivLevels); +int ccgSubSurf_getEdgeSize(CCGSubSurf *ss) { + return ccgSubSurf_getEdgeLevelSize(ss, ss->subdivLevels); } -int CCS_getEdgeLevelSize(CSubSurf *ss, int level) { +int ccgSubSurf_getEdgeLevelSize(CCGSubSurf *ss, int level) { if (level<1 || level>ss->subdivLevels) { return -1; } else { return 1 + (1<<level); } } -int CCS_getGridSize(CSubSurf *ss) { - return CCS_getGridLevelSize(ss, ss->subdivLevels); +int ccgSubSurf_getGridSize(CCGSubSurf *ss) { + return ccgSubSurf_getGridLevelSize(ss, ss->subdivLevels); } -int CCS_getGridLevelSize(CSubSurf *ss, int level) { +int ccgSubSurf_getGridLevelSize(CCGSubSurf *ss, int level) { if (level<1 || level>ss->subdivLevels) { return -1; } else { @@ -2078,44 +2482,44 @@ int CCS_getGridLevelSize(CSubSurf *ss, int level) { /* Vert accessors */ -CCVertHDL CCS_getVertVertHandle(CCVert *v) { +CCGVertHDL ccgSubSurf_getVertVertHandle(CCGVert *v) { return v->vHDL; } -int CCS_getVertAge(CSubSurf *ss, CCVert *v) { +int ccgSubSurf_getVertAge(CCGSubSurf *ss, CCGVert *v) { if (ss->useAgeCounts) { - byte *userData = CCS_getVertUserData(ss, v); + byte *userData = ccgSubSurf_getVertUserData(ss, v); return ss->currentAge - *((int*) &userData[ss->vertUserAgeOffset]); } else { return 0; } } -void *CCS_getVertUserData(CSubSurf *ss, CCVert *v) { +void *ccgSubSurf_getVertUserData(CCGSubSurf *ss, CCGVert *v) { return VERT_getLevelData(v) + ss->meshIFC.vertDataSize*(ss->subdivLevels+1); } -int CCS_getVertNumFaces(CCVert *v) { +int ccgSubSurf_getVertNumFaces(CCGVert *v) { return v->numFaces; } -CCFace *CCS_getVertFace(CCVert *v, int index) { +CCGFace *ccgSubSurf_getVertFace(CCGVert *v, int index) { if (index<0 || index>=v->numFaces) { return NULL; } else { return v->faces[index]; } } -int CCS_getVertNumEdges(CCVert *v) { +int ccgSubSurf_getVertNumEdges(CCGVert *v) { return v->numEdges; } -CCEdge *CCS_getVertEdge(CCVert *v, int index) { +CCGEdge *ccgSubSurf_getVertEdge(CCGVert *v, int index) { if (index<0 || index>=v->numEdges) { return NULL; } else { return v->edges[index]; } } -void *CCS_getVertData(CSubSurf *ss, CCVert *v) { - return CCS_getVertLevelData(ss, v, ss->subdivLevels); +void *ccgSubSurf_getVertData(CCGSubSurf *ss, CCGVert *v) { + return ccgSubSurf_getVertLevelData(ss, v, ss->subdivLevels); } -void *CCS_getVertLevelData(CSubSurf *ss, CCVert *v, int level) { +void *ccgSubSurf_getVertLevelData(CCGSubSurf *ss, CCGVert *v, int level) { if (level<0 || level>ss->subdivLevels) { return NULL; } else { @@ -2125,88 +2529,88 @@ void *CCS_getVertLevelData(CSubSurf *ss, CCVert *v, int level) { /* Edge accessors */ -CCEdgeHDL CCS_getEdgeEdgeHandle(CCEdge *e) { +CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle(CCGEdge *e) { return e->eHDL; } -int CCS_getEdgeAge(CSubSurf *ss, CCEdge *e) { +int ccgSubSurf_getEdgeAge(CCGSubSurf *ss, CCGEdge *e) { if (ss->useAgeCounts) { - byte *userData = CCS_getEdgeUserData(ss, e); + byte *userData = ccgSubSurf_getEdgeUserData(ss, e); return ss->currentAge - *((int*) &userData[ss->edgeUserAgeOffset]); } else { return 0; } } -void *CCS_getEdgeUserData(CSubSurf *ss, CCEdge *e) { +void *ccgSubSurf_getEdgeUserData(CCGSubSurf *ss, CCGEdge *e) { return EDGE_getLevelData(e) + ss->meshIFC.vertDataSize *((ss->subdivLevels+1) + (1<<(ss->subdivLevels+1))-1); } -int CCS_getEdgeNumFaces(CCEdge *e) { +int ccgSubSurf_getEdgeNumFaces(CCGEdge *e) { return e->numFaces; } -CCFace *CCS_getEdgeFace(CCEdge *e, int index) { +CCGFace *ccgSubSurf_getEdgeFace(CCGEdge *e, int index) { if (index<0 || index>=e->numFaces) { return NULL; } else { return e->faces[index]; } } -CCVert *CCS_getEdgeVert0(CCEdge *e) { +CCGVert *ccgSubSurf_getEdgeVert0(CCGEdge *e) { return e->v0; } -CCVert *CCS_getEdgeVert1(CCEdge *e) { +CCGVert *ccgSubSurf_getEdgeVert1(CCGEdge *e) { return e->v1; } -void *CCS_getEdgeDataArray(CSubSurf *ss, CCEdge *e) { - return CCS_getEdgeData(ss, e, 0); +void *ccgSubSurf_getEdgeDataArray(CCGSubSurf *ss, CCGEdge *e) { + return ccgSubSurf_getEdgeData(ss, e, 0); } -void *CCS_getEdgeData(CSubSurf *ss, CCEdge *e, int x) { - return CCS_getEdgeLevelData(ss, e, x, ss->subdivLevels); +void *ccgSubSurf_getEdgeData(CCGSubSurf *ss, CCGEdge *e, int x) { + return ccgSubSurf_getEdgeLevelData(ss, e, x, ss->subdivLevels); } -void *CCS_getEdgeLevelData(CSubSurf *ss, CCEdge *e, int x, int level) { +void *ccgSubSurf_getEdgeLevelData(CCGSubSurf *ss, CCGEdge *e, int x, int level) { if (level<0 || level>ss->subdivLevels) { return NULL; } else { return _edge_getCo(e, level, x, ss->meshIFC.vertDataSize); } } -float CCS_getEdgeCrease(CCEdge *e) { +float ccgSubSurf_getEdgeCrease(CCGEdge *e) { return e->crease; } /* Face accessors */ -CCFaceHDL CCS_getFaceFaceHandle(CSubSurf *ss, CCFace *f) { +CCGFaceHDL ccgSubSurf_getFaceFaceHandle(CCGSubSurf *ss, CCGFace *f) { return f->fHDL; } -int CCS_getFaceAge(CSubSurf *ss, CCFace *f) { +int ccgSubSurf_getFaceAge(CCGSubSurf *ss, CCGFace *f) { if (ss->useAgeCounts) { - byte *userData = CCS_getFaceUserData(ss, f); + byte *userData = ccgSubSurf_getFaceUserData(ss, f); return ss->currentAge - *((int*) &userData[ss->faceUserAgeOffset]); } else { return 0; } } -void *CCS_getFaceUserData(CSubSurf *ss, CCFace *f) { +void *ccgSubSurf_getFaceUserData(CCGSubSurf *ss, CCGFace *f) { int maxGridSize = 1 + (1<<(ss->subdivLevels-1)); return FACE_getCenterData(f) + ss->meshIFC.vertDataSize *(1 + f->numVerts*maxGridSize + f->numVerts*maxGridSize*maxGridSize); } -int CCS_getFaceNumVerts(CCFace *f) { +int ccgSubSurf_getFaceNumVerts(CCGFace *f) { return f->numVerts; } -CCVert *CCS_getFaceVert(CSubSurf *ss, CCFace *f, int index) { +CCGVert *ccgSubSurf_getFaceVert(CCGSubSurf *ss, CCGFace *f, int index) { if (index<0 || index>=f->numVerts) { return NULL; } else { return FACE_getVerts(f)[index]; } } -CCEdge *CCS_getFaceEdge(CSubSurf *ss, CCFace *f, int index) { +CCGEdge *ccgSubSurf_getFaceEdge(CCGSubSurf *ss, CCGFace *f, int index) { if (index<0 || index>=f->numVerts) { return NULL; } else { return FACE_getEdges(f)[index]; } } -int CCS_getFaceEdgeIndex(CCFace *f, CCEdge *e) { +int ccgSubSurf_getFaceEdgeIndex(CCGFace *f, CCGEdge *e) { int i; for (i=0; i<f->numVerts; i++) @@ -2215,88 +2619,88 @@ int CCS_getFaceEdgeIndex(CCFace *f, CCEdge *e) { return -1; } -void *CCS_getFaceCenterData(CCFace *f) { +void *ccgSubSurf_getFaceCenterData(CCGFace *f) { return FACE_getCenterData(f); } -void *CCS_getFaceGridEdgeDataArray(CSubSurf *ss, CCFace *f, int gridIndex) { - return CCS_getFaceGridEdgeData(ss, f, gridIndex, 0); +void *ccgSubSurf_getFaceGridEdgeDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) { + return ccgSubSurf_getFaceGridEdgeData(ss, f, gridIndex, 0); } -void *CCS_getFaceGridEdgeData(CSubSurf *ss, CCFace *f, int gridIndex, int x) { +void *ccgSubSurf_getFaceGridEdgeData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x) { return _face_getIECo(f, ss->subdivLevels, gridIndex, x, ss->subdivLevels, ss->meshIFC.vertDataSize); } -void *CCS_getFaceGridDataArray(CSubSurf *ss, CCFace *f, int gridIndex) { - return CCS_getFaceGridData(ss, f, gridIndex, 0, 0); +void *ccgSubSurf_getFaceGridDataArray(CCGSubSurf *ss, CCGFace *f, int gridIndex) { + return ccgSubSurf_getFaceGridData(ss, f, gridIndex, 0, 0); } -void *CCS_getFaceGridData(CSubSurf *ss, CCFace *f, int gridIndex, int x, int y) { +void *ccgSubSurf_getFaceGridData(CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y) { return _face_getIFCo(f, ss->subdivLevels, gridIndex, x, y, ss->subdivLevels, ss->meshIFC.vertDataSize); } /*** External API iterator functions ***/ -CCVertIterator *CCS_getVertIterator(CSubSurf *ss) { - return (CCVertIterator*) _ehashIterator_new(ss->vMap); +CCGVertIterator *ccgSubSurf_getVertIterator(CCGSubSurf *ss) { + return (CCGVertIterator*) _ehashIterator_new(ss->vMap); } -CCEdgeIterator *CCS_getEdgeIterator(CSubSurf *ss) { - return (CCEdgeIterator*) _ehashIterator_new(ss->eMap); +CCGEdgeIterator *ccgSubSurf_getEdgeIterator(CCGSubSurf *ss) { + return (CCGEdgeIterator*) _ehashIterator_new(ss->eMap); } -CCFaceIterator *CCS_getFaceIterator(CSubSurf *ss) { - return (CCFaceIterator*) _ehashIterator_new(ss->fMap); +CCGFaceIterator *ccgSubSurf_getFaceIterator(CCGSubSurf *ss) { + return (CCGFaceIterator*) _ehashIterator_new(ss->fMap); } -CCVert *CCVIter_getCurrent(CCVertIterator *vi) { - return (CCVert*) _ehashIterator_getCurrent((EHashIterator*) vi); +CCGVert *ccgVertIterator_getCurrent(CCGVertIterator *vi) { + return (CCGVert*) _ehashIterator_getCurrent((EHashIterator*) vi); } -int CCVIter_isStopped(CCVertIterator *vi) { +int ccgVertIterator_isStopped(CCGVertIterator *vi) { return _ehashIterator_isStopped((EHashIterator*) vi); } -void CCVIter_next(CCVertIterator *vi) { +void ccgVertIterator_next(CCGVertIterator *vi) { _ehashIterator_next((EHashIterator*) vi); } -void CCVIter_free(CCVertIterator *vi) { +void ccgVertIterator_free(CCGVertIterator *vi) { _ehashIterator_free((EHashIterator*) vi); } -CCEdge *CCEIter_getCurrent(CCEdgeIterator *vi) { - return (CCEdge*) _ehashIterator_getCurrent((EHashIterator*) vi); +CCGEdge *ccgEdgeIterator_getCurrent(CCGEdgeIterator *vi) { + return (CCGEdge*) _ehashIterator_getCurrent((EHashIterator*) vi); } -int CCEIter_isStopped(CCEdgeIterator *vi) { +int ccgEdgeIterator_isStopped(CCGEdgeIterator *vi) { return _ehashIterator_isStopped((EHashIterator*) vi); } -void CCEIter_next(CCEdgeIterator *vi) { +void ccgEdgeIterator_next(CCGEdgeIterator *vi) { _ehashIterator_next((EHashIterator*) vi); } -void CCEIter_free(CCEdgeIterator *vi) { +void ccgEdgeIterator_free(CCGEdgeIterator *vi) { _ehashIterator_free((EHashIterator*) vi); } -CCFace *CCFIter_getCurrent(CCFaceIterator *vi) { - return (CCFace*) _ehashIterator_getCurrent((EHashIterator*) vi); +CCGFace *ccgFaceIterator_getCurrent(CCGFaceIterator *vi) { + return (CCGFace*) _ehashIterator_getCurrent((EHashIterator*) vi); } -int CCFIter_isStopped(CCFaceIterator *vi) { +int ccgFaceIterator_isStopped(CCGFaceIterator *vi) { return _ehashIterator_isStopped((EHashIterator*) vi); } -void CCFIter_next(CCFaceIterator *vi) { +void ccgFaceIterator_next(CCGFaceIterator *vi) { _ehashIterator_next((EHashIterator*) vi); } -void CCFIter_free(CCFaceIterator *vi) { +void ccgFaceIterator_free(CCGFaceIterator *vi) { _ehashIterator_free((EHashIterator*) vi); } /*** Extern API final vert/edge/face interface ***/ -int CCS_getNumFinalVerts(CSubSurf *ss) { +int ccgSubSurf_getNumFinalVerts(CCGSubSurf *ss) { int edgeSize = 1 + (1<<ss->subdivLevels); int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalVerts = ss->vMap->numEntries + ss->eMap->numEntries*(edgeSize-2) + ss->fMap->numEntries + ss->numGrids*((gridSize-2) + ((gridSize-2)*(gridSize-2))); return numFinalVerts; } -int CCS_getNumFinalEdges(CSubSurf *ss) { +int ccgSubSurf_getNumFinalEdges(CCGSubSurf *ss) { int edgeSize = 1 + (1<<ss->subdivLevels); int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalEdges = ss->eMap->numEntries*(edgeSize-1) + ss->numGrids*((gridSize-1) + 2*((gridSize-2)*(gridSize-1))); return numFinalEdges; } -int CCS_getNumFinalFaces(CSubSurf *ss) { +int ccgSubSurf_getNumFinalFaces(CCGSubSurf *ss) { int gridSize = 1 + (1<<(ss->subdivLevels-1)); int numFinalFaces = ss->numGrids*((gridSize-1)*(gridSize-1)); return numFinalFaces; diff --git a/source/blender/blenkernel/intern/CCGSubSurf.h b/source/blender/blenkernel/intern/CCGSubSurf.h index 2d4bef3d038..12212c7a37b 100644 --- a/source/blender/blenkernel/intern/CCGSubSurf.h +++ b/source/blender/blenkernel/intern/CCGSubSurf.h @@ -1,30 +1,31 @@ /* $Id$ */ typedef void* CCGMeshHDL; -typedef void* CCVertHDL; -typedef void* CCEdgeHDL; -typedef void* CCFaceHDL; +typedef void* CCGVertHDL; +typedef void* CCGEdgeHDL; +typedef void* CCGFaceHDL; -typedef struct _CCVert CCVert; -typedef struct _CCEdge CCEdge; -typedef struct _CCFace CCFace; +typedef struct _CCGVert CCGVert; +typedef struct _CCGEdge CCGEdge; +typedef struct _CCGFace CCGFace; typedef struct _CCGMeshIFC CCGMeshIFC; struct _CCGMeshIFC { - int vertUserSize, edgeUserSize, faceUserSize; - int vertDataSize; + int vertUserSize, edgeUserSize, faceUserSize; + + int vertDataSize; }; /***/ -typedef void* CCAllocHDL; +typedef void* CCGAllocatorHDL; typedef struct _CCGAllocatorIFC CCGAllocatorIFC; struct _CCGAllocatorIFC { - void* (*alloc) (CCAllocHDL a, int numBytes); - void* (*realloc) (CCAllocHDL a, void *ptr, int newSize, int oldSize); - void (*free) (CCAllocHDL a, void *ptr); - void (*release) (CCAllocHDL a); + void* (*alloc) (CCGAllocatorHDL a, int numBytes); + void* (*realloc) (CCGAllocatorHDL a, void *ptr, int newSize, int oldSize); + void (*free) (CCGAllocatorHDL a, void *ptr); + void (*release) (CCGAllocatorHDL a); }; /***/ @@ -38,114 +39,120 @@ typedef enum { /***/ -typedef struct _CSubSurf CSubSurf; +typedef struct _CCGSubSurf CCGSubSurf; + +CCGSubSurf* ccgSubSurf_new (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCGAllocatorHDL allocator); +void ccgSubSurf_free (CCGSubSurf *ss); -CSubSurf* CCS_new (CCGMeshIFC *ifc, int subdivisionLevels, CCGAllocatorIFC *allocatorIFC, CCAllocHDL allocator); -void CCS_free (CSubSurf *ss); +CCGError ccgSubSurf_sync (CCGSubSurf *ss); -CCGError CCS_sync (CSubSurf *ss); +CCGError ccgSubSurf_initFullSync (CCGSubSurf *ss); +CCGError ccgSubSurf_initPartialSync (CCGSubSurf *ss); -CCGError CCS_initFullSync (CSubSurf *ss); -CCGError CCS_initPartialSync (CSubSurf *ss); +CCGError ccgSubSurf_syncVert (CCGSubSurf *ss, CCGVertHDL vHDL, void *vertData, int seam, CCGVert **v_r); +CCGError ccgSubSurf_syncEdge (CCGSubSurf *ss, CCGEdgeHDL eHDL, CCGVertHDL e_vHDL0, CCGVertHDL e_vHDL1, float crease, CCGEdge **e_r); +CCGError ccgSubSurf_syncFace (CCGSubSurf *ss, CCGFaceHDL fHDL, int numVerts, CCGVertHDL *vHDLs, CCGFace **f_r); -CCGError CCS_syncVert (CSubSurf *ss, CCVertHDL vHDL, void *vertData, int seam, CCVert **v_r); -CCGError CCS_syncEdge (CSubSurf *ss, CCEdgeHDL eHDL, CCVertHDL e_vHDL0, CCVertHDL e_vHDL1, float crease, CCEdge **e_r); -CCGError CCS_syncFace (CSubSurf *ss, CCFaceHDL fHDL, int numVerts, CCVertHDL *vHDLs, CCFace **f_r); +CCGError ccgSubSurf_syncVertDel (CCGSubSurf *ss, CCGVertHDL vHDL); +CCGError ccgSubSurf_syncEdgeDel (CCGSubSurf *ss, CCGEdgeHDL eHDL); +CCGError ccgSubSurf_syncFaceDel (CCGSubSurf *ss, CCGFaceHDL fHDL); -CCGError CCS_syncVertDel (CSubSurf *ss, CCVertHDL vHDL); -CCGError CCS_syncEdgeDel (CSubSurf *ss, CCEdgeHDL eHDL); -CCGError CCS_syncFaceDel (CSubSurf *ss, CCFaceHDL fHDL); +CCGError ccgSubSurf_processSync (CCGSubSurf *ss); -CCGError CCS_processSync (CSubSurf *ss); +CCGError ccgSubSurf_updateFromFaces(CCGSubSurf *ss, int lvl, CCGFace **faces, int numFaces); +CCGError ccgSubSurf_updateToFaces(CCGSubSurf *ss, int lvl, CCGFace **faces, int numFaces); +CCGError ccgSubSurf_updateNormals(CCGSubSurf *ss, CCGFace **faces, int numFaces); +CCGError ccgSubSurf_updateLevels(CCGSubSurf *ss, int lvl, CCGFace **faces, int numFaces); +CCGError ccgSubSurf_stitchFaces(CCGSubSurf *ss, int lvl, CCGFace **faces, int numFaces); -CCGError CCS_setSubdivisionLevels(CSubSurf *ss, int subdivisionLevels); +CCGError ccgSubSurf_setSubdivisionLevels (CCGSubSurf *ss, int subdivisionLevels); -CCGError CCS_setAllowEdgeCreation(CSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData); -void CCS_getAllowEdgeCreation(CSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r); +CCGError ccgSubSurf_setAllowEdgeCreation (CCGSubSurf *ss, int allowEdgeCreation, float defaultCreaseValue, void *defaultUserData); +void ccgSubSurf_getAllowEdgeCreation (CCGSubSurf *ss, int *allowEdgeCreation_r, float *defaultCreaseValue_r, void *defaultUserData_r); -void CCS_getUseAgeCounts (CSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r); -CCGError CCS_setUseAgeCounts (CSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset); +void ccgSubSurf_getUseAgeCounts (CCGSubSurf *ss, int *useAgeCounts_r, int *vertUserOffset_r, int *edgeUserOffset_r, int *faceUserOffset_r); +CCGError ccgSubSurf_setUseAgeCounts (CCGSubSurf *ss, int useAgeCounts, int vertUserOffset, int edgeUserOffset, int faceUserOffset); -CCGError CCS_setCalcVertexNormals(CSubSurf *ss, int useVertNormals, int normalDataOffset); +CCGError ccgSubSurf_setCalcVertexNormals (CCGSubSurf *ss, int useVertNormals, int normalDataOffset); /***/ -int CCS_getNumVerts (CSubSurf *ss); -int CCS_getNumEdges (CSubSurf *ss); -int CCS_getNumFaces (CSubSurf *ss); - -int CCS_getSubdivisionLevels(CSubSurf *ss); -int CCS_getEdgeSize (CSubSurf *ss); -int CCS_getEdgeLevelSize (CSubSurf *ss, int level); -int CCS_getGridSize (CSubSurf *ss); -int CCS_getGridLevelSize (CSubSurf *ss, int level); - -CCVert* CCS_getVert (CSubSurf *ss, CCVertHDL v); -CCVertHDL CCS_getVertVertHandle (CCVert *v); -int CCS_getVertNumFaces (CCVert *v); -CCFace* CCS_getVertFace (CCVert *v, int index); -int CCS_getVertNumEdges (CCVert *v); -CCEdge* CCS_getVertEdge (CCVert *v, int index); - -int CCS_getVertAge (CSubSurf *ss, CCVert *v); -void* CCS_getVertUserData (CSubSurf *ss, CCVert *v); -void* CCS_getVertData (CSubSurf *ss, CCVert *v); -void* CCS_getVertLevelData (CSubSurf *ss, CCVert *v, int level); - -CCEdge* CCS_getEdge (CSubSurf *ss, CCEdgeHDL e); -CCEdgeHDL CCS_getEdgeEdgeHandle (CCEdge *e); -int CCS_getEdgeNumFaces (CCEdge *e); -CCFace* CCS_getEdgeFace (CCEdge *e, int index); -CCVert* CCS_getEdgeVert0 (CCEdge *e); -CCVert* CCS_getEdgeVert1 (CCEdge *e); -float CCS_getEdgeCrease (CCEdge *e); - -int CCS_getEdgeAge (CSubSurf *ss, CCEdge *e); -void* CCS_getEdgeUserData (CSubSurf *ss, CCEdge *e); -void* CCS_getEdgeDataArray (CSubSurf *ss, CCEdge *e); -void* CCS_getEdgeData (CSubSurf *ss, CCEdge *e, int x); -void* CCS_getEdgeLevelData (CSubSurf *ss, CCEdge *e, int x, int level); - -CCFace* CCS_getFace (CSubSurf *ss, CCFaceHDL f); -CCFaceHDL CCS_getFaceFaceHandle (CSubSurf *ss, CCFace *f); -int CCS_getFaceNumVerts (CCFace *f); -CCVert* CCS_getFaceVert (CSubSurf *ss, CCFace *f, int index); -CCEdge* CCS_getFaceEdge (CSubSurf *ss, CCFace *f, int index); -int CCS_getFaceEdgeIndex (CCFace *f, CCEdge *e); - -int CCS_getFaceAge (CSubSurf *ss, CCFace *f); -void* CCS_getFaceUserData (CSubSurf *ss, CCFace *f); -void* CCS_getFaceCenterData (CCFace *f); -void* CCS_getFaceGridEdgeDataArray (CSubSurf *ss, CCFace *f, int gridIndex); -void* CCS_getFaceGridEdgeData (CSubSurf *ss, CCFace *f, int gridIndex, int x); -void* CCS_getFaceGridDataArray (CSubSurf *ss, CCFace *f, int gridIndex); -void* CCS_getFaceGridData (CSubSurf *ss, CCFace *f, int gridIndex, int x, int y); - -int CCS_getNumFinalVerts (CSubSurf *ss); -int CCS_getNumFinalEdges (CSubSurf *ss); -int CCS_getNumFinalFaces (CSubSurf *ss); +int ccgSubSurf_getNumVerts (CCGSubSurf *ss); +int ccgSubSurf_getNumEdges (CCGSubSurf *ss); +int ccgSubSurf_getNumFaces (CCGSubSurf *ss); + +int ccgSubSurf_getSubdivisionLevels (CCGSubSurf *ss); +int ccgSubSurf_getEdgeSize (CCGSubSurf *ss); +int ccgSubSurf_getEdgeLevelSize (CCGSubSurf *ss, int level); +int ccgSubSurf_getGridSize (CCGSubSurf *ss); +int ccgSubSurf_getGridLevelSize (CCGSubSurf *ss, int level); + +CCGVert* ccgSubSurf_getVert (CCGSubSurf *ss, CCGVertHDL v); +CCGVertHDL ccgSubSurf_getVertVertHandle (CCGVert *v); +int ccgSubSurf_getVertNumFaces (CCGVert *v); +CCGFace* ccgSubSurf_getVertFace (CCGVert *v, int index); +int ccgSubSurf_getVertNumEdges (CCGVert *v); +CCGEdge* ccgSubSurf_getVertEdge (CCGVert *v, int index); + +int ccgSubSurf_getVertAge (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertUserData (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertData (CCGSubSurf *ss, CCGVert *v); +void* ccgSubSurf_getVertLevelData (CCGSubSurf *ss, CCGVert *v, int level); + +CCGEdge* ccgSubSurf_getEdge (CCGSubSurf *ss, CCGEdgeHDL e); +CCGEdgeHDL ccgSubSurf_getEdgeEdgeHandle (CCGEdge *e); +int ccgSubSurf_getEdgeNumFaces (CCGEdge *e); +CCGFace* ccgSubSurf_getEdgeFace (CCGEdge *e, int index); +CCGVert* ccgSubSurf_getEdgeVert0 (CCGEdge *e); +CCGVert* ccgSubSurf_getEdgeVert1 (CCGEdge *e); +float ccgSubSurf_getEdgeCrease (CCGEdge *e); + +int ccgSubSurf_getEdgeAge (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeUserData (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeDataArray (CCGSubSurf *ss, CCGEdge *e); +void* ccgSubSurf_getEdgeData (CCGSubSurf *ss, CCGEdge *e, int x); +void* ccgSubSurf_getEdgeLevelData (CCGSubSurf *ss, CCGEdge *e, int x, int level); + +CCGFace* ccgSubSurf_getFace (CCGSubSurf *ss, CCGFaceHDL f); +CCGFaceHDL ccgSubSurf_getFaceFaceHandle (CCGSubSurf *ss, CCGFace *f); +int ccgSubSurf_getFaceNumVerts (CCGFace *f); +CCGVert* ccgSubSurf_getFaceVert (CCGSubSurf *ss, CCGFace *f, int index); +CCGEdge* ccgSubSurf_getFaceEdge (CCGSubSurf *ss, CCGFace *f, int index); +int ccgSubSurf_getFaceEdgeIndex (CCGFace *f, CCGEdge *e); + +int ccgSubSurf_getFaceAge (CCGSubSurf *ss, CCGFace *f); +void* ccgSubSurf_getFaceUserData (CCGSubSurf *ss, CCGFace *f); +void* ccgSubSurf_getFaceCenterData (CCGFace *f); +void* ccgSubSurf_getFaceGridEdgeDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex); +void* ccgSubSurf_getFaceGridEdgeData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x); +void* ccgSubSurf_getFaceGridDataArray (CCGSubSurf *ss, CCGFace *f, int gridIndex); +void* ccgSubSurf_getFaceGridData (CCGSubSurf *ss, CCGFace *f, int gridIndex, int x, int y); + +int ccgSubSurf_getNumFinalVerts (CCGSubSurf *ss); +int ccgSubSurf_getNumFinalEdges (CCGSubSurf *ss); +int ccgSubSurf_getNumFinalFaces (CCGSubSurf *ss); /***/ -typedef struct _CCVertIterator CCVertIterator; -typedef struct _CCEdgeIterator CCEdgeIterator; -typedef struct _CCFaceIterator CCFaceIterator; +typedef struct _CCGVertIterator CCGVertIterator; +typedef struct _CCGEdgeIterator CCGEdgeIterator; +typedef struct _CCGFaceIterator CCGFaceIterator; -CCVertIterator* CCS_getVertIterator (CSubSurf *ss); -CCEdgeIterator* CCS_getEdgeIterator (CSubSurf *ss); -CCFaceIterator* CCS_getFaceIterator (CSubSurf *ss); +CCGVertIterator* ccgSubSurf_getVertIterator (CCGSubSurf *ss); +CCGEdgeIterator* ccgSubSurf_getEdgeIterator (CCGSubSurf *ss); +CCGFaceIterator* ccgSubSurf_getFaceIterator (CCGSubSurf *ss); -CCVert* CCVIter_getCurrent (CCVertIterator *vi); -int CCVIter_isStopped (CCVertIterator *vi); -void CCVIter_next (CCVertIterator *vi); -void CCVIter_free (CCVertIterator *vi); +CCGVert* ccgVertIterator_getCurrent (CCGVertIterator *vi); +int ccgVertIterator_isStopped (CCGVertIterator *vi); +void ccgVertIterator_next (CCGVertIterator *vi); +void ccgVertIterator_free (CCGVertIterator *vi); -CCEdge* CCEIter_getCurrent (CCEdgeIterator *ei); -int CCEIter_isStopped (CCEdgeIterator *ei); -void CCEIter_next (CCEdgeIterator *ei); -void CCEIter_free (CCEdgeIterator *ei); +CCGEdge* ccgEdgeIterator_getCurrent (CCGEdgeIterator *ei); +int ccgEdgeIterator_isStopped (CCGEdgeIterator *ei); +void ccgEdgeIterator_next (CCGEdgeIterator *ei); +void ccgEdgeIterator_free (CCGEdgeIterator *ei); -CCFace* CCFIter_getCurrent (CCFaceIterator *fi); -int CCFIter_isStopped (CCFaceIterator *fi); -void CCFIter_next (CCFaceIterator *fi); -void CCFIter_free (CCFaceIterator *fi); +CCGFace* ccgFaceIterator_getCurrent (CCGFaceIterator *fi); +int ccgFaceIterator_isStopped (CCGFaceIterator *fi); +void ccgFaceIterator_next (CCGFaceIterator *fi); +void ccgFaceIterator_free (CCGFaceIterator *fi); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 4585a56675a..1876493f5e2 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1770,7 +1770,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier md->scene= scene; if (!(md->mode&eModifierMode_Realtime)) return NULL; - if (mti->isDisabled && mti->isDisabled(md)) return NULL; + if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL; if (mti->type==eModifierTypeType_OnlyDeform) { int numVerts; @@ -2141,7 +2141,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos mask &= ~CD_MASK_ORCO; DM_set_only_copy(orcodm, mask); - ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, !inputVertexCos); + ndm = mti->applyModifier(md, ob, orcodm, useRenderParams, 0); if(ndm) { /* if the modifier returned a new dm, release the old one */ @@ -2748,7 +2748,7 @@ int editbmesh_get_first_deform_matrices(Object *ob, BMEditMesh *em, float (**def } for(; md && i <= cageIndex; md = md->next, i++) - if(editbmesh_modifier_is_enabled(md, dm) && modifier_isDeformer(md)) + if(editbmesh_modifier_is_enabled(md, dm) && modifier_isCorrectableDeformed(md)) numleft++; if(dm) diff --git a/source/blender/blenkernel/intern/Makefile b/source/blender/blenkernel/intern/Makefile index 26b9b9ef0dd..95c82d31890 100644 --- a/source/blender/blenkernel/intern/Makefile +++ b/source/blender/blenkernel/intern/Makefile @@ -53,6 +53,8 @@ CPPFLAGS += -I../../blenlib CPPFLAGS += -I../../blenloader CPPFLAGS += -I../../python CPPFLAGS += -I../../blenfont +# This is bad level, remove eventually +CPPFLAGS += -I../../windowmanager # also avi is used CPPFLAGS += -I../../avi CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index af3c4719e32..303cd208b7c 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -153,7 +153,6 @@ void make_local_action(bAction *act) } } - void free_action (bAction *act) { /* sanity check */ @@ -255,101 +254,68 @@ void set_active_action_group (bAction *act, bActionGroup *agrp, short select) * - always adds at the end of the group */ void action_groups_add_channel (bAction *act, bActionGroup *agrp, FCurve *fcurve) -{ - FCurve *fcu; - short done=0; - +{ /* sanity checks */ if (ELEM3(NULL, act, agrp, fcurve)) return; - /* if no channels, just add to two lists at the same time */ + /* if no channels anywhere, just add to two lists at the same time */ if (act->curves.first == NULL) { fcurve->next = fcurve->prev = NULL; agrp->channels.first = agrp->channels.last = fcurve; act->curves.first = act->curves.last = fcurve; - - fcurve->grp= agrp; - return; } - /* try to find a channel to slot this in before/after */ - for (fcu= act->curves.first; fcu; fcu= fcu->next) { - /* if channel has no group, then we have ungrouped channels, which should always occur after groups */ - if (fcu->grp == NULL) { - BLI_insertlinkbefore(&act->curves, fcu, fcurve); - - if (agrp->channels.first == NULL) - agrp->channels.first= fcurve; - agrp->channels.last= fcurve; + /* if the group already has channels, the F-Curve can simply be added to the list + * (i.e. as the last channel in the group) + */ + else if (agrp->channels.first) { + /* if the group's last F-Curve is the action's last F-Curve too, + * then set the F-Curve as the last for the action first so that + * the lists will be in sync after linking + */ + if (agrp->channels.last == act->curves.last) + act->curves.last= fcurve; - done= 1; - break; - } + /* link in the given F-Curve after the last F-Curve in the group, + * which means that it should be able to fit in with the rest of the + * list seamlessly + */ + BLI_insertlinkafter(&agrp->channels, agrp->channels.last, fcurve); + } + + /* otherwise, need to find the nearest F-Curve in group before/after current to link with */ + else { + bActionGroup *grp; - /* if channel has group after current, we can now insert (otherwise we have gone too far) */ - else if (fcu->grp == agrp->next) { - BLI_insertlinkbefore(&act->curves, fcu, fcurve); - - if (agrp->channels.first == NULL) - agrp->channels.first= fcurve; - agrp->channels.last= fcurve; - - done= 1; - break; - } + /* firstly, link this F-Curve to the group */ + agrp->channels.first = agrp->channels.last = fcurve; - /* if channel has group we're targeting, check whether it is the last one of these */ - else if (fcu->grp == agrp) { - if ((fcu->next) && (fcu->next->grp != agrp)) { - BLI_insertlinkafter(&act->curves, fcu, fcurve); - agrp->channels.last= fcurve; - done= 1; - break; - } - else if (fcu->next == NULL) { - BLI_addtail(&act->curves, fcurve); - agrp->channels.last= fcurve; - done= 1; + /* step through the groups preceeding this one, finding the F-Curve there to attach this one after */ + for (grp= agrp->prev; grp; grp= grp->prev) { + /* if this group has F-Curves, we want weave the given one in right after the last channel there, + * but via the Action's list not this group's list + * - this is so that the F-Curve is in the right place in the Action, + * but won't be included in the previous group + */ + if (grp->channels.last) { + /* once we've added, break here since we don't need to search any further... */ + BLI_insertlinkafter(&act->curves, grp->channels.last, fcurve); break; } } - /* if channel has group before target, check whether the next one is something after target */ - else if (fcu->grp == agrp->prev) { - if (fcu->next) { - if ((fcu->next->grp != fcu->grp) && (fcu->next->grp != agrp)) { - BLI_insertlinkafter(&act->curves, fcu, fcurve); - - agrp->channels.first= fcurve; - agrp->channels.last= fcurve; - - done= 1; - break; - } - } - else { - BLI_insertlinkafter(&act->curves, fcu, fcurve); - - agrp->channels.first= fcurve; - agrp->channels.last= fcurve; - - done= 1; - break; - } - } + /* if grp is NULL, that means we fell through, and this F-Curve should be added as the new first + * since group is (effectively) the first group. Thus, the existing first F-Curve becomes the + * second in the chain, etc. etc. + */ + if (grp == NULL) + BLI_insertlinkbefore(&act->curves, act->curves.first, fcurve); } - /* only if added, set channel as belonging to this group */ - if (done) { - //printf("FCurve added to group \n"); - fcurve->grp= agrp; - } - else { - printf("Error: FCurve '%s' couldn't be added to Group '%s' \n", fcurve->rna_path, agrp->name); - BLI_addtail(&act->curves, fcurve); - } + /* set the F-Curve's new group */ + fcurve->grp= agrp; } /* Remove the given channel from all groups */ @@ -457,6 +423,8 @@ bPoseChannel *verify_pose_channel(bPose* pose, const char* name) chan->ikrotweight = chan->iklinweight = 0.0f; unit_m4(chan->constinv); + chan->protectflag = OB_LOCK_ROT4D; /* lock by components by default */ + BLI_addtail(&pose->chanbase, chan); return chan; @@ -640,6 +608,48 @@ static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan } } +/* makes copies of internal data, unlike copy_pose_channel_data which only + * copies the pose state. + * hint: use when copying bones in editmode (on returned value from verify_pose_channel) */ +void duplicate_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *pchan_from) +{ + /* copy transform locks */ + pchan->protectflag = pchan_from->protectflag; + + /* copy rotation mode */ + pchan->rotmode = pchan_from->rotmode; + + /* copy bone group */ + pchan->agrp_index= pchan_from->agrp_index; + + /* ik (dof) settings */ + pchan->ikflag = pchan_from->ikflag; + VECCOPY(pchan->limitmin, pchan_from->limitmin); + VECCOPY(pchan->limitmax, pchan_from->limitmax); + VECCOPY(pchan->stiffness, pchan_from->stiffness); + pchan->ikstretch= pchan_from->ikstretch; + pchan->ikrotweight= pchan_from->ikrotweight; + pchan->iklinweight= pchan_from->iklinweight; + + /* constraints */ + copy_constraints(&pchan->constraints, &pchan_from->constraints); + + /* id-properties */ + if(pchan->prop) { + /* unlikely but possible it exists */ + IDP_FreeProperty(pchan->prop); + MEM_freeN(pchan->prop); + pchan->prop= NULL; + } + if(pchan_from->prop) { + pchan->prop= IDP_CopyProperty(pchan_from->prop); + } + + /* custom shape */ + pchan->custom= pchan_from->custom; +} + + /* checks for IK constraint, Spline IK, and also for Follow-Path constraint. * can do more constraints flags later */ @@ -1042,7 +1052,10 @@ void copy_pose_result(bPose *to, bPose *from) VECCOPY(pchanto->pose_head, pchanfrom->pose_head); VECCOPY(pchanto->pose_tail, pchanfrom->pose_tail); + + pchanto->rotmode= pchanfrom->rotmode; pchanto->flag= pchanfrom->flag; + pchanto->protectflag= pchanfrom->protectflag; } } } diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 5ebcec63cd4..a6f733708c7 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -697,20 +697,26 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i switch (RNA_property_type(prop)) { case PROP_BOOLEAN: - if (RNA_property_array_length(&new_ptr, prop)) - RNA_property_boolean_set_index(&new_ptr, prop, array_index, (int)value); + if (RNA_property_array_length(&new_ptr, prop)) { + if (RNA_property_editable_index(&new_ptr, prop, array_index)) + RNA_property_boolean_set_index(&new_ptr, prop, array_index, (int)value); + } else RNA_property_boolean_set(&new_ptr, prop, (int)value); break; case PROP_INT: - if (RNA_property_array_length(&new_ptr, prop)) - RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value); + if (RNA_property_array_length(&new_ptr, prop)){ + if (RNA_property_editable_index(&new_ptr, prop, array_index)) + RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value); + } else RNA_property_int_set(&new_ptr, prop, (int)value); break; case PROP_FLOAT: - if (RNA_property_array_length(&new_ptr, prop)) - RNA_property_float_set_index(&new_ptr, prop, array_index, value); + if (RNA_property_array_length(&new_ptr, prop)) { + if (RNA_property_editable_index(&new_ptr, prop, array_index)) + RNA_property_float_set_index(&new_ptr, prop, array_index, value); + } else RNA_property_float_set(&new_ptr, prop, value); break; @@ -1434,20 +1440,26 @@ void nladata_flush_channels (ListBase *channels) switch (RNA_property_type(prop)) { case PROP_BOOLEAN: - if (RNA_property_array_length(ptr, prop)) - RNA_property_boolean_set_index(ptr, prop, array_index, (int)value); + if (RNA_property_array_length(ptr, prop)) { + if (RNA_property_editable_index(ptr, prop, array_index)) + RNA_property_boolean_set_index(ptr, prop, array_index, (int)value); + } else RNA_property_boolean_set(ptr, prop, (int)value); break; case PROP_INT: - if (RNA_property_array_length(ptr, prop)) - RNA_property_int_set_index(ptr, prop, array_index, (int)value); + if (RNA_property_array_length(ptr, prop)) { + if (RNA_property_editable_index(ptr, prop, array_index)) + RNA_property_int_set_index(ptr, prop, array_index, (int)value); + } else RNA_property_int_set(ptr, prop, (int)value); break; case PROP_FLOAT: - if (RNA_property_array_length(ptr, prop)) - RNA_property_float_set_index(ptr, prop, array_index, value); + if (RNA_property_array_length(ptr, prop)) { + if (RNA_property_editable_index(ptr, prop, array_index)) + RNA_property_float_set_index(ptr, prop, array_index, value); + } else RNA_property_float_set(ptr, prop, value); break; diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 75ee27a73af..8d8f33238c3 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BLI_cellalloc.h" +#include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_action_types.h" #include "DNA_curve_types.h" @@ -50,6 +51,7 @@ #include "DNA_scene_types.h" #include "DNA_view3d_types.h" +#include "BKE_animsys.h" #include "BKE_armature.h" #include "BKE_action.h" #include "BKE_anim.h" @@ -128,6 +130,12 @@ void free_armature(bArmature *arm) freeSketch(arm->sketch); arm->sketch = NULL; } + + /* free animation data */ + if (arm->adt) { + BKE_free_animdata(&arm->id); + arm->adt= NULL; + } } } @@ -177,6 +185,9 @@ static void copy_bonechildren (Bone* newBone, Bone* oldBone, Bone* actBone, Bone if(oldBone == actBone) *newActBone= newBone; + if(oldBone->prop) + newBone->prop= IDP_CopyProperty(oldBone->prop); + /* Copy this bone's list*/ BLI_duplicatelist(&newBone->childbase, &oldBone->childbase); @@ -1502,6 +1513,10 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected pchanw.child= pchan->child; pchanw.path= NULL; + /* this is freed so copy a copy, else undo crashes */ + if(pchanw.prop) + pchanw.prop= IDP_CopyProperty(pchanw.prop); + /* constraints - proxy constraints are flushed... local ones are added after * 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints * 2. copy proxy-pchan's constraints on-to new @@ -2221,34 +2236,43 @@ void where_is_pose_bone(Scene *scene, Object *ob, bPoseChannel *pchan, float cti /* the rotation of the parent restposition */ copy_m4_m4(tmat, parbone->arm_mat); - - /* the location of actual parent transform */ - VECCOPY(tmat[3], offs_bone[3]); - offs_bone[3][0]= offs_bone[3][1]= offs_bone[3][2]= 0.0f; - mul_m4_v3(parchan->pose_mat, tmat[3]); - mul_serie_m4(pchan->pose_mat, tmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); } else if(bone->flag & BONE_NO_SCALE) { float orthmat[4][4]; - /* get the official transform, but we only use the vector from it (optimize...) */ - mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - VECCOPY(vec, pchan->pose_mat[3]); - - /* do this again, but with an ortho-parent matrix */ + /* do transform, with an ortho-parent matrix */ copy_m4_m4(orthmat, parchan->pose_mat); normalize_m4(orthmat); mul_serie_m4(pchan->pose_mat, orthmat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); - - /* copy correct transform */ - VECCOPY(pchan->pose_mat[3], vec); } - else + else mul_serie_m4(pchan->pose_mat, parchan->pose_mat, offs_bone, pchan->chan_mat, NULL, NULL, NULL, NULL, NULL); + + /* in these cases we need to compute location separately */ + if(bone->flag & (BONE_HINGE|BONE_NO_SCALE|BONE_NO_LOCAL_LOCATION)) { + float bone_loc[3], chan_loc[3]; + + mul_v3_m4v3(bone_loc, parchan->pose_mat, offs_bone[3]); + copy_v3_v3(chan_loc, pchan->chan_mat[3]); + + /* no local location is not transformed by bone matrix */ + if(!(bone->flag & BONE_NO_LOCAL_LOCATION)) + mul_mat3_m4_v3(offs_bone, chan_loc); + + /* for hinge we use armature instead of pose mat */ + if(bone->flag & BONE_HINGE) mul_mat3_m4_v3(parbone->arm_mat, chan_loc); + else mul_mat3_m4_v3(parchan->pose_mat, chan_loc); + + add_v3_v3v3(pchan->pose_mat[3], bone_loc, chan_loc); + } } else { mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, bone->arm_mat); + + /* optional location without arm_mat rotation */ + if(bone->flag & BONE_NO_LOCAL_LOCATION) + add_v3_v3v3(pchan->pose_mat[3], bone->arm_mat[3], pchan->chan_mat[3]); /* only rootbones get the cyclic offset (unless user doesn't want that) */ if ((bone->flag & BONE_NO_CYCLICOFFSET) == 0) diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index a803f14b664..f3e46104efc 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -83,7 +83,7 @@ #include "BKE_report.h" #include "BKE_scene.h" #include "BKE_screen.h" -#include "BKE_sequence.h" +#include "BKE_sequencer.h" #include "BKE_sound.h" #include "BLI_editVert.h" @@ -94,6 +94,8 @@ #include "BKE_utildefines.h" // O_BINARY FALSE +#include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie + Global G; UserDef U; ListBase WMlist= {NULL, NULL}; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index a9d72d93091..667b0d50ee9 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -40,6 +40,8 @@ #include "DNA_scene_types.h" #include "DNA_windowmanager_types.h" +#include "WM_types.h" + #include "RNA_access.h" #include "BLI_math.h" @@ -56,6 +58,8 @@ #include "BKE_texture.h" #include "BKE_utildefines.h" + + #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -75,13 +79,14 @@ Brush *add_brush(const char *name) brush->rgb[2]= 1.0f; brush->alpha= 0.2f; brush->size= 25; - brush->spacing= 10.0f; + brush->spacing= 7.5f; brush->smooth_stroke_radius= 75; brush->smooth_stroke_factor= 0.9; brush->rate= 0.1f; brush->jitter= 0.0f; brush->clone.alpha= 0.5; brush->sculpt_tool = SCULPT_TOOL_DRAW; + brush->flag |= BRUSH_SPACE; brush_curve_preset(brush, BRUSH_PRESET_SMOOTH); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index c76d40fc0b1..9d47425fcd4 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1,4 +1,4 @@ -/* + /* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -52,7 +52,7 @@ #include "BLI_blenlib.h" #include "BLI_edgehash.h" #include "BLI_editVert.h" -#include "BLI_ghash.h" +#include "BLI_pbvh.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -82,6 +82,12 @@ typedef struct { MFace *mface; MLoop *mloop; MPoly *mpoly; + + /* Cached */ + struct PBVH *pbvh; + /* Mesh connectivity */ + struct ListBase *fmap; + struct IndexNode *fmap_mem; } CDDerivedMesh; DMFaceIter *cdDM_newFaceIter(DerivedMesh *source); @@ -183,6 +189,33 @@ static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) no_r[2] = no[2]/32767.f; } +static ListBase *cdDM_getFaceMap(DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + + if(!cddm->fmap) { + create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, cddm->mface, + dm->getNumVerts(dm), dm->getNumFaces(dm)); + } + + return cddm->fmap; +} + +static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + + if(!cddm->pbvh && ob->type == OB_MESH) { + Mesh *me= ob->data; + + cddm->pbvh = BLI_pbvh_new(); + BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, + me->totface, me->totvert); + } + + return cddm->pbvh; +} + static void cdDM_drawVerts(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; @@ -372,7 +405,9 @@ static void cdDM_drawLooseEdges(DerivedMesh *dm) } } -static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) +static void cdDM_drawFacesSolid(DerivedMesh *dm, + float (*partial_redraw_planes)[4], + int fast, int (*setMaterial)(int, void *attribs)) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; MVert *mvert = cddm->mvert; @@ -388,6 +423,20 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a glVertex3fv(mvert[index].co); \ } + if(cddm->pbvh) { + float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL); + + /* should be per face */ + if(dm->numFaceData && mface->flag & ME_SMOOTH) + glShadeModel(GL_SMOOTH); + + BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors); + + glShadeModel(GL_FLAT); + + return; + } + if( GPU_buffer_legacy(dm) ) { DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" ); glBegin(glmode = GL_QUADS); @@ -563,7 +612,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, unsigned char *cp = NULL; if(drawParams) { - flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr); + flag = drawParams(tf? &tf[i]: NULL, mcol!=NULL, mf->mat_nr); } else { if(index) { @@ -668,7 +717,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, int flag = 1; if(drawParams) { - flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr); + flag = drawParams(tf? &tf[actualFace]: NULL, mcol!=NULL, mf[actualFace].mat_nr); } else { if(index) { @@ -897,7 +946,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo continue; } else if(setDrawOptions) { - orig = index[a]; + orig = (index)? index[a]: a; if(orig == ORIGINDEX_NONE) continue; @@ -1299,7 +1348,7 @@ static void cdDM_recalcTesselation(DerivedMesh *dm) dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, - dm->numPolyData, 1); + dm->numPolyData, 1, 0); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); } @@ -1311,17 +1360,26 @@ static void cdDM_recalcTesselation2(DerivedMesh *dm) dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData, &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData, - dm->numPolyData, 0); + dm->numPolyData, 0, 0); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); } +static void cdDM_free_internal(CDDerivedMesh *cddm) +{ + if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh); + if(cddm->fmap) MEM_freeN(cddm->fmap); + if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem); +} + static void cdDM_release(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - if (DM_release(dm)) + if (DM_release(dm)) { + cdDM_free_internal(cddm); MEM_freeN(cddm); + } } int CDDM_Check(DerivedMesh *dm) @@ -1367,6 +1425,9 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->getVertCo = cdDM_getVertCo; dm->getVertNo = cdDM_getVertNo; + dm->getPBVH = cdDM_getPBVH; + dm->getFaceMap = cdDM_getFaceMap; + dm->drawVerts = cdDM_drawVerts; dm->drawUVEdges = cdDM_drawUVEdges; @@ -1423,18 +1484,13 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm"); DerivedMesh *dm = &cddm->dm; CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS); - int i, *index, alloctype; + int alloctype; - /* this does a referenced copy, the only new layers being ORIGINDEX, - * with an exception for fluidsim */ + /* this does a referenced copy, with an exception for fluidsim */ DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface, mesh->totloop, mesh->totpoly); - CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert); - CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge); - CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totpoly); - dm->deformedOnly = 1; alloctype= CD_REFERENCE; @@ -1456,18 +1512,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); - index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX); - for(i = 0; i < mesh->totvert; ++i, ++index) - *index = i; - - index = CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX); - for(i = 0; i < mesh->totedge; ++i, ++index) - *index = i; - - index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX); - for(i = 0; i < mesh->totpoly; ++i, ++index) - *index = i; - if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface); @@ -1907,6 +1951,11 @@ DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces) int numLoops = source->numLoopData; int numPolys = source->numPolyData; + /* ensure these are created if they are made on demand */ + source->getVertDataArray(source, CD_ORIGINDEX); + source->getEdgeDataArray(source, CD_ORIGINDEX); + source->getTessFaceDataArray(source, CD_ORIGINDEX); + /* this initializes dm, and copies all non mvert/medge/mface layers */ DM_from_template(dm, source, numVerts, numEdges, numFaces, numLoops, numPolys); @@ -1953,6 +2002,13 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops); CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys); + if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX)) + CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts); + if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX)) + CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges); + if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) + CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces); + cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE); @@ -2334,244 +2390,20 @@ void CDDM_tessfaces_to_faces(DerivedMesh *dm) void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - CustomData_add_layer(&cddm->dm.vertData, CD_MVERT, CD_ASSIGN, mvert, cddm->dm.numVertData); + cddm->mvert = mvert; } void CDDM_set_medge(DerivedMesh *dm, MEdge *medge) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - CustomData_add_layer(&cddm->dm.edgeData, CD_MEDGE, CD_ASSIGN, medge, cddm->dm.numEdgeData); + cddm->medge = medge; } void CDDM_set_mface(DerivedMesh *dm, MFace *mface) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - CustomData_add_layer(&cddm->dm.faceData, CD_MFACE, CD_ASSIGN, mface, cddm->dm.numFaceData); - cddm->mface = mface; -} - -void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop) -{ - CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, mloop, cddm->dm.numLoopData); - cddm->mloop = mloop; -} - -void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly) -{ - CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, mpoly, cddm->dm.numPolyData); - cddm->mpoly = mpoly; -} - - -/* Multires DerivedMesh, extends CDDM */ -typedef struct MultiresDM { - CDDerivedMesh cddm; - - MultiresModifierData *mmd; - int local_mmd; - - int lvl, totlvl; - float (*orco)[3]; - MVert *subco; - - ListBase *vert_face_map, *vert_edge_map; - IndexNode *vert_face_map_mem, *vert_edge_map_mem; - int *face_offsets; - - Object *ob; - int modified; - - void (*update)(DerivedMesh*); -} MultiresDM; - -static void MultiresDM_release(DerivedMesh *dm) -{ - MultiresDM *mrdm = (MultiresDM*)dm; - int mvert_layer; - - /* Before freeing, need to update the displacement map */ - if(dm->needsFree && mrdm->modified) { - /* Check that mmd still exists */ - if(!mrdm->local_mmd && BLI_findindex(&mrdm->ob->modifiers, mrdm->mmd) < 0) - mrdm->mmd = NULL; - if(mrdm->mmd) - mrdm->update(dm); - } - - /* If the MVert data is being used as the sculpt undo store, don't free it */ - mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT); - if(mvert_layer != -1) { - CustomDataLayer *cd = &dm->vertData.layers[mvert_layer]; - if(mrdm->mmd && cd->data == mrdm->mmd->undo_verts) - cd->flag |= CD_FLAG_NOFREE; - } - - if(DM_release(dm)) { - MEM_freeN(mrdm->subco); - MEM_freeN(mrdm->orco); - if(mrdm->vert_face_map) - MEM_freeN(mrdm->vert_face_map); - if(mrdm->vert_face_map_mem) - MEM_freeN(mrdm->vert_face_map_mem); - if(mrdm->vert_edge_map) - MEM_freeN(mrdm->vert_edge_map); - if(mrdm->vert_edge_map_mem) - MEM_freeN(mrdm->vert_edge_map_mem); - if(mrdm->face_offsets) - MEM_freeN(mrdm->face_offsets); - MEM_freeN(mrdm); - } -} -DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, - int numVerts, int numEdges, int numFaces, - int numLoops, int numPolys) -{ - MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM"); - CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM"); - DerivedMesh *dm = NULL; - - mrdm->cddm = *cddm; - MEM_freeN(cddm); - dm = &mrdm->cddm.dm; - - mrdm->mmd = ms->mmd; - mrdm->ob = ms->ob; - mrdm->local_mmd = ms->local_mmd; - - if(dm) { - MDisps *disps; - MVert *mvert; - int i; - - DM_from_template(dm, orig, numVerts, numEdges, numFaces, - numLoops, numPolys); - CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces); - - disps = CustomData_get_layer(&orig->faceData, CD_MDISPS); - if(disps) - CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces); - - - mvert = CustomData_get_layer(&orig->vertData, CD_MVERT); - mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco"); - for(i = 0; i < orig->getNumVerts(orig); ++i) - copy_v3_v3(mrdm->orco[i], mvert[i].co); - } - else - DM_init(dm, numVerts, numEdges, numFaces, numLoops, numPolys); - - CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts); - CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges); - CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces); - - mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); - mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); - mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE); - - mrdm->lvl = ms->mmd->lvl; - mrdm->totlvl = ms->mmd->totlvl; - mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts"); - mrdm->modified = 0; - - dm->release = MultiresDM_release; - - return dm; -} - -Mesh *MultiresDM_get_mesh(DerivedMesh *dm) -{ - return get_mesh(((MultiresDM*)dm)->ob); -} - -Object *MultiresDM_get_object(DerivedMesh *dm) -{ - return ((MultiresDM*)dm)->ob; -} - -void *MultiresDM_get_orco(DerivedMesh *dm) -{ - return ((MultiresDM*)dm)->orco; - -} - -MVert *MultiresDM_get_subco(DerivedMesh *dm) -{ - return ((MultiresDM*)dm)->subco; -} - -int MultiresDM_get_totlvl(DerivedMesh *dm) -{ - return ((MultiresDM*)dm)->totlvl; -} - -int MultiresDM_get_lvl(DerivedMesh *dm) -{ - return ((MultiresDM*)dm)->lvl; -} - -void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3]) -{ - ((MultiresDM*)dm)->orco = orco; -} - -void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*)) -{ - ((MultiresDM*)dm)->update = update; -} - -ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm) -{ - MultiresDM *mrdm = (MultiresDM*)dm; - Mesh *me = mrdm->ob->data; - - if(!mrdm->vert_face_map) - create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, me->mface, - me->totvert, me->totface); - - return mrdm->vert_face_map; -} - -ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm) -{ - MultiresDM *mrdm = (MultiresDM*)dm; - Mesh *me = mrdm->ob->data; - - if(!mrdm->vert_edge_map) - create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, me->medge, - me->totvert, me->totedge); - - return mrdm->vert_edge_map; -} - -int *MultiresDM_get_face_offsets(DerivedMesh *dm) -{ - MultiresDM *mrdm = (MultiresDM*)dm; - Mesh *me = mrdm->ob->data; - int i, accum = 0; - - if(!mrdm->face_offsets) { - int len = (int)pow(2, mrdm->lvl - 2) - 1; - int area = len * len; - int t = 1 + len * 3 + area * 3, q = t + len + area; - - mrdm->face_offsets = MEM_callocN(sizeof(int) * me->totface, "mrdm face offsets"); - for(i = 0; i < me->totface; ++i) { - mrdm->face_offsets[i] = accum; - - accum += (me->mface[i].v4 ? q : t); - } - } - - return mrdm->face_offsets; -} - -void MultiresDM_mark_as_modified(DerivedMesh *dm) -{ - ((MultiresDM*)dm)->modified = 1; + cddm->mface = mface; } - diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index a3517404c2b..2fdfaaabc01 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -155,6 +155,7 @@ void cloth_init ( ClothModifierData *clmd ) clmd->sim_parms->defgoal = 0.0f; clmd->sim_parms->goalspring = 1.0f; clmd->sim_parms->goalfrict = 0.0f; + clmd->sim_parms->velocity_smooth = 0.0f; if(!clmd->sim_parms->effector_weights) clmd->sim_parms->effector_weights = BKE_add_effector_weights(NULL); diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index f3448a60b5a..48e42bc539f 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -58,52 +58,6 @@ #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -/* ********************************* color transforms ********************************* */ - -/*Transform linear RGB values to nonlinear RGB values. Rec. - 709 is ITU-R Recommendation BT. 709 (1990) ``Basic - Parameter Values for the HDTV Standard for the Studio and - for International Programme Exchange'', formerly CCIR Rec. - 709.*/ -void gamma_correct_rec709(float *c, float gamma) -{ - /* Rec. 709 gamma correction. */ - const float cc = 0.018f; - - if (*c < cc) - *c *= ((1.099f * (float)powf(cc, gamma)) - 0.099f) * (1.0f/cc); - else - *c = (1.099f * (float)powf(*c, gamma)) - 0.099f; -} - -void gamma_correct(float *c, float gamma) -{ - *c = powf((*c), gamma); -} - -float srgb_to_linearrgb(float c) -{ - if (c < 0.04045f) - return (c < 0.0f)? 0.0f: c*(1.0f/12.92f); - else - return powf((c + 0.055f)*(1.0f/1.055f), 2.4f); -} - -float linearrgb_to_srgb(float c) -{ - if (c < 0.0031308f) - return (c < 0.0f)? 0.0f: c * 12.92f; - else - return 1.055f * powf(c, 1.0f/2.4f) - 0.055f; -} - -/* utility function convert an RGB triplet from sRGB to linear RGB color space */ -void color_manage_linearize(float *col_to, float *col_from) -{ - col_to[0] = srgb_to_linearrgb(col_from[0]); - col_to[1] = srgb_to_linearrgb(col_from[1]); - col_to[2] = srgb_to_linearrgb(col_from[2]); -} void floatbuf_to_srgb_byte(float *rectf, unsigned char *rectc, int x1, int x2, int y1, int y2, int w) { diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 8d750e73459..26f9215ad08 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -442,15 +442,14 @@ static void contarget_get_mesh_mat (Scene *scene, Object *ob, char *substring, f /* only continue if there's a valid DerivedMesh */ if (dm) { MDeformVert *dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); - int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); int numVerts = dm->getNumVerts(dm); int i, j, count = 0; float co[3], nor[3]; - /* check that dvert and index are valid pointers (just in case) */ - if (dvert && index) { + /* check that dvert is a valid pointers (just in case) */ + if (dvert) { /* get the average of all verts with that are in the vertex-group */ - for (i = 0; i < numVerts; i++, index++) { + for (i = 0; i < numVerts; i++) { for (j = 0; j < dvert[i].totweight; j++) { /* does this vertex belong to nominated vertex group? */ if (dvert[i].dw[j].def_nr == dgroup) { @@ -1194,17 +1193,17 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if ((data->followflag & FOLLOWPATH_STATIC) == 0) { /* animated position along curve depending on time */ if (cob->scene) - curvetime= bsystem_time(cob->scene, ct->tar, ctime, 0.0) - data->offset; + curvetime= bsystem_time(cob->scene, ct->tar, cu->ctime, 0.0) - data->offset; else - curvetime= ctime - data->offset; + curvetime= cu->ctime - data->offset; /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, * but this will only work if it actually is animated... * - * we firstly calculate the modulus of cu->ctime/cu->pathlen to clamp ctime within the 0.0 to 1.0 times pathlen - * range, then divide this (the modulus) by pathlen to get a value between 0.0 and 1.0 + * we divide the curvetime calculated in the previous step by the length of the path, to get a time + * factor, which then gets clamped to lie within 0.0 - 1.0 range */ - curvetime= fmod(cu->ctime, cu->pathlen) / cu->pathlen; + curvetime /= cu->pathlen; CLAMP(curvetime, 0.0, 1.0); } else { @@ -1214,7 +1213,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr if ( where_on_path(ct->tar, curvetime, vec, dir, NULL, &radius) ) { if (data->followflag & FOLLOWPATH_FOLLOW) { - vec_to_quat( quat,dir, (short) data->trackflag, (short) data->upflag); + vec_to_quat(quat, dir, (short)data->trackflag, (short)data->upflag); normalize_v3(dir); q[0]= (float)cos(0.5*vec[3]); @@ -1224,7 +1223,7 @@ static void followpath_get_tarmat (bConstraint *con, bConstraintOb *cob, bConstr q[3]= -x1*dir[2]; mul_qt_qtqt(quat, q, quat); - quat_to_mat4( totmat,quat); + quat_to_mat4(totmat, quat); } if (data->followflag & FOLLOWPATH_RADIUS) { @@ -1254,12 +1253,12 @@ static void followpath_evaluate (bConstraint *con, bConstraintOb *cob, ListBase float size[3]; bFollowPathConstraint *data= con->data; - /* get Object local transform (loc/rot/size) to determine transformation from path */ - //object_to_mat4(ob, obmat); - copy_m4_m4(obmat, cob->matrix); // FIXME!!! + /* get Object transform (loc/rot/size) to determine transformation from path */ + // TODO: this used to be local at one point, but is probably more useful as-is + copy_m4_m4(obmat, cob->matrix); /* get scaling of object before applying constraint */ - mat4_to_size( size,cob->matrix); + mat4_to_size(size, cob->matrix); /* apply targetmat - containing location on path, and rotation */ mul_serie_m4(cob->matrix, ct->matrix, obmat, NULL, NULL, NULL, NULL, NULL, NULL); @@ -3790,7 +3789,7 @@ void relink_constraints (ListBase *conlist) /* ......... */ /* duplicate all of the constraints in a constraint stack */ -void copy_constraints (ListBase *dst, ListBase *src) +void copy_constraints (ListBase *dst, const ListBase *src) { bConstraint *con, *srccon; diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 21549f6b147..fc1ef4aede9 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -878,18 +878,18 @@ int CTX_data_editable_bones(const bContext *C, ListBase *list) return ctx_data_collection_get(C, "editable_bones", list); } -struct bPoseChannel *CTX_data_active_pchan(const bContext *C) +struct bPoseChannel *CTX_data_active_pose_bone(const bContext *C) { - return ctx_data_pointer_get(C, "active_pchan"); + return ctx_data_pointer_get(C, "active_pose_bone"); } -int CTX_data_selected_pchans(const bContext *C, ListBase *list) +int CTX_data_selected_pose_bones(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "selected_pchans", list); + return ctx_data_collection_get(C, "selected_pose_bones", list); } -int CTX_data_visible_pchans(const bContext *C, ListBase *list) +int CTX_data_visible_pose_bones(const bContext *C, ListBase *list) { - return ctx_data_collection_get(C, "visible_pchans", list); + return ctx_data_collection_get(C, "visible_pose_bones", list); } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index eba35d579bf..e0f1c1342da 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -32,19 +32,27 @@ * */ -#include "BKE_customdata.h" -#include "BKE_utildefines.h" // CLAMP -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_linklist.h" -#include "BLI_mempool.h" +#include <math.h> +#include <string.h> #include "BLI_cellalloc.h" +#include "MEM_guardedalloc.h" + #include "DNA_customdata_types.h" #include "DNA_listBase.h" #include "DNA_meshdata_types.h" +#include "DNA_ID.h" -#include "MEM_guardedalloc.h" +#include "BLI_blenlib.h" +#include "BLI_linklist.h" +#include "BLI_math.h" +#include "BLI_mempool.h" +#include "BLI_string.h" + +#include "BKE_customdata.h" +#include "BKE_customdata_file.h" +#include "BKE_global.h" +#include "BKE_utildefines.h" #include "bmesh.h" @@ -100,6 +108,15 @@ typedef struct LayerTypeInfo { void (*add)(void *data1, void *data2); void (*dominmax)(void *data1, void *min, void *max); void (*copyvalue)(void *source, void *dest); + + /* a function to read data from a cdf file */ + int (*read)(CDataFile *cdf, void *data, int count); + + /* a function to write data to a cdf file */ + int (*write)(CDataFile *cdf, void *data, int count); + + /* a function to determine file size */ + size_t (*filesize)(CDataFile *cdf, void *data, int count); } LayerTypeInfo; static void layerCopy_mdeformvert(const void *source, void *dest, @@ -393,6 +410,7 @@ static void layerDefault_origspace_face(void *data, int count) osf[i] = default_osf; } +#if 0 /* Adapted from sculptmode.c */ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v) { @@ -438,23 +456,28 @@ static void mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, fl add_v3_v3v3(out, d2[0], d2[1]); } +#endif + +static int mdisp_corners(MDisps *s) +{ + /* silly trick because we don't get it from callback */ + return (s->totdisp % (3*3) == 0)? 3: 4; +} static void layerSwap_mdisps(void *data, int *ci) { MDisps *s = data; float (*d)[3] = NULL; - int x, y, st; + int corners, cornersize, S; - if(!(ci[0] == 2 && ci[1] == 3 && ci[2] == 0 && ci[3] == 1)) return; + /* this function is untested .. */ + corners = mdisp_corners(s); + cornersize = s->totdisp/corners; d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap"); - st = sqrt(s->totdisp); - for(y = 0; y < st; ++y) { - for(x = 0; x < st; ++x) { - copy_v3_v3(d[(st - y - 1) * st + (st - x - 1)], s->disps[y * st + x]); - } - } + for(S = 0; S < corners; S++) + memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float)); if(s->disps) MEM_freeN(s->disps); @@ -464,6 +487,8 @@ static void layerSwap_mdisps(void *data, int *ci) static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights, int count, void *dest) { + // XXX +#if 0 MDisps *d = dest; MDisps *s = NULL; int st, stl; @@ -508,6 +533,7 @@ static void layerInterp_mdisps(void **sources, float *weights, float *sub_weight copy_v3_v3(d->disps[y * st + x], srcdisp); } } +#endif } static void layerCopy_mdisps(const void *source, void *dest, int count) @@ -542,6 +568,51 @@ static void layerFree_mdisps(void *data, int count, int size) } } +static int layerRead_mdisps(CDataFile *cdf, void *data, int count) +{ + MDisps *d = data; + int i; + + for(i = 0; i < count; ++i) { + if(!d[i].disps) + d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read"); + + if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) { + printf("failed to read %d/%d %d\n", i, count, d[i].totdisp); + return 0; + } + } + + return 1; +} + +static int layerWrite_mdisps(CDataFile *cdf, void *data, int count) +{ + MDisps *d = data; + int i; + + for(i = 0; i < count; ++i) { + if(!cdf_write_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) { + printf("failed to write %d/%d %d\n", i, count, d[i].totdisp); + return 0; + } + } + + return 1; +} + +static size_t layerFilesize_mdisps(CDataFile *cdf, void *data, int count) +{ + MDisps *d = data; + size_t size = 0; + int i; + + for(i = 0; i < count; ++i) + size += d[i].totdisp*3*sizeof(float); + + return size; +} + /* --------- */ static void layerCopyValue_mloopcol(void *source, void *dest) { @@ -882,7 +953,9 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol}, {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps, - layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}, + layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, + layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps}, {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol, layerSwap_mcol, layerDefault_mcol}, {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL}, @@ -912,7 +985,7 @@ const CustomDataMask CD_MASK_MESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP | - CD_MASK_MTEXPOLY | CD_MASK_NORMAL; + CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_MDISPS; const CustomDataMask CD_MASK_EDITMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX | @@ -926,7 +999,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL; const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX; + CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS; const CustomDataMask CD_MASK_FACECORNERS = CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL; @@ -1036,6 +1109,14 @@ static void customData_free_layer__internal(CustomDataLayer *layer, int totelem) } } +static void CustomData_external_free(CustomData *data) +{ + if(data->external) { + MEM_freeN(data->external); + data->external= NULL; + } +} + void CustomData_free(CustomData *data, int totelem) { int i; @@ -1046,6 +1127,8 @@ void CustomData_free(CustomData *data, int totelem) if(data->layers) MEM_freeN(data->layers); + CustomData_external_free(data); + memset(data, 0, sizeof(*data)); } @@ -1131,7 +1214,7 @@ int CustomData_get_clone_layer_index(const CustomData *data, int type) return -1; } -int CustomData_get_mask_layer_index(const CustomData *data, int type) +int CustomData_get_stencil_layer_index(const CustomData *data, int type) { int i; @@ -1175,7 +1258,7 @@ int CustomData_get_clone_layer(const CustomData *data, int type) return -1; } -int CustomData_get_mask_layer(const CustomData *data, int type) +int CustomData_get_stencil_layer(const CustomData *data, int type) { int i; @@ -1213,7 +1296,7 @@ void CustomData_set_layer_clone(CustomData *data, int type, int n) data->layers[i].active_clone = n; } -void CustomData_set_layer_mask(CustomData *data, int type, int n) +void CustomData_set_layer_stencil(CustomData *data, int type, int n) { int i; @@ -1250,7 +1333,7 @@ void CustomData_set_layer_clone_index(CustomData *data, int type, int n) data->layers[i].active_clone = n-i; } -void CustomData_set_layer_mask_index(CustomData *data, int type, int n) +void CustomData_set_layer_stencil_index(CustomData *data, int type, int n) { int i; @@ -2599,3 +2682,236 @@ int CustomData_verify_versions(struct CustomData *data, int index) return keeplayer; } +/****************************** External Files *******************************/ + +static void customdata_external_filename(char filename[FILE_MAX], ID *id, CustomDataExternal *external) +{ + char *path = (id->lib)? id->lib->filename: G.sce; + + BLI_strncpy(filename, external->filename, FILE_MAX); + BLI_convertstringcode(filename, path); +} + +void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int totelem) +{ + CustomDataExternal *external= data->external; + CustomDataLayer *layer; + CDataFile *cdf; + CDataFileLayer *blay; + char filename[FILE_MAX]; + const LayerTypeInfo *typeInfo; + int i, update = 0; + + if(!external) + return; + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if(!(mask & (1<<layer->type))); + else if(layer->flag & CD_FLAG_IN_MEMORY); + else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) + update= 1; + } + + if(!update) + return; + + customdata_external_filename(filename, id, external); + + cdf= cdf_create(CDF_TYPE_MESH); + if(!cdf_read_open(cdf, filename)) + return; + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if(!(mask & (1<<layer->type))); + else if(layer->flag & CD_FLAG_IN_MEMORY); + else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { + blay= cdf_layer_find(cdf, layer->type, layer->name); + + if(blay) { + if(cdf_read_layer(cdf, blay)) { + if(typeInfo->read(cdf, layer->data, totelem)); + else break; + layer->flag |= CD_FLAG_IN_MEMORY; + } + else + break; + } + } + } + + cdf_read_close(cdf); + cdf_free(cdf); +} + +void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, int totelem, int free) +{ + CustomDataExternal *external= data->external; + CustomDataLayer *layer; + CDataFile *cdf; + CDataFileLayer *blay; + const LayerTypeInfo *typeInfo; + int i, update = 0; + char filename[FILE_MAX]; + + if(!external) + return; + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if(!(mask & (1<<layer->type))); + else if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) + update= 1; + } + + if(!update) + return; + + CustomData_external_read(data, id, mask, totelem); + + cdf= cdf_create(CDF_TYPE_MESH); + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->filesize) + cdf_layer_add(cdf, layer->type, layer->name, + typeInfo->filesize(cdf, layer->data, totelem)); + } + + customdata_external_filename(filename, id, external); + if(!cdf_write_open(cdf, filename)) + return; + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { + blay= cdf_layer_find(cdf, layer->type, layer->name); + + if(cdf_write_layer(cdf, blay)) { + if(typeInfo->write(cdf, layer->data, totelem)); + else break; + } + else + break; + } + } + + if(i != data->totlayer) { + cdf_free(cdf); + return; + } + + for(i=0; i<data->totlayer; i++) { + layer = &data->layers[i]; + typeInfo = layerType_getInfo(layer->type); + + if((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { + if(free) { + if(typeInfo->free) + typeInfo->free(layer->data, totelem, typeInfo->size); + layer->flag &= ~CD_FLAG_IN_MEMORY; + } + } + } + + cdf_write_close(cdf); + cdf_free(cdf); +} + +void CustomData_external_add(CustomData *data, ID *id, int type, int totelem, const char *filename) +{ + CustomDataExternal *external= data->external; + CustomDataLayer *layer; + int layer_index; + + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return; + + layer = &data->layers[layer_index]; + + if(layer->flag & CD_FLAG_EXTERNAL) + return; + + if(!external) { + external= MEM_callocN(sizeof(CustomDataExternal), "CustomDataExternal"); + BLI_strncpy(external->filename, filename, sizeof(external->filename)); + data->external= external; + } + + layer->flag |= CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY; +} + +void CustomData_external_remove(CustomData *data, ID *id, int type, int totelem) +{ + CustomDataExternal *external= data->external; + CustomDataLayer *layer; + //char filename[FILE_MAX]; + int layer_index; // i, remove_file; + + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return; + + layer = &data->layers[layer_index]; + + if(!external) + return; + + if(layer->flag & CD_FLAG_EXTERNAL) { + if(!(layer->flag & CD_FLAG_IN_MEMORY)) + CustomData_external_read(data, id, (1<<layer->type), totelem); + + layer->flag &= ~CD_FLAG_EXTERNAL; + +#if 0 + remove_file= 1; + for(i=0; i<data->totlayer; i++) + if(data->layers[i].flag & CD_FLAG_EXTERNAL) + remove_file= 0; + + if(remove_file) { + customdata_external_filename(filename, id, external); + cdf_remove(filename); + CustomData_external_free(data); + } +#endif + } +} + +int CustomData_external_test(CustomData *data, int type) +{ + CustomDataLayer *layer; + int layer_index; + + layer_index = CustomData_get_active_layer_index(data, type); + if(layer_index < 0) return 0; + + layer = &data->layers[layer_index]; + return (layer->flag & CD_FLAG_EXTERNAL); +} + +#if 0 +void CustomData_external_remove_object(CustomData *data, ID *id) +{ + CustomDataExternal *external= data->external; + char filename[FILE_MAX]; + + if(!external) + return; + + customdata_external_filename(filename, id, external); + cdf_remove(filename); + CustomData_external_free(data); +} +#endif + diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c new file mode 100644 index 00000000000..b58ada878de --- /dev/null +++ b/source/blender/blenkernel/intern/customdata_file.c @@ -0,0 +1,446 @@ +/* + * $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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_fileops.h" +#include "BLI_string.h" + +#include "BKE_customdata_file.h" +#include "BKE_global.h" +#include "BKE_utildefines.h" + +/************************* File Format Definitions ***************************/ + +#define CDF_ENDIAN_LITTLE 0 +#define CDF_ENDIAN_BIG 1 + +#define CDF_DATA_FLOAT 0 + +typedef struct CDataFileHeader { + char ID[4]; /* "BCDF" */ + char endian; /* little, big */ + char version; /* non-compatible versions */ + char subversion; /* compatible sub versions */ + char pad; /* padding */ + + int structbytes; /* size of this struct in bytes */ + int type; /* image, mesh */ + int totlayer; /* number of layers in the file */ +} CDataFileHeader; + +typedef struct CDataFileImageHeader { + int structbytes; /* size of this struct in bytes */ + int width; /* image width */ + int height; /* image height */ + int tile_size; /* tile size (required power of 2) */ +} CDataFileImageHeader; + +typedef struct CDataFileMeshHeader { + int structbytes; /* size of this struct in bytes */ +} CDataFileMeshHeader; + +struct CDataFileLayer { + int structbytes; /* size of this struct in bytes */ + int datatype; /* only float for now */ + uint64_t datasize; /* size of data in layer */ + int type; /* layer type */ + char name[CDF_LAYER_NAME_MAX]; /* layer name */ +}; + +/**************************** Other Definitions ******************************/ + +#define CDF_VERSION 0 +#define CDF_SUBVERSION 0 +#define CDF_TILE_SIZE 64 + +struct CDataFile { + int type; + + CDataFileHeader header; + union { + CDataFileImageHeader image; + CDataFileMeshHeader mesh; + } btype; + + CDataFileLayer *layer; + int totlayer; + + FILE *readf; + FILE *writef; + int switchendian; + size_t dataoffset; +}; + +/********************************* Create/Free *******************************/ + +static int cdf_endian(void) +{ + if(ENDIAN_ORDER == L_ENDIAN) + return CDF_ENDIAN_LITTLE; + else + return CDF_ENDIAN_BIG; +} + +/*static int cdf_data_type_size(int datatype) +{ + if(datatype == CDF_DATA_FLOAT) + return sizeof(float); + + return 0; +}*/ + +CDataFile *cdf_create(int type) +{ + CDataFile *cdf= MEM_callocN(sizeof(CDataFile), "CDataFile"); + + cdf->type= type; + + return cdf; +} + +void cdf_free(CDataFile *cdf) +{ + cdf_read_close(cdf); + cdf_write_close(cdf); + + if(cdf->layer) + MEM_freeN(cdf->layer); + + MEM_freeN(cdf); +} + +/********************************* Read/Write ********************************/ + +static int cdf_read_header(CDataFile *cdf) +{ + CDataFileHeader *header; + CDataFileImageHeader *image; + CDataFileMeshHeader *mesh; + CDataFileLayer *layer; + FILE *f= cdf->readf; + size_t offset = 0; + int a; + + header= &cdf->header; + + if(!fread(header, sizeof(CDataFileHeader), 1, cdf->readf)) + return 0; + + if(memcmp(header->ID, "BCDF", sizeof(header->ID)) != 0) + return 0; + if(header->version > CDF_VERSION) + return 0; + + cdf->switchendian= header->endian != cdf_endian(); + header->endian= cdf_endian(); + + if(cdf->switchendian) { + SWITCH_INT(header->type); + SWITCH_INT(header->totlayer); + SWITCH_INT(header->structbytes); + } + + if(!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH)) + return 0; + + offset += header->structbytes; + header->structbytes= sizeof(CDataFileHeader); + + if(fseek(f, offset, SEEK_SET) != 0) + return 0; + + if(header->type == CDF_TYPE_IMAGE) { + image= &cdf->btype.image; + if(!fread(image, sizeof(CDataFileImageHeader), 1, f)) + return 0; + + if(cdf->switchendian) { + SWITCH_INT(image->width); + SWITCH_INT(image->height); + SWITCH_INT(image->tile_size); + SWITCH_INT(image->structbytes); + } + + offset += image->structbytes; + image->structbytes= sizeof(CDataFileImageHeader); + } + else if(header->type == CDF_TYPE_MESH) { + mesh= &cdf->btype.mesh; + if(!fread(mesh, sizeof(CDataFileMeshHeader), 1, f)) + return 0; + + if(cdf->switchendian) + SWITCH_INT(mesh->structbytes); + + offset += mesh->structbytes; + mesh->structbytes= sizeof(CDataFileMeshHeader); + } + + if(fseek(f, offset, SEEK_SET) != 0) + return 0; + + cdf->layer= MEM_callocN(sizeof(CDataFileLayer)*header->totlayer, "CDataFileLayer"); + cdf->totlayer= header->totlayer; + + for(a=0; a<header->totlayer; a++) { + layer= &cdf->layer[a]; + + if(!fread(layer, sizeof(CDataFileLayer), 1, f)) + return 0; + + if(cdf->switchendian) { + SWITCH_INT(layer->type); + SWITCH_INT(layer->datatype); + SWITCH_INT64(layer->datasize); + SWITCH_INT(layer->structbytes); + } + + if(layer->datatype != CDF_DATA_FLOAT) + return 0; + + offset += layer->structbytes; + layer->structbytes= sizeof(CDataFileLayer); + + if(fseek(f, offset, SEEK_SET) != 0) + return 0; + } + + cdf->dataoffset= offset; + + return 1; +} + +static int cdf_write_header(CDataFile *cdf) +{ + CDataFileHeader *header; + CDataFileImageHeader *image; + CDataFileMeshHeader *mesh; + CDataFileLayer *layer; + FILE *f= cdf->writef; + int a; + + header= &cdf->header; + + if(!fwrite(header, sizeof(CDataFileHeader), 1, f)) + return 0; + + if(header->type == CDF_TYPE_IMAGE) { + image= &cdf->btype.image; + if(!fwrite(image, sizeof(CDataFileImageHeader), 1, f)) + return 0; + } + else if(header->type == CDF_TYPE_MESH) { + mesh= &cdf->btype.mesh; + if(!fwrite(mesh, sizeof(CDataFileMeshHeader), 1, f)) + return 0; + } + + for(a=0; a<header->totlayer; a++) { + layer= &cdf->layer[a]; + + if(!fwrite(layer, sizeof(CDataFileLayer), 1, f)) + return 0; + } + + return 1; +} + +int cdf_read_open(CDataFile *cdf, char *filename) +{ + FILE *f; + + f= fopen(filename, "rb"); + if(!f) + return 0; + + cdf->readf= f; + + if(!cdf_read_header(cdf)) { + cdf_read_close(cdf); + return 0; + } + + if(cdf->header.type != cdf->type) { + cdf_read_close(cdf); + return 0; + } + + return 1; +} + +int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay) +{ + size_t offset; + int a; + + /* seek to right location in file */ + offset= cdf->dataoffset; + for(a=0; a<cdf->totlayer; a++) { + if(&cdf->layer[a] == blay) + break; + else + offset += cdf->layer[a].datasize; + } + + return (fseek(cdf->readf, offset, SEEK_SET) == 0); +} + +int cdf_read_data(CDataFile *cdf, int size, void *data) +{ + float *fdata; + int a; + + /* read data */ + if(!fread(data, size, 1, cdf->readf)) + return 0; + + /* switch endian if necessary */ + if(cdf->switchendian) { + fdata= data; + + for(a=0; a<size/sizeof(float); a++) + SWITCH_INT(fdata[a]) + } + + return 1; +} + +void cdf_read_close(CDataFile *cdf) +{ + if(cdf->readf) { + fclose(cdf->readf); + cdf->readf= NULL; + } +} + +int cdf_write_open(CDataFile *cdf, char *filename) +{ + CDataFileHeader *header; + CDataFileImageHeader *image; + CDataFileMeshHeader *mesh; + FILE *f; + + f= fopen(filename, "wb"); + if(!f) + return 0; + + cdf->writef= f; + + /* fill header */ + header= &cdf->header; + strcpy(header->ID, "BCDF"); + header->endian= cdf_endian(); + header->version= CDF_VERSION; + header->subversion= CDF_SUBVERSION; + + header->structbytes= sizeof(CDataFileHeader); + header->type= cdf->type; + header->totlayer= cdf->totlayer; + + if(cdf->type == CDF_TYPE_IMAGE) { + /* fill image header */ + image= &cdf->btype.image; + image->structbytes= sizeof(CDataFileImageHeader); + image->tile_size= CDF_TILE_SIZE; + } + else if(cdf->type == CDF_TYPE_MESH) { + /* fill mesh header */ + mesh= &cdf->btype.mesh; + mesh->structbytes= sizeof(CDataFileMeshHeader); + } + + cdf_write_header(cdf); + + return 1; +} + +int cdf_write_layer(CDataFile *cdf, CDataFileLayer *blay) +{ + return 1; +} + +int cdf_write_data(CDataFile *cdf, int size, void *data) +{ + /* write data */ + if(!fwrite(data, size, 1, cdf->writef)) + return 0; + + return 1; +} + +void cdf_write_close(CDataFile *cdf) +{ + if(cdf->writef) { + fclose(cdf->writef); + cdf->writef= NULL; + } +} + +void cdf_remove(char *filename) +{ + BLI_delete(filename, 0, 0); +} + +/********************************** Layers ***********************************/ + +CDataFileLayer *cdf_layer_find(CDataFile *cdf, int type, char *name) +{ + CDataFileLayer *layer; + int a; + + for(a=0; a<cdf->totlayer; a++) { + layer= &cdf->layer[a]; + + if(layer->type == type && strcmp(layer->name, name) == 0) + return layer; + } + + return NULL; +} + +CDataFileLayer *cdf_layer_add(CDataFile *cdf, int type, char *name, size_t datasize) +{ + CDataFileLayer *newlayer, *layer; + + /* expand array */ + newlayer= MEM_callocN(sizeof(CDataFileLayer)*(cdf->totlayer+1), "CDataFileLayer"); + memcpy(newlayer, cdf->layer, sizeof(CDataFileLayer)*cdf->totlayer); + cdf->layer= newlayer; + + cdf->totlayer++; + + /* fill in new layer */ + layer= &cdf->layer[cdf->totlayer-1]; + layer->structbytes= sizeof(CDataFileLayer); + layer->datatype= CDF_DATA_FLOAT; + layer->datasize= datasize; + layer->type= type; + BLI_strncpy(layer->name, name, CDF_LAYER_NAME_MAX); + + return layer; +} + diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 302b81f2a04..8535bfc6d0c 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -2155,7 +2155,7 @@ static void dag_current_scene_layers(Main *bmain, Scene **sce, unsigned int *lay for(win=wm->windows.first; win; win=win->next) { if(win->screen) { if(!*sce) *sce= win->screen->scene; - *lay |= BKE_screen_visible_layers(win->screen); + *lay |= BKE_screen_visible_layers(win->screen, win->screen->scene); } } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 3d8fbe248bf..c694422124a 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1225,7 +1225,7 @@ static ModifierData *curve_get_tesselate_point(Object *ob, int forRender, int ed ModifierTypeInfo *mti = modifierType_getInfo(md->type); if ((md->mode & required_mode) != required_mode) continue; - if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { preTesselatePoint = md; @@ -1275,7 +1275,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl md->scene= scene; if ((md->mode & required_mode) != required_mode) continue; - if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; if (mti->type!=eModifierTypeType_OnlyDeform) continue; if (!deformedVerts) { @@ -1330,7 +1330,7 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba md->scene= scene; if ((md->mode & required_mode) != required_mode) continue; - if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; if (mti->type!=eModifierTypeType_OnlyDeform && mti->type!=eModifierTypeType_DeformOrConstruct) continue; /* need to put all verts in 1 block for curve deform */ diff --git a/source/blender/blenkernel/intern/editderivedbmesh.c b/source/blender/blenkernel/intern/editderivedbmesh.c index 6c9957e3ab3..b23322299b5 100644 --- a/source/blender/blenkernel/intern/editderivedbmesh.c +++ b/source/blender/blenkernel/intern/editderivedbmesh.c @@ -268,8 +268,8 @@ void BMEdit_UpdateLinkedCustomData(BMEditMesh *em) act = CustomData_get_clone_layer(&bm->pdata, CD_MTEXPOLY); CustomData_set_layer_clone(&bm->ldata, CD_MLOOPUV, act); - act = CustomData_get_mask_layer(&bm->pdata, CD_MTEXPOLY); - CustomData_set_layer_mask(&bm->ldata, CD_MLOOPUV, act); + act = CustomData_get_stencil_layer(&bm->pdata, CD_MTEXPOLY); + CustomData_set_layer_stencil(&bm->ldata, CD_MLOOPUV, act); } } diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index d8d0e49dcb4..0f4d09f82d3 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -128,7 +128,6 @@ PartDeflect *object_add_collision_fields(int type) pd->seed = ((unsigned int)(ceil(PIL_check_seconds_timer()))+1) % 128; pd->f_strength = 1.0f; pd->f_damp = 1.0f; - pd->f_size = 1.0f; /* set sensible defaults based on type */ switch(type) { @@ -139,6 +138,9 @@ PartDeflect *object_add_collision_fields(int type) pd->shape = PFIELD_SHAPE_PLANE; pd->f_flow = 1.0f; /* realistic wind behavior */ break; + case PFIELD_TEXTURE: + pd->f_size = 1.0f; + break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; @@ -693,6 +695,10 @@ int get_effector_data(EffectorCache *eff, EffectorData *efd, EffectedPoint *poin sub_v3_v3v3(efd->vec_to_point, point->loc, efd->loc); efd->distance = len_v3(efd->vec_to_point); + /* rest length for harmonic effector, will have to see later if this could be extended to other effectors */ + if(eff->pd->forcefield == PFIELD_HARMONIC && eff->pd->f_size) + mul_v3_fl(efd->vec_to_point, (efd->distance-eff->pd->f_size)/efd->distance); + if(eff->flag & PE_USE_NORMAL_DATA) { VECCOPY(efd->vec_to_point2, efd->vec_to_point); VECCOPY(efd->nor2, efd->nor); @@ -735,7 +741,7 @@ static void get_effector_tot(EffectorCache *eff, EffectorData *efd, EffectedPoin */ efd->charge = eff->pd->f_strength; } - else if(eff->pd->forcefield == PFIELD_HARMONIC) { + else if(eff->pd->forcefield == PFIELD_HARMONIC && (eff->pd->flag & PFIELD_MULTIPLE_SPRINGS)==0) { /* every particle is mapped to only one harmonic effector particle */ *p= point->index % eff->psys->totpart; *tot= *p + 1; diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c index 6ea1acaf645..c83a0443356 100644 --- a/source/blender/blenkernel/intern/exotic.c +++ b/source/blender/blenkernel/intern/exotic.c @@ -4050,7 +4050,7 @@ static void dxf_read(Scene *scene, char *filename) ob->type= OB_MESH; - ob->dt= OB_SHADED; + ob->dt= OB_TEXTURE; ob->trackflag= OB_POSY; ob->upflag= OB_POSZ; diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index c451168a005..d5e033652a8 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -167,53 +167,42 @@ void copy_fcurves (ListBase *dst, ListBase *src) } } -/* ---------------------- Relink --------------------------- */ - -#if 0 -/* uses id->newid to match pointers with other copied data - * - called after single-user or other such - */ - if (icu->driver) - ID_NEW(icu->driver->ob); -#endif - /* --------------------- Finding -------------------------- */ +/* high level function to get an fcurve from C without having the rna */ FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, char *prop_name, int index) { /* anim vars */ - AnimData *adt; + AnimData *adt= BKE_animdata_from_id(id); FCurve *fcu= NULL; /* rna vars */ PointerRNA ptr; PropertyRNA *prop; char *path; - - adt= BKE_animdata_from_id(id); - + /* only use the current action ??? */ - if(adt==NULL || adt->action==NULL) + if (ELEM(NULL, adt, adt->action)) return NULL; - + RNA_pointer_create(id, type, data, &ptr); prop = RNA_struct_find_property(&ptr, prop_name); - - if(prop) { + + if (prop) { path= RNA_path_from_ID_to_property(&ptr, prop); - - if(path) { + + if (path) { /* animation takes priority over drivers */ - if(adt->action && adt->action->curves.first) + if ((adt->action) && (adt->action->curves.first)) fcu= list_find_fcurve(&adt->action->curves, path, index); - + /* if not animated, check if driven */ #if 0 - if(!fcu && (adt->drivers.first)) { + if ((fcu == NULL) && (adt->drivers.first)) { fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex); } #endif - + MEM_freeN(path); } } @@ -245,6 +234,54 @@ FCurve *list_find_fcurve (ListBase *list, const char rna_path[], const int array return NULL; } +/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated + * Lists... + * - dst: list of LinkData's matching the criteria returned. + * List must be freed after use, and is assumed to be empty when passed. + * - src: list of F-Curves to search through + * Filters... + * - dataPrefix: i.e. 'pose.bones[' or 'nodes[' + * - dataName: name of entity within "" immediately following the prefix + */ +int list_find_data_fcurves (ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName) +{ + FCurve *fcu; + int matches = 0; + + /* sanity checks */ + if (ELEM4(NULL, dst, src, dataPrefix, dataName)) + return 0; + else if ((dataPrefix[0] == 0) || (dataName[0] == 0)) + return 0; + + /* search each F-Curve one by one */ + for (fcu= src->first; fcu; fcu= fcu->next) { + /* check if quoted string matches the path */ + if ((fcu->rna_path) && strstr(fcu->rna_path, dataPrefix)) { + char *quotedName= BLI_getQuotedStr(fcu->rna_path, dataPrefix); + + if (quotedName) { + /* check if the quoted name matches the required name */ + if (strcmp(quotedName, dataName) == 0) { + LinkData *ld= MEM_callocN(sizeof(LinkData), "list_find_data_fcurves"); + + ld->data= fcu; + BLI_addtail(dst, ld); + + matches++; + } + + /* always free the quoted string, since it needs freeing */ + MEM_freeN(quotedName); + } + } + } + + /* return the number of matches */ + return matches; +} + + /* threshold for binary-searching keyframes - threshold here should be good enough for now, but should become userpref */ #define BEZT_BINARYSEARCH_THRESH 0.00001f @@ -731,6 +768,9 @@ DriverTarget *driver_add_new_target (ChannelDriver *driver) dtar= MEM_callocN(sizeof(DriverTarget), "DriverTarget"); BLI_addtail(&driver->targets, dtar); + /* make the default ID-type ID_OB, since most driver targets refer to objects */ + dtar->idtype= ID_OB; + /* give the target a 'unique' name */ strcpy(dtar->name, "var"); BLI_uniquename(&driver->targets, dtar, "var", '_', offsetof(DriverTarget, name), 64); @@ -755,7 +795,12 @@ void fcurve_free_driver(FCurve *fcu) dtarn= dtar->next; driver_free_target(driver, dtar); } - + +#ifndef DISABLE_PYTHON + if(driver->expr_comp) + BPY_DECREF(driver->expr_comp); +#endif + /* free driver itself, then set F-Curve's point to this to NULL (as the curve may still be used) */ MEM_freeN(driver); fcu->driver= NULL; @@ -819,7 +864,11 @@ float driver_get_target_value (ChannelDriver *driver, DriverTarget *dtar) } /* get property to read from, and get value as appropriate */ - if (RNA_path_resolve(&id_ptr, path, &ptr, &prop)) { + if (RNA_path_resolve_full(&id_ptr, path, &ptr, &prop, &index)) { + /* for now, if there is no valid index, fall back to the array-index specified separately */ + if (index == -1) + index= dtar->array_index; + switch (RNA_property_type(prop)) { case PROP_BOOLEAN: if (RNA_property_array_length(&ptr, prop)) @@ -907,6 +956,7 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime) // TODO: the flags for individual targets need to be used too for more fine-grained support... switch (driver->type) { case DRIVER_TYPE_AVERAGE: /* average values of driver targets */ + case DRIVER_TYPE_SUM: /* sum values of driver targets */ { /* check how many targets there are first (i.e. just one?) */ if (driver->targets.first == driver->targets.last) { @@ -921,16 +971,19 @@ static float evaluate_driver (ChannelDriver *driver, float evaltime) /* loop through targets, adding (hopefully we don't get any overflow!) */ for (dtar= driver->targets.first; dtar; dtar=dtar->next) { - value += driver_get_target_value(driver, dtar); + value += driver_get_target_value(driver, dtar); tot++; } /* return the average of these */ - return (value / (float)tot); + if (driver->type == DRIVER_TYPE_AVERAGE) + return (value / (float)tot); + else + return value; + } } break; - case DRIVER_TYPE_PYTHON: /* expression */ { #ifndef DISABLE_PYTHON diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index d4dde0fed5d..3be9d0133fe 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -53,8 +53,6 @@ #include "RNA_access.h" #include "RNA_types.h" -#include "AUD_C-API.h" - #ifndef DISABLE_PYTHON #include "BPY_extern.h" /* for BPY_pydriver_eval() */ #endif @@ -873,96 +871,6 @@ static FModifierTypeInfo FMI_LIMITS = { fcm_limits_evaluate /* evaluate */ }; -/* Sound F-Curve Modifier --------------------------- */ - -static void fcm_sound_new_data (void *mdata) -{ - FMod_Sound *data= (FMod_Sound *)mdata; - - /* defaults */ - data->strength= 1.0f; - data->delay = 0.0f; - data->modification = FCM_SOUND_MODIF_REPLACE; - data->sound = NULL; -} - -static void fcm_sound_evaluate (FCurve *fcu, FModifier *fcm, float *cvalue, float evaltime) -{ - FMod_Sound *data= (FMod_Sound *)fcm->data; - float amplitude; - - AUD_Device *device; - AUD_Sound *limiter; - AUD_SoundInfo info; - - // XXX fixme - need to get in terms of time instead of frames to be really useful -// evaltime = FRA2TIME(evaltime); - evaltime -= data->delay; - - /* sound-system cannot cope with negative times/frames */ - if (evaltime < 0.0f) - return; - /* must have a sound with a cache so that this can be used */ - if (ELEM(NULL, data->sound, data->sound->cache)) - return; - - /* examine this snippet of the wave, and extract the amplitude from it */ - info = AUD_getInfo(data->sound->cache); - info.specs.channels = 1; - info.specs.format = AUD_FORMAT_FLOAT32; - device = AUD_openReadDevice(info.specs); - limiter = AUD_limitSound(data->sound->cache, evaltime, evaltime + 1); - AUD_playDevice(device, limiter); - AUD_unload(limiter); - AUD_readDevice(device, (sample_t*)&litude, 1); - AUD_closeReadDevice(device); - - /* combine the amplitude with existing motion data */ - switch (data->modification) { - case FCM_SOUND_MODIF_ADD: - *cvalue= *cvalue + amplitude * data->strength; - break; - case FCM_SOUND_MODIF_SUBTRACT: - *cvalue= *cvalue - amplitude * data->strength; - break; - case FCM_SOUND_MODIF_MULTIPLY: - *cvalue= *cvalue * amplitude * data->strength; - break; - case FCM_SOUND_MODIF_REPLACE: - default: - *cvalue= *cvalue + amplitude * data->strength; - break; - } -} - -static float fcm_sound_time (FCurve *fcu, FModifier *fcm, float cvalue, float evaltime) -{ - FMod_Sound *data= (FMod_Sound *)fcm->data; - - /* check for the time delay */ -// evaltime = FRA2TIME(evaltime); - if(evaltime < data->delay) - return data->delay; - - /* modifier doesn't change time */ - return evaltime; -} - -static FModifierTypeInfo FMI_SOUND = { - FMODIFIER_TYPE_SOUND, /* type */ - sizeof(FMod_Sound), /* size */ - FMI_TYPE_REPLACE_VALUES, /* action type */ - 0, /* requirements */ - "Sound", /* name */ - "FMod_Sound", /* struct name */ - NULL, /* free data */ - NULL, /* copy data */ - fcm_sound_new_data, /* new data */ - NULL, /* verify */ - fcm_sound_time, /* evaluate time */ - fcm_sound_evaluate /* evaluate */ -}; - /* F-Curve Modifier API --------------------------- */ /* All of the F-Curve Modifier api functions use FModifierTypeInfo structs to carry out * and operations that involve F-Curve modifier specific code. @@ -984,7 +892,6 @@ static void fmods_init_typeinfo () fmodifiersTypeInfo[6]= NULL/*&FMI_FILTER*/; /* Filter F-Curve Modifier */ // XXX unimplemented fmodifiersTypeInfo[7]= &FMI_PYTHON; /* Custom Python F-Curve Modifier */ fmodifiersTypeInfo[8]= &FMI_LIMITS; /* Limits F-Curve Modifier */ - fmodifiersTypeInfo[9]= &FMI_SOUND; /* Sound F-Curve Modifier */ } /* This function should be used for getting the appropriate type-info when only diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index e2dccf02b40..1a63f97e310 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -705,10 +705,10 @@ struct chartrans *BKE_text_to_curve(Scene *scene, Object *ob, int mode) /* We assume the worst case: 1 character per line (is freed at end anyway) */ - linedata= MEM_mallocN(sizeof(float)*(slen+2),"buildtext2"); - linedata2= MEM_mallocN(sizeof(float)*(slen+2),"buildtext3"); - linedata3= MEM_callocN(sizeof(float)*(slen+2),"buildtext4"); - linedata4= MEM_callocN(sizeof(float)*(slen+2),"buildtext5"); + linedata= MEM_mallocN(sizeof(float)*(slen*2 + 1),"buildtext2"); + linedata2= MEM_mallocN(sizeof(float)*(slen*2 + 1),"buildtext3"); + linedata3= MEM_callocN(sizeof(float)*(slen*2 + 1),"buildtext4"); + linedata4= MEM_callocN(sizeof(float)*(slen*2 + 1),"buildtext5"); linedist= cu->linedist; diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c index 3ab02a576d0..f35a0a96bb4 100644 --- a/source/blender/blenkernel/intern/group.c +++ b/source/blender/blenkernel/intern/group.c @@ -217,8 +217,8 @@ static int rem_from_group_internal(Group *group, Object *ob) int rem_from_group(Group *group, Object *object, Scene *scene, Base *base) { if(rem_from_group_internal(group, object)) { - - if(find_group(object, NULL) == NULL) { + /* object can be NULL */ + if(object && find_group(object, NULL) == NULL) { if(scene && base==NULL) base= object_in_scene(object, scene); diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 18a8210c68d..6fc3fc547df 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -885,6 +885,17 @@ static char *get_rna_access (int blocktype, int adrcode, char actname[], char co case ID_SEQ: /* sequencer strip */ //SEQ_FAC1: + switch (adrcode) { + case SEQ_FAC1: + propname= "effect_fader"; + break; + case SEQ_FAC_SPEED: + propname= "speed_fader"; + break; + case SEQ_FAC_OPACITY: + propname= "blend_opacity"; + break; + } // poin= &(seq->facf0); // XXX this doesn't seem to be included anywhere in sequencer RNA... break; @@ -1604,6 +1615,7 @@ void do_versions_ipos_to_animato(Main *main) ListBase drivers = {NULL, NULL}; ID *id; AnimData *adt; + Scene *scene; if (main == NULL) { printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n"); @@ -1781,6 +1793,51 @@ void do_versions_ipos_to_animato(Main *main) } } + /* sequence strips */ + for(scene = main->scene.first; scene; scene = scene->id.next) { + if(scene->ed && scene->ed->seqbasep) { + Sequence * seq; + + for(seq = scene->ed->seqbasep->first; + seq; seq = seq->next) { + short adrcode = SEQ_FAC1; + + if (G.f & G_DEBUG) + printf("\tconverting sequence strip %s \n", seq->name+2); + + if (!seq->ipo || !seq->ipo->curve.first) { + seq->flag |= + SEQ_USE_EFFECT_DEFAULT_FADE; + continue; + } + + /* patch adrcode, so that we can map + to different DNA variables later + (semi-hack (tm) ) + */ + switch(seq->type) { + case SEQ_IMAGE: + case SEQ_META: + case SEQ_SCENE: + case SEQ_MOVIE: + case SEQ_COLOR: + adrcode = SEQ_FAC_OPACITY; + break; + case SEQ_SPEED: + adrcode = SEQ_FAC_SPEED; + break; + } + ((IpoCurve*) seq->ipo->curve.first) + ->adrcode = adrcode; + ipo_to_animdata((ID*) seq, seq->ipo, + NULL, NULL); + seq->ipo->id.us--; + seq->ipo = NULL; + } + } + } + + /* textures */ for (id= main->tex.first; id; id= id->next) { Tex *te= (Tex *)id; diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index af3642f1b06..d2f17292df8 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -1003,7 +1003,7 @@ void lattice_calc_modifiers(Scene *scene, Object *ob) if (!(md->mode&eModifierMode_Realtime)) continue; if (editmode && !(md->mode&eModifierMode_Editmode)) continue; - if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->isDisabled && mti->isDisabled(md, 0)) continue; if (mti->type!=eModifierTypeType_OnlyDeform) continue; if (!vertexCos) vertexCos = lattice_getVertexCos(ob, &numVerts); diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 0867afc0fb2..eee2df20743 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -141,9 +141,9 @@ void mesh_update_linked_customdata(Mesh *me) CustomData_set_layer_clone(&me->ldata, CD_MLOOPUV, act); CustomData_set_layer_clone(&me->fdata, CD_MTFACE, act); - act = CustomData_get_mask_layer(&me->pdata, CD_MTEXPOLY); - CustomData_set_layer_mask(&me->ldata, CD_MLOOPUV, act); - CustomData_set_layer_mask(&me->fdata, CD_MTFACE, act); + act = CustomData_get_stencil_layer(&me->pdata, CD_MTEXPOLY); + CustomData_set_layer_stencil(&me->ldata, CD_MLOOPUV, act); + CustomData_set_layer_stencil(&me->fdata, CD_MTFACE, act); } if (CustomData_has_layer(&me->ldata, CD_MLOOPCOL)) { @@ -156,8 +156,8 @@ void mesh_update_linked_customdata(Mesh *me) act = CustomData_get_clone_layer(&me->ldata, CD_MLOOPCOL); CustomData_set_layer_clone(&me->fdata, CD_MCOL, act); - act = CustomData_get_mask_layer(&me->ldata, CD_MLOOPCOL); - CustomData_set_layer_mask(&me->fdata, CD_MCOL, act); + act = CustomData_get_stencil_layer(&me->ldata, CD_MLOOPCOL); + CustomData_set_layer_stencil(&me->fdata, CD_MCOL, act); } } @@ -1604,7 +1604,8 @@ static void mesh_loops_to_corners(CustomData *fdata, CustomData *ldata, int mesh_recalcTesselation(CustomData *fdata, CustomData *ldata, CustomData *pdata, MVert *mvert, int totface, int totloop, - int totpoly, int use_poly_origindex) + int totpoly, int use_poly_origindex, + int use_face_origindex) { MPoly *mp, *mpoly; MLoop *ml, *mloop; @@ -1659,7 +1660,7 @@ int mesh_recalcTesselation(CustomData *fdata, mf[k].v3 = f->v3->keyindex; mf[k].mat_nr = mp->mat_nr; mf[k].flag = mp->flag; - origIndex[k] = f->v1->tmp.l; + origIndex[k] = use_face_origindex ? k : f->v1->tmp.l; k++; } diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index e26d084c1d1..6f428213e53 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -192,7 +192,7 @@ static DerivedMesh *get_original_dm(Scene *scene, Object *ob, float (*vertexCos) /***/ -static int noneModifier_isDisabled(ModifierData *md) +static int noneModifier_isDisabled(ModifierData *md, int userRenderParams) { return 1; } @@ -227,7 +227,7 @@ static CustomDataMask curveModifier_requiredDataMask(Object *ob, ModifierData *m return dataMask; } -static int curveModifier_isDisabled(ModifierData *md) +static int curveModifier_isDisabled(ModifierData *md, int userRenderParams) { CurveModifierData *cmd = (CurveModifierData*) md; @@ -303,7 +303,7 @@ static CustomDataMask latticeModifier_requiredDataMask(Object *ob, ModifierData return dataMask; } -static int latticeModifier_isDisabled(ModifierData *md) +static int latticeModifier_isDisabled(ModifierData *md, int userRenderParams) { LatticeModifierData *lmd = (LatticeModifierData*) md; @@ -400,13 +400,20 @@ static void subsurfModifier_freeData(ModifierData *md) SubsurfModifierData *smd = (SubsurfModifierData*) md; if(smd->mCache) { - CCS_free(smd->mCache); + ccgSubSurf_free(smd->mCache); } if(smd->emCache) { - CCS_free(smd->emCache); + ccgSubSurf_free(smd->emCache); } } +static int subsurfModifier_isDisabled(ModifierData *md, int useRenderParams) +{ + SubsurfModifierData *smd = (SubsurfModifierData*) md; + + return (useRenderParams)? (smd->renderLevels == 0): (smd->levels == 0); +} + static DerivedMesh *subsurfModifier_applyModifier( ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) @@ -415,8 +422,13 @@ static DerivedMesh *subsurfModifier_applyModifier( DerivedMesh *result; result = subsurf_make_derived_from_derived(derivedData, smd, - useRenderParams, NULL, - isFinalCalc, 0); + useRenderParams, NULL, isFinalCalc, 0); + + if(useRenderParams || !isFinalCalc) { + DerivedMesh *cddm= CDDM_copy(result, 1); + result->release(result); + result= cddm; + } return result; } @@ -2501,7 +2513,7 @@ DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd) cddm->numFaceData = mesh_recalcTesselation(&cddm->faceData, &cddm->loopData, &cddm->polyData, mvert, cddm->numFaceData, - cddm->numLoopData, cddm->numPolyData, 1); + cddm->numLoopData, cddm->numPolyData, 1, 0); CDDM_set_mface(cddm, DM_get_tessface_data_layer(cddm, CD_MFACE)); CDDM_calc_normals(cddm); @@ -2717,7 +2729,7 @@ static void displaceModifier_foreachIDLink(ModifierData *md, Object *ob, displaceModifier_foreachObjectLink(md, ob, (ObjectWalkFunc)walk, userData); } -static int displaceModifier_isDisabled(ModifierData *md) +static int displaceModifier_isDisabled(ModifierData *md, int useRenderParams) { DisplaceModifierData *dmd = (DisplaceModifierData*) md; @@ -3462,7 +3474,7 @@ static void smoothModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tsmd->defgrp_name, smd->defgrp_name, 32); } -static int smoothModifier_isDisabled(ModifierData *md) +static int smoothModifier_isDisabled(ModifierData *md, int useRenderParams) { SmoothModifierData *smd = (SmoothModifierData*) md; short flag; @@ -3692,7 +3704,7 @@ static void castModifier_copyData(ModifierData *md, ModifierData *target) strncpy(tcmd->defgrp_name, cmd->defgrp_name, 32); } -static int castModifier_isDisabled(ModifierData *md) +static int castModifier_isDisabled(ModifierData *md, int useRenderParams) { CastModifierData *cmd = (CastModifierData*) md; short flag; @@ -4681,7 +4693,7 @@ static CustomDataMask armatureModifier_requiredDataMask(Object *ob, ModifierData return dataMask; } -static int armatureModifier_isDisabled(ModifierData *md) +static int armatureModifier_isDisabled(ModifierData *md, int useRenderParams) { ArmatureModifierData *amd = (ArmatureModifierData*) md; @@ -4804,7 +4816,7 @@ static void hookModifier_freeData(ModifierData *md) if (hmd->indexar) MEM_freeN(hmd->indexar); } -static int hookModifier_isDisabled(ModifierData *md) +static int hookModifier_isDisabled(ModifierData *md, int useRenderParams) { HookModifierData *hmd = (HookModifierData*) md; @@ -4876,7 +4888,7 @@ static void hookModifier_deformVerts( /* if DerivedMesh is present and has original index data, * use it */ - if(dm && dm->getVertData(dm, 0, CD_ORIGINDEX)) { + if(dm && dm->getVertDataArray(dm, CD_ORIGINDEX)) { int j; int orig_index; for(j = 0; j < numVerts; ++j) { @@ -4989,6 +5001,465 @@ static int softbodyModifier_dependsOnTime(ModifierData *md) return 1; } +/* Solidify */ + + +typedef struct EdgeFaceRef { + int f1; /* init as -1 */ + int f2; +} EdgeFaceRef; + +static void dm_calc_normal(DerivedMesh *dm, float (*temp_nors)[3]) +{ + int i, numVerts, numEdges, numFaces; + MFace *mface, *mf; + MVert *mvert, *mv; + + float (*face_nors)[3]; + float *f_no; + int calc_face_nors= 0; + + numVerts = dm->getNumVerts(dm); + numEdges = dm->getNumEdges(dm); + numFaces = dm->getNumFaces(dm); + mface = dm->getTessFaceArray(dm); + mvert = dm->getVertArray(dm); + + /* we don't want to overwrite any referenced layers */ + + /* + Dosnt work here! + mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT); + cddm->mvert = mv; + */ + + face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + if(!face_nors) { + calc_face_nors = 1; + face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, numFaces); + } + + mv = mvert; + mf = mface; + + { + EdgeHash *edge_hash = BLI_edgehash_new(); + EdgeHashIterator *edge_iter; + int edge_ref_count = 0; + int ed_v1, ed_v2; /* use when getting the key */ + EdgeFaceRef *edge_ref_array = MEM_callocN(numEdges * sizeof(EdgeFaceRef), "Edge Connectivity"); + EdgeFaceRef *edge_ref; + float edge_normal[3]; + + /* This function adds an edge hash if its not there, and adds the face index */ +#define NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(EDV1, EDV2); \ + edge_ref = (EdgeFaceRef *)BLI_edgehash_lookup(edge_hash, EDV1, EDV2); \ + if (!edge_ref) { \ + edge_ref = &edge_ref_array[edge_ref_count]; edge_ref_count++; \ + edge_ref->f1=i; \ + edge_ref->f2=-1; \ + BLI_edgehash_insert(edge_hash, EDV1, EDV2, edge_ref); \ + } else { \ + edge_ref->f2=i; \ + } + + for(i = 0; i < numFaces; i++, mf++) { + f_no = face_nors[i]; + + if(mf->v4) { + if(calc_face_nors) + normal_quad_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); + + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v4); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v4, mf->v1); + } else { + if(calc_face_nors) + normal_tri_v3(f_no, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); + + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v1, mf->v2); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v2, mf->v3); + NOCALC_EDGEWEIGHT_ADD_EDGEREF_FACE(mf->v3, mf->v1); + } + } + + for(edge_iter = BLI_edgehashIterator_new(edge_hash); !BLI_edgehashIterator_isDone(edge_iter); BLI_edgehashIterator_step(edge_iter)) { + /* Get the edge vert indicies, and edge value (the face indicies that use it)*/ + BLI_edgehashIterator_getKey(edge_iter, (int*)&ed_v1, (int*)&ed_v2); + edge_ref = BLI_edgehashIterator_getValue(edge_iter); + + if (edge_ref->f2 != -1) { + /* We have 2 faces using this edge, calculate the edges normal + * using the angle between the 2 faces as a weighting */ + add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]); + normalize_v3(edge_normal); + mul_v3_fl(edge_normal, angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2])); + } else { + /* only one face attached to that edge */ + /* an edge without another attached- the weight on this is + * undefined, M_PI/2 is 90d in radians and that seems good enough */ + VECCOPY(edge_normal, face_nors[edge_ref->f1]) + mul_v3_fl(edge_normal, M_PI/2); + } + add_v3_v3(temp_nors[ed_v1], edge_normal); + add_v3_v3(temp_nors[ed_v2], edge_normal); + } + BLI_edgehashIterator_free(edge_iter); + BLI_edgehash_free(edge_hash, NULL); + MEM_freeN(edge_ref_array); + } + + /* normalize vertex normals and assign */ + for(i = 0; i < numVerts; i++, mv++) { + if(normalize_v3(temp_nors[i]) == 0.0f) { + normal_short_to_float_v3(temp_nors[i], mv->no); + } + } +} + +static void solidifyModifier_initData(ModifierData *md) +{ + SolidifyModifierData *smd = (SolidifyModifierData*) md; + smd->offset = 0.01f; + smd->flag = MOD_SOLIDIFY_EVEN | MOD_SOLIDIFY_RIM | MOD_SOLIDIFY_NORMAL_CALC; +} + +static void solidifyModifier_copyData(ModifierData *md, ModifierData *target) +{ + SolidifyModifierData *smd = (SolidifyModifierData*) md; + SolidifyModifierData *tsmd = (SolidifyModifierData*) target; + tsmd->offset = smd->offset; + tsmd->crease_inner = smd->crease_inner; + tsmd->crease_outer = smd->crease_outer; + tsmd->crease_rim = smd->crease_rim; + strcpy(tsmd->vgroup, smd->vgroup); +} + +static DerivedMesh *solidifyModifier_applyModifier(ModifierData *md, + Object *ob, + DerivedMesh *dm, + int useRenderParams, + int isFinalCalc) +{ + int i; + DerivedMesh *result; + SolidifyModifierData *smd = (SolidifyModifierData*) md; + + MFace *mf, *mface, *orig_mface; + MEdge *ed, *medge, *orig_medge; + MVert *mv, *mvert, *orig_mvert; + + int numVerts = dm->getNumVerts(dm); + int numEdges = dm->getNumEdges(dm); + int numFaces = dm->getNumFaces(dm); + + /* use for edges */ + int *new_vert_arr= NULL; + int newFaces = 0; + + int *new_edge_arr= NULL; + int newEdges = 0; + + int *edge_users= NULL; + char *edge_order= NULL; + + float (*vert_nors)[3]= NULL; + + orig_mface = dm->getTessFaceArray(dm); + orig_medge = dm->getEdgeArray(dm); + orig_mvert = dm->getVertArray(dm); + + if(smd->flag & MOD_SOLIDIFY_RIM) { + EdgeHash *edgehash = BLI_edgehash_new(); + EdgeHashIterator *ehi; + int v1, v2; + int eidx; + + for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) { + mv->flag &= ~ME_VERT_TMP_TAG; + } + + for(i=0, ed=orig_medge; i<numEdges; i++, ed++) { + BLI_edgehash_insert(edgehash, ed->v1, ed->v2, SET_INT_IN_POINTER(i)); + } + +#define INVALID_UNUSED -1 +#define INVALID_PAIR -2 + +#define ADD_EDGE_USER(_v1, _v2, edge_ord) \ + eidx= GET_INT_FROM_POINTER(BLI_edgehash_lookup(edgehash, _v1, _v2)); \ + if(edge_users[eidx] == INVALID_UNUSED) { \ + edge_users[eidx]= (_v1 < _v2) ? i:(i+numFaces); \ + edge_order[eidx]= edge_ord; \ + } else { \ + edge_users[eidx]= INVALID_PAIR; \ + } \ + + + edge_users= MEM_mallocN(sizeof(int) * numEdges, "solid_mod edges"); + edge_order= MEM_mallocN(sizeof(char) * numEdges, "solid_mod eorder"); + memset(edge_users, INVALID_UNUSED, sizeof(int) * numEdges); + + for(i=0, mf=orig_mface; i<numFaces; i++, mf++) { + if(mf->v4) { + ADD_EDGE_USER(mf->v1, mf->v2, 0); + ADD_EDGE_USER(mf->v2, mf->v3, 1); + ADD_EDGE_USER(mf->v3, mf->v4, 2); + ADD_EDGE_USER(mf->v4, mf->v1, 3); + } + else { + ADD_EDGE_USER(mf->v1, mf->v2, 0); + ADD_EDGE_USER(mf->v2, mf->v3, 1); + ADD_EDGE_USER(mf->v3, mf->v1, 2); + } + } + +#undef ADD_EDGE_USER +#undef INVALID_UNUSED +#undef INVALID_PAIR + + + new_edge_arr= MEM_callocN(sizeof(int) * numEdges, "solid_mod arr"); + + ehi= BLI_edgehashIterator_new(edgehash); + for(; !BLI_edgehashIterator_isDone(ehi); BLI_edgehashIterator_step(ehi)) { + int eidx= GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi)); + if(edge_users[eidx] >= 0) { + BLI_edgehashIterator_getKey(ehi, &v1, &v2); + orig_mvert[v1].flag |= ME_VERT_TMP_TAG; + orig_mvert[v2].flag |= ME_VERT_TMP_TAG; + new_edge_arr[newFaces]= eidx; + newFaces++; + } + } + BLI_edgehashIterator_free(ehi); + + + + new_vert_arr= MEM_callocN(sizeof(int) * numVerts, "solid_mod new_varr"); + for(i=0, mv=orig_mvert; i<numVerts; i++, mv++) { + if(mv->flag & ME_VERT_TMP_TAG) { + new_vert_arr[newEdges] = i; + newEdges++; + + mv->flag &= ~ME_VERT_TMP_TAG; + } + } + + BLI_edgehash_free(edgehash, NULL); + } + + if(smd->flag & MOD_SOLIDIFY_NORMAL_CALC) { + vert_nors= MEM_callocN(sizeof(float) * numVerts * 3, "mod_solid_vno_hq"); + dm_calc_normal(dm, vert_nors); + } + + result = CDDM_from_template(dm, numVerts * 2, (numEdges * 2) + newEdges, (numFaces * 2) + newFaces, 0, 0); + + mface = result->getTessFaceArray(result); + medge = result->getEdgeArray(result); + mvert = result->getVertArray(result); + + DM_copy_face_data(dm, result, 0, 0, numFaces); + DM_copy_face_data(dm, result, 0, numFaces, numFaces); + + DM_copy_edge_data(dm, result, 0, 0, numEdges); + DM_copy_edge_data(dm, result, 0, numEdges, numEdges); + + DM_copy_vert_data(dm, result, 0, 0, numVerts); + DM_copy_vert_data(dm, result, 0, numVerts, numVerts); + + { + static int corner_indices[4] = {2, 1, 0, 3}; + int is_quad; + + for(i=0, mf=mface+numFaces; i<numFaces; i++, mf++) { + mf->v1 += numVerts; + mf->v2 += numVerts; + mf->v3 += numVerts; + if(mf->v4) + mf->v4 += numVerts; + + /* Flip face normal */ + { + is_quad = mf->v4; + SWAP(int, mf->v1, mf->v3); + DM_swap_tessface_data(result, i+numFaces, corner_indices); + test_index_face(mf, &result->faceData, numFaces, is_quad ? 4:3); + } + } + } + + for(i=0, ed=medge+numEdges; i<numEdges; i++, ed++) { + ed->v1 += numVerts; + ed->v2 += numVerts; + } + + if((smd->flag & MOD_SOLIDIFY_EVEN) == 0) { + /* no even thickness, very simple */ + float scalar_short = smd->offset / 32767.0f; + + if(smd->offset < 0.0f) mv= mvert+numVerts; + else mv= mvert; + + for(i=0; i<numVerts; i++, mv++) { + mv->co[0] += mv->no[0] * scalar_short; + mv->co[1] += mv->no[1] * scalar_short; + mv->co[2] += mv->no[2] * scalar_short; + } + } + else { + /* make a face normal layer if not present */ + float (*face_nors)[3]; + int face_nors_calc= 0; + + /* same as EM_solidify() in editmesh_lib.c */ + float *vert_angles= MEM_callocN(sizeof(float) * numVerts * 2, "mod_solid_pair"); /* 2 in 1 */ + float *vert_accum= vert_angles + numVerts; + float face_angles[4]; + int i, j, vidx; + + face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + if(!face_nors) { + face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numFaceData); + face_nors_calc= 1; + } + + if(vert_nors==NULL) { + vert_nors= MEM_mallocN(sizeof(float) * numVerts * 3, "mod_solid_vno"); + for(i=0, mv=mvert; i<numVerts; i++, mv++) { + normal_short_to_float_v3(vert_nors[i], mv->no); + } + } + + for(i=0, mf=mface; i<numFaces; i++, mf++) { + + /* just added, calc the normal */ + if(face_nors_calc) { + if(mf->v4) + normal_quad_v3(face_nors[i], mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + else + normal_tri_v3(face_nors[i] , mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); + } + + if(mf->v4) { + angle_quad_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co); + j= 3; + } + else { + angle_tri_v3(face_angles, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co); + j= 2; + } + + for(; j>=0; j--) { + vidx = *(&mf->v1 + j); + vert_accum[vidx] += face_angles[j]; + vert_angles[vidx]+= shell_angle_to_dist(angle_normalized_v3v3(vert_nors[vidx], face_nors[i])) * face_angles[j]; + } + } + + if(smd->offset < 0.0f) mv= mvert+numVerts; + else mv= mvert; + + for(i=0; i<numVerts; i++, mv++) { + if(vert_accum[i]) { /* zero if unselected */ + madd_v3_v3fl(mv->co, vert_nors[i], smd->offset * (vert_angles[i] / vert_accum[i])); + } + } + + MEM_freeN(vert_angles); + } + + if(vert_nors) + MEM_freeN(vert_nors); + + if(smd->flag & MOD_SOLIDIFY_RIM) { + + static int edge_indices[4][4] = { + {1, 0, 0, 1}, + {2, 1, 1, 2}, + {3, 2, 2, 3}, + {0, 3, 3, 0}}; + + /* add faces & edges */ + ed= medge + (numEdges * 2); + for(i=0; i<newEdges; i++, ed++) { + ed->v1= new_vert_arr[i]; + ed->v2= new_vert_arr[i] + numVerts; + ed->flag |= ME_EDGEDRAW; + + if(smd->crease_rim) + ed->crease= smd->crease_rim * 255.0f; + } + + /* faces */ + mf= mface + (numFaces * 2); + for(i=0; i<newFaces; i++, mf++) { + int eidx= new_edge_arr[i]; + int fidx= edge_users[eidx]; + int flip; + + if(fidx >= numFaces) { + fidx -= numFaces; + flip= 1; + } + else { + flip= 0; + } + + ed= medge + eidx; + + /* copy most of the face settings */ + DM_copy_face_data(dm, result, fidx, (numFaces * 2) + i, 1); + + if(flip) { + DM_swap_tessface_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + + mf->v1= ed->v1; + mf->v2= ed->v2; + mf->v3= ed->v2 + numVerts; + mf->v4= ed->v1 + numVerts; + } + else { + DM_swap_tessface_data(result, (numFaces * 2) + i, edge_indices[edge_order[eidx]]); + + mf->v1= ed->v2; + mf->v2= ed->v1; + mf->v3= ed->v1 + numVerts; + mf->v4= ed->v2 + numVerts; + + + } + + if(smd->crease_outer > 0.0f) + ed->crease= smd->crease_outer * 255.0f; + + if(smd->crease_inner > 0.0f) { + ed= medge + (numEdges + eidx); + ed->crease= smd->crease_inner * 255.0f; + } + } + + MEM_freeN(new_vert_arr); + MEM_freeN(new_edge_arr); + MEM_freeN(edge_users); + MEM_freeN(edge_order); + } + + CDDM_tessfaces_to_faces(result); + + return result; +} + +static DerivedMesh *solidifyModifier_applyModifierEM(ModifierData *md, + Object *ob, + EditMesh *editData, + DerivedMesh *derivedData) +{ + return solidifyModifier_applyModifier(md, ob, derivedData, 0, 1); +} + /* Smoke */ static void smokeModifier_initData(ModifierData *md) @@ -5502,7 +5973,7 @@ static void booleanModifier_copyData(ModifierData *md, ModifierData *target) tbmd->operation = bmd->operation; } -static int booleanModifier_isDisabled(ModifierData *md) +static int booleanModifier_isDisabled(ModifierData *md, int useRenderParams) { BooleanModifierData *bmd = (BooleanModifierData*) md; @@ -5752,6 +6223,7 @@ static void particleInstanceModifier_copyData(ModifierData *md, ModifierData *ta tpimd->ob = pimd->ob; tpimd->psys = pimd->psys; tpimd->flag = pimd->flag; + tpimd->axis = pimd->axis; tpimd->position = pimd->position; tpimd->random_position = pimd->random_position; } @@ -6954,7 +7426,7 @@ static CustomDataMask meshdeformModifier_requiredDataMask(Object *ob, ModifierDa return dataMask; } -static int meshdeformModifier_isDisabled(ModifierData *md) +static int meshdeformModifier_isDisabled(ModifierData *md, int useRenderParams) { MeshDeformModifierData *mmd = (MeshDeformModifierData*) md; @@ -7091,7 +7563,7 @@ static void meshdeformModifier_do( /* progress bar redraw can make this recursive .. */ if(!recursive) { recursive = 1; - mmd->bindfunc(md->scene, mmd, (float*)vertexCos, numVerts, cagemat); + mmd->bindfunc(md->scene, dm, mmd, (float*)vertexCos, numVerts, cagemat); recursive = 0; } } @@ -7244,15 +7716,10 @@ static void multiresModifier_initData(ModifierData *md) { MultiresModifierData *mmd = (MultiresModifierData*)md; - mmd->lvl = mmd->totlvl = 1; -} - -static void multiresModifier_freeData(ModifierData *md) -{ - MultiresModifierData *mmd = (MultiresModifierData*)md; - - if(mmd->undo_verts) - MEM_freeN(mmd->undo_verts); + mmd->lvl = 0; + mmd->sculptlvl = 0; + mmd->renderlvl = 0; + mmd->totlvl = 0; } static void multiresModifier_copyData(ModifierData *md, ModifierData *target) @@ -7260,37 +7727,35 @@ static void multiresModifier_copyData(ModifierData *md, ModifierData *target) MultiresModifierData *mmd = (MultiresModifierData*) md; MultiresModifierData *tmmd = (MultiresModifierData*) target; - tmmd->totlvl = mmd->totlvl; tmmd->lvl = mmd->lvl; + tmmd->sculptlvl = mmd->sculptlvl; + tmmd->renderlvl = mmd->renderlvl; + tmmd->totlvl = mmd->totlvl; } static DerivedMesh *multiresModifier_applyModifier(ModifierData *md, Object *ob, DerivedMesh *dm, int useRenderParams, int isFinalCalc) { MultiresModifierData *mmd = (MultiresModifierData*)md; - DerivedMesh *final; + DerivedMesh *result; - /* TODO: for now just skip a level1 mesh */ - if(mmd->lvl == 1) - return dm; + result = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc); - final = multires_dm_create_from_derived(mmd, 0, dm, ob, useRenderParams, isFinalCalc); - if(mmd->undo_signal && mmd->undo_verts && mmd->undo_verts_tot == final->getNumVerts(final)) { - int i; - MVert *dst = CDDM_get_verts(final); - for(i = 0; i < mmd->undo_verts_tot; ++i) { - copy_v3_v3(dst[i].co, mmd->undo_verts[i].co); - } - CDDM_calc_normals(final); - - MultiresDM_mark_as_modified(final); + if(result == dm) + return dm; - MEM_freeN(mmd->undo_verts); - mmd->undo_signal = 0; - mmd->undo_verts = NULL; + if(useRenderParams || !isFinalCalc) { + DerivedMesh *cddm= CDDM_copy(result, 0); + result->release(result); + result= cddm; + } + else if(ob->mode & OB_MODE_SCULPT) { + /* would be created on the fly too, just nicer this + way on first stroke after e.g. switching levels */ + result->getPBVH(ob, result); } - return final; + return result; } /* Shrinkwrap */ @@ -7339,7 +7804,7 @@ static CustomDataMask shrinkwrapModifier_requiredDataMask(Object *ob, ModifierDa return dataMask; } -static int shrinkwrapModifier_isDisabled(ModifierData *md) +static int shrinkwrapModifier_isDisabled(ModifierData *md, int useRenderParams) { ShrinkwrapModifierData *smd = (ShrinkwrapModifierData*) md; return !smd->target; @@ -7635,6 +8100,7 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->initData = subsurfModifier_initData; mti->copyData = subsurfModifier_copyData; mti->freeData = subsurfModifier_freeData; + mti->isDisabled = subsurfModifier_isDisabled; mti->applyModifier = subsurfModifier_applyModifier; mti->applyModifierEM = subsurfModifier_applyModifierEM; @@ -7967,7 +8433,6 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->type = eModifierTypeType_Constructive; mti->flags = eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_RequiresOriginalData; mti->initData = multiresModifier_initData; - mti->freeData = multiresModifier_freeData; mti->copyData = multiresModifier_copyData; mti->applyModifier = multiresModifier_applyModifier; @@ -7979,6 +8444,16 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type) mti->deformVertsEM = shapekeyModifier_deformVertsEM; mti->deformMatricesEM = shapekeyModifier_deformMatricesEM; + mti = INIT_TYPE(Solidify); + mti->type = eModifierTypeType_Constructive; + mti->flags = eModifierTypeFlag_AcceptsMesh + //| eModifierTypeFlag_SupportsMapping + | eModifierTypeFlag_SupportsEditmode + | eModifierTypeFlag_EnableInEditmode; + mti->initData = solidifyModifier_initData; + mti->copyData = solidifyModifier_copyData; + mti->applyModifier = solidifyModifier_applyModifier; + mti->applyModifierEM = solidifyModifier_applyModifierEM; typeArrInit = 0; #undef INIT_TYPE } @@ -8117,7 +8592,7 @@ int modifier_couldBeCage(ModifierData *md) return ( (md->mode & eModifierMode_Realtime) && (md->mode & eModifierMode_Editmode) && - (!mti->isDisabled || !mti->isDisabled(md)) && + (!mti->isDisabled || !mti->isDisabled(md, 0)) && modifier_supportsMapping(md)); } @@ -8160,7 +8635,7 @@ int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual if (!(md->mode & eModifierMode_Realtime)) continue; if (!(md->mode & eModifierMode_Editmode)) continue; - if (mti->isDisabled && mti->isDisabled(md)) continue; + if (mti->isDisabled && mti->isDisabled(md, 0)) continue; if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue; if (md->mode & eModifierMode_DisableTemporary) continue; @@ -8202,7 +8677,7 @@ int modifier_isEnabled(ModifierData *md, int required_mode) ModifierTypeInfo *mti = modifierType_getInfo(md->type); if((md->mode & required_mode) != required_mode) return 0; - if(mti->isDisabled && mti->isDisabled(md)) return 0; + if(mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return 0; if(md->mode & eModifierMode_DisableTemporary) return 0; if(required_mode & eModifierMode_Editmode) if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0; @@ -8348,15 +8823,15 @@ Object *modifiers_isDeformedByArmature(Object *ob) } /* Takes an object and returns its first selected lattice, else just its -* armature -* This should work for multiple armatures per object +* lattice +* This should work for multiple lattics per object */ Object *modifiers_isDeformedByLattice(Object *ob) { ModifierData *md = modifiers_getVirtualModifierList(ob); LatticeModifierData *lmd= NULL; - /* return the first selected armature, this lets us use multiple armatures + /* return the first selected lattice, this lets us use multiple lattices */ for (; md; md=md->next) { if (md->type==eModifierType_Lattice) { @@ -8389,28 +8864,24 @@ int modifiers_usesArmature(Object *ob, bArmature *arm) return 0; } -int modifier_isDeformer(ModifierData *md) +int modifier_isCorrectableDeformed(ModifierData *md) { if (md->type==eModifierType_Armature) return 1; - if (md->type==eModifierType_Curve) - return 1; - if (md->type==eModifierType_Lattice) - return 1; if (md->type==eModifierType_ShapeKey) return 1; return 0; } -int modifiers_isDeformed(Scene *scene, Object *ob) +int modifiers_isCorrectableDeformed(Scene *scene, Object *ob) { ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md=md->next) { if(ob->mode==OB_MODE_EDIT && (md->mode & eModifierMode_Editmode)==0); else - if(modifier_isDeformer(md)) + if(modifier_isCorrectableDeformed(md)) return 1; } return 0; diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 09673aba7f7..b1f2a9d90f2 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -39,6 +39,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_pbvh.h" #include "BKE_cdderivedmesh.h" #include "BKE_customdata.h" @@ -50,14 +51,20 @@ #include "BKE_multires.h" #include "BKE_object.h" #include "BKE_subsurf.h" +#include "BKE_utildefines.h" + +#include "CCGSubSurf.h" #include <math.h> #include <string.h> /* MULTIRES MODIFIER */ static const int multires_max_levels = 13; -static const int multires_quad_tot[] = {4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; -static const int multires_side_tot[] = {2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; +static const int multires_grid_tot[] = {0, 4, 9, 25, 81, 289, 1089, 4225, 16641, 66049, 263169, 1050625, 4198401, 16785409}; +static const int multires_side_tot[] = {0, 2, 3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097}; + +static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert); +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl); MultiresModifierData *find_multires_modifier(Object *ob) { @@ -72,23 +79,53 @@ MultiresModifierData *find_multires_modifier(Object *ob) } return mmd; +} +static int multires_get_level(Object *ob, MultiresModifierData *mmd, int render) +{ + if(render) + return mmd->renderlvl; + else if(ob->mode == OB_MODE_SCULPT) + return mmd->sculptlvl; + else + return mmd->lvl; } -int multiresModifier_switch_level(Object *ob, const int distance) +static void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl) { - MultiresModifierData *mmd = find_multires_modifier(ob); - - if(mmd) { - mmd->lvl += distance; - if(mmd->lvl < 1) mmd->lvl = 1; - else if(mmd->lvl > mmd->totlvl) mmd->lvl = mmd->totlvl; - /* XXX: DAG_id_flush_update(&ob->id, OB_RECALC_DATA); - object_handle_update(ob);*/ - return 1; + mmd->totlvl = lvl; + + if(ob->mode != OB_MODE_SCULPT) { + mmd->lvl = MAX2(mmd->lvl, lvl); + CLAMP(mmd->lvl, 0, mmd->totlvl); + } + + mmd->sculptlvl = MAX2(mmd->sculptlvl, lvl); + CLAMP(mmd->sculptlvl, 0, mmd->totlvl); + + mmd->renderlvl = MAX2(mmd->renderlvl, lvl); + CLAMP(mmd->renderlvl, 0, mmd->totlvl); +} + +static void multires_dm_mark_as_modified(DerivedMesh *dm) +{ + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; + ccgdm->multires.modified = 1; +} + +void multires_mark_as_modified(Object *ob) +{ + if(ob && ob->derivedFinal) + multires_dm_mark_as_modified(ob->derivedFinal); +} + +void multires_force_update(Object *ob) +{ + if(ob && ob->derivedFinal) { + ob->derivedFinal->needsFree =1; + ob->derivedFinal->release(ob->derivedFinal); + ob->derivedFinal = NULL; } - else - return 0; } /* XXX */ @@ -153,338 +190,158 @@ void multiresModifier_join(Object *ob) } #endif -/* Returns 0 on success, 1 if the src's totvert doesn't match */ +/* Returns 1 on success, 0 if the src's totvert doesn't match */ int multiresModifier_reshape(MultiresModifierData *mmd, Object *dst, Object *src) { - Mesh *src_me = get_mesh(src); + DerivedMesh *srcdm = src->derivedFinal; DerivedMesh *mrdm = dst->derivedFinal; - if(mrdm && mrdm->getNumVerts(mrdm) == src_me->totvert) { - MVert *mvert = CDDM_get_verts(mrdm); - int i; + if(mrdm && srcdm && mrdm->getNumVerts(mrdm) == srcdm->getNumVerts(srcdm)) { + multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm)); - for(i = 0; i < src_me->totvert; ++i) - copy_v3_v3(mvert[i].co, src_me->mvert[i].co); - mrdm->needsFree = 1; - MultiresDM_mark_as_modified(mrdm); - mrdm->release(mrdm); - dst->derivedFinal = NULL; + multires_dm_mark_as_modified(mrdm); + multires_force_update(dst); - return 0; + return 1; } - return 1; + return 0; } -static void Mat3FromColVecs(float mat[][3], float v1[3], float v2[3], float v3[3]) +static void column_vectors_to_mat3(float mat[][3], float v1[3], float v2[3], float v3[3]) { copy_v3_v3(mat[0], v1); copy_v3_v3(mat[1], v2); copy_v3_v3(mat[2], v3); } -static DerivedMesh *multires_subdisp_pre(DerivedMesh *mrdm, int distance, int simple) +static void multires_copy_grid(float (*gridA)[3], float (*gridB)[3], int sizeA, int sizeB) { - DerivedMesh *final; - SubsurfModifierData smd; + int x, y, j, skip; - memset(&smd, 0, sizeof(SubsurfModifierData)); - smd.levels = distance; - if(simple) - smd.subdivType = ME_SIMPLE_SUBSURF; + if(sizeA > sizeB) { + skip = (sizeA-1)/(sizeB-1); - final = subsurf_make_derived_from_derived_with_multires(mrdm, &smd, NULL, 0, NULL, 0, 0); + for(j = 0, y = 0; y < sizeB; y++) + for(x = 0; x < sizeB; x++, j++) + copy_v3_v3(gridA[y*skip*sizeA + x*skip], gridB[j]); + } + else { + skip = (sizeB-1)/(sizeA-1); - return final; + for(j = 0, y = 0; y < sizeA; y++) + for(x = 0; x < sizeA; x++, j++) + copy_v3_v3(gridA[j], gridB[y*skip*sizeB + x*skip]); + } } -static void VecAddUf(float a[3], float b[3]) +static void multires_copy_dm_grid(DMGridData *gridA, DMGridData *gridB, int sizeA, int sizeB) { - a[0] += b[0]; - a[1] += b[1]; - a[2] += b[2]; -} + int x, y, j, skip; -static void multires_subdisp(DerivedMesh *orig, Object *ob, DerivedMesh *final, int lvl, int totlvl, - int totsubvert, int totsubedge, int totsubface, int addverts) -{ - DerivedMesh *mrdm; - Mesh *me = ob->data; - MultiresModifierData mmd_sub; - MVert *mvs = CDDM_get_verts(final); - MVert *mvd, *mvd_f1, *mvs_f1, *mvd_f3, *mvd_f4; - MVert *mvd_f2, *mvs_f2, *mvs_e1, *mvd_e1, *mvs_e2; - int totvert; - int slo1 = multires_side_tot[lvl - 1]; - int sll = slo1 / 2; - int slo2 = multires_side_tot[totlvl - 2]; - int shi2 = multires_side_tot[totlvl - 1]; - int skip = multires_side_tot[totlvl - lvl] - 1; - int i, j, k; + if(sizeA > sizeB) { + skip = (sizeA-1)/(sizeB-1); - memset(&mmd_sub, 0, sizeof(MultiresModifierData)); - mmd_sub.lvl = mmd_sub.totlvl = totlvl; - mrdm = multires_dm_create_from_derived(&mmd_sub, 1, orig, ob, 0, 0); - - mvd = CDDM_get_verts(mrdm); - /* Need to map from ccg to mrdm */ - totvert = mrdm->getNumVerts(mrdm); - - if(!addverts) { - for(i = 0; i < totvert; ++i) { - float z[3] = {0,0,0}; - copy_v3_v3(mvd[i].co, z); - } + for(j = 0, y = 0; y < sizeB; y++) + for(x = 0; x < sizeB; x++, j++) + copy_v3_v3(gridA[y*skip*sizeA + x*skip].co, gridB[j].co); } + else { + skip = (sizeB-1)/(sizeA-1); - /* Load base verts */ - for(i = 0; i < me->totvert; ++i) - VecAddUf(mvd[totvert - me->totvert + i].co, mvs[totvert - me->totvert + i].co); + for(j = 0, y = 0; y < sizeA; y++) + for(x = 0; x < sizeA; x++, j++) + copy_v3_v3(gridA[j].co, gridB[y*skip*sizeB + x*skip].co); + } +} - mvd_f1 = mvd; - mvs_f1 = mvs; - mvd_f2 = mvd; - mvs_f2 = mvs + totvert - totsubvert; - mvs_e1 = mvs + totsubface * (skip-1) * (skip-1); +/* direction=1 for delete higher, direction=0 for lower (not implemented yet) */ +void multiresModifier_del_levels(MultiresModifierData *mmd, Object *ob, int direction) +{ + Mesh *me = get_mesh(ob); + int lvl = multires_get_level(ob, mmd, 0); + int levels = mmd->totlvl - lvl; + MDisps *mdisps; - for(i = 0; i < me->totface; ++i) { - const int end = me->mface[i].v4 ? 4 : 3; - int x, y, x2, y2, mov= 0; - - mvd_f1 += 1 + end * (slo2-2); //center+edgecross - mvd_f3 = mvd_f4 = mvd_f1; - - for(j = 0; j < end; ++j) { - mvd_f1 += (skip/2 - 1) * (slo2 - 2) + (skip/2 - 1); - /* Update sub faces */ - for(y = 0; y < sll; ++y) { - for(x = 0; x < sll; ++x) { - /* Face center */ - VecAddUf(mvd_f1->co, mvs_f1->co); - mvs_f1 += 1; - - /* Now we hold the center of the subface at mvd_f1 - and offset it to the edge cross and face verts */ - - /* Edge cross */ - for(k = 0; k < 4; ++k) { - if(k == 0) mov = -1; - else if(k == 1) mov = slo2 - 2; - else if(k == 2) mov = 1; - else if(k == 3) mov = -(slo2 - 2); - - for(x2 = 1; x2 < skip/2; ++x2) { - VecAddUf((mvd_f1 + mov * x2)->co, mvs_f1->co); - ++mvs_f1; - } - } + CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop); + mdisps= CustomData_get_layer(&me->ldata, CD_MDISPS); - /* Main face verts */ - for(k = 0; k < 4; ++k) { - int movx= 0, movy= 0; - - if(k == 0) { movx = -1; movy = -(slo2 - 2); } - else if(k == 1) { movx = slo2 - 2; movy = -1; } - else if(k == 2) { movx = 1; movy = slo2 - 2; } - else if(k == 3) { movx = -(slo2 - 2); movy = 1; } - - for(y2 = 1; y2 < skip/2; ++y2) { - for(x2 = 1; x2 < skip/2; ++x2) { - VecAddUf((mvd_f1 + movy * y2 + movx * x2)->co, mvs_f1->co); - ++mvs_f1; - } - } - } - - mvd_f1 += skip; - } - mvd_f1 += (skip - 1) * (slo2 - 2) - 1; - } - mvd_f1 -= (skip - 1) * (slo2 - 2) - 1 + skip; - mvd_f1 += (slo2 - 2) * (skip/2-1) + skip/2-1 + 1; - } + multires_force_update(ob); - /* update face center verts */ - VecAddUf(mvd_f2->co, mvs_f2->co); + if(mdisps && levels > 0 && direction == 1) { + if(lvl > 0) { + MLoop *ml = me->mloop; + int nsize = multires_side_tot[lvl]; + int hsize = multires_side_tot[mmd->totlvl]; + int i, j, k=0; - mvd_f2 += 1; - mvs_f2 += 1; + for(i = 0; i < me->totpoly; ++i) { + for (j=0; j<me->mpoly[i].totloop; j++, k++) { + MDisps *mdisp= &mdisps[k]; + float (*disps)[3], (*ndisps)[3], (*hdisps)[3]; + int totdisp = multires_grid_tot[lvl]; - /* update face edge verts */ - for(j = 0; j < end; ++j) { - MVert *restore; + disps = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps"); - /* Super-face edge cross */ - for(k = 0; k < skip-1; ++k) { - VecAddUf(mvd_f2->co, mvs_e1->co); - mvd_f2++; - mvs_e1++; - } - for(x = 1; x < sll; ++x) { - VecAddUf(mvd_f2->co, mvs_f2->co); - mvd_f2++; - mvs_f2++; - - for(k = 0; k < skip-1; ++k) { - VecAddUf(mvd_f2->co, mvs_e1->co); - mvd_f2++; - mvs_e1++; - } - } + ndisps = disps; + hdisps = mdisp->disps; - restore = mvs_e1; - for(y = 0; y < sll - 1; ++y) { - for(x = 0; x < sll; ++x) { - for(k = 0; k < skip - 1; ++k) { - VecAddUf(mvd_f3[(skip-1)+(y*skip) + (x*skip+k)*(slo2-2)].co, - mvs_e1->co); - ++mvs_e1; - } - mvs_e1 += skip-1; - } - } - - mvs_e1 = restore + skip - 1; - for(y = 0; y < sll - 1; ++y) { - for(x = 0; x < sll; ++x) { - for(k = 0; k < skip - 1; ++k) { - VecAddUf(mvd_f3[(slo2-2)*(skip-1)+(x*skip)+k + y*skip*(slo2-2)].co, - mvs_e1->co); - ++mvs_e1; - } - mvs_e1 += skip - 1; - } - } + multires_copy_grid(ndisps, hdisps, nsize, hsize); - mvd_f3 += (slo2-2)*(slo2-2); - mvs_e1 -= skip - 1; - } + ndisps += nsize*nsize; + hdisps += hsize*hsize; - /* update base (2) face verts */ - for(j = 0; j < end; ++j) { - mvd_f2 += (slo2 - 1) * (skip - 1); - for(y = 0; y < sll - 1; ++y) { - for(x = 0; x < sll - 1; ++x) { - VecAddUf(mvd_f2->co, mvs_f2->co); - mvd_f2 += skip; - ++mvs_f2; + MEM_freeN(mdisp->disps); + mdisp->disps = disps; + mdisp->totdisp = totdisp; } - mvd_f2 += (slo2 - 1) * (skip - 1); } - mvd_f2 -= (skip - 1); } - } - - /* edges */ - mvd_e1 = mvd + totvert - me->totvert - me->totedge * (shi2-2); - mvs_e2 = mvs + totvert - me->totvert - me->totedge * (slo1-2); - for(i = 0; i < me->totedge; ++i) { - for(j = 0; j < skip - 1; ++j) { - VecAddUf(mvd_e1->co, mvs_e1->co); - mvd_e1++; - mvs_e1++; - } - for(j = 0; j < slo1 - 2; j++) { - VecAddUf(mvd_e1->co, mvs_e2->co); - mvd_e1++; - mvs_e2++; - - for(k = 0; k < skip - 1; ++k) { - VecAddUf(mvd_e1->co, mvs_e1->co); - mvd_e1++; - mvs_e1++; - } + else { + CustomData_external_remove(&me->ldata, &me->id, CD_MDISPS, me->totloop); + CustomData_free_layer_active(&me->ldata, CD_MDISPS, me->totloop); } } - final->needsFree = 1; - final->release(final); - mrdm->needsFree = 1; - MultiresDM_mark_as_modified(mrdm); - mrdm->release(mrdm); + multires_set_tot_level(ob, mmd, lvl); } -/* direction=1 for delete higher, direction=0 for lower (not implemented yet) */ -void multiresModifier_del_levels(struct MultiresModifierData *mmd, struct Object *ob, int direction) +static DerivedMesh *multires_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int totlvl, int simple) { - Mesh *me = get_mesh(ob); - int distance = mmd->totlvl - mmd->lvl; - MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); + MultiresModifierData mmd; - multires_force_update(ob); + memset(&mmd, 0, sizeof(MultiresModifierData)); + mmd.lvl = lvl; + mmd.sculptlvl = lvl; + mmd.renderlvl = lvl; + mmd.totlvl = totlvl; + mmd.simple = simple; - if(mdisps && distance > 0 && direction == 1) { - int skip = multires_side_tot[distance] - 1; - int st = multires_side_tot[mmd->totlvl - 1]; - int totdisp = multires_quad_tot[mmd->lvl - 1]; - int i, j, x, y; + return multires_dm_create_from_derived(&mmd, 1, dm, ob, 0, 0); +} - for(i = 0; i < me->totface; ++i) { - float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires del disps"); - - for(j = 0, y = 0; y < st; y += skip) { - for(x = 0; x < st; x += skip) { - copy_v3_v3(disps[j], mdisps[i].disps[y * st + x]); - ++j; - } - } +static DerivedMesh *subsurf_dm_create_local(Object *ob, DerivedMesh *dm, int lvl, int simple, int optimal) +{ + SubsurfModifierData smd; - MEM_freeN(mdisps[i].disps); - mdisps[i].disps = disps; - mdisps[i].totdisp = totdisp; - } - } + memset(&smd, 0, sizeof(SubsurfModifierData)); + smd.levels = smd.renderLevels = lvl; + smd.flags |= eSubsurfModifierFlag_SubsurfUv; + if(simple) + smd.subdivType = ME_SIMPLE_SUBSURF; + if(optimal) + smd.flags |= eSubsurfModifierFlag_ControlEdges; - mmd->totlvl = mmd->lvl; + return subsurf_make_derived_from_derived(dm, &smd, 0, NULL, 0, 0); } -void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int distance, int updateblock, int simple) +static void multires_reallocate_mdisps(Mesh *me, MDisps *mdisps, int lvl) { - DerivedMesh *final = NULL; - int totsubvert = 0, totsubface = 0, totsubedge = 0; - Mesh *me = get_mesh(ob); - MDisps *mdisps; int i; - if(distance == 0) - return; - - if(mmd->totlvl > multires_max_levels) - mmd->totlvl = multires_max_levels; - if(mmd->lvl > multires_max_levels) - mmd->lvl = multires_max_levels; - - multires_force_update(ob); - - mmd->lvl = mmd->totlvl; - mmd->totlvl += distance; - - mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); - if(!mdisps) - mdisps = CustomData_add_layer(&me->fdata, CD_MDISPS, CD_DEFAULT, NULL, me->totface); - - if(mdisps->disps && !updateblock && mmd->totlvl > 2) { - DerivedMesh *orig, *mrdm; - MultiresModifierData mmd_sub; - - orig = CDDM_from_mesh(me, NULL); - memset(&mmd_sub, 0, sizeof(MultiresModifierData)); - mmd_sub.lvl = mmd_sub.totlvl = mmd->lvl; - mmd_sub.simple = simple; - mrdm = multires_dm_create_from_derived(&mmd_sub, 1, orig, ob, 0, 0); - totsubvert = mrdm->getNumVerts(mrdm); - totsubedge = mrdm->getNumEdges(mrdm); - totsubface = mrdm->getNumTessFaces(mrdm); - orig->needsFree = 1; - orig->release(orig); - - final = multires_subdisp_pre(mrdm, distance, simple); - mrdm->needsFree = 1; - mrdm->release(mrdm); - } - - for(i = 0; i < me->totface; ++i) { - const int totdisp = multires_quad_tot[mmd->totlvl - 1]; + /* reallocate displacements to be filled in */ + for(i = 0; i < me->totloop; ++i) { + int totdisp = multires_grid_tot[lvl]; float (*disps)[3] = MEM_callocN(sizeof(float) * 3 * totdisp, "multires disps"); if(mdisps[i].disps) @@ -493,772 +350,482 @@ void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int dista mdisps[i].disps = disps; mdisps[i].totdisp = totdisp; } - - - if(final) { - DerivedMesh *orig; - - orig = CDDM_from_mesh(me, NULL); - - multires_subdisp(orig, ob, final, mmd->lvl, mmd->totlvl, totsubvert, totsubedge, totsubface, 0); - - orig->needsFree = 1; - orig->release(orig); - } - - mmd->lvl = mmd->totlvl; } -typedef struct DisplacerEdges { - /* DerivedMesh index at the start of each edge (using face x/y directions to define the start) */ - int base[4]; - /* 1 if edge moves in the positive x or y direction, -1 otherwise */ - int dir[4]; -} DisplacerEdges; - -typedef struct DisplacerSpill { - /* Index of face (in base mesh), -1 for none */ - int face; - - /* Spill flag */ - /* 1 = Negative variable axis */ - /* 2 = Near fixed axis */ - /* 4 = Flip axes */ - int f; +void multiresModifier_subdivide(MultiresModifierData *mmd, Object *ob, int updateblock, int simple) +{ + Mesh *me = ob->data; + MDisps *mdisps; + int lvl= mmd->totlvl; + int totlvl= mmd->totlvl+1; - /* Neighboring edges */ - DisplacerEdges edges; -} DisplacerSpill; + if(totlvl > multires_max_levels) + return; -typedef struct MultiresDisplacer { - Mesh *me; - MDisps *grid; - MFace *face; - - int dm_first_base_vert_index; + multires_force_update(ob); - int spacing; - int sidetot, interior_st, disp_st; - int sidendx; - int type; - int invert; - MVert *subco; - int subco_index, face_index; - float weight; + mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); + if(!mdisps) + mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop); + + if(mdisps->disps && !updateblock && totlvl > 1) { + /* upsample */ + DerivedMesh *lowdm, *cddm, *highdm; + DMGridData **highGridData, **lowGridData, **subGridData; + CCGSubSurf *ss; + int i, numGrids, highGridSize, lowGridSize; + + /* create subsurf DM from original mesh at high level */ + cddm = CDDM_from_mesh(me, NULL); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0); + + /* create multires DM from original mesh at low level */ + lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple); + cddm->release(cddm); + + /* copy subsurf grids and replace them with low displaced grids */ + numGrids = highdm->getNumGrids(highdm); + highGridSize = highdm->getGridSize(highdm); + highGridData = highdm->getGridData(highdm); + lowGridSize = lowdm->getGridSize(lowdm); + lowGridData = lowdm->getGridData(lowdm); + + subGridData = MEM_callocN(sizeof(float*)*numGrids, "subGridData*"); + + for(i = 0; i < numGrids; ++i) { + /* backup subsurf grids */ + subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData"); + memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize); + + /* overwrite with current displaced grids */ + multires_copy_dm_grid(highGridData[i], lowGridData[i], highGridSize, lowGridSize); + } - /* Valence for each corner */ - int valence[4]; + /* low lower level dm no longer needed at this point */ + lowdm->release(lowdm); - /* Neighboring edges for current face */ - DisplacerEdges edges_primary; + /* subsurf higher levels again with displaced data */ + ss= ((CCGDerivedMesh*)highdm)->ss; + ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0); + ccgSubSurf_updateLevels(ss, lvl, NULL, 0); - /* Neighboring faces */ - DisplacerSpill spill_x, spill_y; + /* reallocate displacements */ + multires_reallocate_mdisps(me, mdisps, totlvl); - int *face_offsets; + /* compute displacements */ + multiresModifier_disp_run(highdm, me, 1, 0, subGridData, totlvl); - int x, y, ax, ay; -} MultiresDisplacer; + /* free */ + highdm->release(highdm); + for(i = 0; i < numGrids; ++i) + MEM_freeN(subGridData[i]); + MEM_freeN(subGridData); + } + else { + /* only reallocate, nothing to upsample */ + multires_reallocate_mdisps(me, mdisps, totlvl); + } -static int mface_v(MFace *f, int v) -{ - return v == 0 ? f->v1 : v == 1 ? f->v2 : v == 2 ? f->v3 : v == 3 ? f->v4 : -1; + multires_set_tot_level(ob, mmd, totlvl); } -/* Get the edges (and their directions) */ -static void find_displacer_edges(MultiresDisplacer *d, DerivedMesh *dm, DisplacerEdges *de, MFace *f) +static void grid_tangent(int gridSize, int index, int x, int y, int axis, DMGridData **gridData, float t[3]) { - ListBase *emap = MultiresDM_get_vert_edge_map(dm); - IndexNode *n; - int i, end = f->v4 ? 4 : 3; - int offset = dm->getNumVerts(dm) - d->me->totvert - d->me->totedge * d->interior_st; - - for(i = 0; i < end; ++i) { - int vcur = mface_v(f, i); - int vnext = mface_v(f, i == end - 1 ? 0 : i + 1); - - de->dir[i] = 1; - - for(n = emap[vcur].first; n; n = n->next) { - MEdge *e = &d->me->medge[n->index]; - - if(e->v1 == vnext || e->v2 == vnext) { - de->base[i] = n->index * d->interior_st; - if(((i == 0 || i == 1) && e->v1 == vnext) || - ((i == 2 || i == 3) && e->v2 == vnext)) { - de->dir[i] = -1; - de->base[i] += d->interior_st - 1; - } - de->base[i] += offset; - break; - } + if(axis == 0) { + if(x == gridSize - 1) { + if(y == gridSize - 1) + sub_v3_v3v3(t, gridData[index][x + gridSize*(y - 1)].co, gridData[index][x - 1 + gridSize*(y - 1)].co); + else + sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x - 1 + gridSize*y].co); } + else + sub_v3_v3v3(t, gridData[index][x + 1 + gridSize*y].co, gridData[index][x + gridSize*y].co); } -} - -/* Returns in out the corners [0-3] that use v1 and v2 */ -static void find_face_corners(MFace *f, int v1, int v2, int out[2]) -{ - int i, end = f->v4 ? 4 : 3; - - for(i = 0; i < end; ++i) { - int corner = mface_v(f, i); - if(corner == v1) - out[0] = i; - if(corner == v2) - out[1] = i; + else if(axis == 1) { + if(y == gridSize - 1) { + if(x == gridSize - 1) + sub_v3_v3v3(t, gridData[index][x - 1 + gridSize*y].co, gridData[index][x - 1 + gridSize*(y - 1)].co); + else + sub_v3_v3v3(t, gridData[index][x + gridSize*y].co, gridData[index][x + gridSize*(y - 1)].co); + } + else + sub_v3_v3v3(t, gridData[index][x + gridSize*(y + 1)].co, gridData[index][x + gridSize*y].co); } } -static void multires_displacer_get_spill_faces(MultiresDisplacer *d, DerivedMesh *dm, MFace *mface) +static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, int invert, int add, DMGridData **oldGridData, int totlvl) { - ListBase *map = MultiresDM_get_vert_face_map(dm); - IndexNode *n1, *n2; - int v4 = d->face->v4 ? d->face->v4 : d->face->v1; - int crn[2], lv; - - memset(&d->spill_x, 0, sizeof(DisplacerSpill)); - memset(&d->spill_y, 0, sizeof(DisplacerSpill)); - d->spill_x.face = d->spill_y.face = -1; - - for(n1 = map[d->face->v3].first; n1; n1 = n1->next) { - if(n1->index == d->face_index) - continue; - - for(n2 = map[d->face->v2].first; n2; n2 = n2->next) { - if(n1->index == n2->index) - d->spill_x.face = n1->index; - } - for(n2 = map[v4].first; n2; n2 = n2->next) { - if(n1->index == n2->index) - d->spill_y.face = n1->index; - } - } - - if(d->spill_x.face != -1) { - /* Neighbor of v2/v3 found, find flip and orientation */ - find_face_corners(&mface[d->spill_x.face], d->face->v2, d->face->v3, crn); - lv = mface[d->spill_x.face].v4 ? 3 : 2; - - if(crn[0] == 0 && crn[1] == lv) - d->spill_x.f = 0+2+0; - else if(crn[0] == lv && crn[1] == 0) - d->spill_x.f = 1+2+0; - else if(crn[0] == 1 && crn[1] == 0) - d->spill_x.f = 1+2+4; - else if(crn[0] == 0 && crn[1] == 1) - d->spill_x.f = 0+2+4; - else if(crn[0] == 2 && crn[1] == 1) - d->spill_x.f = 1+0+0; - else if(crn[0] == 1 && crn[1] == 2) - d->spill_x.f = 0+0+0; - else if(crn[0] == 3 && crn[1] == 2) - d->spill_x.f = 0+0+4; - else if(crn[0] == 2 && crn[1] == 3) - d->spill_x.f = 1+0+4; - - find_displacer_edges(d, dm, &d->spill_x.edges, &mface[d->spill_x.face]); - } - - if(d->spill_y.face != -1) { - /* Neighbor of v3/v4 found, find flip and orientation */ - find_face_corners(&mface[d->spill_y.face], d->face->v3, v4, crn); - lv = mface[d->spill_y.face].v4 ? 3 : 2; - - if(crn[0] == 1 && crn[1] == 0) - d->spill_y.f = 1+2+0; - else if(crn[0] == 0 && crn[1] == 1) - d->spill_y.f = 0+2+0; - else if(crn[0] == 2 && crn[1] == 1) - d->spill_y.f = 1+0+4; - else if(crn[0] == 1 && crn[1] == 2) - d->spill_y.f = 0+0+4; - else if(crn[0] == 3 && crn[1] == 2) - d->spill_y.f = 0+0+0; - else if(crn[0] == 2 && crn[1] == 3) - d->spill_y.f = 1+0+0; - else if(crn[0] == 0 && crn[1] == lv) - d->spill_y.f = 0+2+4; - else if(crn[0] == lv && crn[1] == 0) - d->spill_y.f = 1+2+4; - - find_displacer_edges(d, dm, &d->spill_y.edges, &mface[d->spill_y.face]); + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; + DMGridData **gridData, **subGridData; + MPoly *mpoly = me->mpoly; + MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); + int *gridOffset; + int i, k, numGrids, gridSize, dGridSize, dSkip; + + if(!mdisps) { + if(invert) + mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, CD_DEFAULT, NULL, me->totloop); + else + return; } -} -static void find_corner_valences(MultiresDisplacer *d, DerivedMesh *dm) -{ - int i; + numGrids = dm->getNumGrids(dm); + gridSize = dm->getGridSize(dm); + gridData = dm->getGridData(dm); + gridOffset = dm->getGridOffset(dm); + subGridData = (oldGridData)? oldGridData: gridData; + + dGridSize = multires_side_tot[totlvl]; + dSkip = (dGridSize-1)/(gridSize-1); + + k = 0; /*current loop/mdisp index within the mloop array*/ + + #pragma omp parallel for private(i) schedule(static) + for(i = 0; i < me->totpoly; ++i) { + const int numVerts = mpoly[i].totloop; + int S, x, y, gIndex = gridOffset[i]; + + for(S = 0; S < numVerts; ++S, ++gIndex, ++k) { + MDisps *mdisp = &mdisps[k]; + DMGridData *grid = gridData[gIndex]; + DMGridData *subgrid = subGridData[gIndex]; + float (*dispgrid)[3] = NULL; + + /* when adding new faces in edit mode, need to allocate disps */ + if(!mdisp->disps) + #pragma omp critical + { + multires_reallocate_mdisps(me, mdisps, totlvl); + } - d->valence[3] = -1; + dispgrid = mdisp->disps; - /* Set the vertex valence for the corners */ - for(i = 0; i < (d->face->v4 ? 4 : 3); ++i) - d->valence[i] = BLI_countlist(&MultiresDM_get_vert_edge_map(dm)[mface_v(d->face, i)]); -} + for(y = 0; y < gridSize; y++) { + for(x = 0; x < gridSize; x++) { + float *co = grid[x + y*gridSize].co; + float *sco = subgrid[x + y*gridSize].co; + float *no = subgrid[x + y*gridSize].no; + float *data = dispgrid[dGridSize*y*dSkip + x*dSkip]; + float mat[3][3], tx[3], ty[3], disp[3], d[3]; -static void multires_displacer_init(MultiresDisplacer *d, DerivedMesh *dm, - const int face_index, const int invert) -{ - Mesh *me = MultiresDM_get_mesh(dm); - - d->me = me; - d->face = me->mface + face_index; - d->face_index = face_index; - d->face_offsets = MultiresDM_get_face_offsets(dm); - /* Get the multires grid from customdata */ - d->grid = CustomData_get_layer(&me->fdata, CD_MDISPS); - if(d->grid) - d->grid += face_index; - - d->spacing = pow(2, MultiresDM_get_totlvl(dm) - MultiresDM_get_lvl(dm)); - d->sidetot = multires_side_tot[MultiresDM_get_lvl(dm) - 1]; - d->interior_st = d->sidetot - 2; - d->disp_st = multires_side_tot[MultiresDM_get_totlvl(dm) - 1]; - d->invert = invert; - - multires_displacer_get_spill_faces(d, dm, me->mface); - find_displacer_edges(d, dm, &d->edges_primary, d->face); - find_corner_valences(d, dm); - - d->dm_first_base_vert_index = dm->getNumVerts(dm) - me->totvert; -} + /* construct tangent space matrix */ + grid_tangent(gridSize, gIndex, x, y, 0, subGridData, tx); + normalize_v3(tx); -static void multires_displacer_weight(MultiresDisplacer *d, const float w) -{ - d->weight = w; -} + grid_tangent(gridSize, gIndex, x, y, 1, subGridData, ty); + normalize_v3(ty); -static void multires_displacer_anchor(MultiresDisplacer *d, const int type, const int side_index) -{ - d->sidendx = side_index; - d->x = d->y = d->sidetot / 2; - d->type = type; - - if(type == 2) { - if(side_index == 0) - d->y -= 1; - else if(side_index == 1) - d->x += 1; - else if(side_index == 2) - d->y += 1; - else if(side_index == 3) - d->x -= 1; - } - else if(type == 3) { - if(side_index == 0) { - d->x -= 1; - d->y -= 1; - } - else if(side_index == 1) { - d->x += 1; - d->y -= 1; - } - else if(side_index == 2) { - d->x += 1; - d->y += 1; - } - else if(side_index == 3) { - d->x -= 1; - d->y += 1; - } - } + //mul_v3_fl(tx, 1.0f/(gridSize-1)); + //mul_v3_fl(ty, 1.0f/(gridSize-1)); + //cross_v3_v3v3(no, tx, ty); - d->ax = d->x; - d->ay = d->y; -} + column_vectors_to_mat3(mat, tx, ty, no); -static void multires_displacer_anchor_edge(MultiresDisplacer *d, int v1, int v2, int x) -{ - d->type = 4; - - if(v1 == d->face->v1) { - d->x = 0; - d->y = 0; - if(v2 == d->face->v2) - d->x += x; - else if(v2 == d->face->v3) { - if(x < d->sidetot / 2) - d->y = x; - else { - d->x = x; - d->y = d->sidetot - 1; - } - } - else - d->y += x; - } - else if(v1 == d->face->v2) { - d->x = d->sidetot - 1; - d->y = 0; - if(v2 == d->face->v1) - d->x -= x; - else - d->y += x; - } - else if(v1 == d->face->v3) { - d->x = d->sidetot - 1; - d->y = d->sidetot - 1; - if(v2 == d->face->v2) - d->y -= x; - else if(v2 == d->face->v1) { - if(x < d->sidetot / 2) - d->x -= x; - else { - d->x = 0; - d->y -= x; + if(!invert) { + /* convert to object space and add */ + mul_v3_m3v3(disp, mat, data); + add_v3_v3v3(co, sco, disp); + } + else if(!add) { + /* convert difference to tangent space */ + sub_v3_v3v3(disp, co, sco); + invert_m3(mat); + mul_v3_m3v3(data, mat, disp); + } + else { + /* convert difference to tangent space */ + invert_m3(mat); + mul_v3_m3v3(d, mat, co); + add_v3_v3(data, d); + } + } } } - else - d->x -= x; } - else if(v1 == d->face->v4) { - d->x = 0; - d->y = d->sidetot - 1; - if(v2 == d->face->v3) - d->x += x; - else - d->y -= x; + + if(!invert) { + ccgSubSurf_stitchFaces(ccgdm->ss, 0, NULL, 0); + ccgSubSurf_updateNormals(ccgdm->ss, NULL, 0); } } -static void multires_displacer_anchor_vert(MultiresDisplacer *d, const int v) +static void multiresModifier_update(DerivedMesh *dm) { - const int e = d->sidetot - 1; + CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; + Object *ob; + Mesh *me; + MDisps *mdisps; + MultiresModifierData *mmd; - d->type = 5; + ob = ccgdm->multires.ob; + me = ccgdm->multires.ob->data; + mmd = ccgdm->multires.mmd; + CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop); + mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS); - d->x = d->y = 0; - if(v == d->face->v2) - d->x = e; - else if(v == d->face->v3) - d->x = d->y = e; - else if(v == d->face->v4) - d->y = e; -} + if(mdisps) { + int lvl = ccgdm->multires.lvl; + int totlvl = ccgdm->multires.totlvl; + + if(lvl < totlvl) { + Mesh *me = ob->data; + DerivedMesh *lowdm, *cddm, *highdm; + DMGridData **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; + CCGSubSurf *ss; + int i, j, numGrids, highGridSize, lowGridSize; + + /* create subsurf DM from original mesh at high level */ + cddm = CDDM_from_mesh(me, NULL); + highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0); + + /* create multires DM from original mesh and displacements */ + lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple); + cddm->release(cddm); + + /* gather grid data */ + numGrids = highdm->getNumGrids(highdm); + highGridSize = highdm->getGridSize(highdm); + highGridData = highdm->getGridData(highdm); + lowGridSize = lowdm->getGridSize(lowdm); + lowGridData = lowdm->getGridData(lowdm); + gridData = dm->getGridData(dm); + + subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*"); + diffGrid = MEM_callocN(sizeof(DMGridData)*lowGridSize*lowGridSize, "diff"); + + for(i = 0; i < numGrids; ++i) { + /* backup subsurf grids */ + subGridData[i] = MEM_callocN(sizeof(DMGridData)*highGridSize*highGridSize, "subGridData"); + memcpy(subGridData[i], highGridData[i], sizeof(DMGridData)*highGridSize*highGridSize); + + /* write difference of subsurf and displaced low level into high subsurf */ + for(j = 0; j < lowGridSize*lowGridSize; ++j) + sub_v3_v3v3(diffGrid[j].co, gridData[i][j].co, lowGridData[i][j].co); + + multires_copy_dm_grid(highGridData[i], diffGrid, highGridSize, lowGridSize); + } -static void multires_displacer_jump(MultiresDisplacer *d) -{ - if(d->sidendx == 0) { - d->x -= 1; - d->y = d->ay; - } - else if(d->sidendx == 1) { - d->x = d->ax; - d->y -= 1; - } - else if(d->sidendx == 2) { - d->x += 1; - d->y = d->ay; - } - else if(d->sidendx == 3) { - d->x = d->ax; - d->y += 1; - } -} + /* lower level dm no longer needed at this point */ + MEM_freeN(diffGrid); + lowdm->release(lowdm); -/* Treating v1 as (0,0) and v3 as (st-1,st-1), - returns the index of the vertex at (x,y). - If x or y is >= st, wraps over to the adjacent face, - or if there is no adjacent face, returns -2. */ -static int multires_index_at_loc(int face_index, int x, int y, MultiresDisplacer *d, DisplacerEdges *de) -{ - int coord_edge = d->sidetot - 1; /* Max value of x/y at edge of grid */ - int mid = d->sidetot / 2; - int lim = mid - 1; - int qtot = lim * lim; - int base = d->face_offsets[face_index]; - - /* Edge spillover */ - if(x == d->sidetot || y == d->sidetot) { - int flags, v_axis, f_axis, lx, ly; - - if(x == d->sidetot && d->spill_x.face != -1) { - flags = d->spill_x.f; - - /* Handle triangle seam between v1 and v3 */ - if(!d->me->mface[d->spill_x.face].v4 && - ((flags == 2 && y >= mid) || (flags == 3 && y < mid))) - flags += 2; - - v_axis = (flags & 1) ? d->sidetot - 1 - y : y; - f_axis = (flags & 2) ? 1 : d->sidetot - 2; - lx = f_axis, ly = v_axis; - - if(flags & 4) { - lx = v_axis; - ly = f_axis; - } + /* subsurf higher levels again with difference of coordinates */ + ss= ((CCGDerivedMesh*)highdm)->ss; + ccgSubSurf_updateFromFaces(ss, lvl, NULL, 0); + ccgSubSurf_updateLevels(ss, lvl, NULL, 0); - return multires_index_at_loc(d->spill_x.face, lx, ly, d, &d->spill_x.edges); + /* add to displacements */ + multiresModifier_disp_run(highdm, me, 1, 1, subGridData, mmd->totlvl); + + /* free */ + highdm->release(highdm); + for(i = 0; i < numGrids; ++i) + MEM_freeN(subGridData[i]); + MEM_freeN(subGridData); } - else if(y == d->sidetot && d->spill_y.face != -1) { - flags = d->spill_y.f; + else { + DerivedMesh *cddm, *subdm; - /* Handle triangle seam between v1 and v3 */ - if(!d->me->mface[d->spill_y.face].v4 && - ((flags == 6 && x >= mid) || (flags == 7 && x < mid))) - flags = ~flags; + cddm = CDDM_from_mesh(me, NULL); + subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0); + cddm->release(cddm); - v_axis = (flags & 1) ? x : d->sidetot - 1 - x; - f_axis = (flags & 2) ? 1 : d->sidetot - 2; - lx = v_axis, ly = f_axis; + multiresModifier_disp_run(dm, me, 1, 0, subdm->getGridData(subdm), mmd->totlvl); - if(flags & 4) { - lx = f_axis; - ly = v_axis; - } - - return multires_index_at_loc(d->spill_y.face, lx, ly, d, &d->spill_y.edges); + subdm->release(subdm); } - else - return -2; - } - /* Corners */ - else if(x == 0 && y == 0) - return d->dm_first_base_vert_index + d->face->v1; - else if(x == coord_edge && y == 0) - return d->dm_first_base_vert_index + d->face->v2; - else if(x == coord_edge && y == coord_edge) - return d->dm_first_base_vert_index + d->face->v3; - else if(x == 0 && y == coord_edge) - return d->dm_first_base_vert_index + d->face->v4; - /* Edges */ - else if(x == 0) { - if(d->face->v4) - return de->base[3] + de->dir[3] * (y - 1); - else - return de->base[2] + de->dir[2] * (y - 1); - } - else if(y == 0) - return de->base[0] + de->dir[0] * (x - 1); - else if(x == d->sidetot - 1) - return de->base[1] + de->dir[1] * (y - 1); - else if(y == d->sidetot - 1) - return de->base[2] + de->dir[2] * (x - 1); - /* Face center */ - else if(x == mid && y == mid) - return base; - /* Cross */ - else if(x == mid && y < mid) - return base + (mid - y); - else if(y == mid && x > mid) - return base + lim + (x - mid); - else if(x == mid && y > mid) - return base + lim*2 + (y - mid); - else if(y == mid && x < mid) { - if(d->face->v4) - return base + lim*3 + (mid - x); - else - return base + lim*2 + (mid - x); - } - /* Quarters */ - else { - int offset = base + lim * (d->face->v4 ? 4 : 3); - if(x < mid && y < mid) - return offset + ((mid - x - 1)*lim + (mid - y)); - else if(x > mid && y < mid) - return offset + qtot + ((mid - y - 1)*lim + (x - mid)); - else if(x > mid && y > mid) - return offset + qtot*2 + ((x - mid - 1)*lim + (y - mid)); - else if(x < mid && y > mid) - return offset + qtot*3 + ((y - mid - 1)*lim + (mid - x)); } - - return -1; } -/* Calculate the TS matrix used for applying displacements. - Uses the undisplaced subdivided mesh's curvature to find a - smoothly normal and tangents. */ -static void calc_disp_mat(MultiresDisplacer *d, float mat[3][3]) +void multires_stitch_grids(Object *ob) { - int u = multires_index_at_loc(d->face_index, d->x + 1, d->y, d, &d->edges_primary); - int v = multires_index_at_loc(d->face_index, d->x, d->y + 1, d, &d->edges_primary); - float norm[3], t1[3], t2[3], inv[3][3]; - MVert *base = d->subco + d->subco_index; + /* utility for smooth brush */ + if(ob && ob->derivedFinal) { + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)ob->derivedFinal; + CCGFace **faces; + int totface; - //printf("f=%d, x=%d, y=%d, i=%d, u=%d, v=%d ", d->face_index, d->x, d->y, d->subco_index, u, v); - - norm[0] = base->no[0] / 32767.0f; - norm[1] = base->no[1] / 32767.0f; - norm[2] = base->no[2] / 32767.0f; - - /* Special handling for vertices of valence 3 */ - if(d->valence[1] == 3 && d->x == d->sidetot - 1 && d->y == 0) - u = -1; - else if(d->valence[2] == 3 && d->x == d->sidetot - 1 && d->y == d->sidetot - 1) - u = v = -1; - else if(d->valence[3] == 3 && d->x == 0 && d->y == d->sidetot - 1) - v = -1; - - /* If either u or v is -2, it's on a boundary. In this - case, back up by one row/column and use the same - vector as the preceeding sub-edge. */ - - if(u < 0) { - u = multires_index_at_loc(d->face_index, d->x - 1, d->y, d, &d->edges_primary); - sub_v3_v3v3(t1, base->co, d->subco[u].co); + if(ccgdm->pbvh) { + BLI_pbvh_get_grid_updates(ccgdm->pbvh, 0, (void***)&faces, &totface); + + if(totface) { + ccgSubSurf_stitchFaces(ccgdm->ss, 0, faces, totface); + MEM_freeN(faces); + } + } } - else - sub_v3_v3v3(t1, d->subco[u].co, base->co); +} - if(v < 0) { - v = multires_index_at_loc(d->face_index, d->x, d->y - 1, d, &d->edges_primary); - sub_v3_v3v3(t2, base->co, d->subco[v].co); +DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob, + int useRenderParams, int isFinalCalc) +{ + Mesh *me= ob->data; + DerivedMesh *result; + CCGDerivedMesh *ccgdm; + DMGridData **gridData, **subGridData; + int lvl= multires_get_level(ob, mmd, useRenderParams); + int i, gridSize, numGrids; + + if(lvl == 0) + return dm; + + result = subsurf_dm_create_local(ob, dm, lvl, + mmd->simple, mmd->flags & eMultiresModifierFlag_ControlEdges); + + if(!local_mmd) { + ccgdm = (CCGDerivedMesh*)result; + + ccgdm->multires.ob = ob; + ccgdm->multires.mmd = mmd; + ccgdm->multires.local_mmd = local_mmd; + ccgdm->multires.lvl = lvl; + ccgdm->multires.totlvl = mmd->totlvl; + ccgdm->multires.modified = 0; + ccgdm->multires.update = multiresModifier_update; } - else - sub_v3_v3v3(t2, d->subco[v].co, base->co); - //printf("uu=%d, vv=%d\n", u, v); + numGrids = result->getNumGrids(result); + gridSize = result->getGridSize(result); + gridData = result->getGridData(result); - normalize_v3(t1); - normalize_v3(t2); - Mat3FromColVecs(mat, t1, t2, norm); + subGridData = MEM_callocN(sizeof(DMGridData*)*numGrids, "subGridData*"); - if(d->invert) { - invert_m3_m3(inv, mat); - copy_m3_m3(mat, inv); + for(i = 0; i < numGrids; i++) { + subGridData[i] = MEM_callocN(sizeof(DMGridData)*gridSize*gridSize, "subGridData"); + memcpy(subGridData[i], gridData[i], sizeof(DMGridData)*gridSize*gridSize); } -} -static void multires_displace(MultiresDisplacer *d, float co[3]) -{ - float disp[3], mat[3][3]; - float *data; - MVert *subco = &d->subco[d->subco_index]; + CustomData_external_read(&me->ldata, &me->id, CD_MASK_MDISPS, me->totloop); + multiresModifier_disp_run(result, ob->data, 0, 0, subGridData, mmd->totlvl); - if(!d->grid || !d->grid->disps) return; + for(i = 0; i < numGrids; i++) + MEM_freeN(subGridData[i]); + MEM_freeN(subGridData); - data = d->grid->disps[(d->y * d->spacing) * d->disp_st + (d->x * d->spacing)]; + return result; +} - if(d->invert) - sub_v3_v3v3(disp, co, subco->co); - else - copy_v3_v3(disp, data); +/**** Old Multires code **** +***************************/ +/* Adapted from sculptmode.c */ +static void old_mdisps_bilinear(float out[3], float (*disps)[3], int st, float u, float v) +{ + int x, y, x2, y2; + const int st_max = st - 1; + float urat, vrat, uopp; + float d[4][3], d2[2][3]; + + if(u < 0) + u = 0; + else if(u >= st) + u = st_max; + if(v < 0) + v = 0; + else if(v >= st) + v = st_max; + + x = floor(u); + y = floor(v); + x2 = x + 1; + y2 = y + 1; + + if(x2 >= st) x2 = st_max; + if(y2 >= st) y2 = st_max; + + urat = u - x; + vrat = v - y; + uopp = 1 - urat; - /* Apply ts matrix to displacement */ - calc_disp_mat(d, mat); - mul_m3_v3(mat, disp); + mul_v3_v3fl(d[0], disps[y * st + x], uopp); + mul_v3_v3fl(d[1], disps[y * st + x2], urat); + mul_v3_v3fl(d[2], disps[y2 * st + x], uopp); + mul_v3_v3fl(d[3], disps[y2 * st + x2], urat); - if(d->invert) { - copy_v3_v3(data, disp); - - } - else { - if(d->type == 4 || d->type == 5) - mul_v3_fl(disp, d->weight); - add_v3_v3v3(co, co, disp); - } + add_v3_v3v3(d2[0], d[0], d[1]); + add_v3_v3v3(d2[1], d[2], d[3]); + mul_v3_fl(d2[0], 1 - vrat); + mul_v3_fl(d2[1], vrat); - if(d->type == 2) { - if(d->sidendx == 0) - d->y -= 1; - else if(d->sidendx == 1) - d->x += 1; - else if(d->sidendx == 2) - d->y += 1; - else if(d->sidendx == 3) - d->x -= 1; - } - else if(d->type == 3) { - if(d->sidendx == 0) - d->y -= 1; - else if(d->sidendx == 1) - d->x += 1; - else if(d->sidendx == 2) - d->y += 1; - else if(d->sidendx == 3) - d->x -= 1; - } + add_v3_v3v3(out, d2[0], d2[1]); } -static void multiresModifier_disp_run(DerivedMesh *dm, MVert *subco, int invert) +static void old_mdisps_rotate(int S, int newside, int oldside, int x, int y, float *u, float *v) { - const int lvl = MultiresDM_get_lvl(dm); - const int gridFaces = multires_side_tot[lvl - 2] - 1; - const int edgeSize = multires_side_tot[lvl - 1] - 1; - MVert *mvert = CDDM_get_verts(dm); - MEdge *medge = MultiresDM_get_mesh(dm)->medge; - MFace *mface = MultiresDM_get_mesh(dm)->mface; - ListBase *map = MultiresDM_get_vert_face_map(dm); - Mesh *me = MultiresDM_get_mesh(dm); - MultiresDisplacer d; - int i, S, x, y; - - d.subco = subco; - d.subco_index = 0; + float offset = oldside*0.5f - 0.5f; - for(i = 0; i < me->totface; ++i) { - const int numVerts = mface[i].v4 ? 4 : 3; - - /* Center */ - multires_displacer_init(&d, dm, i, invert); - multires_displacer_anchor(&d, 1, 0); - multires_displace(&d, mvert->co); - ++mvert; - ++d.subco_index; - - /* Cross */ - for(S = 0; S < numVerts; ++S) { - multires_displacer_anchor(&d, 2, S); - for(x = 1; x < gridFaces; ++x) { - multires_displace(&d, mvert->co); - ++mvert; - ++d.subco_index; - } - } + if(S == 1) { *u= offset + x; *v = offset - y; } + if(S == 2) { *u= offset + y; *v = offset + x; } + if(S == 3) { *u= offset - x; *v = offset + y; } + if(S == 0) { *u= offset - y; *v = offset - x; } +} - /* Quarters */ - for(S = 0; S < numVerts; S++) { - multires_displacer_anchor(&d, 3, S); - for(y = 1; y < gridFaces; y++) { - for(x = 1; x < gridFaces; x++) { - multires_displace(&d, mvert->co); - ++mvert; - ++d.subco_index; - } - multires_displacer_jump(&d); +static void old_mdisps_convert(MFace *mface, MDisps *mdisp) +{ + int newlvl = log(sqrt(mdisp->totdisp)-1)/log(2); + int oldlvl = newlvl+1; + int oldside = multires_side_tot[oldlvl]; + int newside = multires_side_tot[newlvl]; + int nvert = (mface->v4)? 4: 3; + int newtotdisp = multires_grid_tot[newlvl]*nvert; + int x, y, S; + float (*disps)[3], (*out)[3], u, v; + + disps = MEM_callocN(sizeof(float) * 3 * newtotdisp, "multires disps"); + + out = disps; + for(S = 0; S < nvert; S++) { + for(y = 0; y < newside; ++y) { + for(x = 0; x < newside; ++x, ++out) { + old_mdisps_rotate(S, newside, oldside, x, y, &u, &v); + old_mdisps_bilinear(*out, mdisp->disps, oldside, u, v); + + if(S == 1) { (*out)[1]= -(*out)[1]; } + else if(S == 2) { SWAP(float, (*out)[0], (*out)[1]); } + else if(S == 3) { (*out)[0]= -(*out)[0]; } + else if(S == 0) { SWAP(float, (*out)[0], (*out)[1]); (*out)[0]= -(*out)[0]; (*out)[1]= -(*out)[1]; }; } } } - for(i = 0; i < me->totedge; ++i) { - const MEdge *e = &medge[i]; - for(x = 1; x < edgeSize; ++x) { - IndexNode *n1, *n2; - int numFaces = 0; - for(n1 = map[e->v1].first; n1; n1 = n1->next) { - for(n2 = map[e->v2].first; n2; n2 = n2->next) { - if(n1->index == n2->index) - ++numFaces; - } - } - multires_displacer_weight(&d, 1.0f / numFaces); - /* TODO: Better to have these loops outside the x loop */ - for(n1 = map[e->v1].first; n1; n1 = n1->next) { - for(n2 = map[e->v2].first; n2; n2 = n2->next) { - if(n1->index == n2->index) { - multires_displacer_init(&d, dm, n1->index, invert); - multires_displacer_anchor_edge(&d, e->v1, e->v2, x); - multires_displace(&d, mvert->co); - } - } - } - ++mvert; - ++d.subco_index; - } - } - - for(i = 0; i < me->totvert; ++i) { - IndexNode *n; - multires_displacer_weight(&d, 1.0f / BLI_countlist(&map[i])); - for(n = map[i].first; n; n = n->next) { - multires_displacer_init(&d, dm, n->index, invert); - multires_displacer_anchor_vert(&d, i); - multires_displace(&d, mvert->co); - } - ++mvert; - ++d.subco_index; - } + MEM_freeN(mdisp->disps); - if(!invert) - CDDM_calc_normals(dm); + mdisp->totdisp= newtotdisp; + mdisp->disps= disps; } -static void multiresModifier_update(DerivedMesh *dm) +void multires_load_old_250(Mesh *me) { - Object *ob; - Mesh *me; - MDisps *mdisps; + MDisps *mdisps, *mdisps2; + MFace *mf; + int i, j, k; - ob = MultiresDM_get_object(dm); - me = MultiresDM_get_mesh(dm); - mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS); + mdisps= CustomData_get_layer(&me->fdata, CD_MDISPS); if(mdisps) { - const int lvl = MultiresDM_get_lvl(dm); - const int totlvl = MultiresDM_get_totlvl(dm); + for(i=0; i<me->totface; i++) + if(mdisps[i].totdisp) + old_mdisps_convert(&me->mface[i], &mdisps[i]); - if(lvl < totlvl) { - /* Propagate disps upwards */ - DerivedMesh *final, *subco_dm, *orig; - MVert *verts_new = NULL, *cur_lvl_orig_verts = NULL; - MultiresModifierData mmd; - int i; - - orig = CDDM_from_mesh(me, NULL); + CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop); + mdisps2 = CustomData_get_layer(&me->ldata, CD_MDISPS); + + k = 0; + mf = me->mface; + for (i=0; i<me->totface; i++, mf++) { + int nvert = mf->v4 ? 4 : 3; + int totdisp = mdisps[i].totdisp / nvert; - /* Regenerate the current level's vertex coordinates - (includes older displacements but not new sculpts) */ - mmd.totlvl = totlvl; - mmd.lvl = lvl; - subco_dm = multires_dm_create_from_derived(&mmd, 1, orig, ob, 0, 0); - cur_lvl_orig_verts = CDDM_get_verts(subco_dm); - - /* Subtract the original vertex cos from the new vertex cos */ - verts_new = CDDM_get_verts(dm); - for(i = 0; i < dm->getNumVerts(dm); ++i) - sub_v3_v3v3(verts_new[i].co, verts_new[i].co, cur_lvl_orig_verts[i].co); - - final = multires_subdisp_pre(dm, totlvl - lvl, 0); - - multires_subdisp(orig, ob, final, lvl, totlvl, dm->getNumVerts(dm), dm->getNumEdges(dm), - dm->getNumTessFaces(dm), 1); + for (j=0; j < mf->v4 ? 4 : 3; j++, k++) { + mdisps2[k].disps = MEM_callocN(sizeof(float)*3*totdisp, "multires disp in conversion"); + mdisps2[k].totdisp = totdisp; + memcpy(mdisps2[k].disps, mdisps[i].disps + totdisp*j, totdisp); + } - subco_dm->release(subco_dm); - orig->release(orig); } - else - multiresModifier_disp_run(dm, MultiresDM_get_subco(dm), 1); - } -} - -void multires_mark_as_modified(struct Object *ob) -{ - if(ob && ob->derivedFinal) { - MultiresDM_mark_as_modified(ob->derivedFinal); - } -} - -void multires_force_update(Object *ob) -{ - if(ob && ob->derivedFinal) { - ob->derivedFinal->needsFree =1; - ob->derivedFinal->release(ob->derivedFinal); - ob->derivedFinal = NULL; } } -struct DerivedMesh *multires_dm_create_from_derived(MultiresModifierData *mmd, int local_mmd, DerivedMesh *dm, Object *ob, - int useRenderParams, int isFinalCalc) -{ - SubsurfModifierData smd; - MultiresSubsurf ms; - DerivedMesh *result; - int i; - - ms.mmd = mmd; - ms.ob = ob; - ms.local_mmd = local_mmd; - - memset(&smd, 0, sizeof(SubsurfModifierData)); - smd.levels = smd.renderLevels = mmd->lvl - 1; - smd.flags |= eSubsurfModifierFlag_SubsurfUv; - - result = subsurf_make_derived_from_derived_with_multires(dm, &smd, &ms, useRenderParams, NULL, isFinalCalc, 0); - for(i = 0; i < result->getNumVerts(result); ++i) - MultiresDM_get_subco(result)[i] = CDDM_get_verts(result)[i]; - multiresModifier_disp_run(result, MultiresDM_get_subco(result), 0); - MultiresDM_set_update(result, multiresModifier_update); - - return result; -} - -/**** Old Multires code **** -***************************/ - /* Does not actually free lvl itself */ static void multires_free_level(MultiresLevel *lvl) { @@ -1419,15 +986,75 @@ static void multires_load_old_faces(ListBase **fmap, ListBase **emap, MultiresLe } } +static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert) +{ + CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; + CCGSubSurf *ss = ccgdm->ss; + DMGridData *vd; + int index; + int totvert, totedge, totface; + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int i = 0; + + totface = ccgSubSurf_getNumFaces(ss); + for(index = 0; index < totface; index++) { + CCGFace *f = ccgdm->faceMap[index].face; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); + + vd= ccgSubSurf_getFaceCenterData(f); + copy_v3_v3(vd->co, mvert[i].co); + i++; + + for(S = 0; S < numVerts; S++) { + for(x = 1; x < gridSize - 1; x++, i++) { + vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); + copy_v3_v3(vd->co, mvert[i].co); + } + } + + for(S = 0; S < numVerts; S++) { + for(y = 1; y < gridSize - 1; y++) { + for(x = 1; x < gridSize - 1; x++, i++) { + vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y); + copy_v3_v3(vd->co, mvert[i].co); + } + } + } + } + + totedge = ccgSubSurf_getNumEdges(ss); + for(index = 0; index < totedge; index++) { + CCGEdge *e = ccgdm->edgeMap[index].edge; + int x; + + for(x = 1; x < edgeSize - 1; x++, i++) { + vd= ccgSubSurf_getEdgeData(ss, e, x); + copy_v3_v3(vd->co, mvert[i].co); + } + } + + totvert = ccgSubSurf_getNumVerts(ss); + for(index = 0; index < totvert; index++) { + CCGVert *v = ccgdm->vertMap[index].vert; + + vd= ccgSubSurf_getVertData(ss, v); + copy_v3_v3(vd->co, mvert[i].co); + i++; + } + + ccgSubSurf_updateToFaces(ss, 0, NULL, 0); +} + /* Loads a multires object stored in the old Multires struct into the new format */ -void multires_load_old(DerivedMesh *dm, Multires *mr) +static void multires_load_old_dm(DerivedMesh *dm, Mesh *me, int totlvl) { MultiresLevel *lvl, *lvl1; + Multires *mr= me->mr; MVert *vsrc, *vdst; int src, dst; - int totlvl = MultiresDM_get_totlvl(dm); - int st = multires_side_tot[totlvl - 2] - 1; - int extedgelen = multires_side_tot[totlvl - 1] - 2; + int st = multires_side_tot[totlvl - 1] - 1; + int extedgelen = multires_side_tot[totlvl] - 2; int *vvmap; // inorder for dst, map to src int crossedgelen; int i, j, s, x, totvert, tottri, totquad; @@ -1435,7 +1062,7 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) src = 0; dst = 0; vsrc = mr->verts; - vdst = CDDM_get_verts(dm); + vdst = dm->getVertArray(dm); totvert = dm->getNumVerts(dm); vvmap = MEM_callocN(sizeof(int) * totvert, "multires vvmap"); @@ -1454,9 +1081,9 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) lvl = lvl1->next; for(j = 2; j <= mr->level_count; ++j) { - int base = multires_side_tot[totlvl - j] - 2; - int skip = multires_side_tot[totlvl - j + 1] - 1; - int st = multires_side_tot[j - 2] - 1; + int base = multires_side_tot[totlvl - j + 1] - 2; + int skip = multires_side_tot[totlvl - j + 2] - 1; + int st = multires_side_tot[j - 1] - 1; for(x = 0; x < st; ++x) vvmap[ldst + base + x * skip] = lsrc + st * i + x; @@ -1483,7 +1110,7 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) /* Face edge cross */ tottri = totquad = 0; - crossedgelen = multires_side_tot[totlvl - 2] - 2; + crossedgelen = multires_side_tot[totlvl - 1] - 2; dst = 0; for(i = 0; i < lvl1->totface; ++i) { int sides = lvl1->faces[i].v[3] ? 4 : 3; @@ -1492,8 +1119,8 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) ++dst; for(j = 3; j <= mr->level_count; ++j) { - int base = multires_side_tot[totlvl - j] - 2; - int skip = multires_side_tot[totlvl - j + 1] - 1; + int base = multires_side_tot[totlvl - j + 1] - 2; + int skip = multires_side_tot[totlvl - j + 2] - 1; int st = pow(2, j - 2); int st2 = pow(2, j - 3); int lsrc = lvl->prev->totvert; @@ -1541,8 +1168,8 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) int ldst = dst + 1 + sides * (st - 1); for(s = 0; s < sides; ++s) { - int st2 = multires_side_tot[totlvl - 2] - 2; - int st3 = multires_side_tot[totlvl - 3] - 2; + int st2 = multires_side_tot[totlvl - 1] - 2; + int st3 = multires_side_tot[totlvl - 2] - 2; int st4 = st3 == 0 ? 1 : (st3 + 1) / 2; int mid = ldst + st2 * st3 + st3; int cv = lvl1->faces[j].v[s]; @@ -1582,4 +1209,64 @@ void multires_load_old(DerivedMesh *dm, Multires *mr) copy_v3_v3(vdst[i].co, vsrc[vvmap[i]].co); MEM_freeN(vvmap); + + multires_mvert_to_ss(dm, vdst); +} + + +void multires_load_old(Object *ob, Mesh *me) +{ + MultiresLevel *lvl; + ModifierData *md; + MultiresModifierData *mmd; + DerivedMesh *dm, *orig; + int i; + + /* Load original level into the mesh */ + lvl = me->mr->levels.first; + CustomData_free_layers(&me->vdata, CD_MVERT, lvl->totvert); + CustomData_free_layers(&me->edata, CD_MEDGE, lvl->totedge); + CustomData_free_layers(&me->fdata, CD_MFACE, lvl->totface); + me->totvert = lvl->totvert; + me->totedge = lvl->totedge; + me->totface = lvl->totface; + me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); + me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); + me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); + memcpy(me->mvert, me->mr->verts, sizeof(MVert) * me->totvert); + for(i = 0; i < me->totedge; ++i) { + me->medge[i].v1 = lvl->edges[i].v[0]; + me->medge[i].v2 = lvl->edges[i].v[1]; + } + for(i = 0; i < me->totface; ++i) { + me->mface[i].v1 = lvl->faces[i].v[0]; + me->mface[i].v2 = lvl->faces[i].v[1]; + me->mface[i].v3 = lvl->faces[i].v[2]; + me->mface[i].v4 = lvl->faces[i].v[3]; + } + + /* Add a multires modifier to the object */ + md = ob->modifiers.first; + while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) + md = md->next; + mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires); + BLI_insertlinkbefore(&ob->modifiers, md, mmd); + + for(i = 0; i < me->mr->level_count - 1; ++i) + multiresModifier_subdivide(mmd, ob, 1, 0); + + mmd->lvl = mmd->totlvl; + orig = CDDM_from_mesh(me, NULL); + dm = multires_dm_create_from_derived(mmd, 0, orig, ob, 0, 0); + + multires_load_old_dm(dm, me, mmd->totlvl+1); + + multires_dm_mark_as_modified(dm); + dm->release(dm); + orig->release(orig); + + /* Remove the old multires */ + multires_free(me->mr); + me->mr= NULL; } + diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 9efbf7699c6..1daf3a0df2f 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -767,6 +767,17 @@ void nodeGroupSocketUseFlags(bNodeTree *ngroup) } } +/* finds a node based on its name */ +bNode *nodeFindNodebyName(bNodeTree *ntree, const char *name) +{ + bNode *node=NULL; + + for(node= ntree->nodes.first; node; node= node->next) { + if (strcmp(name, node->name) == 0) + break; + } + return node; +} /* finds a node based on given socket */ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockindex) @@ -1675,7 +1686,9 @@ void ntreeSocketUseFlags(bNodeTree *ntree) /* tag all thats in use */ for(link= ntree->links.first; link; link= link->next) { - link->fromsock->flag |= SOCK_IN_USE; + + if(link->fromsock) // FIXME, see below + link->fromsock->flag |= SOCK_IN_USE; if(link->tosock) // FIXME This can be NULL, when dragging a new link in the UI, should probably copy the node tree for preview render - campbell link->tosock->flag |= SOCK_IN_USE; } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a8acdf36461..b61ada3cf9b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -229,14 +229,6 @@ void free_sculptsession(SculptSession **ssp) { if(ssp && *ssp) { SculptSession *ss = *ssp; - if(ss->projverts) - MEM_freeN(ss->projverts); - - if(ss->fmap) - MEM_freeN(ss->fmap); - - if(ss->fmap_mem) - MEM_freeN(ss->fmap_mem); if(ss->texcache) MEM_freeN(ss->texcache); @@ -244,8 +236,8 @@ void free_sculptsession(SculptSession **ssp) if(ss->layer_disps) MEM_freeN(ss->layer_disps); - if(ss->mesh_co_orig) - MEM_freeN(ss->mesh_co_orig); + if(ss->layer_co) + MEM_freeN(ss->layer_co); MEM_freeN(ss); @@ -563,6 +555,17 @@ void unlink_object(Scene *scene, Object *ob) if(sce->id.lib==NULL) { if(sce->camera==ob) sce->camera= NULL; if(sce->toolsettings->skgen_template==ob) sce->toolsettings->skgen_template = NULL; + +#ifdef DURIAN_CAMERA_SWITCH + { + TimeMarker *m; + + for (m= sce->markers.first; m; m= m->next) { + if(m->camera==ob) + m->camera= NULL; + } + } +#endif } sce= sce->id.next; } @@ -742,12 +745,12 @@ float dof_camera(Object *ob) if (cam->dof_ob) { /* too simple, better to return the distance on the view axis only * return len_v3v3(ob->obmat[3], cam->dof_ob->obmat[3]); */ - float mat[4][4], obmat[4][4]; + float mat[4][4], imat[4][4], obmat[4][4]; copy_m4_m4(obmat, ob->obmat); normalize_m4(obmat); - invert_m4_m4(ob->imat, obmat); - mul_m4_m4m4(mat, cam->dof_ob->obmat, ob->imat); + invert_m4_m4(imat, obmat); + mul_m4_m4m4(mat, cam->dof_ob->obmat, imat); return (float)fabs(mat[3][2]); } return cam->YF_dofdist; @@ -796,7 +799,7 @@ void *add_lamp(char *name) la->sun_intensity = 1.0f; la->skyblendtype= MA_RAMP_ADD; la->skyblendfac= 1.0f; - la->sky_colorspace= BLI_CS_CIE; + la->sky_colorspace= BLI_XYZ_CIE; la->sky_exposure= 1.0f; curvemapping_initialize(la->curfalloff); @@ -963,24 +966,27 @@ Object *add_only_object(int type, char *name) /* default object vars */ ob->type= type; - /* ob->transflag= OB_QUAT; */ - -#if 0 /* not used yet */ - unit_qt(ob->quat); - unit_qt(ob->dquat); -#endif - + ob->col[0]= ob->col[1]= ob->col[2]= 1.0; ob->col[3]= 1.0; - - ob->loc[0]= ob->loc[1]= ob->loc[2]= 0.0; - ob->rot[0]= ob->rot[1]= ob->rot[2]= 0.0; + ob->size[0]= ob->size[1]= ob->size[2]= 1.0; + + /* objects should default to having Euler XYZ rotations, + * but rotations default to quaternions + */ + ob->rotmode= ROT_MODE_EUL; + /* axis-angle must not have a 0,0,0 axis, so set y-axis as default... */ + ob->rotAxis[1]= ob->drotAxis[1]= 1.0f; + /* quaternions should be 1,0,0,0 by default.... */ + ob->quat[0]= ob->dquat[0]= 1.0f; + /* rotation locks should be 4D for 4 component rotations by default... */ + ob->protectflag = OB_LOCK_ROT4D; unit_m4(ob->constinv); unit_m4(ob->parentinv); unit_m4(ob->obmat); - ob->dt= OB_SHADED; + ob->dt= OB_TEXTURE; ob->empty_drawtype= OB_ARROWS; ob->empty_drawsize= 1.0; @@ -993,11 +999,6 @@ Object *add_only_object(int type, char *name) ob->upflag= OB_POSZ; } -#if 0 // XXX old animation system - ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT; - ob->ipowin= ID_OB; /* the ipowin shown */ -#endif // XXX old animation system - ob->dupon= 1; ob->dupoff= 0; ob->dupsta= 1; ob->dupend= 100; ob->dupfacesca = 1.0; @@ -1039,13 +1040,6 @@ Object *add_object(struct Scene *scene, int type) ob->lay= scene->lay; - /* objects should default to having Euler XYZ rotations, - * but rotations default to quaternions - */ - ob->rotmode= ROT_MODE_EUL; - /* axis-angle must not have a 0,0,0 axis, so set y-axis as default... */ - ob->rotAxis[1]= ob->drotAxis[1]= 1.0f; - base= scene_add_base(scene, ob); scene_select_base(scene, base); ob->recalc |= OB_RECALC; @@ -1625,6 +1619,32 @@ void object_rot_to_mat3(Object *ob, float mat[][3]) mul_m3_m3m3(mat, dmat, rmat); } +void object_mat3_to_rot(Object *ob, float mat[][3], int use_compat) +{ + if (ob->rotmode == ROT_MODE_QUAT) + mat3_to_quat(ob->quat, mat); + else if (ob->rotmode == ROT_MODE_AXISANGLE) + mat3_to_axis_angle(ob->rotAxis, &ob->rotAngle, mat); + else { + if(use_compat) { + float eul[3]; + VECCOPY(eul, ob->rot); + mat3_to_compatible_eulO(ob->rot, eul, ob->rotmode, mat); + } + else + mat3_to_eulO(ob->rot, ob->rotmode, mat); + } +} + +void object_apply_mat4(Object *ob, float mat[][4]) +{ + float mat3[3][3]; + VECCOPY(ob->loc, mat[3]); + mat4_to_size(ob->size, mat); + copy_m3_m4(mat3, mat); + object_mat3_to_rot(ob, mat3, 0); +} + void object_to_mat3(Object *ob, float mat[][3]) /* no parent */ { float smat[3][3]; @@ -1682,10 +1702,10 @@ static void ob_parcurve(Scene *scene, Object *ob, Object *par, float mat[][4]) /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, * but this will only work if it actually is animated... * - * we firstly calculate the modulus of cu->ctime/cu->pathlen to clamp ctime within the 0.0 to 1.0 times pathlen - * range, then divide this (the modulus) by pathlen to get a value between 0.0 and 1.0 + * we divide the curvetime calculated in the previous step by the length of the path, to get a time + * factor, which then gets clamped to lie within 0.0 - 1.0 range */ - ctime= fmod(cu->ctime, cu->pathlen) / cu->pathlen; + ctime= cu->ctime / cu->pathlen; CLAMP(ctime, 0.0, 1.0); } else { @@ -1787,13 +1807,15 @@ static void give_parvert(Object *par, int nr, float *vec) DerivedMesh *dm = par->derivedFinal; if(dm) { - int i, count = 0, numVerts = dm->getNumVerts(dm); + int i, count = 0, vindex, numVerts = dm->getNumVerts(dm); int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); float co[3]; /* get the average of all verts with (original index == nr) */ - for(i = 0; i < numVerts; ++i, ++index) { - if(*index == nr) { + for(i = 0; i < numVerts; ++i) { + vindex= (index)? *index: i; + + if(vindex == nr) { dm->getVertCo(dm, i, co); add_v3_v3v3(vec, vec, co); count++; @@ -2365,6 +2387,9 @@ void object_handle_update(Scene *scene, Object *ob) } if(ob->recalc & OB_RECALC_DATA) { + ID *data_id= (ID *)ob->data; + AnimData *adt= BKE_animdata_from_id(data_id); + float ctime= (float)scene->r.cfra; // XXX this is bad... if (G.f & G_DEBUG) printf("recalcdata %s\n", ob->id.name+2); @@ -2386,10 +2411,6 @@ void object_handle_update(Scene *scene, Object *ob) makeDispListCurveTypes(scene, ob, 0); } else if(ELEM(ob->type, OB_CAMERA, OB_LAMP)) { - ID *data_id= (ID *)ob->data; - AnimData *adt= BKE_animdata_from_id(data_id); - float ctime= (float)scene->r.cfra; // XXX this is bad... - /* evaluate drivers */ BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS); } @@ -2402,6 +2423,9 @@ void object_handle_update(Scene *scene, Object *ob) if(ob->pose==NULL || (ob->pose->flag & POSE_RECALC)) armature_rebuild_pose(ob, ob->data); + /* evaluate drivers */ + BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS); + if(ob->id.lib && ob->proxy_from) { copy_pose_result(ob->pose, ob->proxy_from->pose); // printf("pose proxy copy, lib ob %s proxy %s\n", ob->id.name, ob->proxy_from->id.name); diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index 27fcfa8b9cb..4fe63a966be 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -175,6 +175,8 @@ void paint_init(Paint *p, const char col[3]) memcpy(p->paint_cursor_col, col, 3); p->paint_cursor_col[3] = 128; + + p->flags |= PAINT_SHOW_BRUSH; } void free_paint(Paint *paint) diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 68846966cb3..55b50499e6a 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -791,7 +791,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) totface= dm->getNumTessFaces(dm); totorigface= me->totface; - if(totface == 0 || totorigface == 0 || origindex == NULL) + if(totface == 0 || totorigface == 0) return tot; facearea= MEM_callocN(sizeof(float)*totorigface, "SimplifyFaceArea"); @@ -808,14 +808,14 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) /* compute number of children per original face */ for(a=0; a<tot; a++) { - b= origindex[ctx->index[a]]; + b= (origindex)? origindex[ctx->index[a]]: ctx->index[a]; if(b != -1) elems[b].totchild++; } /* compute areas and centers of original faces */ for(mf=mface, a=0; a<totface; a++, mf++) { - b= origindex[a]; + b= (origindex)? origindex[a]: a; if(b != -1) { VECCOPY(co1, mvert[mf->v1].co); @@ -911,7 +911,7 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot) skipped= 0; for(a=0, newtot=0; a<tot; a++) { - b= origindex[ctx->index[a]]; + b= (origindex)? origindex[ctx->index[a]]: ctx->index[a]; if(b != -1) { if(elems[b].curchild++ < ceil(elems[b].lambda*elems[b].totchild)) { ctx->index[newtot]= ctx->index[a]; @@ -944,7 +944,7 @@ int psys_render_simplify_params(ParticleSystem *psys, ChildParticle *cpa, float if(!data->dosimplify) return 0; - b= data->origindex[cpa->num]; + b= (data->origindex)? data->origindex[cpa->num]: cpa->num; if(b == -1) return 0; @@ -2333,6 +2333,7 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c ctx->totparent= totparent; ctx->parent_pass= 0; ctx->cfra= cfra; + ctx->editupdate= editupdate; psys->lattice = psys_get_lattice(&ctx->sim); @@ -2444,7 +2445,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle mul_m4_v3(ob->obmat,cpa_1st); } - pa = psys->particles + cpa->parent; + pa = psys->particles + cpa->pa[0]; psys_mat_hair_to_global(ob, ctx->sim.psmd->dm, psys->part->from, pa, hairmat); @@ -2616,6 +2617,9 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle get_strand_normal(ctx->ma, ornor, cur_length, (state-1)->vel); } + if(k == ctx->steps) + VECSUB(state->vel,state->co,(state-1)->co); + /* check if path needs to be cut before actual end of data points */ if(k){ VECSUB(dvec,state->co,(state-1)->co); @@ -3269,14 +3273,14 @@ void psys_mat_hair_to_global(Object *ob, DerivedMesh *dm, short from, ParticleDa /************************************************/ /* ParticleSettings handling */ /************************************************/ -void object_add_particle_system(Scene *scene, Object *ob) +ModifierData *object_add_particle_system(Scene *scene, Object *ob, char *name) { ParticleSystem *psys; ModifierData *md; ParticleSystemModifierData *psmd; if(!ob || ob->type != OB_MESH) - return; + return NULL; psys = ob->particlesystem.first; for(; psys; psys=psys->next) @@ -3294,7 +3298,11 @@ void object_add_particle_system(Scene *scene, Object *ob) strcpy(psys->name, "ParticleSystem"); md= modifier_new(eModifierType_ParticleSystem); - sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + + if(name) BLI_strncpy(md->name, name, sizeof(md->name)); + else sprintf(md->name, "ParticleSystem %i", BLI_countlist(&ob->particlesystem)); + modifier_unique_name(&ob->modifiers, md); + psmd= (ParticleSystemModifierData*) md; psmd->psys=psys; BLI_addtail(&ob->modifiers, md); @@ -3305,6 +3313,8 @@ void object_add_particle_system(Scene *scene, Object *ob) DAG_scene_sort(scene); DAG_id_flush_update(&ob->id, OB_RECALC_DATA); + + return md; } void object_remove_particle_system(Scene *scene, Object *ob) { @@ -4060,7 +4070,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta else{ if(cpa){ ParticleKey *key1; - float t = (cfra - pa->time + pa->loop * pa->lifetime) / pa->lifetime; + float t = (cfra - pa->time) / pa->lifetime; key1=&pa->state; offset_child(cpa, key1, state, part->childflat, part->childrad); diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 0f8e70054f6..670db6157ff 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -170,6 +170,12 @@ static void realloc_particles(ParticleSimulationData *sim, int new_totpart) PARTICLE_P; int totpart, totsaved = 0; + if(psys->edit && psys->free_edit) { + psys->free_edit(psys->edit); + psys->edit = NULL; + psys->free_edit = NULL; + } + if(new_totpart<0) { if(part->distr==PART_DISTR_GRID && part->from != PART_FROM_VERT) { totpart= part->grid_res; @@ -287,12 +293,12 @@ void psys_calc_dmcache(Object *ob, DerivedMesh *dm, ParticleSystem *psys) if(psys->part->from == PART_FROM_VERT) { totdmelem= dm->getNumVerts(dm); totelem= me->totvert; - origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX); + origindex= dm->getVertDataArray(dm, CD_ORIGINDEX); } else { /* FROM_FACE/FROM_VOLUME */ totdmelem= dm->getNumTessFaces(dm); totelem= me->totface; - origindex= DM_get_face_data_layer(dm, CD_ORIGINDEX); + origindex= dm->getTessFaceDataArray(dm, CD_ORIGINDEX); } nodedmelem= MEM_callocN(sizeof(LinkNode)*totdmelem, "psys node elems"); @@ -389,7 +395,7 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys) pa->fuv[1]=min[1]+(float)j*d; pa->fuv[2]=min[2]+(float)k*d; pa->flag |= PARS_UNEXIST; - pa->loop=0; /* abused in volume calculation */ + pa->hair_index=0; /* abused in volume calculation */ } } } @@ -451,7 +457,7 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys) if(from==PART_FROM_FACE) (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST; else /* store number of intersections */ - (pa+(int)(lambda*size[a])*a0mul)->loop++; + (pa+(int)(lambda*size[a])*a0mul)->hair_index++; } if(mface->v4){ @@ -461,20 +467,20 @@ static void distribute_particles_in_grid(DerivedMesh *dm, ParticleSystem *psys) if(from==PART_FROM_FACE) (pa+(int)(lambda*size[a])*a0mul)->flag &= ~PARS_UNEXIST; else - (pa+(int)(lambda*size[a])*a0mul)->loop++; + (pa+(int)(lambda*size[a])*a0mul)->hair_index++; } } } if(from==PART_FROM_VOLUME){ - int in=pa->loop%2; - if(in) pa->loop++; + int in=pa->hair_index%2; + if(in) pa->hair_index++; for(i=0; i<size[0]; i++){ - if(in || (pa+i*a0mul)->loop%2) + if(in || (pa+i*a0mul)->hair_index%2) (pa+i*a0mul)->flag &= ~PARS_UNEXIST; /* odd intersections == in->out / out->in */ /* even intersections -> in stays same */ - in=(in + (pa+i*a0mul)->loop) % 2; + in=(in + (pa+i*a0mul)->hair_index) % 2; } } } @@ -948,7 +954,8 @@ static int psys_threads_init_distribution(ParticleThread *threads, Scene *scene, if(totpart==0) return 0; - if (!finaldm->deformedOnly && !CustomData_has_layer( &finaldm->faceData, CD_ORIGINDEX ) ) { + if (!finaldm->deformedOnly && !finaldm->getTessFaceDataArray(finaldm, CD_ORIGINDEX)) { + printf("Can't create particles with the current modifier stack, disable destructive modifiers\n"); // XXX error("Can't paint with the current modifier stack, disable destructive modifiers"); return 0; } @@ -1583,7 +1590,7 @@ void initialize_particle(ParticleSimulationData *sim, ParticleData *pa, int p) pa->flag &= ~PARS_UNEXIST; } - pa->loop=0; + pa->hair_index=0; /* we can't reset to -1 anymore since we've figured out correct index in distribute_particles */ /* usage other than straight after distribute has to handle this index by itself - jahka*/ //pa->num_dmcache = DMCACHE_NOTFOUND; /* assume we dont have a derived mesh face */ @@ -2267,12 +2274,13 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra EffectedPoint epoint; ParticleKey states[5], tkey; float timestep = psys_get_timestep(sim); - float force[3],impulse[3],dx[4][3],dv[4][3]; + float force[3],impulse[3],dx[4][3],dv[4][3],oldpos[3]; float dtime=dfra*timestep, time, pa_mass=part->mass, fac, fra=sim->psys->cfra; int i, steps=1; /* maintain angular velocity */ VECCOPY(pa->state.ave,pa->prev_state.ave); + VECCOPY(oldpos,pa->state.co); if(part->flag & PART_SIZEMASS) pa_mass*=pa->size; @@ -2287,6 +2295,9 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra case PART_INT_RK4: steps=4; break; + case PART_INT_VERLET: + steps=1; + break; } copy_particle_key(states,&pa->state,1); @@ -2392,6 +2403,13 @@ static void apply_particle_forces(ParticleSimulationData *sim, int p, float dfra VECADDFAC(pa->state.vel,pa->state.vel,dv[3],1.0f/6.0f); } break; + case PART_INT_VERLET: /* Verlet integration */ + VECADDFAC(pa->state.vel,pa->state.vel,force,dtime); + VECADDFAC(pa->state.co,pa->state.co,pa->state.vel,dtime); + + VECSUB(pa->state.vel,pa->state.co,oldpos); + mul_v3_fl(pa->state.vel,1.0f/dtime); + break; } } @@ -2914,6 +2932,8 @@ static void psys_update_path_cache(ParticleSimulationData *sim, float cfra) psys_find_parents(sim); } } + else + psys_free_children(psys); } if((part->type==PART_HAIR || psys->flag&PSYS_KEYED || psys->pointcache->flag & PTCACHE_BAKED)==0) @@ -3201,14 +3221,6 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) pa->size *= 1.0f - part->randsize * PSYS_FRAND(p + 1); reset_particle(sim, pa, dtime, cfra); - - if(cfra > pa->time && part->flag & PART_LOOP && part->type!=PART_HAIR){ - pa->loop = (short)((cfra-pa->time)/pa->lifetime); - pa->alive = PARS_UNBORN; - } - else{ - pa->loop = 0; - } } if(vg_size) @@ -3262,7 +3274,7 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) //if(psys->reactevents.first && ELEM(pa->alive,PARS_DEAD,PARS_KILLED)==0) // react_to_events(psys,p); - birthtime = pa->time + pa->loop * pa->lifetime; + birthtime = pa->time; dietime = birthtime + pa->lifetime; pa_dfra = dfra; @@ -3321,15 +3333,8 @@ static void dynamics_step(ParticleSimulationData *sim, float cfra) if(pa->alive == PARS_DYING){ //push_reaction(ob,psys,p,PART_EVENT_DEATH,&pa->state); - if(part->flag & PART_LOOP && part->type!=PART_HAIR){ - pa->loop++; - reset_particle(sim, pa, 0.0, cfra); - pa->alive=PARS_ALIVE; - } - else{ - pa->alive=PARS_DEAD; - pa->state.time=pa->dietime; - } + pa->alive=PARS_DEAD; + pa->state.time=pa->dietime; } else pa->state.time=cfra; @@ -3380,13 +3385,8 @@ static void cached_step(ParticleSimulationData *sim, float cfra) psys->lattice= psys_get_lattice(sim); - if(part->flag & PART_LOOP && part->type!=PART_HAIR) - pa->loop = (short)((cfra - pa->time) / pa->lifetime); - else - pa->loop = 0; - - birthtime = pa->time + pa->loop * pa->lifetime; - dietime = birthtime + (1 + pa->loop) * (pa->dietime - pa->time); + birthtime = pa->time; + dietime = pa->dietime; /* update alive status and push events */ if(pa->time > cfra) { diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index c2798b4a746..7b2cf72e311 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -2232,6 +2232,7 @@ void BKE_ptcache_quick_cache_all(Scene *scene) baker.break_test=NULL; baker.pid=NULL; baker.progressbar=NULL; + baker.progressend=NULL; baker.progresscontext=NULL; baker.render=0; baker.anim_init = 0; @@ -2361,6 +2362,9 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) break; } + if (baker->progressend) + baker->progressend(baker->progresscontext); + /* clear baking flag */ if(pid) { cache->flag &= ~(PTCACHE_BAKING|PTCACHE_REDO_NEEDED); @@ -2400,7 +2404,7 @@ void BKE_ptcache_make_cache(PTCacheBaker* baker) scene->r.framelen = frameleno; CFRA = cfrao; - + if(bake) /* already on cfra unless baking */ scene_update_for_newframe(scene, scene->lay); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 91fd0bac400..eadeac585b2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -29,6 +29,7 @@ * ***** END GPL LICENSE BLOCK ***** */ +#include <stddef.h> #include <stdio.h> #include <string.h> @@ -77,8 +78,9 @@ #include "BKE_node.h" #include "BKE_object.h" #include "BKE_paint.h" +#include "BKE_pointcache.h" #include "BKE_scene.h" -#include "BKE_sequence.h" +#include "BKE_sequencer.h" #include "BKE_world.h" #include "BKE_utildefines.h" @@ -247,7 +249,12 @@ void free_scene(Scene *sce) /* do not free objects! */ if(sce->gpd) { +#if 0 // removed since this can be invalid memory when freeing everything + // since the grease pencil data is free'd before the scene. + // since grease pencil data is not (yet?), shared between objects + // its probably safe not to do this, some save and reload will free this. sce->gpd->id.us--; +#endif sce->gpd= NULL; } @@ -348,7 +355,7 @@ Scene *add_scene(char *name) sce->r.bake_normal_space= R_BAKE_SPACE_TANGENT; sce->r.scemode= R_DOCOMP|R_DOSEQ|R_EXTENSION; - sce->r.stamp= R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_SCENE|R_STAMP_CAMERA; + sce->r.stamp= R_STAMP_TIME|R_STAMP_FRAME|R_STAMP_DATE|R_STAMP_SCENE|R_STAMP_CAMERA|R_STAMP_RENDERTIME; sce->r.threads= 1; @@ -416,6 +423,7 @@ Scene *add_scene(char *name) pset->brushtype= PE_BRUSH_NONE; pset->draw_step= 2; pset->fade_frames= 2; + pset->selectmode= SCE_SELECT_PATH; for(a=0; a<PE_TOT_BRUSH; a++) { pset->brush[a].strength= 50; pset->brush[a].size= 50; @@ -695,6 +703,47 @@ Object *scene_find_camera(Scene *sc) return NULL; } +#ifdef DURIAN_CAMERA_SWITCH +Object *scene_find_camera_switch(Scene *scene) +{ + TimeMarker *m; + int cfra = scene->r.cfra; + int frame = -(MAXFRAME + 1); + Object *camera= NULL; + + for (m= scene->markers.first; m; m= m->next) { + if(m->camera && (m->frame <= cfra) && (m->frame > frame)) { + camera= m->camera; + frame= m->frame; + + if(frame == cfra) + break; + + } + } + return camera; +} +#endif + +static char *get_cfra_marker_name(Scene *scene) +{ + ListBase *markers= &scene->markers; + TimeMarker *m1, *m2; + + /* search through markers for match */ + for (m1=markers->first, m2=markers->last; m1 && m2; m1=m1->next, m2=m2->prev) { + if (m1->frame==CFRA) + return m1->name; + + if (m1 == m2) + break; + + if (m2->frame==CFRA) + return m2->name; + } + + return NULL; +} Base *scene_add_base(Scene *sce, Object *ob) { @@ -771,7 +820,7 @@ float frame_to_float (Scene *scene, int cfra) /* see also bsystem_time in objec return ctime; } -static void scene_update(Scene *sce, unsigned int lay) +static void scene_update_newframe(Scene *sce, unsigned int lay) { Base *base; Object *ob; @@ -803,6 +852,40 @@ static void scene_update(Scene *sce, unsigned int lay) } } +/* this is called in main loop, doing tagged updates before redraw */ +void scene_update_tagged(Scene *scene) +{ + Scene *sce; + Base *base; + float ctime = frame_to_float(scene, scene->r.cfra); + + /* update all objects: drivers, matrices, displists, etc. flags set + by depgraph or manual, no layer check here, gets correct flushed */ + + /* sets first, we allow per definition current scene to have + dependencies on sets, but not the other way around. */ + if(scene->set) { + for(SETLOOPER(scene->set, base)) + object_handle_update(scene, base->object); + } + + for(base= scene->base.first; base; base= base->next) { + object_handle_update(scene, base->object); + } + + /* recalc scene animation data here (for sequencer) */ + { + AnimData *adt= BKE_animdata_from_id(&scene->id); + + if(adt && (adt->recalc & ADT_RECALC_ANIM)) + BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0); + } + + BKE_ptcache_quick_cache_all(scene); + + /* in the future this should handle updates for all datablocks, not + only objects and scenes. - brecht */ +} /* applies changes right away, does all sets too */ void scene_update_for_newframe(Scene *sce, unsigned int lay) @@ -814,19 +897,20 @@ void scene_update_for_newframe(Scene *sce, unsigned int lay) /* sets first, we allow per definition current scene to have dependencies on sets */ for(sce= sce->set; sce; sce= sce->set) - scene_update(sce, lay); + scene_update_newframe(sce, lay); - scene_update(scene, lay); + scene_update_newframe(scene, lay); } /* return default layer, also used to patch old files */ void scene_add_render_layer(Scene *sce) { SceneRenderLayer *srl; - int tot= 1 + BLI_countlist(&sce->r.layers); +// int tot= 1 + BLI_countlist(&sce->r.layers); srl= MEM_callocN(sizeof(SceneRenderLayer), "new render layer"); - sprintf(srl->name, "%d RenderLayer", tot); + sprintf(srl->name, "RenderLayer"); + BLI_uniquename(&sce->r.layers, srl, "RenderLayer", '.', offsetof(SceneRenderLayer, name), 32); BLI_addtail(&sce->r.layers, srl); /* note, this is also in render, pipeline.c, to make layer when scenedata doesnt have it */ diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index 459db96dbfb..0dc6bf359f6 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -318,21 +318,20 @@ void free_screen(bScreen *sc) } /* for depsgraph */ -unsigned int BKE_screen_visible_layers(bScreen *screen) +unsigned int BKE_screen_visible_layers(bScreen *screen, Scene *scene) { ScrArea *sa; unsigned int layer= 0; - if(!screen) - return layer; - - /* get all used view3d layers */ - for(sa= screen->areabase.first; sa; sa= sa->next) - if(sa->spacetype==SPACE_VIEW3D) - layer |= ((View3D *)sa->spacedata.first)->lay; + if(screen) { + /* get all used view3d layers */ + for(sa= screen->areabase.first; sa; sa= sa->next) + if(sa->spacetype==SPACE_VIEW3D) + layer |= ((View3D *)sa->spacedata.first)->lay; + } if(!layer) - return screen->scene->lay; + return scene->lay; return layer; } diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index a1f81bf6166..2c532bfed1c 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -44,7 +44,7 @@ #include "BKE_global.h" #include "BKE_fcurve.h" #include "BKE_plugin_types.h" -#include "BKE_sequence.h" +#include "BKE_sequencer.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -231,7 +231,7 @@ static ImBuf * IMB_cast_away_list(ImBuf * i) return (ImBuf*) (((void**) i) + 2); } -static void do_plugin_effect(Sequence * seq,int cfra, +static void do_plugin_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -477,7 +477,7 @@ static void do_alphaover_effect_float(float facf0, float facf1, int x, int y, } } -static void do_alphaover_effect(Sequence * seq,int cfra, +static void do_alphaover_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -644,7 +644,7 @@ static void do_alphaunder_effect_float(float facf0, float facf1, int x, int y, } } -static void do_alphaunder_effect(Sequence * seq,int cfra, +static void do_alphaunder_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -764,7 +764,7 @@ void do_cross_effect_float(float facf0, float facf1, int x, int y, /* carefull: also used by speed effect! */ -static void do_cross_effect(Sequence * seq,int cfra, +static void do_cross_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1026,7 +1026,7 @@ static void do_gammacross_effect_float(float facf0, float facf1, } } -static void do_gammacross_effect(Sequence * seq,int cfra, +static void do_gammacross_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1140,7 +1140,7 @@ static void do_add_effect_float(float facf0, float facf1, int x, int y, } } -static void do_add_effect(Sequence * seq,int cfra, +static void do_add_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1252,7 +1252,7 @@ static void do_sub_effect_float(float facf0, float facf1, int x, int y, } } -static void do_sub_effect(Sequence * seq,int cfra, +static void do_sub_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1360,7 +1360,7 @@ static void do_drop_effect_float(float facf0, float facf1, int x, int y, } -static void do_drop_effect(Sequence * seq,int cfra, +static void do_drop_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf * ibuf3, @@ -1481,7 +1481,7 @@ static void do_mul_effect_float(float facf0, float facf1, int x, int y, } } -static void do_mul_effect(Sequence * seq,int cfra, +static void do_mul_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1931,7 +1931,7 @@ static void do_wipe_effect_float(Sequence *seq, float facf0, float facf1, } } -static void do_wipe_effect(Sequence * seq,int cfra, +static void do_wipe_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -1953,27 +1953,29 @@ static void do_wipe_effect(Sequence * seq,int cfra, ********************************************************************** */ static void init_transform_effect(Sequence *seq) { - TransformVars *scale; + TransformVars *transform; if(seq->effectdata)MEM_freeN(seq->effectdata); seq->effectdata = MEM_callocN(sizeof(struct TransformVars), "transformvars"); - scale = (TransformVars *)seq->effectdata; - scale->ScalexIni = 1; - scale->ScaleyIni = 1; - scale->ScalexFin = 1; - scale->ScaleyFin = 1; - - scale->xIni=0; - scale->xFin=0; - scale->yIni=0; - scale->yFin=0; - - scale->rotIni=0; - scale->rotFin=0; + transform = (TransformVars *)seq->effectdata; + + transform->ScalexIni = 1.0f; + transform->ScaleyIni = 1.0f; + transform->ScalexFin = 1.0f; + transform->ScalexFin = 1.0f; + + transform->xIni=0.0f; + transform->xFin=0.0f; + transform->yIni=0.0f; + transform->yFin=0.0f; + + transform->rotIni=0.0f; + transform->rotFin=0.0f; - scale->interpolation=1; - scale->percent=1; + transform->interpolation=1; + transform->percent=1; + transform->uniform_scale=0; } static int num_inputs_transform() @@ -1992,82 +1994,94 @@ static void copy_transform_effect(Sequence *dst, Sequence *src) dst->effectdata = MEM_dupallocN(src->effectdata); } -static void do_transform(Sequence * seq,float facf0, int x, int y, - struct ImBuf *ibuf1,struct ImBuf *out) +static void transform_image(int x, int y, struct ImBuf *ibuf1, struct ImBuf *out, + float scale_x, float scale_y, float translate_x, float translate_y, + float rotate, int interpolation) { int xo, yo, xi, yi; - float xs,ys,factxScale,factyScale,tx,ty,rad,s,c,xaux,yaux,factRot,px,py; - TransformVars *scale; - - // XXX struct RenderData *rd = NULL; // 2.5 global: &G.scene->r; + float xt, yt, xr, yr; + float s,c; - - scale = (TransformVars *)seq->effectdata; xo = x; yo = y; - - //factor scale - factxScale = scale->ScalexIni + (scale->ScalexFin - scale->ScalexIni) * facf0; - factyScale = scale->ScaleyIni + (scale->ScaleyFin - scale->ScaleyIni) * facf0; - - //Factor translate - if(!scale->percent){ - float rd_s = 0.0f; // XXX 2.5 global: (rd->size / 100.0f); - - tx = scale->xIni * rd_s+(xo / 2.0f) + (scale->xFin * rd_s -(xo / 2.0f) - scale->xIni * rd_s +(xo / 2.0f)) * facf0; - ty = scale->yIni * rd_s+(yo / 2.0f) + (scale->yFin * rd_s -(yo / 2.0f) - scale->yIni * rd_s +(yo / 2.0f)) * facf0; - }else{ - tx = xo*(scale->xIni/100.0f)+(xo / 2.0f) + (xo*(scale->xFin/100.0f)-(xo / 2.0f) - xo*(scale->xIni/100.0f)+(xo / 2.0f)) * facf0; - ty = yo*(scale->yIni/100.0f)+(yo / 2.0f) + (yo*(scale->yFin/100.0f)-(yo / 2.0f) - yo*(scale->yIni/100.0f)+(yo / 2.0f)) * facf0; - } - - //factor Rotate - factRot = scale->rotIni + (scale->rotFin - scale->rotIni) * facf0; - rad = (M_PI * factRot) / 180.0f; - s= sin(rad); - c= cos(rad); - + + // Rotate + s= sin(rotate); + c= cos(rotate); for (yi = 0; yi < yo; yi++) { for (xi = 0; xi < xo; xi++) { - //tranlate point - px = xi-tx; - py = yi-ty; + + //translate point + xt = xi-translate_x; + yt = yi-translate_y; //rotate point with center ref - xaux = c*px + py*s ; - yaux = -s*px + c*py; + xr = c*xt + s*yt; + yr = -s*xt + c*yt; //scale point with center ref - xs = xaux / factxScale; - ys = yaux / factyScale; + xt = xr / scale_x; + yt = yr / scale_y; //undo reference center point - xs += (xo / 2.0f); - ys += (yo / 2.0f); + xt += (xo / 2.0f); + yt += (yo / 2.0f); //interpolate - switch(scale->interpolation) { + switch(interpolation) { case 0: - neareast_interpolation(ibuf1,out, xs,ys,xi,yi); + neareast_interpolation(ibuf1,out, xt,yt,xi,yi); break; case 1: - bilinear_interpolation(ibuf1,out, xs,ys,xi,yi); + bilinear_interpolation(ibuf1,out, xt,yt,xi,yi); break; case 2: - bicubic_interpolation(ibuf1,out, xs,ys,xi,yi); + bicubic_interpolation(ibuf1,out, xt,yt,xi,yi); break; } } - } + } +} + +static void do_transform(Scene *scene, Sequence *seq, float facf0, int x, int y, + struct ImBuf *ibuf1,struct ImBuf *out) +{ + TransformVars *transform = (TransformVars *)seq->effectdata; + float scale_x, scale_y, translate_x, translate_y, rotate_radians; + + // Scale + if (transform->uniform_scale) { + scale_x = scale_y = transform->ScalexIni; + } else { + scale_x = transform->ScalexIni; + scale_y = transform->ScaleyIni; + } + + // Translate + if(!transform->percent){ + float rd_s = (scene->r.size/100.0f); + + translate_x = transform->xIni*rd_s+(x/2.0f); + translate_y = transform->yIni*rd_s+(y/2.0f); + }else{ + translate_x = x*(transform->xIni/100.0f)+(x/2.0f); + translate_y = y*(transform->yIni/100.0f)+(y/2.0f); + } + + // Rotate + rotate_radians = (M_PI*transform->rotIni)/180.0f; + transform_image(x,y, ibuf1, out, scale_x, scale_y, translate_x, translate_y, rotate_radians, transform->interpolation); } -static void do_transform_effect(Sequence * seq,int cfra, + + +static void do_transform_effect(Scene *scene, Sequence *seq,int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) { - do_transform(seq, facf0, x, y, ibuf1, out); + do_transform(scene, seq, facf0, x, y, ibuf1, out); } @@ -2574,7 +2588,7 @@ static void do_glow_effect_float(Sequence *seq, float facf0, float facf1, RVAddBitmaps_float (inbuf , outbuf, outbuf, x, y); } -static void do_glow_effect(Sequence * seq,int cfra, +static void do_glow_effect(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -2629,7 +2643,7 @@ static int early_out_color(struct Sequence *seq, return -1; } -static void do_solid_color(Sequence * seq,int cfra, +static void do_solid_color(Scene *scene, Sequence *seq, int cfra, float facf0, float facf1, int x, int y, struct ImBuf *ibuf1, struct ImBuf *ibuf2, struct ImBuf *ibuf3, struct ImBuf *out) @@ -2992,16 +3006,16 @@ static void get_default_fac_fade(struct Sequence *seq, int cfra, *facf1 /= seq->len; } -static void do_overdrop_effect(struct Sequence * seq, int cfra, +static void do_overdrop_effect(Scene *scene, Sequence *seq, int cfra, float fac, float facf, int x, int y, struct ImBuf * ibuf1, struct ImBuf * ibuf2, struct ImBuf * ibuf3, struct ImBuf * out) { - do_drop_effect(seq, cfra, fac, facf, x, y, + do_drop_effect(scene, seq, cfra, fac, facf, x, y, ibuf1, ibuf2, ibuf3, out); - do_alphaover_effect(seq, cfra, fac, facf, x, y, + do_alphaover_effect(scene, seq, cfra, fac, facf, x, y, ibuf1, ibuf2, ibuf3, out); } diff --git a/source/blender/blenkernel/intern/sequence.c b/source/blender/blenkernel/intern/sequencer.c index 07969704521..aa81cea79f5 100644 --- a/source/blender/blenkernel/intern/sequence.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -43,20 +43,23 @@ #include "BKE_global.h" #include "BKE_image.h" #include "BKE_main.h" -#include "BKE_sequence.h" +#include "BKE_sequencer.h" #include "BKE_fcurve.h" #include "BKE_utildefines.h" #include "RNA_access.h" #include "RE_pipeline.h" -#include "BLI_blenlib.h" -#include "BLI_util.h" +#include "BLI_fileops.h" +#include "BLI_listbase.h" +#include "BLI_path_util.h" +#include "BLI_string.h" +#include "BLI_threads.h" +#include <pthread.h> #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" -#include "BLI_threads.h" -#include <pthread.h> + #include "BKE_context.h" #include "BKE_sound.h" @@ -73,7 +76,9 @@ static int seqrecty= 0; //static int blender_test_break() {return 0;} /* **** XXX ******** */ - +#define SELECT 1 +ListBase seqbase_clipboard; +int seqbase_clipboard_frame; void printf_strip(Sequence *seq) { @@ -82,6 +87,20 @@ void printf_strip(Sequence *seq) fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0)); } +void seqbase_recursive_apply(ListBase *seqbase, int (*apply_func)(Sequence *seq, void *), void *arg) +{ + Sequence *iseq; + for(iseq= seqbase->first; iseq; iseq= iseq->next) { + seq_recursive_apply(iseq, apply_func, arg); + } +} + +void seq_recursive_apply(Sequence *seq, int (*apply_func)(Sequence *, void *), void *arg) +{ + if(apply_func(seq, arg) && seq->seqbase.first) + seqbase_recursive_apply(&seq->seqbase, apply_func, arg); +} + /* ********************************************************************** alloc / free functions ********************************************************************** */ @@ -197,23 +216,26 @@ void seq_free_strip(Strip *strip) void seq_free_sequence(Scene *scene, Sequence *seq) { - Editing *ed = scene->ed; - if(seq->strip) seq_free_strip(seq->strip); if(seq->anim) IMB_free_anim(seq->anim); - if(seq->sound_handle) - sound_delete_handle(scene, seq->sound_handle); - if (seq->type & SEQ_EFFECT) { struct SeqEffectHandle sh = get_sequence_effect(seq); sh.free(seq); } - if (ed->act_seq==seq) - ed->act_seq= NULL; + /* clipboard has no scene and will never have a sound handle or be active */ + if(scene) { + Editing *ed = scene->ed; + + if (ed->act_seq==seq) + ed->act_seq= NULL; + + if(seq->sound_handle) + sound_delete_handle(scene, seq->sound_handle); + } MEM_freeN(seq); } @@ -229,6 +251,17 @@ Editing *seq_give_editing(Scene *scene, int alloc) return scene->ed; } +void seq_free_clipboard(void) +{ + Sequence *seq, *nseq; + + for(seq= seqbase_clipboard.first; seq; seq= nseq) { + nseq= seq->next; + seq_free_sequence(NULL, seq); + } + seqbase_clipboard.first= seqbase_clipboard.last= NULL; +} + void seq_free_editing(Scene *scene) { Editing *ed = scene->ed; @@ -670,28 +703,22 @@ void sort_seq(Scene *scene) } -void clear_scene_in_allseqs(Scene *sce) +static int clear_scene_in_allseqs_cb(Sequence *seq, void *arg_pt) { - Scene *sce1; - Editing *ed; - Sequence *seq; - - /* when a scene is deleted: test all seqs */ - - sce1= G.main->scene.first; - while(sce1) { - if(sce1!=sce && sce1->ed) { - ed= sce1->ed; - - SEQ_BEGIN(ed, seq) { + if(seq->scene==(Scene *)arg_pt) + seq->scene= NULL; + return 1; +} - if(seq->scene==sce) seq->scene= 0; +void clear_scene_in_allseqs(Scene *scene) +{ + Scene *scene_iter; - } - SEQ_END + /* when a scene is deleted: test all seqs */ + for(scene_iter= G.main->scene.first; scene_iter; scene_iter= scene_iter->id.next) { + if(scene_iter != scene && scene_iter->ed) { + seqbase_recursive_apply(&scene_iter->ed->seqbase, clear_scene_in_allseqs_cb, scene); } - - sce1= sce1->id.next; } } @@ -820,23 +847,26 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se) return; } - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, - "effect_fader", 0); - - if (!fcu) { + if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) { sh.get_default_fac(seq, cfra, &fac, &facf); if( scene->r.mode & R_FIELDS ); else facf= fac; } else { - fac = facf = evaluate_fcurve(fcu, cfra); - if( scene->r.mode & R_FIELDS ) { - facf = evaluate_fcurve(fcu, cfra + 0.5); + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, + "effect_fader", 0); + if (fcu) { + fac = facf = evaluate_fcurve(fcu, cfra); + if( scene->r.mode & R_FIELDS ) { + facf = evaluate_fcurve(fcu, cfra + 0.5); + } + } else { + fac = facf = seq->effect_fader; } } early_out = sh.early_out(seq, fac, facf); if (early_out == -1) { /* no input needed */ - sh.execute(seq, cfra, fac, facf, + sh.execute(scene, seq, cfra, fac, facf, se->ibuf->x, se->ibuf->y, 0, 0, 0, se->ibuf); return; @@ -925,7 +955,7 @@ static void do_effect(Scene *scene, int cfra, Sequence *seq, TStripElem * se) IMB_rect_from_float(se3->ibuf); } - sh.execute(seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf, + sh.execute(scene, seq, cfra, fac, facf, x, y, se1->ibuf, se2->ibuf, se3->ibuf, se->ibuf); } @@ -2007,13 +2037,18 @@ static void do_build_seq_ibuf(Scene *scene, Sequence * seq, TStripElem *se, int } } } else if(seq->type == SEQ_SCENE) { // scene can be NULL after deletions - Scene *sce= seq->scene, *oldsce= scene; + Scene *sce= seq->scene;// *oldsce= scene; Render *re; RenderResult rres; char scenename[64]; - int have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first; - int sce_valid =sce && (sce->camera || have_seq); - + int have_seq= FALSE; + int sce_valid= FALSE; + + if(sce) { + have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first; + sce_valid= (sce->camera || have_seq); + } + if (se->ibuf == NULL && sce_valid && !build_proxy_run) { se->ibuf = seq_proxy_fetch(scene, seq, cfra, render_size); if (se->ibuf) { @@ -2122,16 +2157,19 @@ static void do_effect_seq_recursively(Scene *scene, Sequence *seq, TStripElem *s se->se2 = 0; se->se3 = 0; - fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, - "effect_fader", 0); - - if (!fcu) { + if ((seq->flag & SEQ_USE_EFFECT_DEFAULT_FADE) != 0) { sh.get_default_fac(seq, cfra, &fac, &facf); if( scene->r.mode & R_FIELDS ); else facf= fac; } else { - fac = facf = evaluate_fcurve(fcu, cfra); - if( scene->r.mode & R_FIELDS ) { - facf = evaluate_fcurve(fcu, cfra + 0.5); + fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, + "effect_fader", 0); + if (fcu) { + fac = facf = evaluate_fcurve(fcu, cfra); + if( scene->r.mode & R_FIELDS ) { + facf = evaluate_fcurve(fcu, cfra + 0.5); + } + } else { + fac = facf = seq->effect_fader; } } @@ -2270,7 +2308,7 @@ static TStripElem* do_handle_speed_effect(Scene *scene, Sequence * seq, int cfra } else { sh = get_sequence_effect(seq); - sh.execute(seq, cfra, + sh.execute(scene, seq, cfra, f_cfra - (float) cfra_left, f_cfra - (float) cfra_left, se->ibuf->x, se->ibuf->y, @@ -2504,12 +2542,12 @@ static TStripElem* do_build_seq_array_recursively(Scene *scene, } if (swap_input) { - sh.execute(seq, cfra, + sh.execute(scene, seq, cfra, facf, facf, x, y, se2->ibuf, se1->ibuf_comp, 0, se2->ibuf_comp); } else { - sh.execute(seq, cfra, + sh.execute(scene, seq, cfra, facf, facf, x, y, se1->ibuf_comp, se2->ibuf, 0, se2->ibuf_comp); @@ -3192,6 +3230,23 @@ static void free_imbuf_seq_with_ipo(Scene *scene, struct Ipo *ipo) } #endif +static int seq_sound_reload_cb(Sequence *seq, void *arg_pt) +{ + if (seq->type==SEQ_SOUND && seq->sound) { + Scene *scene= (Scene *)arg_pt; + if(seq->sound_handle) + sound_delete_handle(scene, seq->sound_handle); + + seq->sound_handle = sound_new_handle(scene, seq->sound, seq->start, seq->start + seq->strip->len, 0); + return 0; + } + return 1; /* recurse meta's */ +} +void seqbase_sound_reload(Scene *scene, ListBase *seqbase) +{ + seqbase_recursive_apply(seqbase, seq_sound_reload_cb, (void *)scene); +} + /* seq funcs's for transforming internally notice the difference between start/end and left/right. @@ -3250,7 +3305,7 @@ void seq_tx_set_final_right(Sequence *seq, int val) /* used so we can do a quick check for single image seq since they work a bit differently to normal image seq's (during transform) */ -int check_single_seq(Sequence *seq) +int seq_single_check(Sequence *seq) { if ( seq->len==1 && (seq->type == SEQ_IMAGE || seq->type == SEQ_COLOR)) return 1; @@ -3258,6 +3313,42 @@ int check_single_seq(Sequence *seq) return 0; } +/* check if the selected seq's reference unselected seq's */ +int seqbase_isolated_sel_check(ListBase *seqbase) +{ + Sequence *seq; + /* is there more than 1 select */ + int ok= FALSE; + + for(seq= seqbase->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + ok= TRUE; + break; + } + } + + if(ok == FALSE) + return FALSE; + + /* test relationships */ + for(seq= seqbase->first; seq; seq= seq->next) { + if(seq->flag & SELECT) { + if(seq->type & SEQ_EFFECT) { + if(seq->seq1 && (seq->seq1->flag & SELECT)==0) return FALSE; + if(seq->seq2 && (seq->seq2->flag & SELECT)==0) return FALSE; + if(seq->seq3 && (seq->seq3->flag & SELECT)==0) return FALSE; + } + } + else if(seq->type & SEQ_EFFECT) { + if(seq->seq1 && (seq->seq1->flag & SELECT)) return FALSE; + if(seq->seq2 && (seq->seq2->flag & SELECT)) return FALSE; + if(seq->seq3 && (seq->seq3->flag & SELECT)) return FALSE; + } + } + + return TRUE; +} + /* use to impose limits when dragging/extending - so impossible situations dont happen * Cant use the SEQ_LEFTSEL and SEQ_LEFTSEL directly because the strip may be in a metastrip */ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) @@ -3267,7 +3358,7 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) seq_tx_set_final_left(seq, seq_tx_get_final_right(seq, 0)-1); } - if (check_single_seq(seq)==0) { + if (seq_single_check(seq)==0) { if (seq_tx_get_final_left(seq, 0) >= seq_tx_get_end(seq)) { seq_tx_set_final_left(seq, seq_tx_get_end(seq)-1); } @@ -3289,7 +3380,7 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) seq_tx_set_final_right(seq, seq_tx_get_final_left(seq, 0)+1); } - if (check_single_seq(seq)==0) { + if (seq_single_check(seq)==0) { if (seq_tx_get_final_right(seq, 0) <= seq_tx_get_start(seq)) { seq_tx_set_final_right(seq, seq_tx_get_start(seq)+1); } @@ -3303,10 +3394,10 @@ void seq_tx_handle_xlimits(Sequence *seq, int leftflag, int rightflag) } } -void fix_single_seq(Sequence *seq) +void seq_single_fix(Sequence *seq) { int left, start, offset; - if (!check_single_seq(seq)) + if (!seq_single_check(seq)) return; /* make sure the image is always at the start since there is only one, @@ -3351,13 +3442,15 @@ int seq_test_overlap(ListBase * seqbasep, Sequence *test) } -static void seq_translate(Sequence *seq, int delta) +static void seq_translate(Scene *evil_scene, Sequence *seq, int delta) { + seq_offset_animdata(evil_scene, seq, delta); seq->start += delta; + if(seq->type==SEQ_META) { Sequence *seq_child; for(seq_child= seq->seqbase.first; seq_child; seq_child= seq_child->next) { - seq_translate(seq_child, delta); + seq_translate(evil_scene, seq_child, delta); } } @@ -3365,7 +3458,7 @@ static void seq_translate(Sequence *seq, int delta) } /* return 0 if there werent enough space */ -int shuffle_seq(ListBase * seqbasep, Sequence *test) +int shuffle_seq(ListBase * seqbasep, Sequence *test, Scene *evil_scene) { int orig_machine= test->machine; test->machine++; @@ -3393,7 +3486,7 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test) test->machine= orig_machine; new_frame = new_frame + (test->start-test->startdisp); /* adjust by the startdisp */ - seq_translate(test, new_frame - test->start); + seq_translate(evil_scene, test, new_frame - test->start); calc_sequence(test); return 0; @@ -3449,7 +3542,7 @@ static int shuffle_seq_time_offset(ListBase * seqbasep, char dir) return tot_ofs; } -int shuffle_seq_time(ListBase * seqbasep) +int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene) { /* note: seq->tmp is used to tag strips to move */ @@ -3462,7 +3555,7 @@ int shuffle_seq_time(ListBase * seqbasep) if(offset) { for(seq= seqbasep->first; seq; seq= seq->next) { if(seq->tmp) { - seq_translate(seq, offset); + seq_translate(evil_scene, seq, offset); seq->flag &= ~SEQ_OVERLAP; } } @@ -3471,19 +3564,118 @@ int shuffle_seq_time(ListBase * seqbasep) return offset? 0:1; } - -void seq_update_sound(struct Sequence *seq) +void seq_update_sound(Sequence *seq) { - if(seq->type == SEQ_SOUND) + if(seq->type == SEQ_SOUND && seq->sound_handle) { seq->sound_handle->startframe = seq->startdisp; seq->sound_handle->endframe = seq->enddisp; seq->sound_handle->frameskip = seq->startofs + seq->anim_startofs; - seq->sound_handle->mute = seq->flag & SEQ_MUTE ? 1 : 0; seq->sound_handle->changed = -1; + /* mute is set in seq_update_muting_recursive */ + } +} + +static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute) +{ + Sequence *seq; + int seqmute; + + /* for sound we go over full meta tree to update muted state, + since sound is played outside of evaluating the imbufs, */ + for(seq=seqbasep->first; seq; seq=seq->next) { + seqmute= (mute || (seq->flag & SEQ_MUTE)); + + if(seq->type == SEQ_META) { + /* if this is the current meta sequence, unmute because + all sequences above this were set to mute */ + if(seq == metaseq) + seqmute= 0; + + seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute); + } + else if(seq->type == SEQ_SOUND) { + if(seq->sound_handle && seqmute != seq->sound_handle->mute) { + seq->sound_handle->mute = seqmute; + seq->sound_handle->changed = -1; + } + } + } +} + +void seq_update_muting(Editing *ed) +{ + if(ed) { + /* mute all sounds up to current metastack list */ + MetaStack *ms= ed->metastack.last; + + if(ms) + seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1); + else + seq_update_muting_recursive(&ed->seqbase, NULL, 0); } } +/* in cases where we done know the sequence's listbase */ +ListBase *seq_seqbase(ListBase *seqbase, Sequence *seq) +{ + Sequence *iseq; + ListBase *lb= NULL; + + for(iseq= seqbase->first; iseq; iseq= iseq->next) { + if(seq==iseq) { + return seqbase; + } + else if(iseq->seqbase.first && (lb= seq_seqbase(&iseq->seqbase, seq))) { + return lb; + } + } + + return NULL; +} + +/* XXX - hackish function needed for transforming strips! TODO - have some better solution */ +void seq_offset_animdata(Scene *scene, Sequence *seq, int ofs) +{ + char str[32]; + FCurve *fcu; + + if(scene->adt==NULL || ofs==0) + return; + + sprintf(str, "[\"%s\"]", seq->name+2); + + for (fcu= scene->adt->action->curves.first; fcu; fcu= fcu->next) { + if(strstr(fcu->rna_path, "sequence_editor.sequences_all[") && strstr(fcu->rna_path, str)) { + int i; + for (i = 0; i < fcu->totvert; i++) { + BezTriple *bezt= &fcu->bezt[i]; + bezt->vec[0][0] += ofs; + bezt->vec[1][0] += ofs; + bezt->vec[2][0] += ofs; + } + } + } +} + + +Sequence *get_seq_by_name(ListBase *seqbase, const char *name, int recursive) +{ + Sequence *iseq=NULL; + Sequence *rseq=NULL; + + for (iseq=seqbase->first; iseq; iseq=iseq->next) { + if (strcmp(name, iseq->name+2) == 0) + return iseq; + else if(recursive && (iseq->seqbase.first) && (rseq=get_seq_by_name(&iseq->seqbase, name, 1))) { + return rseq; + } + } + + return NULL; +} + + Sequence *active_seq_get(Scene *scene) { Editing *ed= seq_give_editing(scene, FALSE); @@ -3512,7 +3704,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load) } if(seq_load->flag & SEQ_LOAD_REPLACE_SEL) { - seq_load->flag |= 1; /* SELECT */ + seq_load->flag |= SELECT; active_seq_set(scene, seq); } @@ -3538,7 +3730,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine) *( (short *)seq->name )= ID_SEQ; seq->name[2]= 0; - seq->flag= 1; /* SELECT */ + seq->flag= SELECT; seq->start= cfra; seq->machine= machine; seq->mul= 1.0; diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index e3a66b33ca3..cf1e5d8d985 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -3753,6 +3753,7 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo } } + /* void SB_estimate_transform */ /* input Object *ob out (says any object that can do SB like mesh,lattice,curve ) output float lloc[3],float lrot[3][3],float lscale[3][3] @@ -3765,164 +3766,40 @@ static void softbody_update_positions(Object *ob, SoftBody *sb, float (*vertexCo lloc,lrot,lscale are allowed to be NULL, just in case you don't need it. should be pretty useful for pythoneers :) not! velocity .. 2nd order stuff + vcloud_estimate_transform see */ -/* can't believe there is none in math utils */ -float _det_m3(float m2[3][3]) -{ - float det = 0.f; - if (m2){ - det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) - -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) - +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); - } - return det; -} - void SB_estimate_transform(Object *ob,float lloc[3],float lrot[3][3],float lscale[3][3]) { BodyPoint *bp; ReferenceVert *rp; - float accu_pos[3] = {0.0f,0.0f,0.0f}; - float com[3],va[3],vb[3],rcom[3]; - float accu_mass = 0.0f,la = 0.0f,lb = 0.0f,eps = 0.000001f; SoftBody *sb = 0; - int a,i=0,imax=16; - int _localdebug; - - if (lloc) zero_v3(lloc); - if (lrot) zero_m3(lrot); - if (lscale) zero_m3(lscale); - + float (*opos)[3]; + float (*rpos)[3]; + float com[3],rcom[3]; + int a; if(!ob ||!ob->soft) return; /* why did we get here ? */ sb= ob->soft; - /*for threading there should be a lock */ - /* sb-> lock; */ - /* calculate center of mass */ if(!sb || !sb->bpoint) return; - _localdebug=sb->solverflags & SBSO_MONITOR; /* turn this on/off if you (don't) want to see progress on console */ - for(a=0,bp=sb->bpoint; a<sb->totpoint; a++, bp++) { - VECADD(accu_pos,accu_pos,bp->pos); - accu_mass += bp->mass; + opos= MEM_callocN( (sb->totpoint)*3*sizeof(float), "SB_OPOS"); + rpos= MEM_callocN( (sb->totpoint)*3*sizeof(float), "SB_RPOS"); + /* might filter vertex selection with a vertex group */ + for(a=0, bp=sb->bpoint, rp=sb->scratch->Ref.ivert; a<sb->totpoint; a++, bp++, rp++) { + VECCOPY(rpos[a],rp->pos); + VECCOPY(opos[a],bp->pos); } - VECCOPY(com,accu_pos); - mul_v3_fl(com,1.0f/accu_mass); - /* center of mass done*/ - if (sb->scratch){ - float dcom[3],stunt[3]; - float m[3][3],mr[3][3],q[3][3],qi[3][3]; - float odet,ndet; - zero_m3(m); - zero_m3(mr); - VECSUB(dcom,com,sb->scratch->Ref.com); - VECCOPY(rcom,sb->scratch->Ref.com); - if (_localdebug) { - printf("DCOM %f %f %f\n",dcom[0],dcom[1],dcom[2]); - } - if (lloc) VECCOPY(lloc,dcom); - VECCOPY(sb->lcom,dcom); - /* build 'projection' matrix */ - for(a=0, bp=sb->bpoint, rp=sb->scratch->Ref.ivert; a<sb->totpoint; a++, bp++, rp++) { - VECSUB(va,rp->pos,rcom); - la += len_v3(va); - /* mul_v3_fl(va,bp->mass); mass needs renormalzation here ?? */ - VECSUB(vb,bp->pos,com); - lb += len_v3(vb); - /* mul_v3_fl(va,rp->mass); */ - m[0][0] += va[0] * vb[0]; - m[0][1] += va[0] * vb[1]; - m[0][2] += va[0] * vb[2]; - - m[1][0] += va[1] * vb[0]; - m[1][1] += va[1] * vb[1]; - m[1][2] += va[1] * vb[2]; - - m[2][0] += va[2] * vb[0]; - m[2][1] += va[2] * vb[1]; - m[2][2] += va[2] * vb[2]; - - /* building the referenc matrix on the fly - needed to scale properly later*/ - - mr[0][0] += va[0] * va[0]; - mr[0][1] += va[0] * va[1]; - mr[0][2] += va[0] * va[2]; - - mr[1][0] += va[1] * va[0]; - mr[1][1] += va[1] * va[1]; - mr[1][2] += va[1] * va[2]; - - mr[2][0] += va[2] * va[0]; - mr[2][1] += va[2] * va[1]; - mr[2][2] += va[2] * va[2]; - } - /* we are pretty much set up here and we could return that raw mess containing essential information - but being nice fellows we proceed: - knowing we did split off the tanslational part to the center of mass (com) part - however let's do some more reverse engeneering and see if we can split - rotation from scale ->Polardecompose - */ - copy_m3_m3(q,m); - stunt[0] = q[0][0]; stunt[1] = q[1][1]; stunt[2] = q[2][2]; - /* nothing to see here but renormalizing works nicely - printf("lenght stunt %5.3f a %5.3f b %5.3f %5.3f\n",len_v3(stunt),la,lb,sqrt(la*lb)); - */ - mul_m3_fl(q,1.f/len_v3(stunt)); - /* not too much to see here - if(_localdebug){ - printf("q0 %5.3f %5.3f %5.3f\n",q[0][0],q[0][1],q[0][2]); - printf("q1 %5.3f %5.3f %5.3f\n",q[1][0],q[1][1],q[1][2]); - printf("q2 %5.3f %5.3f %5.3f\n",q[2][0],q[2][1],q[2][2]); - } - */ - /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */ - /* without the far case !!! but seems to work here pretty neat */ - odet = 0.f; - ndet = _det_m3(q); - while((odet-ndet)*(odet-ndet) > eps && i<imax){ - invert_m3_m3(qi,q); - transpose_m3(qi); - add_m3_m3m3(q,q,qi); - mul_m3_fl(q,0.5f); - odet =ndet; - ndet =_det_m3(q); - i++; - } - if (i){ - float scale[3][3]; - float irot[3][3]; - if(lrot) copy_m3_m3(lrot,q); - copy_m3_m3(sb->lrot,q); - if(_localdebug){ - printf("Rot .. i %d\n",i); - printf("!q0 %5.3f %5.3f %5.3f\n",q[0][0],q[0][1],q[0][2]); - printf("!q1 %5.3f %5.3f %5.3f\n",q[1][0],q[1][1],q[1][2]); - printf("!q2 %5.3f %5.3f %5.3f\n",q[2][0],q[2][1],q[2][2]); - } - invert_m3_m3(irot,q); - /* now that's where we need mr to get scaling right */ - invert_m3_m3(qi,mr); - mul_m3_m3m3(q,m,qi); - - //mul_m3_m3m3(scale,q,irot); - mul_m3_m3m3(scale,irot,q); /* i always have a problem with this C functions left/right operator applies first*/ - mul_m3_fl(scale,lb/la); /* 0 order scale was normalized away so put it back here dunno if that is needed here ???*/ - - if(lscale) copy_m3_m3(lscale,scale); - copy_m3_m3(sb->lscale,scale); - if(_localdebug){ - printf("Scale .. \n"); - printf("!s0 %5.3f %5.3f %5.3f\n",scale[0][0],scale[0][1],scale[0][2]); - printf("!s1 %5.3f %5.3f %5.3f\n",scale[1][0],scale[1][1],scale[1][2]); - printf("!s2 %5.3f %5.3f %5.3f\n",scale[2][0],scale[2][1],scale[2][2]); - } - - } - } - /*for threading there should be a unlock */ - /* sb-> unlock; */ + vcloud_estimate_transform(sb->totpoint, opos, NULL, rpos, NULL, com, rcom,lrot,lscale); + //VECSUB(com,com,rcom); + if (lloc) VECCOPY(lloc,com); + VECCOPY(sb->lcom,com); + if (lscale) copy_m3_m3(sb->lscale,lscale); + if (lrot) copy_m3_m3(sb->lrot,lrot); + + + MEM_freeN(opos); + MEM_freeN(rpos); } static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int numVerts) @@ -4183,10 +4060,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i dtime = timescale; softbody_update_positions(ob, sb, vertexCos, numVerts); softbody_step(scene, ob, sb, dtime); - if(sb->solverflags & SBSO_MONITOR ){ - printf("Picked from cache continue_physics %d\n",framenr); - } - softbody_to_object(ob, vertexCos, numVerts, 0); return; } @@ -4211,9 +4084,6 @@ void sbObjectStep(Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], i cache_result = BKE_ptcache_read_cache(&pid, framenr, scene->r.frs_sec); if(cache_result == PTCACHE_READ_EXACT || cache_result == PTCACHE_READ_INTERPOLATED) { - if(sb->solverflags & SBSO_MONITOR ){ - printf("Picked from cache at frame %d\n",framenr); - } softbody_to_object(ob, vertexCos, numVerts, sb->local); cache->simframe= framenr; diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index d8950c7dace..74c6afdc018 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -31,6 +31,13 @@ #include <config.h> #endif +static int sound_disabled = 0; + +void sound_disable() +{ + sound_disabled = 1; +} + void sound_init() { AUD_Specs specs; @@ -42,6 +49,9 @@ void sound_init() specs.format = U.audioformat; specs.rate = U.audiorate; + if (sound_disabled) + device = 0; + if(buffersize < 128) buffersize = AUD_DEFAULT_BUFFER_SIZE; diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index af5cefbe161..092c0ff1042 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -54,11 +54,12 @@ #include "BKE_tessmesh.h" #include "BLI_blenlib.h" +#include "BLI_edgehash.h" #include "BLI_editVert.h" -#include "BLI_math.h" #include "BLI_linklist.h" +#include "BLI_math.h" #include "BLI_memarena.h" -#include "BLI_edgehash.h" +#include "BLI_pbvh.h" #include "PIL_time.h" #include "BLI_array.h" @@ -71,58 +72,32 @@ #include "CCGSubSurf.h" -typedef struct _VertData { - float co[3]; - float no[3]; -} VertData; - -struct CCGDerivedMesh { - DerivedMesh dm; - - CSubSurf *ss; - int drawInteriorEdges, useSubsurfUv; - - struct {int startVert; CCVert *vert;} *vertMap; - struct {int startVert; int startEdge; CCEdge *edge;} *edgeMap; - struct {int startVert; int startEdge; - int startFace; CCFace *face;} *faceMap; - /*maps final faces to faceMap faces*/ - int *reverseFaceMap; - - EdgeHash *ehash; -}; - -typedef struct CCGDerivedMesh CCGDerivedMesh; - -static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v); -static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e); -static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f); -static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm); /// -static void *arena_alloc(CCAllocHDL a, int numBytes) { +static void *arena_alloc(CCGAllocatorHDL a, int numBytes) { return BLI_memarena_alloc(a, numBytes); } -static void *arena_realloc(CCAllocHDL a, void *ptr, int newSize, int oldSize) { +static void *arena_realloc(CCGAllocatorHDL a, void *ptr, int newSize, int oldSize) { void *p2 = BLI_memarena_alloc(a, newSize); if (ptr) { memcpy(p2, ptr, oldSize); } return p2; } -static void arena_free(CCAllocHDL a, void *ptr) { +static void arena_free(CCGAllocatorHDL a, void *ptr) { } -static void arena_release(CCAllocHDL a) { +static void arena_release(CCGAllocatorHDL a) { BLI_memarena_free(a); } -static CSubSurf *_getSubSurf(CSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) { +static CCGSubSurf *_getSubSurf(CCGSubSurf *prevSS, int subdivLevels, int useAging, int useArena, int useFlatSubdiv) { CCGMeshIFC ifc; - CSubSurf *ccgSS; + CCGSubSurf *ccgSS; /* subdivLevels==0 is not allowed */ subdivLevels = MAX2(subdivLevels, 1); @@ -131,12 +106,12 @@ static CSubSurf *_getSubSurf(CSubSurf *prevSS, int subdivLevels, int useAging, i int oldUseAging; useAging = !!useAging; - CCS_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); + ccgSubSurf_getUseAgeCounts(prevSS, &oldUseAging, NULL, NULL, NULL); if (oldUseAging!=useAging) { - CCS_free(prevSS); + ccgSubSurf_free(prevSS); } else { - CCS_setSubdivisionLevels(prevSS, subdivLevels); + ccgSubSurf_setSubdivisionLevels(prevSS, subdivLevels); return prevSS; } @@ -147,37 +122,37 @@ static CSubSurf *_getSubSurf(CSubSurf *prevSS, int subdivLevels, int useAging, i } else { ifc.vertUserSize = ifc.edgeUserSize = ifc.faceUserSize = 8; } - ifc.vertDataSize = sizeof(VertData); + ifc.vertDataSize = sizeof(DMGridData); if (useArena) { CCGAllocatorIFC allocatorIFC; - CCAllocHDL allocator = BLI_memarena_new((1<<16)); + CCGAllocatorHDL allocator = BLI_memarena_new((1<<16)); allocatorIFC.alloc = arena_alloc; allocatorIFC.realloc = arena_realloc; allocatorIFC.free = arena_free; allocatorIFC.release = arena_release; - ccgSS = CCS_new(&ifc, subdivLevels, &allocatorIFC, allocator); + ccgSS = ccgSubSurf_new(&ifc, subdivLevels, &allocatorIFC, allocator); } else { - ccgSS = CCS_new(&ifc, subdivLevels, NULL, NULL); + ccgSS = ccgSubSurf_new(&ifc, subdivLevels, NULL, NULL); } if (useAging) { - CCS_setUseAgeCounts(ccgSS, 1, 8, 8, 8); + ccgSubSurf_setUseAgeCounts(ccgSS, 1, 8, 8, 8); } - CCS_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(VertData, no)); + ccgSubSurf_setCalcVertexNormals(ccgSS, 1, BLI_STRUCT_OFFSET(DMGridData, no)); return ccgSS; } -static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) { - CCVert *v0 = CCS_getEdgeVert0(e); - CCVert *v1 = CCS_getEdgeVert1(e); - int v0idx = *((int*) CCS_getVertUserData(ss, v0)); - int v1idx = *((int*) CCS_getVertUserData(ss, v1)); - int edgeBase = *((int*) CCS_getEdgeUserData(ss, e)); +static int getEdgeIndex(CCGSubSurf *ss, CCGEdge *e, int x, int edgeSize) { + CCGVert *v0 = ccgSubSurf_getEdgeVert0(e); + CCGVert *v1 = ccgSubSurf_getEdgeVert1(e); + int v0idx = *((int*) ccgSubSurf_getVertUserData(ss, v0)); + int v1idx = *((int*) ccgSubSurf_getVertUserData(ss, v1)); + int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); if (x==0) { return v0idx; @@ -188,27 +163,27 @@ static int getEdgeIndex(CSubSurf *ss, CCEdge *e, int x, int edgeSize) { } } -BM_INLINE int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edgeSize, int gridSize) { - int faceBase = *((int*) CCS_getFaceUserData(ss, f)); - int numVerts = CCS_getFaceNumVerts(f); +BM_INLINE int getFaceIndex(CCGSubSurf *ss, CCGFace *f, int S, int x, int y, int edgeSize, int gridSize) { + int faceBase = *((int*) ccgSubSurf_getFaceUserData(ss, f)); + int numVerts = ccgSubSurf_getFaceNumVerts(f); if (x==gridSize-1 && y==gridSize-1) { - CCVert *v = CCS_getFaceVert(ss, f, S); - return *((int*) CCS_getVertUserData(ss, v)); + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + return *((int*) ccgSubSurf_getVertUserData(ss, v)); } else if (x==gridSize-1) { - CCVert *v = CCS_getFaceVert(ss, f, S); - CCEdge *e = CCS_getFaceEdge(ss, f, S); - int edgeBase = *((int*) CCS_getEdgeUserData(ss, e)); - if (v==CCS_getEdgeVert0(e)) { + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, S); + int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); + if (v==ccgSubSurf_getEdgeVert0(e)) { return edgeBase + (gridSize-1-y)-1; } else { return edgeBase + (edgeSize-2-1)-((gridSize-1-y)-1); } } else if (y==gridSize-1) { - CCVert *v = CCS_getFaceVert(ss, f, S); - CCEdge *e = CCS_getFaceEdge(ss, f, (S+numVerts-1)%numVerts); - int edgeBase = *((int*) CCS_getEdgeUserData(ss, e)); - if (v==CCS_getEdgeVert0(e)) { + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); + CCGEdge *e = ccgSubSurf_getFaceEdge(ss, f, (S+numVerts-1)%numVerts); + int edgeBase = *((int*) ccgSubSurf_getEdgeUserData(ss, e)); + if (v==ccgSubSurf_getEdgeVert0(e)) { return edgeBase + (gridSize-1-x)-1; } else { return edgeBase + (edgeSize-2-1)-((gridSize-1-x)-1); @@ -225,7 +200,7 @@ BM_INLINE int getFaceIndex(CSubSurf *ss, CCFace *f, int S, int x, int y, int edg } } -static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCVertHDL *fverts) { +static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCGVertHDL *fverts) { unsigned int *fv = &mf->v1; UvMapVert *v, *nv; int j, nverts= mf->v4? 4: 3; @@ -242,7 +217,7 @@ static void get_face_uv_map_vert(UvVertMap *vmap, struct MFace *mf, int fi, CCVe } } -static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFace *tface) { +static int ss_sync_from_uv(CCGSubSurf *ss, CCGSubSurf *origss, DerivedMesh *dm, MTFace *tface) { #if 0 MFace *mface = dm->getTessFaceArray(dm); MVert *mvert = dm->getVertArray(dm); @@ -252,16 +227,16 @@ static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFa UvMapVert *v; UvVertMap *vmap; float limit[2]; - CCVertHDL fverts[4]; + CCGVertHDL fverts[4]; EdgeHash *ehash; - float creaseFactor = (float)CCS_getSubdivisionLevels(ss); + float creaseFactor = (float)ccgSubSurf_getSubdivisionLevels(ss); limit[0]= limit[1]= STD_UV_CONNECT_LIMIT; vmap= make_uv_vert_map(mface, tface, totface, totvert, 0, limit); if (!vmap) return 0; - CCS_initFullSync(ss); + ccgSubSurf_initFullSync(ss); /* create vertices */ for (i=0; i<totvert; i++) { @@ -276,15 +251,15 @@ static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFa for (v=get_uv_map_vert(vmap, i); v; v=v->next) { if (v->separate) { - CCVert *ssv; - CCVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex); + CCGVert *ssv; + CCGVertHDL vhdl = SET_INT_IN_POINTER(v->f*4 + v->tfindex); float uv[3]; uv[0]= (tface+v->f)->uv[v->tfindex][0]; uv[1]= (tface+v->f)->uv[v->tfindex][1]; uv[2]= 0.0f; - CCS_syncVert(ss, vhdl, uv, seam, &ssv); + ccgSubSurf_syncVert(ss, vhdl, uv, seam, &ssv); } } } @@ -295,7 +270,7 @@ static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFa for (i=0; i<totface; i++) { MFace *mf = &((MFace*) mface)[i]; int nverts= mf->v4? 4: 3; - CCFace *origf= CCS_getFace(origss, SET_INT_IN_POINTER(i)); + CCGFace *origf= ccgSubSurf_getFace(origss, SET_INT_IN_POINTER(i)); unsigned int *fv = &mf->v1; get_face_uv_map_vert(vmap, mf, i, fverts); @@ -307,16 +282,16 @@ static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFa MVert *mv1 = mvert + *(fv+((j+1)%nverts)); if (!BLI_edgehash_haskey(ehash, v0, v1)) { - CCEdge *e, *orige= CCS_getFaceEdge(origss, origf, j); - CCEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j); + CCGEdge *e, *orige= ccgSubSurf_getFaceEdge(origss, origf, j); + CCGEdgeHDL ehdl= SET_INT_IN_POINTER(i*4 + j); float crease; if ((mv0->flag&mv1->flag) & ME_VERT_MERGED) crease = creaseFactor; else - crease = CCS_getEdgeCrease(orige); + crease = ccgSubSurf_getEdgeCrease(orige); - CCS_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e); + ccgSubSurf_syncEdge(ss, ehdl, fverts[j], fverts[(j+1)%nverts], crease, &e); BLI_edgehash_insert(ehash, v0, v1, NULL); } } @@ -328,25 +303,25 @@ static int ss_sync_from_uv(CSubSurf *ss, CSubSurf *origss, DerivedMesh *dm, MTFa for (i=0; i<totface; i++) { MFace *mf = &((MFace*) mface)[i]; int nverts= mf->v4? 4: 3; - CCFace *f; + CCGFace *f; get_face_uv_map_vert(vmap, mf, i, fverts); - CCS_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f); + ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), nverts, fverts, &f); } free_uv_vert_map(vmap); - CCS_processSync(ss); + ccgSubSurf_processSync(ss); #endif return 1; } -static void set_subsurf_uv(CSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n) +static void set_subsurf_uv(CCGSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, int n) { - CSubSurf *uvss; - CCFace **faceMap; + CCGSubSurf *uvss; + CCGFace **faceMap; MTFace *tf; - CCFaceIterator *fi; + CCGFaceIterator *fi; int index, gridSize, gridFaces, edgeSize, totface, x, y, S; MTFace *dmtface = CustomData_get_layer_n(&dm->faceData, CD_MTFACE, n); MTFace *tface = CustomData_get_layer_n(&result->faceData, CD_MTFACE, n); @@ -354,39 +329,39 @@ static void set_subsurf_uv(CSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, i if(!dmtface || !tface) return; - /* create a CCGSubsurf from uv's */ - uvss = _getSubSurf(NULL, CCS_getSubdivisionLevels(ss), 0, 1, 0); + /* create a CCGSubSurf from uv's */ + uvss = _getSubSurf(NULL, ccgSubSurf_getSubdivisionLevels(ss), 0, 1, 0); if(!ss_sync_from_uv(uvss, ss, dm, dmtface)) { - CCS_free(uvss); + ccgSubSurf_free(uvss); return; } - /* get some info from CCGSubsurf */ - totface = CCS_getNumFaces(uvss); - edgeSize = CCS_getEdgeSize(uvss); - gridSize = CCS_getGridSize(uvss); + /* get some info from CCGSubSurf */ + totface = ccgSubSurf_getNumFaces(uvss); + edgeSize = ccgSubSurf_getEdgeSize(uvss); + gridSize = ccgSubSurf_getGridSize(uvss); gridFaces = gridSize - 1; - /* make a map from original faces to CCFaces */ + /* make a map from original faces to CCGFaces */ faceMap = MEM_mallocN(totface*sizeof(*faceMap), "facemapuv"); - fi = CCS_getFaceIterator(uvss); - for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - faceMap[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(uvss, f))] = f; + fi = ccgSubSurf_getFaceIterator(uvss); + for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(uvss, f))] = f; } - CCFIter_free(fi); + ccgFaceIterator_free(fi); /* load coordinates from uvss into tface */ tf= tface; for(index = 0; index < totface; index++) { - CCFace *f = faceMap[index]; - int numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = faceMap[index]; + int numVerts = ccgSubSurf_getFaceNumVerts(f); for (S=0; S<numVerts; S++) { - VertData *faceGridData= CCS_getFaceGridDataArray(uvss, f, S); + DMGridData *faceGridData= ccgSubSurf_getFaceGridDataArray(uvss, f, S); for(y = 0; y < gridFaces; y++) { for(x = 0; x < gridFaces; x++) { @@ -406,42 +381,10 @@ static void set_subsurf_uv(CSubSurf *ss, DerivedMesh *dm, DerivedMesh *result, i } } - CCS_free(uvss); + ccgSubSurf_free(uvss); MEM_freeN(faceMap); } -#if 0 -static unsigned int ss_getEdgeFlags(CSubSurf *ss, CCEdge *e, int ssFromEditmesh, DispListMesh *dlm, MEdge *medge, MTFace *tface) -{ - unsigned int flags = 0; - int N = CCS_getEdgeNumFaces(e); - - if (!N) flags |= ME_LOOSEEDGE; - - if (ssFromEditmesh) { - EditEdge *eed = CCS_getEdgeEdgeHandle(e); - - flags |= ME_EDGEDRAW|ME_EDGERENDER; - if (eed->seam) { - flags |= ME_SEAM; - } - } else { - if (edgeIdx!=-1) { - MEdge *origMed = &medge[edgeIdx]; - - if (dlm) { - flags |= origMed->flag&~ME_EDGE_STEPINDEX; - } else { - flags |= (origMed->flag&ME_SEAM)|ME_EDGEDRAW|ME_EDGERENDER; - } - } - } - - return flags; -} -#endif - - static void calc_ss_weights(int gridFaces, FaceVertWeight **qweight, FaceVertWeight **tweight) { @@ -558,9 +501,9 @@ void free_ss_weights(WeightTable *wtable) } } -static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, +static DerivedMesh *ss_to_cdderivedmesh(CCGSubSurf *ss, int ssFromEditmesh, int drawInteriorEdges, int useSubsurfUv, - DerivedMesh *dm, MultiresSubsurf *ms) + DerivedMesh *dm, struct MultiresSubsurf *ms) { DerivedMesh *cgdm, *result; double curt = PIL_check_seconds_timer(); @@ -578,19 +521,19 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, return result; #if 0 DerivedMesh *result; - int edgeSize = CCS_getEdgeSize(ss); - int gridSize = CCS_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; int edgeBase, faceBase; int i, j, k, S, x, y, index; int *vertIdx = NULL; BLI_array_declare(vertIdx); - CCVertIterator *vi; - CCEdgeIterator *ei; - CCFaceIterator *fi; - CCFace **faceMap2; - CCEdge **edgeMap2; - CCVert **vertMap2; + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; + CCGFace **faceMap2; + CCGEdge **edgeMap2; + CCGVert **vertMap2; int totvert, totedge, totface; MVert *mvert; MEdge *med; @@ -603,49 +546,49 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, memset(&wtable, 0, sizeof(wtable)); /* vert map */ - totvert = CCS_getNumVerts(ss); + totvert = ccgSubSurf_getNumVerts(ss); vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); - vi = CCS_getVertIterator(ss); - for(; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); + vi = ccgSubSurf_getVertIterator(ss); + for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); - vertMap2[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))] = v; + vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v; } - CCVIter_free(vi); + ccgVertIterator_free(vi); - totedge = CCS_getNumEdges(ss); + totedge = ccgSubSurf_getNumEdges(ss); edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap"); - ei = CCS_getEdgeIterator(ss); - for(; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); + ei = ccgSubSurf_getEdgeIterator(ss); + for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - edgeMap2[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))] = e; + edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e; } - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap"); - fi = CCS_getFaceIterator(ss); - for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); + fi = ccgSubSurf_getFaceIterator(ss); + for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); - faceMap2[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))] = f; + faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f; } - CCFIter_free(fi); + ccgFaceIterator_free(fi); if(ms) { - result = MultiresDM_new(ms, dm, CCS_getNumFinalVerts(ss), - CCS_getNumFinalEdges(ss), - CCS_getNumFinalFaces(ss), 0, 0); + result = MultiresDM_new(ms, dm, ccgSubSurf_getNumFinalVerts(ss), + ccgSubSurf_getNumFinalEdges(ss), + ccgSubSurf_getNumFinalFaces(ss), 0, 0); } else { if(dm) { - result = CDDM_from_template(dm, CCS_getNumFinalVerts(ss), - CCS_getNumFinalEdges(ss), - CCS_getNumFinalFaces(ss), 0, 0); + result = CDDM_from_template(dm, ccgSubSurf_getNumFinalVerts(ss), + ccgSubSurf_getNumFinalEdges(ss), + ccgSubSurf_getNumFinalFaces(ss), 0, 0); } else { - result = CDDM_new(CCS_getNumFinalVerts(ss), - CCS_getNumFinalEdges(ss), - CCS_getNumFinalFaces(ss), 0, 0); + result = CDDM_new(ccgSubSurf_getNumFinalVerts(ss), + ccgSubSurf_getNumFinalEdges(ss), + ccgSubSurf_getNumFinalFaces(ss), 0, 0); } } @@ -655,23 +598,23 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, origIndex = result->getVertData(result, 0, CD_ORIGINDEX); for(index = 0; index < totface; index++) { - CCFace *f = faceMap2[index]; - int x, y, S, numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = faceMap2[index]; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); FaceVertWeight *weight = 0;//get_ss_weights(&wtable, gridFaces-1, numVerts); BLI_array_empty(vertIdx); for(S = 0; S < numVerts; S++) { - CCVert *v = CCS_getFaceVert(ss, f, S); + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, S); BLI_array_growone(vertIdx); - vertIdx[S] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + vertIdx[S] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); } #if 0 DM_interp_vert_data(dm, result, vertIdx, weight[0][0], numVerts, i); #endif - copy_v3_v3(mvert->co, CCS_getFaceCenterData(f)); + copy_v3_v3(mvert->co, ccgSubSurf_getFaceCenterData(f)); *origIndex = ORIGINDEX_NONE; ++mvert; ++origIndex; @@ -697,7 +640,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, DM_interp_vert_data(dm, result, vertIdx, w, numVerts, i); #endif copy_v3_v3(mvert->co, - CCS_getFaceGridEdgeData(ss, f, S, x)); + ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); *origIndex = ORIGINDEX_NONE; ++mvert; @@ -727,7 +670,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, #endif copy_v3_v3(mvert->co, - CCS_getFaceGridData(ss, f, S, x, y)); + ccgSubSurf_getFaceGridData(ss, f, S, x, y)); *origIndex = ORIGINDEX_NONE; ++mvert; ++origIndex; @@ -735,21 +678,21 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, } } } - *((int*)CCS_getFaceUserData(ss, f)) = faceBase; + *((int*)ccgSubSurf_getFaceUserData(ss, f)) = faceBase; faceBase += 1 + numVerts * ((gridSize-2) + (gridSize-2) * (gridSize-2)); } edgeBase = i; for(index = 0; index < totedge; index++) { - CCEdge *e = edgeMap2[index]; + CCGEdge *e = edgeMap2[index]; int x; int vertIdx[2]; - CCVert *v; - v = CCS_getEdgeVert0(e); - vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - v = CCS_getEdgeVert1(e); - vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + CCGVert *v; + v = ccgSubSurf_getEdgeVert0(e); + vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); + v = ccgSubSurf_getEdgeVert1(e); + vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); for(x = 1; x < edgeSize - 1; x++) { float w2[2]; @@ -758,28 +701,28 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, w2[0] = 1 - w2[1]; DM_interp_vert_data(dm, result, vertIdx, w2, 2, i); - copy_v3_v3(mvert->co, CCS_getEdgeData(ss, e, x)); + copy_v3_v3(mvert->co, ccgSubSurf_getEdgeData(ss, e, x)); *origIndex = ORIGINDEX_NONE; ++mvert; ++origIndex; i++; } - *((int*)CCS_getEdgeUserData(ss, e)) = edgeBase; + *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = edgeBase; edgeBase += edgeSize-2; } for(index = 0; index < totvert; index++) { - CCVert *v = vertMap2[index]; + CCGVert *v = vertMap2[index]; int vertIdx; - vertIdx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + vertIdx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); DM_copy_vert_data(dm, result, vertIdx, i, 1); - copy_v3_v3(mvert->co, CCS_getVertData(ss, v)); + copy_v3_v3(mvert->co, ccgSubSurf_getVertData(ss, v)); - *((int*)CCS_getVertUserData(ss, v)) = i; - *origIndex = cgdm_getVertMapIndex(ss, v); + *((int*)ccgSubSurf_getVertUserData(ss, v)) = i; + *origIndex = ccgDM_getVertMapIndex(ss, v); ++mvert; ++origIndex; i++; @@ -791,8 +734,8 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, origIndex = result->getEdgeData(result, 0, CD_ORIGINDEX); for(index = 0; index < totface; index++) { - CCFace *f = faceMap2[index]; - int numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = faceMap2[index]; + int numVerts = ccgSubSurf_getFaceNumVerts(f); for(k = 0; k < numVerts; k++) { for(x = 0; x < gridFaces; x++) { @@ -832,12 +775,12 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, } for(index = 0; index < totedge; index++) { - CCEdge *e = edgeMap2[index]; + CCGEdge *e = edgeMap2[index]; unsigned int flags = 0; char bweight = 0; - int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e)); + int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); - if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; + if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; if(edgeIdx != -1 && dm) { @@ -853,7 +796,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, med->v2 = getEdgeIndex(ss, e, x + 1, edgeSize); med->flag = flags; med->bweight = bweight; - *origIndex = cgdm_getEdgeMapIndex(ss, e); + *origIndex = ccgDM_getEdgeMapIndex(ss, e); ++med; ++origIndex; i++; @@ -866,12 +809,12 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, origIndex = result->getTessFaceData(result, 0, CD_ORIGINDEX); for(index = 0; index < totface; index++) { - CCFace *f = faceMap2[index]; - int numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = faceMap2[index]; + int numVerts = ccgSubSurf_getFaceNumVerts(f); int mat_nr; int flag; - int mapIndex = cgdm_getFaceMapIndex(ss, f); - int faceIdx = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); + int mapIndex = ccgDM_getFaceMapIndex(ss, f); + int faceIdx = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); if(!ssFromEditmesh) { MFace origMFace; @@ -880,7 +823,7 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, mat_nr = origMFace.mat_nr; flag = origMFace.flag; } else { - BMFace *ef = CCS_getFaceFaceHandle(ss, f); + BMFace *ef = ccgSubSurf_getFaceFaceHandle(ss, f); mat_nr = ef->mat_nr; flag = BMFlags_To_MEFlags(ef); } @@ -955,11 +898,11 @@ static DerivedMesh *ss_to_cdderivedmesh(CSubSurf *ss, int ssFromEditmesh, #endif } -static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm, +static void ss_sync_from_derivedmesh(CCGSubSurf *ss, DerivedMesh *dm, float (*vertexCos)[3], int useFlatSubdiv) { - float creaseFactor = (float) CCS_getSubdivisionLevels(ss); - CCVertHDL *fVerts = NULL; + float creaseFactor = (float) ccgSubSurf_getSubdivisionLevels(ss); + CCGVertHDL *fVerts = NULL; BLI_array_declare(fVerts); int totvert = dm->getNumVerts(dm); int totedge = dm->getNumEdges(dm); @@ -976,40 +919,40 @@ static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm, DMFaceIter *fiter; DMLoopIter *liter; - CCS_initFullSync(ss); + ccgSubSurf_initFullSync(ss); mv = mvert; index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX); - for(i = 0; i < totvert; i++, mv++, index++) { - CCVert *v; + for(i = 0; i < totvert; i++, mv++) { + CCGVert *v; if(vertexCos) { - CCS_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v); + ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), vertexCos[i], 0, &v); } else { - CCS_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v); + ccgSubSurf_syncVert(ss, SET_INT_IN_POINTER(i), mv->co, 0, &v); } - ((int*)CCS_getVertUserData(ss, v))[1] = *index; + ((int*)ccgSubSurf_getVertUserData(ss, v))[1] = (index)? *index++: i; } me = medge; index = (int *)dm->getEdgeDataArray(dm, CD_ORIGINDEX); - for(i = 0; i < totedge; i++, me++, index++) { - CCEdge *e; + for(i = 0; i < totedge; i++, me++) { + CCGEdge *e; float crease; crease = useFlatSubdiv ? creaseFactor : me->crease * creaseFactor / 255.0f; - CCS_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1), + ccgSubSurf_syncEdge(ss, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(me->v1), SET_INT_IN_POINTER(me->v2), crease, &e); - ((int*)CCS_getEdgeUserData(ss, e))[1] = *index; + ((int*)ccgSubSurf_getEdgeUserData(ss, e))[1] = (index)? *index++: i; } fiter = dm->newFaceIter(dm); for (i=0; !fiter->done; fiter->step(fiter), i++) { - CCFace *f; + CCGFace *f; BLI_array_empty(fVerts); index = (int*) fiter->getCDData(fiter, CD_ORIGINDEX, -1); @@ -1024,7 +967,7 @@ static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm, * it is not really possible to continue without modifying * other parts of code significantly to handle missing faces. * since this really shouldn't even be possible we just bail.*/ - if(CCS_syncFace(ss, SET_INT_IN_POINTER(i), fiter->len, + if(ccgSubSurf_syncFace(ss, SET_INT_IN_POINTER(i), fiter->len, fVerts, &f) == eCCGError_InvalidValue) { static int hasGivenError = 0; @@ -1038,62 +981,62 @@ static void ss_sync_from_derivedmesh(CSubSurf *ss, DerivedMesh *dm, return; } - ((int*)CCS_getFaceUserData(ss, f))[1] = *index; + ((int*)ccgSubSurf_getFaceUserData(ss, f))[1] = (index)? *index++: i; } fiter->free(fiter); - CCS_processSync(ss); + ccgSubSurf_processSync(ss); BLI_array_free(fVerts); } /***/ -static int cgdm_getVertMapIndex(CSubSurf *ss, CCVert *v) { - return ((int*) CCS_getVertUserData(ss, v))[1]; +int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v) { + return ((int*) ccgSubSurf_getVertUserData(ss, v))[1]; } -static int cgdm_getEdgeMapIndex(CSubSurf *ss, CCEdge *e) { - return ((int*) CCS_getEdgeUserData(ss, e))[1]; +int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e) { + return ((int*) ccgSubSurf_getEdgeUserData(ss, e))[1]; } -static int cgdm_getFaceMapIndex(CSubSurf *ss, CCFace *f) { - return ((int*) CCS_getFaceUserData(ss, f))[1]; +int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f) { + return ((int*) ccgSubSurf_getFaceUserData(ss, f))[1]; } static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCVertIterator *vi = CCS_getVertIterator(ss); - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - CCFaceIterator *fi = CCS_getFaceIterator(ss); - int i, edgeSize = CCS_getEdgeSize(ss); - int gridSize = CCS_getGridSize(ss); - - if (!CCS_getNumVerts(ss)) + CCGSubSurf *ss = cgdm->ss; + CCGVertIterator *vi = ccgSubSurf_getVertIterator(ss); + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + int i, edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + + if (!ccgSubSurf_getNumVerts(ss)) min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0; - for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); - float *co = CCS_getVertData(ss, v); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + float *co = ccgSubSurf_getVertData(ss, v); DO_MINMAX(co, min_r, max_r); } - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); for (i=0; i<edgeSize; i++) DO_MINMAX(edgeData[i].co, min_r, max_r); } - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int S, x, y, numVerts = CCS_getFaceNumVerts(f); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); for (y=0; y<gridSize; y++) for (x=0; x<gridSize; x++) @@ -1101,41 +1044,41 @@ static void cgdm_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3]) { } } - CCFIter_free(fi); - CCEIter_free(ei); - CCVIter_free(vi); + ccgFaceIterator_free(fi); + ccgEdgeIterator_free(ei); + ccgVertIterator_free(vi); } static int cgdm_getNumVerts(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - return CCS_getNumFinalVerts(cgdm->ss); + return ccgSubSurf_getNumFinalVerts(cgdm->ss); } static int cgdm_getNumEdges(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - return CCS_getNumFinalEdges(cgdm->ss); + return ccgSubSurf_getNumFinalEdges(cgdm->ss); } static int cgdm_getNumTessFaces(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - return CCS_getNumFinalFaces(cgdm->ss); + return ccgSubSurf_getNumFinalFaces(cgdm->ss); } static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; + CCGSubSurf *ss = cgdm->ss; int i; memset(mv, 0, sizeof(*mv)); - if((vertNum < cgdm->edgeMap[0].startVert) && (CCS_getNumFaces(ss) > 0)) { + if((vertNum < cgdm->edgeMap[0].startVert) && (ccgSubSurf_getNumFaces(ss) > 0)) { /* this vert comes from face data */ - int lastface = CCS_getNumFaces(ss) - 1; - CCFace *f; + int lastface = ccgSubSurf_getNumFaces(ss) - 1; + CCGFace *f; int x, y, grid, numVerts; int offset; - int gridSize = CCS_getGridSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); int gridSideVerts; int gridInternalVerts; int gridSideEnd; @@ -1146,7 +1089,7 @@ static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) ++i; f = cgdm->faceMap[i].face; - numVerts = CCS_getFaceNumVerts(f); + numVerts = ccgSubSurf_getFaceNumVerts(f); gridSideVerts = gridSize - 2; gridInternalVerts = gridSideVerts * gridSideVerts; @@ -1156,24 +1099,24 @@ static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) offset = vertNum - cgdm->faceMap[i].startVert; if(offset < 1) { - copy_v3_v3(mv->co, CCS_getFaceCenterData(f)); + copy_v3_v3(mv->co, ccgSubSurf_getFaceCenterData(f)); } else if(offset < gridSideEnd) { offset -= 1; grid = offset / gridSideVerts; x = offset % gridSideVerts + 1; - copy_v3_v3(mv->co, CCS_getFaceGridEdgeData(ss, f, grid, x)); + copy_v3_v3(mv->co, ccgSubSurf_getFaceGridEdgeData(ss, f, grid, x)); } else if(offset < gridInternalEnd) { offset -= gridSideEnd; grid = offset / gridInternalVerts; offset %= gridInternalVerts; y = offset / gridSideVerts + 1; x = offset % gridSideVerts + 1; - copy_v3_v3(mv->co, CCS_getFaceGridData(ss, f, grid, x, y)); + copy_v3_v3(mv->co, ccgSubSurf_getFaceGridData(ss, f, grid, x, y)); } - } else if((vertNum < cgdm->vertMap[0].startVert) && (CCS_getNumEdges(ss) > 0)) { + } else if((vertNum < cgdm->vertMap[0].startVert) && (ccgSubSurf_getNumEdges(ss) > 0)) { /* this vert comes from edge data */ - CCEdge *e; - int lastedge = CCS_getNumEdges(ss) - 1; + CCGEdge *e; + int lastedge = ccgSubSurf_getNumEdges(ss) - 1; int x; i = 0; @@ -1183,33 +1126,33 @@ static void cgdm_getFinalVert(DerivedMesh *dm, int vertNum, MVert *mv) e = cgdm->edgeMap[i].edge; x = vertNum - cgdm->edgeMap[i].startVert + 1; - copy_v3_v3(mv->co, CCS_getEdgeData(ss, e, x)); + copy_v3_v3(mv->co, ccgSubSurf_getEdgeData(ss, e, x)); } else { /* this vert comes from vert data */ - CCVert *v; + CCGVert *v; i = vertNum - cgdm->vertMap[0].startVert; v = cgdm->vertMap[i].vert; - copy_v3_v3(mv->co, CCS_getVertData(ss, v)); + copy_v3_v3(mv->co, ccgSubSurf_getVertData(ss, v)); } } static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; + CCGSubSurf *ss = cgdm->ss; int i; memset(med, 0, sizeof(*med)); if(edgeNum < cgdm->edgeMap[0].startEdge) { /* this edge comes from face data */ - int lastface = CCS_getNumFaces(ss) - 1; - CCFace *f; + int lastface = ccgSubSurf_getNumFaces(ss) - 1; + CCGFace *f; int x, y, grid, numVerts; int offset; - int gridSize = CCS_getGridSize(ss); - int edgeSize = CCS_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSideEdges; int gridInternalEdges; @@ -1218,7 +1161,7 @@ static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) ++i; f = cgdm->faceMap[i].face; - numVerts = CCS_getFaceNumVerts(f); + numVerts = ccgSubSurf_getFaceNumVerts(f); gridSideEdges = gridSize - 1; gridInternalEdges = (gridSideEdges - 1) * gridSideEdges * 2; @@ -1245,23 +1188,24 @@ static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) } } else { /* this vert comes from edge data */ - CCEdge *e; - int edgeSize = CCS_getEdgeSize(ss); - int x, *edgeFlag; + CCGEdge *e; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int x; + short *edgeFlag; unsigned int flags = 0; i = (edgeNum - cgdm->edgeMap[0].startEdge) / (edgeSize - 1); e = cgdm->edgeMap[i].edge; - if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; + if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; x = edgeNum - cgdm->edgeMap[i].startEdge; med->v1 = getEdgeIndex(ss, e, x, edgeSize); med->v2 = getEdgeIndex(ss, e, x+1, edgeSize); - edgeFlag = dm->getEdgeData(dm, edgeNum, CD_FLAGS); + edgeFlag = (cgdm->edgeFlags)? &cgdm->edgeFlags[i]: NULL; if(edgeFlag) flags |= (*edgeFlag & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER; @@ -1275,19 +1219,19 @@ static void cgdm_getFinalEdge(DerivedMesh *dm, int edgeNum, MEdge *med) static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - int gridSize = CCS_getGridSize(ss); - int edgeSize = CCS_getEdgeSize(ss); + CCGSubSurf *ss = cgdm->ss; + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int gridSideEdges = gridSize - 1; int gridFaces = gridSideEdges * gridSideEdges; int i; - CCFace *f; + CCGFace *f; int numVerts; int offset; int grid; int x, y; - int lastface = CCS_getNumFaces(ss) - 1; - char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS); + int lastface = ccgSubSurf_getNumFaces(ss) - 1; + char *faceFlags = cgdm->faceFlags; memset(mf, 0, sizeof(*mf)); if (faceNum >= cgdm->dm.numFaceData) @@ -1296,7 +1240,7 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) i = cgdm->reverseFaceMap[faceNum]; f = cgdm->faceMap[i].face; - numVerts = CCS_getFaceNumVerts(f); + numVerts = ccgSubSurf_getFaceNumVerts(f); offset = faceNum - cgdm->faceMap[i].startFace; grid = offset / gridFaces; @@ -1310,8 +1254,8 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) mf->v4 = getFaceIndex(ss, f, grid, x+1, y+0, edgeSize, gridSize); if(faceFlags) { - mf->flag = faceFlags[i*4]; - mf->mat_nr = faceFlags[i*4+1]; + mf->flag = faceFlags[i*2]; + mf->mat_nr = faceFlags[i*2+1]; } else mf->flag = ME_SMOOTH; } @@ -1319,53 +1263,63 @@ static void cgdm_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; + CCGSubSurf *ss = cgdm->ss; + DMGridData *vd; int index; int totvert, totedge, totface; - int gridSize = CCS_getGridSize(ss); - int edgeSize = CCS_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); for(index = 0; index < totface; index++) { - CCFace *f = cgdm->faceMap[index].face; - int x, y, S, numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = cgdm->faceMap[index].face; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - copy_v3_v3(mvert[i++].co, CCS_getFaceCenterData(f)); + vd= ccgSubSurf_getFaceCenterData(f); + copy_v3_v3(mvert[i].co, vd->co); + normal_float_to_short_v3(mvert[i].no, vd->no); + i++; for(S = 0; S < numVerts; S++) { - for(x = 1; x < gridSize - 1; x++) { - copy_v3_v3(mvert[i++].co, - CCS_getFaceGridEdgeData(ss, f, S, x)); + for(x = 1; x < gridSize - 1; x++, i++) { + vd= ccgSubSurf_getFaceGridEdgeData(ss, f, S, x); + copy_v3_v3(mvert[i].co, vd->co); + normal_float_to_short_v3(mvert[i].no, vd->no); } } for(S = 0; S < numVerts; S++) { for(y = 1; y < gridSize - 1; y++) { - for(x = 1; x < gridSize - 1; x++) { - copy_v3_v3(mvert[i++].co, - CCS_getFaceGridData(ss, f, S, x, y)); + for(x = 1; x < gridSize - 1; x++, i++) { + vd= ccgSubSurf_getFaceGridData(ss, f, S, x, y); + copy_v3_v3(mvert[i].co, vd->co); + normal_float_to_short_v3(mvert[i].no, vd->no); } } } } - totedge = CCS_getNumEdges(ss); + totedge = ccgSubSurf_getNumEdges(ss); for(index = 0; index < totedge; index++) { - CCEdge *e = cgdm->edgeMap[index].edge; + CCGEdge *e = cgdm->edgeMap[index].edge; int x; - for(x = 1; x < edgeSize - 1; x++) { - copy_v3_v3(mvert[i++].co, CCS_getEdgeData(ss, e, x)); + for(x = 1; x < edgeSize - 1; x++, i++) { + vd= ccgSubSurf_getEdgeData(ss, e, x); + copy_v3_v3(mvert[i].co, vd->co); + /* TODO CCGSubsurf does not set these */ + normal_float_to_short_v3(mvert[i].no, vd->no); } } - totvert = CCS_getNumVerts(ss); + totvert = ccgSubSurf_getNumVerts(ss); for(index = 0; index < totvert; index++) { - CCVert *v = cgdm->vertMap[index].vert; - - copy_v3_v3(mvert[i].co, CCS_getVertData(ss, v)); + CCGVert *v = cgdm->vertMap[index].vert; + vd= ccgSubSurf_getVertData(ss, v); + copy_v3_v3(mvert[i].co, vd->co); + normal_float_to_short_v3(mvert[i].no, vd->no); i++; } } @@ -1373,18 +1327,18 @@ static void cgdm_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; + CCGSubSurf *ss = cgdm->ss; int index; int totedge, totface; - int gridSize = CCS_getGridSize(ss); - int edgeSize = CCS_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; - int *edgeFlags = dm->getEdgeDataArray(dm, CD_FLAGS); + short *edgeFlags = cgdm->edgeFlags; - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); for(index = 0; index < totface; index++) { - CCFace *f = cgdm->faceMap[index].face; - int x, y, S, numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = cgdm->faceMap[index].face; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); for(S = 0; S < numVerts; S++) { for(x = 0; x < gridSize - 1; x++) { @@ -1423,18 +1377,18 @@ static void cgdm_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) } } - totedge = CCS_getNumEdges(ss); + totedge = ccgSubSurf_getNumEdges(ss); for(index = 0; index < totedge; index++) { - CCEdge *e = cgdm->edgeMap[index].edge; + CCGEdge *e = cgdm->edgeMap[index].edge; unsigned int flags = 0; int x; - int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e)); + int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); - if(!CCS_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; + if(!ccgSubSurf_getEdgeNumFaces(e)) flags |= ME_LOOSEEDGE; if(edgeFlags) { if(edgeIdx != -1) { - flags |= (edgeFlags[i] & (ME_SEAM | ME_SHARP)) + flags |= (edgeFlags[index] & (ME_SEAM | ME_SHARP)) | ME_EDGEDRAW | ME_EDGERENDER; } } else { @@ -1481,7 +1435,7 @@ void cgdm_faceIterStep(void *self) fiter->head.index++; - if (fiter->head.index >= CCS_getNumFinalFaces(fiter->cgdm->ss)) { + if (fiter->head.index >= ccgSubSurf_getNumFinalFaces(fiter->cgdm->ss)) { fiter->head.done = 1; return; }; @@ -1611,20 +1565,20 @@ DMFaceIter *cgdm_newFaceIter(DerivedMesh *dm) static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; + CCGSubSurf *ss = cgdm->ss; int index; int totface; - int gridSize = CCS_getGridSize(ss); - int edgeSize = CCS_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int i = 0; - char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS); + char *faceFlags = cgdm->faceFlags; - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); for(index = 0; index < totface; index++) { - CCFace *f = cgdm->faceMap[index].face; - int x, y, S, numVerts = CCS_getFaceNumVerts(f); - int mat_nr = 0; - int flag = ME_SMOOTH; /* assume face is smooth by default */ + CCGFace *f = cgdm->faceMap[index].face; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); + int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; + int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; for(S = 0; S < numVerts; S++) { for(y = 0; y < gridSize - 1; y++) { @@ -1639,11 +1593,13 @@ static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize); if (faceFlags) { - mat_nr = faceFlags[index*4+1]; - mf->flag = faceFlags[index*4]; + mat_nr = faceFlags[index*2+1]; + mf->flag = faceFlags[index*2]; } else mf->flag = flag; mf->mat_nr = mat_nr; + mf->flag = flag; + i++; } } @@ -1653,81 +1609,81 @@ static void cgdm_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - int edgeSize = CCS_getEdgeSize(ss); - int gridSize = CCS_getGridSize(ss); + CCGSubSurf *ss = cgdm->ss; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); int i; - CCVertIterator *vi; - CCEdgeIterator *ei; - CCFaceIterator *fi; - CCFace **faceMap2; - CCEdge **edgeMap2; - CCVert **vertMap2; + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; + CCGFace **faceMap2; + CCGEdge **edgeMap2; + CCGVert **vertMap2; int index, totvert, totedge, totface; - totvert = CCS_getNumVerts(ss); + totvert = ccgSubSurf_getNumVerts(ss); vertMap2 = MEM_mallocN(totvert*sizeof(*vertMap2), "vertmap"); - vi = CCS_getVertIterator(ss); - for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); - vertMap2[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))] = v; + vertMap2[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))] = v; } - CCVIter_free(vi); + ccgVertIterator_free(vi); - totedge = CCS_getNumEdges(ss); + totedge = ccgSubSurf_getNumEdges(ss); edgeMap2 = MEM_mallocN(totedge*sizeof(*edgeMap2), "edgemap"); - ei = CCS_getEdgeIterator(ss); - for (i=0; !CCEIter_isStopped(ei); i++,CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); + ei = ccgSubSurf_getEdgeIterator(ss); + for (i=0; !ccgEdgeIterator_isStopped(ei); i++,ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - edgeMap2[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))] = e; + edgeMap2[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))] = e; } - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); faceMap2 = MEM_mallocN(totface*sizeof(*faceMap2), "facemap"); - fi = CCS_getFaceIterator(ss); - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); - faceMap2[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))] = f; + faceMap2[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))] = f; } - CCFIter_free(fi); + ccgFaceIterator_free(fi); i = 0; for (index=0; index<totface; index++) { - CCFace *f = faceMap2[index]; - int x, y, S, numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = faceMap2[index]; + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - copy_v3_v3(cos[i++], CCS_getFaceCenterData(f)); + copy_v3_v3(cos[i++], ccgSubSurf_getFaceCenterData(f)); for (S=0; S<numVerts; S++) { for (x=1; x<gridSize-1; x++) { - copy_v3_v3(cos[i++], CCS_getFaceGridEdgeData(ss, f, S, x)); + copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); } } for (S=0; S<numVerts; S++) { for (y=1; y<gridSize-1; y++) { for (x=1; x<gridSize-1; x++) { - copy_v3_v3(cos[i++], CCS_getFaceGridData(ss, f, S, x, y)); + copy_v3_v3(cos[i++], ccgSubSurf_getFaceGridData(ss, f, S, x, y)); } } } } for (index=0; index<totedge; index++) { - CCEdge *e= edgeMap2[index]; + CCGEdge *e= edgeMap2[index]; int x; for (x=1; x<edgeSize-1; x++) { - copy_v3_v3(cos[i++], CCS_getEdgeData(ss, e, x)); + copy_v3_v3(cos[i++], ccgSubSurf_getEdgeData(ss, e, x)); } } for (index=0; index<totvert; index++) { - CCVert *v = vertMap2[index]; - copy_v3_v3(cos[i++], CCS_getVertData(ss, v)); + CCGVert *v = vertMap2[index]; + copy_v3_v3(cos[i++], ccgSubSurf_getVertData(ss, v)); } MEM_freeN(vertMap2); @@ -1736,29 +1692,29 @@ static void cgdm_getVertCos(DerivedMesh *dm, float (*cos)[3]) { } static void cgdm_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CCVertIterator *vi = CCS_getVertIterator(cgdm->ss); + CCGVertIterator *vi = ccgSubSurf_getVertIterator(cgdm->ss); - for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); - VertData *vd = CCS_getVertData(cgdm->ss, v); - int index = cgdm_getVertMapIndex(cgdm->ss, v); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + DMGridData *vd = ccgSubSurf_getVertData(cgdm->ss, v); + int index = ccgDM_getVertMapIndex(cgdm->ss, v); if (index!=-1) func(userData, index, vd->co, vd->no, NULL); } - CCVIter_free(vi); + ccgVertIterator_free(vi); } static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - int i, edgeSize = CCS_getEdgeSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + int i, edgeSize = ccgSubSurf_getEdgeSize(ss); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); - int index = cgdm_getEdgeMapIndex(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ss, e); if (index!=-1) { for (i=0; i<edgeSize-1; i++) @@ -1766,73 +1722,73 @@ static void cgdm_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, } } - CCEIter_free(ei); + ccgEdgeIterator_free(ei); } static void cgdm_drawVerts(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - int edgeSize = CCS_getEdgeSize(ss); - int gridSize = CCS_getGridSize(ss); - CCVertIterator *vi; - CCEdgeIterator *ei; - CCFaceIterator *fi; + CCGSubSurf *ss = cgdm->ss; + int edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; glBegin(GL_POINTS); - vi = CCS_getVertIterator(ss); - for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); - glVertex3fv(CCS_getVertData(ss, v)); + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + glVertex3fv(ccgSubSurf_getVertData(ss, v)); } - CCVIter_free(vi); + ccgVertIterator_free(vi); - ei = CCS_getEdgeIterator(ss); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); + ei = ccgSubSurf_getEdgeIterator(ss); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); int x; for (x=1; x<edgeSize-1; x++) - glVertex3fv(CCS_getEdgeData(ss, e, x)); + glVertex3fv(ccgSubSurf_getEdgeData(ss, e, x)); } - CCEIter_free(ei); + ccgEdgeIterator_free(ei); - fi = CCS_getFaceIterator(ss); - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int x, y, S, numVerts = CCS_getFaceNumVerts(f); + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - glVertex3fv(CCS_getFaceCenterData(f)); + glVertex3fv(ccgSubSurf_getFaceCenterData(f)); for (S=0; S<numVerts; S++) for (x=1; x<gridSize-1; x++) - glVertex3fv(CCS_getFaceGridEdgeData(ss, f, S, x)); + glVertex3fv(ccgSubSurf_getFaceGridEdgeData(ss, f, S, x)); for (S=0; S<numVerts; S++) for (y=1; y<gridSize-1; y++) for (x=1; x<gridSize-1; x++) - glVertex3fv(CCS_getFaceGridData(ss, f, S, x, y)); + glVertex3fv(ccgSubSurf_getFaceGridData(ss, f, S, x, y)); } - CCFIter_free(fi); + ccgFaceIterator_free(fi); glEnd(); } static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - CCFaceIterator *fi = CCS_getFaceIterator(ss); - int i, edgeSize = CCS_getEdgeSize(ss); - int gridSize = CCS_getGridSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + int i, edgeSize = ccgSubSurf_getEdgeSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); int useAging; - CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); + ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - if (!drawLooseEdges && !CCS_getEdgeNumFaces(e)) + if (!drawLooseEdges && !ccgSubSurf_getEdgeNumFaces(e)) continue; if (useAging && !(G.f&G_BACKBUFSEL)) { - int ageCol = 255-CCS_getEdgeAge(ss, e)*4; + int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; glColor3ub(0, ageCol>0?ageCol:0, 0); } @@ -1849,12 +1805,12 @@ static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) { } if (cgdm->drawInteriorEdges) { - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int S, x, y, numVerts = CCS_getFaceNumVerts(f); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); glBegin(GL_LINE_STRIP); for (x=0; x<gridSize; x++) @@ -1876,20 +1832,20 @@ static void cgdm_drawEdges(DerivedMesh *dm, int drawLooseEdges) { } } - CCFIter_free(fi); - CCEIter_free(ei); + ccgFaceIterator_free(fi); + ccgEdgeIterator_free(ei); } static void cgdm_drawLooseEdges(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - int i, edgeSize = CCS_getEdgeSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + int i, edgeSize = ccgSubSurf_getEdgeSize(ss); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); - if (!CCS_getEdgeNumFaces(e)) { + if (!ccgSubSurf_getEdgeNumFaces(e)) { glBegin(GL_LINE_STRIP); for (i=0; i<edgeSize-1; i++) { glVertex3fv(edgeData[i].co); @@ -1899,10 +1855,10 @@ static void cgdm_drawLooseEdges(DerivedMesh *dm) { } } - CCEIter_free(ei); + ccgEdgeIterator_free(ei); } -static void cgdm_glNormalFast(float *a, float *b, float *c, float *d) +void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) { float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; @@ -1917,22 +1873,48 @@ static void cgdm_glNormalFast(float *a, float *b, float *c, float *d) } /* Only used by non-editmesh types */ -static void cgdm_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) { +static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int fast, int (*setMaterial)(int, void *attribs)) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCFaceIterator *fi = CCS_getFaceIterator(ss); - int gridSize = CCS_getGridSize(ss); - char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS); - - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int S, x, y, numVerts = CCS_getFaceNumVerts(f); - int index = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); + CCGSubSurf *ss = cgdm->ss; + CCGFaceIterator *fi; + int gridSize; + char *faceFlags = cgdm->faceFlags; + int step = (fast)? gridSize-1: 1; + + if(cgdm->pbvh && cgdm->multires.mmd && !fast) { + CCGFace **faces; + int totface; + + BLI_pbvh_get_grid_updates(cgdm->pbvh, 1, (void***)&faces, &totface); + if(totface) { + ccgSubSurf_updateFromFaces(ss, 0, faces, totface); + ccgSubSurf_updateNormals(ss, faces, totface); + MEM_freeN(faces); + } + + /* should be per face */ + if(faceFlags && faceFlags[0] & ME_SMOOTH) + glShadeModel(GL_SMOOTH); + + BLI_pbvh_draw(cgdm->pbvh, partial_redraw_planes, NULL); + + glShadeModel(GL_FLAT); + + return; + } + + gridSize = ccgSubSurf_getGridSize(ss); + + fi = ccgSubSurf_getFaceIterator(ss); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); + int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); int drawSmooth, mat_nr; if(faceFlags) { - drawSmooth = (faceFlags[index*4] & ME_SMOOTH); - mat_nr= faceFlags[index*4 + 1]; + drawSmooth = (faceFlags[index*2] & ME_SMOOTH); + mat_nr= faceFlags[index*2 + 1]; } else { drawSmooth = 1; @@ -1944,14 +1926,14 @@ static void cgdm_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); if (drawSmooth) { - for (y=0; y<gridSize-1; y++) { + for (y=0; y<gridSize-1; y+=step) { glBegin(GL_QUAD_STRIP); - for (x=0; x<gridSize; x++) { - VertData *a = &faceGridData[(y+0)*gridSize + x]; - VertData *b = &faceGridData[(y+1)*gridSize + x]; + for (x=0; x<gridSize; x+=step) { + DMGridData *a = &faceGridData[(y+0)*gridSize + x]; + DMGridData *b = &faceGridData[(y+step)*gridSize + x]; glNormal3fv(a->no); glVertex3fv(a->co); @@ -1962,14 +1944,14 @@ static void cgdm_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a } } else { glBegin(GL_QUADS); - for (y=0; y<gridSize-1; y++) { - for (x=0; x<gridSize-1; x++) { + for (y=0; y<gridSize-1; y+=step) { + for (x=0; x<gridSize-1; x+=step) { float *a = faceGridData[(y+0)*gridSize + x].co; - float *b = faceGridData[(y+0)*gridSize + x + 1].co; - float *c = faceGridData[(y+1)*gridSize + x + 1].co; - float *d = faceGridData[(y+1)*gridSize + x].co; + float *b = faceGridData[(y+0)*gridSize + x + step].co; + float *c = faceGridData[(y+step)*gridSize + x + step].co; + float *d = faceGridData[(y+step)*gridSize + x].co; - cgdm_glNormalFast(a, b, c, d); + ccgDM_glNormalFast(a, b, c, d); glVertex3fv(d); glVertex3fv(c); @@ -1982,22 +1964,22 @@ static void cgdm_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *a } } - CCFIter_free(fi); + ccgFaceIterator_free(fi); } /* Only used by non-editmesh types */ static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCFaceIterator *fi = CCS_getFaceIterator(ss); + CCGSubSurf *ss = cgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); GPUVertexAttribs gattribs; DMVertexAttribs attribs; MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); - int gridSize = CCS_getGridSize(ss); + int gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; - int edgeSize = CCS_getEdgeSize(ss); + int edgeSize = ccgSubSurf_getEdgeSize(ss); int transp, orig_transp, new_transp; - char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS); + char *faceFlags = cgdm->faceFlags; int a, b, i, doDraw, numVerts, matnr, new_matnr, totface; doDraw = 0; @@ -2029,18 +2011,18 @@ static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo } \ } - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); for(a = 0, i = 0; i < totface; i++) { - CCFace *f = cgdm->faceMap[i].face; + CCGFace *f = cgdm->faceMap[i].face; int S, x, y, drawSmooth; - int index = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); - int origIndex = cgdm_getFaceMapIndex(ss, f); + int index = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); + int origIndex = ccgDM_getFaceMapIndex(ss, f); - numVerts = CCS_getFaceNumVerts(f); + numVerts = ccgSubSurf_getFaceNumVerts(f); if(faceFlags) { - drawSmooth = (faceFlags[index*4] & ME_SMOOTH); - new_matnr= faceFlags[index*4 + 1] + 1; + drawSmooth = (faceFlags[index*2] & ME_SMOOTH); + new_matnr= faceFlags[index*2 + 1] + 1; } else { drawSmooth = 1; @@ -2072,8 +2054,8 @@ static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); - VertData *vda, *vdb; + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + DMGridData *vda, *vdb; if (drawSmooth) { for (y=0; y<gridFaces; y++) { @@ -2118,7 +2100,7 @@ static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo float *cco = faceGridData[(y+1)*gridSize + x + 1].co; float *dco = faceGridData[(y+1)*gridSize + x].co; - cgdm_glNormalFast(aco, bco, cco, dco); + ccgDM_glNormalFast(aco, bco, cco, dco); PASSATTRIB(0, 1, 1); glVertex3fv(dco); @@ -2139,7 +2121,7 @@ static void cgdm_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo #undef PASSATTRIB - CCFIter_free(fi); + ccgFaceIterator_free(fi); } static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs)) { @@ -2148,9 +2130,9 @@ static void cgdm_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *at static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCFaceIterator *fi = CCS_getFaceIterator(ss); - int gridSize = CCS_getGridSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); + int gridSize = ccgSubSurf_getGridSize(ss); unsigned char *cp1, *cp2; int useTwoSide=1; @@ -2167,12 +2149,12 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha glEnable(GL_CULL_FACE); glBegin(GL_QUADS); - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int S, x, y, numVerts = CCS_getFaceNumVerts(f); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); for (y=0; y<gridSize-1; y++) { for (x=0; x<gridSize-1; x++) { float *a = faceGridData[(y+0)*gridSize + x].co; @@ -2208,7 +2190,7 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha } glEnd(); - CCFIter_free(fi); + ccgFaceIterator_free(fi); } static void cgdm_drawFacesTex_common(DerivedMesh *dm, @@ -2217,25 +2199,28 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm, void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - MCol *mcol = DM_get_tessface_data_layer(dm, CD_MCOL); + CCGSubSurf *ss = cgdm->ss; + MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL); MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE); - char *faceFlags = DM_get_tessface_data_layer(dm, CD_FLAGS); - int i, totface, flag, gridSize = CCS_getGridSize(ss); + char *faceFlags = cgdm->faceFlags; + int i, totface, flag, gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; - totface = CCS_getNumFaces(ss); + if(!mcol) + mcol = dm->getTessFaceDataArray(dm, CD_MCOL); + + totface = ccgSubSurf_getNumFaces(ss); for(i = 0; i < totface; i++) { - CCFace *f = cgdm->faceMap[i].face; - int S, x, y, numVerts = CCS_getFaceNumVerts(f); - int drawSmooth, index = cgdm_getFaceMapIndex(ss, f); - int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); + CCGFace *f = cgdm->faceMap[i].face; + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); + int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); + int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); unsigned char *cp= NULL; int mat_nr; if(faceFlags) { - drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH); - mat_nr= faceFlags[origIndex*4 + 1]; + drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH); + mat_nr= faceFlags[origIndex*2 + 1]; } else { drawSmooth = 1; @@ -2260,8 +2245,8 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm, } for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); - VertData *a, *b; + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); + DMGridData *a, *b; if (drawSmooth) { glShadeModel(GL_SMOOTH); @@ -2315,7 +2300,7 @@ static void cgdm_drawFacesTex_common(DerivedMesh *dm, float *c_co = faceGridData[(y+1)*gridSize + x + 1].co; float *d_co = faceGridData[(y+1)*gridSize + x].co; - cgdm_glNormalFast(a_co, b_co, c_co, d_co); + ccgDM_glNormalFast(a_co, b_co, c_co, d_co); if(tf) glTexCoord2fv(tf->uv[1]); if(cp) glColor3ub(cp[7], cp[6], cp[5]); @@ -2386,24 +2371,38 @@ static void cgdm_drawUVEdges(DerivedMesh *dm) } } -static void cgdm_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) { +static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCFaceIterator *fi = CCS_getFaceIterator(ss); - int i, gridSize = CCS_getGridSize(ss); - char *faceFlags = dm->getTessFaceDataArray(dm, CD_FLAGS); - - for (i=0; !CCFIter_isStopped(fi); i++,CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int S, x, y, numVerts = CCS_getFaceNumVerts(f); - int drawSmooth, index = cgdm_getFaceMapIndex(ss, f); + CCGSubSurf *ss = cgdm->ss; + MCol *mcol= NULL; + int i, gridSize = ccgSubSurf_getGridSize(ss); + char *faceFlags = cgdm->faceFlags; + int gridFaces = gridSize - 1, totface; + + if(useColors) { + mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL); + if(!mcol) + mcol = dm->getTessFaceDataArray(dm, CD_MCOL); + } + + totface = ccgSubSurf_getNumFaces(ss); + for(i = 0; i < totface; i++) { + CCGFace *f = cgdm->faceMap[i].face; + int S, x, y, numVerts = ccgSubSurf_getFaceNumVerts(f); + int drawSmooth, index = ccgDM_getFaceMapIndex(ss, f); int origIndex; + unsigned char *cp= NULL; - origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); + origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); - if(faceFlags) drawSmooth = (faceFlags[origIndex*4] & ME_SMOOTH); + if(faceFlags) drawSmooth = (faceFlags[origIndex*2] & ME_SMOOTH); else drawSmooth = 1; - + + if(mcol) { + cp= (unsigned char*)mcol; + mcol += gridFaces*gridFaces*numVerts*4; + } + if (index!=-1) { int draw; draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, index, &drawSmooth); @@ -2415,44 +2414,64 @@ static void cgdm_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us } for (S=0; S<numVerts; S++) { - VertData *faceGridData = CCS_getFaceGridDataArray(ss, f, S); + DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); if (drawSmooth) { glShadeModel(GL_SMOOTH); - for (y=0; y<gridSize-1; y++) { + for (y=0; y<gridFaces; y++) { + DMGridData *a, *b; glBegin(GL_QUAD_STRIP); - for (x=0; x<gridSize; x++) { - VertData *a = &faceGridData[(y+0)*gridSize + x]; - VertData *b = &faceGridData[(y+1)*gridSize + x]; + for (x=0; x<gridFaces; x++) { + a = &faceGridData[(y+0)*gridSize + x]; + b = &faceGridData[(y+1)*gridSize + x]; + if(cp) glColor3ub(cp[3], cp[2], cp[1]); glNormal3fv(a->no); glVertex3fv(a->co); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); glNormal3fv(b->no); glVertex3fv(b->co); + + if(x != gridFaces-1) { + if(cp) cp += 16; + } } + + a = &faceGridData[(y+0)*gridSize + x]; + b = &faceGridData[(y+1)*gridSize + x]; + + if(cp) glColor3ub(cp[15], cp[14], cp[13]); + glNormal3fv(a->no); + glVertex3fv(a->co); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); + glNormal3fv(b->no); + glVertex3fv(b->co); + + if(cp) cp += 16; + glEnd(); } } else { glShadeModel(GL_FLAT); glBegin(GL_QUADS); - for (y=0; y<gridSize-1; y++) { - for (x=0; x<gridSize-1; x++) { + for (y=0; y<gridFaces; y++) { + for (x=0; x<gridFaces; x++) { float *a = faceGridData[(y+0)*gridSize + x].co; float *b = faceGridData[(y+0)*gridSize + x + 1].co; float *c = faceGridData[(y+1)*gridSize + x + 1].co; float *d = faceGridData[(y+1)*gridSize + x].co; - float a_cX = c[0]-a[0], a_cY = c[1]-a[1], a_cZ = c[2]-a[2]; - float b_dX = d[0]-b[0], b_dY = d[1]-b[1], b_dZ = d[2]-b[2]; - float no[3]; - - no[0] = b_dY*a_cZ - b_dZ*a_cY; - no[1] = b_dZ*a_cX - b_dX*a_cZ; - no[2] = b_dX*a_cY - b_dY*a_cX; - glNormal3fv(no); + + ccgDM_glNormalFast(a, b, c, d); + if(cp) glColor3ub(cp[7], cp[6], cp[5]); glVertex3fv(d); + if(cp) glColor3ub(cp[11], cp[10], cp[9]); glVertex3fv(c); + if(cp) glColor3ub(cp[15], cp[14], cp[13]); glVertex3fv(b); + if(cp) glColor3ub(cp[3], cp[2], cp[1]); glVertex3fv(a); + + if(cp) cp += 16; } } glEnd(); @@ -2463,26 +2482,24 @@ static void cgdm_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us } } } - - CCFIter_free(fi); } static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - int i, useAging, edgeSize = CCS_getEdgeSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); + ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); - int index = cgdm_getEdgeMapIndex(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ss, e); glBegin(GL_LINE_STRIP); if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { if (useAging && !(G.f&G_BACKBUFSEL)) { - int ageCol = 255-CCS_getEdgeAge(ss, e)*4; + int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; glColor3ub(0, ageCol>0?ageCol:0, 0); } @@ -2494,20 +2511,20 @@ static void cgdm_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *us glEnd(); } - CCEIter_free(ei); + ccgEdgeIterator_free(ei); } static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCEdgeIterator *ei = CCS_getEdgeIterator(ss); - int i, useAging, edgeSize = CCS_getEdgeSize(ss); + CCGSubSurf *ss = cgdm->ss; + CCGEdgeIterator *ei = ccgSubSurf_getEdgeIterator(ss); + int i, useAging, edgeSize = ccgSubSurf_getEdgeSize(ss); - CCS_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); + ccgSubSurf_getUseAgeCounts(ss, &useAging, NULL, NULL, NULL); - for (; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); - VertData *edgeData = CCS_getEdgeDataArray(ss, e); - int index = cgdm_getEdgeMapIndex(ss, e); + for (; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); + DMGridData *edgeData = ccgSubSurf_getEdgeDataArray(ss, e); + int index = ccgDM_getEdgeMapIndex(ss, e); glBegin(GL_LINE_STRIP); if (index!=-1 && (!setDrawOptions || setDrawOptions(userData, index))) { @@ -2515,7 +2532,7 @@ static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(vo setDrawInterpOptions(userData, index, (float) i/(edgeSize-1)); if (useAging && !(G.f&G_BACKBUFSEL)) { - int ageCol = 255-CCS_getEdgeAge(ss, e)*4; + int ageCol = 255-ccgSubSurf_getEdgeAge(ss, e)*4; glColor3ub(0, ageCol>0?ageCol:0, 0); } @@ -2525,42 +2542,60 @@ static void cgdm_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(vo glEnd(); } - CCEIter_free(ei); + ccgEdgeIterator_free(ei); } static void cgdm_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; - CSubSurf *ss = cgdm->ss; - CCFaceIterator *fi = CCS_getFaceIterator(ss); + CCGSubSurf *ss = cgdm->ss; + CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); - for (; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); - int index = cgdm_getFaceMapIndex(ss, f); + for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); + int index = ccgDM_getFaceMapIndex(ss, f); if (index!=-1) { /* Face center data normal isn't updated atm. */ - VertData *vd = CCS_getFaceGridData(ss, f, 0, 0, 0); + DMGridData *vd = ccgSubSurf_getFaceGridData(ss, f, 0, 0, 0); func(userData, index, vd->co, vd->no); } } - CCFIter_free(fi); + ccgFaceIterator_free(fi); } static void cgdm_release(DerivedMesh *dm) { CCGDerivedMesh *cgdm = (CCGDerivedMesh*) dm; if (DM_release(dm)) { + /* Before freeing, need to update the displacement map */ + if(cgdm->multires.modified) { + /* Check that mmd still exists */ + if(!cgdm->multires.local_mmd && BLI_findindex(&cgdm->multires.ob->modifiers, cgdm->multires.mmd) < 0) + cgdm->multires.mmd = NULL; + if(cgdm->multires.mmd) + cgdm->multires.update(dm); + } + + if(cgdm->pbvh) BLI_pbvh_free(cgdm->pbvh); + if(cgdm->gridFaces) MEM_freeN(cgdm->gridFaces); + if(cgdm->gridData) MEM_freeN(cgdm->gridData); + if(cgdm->gridAdjacency) MEM_freeN(cgdm->gridAdjacency); + if(cgdm->gridOffset) MEM_freeN(cgdm->gridOffset); + if(cgdm->freeSS) ccgSubSurf_free(cgdm->ss); + if(cgdm->reverseFaceMap) MEM_freeN(cgdm->reverseFaceMap); + + BLI_edgehash_free(cgdm->ehash, NULL); + + MEM_freeN(cgdm->edgeFlags); + MEM_freeN(cgdm->faceFlags); MEM_freeN(cgdm->vertMap); MEM_freeN(cgdm->edgeMap); MEM_freeN(cgdm->faceMap); - MEM_freeN(cgdm->reverseFaceMap); - BLI_edgehash_free(cgdm->ehash, NULL); MEM_freeN(cgdm); } } - void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, CustomData *pdata, int loopstart, int findex, int polyindex, int numTex, int numCol) @@ -2615,69 +2650,330 @@ void ccg_loops_to_corners(CustomData *fdata, CustomData *ldata, } } -/*this function requires dm to be a CDDM*/ -static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, +static void *ccgDM_get_vert_data_layer(DerivedMesh *dm, int type) +{ + if(type == CD_ORIGINDEX) { + /* create origindex on demand to save memory */ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + CCGSubSurf *ss= cgdm->ss; + int *origindex; + int a, index, totnone, totorig; + + DM_add_vert_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex= DM_get_vert_data_layer(dm, CD_ORIGINDEX); + + totorig = ccgSubSurf_getNumVerts(ss); + totnone= dm->numVertData - totorig; + + /* original vertices are at the end */ + for(a=0; a<totnone; a++) + origindex[a]= ORIGINDEX_NONE; + + for(index=0; index<totorig; index++, a++) { + CCGVert *v = cgdm->vertMap[index].vert; + origindex[a] = ccgDM_getVertMapIndex(cgdm->ss, v); + } + + return origindex; + } + + return DM_get_vert_data_layer(dm, type); +} + +static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) +{ + if(type == CD_ORIGINDEX) { + /* create origindex on demand to save memory */ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + CCGSubSurf *ss= cgdm->ss; + int *origindex; + int a, i, index, totnone, totorig, totedge; + int edgeSize= ccgSubSurf_getEdgeSize(ss); + + DM_add_edge_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex= DM_get_edge_data_layer(dm, CD_ORIGINDEX); + + totedge= ccgSubSurf_getNumEdges(ss); + totorig= totedge*(edgeSize - 1); + totnone= dm->numEdgeData - totorig; + + /* original edges are at the end */ + for(a=0; a<totnone; a++) + origindex[a]= ORIGINDEX_NONE; + + for(index=0; index<totedge; index++) { + CCGEdge *e= cgdm->edgeMap[index].edge; + int mapIndex= ccgDM_getEdgeMapIndex(ss, e); + + for(i = 0; i < edgeSize - 1; i++, a++) + origindex[a]= mapIndex; + } + + return origindex; + } + + return DM_get_edge_data_layer(dm, type); +} + +static void *ccgDM_get_face_data_layer(DerivedMesh *dm, int type) +{ + if(type == CD_ORIGINDEX) { + /* create origindex on demand to save memory */ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + CCGSubSurf *ss= cgdm->ss; + int *origindex; + int a, i, index, totface; + int gridFaces = ccgSubSurf_getGridSize(ss) - 1; + + DM_add_face_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); + origindex= DM_get_tessface_data_layer(dm, CD_ORIGINDEX); + + totface= ccgSubSurf_getNumFaces(ss); + + for(a=0, index=0; index<totface; index++) { + CCGFace *f = cgdm->faceMap[index].face; + int numVerts = ccgSubSurf_getFaceNumVerts(f); + int mapIndex = ccgDM_getFaceMapIndex(ss, f); + + for(i=0; i<gridFaces*gridFaces*numVerts; i++, a++) + origindex[a]= mapIndex; + } + + return origindex; + } + + return DM_get_tessface_data_layer(dm, type); +} + +static int ccgDM_getNumGrids(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + int index, numFaces, numGrids; + + numFaces= ccgSubSurf_getNumFaces(cgdm->ss); + numGrids= 0; + + for(index=0; index<numFaces; index++) { + CCGFace *f = cgdm->faceMap[index].face; + numGrids += ccgSubSurf_getFaceNumVerts(f); + } + + return numGrids; +} + +static int ccgDM_getGridSize(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + return ccgSubSurf_getGridSize(cgdm->ss); +} + +static int cgdm_adjacent_grid(CCGSubSurf *ss, int *gridOffset, CCGFace *f, int S, int offset) +{ + CCGFace *adjf; + CCGEdge *e; + int i, j= 0, numFaces, fIndex, numEdges= 0; + + e = ccgSubSurf_getFaceEdge(ss, f, S); + numFaces = ccgSubSurf_getEdgeNumFaces(e); + + if(numFaces != 2) + return -1; + + for(i = 0; i < numFaces; i++) { + adjf = ccgSubSurf_getEdgeFace(e, i); + + if(adjf != f) { + numEdges = ccgSubSurf_getFaceNumVerts(adjf); + for(j = 0; j < numEdges; j++) + if(ccgSubSurf_getFaceEdge(ss, adjf, j) == e) + break; + + if(j != numEdges) + break; + } + } + + fIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, adjf)); + + return gridOffset[fIndex] + (j + offset)%numEdges; +} + +static void cgdm_create_grids(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + CCGSubSurf *ss= cgdm->ss; + DMGridData **gridData; + DMGridAdjacency *gridAdjacency, *adj; + CCGFace **gridFaces; + int *gridOffset; + int index, numFaces, numGrids, S, gIndex, gridSize; + + if(cgdm->gridData) + return; + + numGrids = ccgDM_getNumGrids(dm); + numFaces = ccgSubSurf_getNumFaces(ss); + gridSize = ccgDM_getGridSize(dm); + + /* compute offset into grid array for each face */ + gridOffset = MEM_mallocN(sizeof(int)*numFaces, "cgdm.gridOffset"); + + for(gIndex = 0, index = 0; index < numFaces; index++) { + CCGFace *f = cgdm->faceMap[index].face; + int numVerts = ccgSubSurf_getFaceNumVerts(f); + + gridOffset[index] = gIndex; + gIndex += numVerts; + } + + /* compute grid data */ + gridData = MEM_mallocN(sizeof(DMGridData*)*numGrids, "cgdm.gridData"); + gridAdjacency = MEM_mallocN(sizeof(DMGridAdjacency)*numGrids, "cgdm.gridAdjacency"); + gridFaces = MEM_mallocN(sizeof(CCGFace*)*numGrids, "cgdm.gridFaces"); + + for(gIndex = 0, index = 0; index < numFaces; index++) { + CCGFace *f = cgdm->faceMap[index].face; + int numVerts = ccgSubSurf_getFaceNumVerts(f); + + for(S = 0; S < numVerts; S++, gIndex++) { + int prevS = (S - 1 + numVerts) % numVerts; + int nextS = (S + 1 + numVerts) % numVerts; + + gridData[gIndex] = ccgSubSurf_getFaceGridDataArray(ss, f, S); + gridFaces[gIndex] = f; + + adj = &gridAdjacency[gIndex]; + + adj->index[0] = gIndex - S + nextS; + adj->rotation[0] = 3; + adj->index[1] = cgdm_adjacent_grid(ss, gridOffset, f, prevS, 0); + adj->rotation[1] = 1; + adj->index[2] = cgdm_adjacent_grid(ss, gridOffset, f, S, 1); + adj->rotation[2] = 3; + adj->index[3] = gIndex - S + prevS; + adj->rotation[3] = 1; + } + } + + cgdm->gridData = gridData; + cgdm->gridFaces = gridFaces; + cgdm->gridAdjacency = gridAdjacency; + cgdm->gridOffset = gridOffset; +} + +static DMGridData **ccgDM_getGridData(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + + cgdm_create_grids(dm); + return cgdm->gridData; +} + +static DMGridAdjacency *ccgDM_getGridAdjacency(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + + cgdm_create_grids(dm); + return cgdm->gridAdjacency; +} + +static int *ccgDM_getGridOffset(DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + + cgdm_create_grids(dm); + return cgdm->gridOffset; +} + +static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) +{ + CCGDerivedMesh *cgdm= (CCGDerivedMesh*)dm; + int gridSize, numGrids; + + if(cgdm->pbvh) + return cgdm->pbvh; + + if(cgdm->multires.mmd) { + cgdm_create_grids(dm); + + gridSize = ccgDM_getGridSize(dm); + numGrids = ccgDM_getNumGrids(dm); + + cgdm->pbvh = BLI_pbvh_new(); + BLI_pbvh_build_grids(cgdm->pbvh, cgdm->gridData, cgdm->gridAdjacency, + numGrids, gridSize, (void**)cgdm->gridFaces); + } + else if(ob->type == OB_MESH) { + Mesh *me= ob->data; + + cgdm->pbvh = BLI_pbvh_new(); + BLI_pbvh_build_mesh(cgdm->pbvh, me->mface, me->mvert, + me->totface, me->totvert); + } + + return cgdm->pbvh; +} + +static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm) { CCGDerivedMesh *cgdm = MEM_callocN(sizeof(*cgdm), "cgdm"); - CCVertIterator *vi; - CCEdgeIterator *ei; - CCFaceIterator *fi; + CCGVertIterator *vi; + CCGEdgeIterator *ei; + CCGFaceIterator *fi; int index, totvert, totedge, totface; int i; int vertNum, edgeNum, faceNum; int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex; /* *edgeOrigIndex - as yet, unused */ - int *edgeFlags; - char *faceFlags, *polyFlags; + short *edgeFlags; + char *faceFlags; int *loopidx = NULL, *vertidx = NULL; BLI_array_declare(loopidx); BLI_array_declare(vertidx); int loopindex, loopindex2; - int edgeSize; + int edgeSize, has_edge_origindex; int gridSize; int gridFaces, gridCuts; int gridSideVerts; - /*int gridInternalVerts; - as yet unused */ int gridSideEdges; int numTex, numCol; int gridInternalEdges; float *w = NULL, one = 1.0f; WeightTable wtable = {0}; - /* MVert *mvert = NULL; - as yet unused */ MCol *mcol; MEdge *medge = NULL, medge2; MFace *mface = NULL; MPoly *mpoly = NULL; - DM_from_template(&cgdm->dm, dm, CCS_getNumFinalVerts(ss), - CCS_getNumFinalEdges(ss), - CCS_getNumFinalFaces(ss), - CCS_getNumFinalFaces(ss)*4, - CCS_getNumFinalFaces(ss)); - DM_add_tessface_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL); - DM_add_face_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL); - DM_add_edge_layer(&cgdm->dm, CD_FLAGS, CD_CALLOC, NULL); + DM_from_template(&cgdm->dm, dm, ccgSubSurf_getNumFinalVerts(ss), + ccgSubSurf_getNumFinalEdges(ss), + ccgSubSurf_getNumFinalFaces(ss), + ccgSubSurf_getNumFinalFaces(ss)*4, + ccgSubSurf_getNumFinalFaces(ss)); numTex = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPUV); numCol = CustomData_number_of_layers(&cgdm->dm.loopData, CD_MLOOPCOL); if (numTex && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MTFACE) != numTex) - CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, CCS_getNumFinalFaces(ss)); + CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss)); else if (numCol && CustomData_number_of_layers(&cgdm->dm.faceData, CD_MCOL) != numCol) - CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, CCS_getNumFinalFaces(ss)); - - CustomData_set_layer_flag(&cgdm->dm.faceData, CD_FLAGS, CD_FLAG_NOCOPY); - CustomData_set_layer_flag(&cgdm->dm.edgeData, CD_FLAGS, CD_FLAG_NOCOPY); + CustomData_from_bmeshpoly(&cgdm->dm.faceData, &cgdm->dm.polyData, &cgdm->dm.loopData, ccgSubSurf_getNumFinalFaces(ss)); cgdm->dm.getMinMax = cgdm_getMinMax; cgdm->dm.getNumVerts = cgdm_getNumVerts; cgdm->dm.getNumTessFaces = cgdm_getNumTessFaces; cgdm->dm.getNumFaces = cgdm_getNumTessFaces; - cgdm->dm.newFaceIter = cgdm_newFaceIter; + cgdm->dm.getNumGrids = ccgDM_getNumGrids; + cgdm->dm.getGridSize = ccgDM_getGridSize; + cgdm->dm.getGridData = ccgDM_getGridData; + cgdm->dm.getGridAdjacency = ccgDM_getGridAdjacency; + cgdm->dm.getGridOffset = ccgDM_getGridOffset; + cgdm->dm.getPBVH = ccgDM_getPBVH; + cgdm->dm.newFaceIter = cgdm_newFaceIter; cgdm->dm.getNumEdges = cgdm_getNumEdges; cgdm->dm.getVert = cgdm_getFinalVert; cgdm->dm.getEdge = cgdm_getFinalEdge; @@ -2700,11 +2996,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, cgdm->dm.drawVerts = cgdm_drawVerts; cgdm->dm.drawEdges = cgdm_drawEdges; cgdm->dm.drawLooseEdges = cgdm_drawLooseEdges; - cgdm->dm.drawFacesSolid = cgdm_drawFacesSolid; + cgdm->dm.drawFacesSolid = ccgDM_drawFacesSolid; cgdm->dm.drawFacesColored = cgdm_drawFacesColored; cgdm->dm.drawFacesTex = cgdm_drawFacesTex; cgdm->dm.drawFacesGLSL = cgdm_drawFacesGLSL; - cgdm->dm.drawMappedFaces = cgdm_drawMappedFaces; + cgdm->dm.drawMappedFaces = ccgDM_drawMappedFaces; cgdm->dm.drawMappedFacesTex = cgdm_drawMappedFacesTex; cgdm->dm.drawMappedFacesGLSL = cgdm_drawMappedFacesGLSL; cgdm->dm.drawUVEdges = cgdm_drawUVEdges; @@ -2718,39 +3014,39 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, cgdm->drawInteriorEdges = drawInteriorEdges; cgdm->useSubsurfUv = useSubsurfUv; - totvert = CCS_getNumVerts(ss); + totvert = ccgSubSurf_getNumVerts(ss); cgdm->vertMap = MEM_mallocN(totvert * sizeof(*cgdm->vertMap), "vertMap"); - vi = CCS_getVertIterator(ss); - for(; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); + vi = ccgSubSurf_getVertIterator(ss); + for(; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); - cgdm->vertMap[GET_INT_FROM_POINTER(CCS_getVertVertHandle(v))].vert = v; + cgdm->vertMap[GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v))].vert = v; } - CCVIter_free(vi); + ccgVertIterator_free(vi); - totedge = CCS_getNumEdges(ss); + totedge = ccgSubSurf_getNumEdges(ss); cgdm->edgeMap = MEM_mallocN(totedge * sizeof(*cgdm->edgeMap), "edgeMap"); - ei = CCS_getEdgeIterator(ss); - for(; !CCEIter_isStopped(ei); CCEIter_next(ei)) { - CCEdge *e = CCEIter_getCurrent(ei); + ei = ccgSubSurf_getEdgeIterator(ss); + for(; !ccgEdgeIterator_isStopped(ei); ccgEdgeIterator_next(ei)) { + CCGEdge *e = ccgEdgeIterator_getCurrent(ei); - cgdm->edgeMap[GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e))].edge = e; + cgdm->edgeMap[GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e))].edge = e; } - totface = CCS_getNumFaces(ss); + totface = ccgSubSurf_getNumFaces(ss); cgdm->faceMap = MEM_mallocN(totface * sizeof(*cgdm->faceMap), "faceMap"); - fi = CCS_getFaceIterator(ss); - for(; !CCFIter_isStopped(fi); CCFIter_next(fi)) { - CCFace *f = CCFIter_getCurrent(fi); + fi = ccgSubSurf_getFaceIterator(ss); + for(; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { + CCGFace *f = ccgFaceIterator_getCurrent(fi); - cgdm->faceMap[GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f))].face = f; + cgdm->faceMap[GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f))].face = f; } - CCFIter_free(fi); + ccgFaceIterator_free(fi); - cgdm->reverseFaceMap = MEM_callocN(sizeof(int)*CCS_getNumFinalFaces(ss), "reverseFaceMap"); + cgdm->reverseFaceMap = MEM_callocN(sizeof(int)*ccgSubSurf_getNumFinalFaces(ss), "reverseFaceMap"); - edgeSize = CCS_getEdgeSize(ss); - gridSize = CCS_getGridSize(ss); + edgeSize = ccgSubSurf_getEdgeSize(ss); + gridSize = ccgSubSurf_getGridSize(ss); gridFaces = gridSize - 1; gridSideVerts = gridSize - 2; gridCuts = gridSize - 2; @@ -2766,30 +3062,31 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, medge = dm->getEdgeArray(dm); mface = dm->getTessFaceArray(dm); - /*CDDM hack*/ mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); + /*CDDM hack*/ + edgeFlags = cgdm->edgeFlags = MEM_callocN(sizeof(short)*totedge, "faceFlags"); + faceFlags = cgdm->faceFlags = MEM_callocN(sizeof(char)*2*totface, "faceFlags"); vertOrigIndex = DM_get_vert_data_layer(&cgdm->dm, CD_ORIGINDEX); /*edgeOrigIndex = DM_get_edge_data_layer(&cgdm->dm, CD_ORIGINDEX);*/ faceOrigIndex = DM_get_tessface_data_layer(&cgdm->dm, CD_ORIGINDEX); - faceFlags = DM_get_tessface_data_layer(&cgdm->dm, CD_FLAGS); polyOrigIndex = DM_get_face_data_layer(&cgdm->dm, CD_ORIGINDEX); - polyFlags = DM_get_face_data_layer(&cgdm->dm, CD_FLAGS); if (!CustomData_has_layer(&cgdm->dm.faceData, CD_MCOL)) DM_add_tessface_layer(&cgdm->dm, CD_MCOL, CD_CALLOC, NULL); mcol = DM_get_tessface_data_layer(&cgdm->dm, CD_MCOL); + has_edge_origindex = CustomData_has_layer(&cgdm->dm.edgeData, CD_ORIGINDEX); faceNum = 0; loopindex = loopindex2 = 0; //current loop index for (index = 0; index < totface; index++) { - CCFace *f = cgdm->faceMap[index].face; - int numVerts = CCS_getFaceNumVerts(f); + CCGFace *f = cgdm->faceMap[index].face; + int numVerts = ccgSubSurf_getFaceNumVerts(f); int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges); - int mapIndex = cgdm_getFaceMapIndex(ss, f); - int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); + int mapIndex = ccgDM_getFaceMapIndex(ss, f); + int origIndex = GET_INT_FROM_POINTER(ccgSubSurf_getFaceFaceHandle(ss, f)); int g2_wid = gridCuts+2; float *w2; int s, x, y; @@ -2800,8 +3097,12 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, cgdm->faceMap[index].startEdge = edgeNum; cgdm->faceMap[index].startFace = faceNum; + faceFlags[0] = mpoly[origIndex].flag; + faceFlags[1] = mpoly[origIndex].mat_nr; + faceFlags += 2; + /* set the face base vert */ - *((int*)CCS_getFaceUserData(ss, f)) = vertNum; + *((int*)ccgSubSurf_getFaceUserData(ss, f)) = vertNum; BLI_array_empty(loopidx); for (s=0; s<numVerts; s++) { @@ -2811,10 +3112,10 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, BLI_array_empty(vertidx); for(s = 0; s < numVerts; s++) { - CCVert *v = CCS_getFaceVert(ss, f, s); + CCGVert *v = ccgSubSurf_getFaceVert(ss, f, s); BLI_array_growone(vertidx); - vertidx[s] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + vertidx[s] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); } @@ -2822,9 +3123,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, w2 = w; // + numVerts*(g2_wid-1)*(g2_wid-1); //numVerts*((g2_wid-1)*g2_wid+g2_wid-1); DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, numVerts, vertNum); - if (vertOrigIndex) + if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; + ++vertOrigIndex; + } + ++vertNum; /*interpolate per-vert data*/ @@ -2834,9 +3137,11 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, numVerts, vertNum); - if (vertOrigIndex) + if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; + ++vertOrigIndex; + } + ++vertNum; } } @@ -2849,17 +3154,22 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, DM_interp_vert_data(dm, &cgdm->dm, vertidx, w2, numVerts, vertNum); - if (vertOrigIndex) + if (vertOrigIndex) { *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; + ++vertOrigIndex; + } + ++vertNum; } } } - for(i = 0; i < numFinalEdges; ++i) - *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, - CD_ORIGINDEX) = ORIGINDEX_NONE; + if (has_edge_origindex) { + for(i = 0; i < numFinalEdges; ++i) + *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, + CD_ORIGINDEX) = ORIGINDEX_NONE; + } + for (s=0; s<numVerts; s++) { /*interpolate per-face data*/ for (y=0; y<gridFaces; y++) { @@ -2892,86 +3202,88 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, &cgdm->dm.polyData, loopindex2-4, faceNum, faceNum, numTex, numCol); /*set original index data*/ - *faceOrigIndex = origIndex; - *polyOrigIndex = origIndex; + if (faceOrigIndex) { + *faceOrigIndex = origIndex; + faceOrigIndex++; + } + if (polyOrigIndex) { + *polyOrigIndex = origIndex; + polyOrigIndex++; + } cgdm->reverseFaceMap[faceNum] = index; - faceOrigIndex++; - polyOrigIndex++; faceNum++; } } } - polyFlags[0] = mpoly[origIndex].flag; - polyFlags[1] = mpoly[origIndex].mat_nr; - faceFlags[0] = polyFlags[0]; - faceFlags[1] = polyFlags[1]; - - faceFlags += 4; - polyFlags += 4; edgeNum += numFinalEdges; } - edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS); for(index = 0; index < totedge; ++index) { - CCEdge *e = cgdm->edgeMap[index].edge; + CCGEdge *e = cgdm->edgeMap[index].edge; int numFinalEdges = edgeSize - 1; - int mapIndex = cgdm_getEdgeMapIndex(ss, e); + int mapIndex = ccgDM_getEdgeMapIndex(ss, e); int x; int vertIdx[2]; - int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e)); + int edgeIdx = GET_INT_FROM_POINTER(ccgSubSurf_getEdgeEdgeHandle(e)); - CCVert *v; - v = CCS_getEdgeVert0(e); - vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - v = CCS_getEdgeVert1(e); - vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + CCGVert *v; + v = ccgSubSurf_getEdgeVert0(e); + vertIdx[0] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); + v = ccgSubSurf_getEdgeVert1(e); + vertIdx[1] = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); cgdm->edgeMap[index].startVert = vertNum; cgdm->edgeMap[index].startEdge = edgeNum; + if(edgeIdx >= 0 && edgeFlags) + edgeFlags[edgeIdx] = medge[edgeIdx].flag; + /* set the edge base vert */ - *((int*)CCS_getEdgeUserData(ss, e)) = vertNum; + *((int*)ccgSubSurf_getEdgeUserData(ss, e)) = vertNum; for(x = 1; x < edgeSize - 1; x++) { float w[2]; w[1] = (float) x / (edgeSize - 1); w[0] = 1 - w[1]; DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum); - *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; + if (vertOrigIndex) { + *vertOrigIndex = ORIGINDEX_NONE; + ++vertOrigIndex; + } ++vertNum; } for(i = 0; i < numFinalEdges; ++i) { - if(edgeIdx >= 0 && edgeFlags) - edgeFlags[edgeNum + i] = medge[edgeIdx].flag; - - *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, + if (has_edge_origindex) { + *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, CD_ORIGINDEX) = mapIndex; + } } edgeNum += numFinalEdges; } for(index = 0; index < totvert; ++index) { - CCVert *v = cgdm->vertMap[index].vert; - int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v); + CCGVert *v = cgdm->vertMap[index].vert; + int mapIndex = ccgDM_getVertMapIndex(cgdm->ss, v); int vidx; - vidx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); + vidx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); cgdm->vertMap[index].startVert = vertNum; /* set the vert base vert */ - *((int*) CCS_getVertUserData(ss, v)) = vertNum; + *((int*) ccgSubSurf_getVertUserData(ss, v)) = vertNum; DM_copy_vert_data(dm, &cgdm->dm, vidx, vertNum, 1); - *vertOrigIndex = mapIndex; - ++vertOrigIndex; + if (vertOrigIndex) { + *vertOrigIndex = mapIndex; + ++vertOrigIndex; + } ++vertNum; } @@ -2990,207 +3302,15 @@ static CCGDerivedMesh *getCCGDerivedMesh(CSubSurf *ss, cgdm_getFinalEdge((DerivedMesh*)cgdm, i, &medge2); BLI_edgehash_insert(cgdm->ehash, medge2.v1, medge2.v2, SET_INT_IN_POINTER(i)); } -#if 0 - for(index = 0; index < totface; ++index) { - CCFace *f = cgdm->faceMap[index].face; - int numVerts = CCS_getFaceNumVerts(f); - int numFinalEdges = numVerts * (gridSideEdges + gridInternalEdges); - int mapIndex = cgdm_getFaceMapIndex(ss, f); - int origIndex = GET_INT_FROM_POINTER(CCS_getFaceFaceHandle(ss, f)); - FaceVertWeight *weight = (numVerts == 4) ? qweight : tweight; - int S, x, y; - - cgdm->faceMap[index].startVert = vertNum; - cgdm->faceMap[index].startEdge = edgeNum; - cgdm->faceMap[index].startFace = faceNum; - /* set the face base vert */ - *((int*)CCS_getFaceUserData(ss, f)) = vertNum; - for(S = 0; S < numVerts; S++) { - CCVert *v = CCS_getFaceVert(ss, f, S); - BLI_array_growone(vertIdx); - - vertIdx[S] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - } - - DM_interp_vert_data(dm, &cgdm->dm, vertIdx, weight[0][0], - numVerts, vertNum); - *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; - ++vertNum; - - for(S = 0; S < numVerts; S++) { - int prevS = (S - 1 + numVerts) % numVerts; - int nextS = (S + 1) % numVerts; - int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; - - for(x = 1; x < gridFaces; x++) { - float w[4]; -#if 0 //BMESH_TODO - w[prevS] = weight[x][0][0]; - w[S] = weight[x][0][1]; - w[nextS] = weight[x][0][2]; - w[otherS] = weight[x][0][3]; - DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, - numVerts, vertNum); -#endif - *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; - ++vertNum; - } - } - - for(S = 0; S < numVerts; S++) { - int prevS = (S - 1 + numVerts) % numVerts; - int nextS = (S + 1) % numVerts; - int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; - for(y = 1; y < gridFaces; y++) { - for(x = 1; x < gridFaces; x++) { - float w[4]; -#if 0 //BMESH_TODO - w[prevS] = weight[y * gridFaces + x][0][0]; - w[S] = weight[y * gridFaces + x][0][1]; - w[nextS] = weight[y * gridFaces + x][0][2]; - w[otherS] = weight[y * gridFaces + x][0][3]; - DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, - numVerts, vertNum); -#endif - *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; - ++vertNum; - } - } - } - - for(i = 0; i < numFinalEdges; ++i) - *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, - CD_ORIGINDEX) = ORIGINDEX_NONE; - - for(S = 0; S < numVerts; S++) { - int prevS = (S - 1 + numVerts) % numVerts; - int nextS = (S + 1) % numVerts; - int otherS = (numVerts == 4) ? (S + 2) % numVerts : 3; - - weight = (numVerts == 4) ? qweight : tweight; - - for(y = 0; y < gridFaces; y++) { - for(x = 0; x < gridFaces; x++) { - FaceVertWeight w; - int j; - -#if 1 //BMESH_TODO - for(j = 0; j < 4; ++j) { - w[j][prevS] = (*weight)[j][0]; - w[j][S] = (*weight)[j][1]; - w[j][nextS] = (*weight)[j][2]; - w[j][otherS] = (*weight)[j][3]; - } - - DM_interp_tessface_data(dm, &cgdm->dm, &origIndex, NULL, - &w, 1, faceNum); - weight++; -#endif - - *faceOrigIndex = mapIndex; - - ++faceOrigIndex; - ++faceNum; - } - } - } - - faceFlags[index*4] = mface[origIndex].flag; - faceFlags[index*4 + 1] = mface[origIndex].mat_nr; - - edgeNum += numFinalEdges; - } - - if(useSubsurfUv) { - CustomData *fdata = &cgdm->dm.faceData; - CustomData *dmfdata = &dm->faceData; - int numlayer = CustomData_number_of_layers(fdata, CD_MTFACE); - int dmnumlayer = CustomData_number_of_layers(dmfdata, CD_MTFACE); - - for (i=0; i<numlayer && i<dmnumlayer; i++) - set_subsurf_uv(ss, dm, &cgdm->dm, i); - } - - edgeFlags = DM_get_edge_data_layer(&cgdm->dm, CD_FLAGS); - - for(index = 0; index < totedge; ++index) { - CCEdge *e = cgdm->edgeMap[index].edge; - int numFinalEdges = edgeSize - 1; - int mapIndex = cgdm_getEdgeMapIndex(ss, e); - int x; - int vertIdx[2]; - int edgeIdx = GET_INT_FROM_POINTER(CCS_getEdgeEdgeHandle(e)); - - CCVert *v; - v = CCS_getEdgeVert0(e); - vertIdx[0] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - v = CCS_getEdgeVert1(e); - vertIdx[1] = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - - cgdm->edgeMap[index].startVert = vertNum; - cgdm->edgeMap[index].startEdge = edgeNum; - - /* set the edge base vert */ - *((int*)CCS_getEdgeUserData(ss, e)) = vertNum; - - for(x = 1; x < edgeSize - 1; x++) { - float w[2]; - w[1] = (float) x / (edgeSize - 1); - w[0] = 1 - w[1]; - DM_interp_vert_data(dm, &cgdm->dm, vertIdx, w, 2, vertNum); - *vertOrigIndex = ORIGINDEX_NONE; - ++vertOrigIndex; - ++vertNum; - } - - for(i = 0; i < numFinalEdges; ++i) { - if(edgeIdx >= 0 && edgeFlags) - edgeFlags[edgeNum + i] = medge[edgeIdx].flag; - - *(int *)DM_get_edge_data(&cgdm->dm, edgeNum + i, - CD_ORIGINDEX) = mapIndex; - } - - edgeNum += numFinalEdges; - } - - for(index = 0; index < totvert; ++index) { - CCVert *v = cgdm->vertMap[index].vert; - int mapIndex = cgdm_getVertMapIndex(cgdm->ss, v); - int vertIdx; - - vertIdx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - - cgdm->vertMap[index].startVert = vertNum; - - /* set the vert base vert */ - *((int*) CCS_getVertUserData(ss, v)) = vertNum; - - DM_copy_vert_data(dm, &cgdm->dm, vertIdx, vertNum, 1); - - *vertOrigIndex = mapIndex; - ++vertOrigIndex; - ++vertNum; - } - - MEM_freeN(qweight); - MEM_freeN(tweight); - - BLI_array_free(vertIdx); -#endif return cgdm; } /***/ -struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( +struct DerivedMesh *subsurf_make_derived_from_derived( struct DerivedMesh *dm, struct SubsurfModifierData *smd, - struct MultiresSubsurf *ms, int useRenderParams, float (*vertCos)[3], int isFinalCalc, int editMode) { @@ -3198,19 +3318,19 @@ struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; int useSubsurfUv = smd->flags & eSubsurfModifierFlag_SubsurfUv; int drawInteriorEdges = !(smd->flags & eSubsurfModifierFlag_ControlEdges); - DerivedMesh *result; + CCGDerivedMesh *result = NULL; if(editMode) { smd->emCache = _getSubSurf(smd->emCache, smd->levels, useAging, 0, useSimple); ss_sync_from_derivedmesh(smd->emCache, dm, vertCos, useSimple); - return (DerivedMesh *)getCCGDerivedMesh(smd->emCache, - drawInteriorEdges, - useSubsurfUv, dm); + result = getCCGDerivedMesh(smd->emCache, + drawInteriorEdges, + useSubsurfUv, dm); } else if(useRenderParams) { /* Do not use cache in render mode. */ - CSubSurf *ss; + CCGSubSurf *ss; int levels; levels= smd->renderLevels; // XXX get_render_subsurf_level(&scene->r, smd->renderLevels); @@ -3221,16 +3341,14 @@ struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); - result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges, - useSubsurfUv, dm, ms); + result = getCCGDerivedMesh(ss, + drawInteriorEdges, useSubsurfUv, dm); - CCS_free(ss); - - return result; + result->freeSS = 1; } else { int useIncremental = 1; //(smd->flags & eSubsurfModifierFlag_Incremental); int useAging = smd->flags & eSubsurfModifierFlag_DebugIncr; - CSubSurf *ss; + CCGSubSurf *ss; /* It is quite possible there is a much better place to do this. It * depends a bit on how rigourously we expect this function to never @@ -3241,7 +3359,7 @@ struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( * comment that no one will read? Hmmm. - zr */ if(smd->emCache) { - CCS_free(smd->emCache); + ccgSubSurf_free(smd->emCache); smd->emCache = NULL; } @@ -3251,57 +3369,27 @@ struct DerivedMesh *subsurf_make_derived_from_derived_with_multires( ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); - - return ss_to_cdderivedmesh(ss, 0, drawInteriorEdges, - useSubsurfUv, dm, ms); - - /*return (DerivedMesh *)getCCGDerivedMesh(smd->mCache, - drawInteriorEdges, - useSubsurfUv, dm);*/ + result = getCCGDerivedMesh(smd->mCache, + drawInteriorEdges, + useSubsurfUv, dm); } else { if (smd->mCache && isFinalCalc) { - CCS_free(smd->mCache); + ccgSubSurf_free(smd->mCache); smd->mCache = NULL; } ss = _getSubSurf(NULL, smd->levels, 0, 1, useSimple); ss_sync_from_derivedmesh(ss, dm, vertCos, useSimple); - /*smd->mCache = ss; - result = (DerivedMesh *)getCCGDerivedMesh(smd->mCache, - drawInteriorEdges, - useSubsurfUv, dm);*/ - - result = ss_to_cdderivedmesh(ss, 0, drawInteriorEdges, - useSubsurfUv, dm, ms); + result = getCCGDerivedMesh(ss, drawInteriorEdges, useSubsurfUv, dm); - CCS_free(ss); - - return result; + if(isFinalCalc) + smd->mCache = ss; + else + result->freeSS = 1; } } -} - -struct DerivedMesh *subsurf_make_derived_from_derived( - struct DerivedMesh *dm, - struct SubsurfModifierData *smd, - int useRenderParams, float (*vertCos)[3], - int isFinalCalc, int editMode) -{ - DerivedMesh *cddm = NULL, *result; - - if (!CDDM_Check(dm)) { - cddm = CDDM_copy(dm, 0); - dm = cddm; - } - - result = subsurf_make_derived_from_derived_with_multires(dm, smd, NULL, useRenderParams, vertCos, isFinalCalc, editMode); - - if (cddm) { - cddm->needsFree = 1; - cddm->release(cddm); - } - + return result; } @@ -3312,19 +3400,19 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) * calculated vert positions is incorrect for the verts * on the boundary of the mesh. */ - CSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0); + CCGSubSurf *ss = _getSubSurf(NULL, 1, 0, 1, 0); float edge_sum[3], face_sum[3]; - CCVertIterator *vi; + CCGVertIterator *vi; DerivedMesh *dm = CDDM_from_mesh(me, NULL); ss_sync_from_derivedmesh(ss, dm, NULL, 0); - vi = CCS_getVertIterator(ss); - for (; !CCVIter_isStopped(vi); CCVIter_next(vi)) { - CCVert *v = CCVIter_getCurrent(vi); - int idx = GET_INT_FROM_POINTER(CCS_getVertVertHandle(v)); - int N = CCS_getVertNumEdges(v); - int numFaces = CCS_getVertNumFaces(v); + vi = ccgSubSurf_getVertIterator(ss); + for (; !ccgVertIterator_isStopped(vi); ccgVertIterator_next(vi)) { + CCGVert *v = ccgVertIterator_getCurrent(vi); + int idx = GET_INT_FROM_POINTER(ccgSubSurf_getVertVertHandle(v)); + int N = ccgSubSurf_getVertNumEdges(v); + int numFaces = ccgSubSurf_getVertNumFaces(v); float *co; int i; @@ -3332,12 +3420,12 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) face_sum[0]= face_sum[1]= face_sum[2]= 0.0; for (i=0; i<N; i++) { - CCEdge *e = CCS_getVertEdge(v, i); - add_v3_v3v3(edge_sum, edge_sum, CCS_getEdgeData(ss, e, 1)); + CCGEdge *e = ccgSubSurf_getVertEdge(v, i); + add_v3_v3v3(edge_sum, edge_sum, ccgSubSurf_getEdgeData(ss, e, 1)); } for (i=0; i<numFaces; i++) { - CCFace *f = CCS_getVertFace(v, i); - add_v3_v3v3(face_sum, face_sum, CCS_getFaceCenterData(f)); + CCGFace *f = ccgSubSurf_getVertFace(v, i); + add_v3_v3v3(face_sum, face_sum, ccgSubSurf_getFaceCenterData(f)); } /* ad-hoc correction for boundary vertices, to at least avoid them @@ -3345,14 +3433,14 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) if(numFaces && numFaces != N) mul_v3_fl(face_sum, (float)N/(float)numFaces); - co = CCS_getVertData(ss, v); + co = ccgSubSurf_getVertData(ss, v); positions_r[idx][0] = (co[0]*N*N + edge_sum[0]*4 + face_sum[0])/(N*(N+5)); positions_r[idx][1] = (co[1]*N*N + edge_sum[1]*4 + face_sum[1])/(N*(N+5)); positions_r[idx][2] = (co[2]*N*N + edge_sum[2]*4 + face_sum[2])/(N*(N+5)); } - CCVIter_free(vi); + ccgVertIterator_free(vi); - CCS_free(ss); + ccgSubSurf_free(ss); dm->release(dm); } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 0171c58f2c6..818e6195049 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -518,7 +518,7 @@ void default_tex(Tex *tex) /* ------------------------------------------------------------------------- */ -Tex *add_texture(char *name) +Tex *add_texture(const char *name) { Tex *tex; diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index 7c58a4f9499..ec3d1185179 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -40,6 +40,7 @@ #include "BLI_blenlib.h" #include "BKE_global.h" +#include "BKE_report.h" #include "BKE_utildefines.h" #include "BKE_writeavi.h" #include "AVI_avi.h" @@ -127,7 +128,7 @@ void makeavistring (RenderData *rd, char *string) } } -void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty) +int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports) { int x, y; char name[256]; @@ -153,10 +154,10 @@ void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty) else format = AVI_FORMAT_MJPEG; if (AVI_open_compress (name, avi, 1, format) != AVI_ERROR_NONE) { - printf("cannot open or start AVI movie file"); + BKE_report(reports, RPT_ERROR, "Cannot open or start AVI movie file."); MEM_freeN (avi); avi = NULL; - return; + return 0; } AVI_set_compress_option (avi, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &x); @@ -170,18 +171,17 @@ void start_avi(struct Scene *scene, RenderData *rd, int rectx, int recty) /* avi->odd_fields= (rd->mode & R_ODDFIELD)?1:0; */ printf("Created avi: %s\n", name); + return 1; } -void append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty) +int append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) { unsigned int *rt1, *rt2, *rectot; int x, y; char *cp, rt; - if (avi == NULL) { - G.afbreek = 1; - return; - } + if (avi == NULL) + return 0; /* note that libavi free's the buffer... stupid interface - zr */ rectot= MEM_mallocN(rectx*recty*sizeof(int), "rectot"); @@ -205,6 +205,8 @@ void append_avi(RenderData *rd, int frame, int *pixels, int rectx, int recty) AVI_write_frame (avi, (frame-sframe), AVI_FORMAT_RGB32, rectot, rectx*recty*4); // printf ("added frame %3d (frame %3d in avi): ", frame, frame-sframe); + + return 1; } void end_avi(void) @@ -215,3 +217,4 @@ void end_avi(void) MEM_freeN (avi); avi= NULL; } + diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index 1953058fddf..417679417e4 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -52,23 +52,24 @@ #define snprintf _snprintf #endif -#include "BKE_writeffmpeg.h" - #include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" + #include "BLI_blenlib.h" +#include "AUD_C-API.h" /* must be before BKE_sound.h for define */ + #include "BKE_global.h" #include "BKE_idprop.h" +#include "BKE_main.h" +#include "BKE_report.h" +#include "BKE_sound.h" +#include "BKE_writeffmpeg.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" -#include "DNA_scene_types.h" - -#include "AUD_C-API.h" -#include "BKE_sound.h" -#include "BKE_main.h" - #ifdef HAVE_CONFIG_H #include <config.h> #endif @@ -239,10 +240,10 @@ static const char** get_file_extensions(int format) } /* Write a frame to the output file */ -static void write_video_frame(RenderData *rd, AVFrame* frame) +static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports) { int outsize = 0; - int ret; + int ret, success= 1; AVCodecContext* c = get_codec_from_stream(video_stream); #ifdef FFMPEG_CODEC_TIME_BASE frame->pts = rd->cfra - rd->sfra; @@ -276,14 +277,17 @@ static void write_video_frame(RenderData *rd, AVFrame* frame) packet.size = outsize; ret = av_interleaved_write_frame(outfile, &packet); } else ret = 0; + if (ret != 0) { - G.afbreek = 1; - //XXX error("Error writing frame"); + success= 0; + BKE_report(reports, RPT_ERROR, "Error writing frame."); } + + return success; } /* read and encode a frame of audio from the buffer */ -static AVFrame* generate_video_frame(uint8_t* pixels) +static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports) { uint8_t* rendered_frame; @@ -295,8 +299,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels) if (c->pix_fmt != PIX_FMT_BGR32) { rgb_frame = alloc_picture(PIX_FMT_BGR32, width, height); if (!rgb_frame) { - G.afbreek=1; - //XXX error("Couldn't allocate temporary frame"); + BKE_report(reports, RPT_ERROR, "Couldn't allocate temporary frame."); return NULL; } } else { @@ -613,7 +616,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex } /* essential functions -- start, append, end */ -static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) +static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, ReportList *reports) { /* Handle to the output file */ AVFormatContext* of; @@ -648,22 +651,19 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) exts = get_file_extensions(ffmpeg_type); if (!exts) { - G.afbreek = 1; /* Abort render */ - //XXX error("No valid formats found"); - return; + BKE_report(reports, RPT_ERROR, "No valid formats found."); + return 0; } fmt = guess_format(NULL, exts[0], NULL); if (!fmt) { - G.afbreek = 1; /* Abort render */ - //XXX error("No valid formats found"); - return; + BKE_report(reports, RPT_ERROR, "No valid formats found."); + return 0; } of = av_alloc_format_context(); if (!of) { - G.afbreek = 1; - //XXX error("Error opening output file"); - return; + BKE_report(reports, RPT_ERROR, "Error opening output file"); + return 0; } of->oformat = fmt; @@ -711,22 +711,16 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) } if (fmt->video_codec == CODEC_ID_DVVIDEO) { if (rectx != 720) { - G.afbreek = 1; - //XXX error("Render width has to be 720 pixels for DV!"); - return; + BKE_report(reports, RPT_ERROR, "Render width has to be 720 pixels for DV!"); + return 0; } if (rd->frs_sec != 25 && recty != 480) { - G.afbreek = 1; - //XXX error("Render height has to be 480 pixels " - // "for DV-NTSC!"); - return; - + BKE_report(reports, RPT_ERROR, "Render height has to be 480 pixels for DV-NTSC!"); + return 0; } if (rd->frs_sec == 25 && recty != 576) { - G.afbreek = 1; - //XXX error("Render height has to be 576 pixels " - // "for DV-PAL!"); - return; + BKE_report(reports, RPT_ERROR, "Render height has to be 576 pixels for DV-PAL!"); + return 0; } } @@ -735,46 +729,42 @@ static void start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty) if (ffmpeg_type == FFMPEG_DV) { fmt->audio_codec = CODEC_ID_PCM_S16LE; if (ffmpeg_multiplex_audio && rd->ffcodecdata.audio_mixrate != 48000) { - G.afbreek = 1; - //XXX error("FFMPEG only supports 48khz / stereo " - // "audio for DV!"); - return; + BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!"); + return 0; } } video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty); + printf("alloc video stream %p\n", video_stream); if (!video_stream) { - G.afbreek = 1; - //XXX error("Error initializing video stream"); - return; + BKE_report(reports, RPT_ERROR, "Error initializing video stream."); + return 0; } if (ffmpeg_multiplex_audio) { audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of); if (!audio_stream) { - G.afbreek = 1; - //XXX error("Error initializing audio stream"); - return; + BKE_report(reports, RPT_ERROR, "Error initializing audio stream."); + return 0; } //XXX audiostream_play(SFRA, 0, 1); } if (av_set_parameters(of, NULL) < 0) { - G.afbreek = 1; - //XXX error("Error setting output parameters"); - return; + BKE_report(reports, RPT_ERROR, "Error setting output parameters."); + return 0; } if (!(fmt->flags & AVFMT_NOFILE)) { if (url_fopen(&of->pb, name, URL_WRONLY) < 0) { - G.afbreek = 1; - // - //XXX error("Could not open file for writing"); - return; + BKE_report(reports, RPT_ERROR, "Could not open file for writing."); + return 0; } } av_write_header(of); outfile = of; dump_format(of, 0, name, 1); + + return 1; } /* ********************************************************************** @@ -831,11 +821,13 @@ static void makeffmpegstring(RenderData* rd, char* string) { } } -void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) +int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports) { + int success; + ffmpeg_autosplit_count = 0; - start_ffmpeg_impl(rd, rectx, recty); + success = start_ffmpeg_impl(rd, rectx, recty, reports); if(ffmpeg_multiplex_audio && audio_stream) { @@ -846,6 +838,8 @@ void start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty) specs.rate = rd->ffcodecdata.audio_mixrate; audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->efra, rd->ffcodecdata.audio_volume); } + + return success; } void end_ffmpeg(void); @@ -870,22 +864,29 @@ static void write_audio_frames() } } -void append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty) +int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) { + AVFrame* avframe; + int success; + fprintf(stderr, "Writing frame %i, " "render width=%d, render height=%d\n", frame, rectx, recty); write_audio_frames(); - write_video_frame(rd, generate_video_frame((unsigned char*) pixels)); + + avframe= generate_video_frame((unsigned char*) pixels, reports); + success= (avframe && write_video_frame(rd, avframe, reports)); if (ffmpeg_autosplit) { if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) { end_ffmpeg(); ffmpeg_autosplit_count++; - start_ffmpeg_impl(rd, rectx, recty); + success &= start_ffmpeg_impl(rd, rectx, recty, reports); } } + + return success; } @@ -914,6 +915,7 @@ void end_ffmpeg(void) if (video_stream && get_codec_from_stream(video_stream)) { avcodec_close(get_codec_from_stream(video_stream)); video_stream = 0; + printf("zero video stream %p\n", video_stream); } diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c index 0780cd0dc48..20d858fffeb 100644 --- a/source/blender/blenkernel/intern/writeframeserver.c +++ b/source/blender/blenkernel/intern/writeframeserver.c @@ -48,6 +48,7 @@ #include "DNA_userdef_types.h" #include "BKE_global.h" +#include "BKE_report.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -101,48 +102,45 @@ static int closesocket(int fd) } #endif -void start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty) +int start_frameserver(struct Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports) { - struct sockaddr_in addr; + struct sockaddr_in addr; int arg = 1; if (!startup_socket_system()) { - G.afbreek = 1; - //XXX error("Can't startup socket system"); - return; + BKE_report(reports, RPT_ERROR, "Can't startup socket system"); + return 0; } if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { shutdown_socket_system(); - G.afbreek = 1; /* Abort render */ - //XXX error("Can't open socket"); - return; - } + BKE_report(reports, RPT_ERROR, "Can't open socket"); + return 0; + } - setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (char*) &arg, sizeof(arg)); + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg)); addr.sin_family = AF_INET; - addr.sin_port = htons(U.frameserverport); - addr.sin_addr.s_addr = INADDR_ANY; + addr.sin_port = htons(U.frameserverport); + addr.sin_addr.s_addr = INADDR_ANY; if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { shutdown_socket_system(); - G.afbreek = 1; /* Abort render */ - //XXX error("Can't bind to socket"); - return; - } + BKE_report(reports, RPT_ERROR, "Can't bind to socket"); + return 0; + } - if (listen(sock, SOMAXCONN) < 0) { + if (listen(sock, SOMAXCONN) < 0) { shutdown_socket_system(); - G.afbreek = 1; /* Abort render */ - //XXX error("Can't establish listen backlog"); - return; - } + BKE_report(reports, RPT_ERROR, "Can't establish listen backlog"); + return 0; + } connsock = -1; render_width = rectx; render_height = recty; + + return 1; } static char index_page[] @@ -249,7 +247,7 @@ static int handle_request(RenderData *rd, char * req) return -1; } -int frameserver_loop(RenderData *rd) +int frameserver_loop(RenderData *rd, ReportList *reports) { fd_set readfds; struct timeval tv; @@ -355,7 +353,7 @@ static void serve_ppm(int *pixels, int rectx, int recty) connsock = -1; } -void append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int recty) +int append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int recty, ReportList *reports) { fprintf(stderr, "Serving frame: %d\n", frame); if (write_ppm) { @@ -365,6 +363,8 @@ void append_frameserver(RenderData *rd, int frame, int *pixels, int rectx, int r closesocket(connsock); connsock = -1; } + + return 0; } void end_frameserver() |