Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h31
-rw-r--r--source/blender/blenkernel/BKE_action.h6
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h6
-rw-r--r--source/blender/blenkernel/BKE_constraint.h2
-rw-r--r--source/blender/blenkernel/BKE_context.h6
-rw-r--r--source/blender/blenkernel/BKE_customdata.h24
-rw-r--r--source/blender/blenkernel/BKE_customdata_file.h59
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h7
-rw-r--r--source/blender/blenkernel/BKE_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_modifier.h6
-rw-r--r--source/blender/blenkernel/BKE_multires.h46
-rw-r--r--source/blender/blenkernel/BKE_node.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h2
-rw-r--r--source/blender/blenkernel/BKE_paint.h14
-rw-r--r--source/blender/blenkernel/BKE_particle.h2
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h1
-rw-r--r--source/blender/blenkernel/BKE_scene.h2
-rw-r--r--source/blender/blenkernel/BKE_screen.h5
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h (renamed from source/blender/blenkernel/BKE_sequence.h)34
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/BKE_subsurf.h59
-rw-r--r--source/blender/blenkernel/BKE_texture.h2
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h10
-rw-r--r--source/blender/blenkernel/BKE_writeavi.h12
-rw-r--r--source/blender/blenkernel/BKE_writeffmpeg.h5
-rw-r--r--source/blender/blenkernel/BKE_writeframeserver.h7
-rw-r--r--source/blender/blenkernel/CMakeLists.txt1
-rw-r--r--source/blender/blenkernel/SConscript3
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c1954
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.h215
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/blenkernel/intern/Makefile2
-rw-r--r--source/blender/blenkernel/intern/action.c165
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c36
-rw-r--r--source/blender/blenkernel/intern/armature.c54
-rw-r--r--source/blender/blenkernel/intern/blender.c4
-rw-r--r--source/blender/blenkernel/intern/brush.c7
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c342
-rw-r--r--source/blender/blenkernel/intern/cloth.c1
-rw-r--r--source/blender/blenkernel/intern/colortools.c46
-rw-r--r--source/blender/blenkernel/intern/constraint.c31
-rw-r--r--source/blender/blenkernel/intern/context.c12
-rw-r--r--source/blender/blenkernel/intern/customdata.c360
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c446
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c6
-rw-r--r--source/blender/blenkernel/intern/editderivedbmesh.c4
-rw-r--r--source/blender/blenkernel/intern/effect.c10
-rw-r--r--source/blender/blenkernel/intern/exotic.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c111
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c93
-rw-r--r--source/blender/blenkernel/intern/font.c8
-rw-r--r--source/blender/blenkernel/intern/group.c4
-rw-r--r--source/blender/blenkernel/intern/ipo.c57
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/mesh.c15
-rw-r--r--source/blender/blenkernel/intern/modifier.c591
-rw-r--r--source/blender/blenkernel/intern/multires.c1647
-rw-r--r--source/blender/blenkernel/intern/node.c15
-rw-r--r--source/blender/blenkernel/intern/object.c118
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c30
-rw-r--r--source/blender/blenkernel/intern/particle_system.c74
-rw-r--r--source/blender/blenkernel/intern/pointcache.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c98
-rw-r--r--source/blender/blenkernel/intern/screen.c17
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c170
-rw-r--r--source/blender/blenkernel/intern/sequencer.c (renamed from source/blender/blenkernel/intern/sequence.c)334
-rw-r--r--source/blender/blenkernel/intern/softbody.c174
-rw-r--r--source/blender/blenkernel/intern/sound.c10
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c1900
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/writeavi.c19
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c120
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c48
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*)&amplitude, 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()