diff options
author | Joseph Eagar <joeedh@gmail.com> | 2011-05-09 03:43:18 +0400 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2011-05-09 03:43:18 +0400 |
commit | 6ef77cf95accc3cb914e7efd964118ce6e9521cf (patch) | |
tree | 1d8dbf95355038c93f79f9053a0bf1d55b561ec3 /source/blender/blenkernel | |
parent | 3462ddf17f38eb61fc3bb2751d55de15a47455c3 (diff) | |
parent | 770119d16f7dbee99a60d19540818892c970c4e2 (diff) |
=bmesh= merge from trunk at r36529
Diffstat (limited to 'source/blender/blenkernel')
66 files changed, 2122 insertions, 3407 deletions
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index eae75d58a0a..48d3d32adf2 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,16 +44,16 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather then defining with quotes */ #define BLENDER_VERSION 257 -#define BLENDER_SUBVERSION 0 +#define BLENDER_SUBVERSION 1 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR b /* alpha/beta/rc/release, docs use this */ -#define BLENDER_VERSION_CYCLE release +#define BLENDER_VERSION_CYCLE beta struct ListBase; struct MemFile; diff --git a/source/blender/blenkernel/BKE_cdderivedmesh.h b/source/blender/blenkernel/BKE_cdderivedmesh.h index dd3a1005bae..8491faf2ceb 100644 --- a/source/blender/blenkernel/BKE_cdderivedmesh.h +++ b/source/blender/blenkernel/BKE_cdderivedmesh.h @@ -58,9 +58,6 @@ int CDDM_Check(struct DerivedMesh *dm); data to not overwrite the original */ struct DerivedMesh *CDDM_from_mesh(struct Mesh *mesh, struct Object *ob); -/* creates a CDDerivedMesh from the given EditMesh */ -struct DerivedMesh *CDDM_from_editmesh(struct EditMesh *em, struct Mesh *me); - /* creates a CDDerivedMesh from the given BMEditMesh */ DerivedMesh *CDDM_from_BMEditMesh(struct BMEditMesh *em, struct Mesh *me, int use_mdisps); diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h index 1ee51cd2122..a5c88000db2 100644 --- a/source/blender/blenkernel/BKE_cloth.h +++ b/source/blender/blenkernel/BKE_cloth.h @@ -35,6 +35,7 @@ */ #include <float.h> +#include "BLI_math_inline.h" struct Object; struct ListBase; @@ -44,16 +45,7 @@ struct DerivedMesh; struct ClothModifierData; struct CollisionTree; -// this is needed for inlining behaviour -#if defined _WIN32 -# define DO_INLINE __inline -#elif defined (__sgi) -# define DO_INLINE -#elif defined (__sun) || defined (__sun__) -# define DO_INLINE -#else -# define DO_INLINE static inline -#endif +#define DO_INLINE MALWAYS_INLINE #define CLOTH_MAX_THREAD 2 diff --git a/source/blender/blenkernel/BKE_collision.h b/source/blender/blenkernel/BKE_collision.h index b54d4275719..4048ee2f457 100644 --- a/source/blender/blenkernel/BKE_collision.h +++ b/source/blender/blenkernel/BKE_collision.h @@ -63,7 +63,11 @@ struct LinkNode; /* COLLISION FLAGS */ typedef enum { - COLLISION_IN_FUTURE = ( 1 << 1 ), + COLLISION_IN_FUTURE = (1 << 1), +#ifdef WITH_ELTOPO + COLLISION_USE_COLLFACE = (1 << 2), + COLLISION_IS_EDGES = (1 << 3), +#endif } COLLISION_FLAGS; @@ -81,7 +85,13 @@ typedef struct CollPair float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 int flag; float time; // collision time, from 0 up to 1 +#ifdef WITH_ELTOPO /*either ap* or bp* can be set, but not both*/ + float bary[3]; + int ap1, ap2, ap3, collp, bp1, bp2, bp3; + int collface; +#else int ap1, ap2, ap3, bp1, bp2, bp3; +#endif int pointsb[4]; } CollPair; @@ -109,6 +119,7 @@ typedef struct FaceCollPair float pa[3], pb[3]; // collision point p1 on face1, p2 on face2 } FaceCollPair; + //////////////////////////////////////// diff --git a/source/blender/blenkernel/BKE_exotic.h b/source/blender/blenkernel/BKE_exotic.h deleted file mode 100644 index 870dd7cb4d5..00000000000 --- a/source/blender/blenkernel/BKE_exotic.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef BKE_EXOTIC_H -#define BKE_EXOTIC_H - -/** \file BKE_exotic.h - * \ingroup bke - * \brief dxf/vrml/stl external file io function prototypes. - * \attention is this used still? Candidate for removal? - */ -struct Mesh; -struct Scene; - -/** - * Reads all 3D fileformats other than Blender fileformat - * @retval 0 The file could not be read. - * @retval 1 The file was read succesfully. - * @attention Used in filesel.c - */ -int BKE_read_exotic(struct Scene *scene, const char *name); - -/* return codes */ -#define BKE_READ_EXOTIC_FAIL_PATH -3 /* file format is not supported */ -#define BKE_READ_EXOTIC_FAIL_FORMAT -2 /* file format is not supported */ -#define BKE_READ_EXOTIC_FAIL_OPEN -1 /* Can't open the file */ -#define BKE_READ_EXOTIC_OK_BLEND 0 /* .blend file */ -#define BKE_READ_EXOTIC_OK_OTHER 1 /* other supported formats */ - -void write_dxf(struct Scene *scene, char *str); -void write_stl(struct Scene *scene, char *str); - -#endif - diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h index 7f4e7c208f6..2195b370a5f 100644 --- a/source/blender/blenkernel/BKE_font.h +++ b/source/blender/blenkernel/BKE_font.h @@ -84,10 +84,10 @@ struct chartrans *BKE_text_to_curve(struct Scene *scene, struct Object *ob, int int BKE_font_getselection(struct Object *ob, int *start, int *end); -void chtoutf8(unsigned long c, char *o); -void wcs2utf8s(char *dst, wchar_t *src); -int wcsleninu8(wchar_t *src); -int utf8towchar(wchar_t *w, char *c); +size_t chtoutf8(const unsigned long c, char o[4]); +void wcs2utf8s(char *dst, const wchar_t *src); +size_t wcsleninu8(wchar_t *src); +size_t utf8towchar(wchar_t *w, const char *c); #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 8f0ce8c1660..10910493ec9 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -44,14 +44,16 @@ struct ImBuf; struct Tex; struct anim; struct Scene; +struct Object; /* call from library */ void free_image(struct Image *me); -void BKE_stamp_info(struct Scene *scene, struct ImBuf *ibuf); -void BKE_stamp_buf(struct Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels); +void BKE_stamp_info(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf); +void BKE_stamp_buf(struct Scene *scene, struct Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels); int BKE_alphatest_ibuf(struct ImBuf *ibuf); -int BKE_write_ibuf(struct Scene *scene, struct ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality); +int BKE_write_ibuf_stamp(struct Scene *scene, struct Object *camera, struct ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality); +int BKE_write_ibuf(struct ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality); void BKE_makepicstring(char *string, const char *base, int frame, int imtype, const short use_ext, const short use_frames); int BKE_add_image_extension(char *string, int imtype); int BKE_ftype_to_imtype(int ftype); @@ -131,6 +133,7 @@ void BKE_image_assign_ibuf(struct Image *ima, struct ImBuf *ibuf); /* called on frame change or before render */ void BKE_image_user_calc_frame(struct ImageUser *iuser, int cfra, int fieldnr); +int BKE_image_user_get_frame(const struct ImageUser *iuser, int cfra, int fieldnr); /* fix things in ImageUser when new image gets assigned */ void BKE_image_user_new_image(struct Image *ima, struct ImageUser *iuser); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 523a67eff67..c445408609c 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -55,6 +55,7 @@ struct Material *copy_material(struct Material *ma); struct Material *localize_material(struct Material *ma); struct Material *give_node_material(struct Material *ma); /* returns node material or self */ void make_local_material(struct Material *ma); +void extern_local_matarar(struct Material **matar, short totcol); void automatname(struct Material *); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 42c4cb47388..44d1f9f1427 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -90,11 +90,6 @@ struct Mesh *add_mesh(const char *name); struct Mesh *copy_mesh(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me); -/*this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or - mloopcol and mcol) have the same relative active/render/clone/mask indices.*/ -void mesh_update_linked_customdata(struct Mesh *me); - -void make_local_tface(struct Mesh *me); void make_local_mesh(struct Mesh *me); void boundbox_mesh(struct Mesh *me, float *loc, float *size); void tex_space_mesh(struct Mesh *me); diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h index cacfa702f7f..3a98f892bd8 100644 --- a/source/blender/blenkernel/BKE_object.h +++ b/source/blender/blenkernel/BKE_object.h @@ -91,7 +91,6 @@ struct Object *add_only_object(int type, const char *name); struct Object *add_object(struct Scene *scene, int type); struct Object *copy_object(struct Object *ob); -void expand_local_object(struct Object *ob); void make_local_object(struct Object *ob); int object_is_libdata(struct Object *ob); int object_data_is_libdata(struct Object *ob); @@ -138,6 +137,7 @@ struct KeyBlock *object_insert_shape_key(struct Scene *scene, struct Object *ob, int object_is_modified(struct Scene *scene, struct Object *ob); +void object_camera_mode(struct RenderData *rd, struct Object *camera); void object_camera_matrix( struct RenderData *rd, struct Object *camera, int winx, int winy, short field_second, float winmat[][4], struct rctf *viewplane, float *clipsta, float *clipend, float *lens, float *ycor, diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 33bff1cd6a7..57829e957f7 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -217,9 +217,16 @@ void seq_stripelem_cache_destruct(void); void seq_stripelem_cache_cleanup(void); +/* returned ImBuf is properly refed and has to be freed */ struct ImBuf * seq_stripelem_cache_get( SeqRenderData context, struct Sequence * seq, float cfra, seq_stripelem_ibuf_t type); + +/* passed ImBuf is properly refed, so ownership is *not* + transfered to the cache. + you can pass the same ImBuf multiple times to the cache without problems. +*/ + void seq_stripelem_cache_put( SeqRenderData context, struct Sequence * seq, float cfra, seq_stripelem_ibuf_t type, struct ImBuf * nval); @@ -323,7 +330,7 @@ struct Sequence *sequencer_add_sound_strip(struct bContext *C, ListBase *seqbase struct Sequence *sequencer_add_movie_strip(struct bContext *C, ListBase *seqbasep, struct SeqLoadInfo *seq_load); /* view3d draw callback, run when not in background view */ -typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, int, int, unsigned int, int, char[256]); +typedef struct ImBuf *(*SequencerDrawView)(struct Scene *, struct Object *, int, int, unsigned int, int, char[256]); extern SequencerDrawView sequencer_view3d_cb; /* copy/paste */ diff --git a/source/blender/blenkernel/BKE_shrinkwrap.h b/source/blender/blenkernel/BKE_shrinkwrap.h index 937a46d68dd..d1fef8b0ce1 100644 --- a/source/blender/blenkernel/BKE_shrinkwrap.h +++ b/source/blender/blenkernel/BKE_shrinkwrap.h @@ -90,7 +90,7 @@ void space_transform_invert(const struct SpaceTransform *data, float *co); * - Normal projection * * ShrinkwrapCalcData encapsulates all needed data for shrinkwrap functions. - * (So that you dont have to pass an enormous ammount of arguments to functions) + * (So that you dont have to pass an enormous amount of arguments to functions) */ struct Object; diff --git a/source/blender/blenkernel/BKE_sketch.h b/source/blender/blenkernel/BKE_sketch.h index f42d733d583..360a95bfb24 100644 --- a/source/blender/blenkernel/BKE_sketch.h +++ b/source/blender/blenkernel/BKE_sketch.h @@ -152,7 +152,7 @@ void sk_endContinuousStroke(SK_Stroke *stk); void sk_updateNextPoint(SK_Sketch *sketch, SK_Stroke *stk); -void sk_initDrawData(SK_DrawData *dd, short mval[2]); +void sk_initDrawData(SK_DrawData *dd, const short mval[2]); void sk_deleteSelectedStrokes(SK_Sketch *sketch); void sk_selectAllSketch(SK_Sketch *sketch, int mode); diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h index a6b98b8ea88..136ce416037 100644 --- a/source/blender/blenkernel/BKE_text.h +++ b/source/blender/blenkernel/BKE_text.h @@ -89,6 +89,7 @@ void txt_split_curline (struct Text *text); void txt_backspace_char (struct Text *text); void txt_backspace_word (struct Text *text); int txt_add_char (struct Text *text, char add); +int txt_add_raw_char (struct Text *text, char add); int txt_replace_char (struct Text *text, char add); void txt_export_to_object (struct Text *text); void txt_export_to_objects(struct Text *text); diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index a5a4f72523c..4040cc7d4f7 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -24,6 +24,11 @@ # # ***** END GPL LICENSE BLOCK ***** +if(WITH_CODEC_FFMPEG) + # FFMPEG gives warnigns which are hard to avoid across multiple versions. + remove_strict_flags() +endif() + set(INC . ../avi @@ -88,7 +93,6 @@ set(SRC intern/displist.c intern/effect.c intern/editderivedbmesh.c - intern/exotic.c intern/fcurve.c intern/fluidsim.c intern/fmodifier.c @@ -143,7 +147,7 @@ set(SRC intern/writeavi.c intern/writeffmpeg.c intern/writeframeserver.c - + BKE_DerivedMesh.h BKE_action.h BKE_anim.h @@ -174,7 +178,6 @@ set(SRC BKE_displist.h BKE_effect.h BKE_endian.h - BKE_exotic.h BKE_fcurve.h BKE_fluidsim.h BKE_font.h @@ -238,6 +241,11 @@ if(WITH_BULLET) add_definitions(-DUSE_BULLET) endif() +if(WITH_MOD_CLOTH_ELTOPO) + list(APPEND INC ../../../extern/eltopo) + add_definitions(-DWITH_ELTOPO) +endif() + if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() @@ -280,6 +288,10 @@ endif() if(WITH_PYTHON) list(APPEND INC ../python ${PYTHON_INCLUDE_DIRS}) add_definitions(-DWITH_PYTHON) + + if(WITH_PYTHON_SECURITY) + add_definitions(-DWITH_PYTHON_SECURITY) + endif() endif() if(WITH_OPENMP) diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript index 931d925bbf6..71b6d02fd4b 100644 --- a/source/blender/blenkernel/SConscript +++ b/source/blender/blenkernel/SConscript @@ -33,6 +33,10 @@ if env['WITH_BF_PYTHON']: if env['BF_DEBUG']: defs.append('DEBUG') +if env['WITH_BF_ELTOPO']: + incs += ' ../../../extern/eltopo' + defs.append('WITH_ELTOPO') + if env['WITH_BF_QUICKTIME']: incs += ' ../quicktime' diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 421e8a89137..a8617773658 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1173,11 +1173,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos modifier_setError(md, "Modifier requires original data, bad stack position."); continue; } - if(sculpt_mode && (!has_multires || multires_applied)) - if(mti->type != eModifierTypeType_OnlyDeform || multires_applied) { + if(sculpt_mode && (!has_multires || multires_applied)) { + int unsupported= 0; + + if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM) + unsupported|= mti->type != eModifierTypeType_OnlyDeform; + + unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0; + unsupported|= multires_applied; + + if(unsupported) { modifier_setError(md, "Not supported in sculpt mode."); continue; } + } if(needMapping && !modifier_supportsMapping(md)) continue; if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; @@ -1216,7 +1225,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos * to avoid giving bogus normals to the next modifier see: [#23673] */ if(dm && isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) { /* XXX, this covers bug #23673, but we may need normal calc for other types */ - if(dm->type == DM_TYPE_CDDM) { + if(dm && dm->type == DM_TYPE_CDDM) { CDDM_apply_vert_coords(dm, deformedVerts); CDDM_calc_normals(dm); } @@ -1931,9 +1940,8 @@ static void GetPosition(const SMikkTSpaceContext * pContext, float fPos[], const { //assert(vert_index>=0 && vert_index<4); SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; - unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2, - pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 }; - VECCOPY(fPos, pMesh->mvert[indices[vert_index]].co); + const float *co= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].co; + VECCOPY(fPos, co); } static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[], const int face_num, const int vert_index) @@ -1941,17 +1949,13 @@ static void GetTextureCoordinate(const SMikkTSpaceContext * pContext, float fUV[ //assert(vert_index>=0 && vert_index<4); SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; - if(pMesh->mtface!=NULL) - { + if(pMesh->mtface!=NULL) { float * uv = pMesh->mtface[face_num].uv[vert_index]; fUV[0]=uv[0]; fUV[1]=uv[1]; } - else - { - unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2, - pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 }; - - map_to_sphere( &fUV[0], &fUV[1],pMesh->orco[indices[vert_index]][0], pMesh->orco[indices[vert_index]][1], pMesh->orco[indices[vert_index]][2]); + else { + const float *orco= pMesh->orco[(&pMesh->mface[face_num].v1)[vert_index]]; + map_to_sphere( &fUV[0], &fUV[1], orco[0], orco[1], orco[2]); } } @@ -1959,38 +1963,30 @@ static void GetNormal(const SMikkTSpaceContext * pContext, float fNorm[], const { //assert(vert_index>=0 && vert_index<4); SGLSLMeshToTangent * pMesh = (SGLSLMeshToTangent *) pContext->m_pUserData; - unsigned int indices[] = { pMesh->mface[face_num].v1, pMesh->mface[face_num].v2, - pMesh->mface[face_num].v3, pMesh->mface[face_num].v4 }; const int smoothnormal = (pMesh->mface[face_num].flag & ME_SMOOTH); - if(!smoothnormal) // flat - { - if(pMesh->precomputedFaceNormals) - { + if(!smoothnormal) { // flat + if(pMesh->precomputedFaceNormals) { VECCOPY(fNorm, &pMesh->precomputedFaceNormals[3*face_num]); } - else - { - float nor[3]; - float * p0, * p1, * p2; - const int iGetNrVerts = pMesh->mface[face_num].v4!=0 ? 4 : 3; - p0 = pMesh->mvert[indices[0]].co; p1 = pMesh->mvert[indices[1]].co; p2 = pMesh->mvert[indices[2]].co; - if(iGetNrVerts==4) - { - float * p3 = pMesh->mvert[indices[3]].co; - normal_quad_v3( nor, p0, p1, p2, p3); + else { + MFace *mf= &pMesh->mface[face_num]; + float *p0= pMesh->mvert[mf->v1].co; + float *p1= pMesh->mvert[mf->v2].co; + float *p2= pMesh->mvert[mf->v3].co; + + if(mf->v4) { + float *p3 = pMesh->mvert[mf->v4].co; + normal_quad_v3(fNorm, p0, p1, p2, p3); } else { - normal_tri_v3(nor, p0, p1, p2); + normal_tri_v3(fNorm, p0, p1, p2); } - VECCOPY(fNorm, nor); } } - else - { - short *no = pMesh->mvert[indices[vert_index]].no; + else { + const short *no= pMesh->mvert[(&pMesh->mface[face_num].v1)[vert_index]].no; normal_short_to_float_v3(fNorm, no); - normalize_v3(fNorm); /* XXX, is this needed */ } } static void SetTSpace(const SMikkTSpaceContext * pContext, const float fvTangent[], const float fSign, const int face_num, const int iVert) @@ -2047,14 +2043,10 @@ void DM_add_tangent_layer(DerivedMesh *dm) // new computation method iCalcNewMethod = 1; - if(iCalcNewMethod!=0) - { - SGLSLMeshToTangent mesh2tangent; - SMikkTSpaceContext sContext; - SMikkTSpaceInterface sInterface; - memset(&mesh2tangent, 0, sizeof(SGLSLMeshToTangent)); - memset(&sContext, 0, sizeof(SMikkTSpaceContext)); - memset(&sInterface, 0, sizeof(SMikkTSpaceInterface)); + if(iCalcNewMethod != 0) { + SGLSLMeshToTangent mesh2tangent= {0}; + SMikkTSpaceContext sContext= {0}; + SMikkTSpaceInterface sInterface= {0}; mesh2tangent.precomputedFaceNormals = nors; mesh2tangent.mtface = mtface; @@ -2077,8 +2069,7 @@ void DM_add_tangent_layer(DerivedMesh *dm) iCalcNewMethod = genTangSpaceDefault(&sContext); } - if(!iCalcNewMethod) - { + if(!iCalcNewMethod) { /* sum tangents at connected vertices */ for(i=0, tf=mtface, mf=mface; i < totface; mf++, tf++, i++) { v1= &mvert[mf->v1]; diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 5b42948072f..5b49d9a9841 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -95,6 +95,7 @@ bAction *add_empty_action(const char name[]) void make_local_action(bAction *act) { // Object *ob; + Main *bmain= G.main; bAction *actn; int local=0, lib=0; @@ -102,7 +103,7 @@ void make_local_action(bAction *act) if (act->id.us==1) { act->id.lib= NULL; act->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)act, NULL); + new_id(&bmain->action, (ID *)act, NULL); return; } @@ -121,7 +122,7 @@ void make_local_action(bAction *act) act->id.lib= NULL; act->id.flag= LIB_LOCAL; //make_local_action_channels(act); - new_id(NULL, (ID *)act, NULL); + new_id(&bmain->action, (ID *)act, NULL); } else if(local && lib) { actn= copy_action(act); @@ -419,11 +420,11 @@ bPoseChannel *verify_pose_channel(bPose *pose, const char *name) return NULL; /* See if this channel exists */ - for (chan=pose->chanbase.first; chan; chan=chan->next) { - if (!strcmp (name, chan->name)) - return chan; + chan= BLI_findstring(&pose->chanbase, name, offsetof(bPoseChannel, name)); + if(chan) { + return chan; } - + /* If not, create it and add it */ chan = MEM_callocN(sizeof(bPoseChannel), "verifyPoseChannel"); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index 2708239a4c3..5198172c205 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -194,7 +194,7 @@ AnimData *BKE_copy_animdata (AnimData *adt, const short do_action) dadt= MEM_dupallocN(adt); /* make a copy of action - at worst, user has to delete copies... */ - if(do_action) { + if (do_action) { dadt->action= copy_action(adt->action); dadt->tmpact= copy_action(adt->tmpact); } @@ -216,11 +216,11 @@ AnimData *BKE_copy_animdata (AnimData *adt, const short do_action) return dadt; } -int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_action) +int BKE_copy_animdata_id (ID *id_to, ID *id_from, const short do_action) { AnimData *adt; - if((id_to && id_from) && (GS(id_to->name) != GS(id_from->name))) + if ((id_to && id_from) && (GS(id_to->name) != GS(id_from->name))) return 0; BKE_free_animdata(id_to); @@ -237,13 +237,13 @@ int BKE_copy_animdata_id(struct ID *id_to, struct ID *id_from, const short do_ac void BKE_copy_animdata_id_action(struct ID *id) { AnimData *adt= BKE_animdata_from_id(id); - if(adt) { - if(adt->action) { - ((ID *)adt->action)->us--; + if (adt) { + if (adt->action) { + id_us_min((ID *)adt->action); adt->action= copy_action(adt->action); } - if(adt->tmpact) { - ((ID *)adt->tmpact)->us--; + if (adt->tmpact) { + id_us_min((ID *)adt->tmpact); adt->tmpact= copy_action(adt->tmpact); } } @@ -1199,6 +1199,39 @@ static void animsys_evaluate_drivers (PointerRNA *ptr, AnimData *adt, float ctim /* ***************************************** */ /* Actions Evaluation */ +/* strictly not necessary for actual "evaluation", but it is a useful safety check + * to reduce the amount of times that users end up having to "revive" wrongly-assigned + * actions + */ +static void action_idcode_patch_check (ID *id, bAction *act) +{ + int idcode = 0; + + /* just in case */ + if (ELEM(NULL, id, act)) + return; + else + idcode = GS(id->name); + + /* the actual checks... hopefully not too much of a performance hit in the long run... */ + if (act->idroot == 0) { + /* use the current root if not set already (i.e. newly created actions and actions from 2.50-2.57 builds) + * - this has problems if there are 2 users, and the first one encountered is the invalid one + * in which case, the user will need to manually fix this (?) + */ + act->idroot = idcode; + } + else if (act->idroot != idcode) { + /* only report this error if debug mode is enabled (to save performance everywhere else) */ + if (G.f & G_DEBUG) { + printf("AnimSys Safety Check Failed: Action '%s' is not meant to be used from ID-Blocks of type %d such as '%s'\n", + act->id.name+2, idcode, id->name); + } + } +} + +/* ----------------------------------------- */ + /* Evaluate Action Group */ void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup *agrp, AnimMapper *remap, float ctime) { @@ -1208,6 +1241,8 @@ void animsys_evaluate_action_group (PointerRNA *ptr, bAction *act, bActionGroup if ELEM(NULL, act, agrp) return; if ((remap) && (remap->target != act)) remap= NULL; + action_idcode_patch_check(ptr->id.data, act); + /* if group is muted, don't evaluated any of the F-Curve */ if (agrp->flag & AGRP_MUTED) return; @@ -1231,6 +1266,8 @@ void animsys_evaluate_action (PointerRNA *ptr, bAction *act, AnimMapper *remap, if (act == NULL) return; if ((remap) && (remap->target != act)) remap= NULL; + action_idcode_patch_check(ptr->id.data, act); + /* calculate then execute each curve */ animsys_evaluate_fcurves(ptr, &act->curves, remap, ctime); } @@ -1630,6 +1667,17 @@ static void nlastrip_evaluate_actionclip (PointerRNA *ptr, ListBase *channels, L FCurve *fcu; float evaltime; + /* sanity checks for action */ + if (strip == NULL) + return; + + if (strip->act == NULL) { + printf("NLA-Strip Eval Error: Strip '%s' has no Action\n", strip->name); + return; + } + + action_idcode_patch_check(ptr->id.data, strip->act); + /* join this strip's modifiers to the parent's modifiers (own modifiers first) */ nlaeval_fmodifiers_join_stacks(&tmp_modifiers, &strip->modifiers, modifiers); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 6a5cc53ef23..3f361fe6b66 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -138,39 +138,42 @@ void free_armature(bArmature *arm) void make_local_armature(bArmature *arm) { + Main *bmain= G.main; int local=0, lib=0; Object *ob; - bArmature *newArm; - - if (arm->id.lib==NULL) - return; + + if (arm->id.lib==NULL) return; if (arm->id.us==1) { arm->id.lib= NULL; arm->id.flag= LIB_LOCAL; - new_id(NULL, (ID*)arm, NULL); + new_id(&bmain->armature, (ID*)arm, NULL); return; } - + + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + if(ob->data == arm) { + if(ob->id.lib) lib= 1; + else local= 1; + } + } + if(local && lib==0) { arm->id.lib= NULL; arm->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)arm, NULL); + new_id(&bmain->armature, (ID *)arm, NULL); } else if(local && lib) { - newArm= copy_armature(arm); - newArm->id.us= 0; + bArmature *armn= copy_armature(arm); + armn->id.us= 0; - ob= G.main->object.first; - while(ob) { - if(ob->data==arm) { - + for(ob= bmain->object.first; ob; ob= ob->id.next) { + if(ob->data == arm) { if(ob->id.lib==NULL) { - ob->data= newArm; - newArm->id.us++; + ob->data= armn; + armn->id.us++; arm->id.us--; } } - ob= ob->id.next; } } } @@ -215,6 +218,11 @@ bArmature *copy_armature(bArmature *arm) }; newArm->act_bone= newActBone; + + newArm->edbo= NULL; + newArm->act_edbone= NULL; + newArm->sketch= NULL; + return newArm; } @@ -1227,10 +1235,10 @@ void pchan_apply_mat4(bPoseChannel *pchan, float mat[][4], short use_compat) */ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float arm_mat[][4]) { - float imat[4][4]; - - invert_m4_m4(imat, arm_mat); - mul_m4_m4m4(delta_mat, pose_mat, imat); + float imat[4][4]; + + invert_m4_m4(imat, arm_mat); + mul_m4_m4m4(delta_mat, pose_mat, imat); } /* **************** Rotation Mode Conversions ****************************** */ diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index c314d476535..29b3bd59e70 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -140,8 +140,12 @@ void initglobals(void) G.charstart = 0x0000; G.charmin = 0x0000; G.charmax = 0xffff; - + +#ifndef WITH_PYTHON_SECURITY /* default */ G.f |= G_SCRIPT_AUTOEXEC; +#else + G.f &= ~G_SCRIPT_AUTOEXEC; +#endif } /***/ @@ -617,24 +621,14 @@ void BKE_reset_undo(void) /* based on index nr it does a restore */ void BKE_undo_number(bContext *C, int nr) { - UndoElem *uel; - int a=1; - - for(uel= undobase.first; uel; uel= uel->next, a++) { - if(a==nr) break; - } - curundo= uel; + curundo= BLI_findlink(&undobase, nr - 1); BKE_undo_step(C, 0); } /* go back to the last occurance of name in stack */ void BKE_undo_name(bContext *C, const char *name) { - UndoElem *uel; - - for(uel= undobase.last; uel; uel= uel->prev) - if(strcmp(name, uel->name)==0) - break; + UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name)); if(uel && uel->prev) { curundo= uel->prev; @@ -646,12 +640,7 @@ void BKE_undo_name(bContext *C, const char *name) int BKE_undo_valid(const char *name) { if(name) { - UndoElem *uel; - - for(uel= undobase.last; uel; uel= uel->prev) - if(strcmp(name, uel->name)==0) - break; - + UndoElem *uel= BLI_rfindstring(&undobase, name, offsetof(UndoElem, name)); return uel && uel->prev; } diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 11ea3384c96..9f808704eee 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -1299,7 +1299,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa) bpa->data.mode = eBoidMode_OnLand; } /* fly above ground */ - else { + else if(bpa->ground) { pa->state.co[2] = ground_co[2] + pa->size * boids->height; pa->state.vel[2] = 0.0f; } diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 96b6ec357f9..fa3b756ae27 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -180,14 +180,20 @@ void free_brush(Brush *brush) curvemapping_free(brush->curve); } +static void extern_local_brush(Brush *brush) +{ + id_lib_extern((ID *)brush->mtex.tex); +} + void make_local_brush(Brush *brush) { + /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ - - Brush *brushn; + * - only local users: set flag + * - mixed: make copy + */ + + Main *bmain= G.main; Scene *scene; int local= 0, lib= 0; @@ -197,19 +203,22 @@ void make_local_brush(Brush *brush) /* special case: ima always local immediately */ brush->clone.image->id.lib= NULL; brush->clone.image->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)brush->clone.image, NULL); + new_id(&bmain->brush, (ID *)brush->clone.image, NULL); + extern_local_brush(brush); } - for(scene= G.main->scene.first; scene; scene=scene->id.next) + for(scene= bmain->scene.first; scene && ELEM(0, lib, local); scene=scene->id.next) { if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(scene->id.lib) lib= 1; else local= 1; } + } if(local && lib==0) { brush->id.lib= NULL; brush->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)brush, NULL); + new_id(&bmain->brush, (ID *)brush, NULL); + extern_local_brush(brush); /* enable fake user by default */ if (!(brush->id.flag & LIB_FAKEUSER)) { @@ -218,17 +227,19 @@ void make_local_brush(Brush *brush) } } else if(local && lib) { - brushn= copy_brush(brush); + Brush *brushn= copy_brush(brush); brushn->id.us= 1; /* only keep fake user */ brushn->id.flag |= LIB_FAKEUSER; - for(scene= G.main->scene.first; scene; scene=scene->id.next) - if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) + for(scene= bmain->scene.first; scene; scene=scene->id.next) { + if(paint_brush(&scene->toolsettings->imapaint.paint)==brush) { if(scene->id.lib==NULL) { paint_brush_set(&scene->toolsettings->imapaint.paint, brushn); brushn->id.us++; brush->id.us--; } + } + } } } @@ -1119,12 +1130,12 @@ float brush_curve_strength_clamp(Brush *br, float p, const float len) * used for sculpt only */ float brush_curve_strength(Brush *br, float p, const float len) { - if(p >= len) - p= 1.0f; - else - p= p/len; + if(p >= len) + p= 1.0f; + else + p= p/len; - return curvemapping_evaluateF(br->curve, 0, p); + return curvemapping_evaluateF(br->curve, 0, p); } /* TODO: should probably be unified with BrushPainter stuff? */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index dcbf3898862..210840f00f0 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -193,11 +193,7 @@ static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3]) static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; - short *no = cddm->mvert[index].no; - - no_r[0] = no[0]/32767.f; - no_r[1] = no[1]/32767.f; - no_r[2] = no[2]/32767.f; + normal_short_to_float_v3(no_r, cddm->mvert[index].no); } static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm) @@ -218,8 +214,20 @@ static int can_pbvh_draw(Object *ob, DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; Mesh *me= ob->data; + int deformed= 0; + + /* active modifiers means extra deformation, which can't be handled correct + on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush + stuff and show final DerivedMesh so user would see actual object shape */ + deformed|= ob->sculpt->modifiers_active; + + /* as in case with modifiers, we can't synchronize deformation made against + PBVH and non-locked keyblock, so also use PBVH only for brushes and + final DM to give final result to user */ + deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0; - if(ob->sculpt->modifiers_active) return 0; + if(deformed) + return 0; return (cddm->mvert == me->mvert) || ob->sculpt->kb; } @@ -244,19 +252,21 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) this derivedmesh is just original mesh. it's the multires subsurf dm that this is actually for, to support a pbvh on a modified mesh */ if(!cddm->pbvh && ob->type == OB_MESH) { + SculptSession *ss= ob->sculpt; Mesh *me= ob->data; cddm->pbvh = BLI_pbvh_new(); cddm->pbvh_draw = can_pbvh_draw(ob, dm); BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, me->totface, me->totvert); - if(ob->sculpt->modifiers_active) { + if(ss->modifiers_active && ob->derivedDeform) { + DerivedMesh *deformdm= ob->derivedDeform; float (*vertCos)[3]; int totvert; - totvert= dm->getNumVerts(dm); + totvert= deformdm->getNumVerts(deformdm); vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos"); - dm->getVertCos(dm, vertCos); + deformdm->getVertCos(deformdm, vertCos); BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos); MEM_freeN(vertCos); } @@ -589,8 +599,9 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha /* there's a conflict here... twosided colors versus culling...? */ /* defined by history, only texture faces have culling option */ /* we need that as mesh option builtin, next to double sided lighting */ - if(col1 && col2) + if(col2) { glEnable(GL_CULL_FACE); + } cdDM_update_normals_from_pbvh(dm); @@ -606,26 +617,26 @@ static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha glBegin(glmode = new_glmode); } - glColor3ub(cp1[0], cp1[1], cp1[2]); + glColor3ubv(cp1+0); glVertex3fv(mvert[mface->v1].co); - glColor3ub(cp1[4], cp1[5], cp1[6]); + glColor3ubv(cp1+4); glVertex3fv(mvert[mface->v2].co); - glColor3ub(cp1[8], cp1[9], cp1[10]); + glColor3ubv(cp1+8); glVertex3fv(mvert[mface->v3].co); if(mface->v4) { - glColor3ub(cp1[12], cp1[13], cp1[14]); + glColor3ubv(cp1+12); glVertex3fv(mvert[mface->v4].co); } if(useTwoSided) { - glColor3ub(cp2[8], cp2[9], cp2[10]); + glColor3ubv(cp2+8); glVertex3fv(mvert[mface->v3].co ); - glColor3ub(cp2[4], cp2[5], cp2[6]); + glColor3ubv(cp2+4); glVertex3fv(mvert[mface->v2].co ); - glColor3ub(cp2[0], cp2[1], cp2[2]); + glColor3ubv(cp2+0); glVertex3fv(mvert[mface->v1].co ); if(mface->v4) { - glColor3ub(cp2[12], cp2[13], cp2[14]); + glColor3ubv(cp2+12); glVertex3fv(mvert[mface->v4].co ); } } @@ -782,6 +793,19 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } if( !GPU_buffer_legacy(dm) ) { + /* warning!, this logic is incorrect, see bug [#27175] + * firstly, there are no checks for changes in context, such as texface image. + * secondly, drawParams() sets the GL context, so checking if there is a change + * from lastFlag is too late once glDrawArrays() runs, since drawing the arrays + * will use the modified, OpenGL settings. + * + * However its tricky to fix this without duplicating the internal logic + * of drawParams(), perhaps we need an argument like... + * drawParams(..., keep_gl_state_but_return_when_changed) ?. + * + * We could also just disable VBO's here, since texface may be deprecated - campbell. + */ + glShadeModel( GL_SMOOTH ); lastFlag = 0; for(i = 0; i < dm->drawObject->nelements/3; i++) { diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 9fabf1d52cf..89e60cc5e0c 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -918,7 +918,7 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d if(!first) implicit_set_positions(clmd); - clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, clmd->coll_parms->epsilon ); + clmd->clothObject->bvhtree = bvhtree_build_from_cloth ( clmd, MAX2(clmd->coll_parms->epsilon, clmd->coll_parms->distance_repel) ); for(i = 0; i < dm->getNumVerts(dm); i++) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 88b6ca296c7..e2a1b0dfb33 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -48,6 +48,9 @@ #include "BLI_math.h" #include "BLI_edgehash.h" #include "BLI_utildefines.h" +#include "BLI_ghash.h" +#include "BLI_memarena.h" +#include "BLI_rand.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" @@ -63,6 +66,10 @@ #include "BLI_kdopbvh.h" #include "BKE_collision.h" +#ifdef WITH_ELTOPO +#include "eltopo-capi.h" +#endif + /*********************************** Collision modifier code start @@ -486,7 +493,7 @@ DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float VECADDMUL ( to, v3, w3 ); } - +#ifndef WITH_ELTOPO static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) { int result = 0; @@ -601,12 +608,799 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM } return result; } +#endif /* !WITH_ELTOPO */ + +#ifdef WITH_ELTOPO +typedef struct edgepairkey { + int a1, a2, b1, b2; +} edgepairkey; + +unsigned int edgepair_hash(void *vkey) +{ + edgepairkey *key = vkey; + int keys[4] = {key->a1, key->a2, key->b1, key->b2}; + int i, j; + + for (i=0; i<4; i++) { + for (j=0; j<3; j++) { + if (keys[j] >= keys[j+1]) { + SWAP(int, keys[j], keys[j+1]); + } + } + } + + return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34; +} + +int edgepair_cmp(const void *va, const void *vb) +{ + edgepairkey *a = va, *b = vb; + int keysa[4] = {a->a1, a->a2, a->b1, a->b2}; + int keysb[4] = {b->a1, b->a2, b->b1, b->b2}; + int i; + + for (i=0; i<4; i++) { + int j, ok=0; + for (j=0; j<4; j++) { + if (keysa[i] == keysa[j]) { + ok = 1; + break; + } + } + if (!ok) + return -1; + } + + return 0; +} + +static void get_edgepairkey(edgepairkey *key, int a1, int a2, int b1, int b2) +{ + key->a1 = a1; + key->a2 = a2; + key->b1 = b1; + key->b2 = b2; +} + +/*an immense amount of duplication goes on here. . .a major performance hit, I'm sure*/ +static CollPair* cloth_edge_collision ( ModifierData *md1, ModifierData *md2, + BVHTreeOverlap *overlap, CollPair *collpair, + GHash *visithash, MemArena *arena) +{ + ClothModifierData *clmd = ( ClothModifierData * ) md1; + CollisionModifierData *collmd = ( CollisionModifierData * ) md2; + MFace *face1=NULL, *face2 = NULL; + ClothVertex *verts1 = clmd->clothObject->verts; + double distance = 0; + edgepairkey *key, tstkey; + float epsilon1 = clmd->coll_parms->epsilon; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + float no[3], uv[3], t, relnor; + int i, i1, i2, i3, i4, i5, i6; + Cloth *cloth = clmd->clothObject; + float n1[3], n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3]; + void **verts[] = {v1, v2, v3, v4, v5, v6}; + int j, ret, bp1, bp2, bp3, ap1, ap2, ap3, table[6]; + + face1 = & ( clmd->clothObject->mfaces[overlap->indexA] ); + face2 = & ( collmd->mfaces[overlap->indexB] ); + + // check all 4 possible collisions + for ( i = 0; i < 4; i++ ) + { + if ( i == 0 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v2; + ap3 = face1->v3; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v2; + bp3 = face2->v3; + } + else if ( i == 1 ) + { + if ( face1->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v3; + ap3 = face1->v4; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v2; + bp3 = face2->v3; + } + else { + continue; + } + } + if ( i == 2 ) + { + if ( face2->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v2; + ap3 = face1->v3; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v3; + bp3 = face2->v4; + } + else { + continue; + } + } + else if ( i == 3 ) + { + if ( face1->v4 && face2->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v3; + ap3 = face1->v4; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v3; + bp3 = face2->v4; + } + else { + continue; + } + } + + copy_v3_v3(v1[0], cloth->verts[ap1].txold); + copy_v3_v3(v1[1], cloth->verts[ap1].tx); + copy_v3_v3(v2[0], cloth->verts[ap2].txold); + copy_v3_v3(v2[1], cloth->verts[ap2].tx); + copy_v3_v3(v3[0], cloth->verts[ap3].txold); + copy_v3_v3(v3[1], cloth->verts[ap3].tx); + + copy_v3_v3(v4[0], collmd->current_x[bp1].co); + copy_v3_v3(v4[1], collmd->current_xnew[bp1].co); + copy_v3_v3(v5[0], collmd->current_x[bp2].co); + copy_v3_v3(v5[1], collmd->current_xnew[bp2].co); + copy_v3_v3(v6[0], collmd->current_x[bp3].co); + copy_v3_v3(v6[1], collmd->current_xnew[bp3].co); + + normal_tri_v3(n2, v4[1], v5[1], v6[1]); + + /*offset new positions a bit, to account for margins*/ + i1 = ap1; i2 = ap2; i3 = ap3; + i4 = bp1; i5 = bp2; i6 = bp3; + + for (j=0; j<3; j++) { + int collp1, collp2, k, j2 = (j+1)%3; + + table[0] = ap1; table[1] = ap2; table[2] = ap3; + table[3] = bp1; table[4] = bp2; table[5] = bp3; + for (k=0; k<3; k++) { + float p1[3], p2[3]; + int k2 = (k+1)%3; + + get_edgepairkey(&tstkey, table[j], table[j2], table[k+3], table[k2+3]); + //if (BLI_ghash_haskey(visithash, &tstkey)) + // continue; + + key = BLI_memarena_alloc(arena, sizeof(edgepairkey)); + *key = tstkey; + BLI_ghash_insert(visithash, key, NULL); + + sub_v3_v3v3(p1, verts[j], verts[j2]); + sub_v3_v3v3(p2, verts[k+3], verts[k2+3]); + + cross_v3_v3v3(off, p1, p2); + normalize_v3(off); + + if (dot_v3v3(n2, off) < 0.0) + negate_v3(off); + + mul_v3_fl(off, epsilon1 + epsilon2 + ALMOST_ZERO); + copy_v3_v3(p1, verts[k+3]); + copy_v3_v3(p2, verts[k2+3]); + add_v3_v3(p1, off); + add_v3_v3(p2, off); + + ret = eltopo_line_line_moving_isect_v3v3_f(verts[j], table[j], verts[j2], table[j2], + p1, table[k+3], p2, table[k2+3], + no, uv, &t, &relnor); + /*cloth vert versus coll face*/ + if (ret) { + collpair->ap1 = table[j]; collpair->ap2 = table[j2]; + collpair->bp1 = table[k+3]; collpair->bp2 = table[k2+3]; + + /*I'm not sure if this is correct, but hopefully it's + better then simply ignoring back edges*/ + if (dot_v3v3(n2, no) < 0.0) { + negate_v3(no); + } + + copy_v3_v3(collpair->normal, no); + mul_v3_v3fl(collpair->vector, collpair->normal, relnor); + collpair->distance = relnor; + collpair->time = t; + + copy_v2_v2(collpair->bary, uv); + + collpair->flag = COLLISION_IS_EDGES; + collpair++; + } + } + } + } + + return collpair; +} + +static int cloth_edge_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) +{ + int result = 0; + Cloth *cloth1; + float w1, w2; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel, pimpulse[3]; + + cloth1 = clmd->clothObject; + + for ( ; collpair != collision_end; collpair++ ) + { + if (!(collpair->flag & COLLISION_IS_EDGES)) + continue; + + // was: txold + w1 = collpair->bary[0]; w2 = collpair->bary[1]; + + // Calculate relative "velocity". + VECADDFAC(v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, w1); + VECADDFAC(v2, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, w2); + + VECSUB ( relativeVelocity, v2, v1); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR ( relativeVelocity, collpair->normal ); + + // If v_n_mag < 0 the edges are approaching each other. + if ( magrelVel > ALMOST_ZERO ) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + float magtangent = 0, repulse = 0, d = 0; + double impulse = 0.0; + float vrel_t_pre[3]; + float temp[3], spf; + + zero_v3(pimpulse); + + // calculate tangential velocity + VECCOPY ( temp, collpair->normal ); + mul_v3_fl( temp, magrelVel ); + VECSUB ( vrel_t_pre, relativeVelocity, temp ); + + // Decrease in magnitude of relative tangential velocity due to coulomb friction + // in original formula "magrelVel" should be the "change of relative velocity in normal direction" + magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) ); + + // Apply friction impulse. + if ( magtangent > ALMOST_ZERO ) + { + normalize_v3( vrel_t_pre ); + + impulse = magtangent; + VECADDMUL ( pimpulse, vrel_t_pre, impulse); + } + + // Apply velocity stopping impulse + // I_c = m * v_N / 2.0 + // no 2.0 * magrelVel normally, but looks nicer DG + impulse = magrelVel; + + mul_v3_fl(collpair->normal, 0.5); + VECADDMUL ( pimpulse, collpair->normal, impulse); + + // Apply repulse impulse if distance too short + // I_r = -min(dt*kd, m(0,1d/dt - v_n)) + spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; + + d = collpair->distance; + if ( ( magrelVel < 0.1*d*spf && ( d > ALMOST_ZERO ) ) ) + { + repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel ); + + // stay on the safe side and clamp repulse + if ( impulse > ALMOST_ZERO ) + repulse = MIN2 ( repulse, 5.0*impulse ); + repulse = MAX2 ( impulse, repulse ); + + impulse = repulse / ( 5.0 ); // original 2.0 / 0.25 + VECADDMUL ( pimpulse, collpair->normal, impulse); + } + + w2 = 1.0f-w1; + if (w1 < 0.5) + w1 *= 2.0; + else + w2 *= 2.0; + + VECADDFAC(cloth1->verts[collpair->ap1].impulse, cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0); + VECADDFAC(cloth1->verts[collpair->ap2].impulse, cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0); + + cloth1->verts[collpair->ap1].impulse_count++; + cloth1->verts[collpair->ap2].impulse_count++; + + result = 1; + } + } + + return result; +} + +static int cloth_collision_response_moving ( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) +{ + int result = 0; + Cloth *cloth1; + float w1, w2, w3, u1, u2, u3; + float v1[3], v2[3], relativeVelocity[3]; + float magrelVel; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + + cloth1 = clmd->clothObject; + + for ( ; collpair != collision_end; collpair++ ) + { + if (collpair->flag & COLLISION_IS_EDGES) + continue; + + if ( collpair->flag & COLLISION_USE_COLLFACE ) { + // was: txold + w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2]; + + // Calculate relative "velocity". + collision_interpolateOnTriangle ( v1, collmd->current_v[collpair->bp1].co, collmd->current_v[collpair->bp2].co, collmd->current_v[collpair->bp3].co, w1, w2, w3); + + VECSUB ( relativeVelocity, v1, cloth1->verts[collpair->collp].tv); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR ( relativeVelocity, collpair->normal ); + + // If v_n_mag < 0 the edges are approaching each other. + if ( magrelVel > ALMOST_ZERO ) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + float magtangent = 0, repulse = 0, d = 0; + double impulse = 0.0; + float vrel_t_pre[3]; + float temp[3], spf; + + // calculate tangential velocity + VECCOPY ( temp, collpair->normal ); + mul_v3_fl( temp, magrelVel ); + VECSUB ( vrel_t_pre, relativeVelocity, temp ); + + // Decrease in magnitude of relative tangential velocity due to coulomb friction + // in original formula "magrelVel" should be the "change of relative velocity in normal direction" + magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) ); + + // Apply friction impulse. + if ( magtangent > ALMOST_ZERO ) + { + normalize_v3( vrel_t_pre ); + + impulse = magtangent; // 2.0 * + VECADDMUL ( cloth1->verts[collpair->collp].impulse, vrel_t_pre, impulse); + } + + // Apply velocity stopping impulse + // I_c = m * v_N / 2.0 + // no 2.0 * magrelVel normally, but looks nicer DG + impulse = magrelVel/2.0; + + VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse); + cloth1->verts[collpair->collp].impulse_count++; + + // Apply repulse impulse if distance too short + // I_r = -min(dt*kd, m(0,1d/dt - v_n)) + spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; + + d = -collpair->distance; + if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) ) + { + repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel ); + + // stay on the safe side and clamp repulse + if ( impulse > ALMOST_ZERO ) + repulse = MIN2 ( repulse, 5.0*impulse ); + repulse = MAX2 ( impulse, repulse ); + + impulse = repulse / ( 5.0 ); // original 2.0 / 0.25 + VECADDMUL ( cloth1->verts[collpair->collp].impulse, collpair->normal, impulse); + } + + result = 1; + } + } else { + w1 = collpair->bary[0]; w2 = collpair->bary[1]; w3 = collpair->bary[2]; + + // Calculate relative "velocity". + collision_interpolateOnTriangle ( v1, cloth1->verts[collpair->ap1].tv, cloth1->verts[collpair->ap2].tv, cloth1->verts[collpair->ap3].tv, w1, w2, w3 ); + + VECSUB ( relativeVelocity, collmd->current_v[collpair->collp].co, v1); + + // Calculate the normal component of the relative velocity (actually only the magnitude - the direction is stored in 'normal'). + magrelVel = INPR ( relativeVelocity, collpair->normal ); + + // If v_n_mag < 0 the edges are approaching each other. + if ( magrelVel > ALMOST_ZERO ) + { + // Calculate Impulse magnitude to stop all motion in normal direction. + float magtangent = 0, repulse = 0, d = 0; + double impulse = 0.0; + float vrel_t_pre[3], pimpulse[3] = {0.0f, 0.0f, 0.0f}; + float temp[3], spf; + + // calculate tangential velocity + VECCOPY ( temp, collpair->normal ); + mul_v3_fl( temp, magrelVel ); + VECSUB ( vrel_t_pre, relativeVelocity, temp ); + + // Decrease in magnitude of relative tangential velocity due to coulomb friction + // in original formula "magrelVel" should be the "change of relative velocity in normal direction" + magtangent = MIN2 ( clmd->coll_parms->friction * 0.01 * magrelVel,sqrt ( INPR ( vrel_t_pre,vrel_t_pre ) ) ); + + // Apply friction impulse. + if ( magtangent > ALMOST_ZERO ) + { + normalize_v3( vrel_t_pre ); + + impulse = magtangent; // 2.0 * + VECADDMUL ( pimpulse, vrel_t_pre, impulse); + } + + // Apply velocity stopping impulse + // I_c = m * v_N / 2.0 + // no 2.0 * magrelVel normally, but looks nicer DG + impulse = magrelVel/2.0; + + VECADDMUL ( pimpulse, collpair->normal, impulse); + + // Apply repulse impulse if distance too short + // I_r = -min(dt*kd, m(0,1d/dt - v_n)) + spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; + + d = -collpair->distance; + if ( ( magrelVel < 0.1*d*spf ) && ( d > ALMOST_ZERO ) ) + { + repulse = MIN2 ( d*1.0/spf, 0.1*d*spf - magrelVel ); + + // stay on the safe side and clamp repulse + if ( impulse > ALMOST_ZERO ) + repulse = MIN2 ( repulse, 5.0*impulse ); + repulse = MAX2 ( impulse, repulse ); + + impulse = repulse / ( 2.0 ); // original 2.0 / 0.25 + VECADDMUL ( pimpulse, collpair->normal, impulse); + } + + if (w1 < 0.5) w1 *= 2.0; + if (w2 < 0.5) w2 *= 2.0; + if (w3 < 0.5) w3 *= 2.0; + + VECADDMUL(cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0); + VECADDMUL(cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0); + VECADDMUL(cloth1->verts[collpair->ap3].impulse, pimpulse, w3*2.0);; + cloth1->verts[collpair->ap1].impulse_count++; + cloth1->verts[collpair->ap2].impulse_count++; + cloth1->verts[collpair->ap3].impulse_count++; + + result = 1; + } + } + } + + return result; +} + + +typedef struct tripairkey { + int p, a1, a2, a3; +} tripairkey; + +unsigned int tripair_hash(void *vkey) +{ + tripairkey *key = vkey; + int keys[4] = {key->p, key->a1, key->a2, key->a3}; + int i, j; + + for (i=0; i<4; i++) { + for (j=0; j<3; j++) { + if (keys[j] >= keys[j+1]) { + SWAP(int, keys[j], keys[j+1]); + } + } + } + + return keys[0]*101 + keys[1]*72 + keys[2]*53 + keys[3]*34; +} + +int tripair_cmp(const void *va, const void *vb) +{ + tripairkey *a = va, *b = vb; + int keysa[4] = {a->p, a->a1, a->a2, a->a3}; + int keysb[4] = {b->p, b->a1, b->a2, b->a3}; + int i; + + for (i=0; i<4; i++) { + int j, ok=0; + for (j=0; j<4; j++) { + if (keysa[i] == keysa[j]) { + ok = 1; + break; + } + } + if (!ok) + return -1; + } + + return 0; +} + +static void get_tripairkey(tripairkey *key, int p, int a1, int a2, int a3) +{ + key->a1 = a1; + key->a2 = a2; + key->a3 = a3; + key->p = p; +} + +static int checkvisit(MemArena *arena, GHash *gh, int p, int a1, int a2, int a3) +{ + tripairkey key, *key2; + + get_tripairkey(&key, p, a1, a2, a3); + if (BLI_ghash_haskey(gh, &key)) + return 1; + + key2 = BLI_memarena_alloc(arena, sizeof(*key2)); + *key2 = key; + BLI_ghash_insert(gh, key2, NULL); + + return 0; +} + +int cloth_point_tri_moving_v3v3_f(float v1[2][3], int i1, float v2[2][3], int i2, + float v3[2][3], int i3, float v4[2][3], int i4, + float normal[3], float bary[3], float *t, + float *relnor, GHash *gh, MemArena *arena) +{ + if (checkvisit(arena, gh, i1, i2, i3, i4)) + return 0; + + return eltopo_point_tri_moving_v3v3_f(v1, i1, v2, i2, v3, i3, v4, i4, normal, bary, t, relnor); +} + +static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, + CollPair *collpair, double dt, GHash *gh, MemArena *arena) +{ + ClothModifierData *clmd = ( ClothModifierData * ) md1; + CollisionModifierData *collmd = ( CollisionModifierData * ) md2; + MFace *face1=NULL, *face2 = NULL; + ClothVertex *verts1 = clmd->clothObject->verts; + double distance = 0; + float epsilon1 = clmd->coll_parms->epsilon; + float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + float no[3], uv[3], t, relnor; + int i, i1, i2, i3, i4, i5, i6; + Cloth *cloth = clmd->clothObject; + float n1[3], sdis, p[3], l, n2[3], off[3], v1[2][3], v2[2][3], v3[2][3], v4[2][3], v5[2][3], v6[2][3]; + int j, ret, bp1, bp2, bp3, ap1, ap2, ap3; + + face1 = & ( clmd->clothObject->mfaces[overlap->indexA] ); + face2 = & ( collmd->mfaces[overlap->indexB] ); + + // check all 4 possible collisions + for ( i = 0; i < 4; i++ ) + { + if ( i == 0 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v2; + ap3 = face1->v3; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v2; + bp3 = face2->v3; + } + else if ( i == 1 ) + { + if ( face1->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v3; + ap3 = face1->v4; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v2; + bp3 = face2->v3; + } + else { + continue; + } + } + if ( i == 2 ) + { + if ( face2->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v2; + ap3 = face1->v3; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v3; + bp3 = face2->v4; + } + else { + continue; + } + } + else if ( i == 3 ) + { + if ( face1->v4 && face2->v4 ) + { + // fill faceA + ap1 = face1->v1; + ap2 = face1->v3; + ap3 = face1->v4; + + // fill faceB + bp1 = face2->v1; + bp2 = face2->v3; + bp3 = face2->v4; + } + else { + continue; + } + } + + copy_v3_v3(v1[0], cloth->verts[ap1].txold); + copy_v3_v3(v1[1], cloth->verts[ap1].tx); + copy_v3_v3(v2[0], cloth->verts[ap2].txold); + copy_v3_v3(v2[1], cloth->verts[ap2].tx); + copy_v3_v3(v3[0], cloth->verts[ap3].txold); + copy_v3_v3(v3[1], cloth->verts[ap3].tx); + + copy_v3_v3(v4[0], collmd->current_x[bp1].co); + copy_v3_v3(v4[1], collmd->current_xnew[bp1].co); + copy_v3_v3(v5[0], collmd->current_x[bp2].co); + copy_v3_v3(v5[1], collmd->current_xnew[bp2].co); + copy_v3_v3(v6[0], collmd->current_x[bp3].co); + copy_v3_v3(v6[1], collmd->current_xnew[bp3].co); + + normal_tri_v3(n2, v4[1], v5[1], v6[1]); + + sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON; + + /*apply a repulsion force, to help the solver along*/ + copy_v3_v3(off, n2); + negate_v3(off); + if (isect_ray_plane_v3(v1[1], off, v4[1], v5[1], v6[1], &l, 0)) { + if (l >= 0.0 && l < sdis) { + mul_v3_fl(off, (l-sdis)*cloth->verts[ap1].mass*dt*clmd->coll_parms->repel_force*0.1); + + add_v3_v3(cloth->verts[ap1].tv, off); + add_v3_v3(cloth->verts[ap2].tv, off); + add_v3_v3(cloth->verts[ap3].tv, off); + } + } + + /*offset new positions a bit, to account for margins*/ + copy_v3_v3(off, n2); + mul_v3_fl(off, epsilon1 + epsilon2 + ALMOST_ZERO); + add_v3_v3(v4[1], off); add_v3_v3(v5[1], off); add_v3_v3(v6[1], off); + + i1 = ap1; i2 = ap2; i3 = ap3; + i4 = bp1+cloth->numverts; i5 = bp2+cloth->numverts; i6 = bp3+cloth->numverts; + + for (j=0; j<6; j++) { + int collp; + + switch (j) { + case 0: + ret = cloth_point_tri_moving_v3v3_f(v1, i1, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena); + collp = ap1; + break; + case 1: + collp = ap2; + ret = cloth_point_tri_moving_v3v3_f(v2, i2, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena); + break; + case 2: + collp = ap3; + ret = cloth_point_tri_moving_v3v3_f(v3, i3, v4, i4, v5, i5, v6, i6, no, uv, &t, &relnor, gh, arena); + break; + case 3: + collp = bp1; + ret = cloth_point_tri_moving_v3v3_f(v4, i4, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena); + break; + case 4: + collp = bp2; + ret = cloth_point_tri_moving_v3v3_f(v5, i5, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena); + break; + case 5: + collp = bp3; + ret = cloth_point_tri_moving_v3v3_f(v6, i6, v1, i1, v2, i2, v3, i3, no, uv, &t, &relnor, gh, arena); + break; + } + + /*cloth vert versus coll face*/ + if (ret && j < 3) { + collpair->bp1 = bp1; collpair->bp2 = bp2; collpair->bp3 = bp3; + collpair->collp = collp; + + copy_v3_v3(collpair->normal, no); + mul_v3_v3fl(collpair->vector, collpair->normal, relnor); + collpair->distance = relnor; + collpair->time = t; + + copy_v3_v3(collpair->bary, uv); + + collpair->flag = COLLISION_USE_COLLFACE; + collpair++; + } else if (ret && j >= 3) { /*coll vert versus cloth face*/ + collpair->ap1 = ap1; collpair->ap2 = ap2; collpair->ap3 = ap3; + collpair->collp = collp; + + copy_v3_v3(collpair->normal, no); + mul_v3_v3fl(collpair->vector, collpair->normal, relnor); + collpair->distance = relnor; + collpair->time = t; + + copy_v3_v3(collpair->bary, uv); + + collpair->flag = 0; + collpair++; + } + } + } + + return collpair; +} + +static void machine_epsilon_offset(Cloth *cloth) { + ClothVertex *cv; + int i, j; + + cv = cloth->verts; + for (i=0; i<cloth->numverts; i++, cv++) { + /*aggrevatingly enough, it's necassary to offset the coordinates + by a multiple of the 32-bit floating point epsilon when switching + into doubles*/ + #define RNDSIGN (float)(-1*(BLI_rand()%2==0)|1) + for (j=0; j<3; j++) { + cv->tx[j] += FLT_EPSILON*30.0f*RNDSIGN; + cv->txold[j] += FLT_EPSILON*30.0f*RNDSIGN; + cv->tv[j] += FLT_EPSILON*30.0f*RNDSIGN; + } + } +} + +#else /* !WITH_ELTOPO */ //Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned -static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTreeOverlap *overlap, CollPair *collpair ) +static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, + BVHTreeOverlap *overlap, CollPair *collpair, float dt ) { ClothModifierData *clmd = ( ClothModifierData * ) md1; CollisionModifierData *collmd = ( CollisionModifierData * ) md2; + Cloth *cloth = clmd->clothObject; MFace *face1=NULL, *face2 = NULL; #ifdef USE_BULLET ClothVertex *verts1 = clmd->clothObject->verts; @@ -614,6 +1408,7 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree double distance = 0; float epsilon1 = clmd->coll_parms->epsilon; float epsilon2 = BLI_bvhtree_getepsilon ( collmd->bvhtree ); + float n2[3], sdis, l; int i; face1 = & ( clmd->clothObject->mfaces[overlap->indexA] ); @@ -685,7 +1480,28 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree else break; } + + normal_tri_v3(n2, collmd->current_xnew[collpair->bp1].co, + collmd->current_xnew[collpair->bp2].co, + collmd->current_xnew[collpair->bp3].co); + + sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON; + + /*apply a repulsion force, to help the solver along. + this is kindof crude, it only tests one vert of the triangle*/ + if (isect_ray_plane_v3(cloth->verts[collpair->ap1].tx, n2, collmd->current_xnew[collpair->bp1].co, + collmd->current_xnew[collpair->bp2].co, + collmd->current_xnew[collpair->bp3].co, &l, 0)) + { + if (l >= 0.0 && l < sdis) { + mul_v3_fl(n2, (l-sdis)*cloth->verts[collpair->ap1].mass*dt*clmd->coll_parms->repel_force*0.1); + add_v3_v3(cloth->verts[collpair->ap1].tv, n2); + add_v3_v3(cloth->verts[collpair->ap2].tv, n2); + add_v3_v3(cloth->verts[collpair->ap3].tv, n2); + } + } + #ifdef USE_BULLET // calc distance + normal distance = plNearestPoints ( @@ -741,6 +1557,8 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2, BVHTree } return collpair; } +#endif /* WITH_ELTOPO */ + #if 0 static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionModifierData *collmd, CollPair *collpair, CollPair *collision_end ) @@ -856,10 +1674,10 @@ static int cloth_collision_response_moving( ClothModifierData *clmd, CollisionMo #if 0 static float projectPointOntoLine(float *p, float *a, float *b) { - float ba[3], pa[3]; - VECSUB(ba, b, a); - VECSUB(pa, p, a); - return INPR(pa, ba) / INPR(ba, ba); + float ba[3], pa[3]; + VECSUB(ba, b, a); + VECSUB(pa, p, a); + return INPR(pa, ba) / INPR(ba, ba); } static void calculateEENormal(float *np1, float *np2, float *np3, float *np4,float *out_normal) @@ -1446,17 +2264,45 @@ void free_collider_cache(ListBase **colliders) } } -static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap) + +static void cloth_bvh_objcollisions_nearcheck ( ClothModifierData * clmd, CollisionModifierData *collmd, + CollPair **collisions, CollPair **collisions_index, int numresult, BVHTreeOverlap *overlap, double dt) { int i; +#ifdef WITH_ELTOPO + GHash *visithash = BLI_ghash_new(edgepair_hash, edgepair_cmp, "visthash, collision.c"); + GHash *tri_visithash = BLI_ghash_new(tripair_hash, tripair_cmp, "tri_visthash, collision.c"); + MemArena *arena = BLI_memarena_new(1<<16, "edge hash arena, collision.c"); +#endif - *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 4, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision + *collisions = ( CollPair* ) MEM_mallocN ( sizeof ( CollPair ) * numresult * 64, "collision array" ); //*4 since cloth_collision_static can return more than 1 collision *collisions_index = *collisions; + +#ifdef WITH_ELTOPO + machine_epsilon_offset(clmd->clothObject); + + for ( i = 0; i < numresult; i++ ) + { + *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, + overlap+i, *collisions_index, dt, tri_visithash, arena ); + } for ( i = 0; i < numresult; i++ ) { - *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, overlap+i, *collisions_index ); + *collisions_index = cloth_edge_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, + overlap+i, *collisions_index, visithash, arena ); } + BLI_ghash_free(visithash, NULL, NULL); + BLI_ghash_free(tri_visithash, NULL, NULL); + BLI_memarena_free(arena); +#else /* WITH_ELTOPO */ + for ( i = 0; i < numresult; i++ ) + { + *collisions_index = cloth_collision ( ( ModifierData * ) clmd, ( ModifierData * ) collmd, + overlap+i, *collisions_index, dt ); + } +#endif /* WITH_ELTOPO */ + } static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, CollisionModifierData *collmd, CollPair *collisions, CollPair *collisions_index) @@ -1481,11 +2327,19 @@ static int cloth_bvh_objcollisions_resolve ( ClothModifierData * clmd, Collision if ( collmd->bvhtree ) { +#ifdef WITH_ELTOPO + result += cloth_collision_response_moving(clmd, collmd, collisions, collisions_index); + result += cloth_edge_collision_response_moving(clmd, collmd, collisions, collisions_index); +#else result += cloth_collision_response_static ( clmd, collmd, collisions, collisions_index ); - +#endif +#ifdef WITH_ELTOPO + { +#else // apply impulses in parallel if ( result ) { +#endif for ( i = 0; i < numverts; i++ ) { // calculate "velocities" (just xnew = xold + v; no dt in v) @@ -1518,7 +2372,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl if ((clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_COLLOBJ) || cloth_bvh==NULL) return 0; - + verts = cloth->verts; numfaces = cloth->numfaces; numverts = cloth->numverts; @@ -1557,6 +2411,7 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl continue; /* move object to position (step) in time */ + collision_move_object ( collmd, step + dt, step ); /* search for overlapping collision pairs */ @@ -1565,7 +2420,8 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl // go to next object if no overlap is there if( result && overlap ) { /* check if collisions really happen (costly near check) */ - cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], &collisions_index[i], result, overlap); + cloth_bvh_objcollisions_nearcheck ( clmd, collmd, &collisions[i], + &collisions_index[i], result, overlap, dt/(float)clmd->coll_parms->loop_count); // resolve nearby collisions ret += cloth_bvh_objcollisions_resolve ( clmd, collmd, collisions[i], collisions_index[i]); @@ -1721,5 +2577,5 @@ int cloth_bvh_objcollision (Object *ob, ClothModifierData * clmd, float step, fl if(collobjs) MEM_freeN(collobjs); - return MIN2 ( ret, 1 ); + return 1|MIN2 ( ret, 1 ); } diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 46f3e124bcc..1d7481b365a 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -793,7 +793,7 @@ void curvemapping_evaluate_premulRGBF(CurveMapping *cumap, float *vecout, const /* basic error handler, if we dont do this blender will exit */ static int ErrorReportingFunction(int ErrorCode, const char *ErrorText) { - fprintf(stderr, "%s:%d\n", ErrorText, ErrorCode); + fprintf(stderr, "%s:%d\n", ErrorText, ErrorCode); return 1; } #endif diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 7956da5da80..b93362b8676 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -4021,7 +4021,9 @@ bConstraintTypeInfo *constraint_get_typeinfo (bConstraint *con) /* ---------- Data Management ------- */ -/* Free data of a specific constraint if it has any info */ +/* Free data of a specific constraint if it has any info. + * be sure to run BIK_clear_data() when freeing an IK constraint, + * unless DAG_scene_sort is called. */ void free_constraint_data (bConstraint *con) { if (con->data) { diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c index 2a44c942865..22646ab3cb5 100644 --- a/source/blender/blenkernel/intern/context.c +++ b/source/blender/blenkernel/intern/context.c @@ -520,11 +520,10 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res C->data.recursion= 1; - for(entry=C->wm.store->entries.first; entry; entry=entry->next) { - if(strcmp(entry->name, member) == 0) { - result->ptr= entry->ptr; - done= 1; - } + entry= BLI_rfindstring(&C->wm.store->entries, member, offsetof(bContextStoreEntry, name)); + if(entry) { + result->ptr= entry->ptr; + done= 1; } } if(done!=1 && recursion < 2 && C->wm.region) { @@ -718,7 +717,7 @@ int CTX_data_equals(const char *member, const char *str) int CTX_data_dir(const char *member) { - return (strcmp(member, "") == 0); + return member[0] == '\0'; } void CTX_data_id_pointer_set(bContextDataResult *result, ID *id) diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index b374727b87c..6d41eb6098b 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -64,7 +64,8 @@ #include "BKE_key.h" #include "BKE_library.h" #include "BKE_main.h" -#include "BKE_object.h" +#include "BKE_object.h" +#include "BKE_material.h" #include "ED_curve.h" @@ -202,6 +203,7 @@ Curve *copy_curve(Curve *cu) cun->editnurb= NULL; cun->editfont= NULL; + cun->selboxes= NULL; #if 0 // XXX old animation system /* single user ipo too */ @@ -216,10 +218,22 @@ Curve *copy_curve(Curve *cu) return cun; } +static void extern_local_curve(Curve *cu) +{ + id_lib_extern((ID *)cu->vfont); + id_lib_extern((ID *)cu->vfontb); + id_lib_extern((ID *)cu->vfonti); + id_lib_extern((ID *)cu->vfontbi); + + if(cu->mat) { + extern_local_matarar(cu->mat, cu->totcol); + } +} + void make_local_curve(Curve *cu) { - Object *ob = NULL; - Curve *cun; + Main *bmain= G.main; + Object *ob; int local=0, lib=0; /* - when there are only lib users: don't do @@ -229,47 +243,41 @@ void make_local_curve(Curve *cu) if(cu->id.lib==NULL) return; - if(cu->vfont) cu->vfont->id.lib= NULL; - if(cu->vfontb) cu->vfontb->id.lib= NULL; - if(cu->vfonti) cu->vfonti->id.lib= NULL; - if(cu->vfontbi) cu->vfontbi->id.lib= NULL; - if(cu->id.us==1) { cu->id.lib= NULL; cu->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)cu, NULL); + + new_id(&bmain->curve, (ID *)cu, NULL); + extern_local_curve(cu); return; } - - ob= G.main->object.first; - while(ob) { - if(ob->data==cu) { + + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + if(ob->data == cu) { if(ob->id.lib) lib= 1; else local= 1; } - ob= ob->id.next; } - + if(local && lib==0) { cu->id.lib= NULL; cu->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)cu, NULL); + + new_id(&bmain->curve, (ID *)cu, NULL); + extern_local_curve(cu); } else if(local && lib) { - cun= copy_curve(cu); + Curve *cun= copy_curve(cu); cun->id.us= 0; - - ob= G.main->object.first; - while(ob) { + + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==cu) { - if(ob->id.lib==NULL) { ob->data= cun; cun->id.us++; cu->id.us--; } } - ob= ob->id.next; } } } @@ -1026,19 +1034,19 @@ void forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int i rt2= 3.0f*(q0-2.0f*q1+q2)/f; f*= it; rt3= (q3-q0+3.0f*(q1-q2))/f; - - q0= rt0; + + q0= rt0; q1= rt1+rt2+rt3; q2= 2*rt2+6*rt3; q3= 6*rt3; - - for(a=0; a<=it; a++) { + + for(a=0; a<=it; a++) { *p= q0; p = (float *)(((char *)p)+stride); q0+= q1; - q1+= q2; - q2+= q3; - } + q1+= q2; + q2+= q3; + } } static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float *p3, float *p, int it, int stride) @@ -1048,7 +1056,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float * * This could also be optimized like forward_diff_bezier */ int a; - for(a=0; a<=it; a++) { + for(a=0; a<=it; a++) { float t = (float)a / (float)it; int i; @@ -1057,7 +1065,7 @@ static void forward_diff_bezier_cotangent(float *p0, float *p1, float *p2, float } normalize_v3(p); p = (float *)(((char *)p)+stride); - } + } } /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ @@ -1092,7 +1100,7 @@ float *make_orco_surf(Object *ob) sizev = nu->pntsv*resolv; if (nu->flagu & CU_NURB_CYCLIC) sizeu++; if (nu->flagv & CU_NURB_CYCLIC) sizev++; - if(nu->pntsv>1) tot+= sizeu * sizev; + if(nu->pntsv>1) tot+= sizeu * sizev; nu= nu->next; } diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index a0f8a0f13ee..0c4d1d067e6 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -255,7 +255,6 @@ int defgroup_find_index (Object *ob, bDeformGroup *dg) if (eg == NULL) return -1; return def_nr; - } /* note, must be freed */ @@ -362,7 +361,7 @@ void flip_side_name (char name[MAX_VGROUP_NAME], const char from_name[MAX_VGROUP index= strrchr(name, '.'); // last occurrence if (index && isdigit(index[1]) ) { // doesnt handle case bone.1abc2 correct..., whatever! if(strip_number==0) - BLI_strncpy(number, index, sizeof(number)); + BLI_strncpy(number, index, sizeof(number)); *index= 0; len= BLI_strnlen(name, MAX_VGROUP_NAME); } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index ff49c64ebf4..6813d5d18a6 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -492,7 +492,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O } } } - + /* softbody collision */ if ((ob->type==OB_MESH) || (ob->type==OB_CURVE) || (ob->type==OB_LATTICE)) { if(modifiers_isSoftbodyEnabled(ob) || modifiers_isClothEnabled(ob) || ob->particlesystem.first) @@ -1092,10 +1092,10 @@ void graph_bfs(void) push_queue(nqueue,itA->node); } - else { + else { fprintf(stderr,"bfs not dag tree edge color :%i \n",itA->node->color); } - + itA = itA->next; } @@ -1225,7 +1225,7 @@ DagNodeQueue * graph_dfs(void) while(nqueue->count) { //graph_print_queue(nqueue); - skip = 0; + skip = 0; node = get_top_node_queue(nqueue); minheight = pos[node->DFS_dist]; @@ -1253,7 +1253,7 @@ DagNodeQueue * graph_dfs(void) */ /*if (node->DFS_dist >= itA->node->DFS_dist) itA->node->DFS_dist = node->DFS_dist + 1; - + fprintf(stderr,"dfs forward or cross edge :%15s %i-%i %15s %i-%i \n", ((ID *) node->ob)->name, node->DFS_dvtm, @@ -1287,17 +1287,17 @@ DagNodeQueue * graph_dfs(void) /* fprintf(stderr,"DFS node : %20s %i %i %i %i\n",((ID *) node->ob)->name,node->BFS_dist, node->DFS_dist, node->DFS_dvtm, node->DFS_fntm ); */ - push_stack(retqueue,node); + push_stack(retqueue,node); } } } node = node->next; } while (node); -// fprintf(stderr,"i size : %i \n", maxpos); - +// fprintf(stderr,"i size : %i \n", maxpos); + queue_delete(nqueue); - return(retqueue); + return(retqueue); } /* unused */ @@ -1905,7 +1905,9 @@ static void dag_scene_flush_layers(Scene *sce, int lay) } /* ensure cameras are set as if they are on a visible layer, because - they ared still used for rendering or setting the camera view */ + * they ared still used for rendering or setting the camera view + * + * XXX, this wont work for local view / unlocked camera's */ if(sce->camera) { node= dag_get_node(sce->theDag, sce->camera); node->scelay |= lay; diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index b314264829c..48192546b0f 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1871,9 +1871,9 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba already applied, thats how it worked for years, so keep for compatibility (sergey) */ copy_displist(&cu->disp, dispbase); - if (!forRender) { - tex_space_curve(cu); - } + if (!forRender) { + tex_space_curve(cu); + } if(!forOrco) curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts); diff --git a/source/blender/blenkernel/intern/exotic.c b/source/blender/blenkernel/intern/exotic.c deleted file mode 100644 index 53384d790e0..00000000000 --- a/source/blender/blenkernel/intern/exotic.c +++ /dev/null @@ -1,2485 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * - * Contributor(s): - * - Martin DeMello - * Added dxf_read_arc, dxf_read_ellipse and dxf_read_lwpolyline - * Copyright (C) 2004 by Etheract Software Labs - * - * - Blender Foundation - * - * ***** END GPL LICENSE BLOCK **** - */ - -/** \file blender/blenkernel/intern/exotic.c - * \ingroup bke - */ - - -#include <stddef.h> -#include "BLI_storage.h" - -#include <stdlib.h> -#include <ctype.h> /* isdigit, isspace */ -#include <math.h> -#include <stdio.h> - -#include <fcntl.h> -#include <string.h> -#include <errno.h> - -#ifndef _WIN32 -#include <unistd.h> -#else -#include <io.h> -#define open _open -#define read _read -#define close _close -#define write _write -#endif - -#include "MEM_guardedalloc.h" - -#include "DNA_object_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_material_types.h" -#include "DNA_curve_types.h" -#include "DNA_camera_types.h" -#include "DNA_scene_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" -#include "BLI_storage.h" -#include "BLI_utildefines.h" - - -#include "BKE_blender.h" -#include "BKE_global.h" -#include "BKE_main.h" -#include "BKE_mesh.h" -#include "BKE_library.h" -#include "BKE_object.h" -#include "BKE_material.h" -#include "BKE_report.h" -#include "BKE_exotic.h" -#include "BKE_displist.h" -#include "BKE_DerivedMesh.h" -#include "BKE_curve.h" - -#ifdef WITH_PYTHON -#include "BPY_extern.h" -#endif - -#include "zlib.h" - -static int is_dxf(const char *str); -static void dxf_read(Scene *scene, const char *filename); -static int is_stl(const char *str); - -static int is_stl_ascii(const char *str) -{ - FILE *fpSTL; - char buffer[1000]; - int numread, i; - - fpSTL = fopen(str, "rb"); - if ( (numread = fread( (void *) buffer, sizeof(char), 1000, fpSTL)) <= 0 ) - { fclose(fpSTL); return 0; } - - for (i=0; i < numread; ++i) { - /* if bit 8 is set we assume binary */ - if (buffer[i] & 0x80) - { fclose(fpSTL); return 0; } - } - - buffer[5] = '\0'; - if ( !(strstr(buffer, "solid")) && !(strstr(buffer, "SOLID")) ) - { fclose(fpSTL); return 0; } - - fclose(fpSTL); - - return 1; -} - -static int is_stl(const char *str) -{ - int i; - i = strlen(str) - 3; - if ( (str[i] !='s') && (str[i] !='S')) - return 0; - i++; - if ( (str[i] !='t') && (str[i] !='T')) - return 0; - i++; - if ( (str[i] !='l') && (str[i] !='L')) - return 0; - - return 1; -} - -#define READSTLVERT { \ - if (fread(mvert->co, sizeof(float), 3, fpSTL) != 3) { \ - char error_msg[255]; \ - MEM_freeN(vertdata); \ - MEM_freeN(facedata); \ - fclose(fpSTL); \ - sprintf(error_msg, "Problems reading face %d!", i); \ - return; \ - } \ - else { \ - if (ENDIAN_ORDER==B_ENDIAN) { \ - SWITCH_INT(mvert->co[0]); \ - SWITCH_INT(mvert->co[1]); \ - SWITCH_INT(mvert->co[2]); \ - } \ - } \ -} - -static void simple_vertex_normal_blend(short *no, short *ble) -{ - if(no[0]==0 && no[1]==0 && no[2]==0) { - VECCOPY(no, ble); - } - else { - no[0]= (2*no[0] + ble[0])/3; - no[1]= (2*no[1] + ble[1])/3; - no[2]= (2*no[2] + ble[2])/3; - } -} - -static void mesh_add_normals_flags(Mesh *me) -{ - MVert *v1, *v2, *v3, *v4; - MFace *mface; - float nor[3]; - int a; - short sno[3]; - - mface= me->mface; - for(a=0; a<me->totface; a++, mface++) { - v1= me->mvert+mface->v1; - v2= me->mvert+mface->v2; - v3= me->mvert+mface->v3; - v4= me->mvert+mface->v4; - - normal_tri_v3( nor,v1->co, v2->co, v3->co); - normal_float_to_short_v3(sno, nor); - - simple_vertex_normal_blend(v1->no, sno); - simple_vertex_normal_blend(v2->no, sno); - simple_vertex_normal_blend(v3->no, sno); - if(mface->v4) { - simple_vertex_normal_blend(v4->no, sno); - } - mface->edcode= ME_V1V2|ME_V2V3; - } -} - -static void read_stl_mesh_binary(Scene *scene, const char *str) -{ - FILE *fpSTL; - Object *ob; - Mesh *me; - MVert *mvert, *vertdata; - MFace *mface, *facedata; - unsigned int numfacets = 0, i, j, vertnum; - unsigned int maxmeshsize, nummesh, lastmeshsize; - unsigned int totvert, totface; - ReportList *reports= NULL; /* XXX */ - - fpSTL= fopen(str, "rb"); - if(fpSTL==NULL) { - BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno)); - return; - } - - if(fseek(fpSTL, 80, SEEK_SET) != 0) { - BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno)); - fclose(fpSTL); - return; - } - - if(fread(&numfacets, 4*sizeof(char), 1, fpSTL) != 1) { - if(feof(fpSTL)) - BKE_reportf(reports, RPT_ERROR, "Failed reading file: premature end of file."); - else - BKE_reportf(reports, RPT_ERROR, "Failed reading file: %s.", strerror(errno)); - fclose(fpSTL); - return; - } - if (ENDIAN_ORDER==B_ENDIAN) { - SWITCH_INT(numfacets); - } - - maxmeshsize = MESH_MAX_VERTS/3; - - nummesh = (numfacets / maxmeshsize) + 1; - lastmeshsize = numfacets % maxmeshsize; - - if (numfacets) { - for (j=0; j < nummesh; ++j) { - /* new object */ - if (j == nummesh-1) { - totface = lastmeshsize; - } - else { - totface = maxmeshsize; - } - totvert = 3 * totface; - - vertdata = MEM_callocN(totvert*sizeof(MVert), "mverts"); - facedata = MEM_callocN(totface*sizeof(MFace), "mface"); - - vertnum = 0; - mvert= vertdata; - mface = facedata; - for (i=0; i < totface; i++) { - fseek(fpSTL, 12, SEEK_CUR); /* skip the face normal */ - READSTLVERT; - mvert++; - READSTLVERT; - mvert++; - READSTLVERT; - mvert++; - - mface->v1 = vertnum++; - mface->v2 = vertnum++; - mface->v3 = vertnum++; - mface++; - - fseek(fpSTL, 2, SEEK_CUR); - } - - ob= add_object(scene, OB_MESH); - me= ob->data; - me->totvert = totvert; - me->totface = totface; - me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, - vertdata, totvert); - me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_ASSIGN, - facedata, totface); - - mesh_add_normals_flags(me); - make_edges(me, 0); - } - //XXX waitcursor(1); - } - fclose(fpSTL); - -} -#undef READSTLVERT - -#define STLALLOCERROR { \ - char error_msg[255]; \ - fclose(fpSTL); \ - sprintf(error_msg, "Can't allocate storage for %d faces!", \ - numtenthousand * 10000); \ - return; \ -} - -#define STLBAILOUT(message) { \ - char error_msg[255]; \ - fclose(fpSTL); \ - free(vertdata); \ - sprintf(error_msg, "Line %d: %s", linenum, message); \ - return; \ -} - -#define STLREADLINE { \ - if (!fgets(buffer, 2048, fpSTL)) STLBAILOUT("Can't read line!"); \ - linenum++; \ -} - -#define STLREADVERT { \ - STLREADLINE; \ - if ( !(cp = strstr(buffer, "vertex")) && \ - !(cp = strstr(buffer, "VERTEX")) ) STLBAILOUT("Bad vertex!"); \ - vp = vertdata + 3 * totvert; \ - if (sscanf(cp + 6, "%f %f %f", vp, vp+1, vp+2) != 3) \ - STLBAILOUT("Bad vertex!"); \ - ++totvert; \ -} -static void read_stl_mesh_ascii(Scene *scene, const char *str) -{ - FILE *fpSTL; - char buffer[2048], *cp; - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mface; - float *vertdata, *vp; - unsigned int numtenthousand, linenum; - unsigned int i, vertnum; - unsigned int totvert, totface; - ReportList *reports= NULL; /* XXX */ - - /* ASCII stl sucks ... we don't really know how many faces there - are until the file is done, so lets allocate faces 10000 at a time */ - - fpSTL= fopen(str, "r"); - if(fpSTL==NULL) { - BKE_reportf(reports, RPT_ERROR, "Can't read file: %s.", strerror(errno)); - return; - } - - /* we'll use the standard malloc/realloc for now ... - * lets allocate enough storage to hold 10000 triangles, - * i.e. 30000 verts, i.e., 90000 floats. - */ - numtenthousand = 1; - vertdata = malloc(numtenthousand*3*30000*sizeof(float)); // uses realloc! - if (!vertdata) { STLALLOCERROR; } - - linenum = 1; - /* Get rid of the first line */ - STLREADLINE; - - totvert = 0; - totface = 0; - while(1) { - /* Read in the next line */ - STLREADLINE; - - /* lets check if this is the end of the file */ - if ( strstr(buffer, "endsolid") || strstr(buffer, "ENDSOLID") ) - break; - - /* Well, guess that wasn't the end, so lets make - * sure we have enough storage for some more faces - */ - if ( (totface) && ( (totface % 10000) == 0 ) ) { - float *vertdata_old= vertdata; - ++numtenthousand; - vertdata = realloc(vertdata, - numtenthousand*3*30000*sizeof(float)); - if (!vertdata) { - if(vertdata_old) { - free(vertdata_old); - } - STLALLOCERROR; - } - } - - /* Don't read normal, but check line for proper syntax anyway - */ - if ( !(cp = strstr(buffer, "facet")) && - !(cp = strstr(buffer, "FACET")) ) STLBAILOUT("Bad normal line!"); - if ( !(strstr(cp+5, "normal")) && - !(strstr(cp+5, "NORMAL")) ) STLBAILOUT("Bad normal line!"); - - /* Read in what should be the outer loop line - */ - STLREADLINE; - if ( !(cp = strstr(buffer, "outer")) && - !(cp = strstr(buffer, "OUTER")) ) STLBAILOUT("Bad outer loop!"); - if ( !(strstr(cp+5, "loop")) && - !(strstr(cp+5, "LOOP")) ) STLBAILOUT("Bad outer loop!"); - - /* Read in the face */ - STLREADVERT; - STLREADVERT; - STLREADVERT; - - /* Read in what should be the endloop line - */ - STLREADLINE; - if ( !strstr(buffer, "endloop") && !strstr(buffer, "ENDLOOP") ) - STLBAILOUT("Bad endloop!"); - - /* Read in what should be the endfacet line - */ - STLREADLINE; - if ( !strstr(buffer, "endfacet") && !strstr(buffer, "ENDFACET") ) - STLBAILOUT("Bad endfacet!"); - - /* Made it this far? Increment face count */ - ++totface; - } - fclose(fpSTL); - - /* OK, lets create our mesh */ - ob = add_object(scene, OB_MESH); - me = ob->data; - - me->totface = totface; - me->totvert = totvert; - me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, - NULL, totvert); - me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, - NULL, totface); - - /* Copy vert coords and create topology */ - mvert = me->mvert; - mface = me->mface; - vertnum = 0; - for (i=0; i < totface; ++i) { - memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) ); - mface->v1 = vertnum; - mvert++; - vertnum++; - - memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) ); - mface->v2 = vertnum; - mvert++; - vertnum++; - - memcpy(mvert->co, vertdata+3*vertnum, 3*sizeof(float) ); - mface->v3 = vertnum; - mvert++; - vertnum++; - - mface++; - } - free(vertdata); - - mesh_add_normals_flags(me); - make_edges(me, 0); - - //XXX waitcursor(1); -} - -#undef STLALLOCERROR -#undef STLBAILOUT -#undef STLREADLINE -#undef STLREADVERT - -/* ************************************************************ */ - -int BKE_read_exotic(Scene *scene, const char *name) -{ - int len; - gzFile gzfile; - char header[7]; - int retval; - - // make sure we're not trying to read a directory.... - - len= strlen(name); - if (ELEM(name[len-1], '/', '\\')) { - retval= BKE_READ_EXOTIC_FAIL_PATH; - } - else { - gzfile = gzopen(name,"rb"); - - if (gzfile == NULL) { - retval= BKE_READ_EXOTIC_FAIL_OPEN; - } - else { - len= gzread(gzfile, header, sizeof(header)); - gzclose(gzfile); - if (len == sizeof(header) && strncmp(header, "BLENDER", 7) == 0) { - retval= BKE_READ_EXOTIC_OK_BLEND; - } - else { - //XXX waitcursor(1); - if(is_dxf(name)) { - dxf_read(scene, name); - retval= BKE_READ_EXOTIC_OK_OTHER; - } - else if(is_stl(name)) { - if (is_stl_ascii(name)) - read_stl_mesh_ascii(scene, name); - else - read_stl_mesh_binary(scene, name); - retval= BKE_READ_EXOTIC_OK_OTHER; - } - else { - retval= BKE_READ_EXOTIC_FAIL_FORMAT; - } - //XXX waitcursor(0); - } - } - } - - return retval; -} - - -/* ************************ WRITE ************************** */ - -static void write_vert_stl(Object *ob, MVert *verts, int index, FILE *fpSTL) -{ - float vert[3]; - - VECCOPY(vert, verts[(index)].co); - mul_m4_v3(ob->obmat, vert); - - if (ENDIAN_ORDER==B_ENDIAN) { - SWITCH_INT(vert[0]); - SWITCH_INT(vert[1]); - SWITCH_INT(vert[2]); - } - - fwrite(vert, sizeof(float), 3, fpSTL); -} - -static int write_derivedmesh_stl(FILE *fpSTL, Object *ob, DerivedMesh *dm) -{ - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int i, numfacets = 0, totface = dm->getNumTessFaces(dm); - float zero[3] = {0.0f, 0.0f, 0.0f}; - - for (i=0; i<totface; i++, mface++) { - fwrite(zero, sizeof(float), 3, fpSTL); - write_vert_stl(ob, mvert, mface->v1, fpSTL); - write_vert_stl(ob, mvert, mface->v2, fpSTL); - write_vert_stl(ob, mvert, mface->v3, fpSTL); - fprintf(fpSTL, " "); - numfacets++; - - if(mface->v4) { /* quad = 2 tri's */ - fwrite(zero, sizeof(float), 3, fpSTL); - write_vert_stl(ob, mvert, mface->v1, fpSTL); - write_vert_stl(ob, mvert, mface->v3, fpSTL); - write_vert_stl(ob, mvert, mface->v4, fpSTL); - fprintf(fpSTL, " "); - numfacets++; - } - } - - return numfacets; -} - -static int write_object_stl(FILE *fpSTL, Scene *scene, Object *ob) -{ - int numfacets = 0; - DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH); - - numfacets += write_derivedmesh_stl(fpSTL, ob, dm); - - dm->release(dm); - - return numfacets; -} - -void write_stl(Scene *scene, char *str) -{ - Object *ob; - Base *base; - FILE *fpSTL; - int numfacets = 0; - ReportList *reports= NULL; /* XXX */ - - /* XXX, operator needs to manage filename extension */ - - fpSTL= fopen(str, "wb"); - - if(fpSTL==NULL) { - BKE_reportf(reports, RPT_ERROR, "Can't open file: %s.", strerror(errno)); - return; - } - - //XXX waitcursor(1); - - /* The header part of the STL */ - /* First 80 characters are a title or whatever you want. - Lets make the first 32 of those spam and the rest the filename. - Those first 80 characters will be followed by 4 bytes - which will be overwritten later with an integer holding - how many facets are written (we set them to ' ' for now). - */ - fprintf(fpSTL, "Binary STL output from Blender: %-48.48s ", str); - - /* Write all selected mesh objects */ - base= scene->base.first; - while(base) { - if (base->flag & SELECT) { - ob = base->object; - if (ob->type == OB_MESH) { - if(ob->data) - numfacets += write_object_stl(fpSTL, scene, ob); - } - } - base= base->next; - } - - /* time to write the number of facets in the 4 bytes - starting at byte 81 - */ - fseek(fpSTL, 80, SEEK_SET); - - if (ENDIAN_ORDER==B_ENDIAN) { - SWITCH_INT(numfacets); - } - fwrite(&numfacets, 4*sizeof(char), 1, fpSTL); - - fclose(fpSTL); - - //XXX waitcursor(0); -} - - -static void replace_chars(char *str1, char *str2) -{ - int a= strlen(str2); - - str1[a]= 0; - while(a--) { - if(str2[a]=='.' || str2[a]==' ') str1[a]= '_'; - else str1[a]= str2[a]; - } -} - -/* ******************************* WRITE DXF ***************************** */ - -#define write_group(id,data) fprintf(fp, "%d\n%s\n", id, data) - -/* A completely wacky function to try and make good -indexed (AutoCAD index) values out of straight rgb -ones... crazy */ - -static int rgb_to_dxf_col (float rf, float gf, float bf) -{ - int r= (int) (rf*255.0f); - int g= (int) (gf*255.0f); - int b= (int) (bf*255.0f); - float h,s,v; - int ret; - - /* Grayscale value */ - if (((int)r/10)==((int)g/10) && ((int)g/10)==((int)b/10)) ret= 250+((int)r/51); - /* A nice chroma value */ - else { - rgb_to_hsv (rf,gf,bf,&h,&s,&v); - - ret= (int) (10.0f + (h*239.0f)); - CLAMP(ret,10,249); - - /* If its whitish make the index odd */ - if (s<.5 || v>.5) if(ret%2) ret++; - } - - return ret; -} - -/* And its completely wacky complement */ - -static void dxf_col_to_rgb (int cid, float *rf, float *gf, float *bf) -{ - float h, s, v; - - /* Grayscale values */ - if (cid>=250 && cid <= 255) { - *rf= *gf= *bf= (float) ((cid-250)*51)/255; - CLAMP(*rf, 0.0, 1.0); - CLAMP(*gf, 0.0, 1.0); - CLAMP(*bf, 0.0, 1.0); - - /* Pure values */ - } else if (cid<10) { - switch (cid) { - case 1: - *rf=1.0; - *gf=0.0; - *bf=0.0; - break; - case 2: - *rf=1.0; - *gf=1.0; - *bf=0.0; - break; - case 3: - *gf=1.0; - *rf=0.0; - *bf=0.0; - break; - case 4: - *rf=0.0; - *gf=1.0; - *bf=1.0; - break; - case 5: - *rf=0.0; - *gf=0.0; - *bf=1.0; - break; - case 6: - *rf=1.0; - *gf=0.0; - *bf=1.0; - break; - case 7: - default: - *rf= *gf= *bf= 1.0; - break; - } - } else { - /* Get chroma values */ - - h= (float) (cid-10)/239; - CLAMP(h, 0.0, 1.0); - - /* If its odd make it a bit whitish */ - if (cid%2) { s=.75; v= 0.25; - } else { s= 0.25; v= 0.75;} - - hsv_to_rgb (h, s, v, rf, gf, bf); - } -} - -static void write_mesh_dxf(FILE *fp, Mesh *me) -{ - Material *ma; - MVert *mvert; - MFace *mface; - int a; - char str[32]; - - replace_chars(str, me->id.name+2); - - write_group(0, "BLOCK"); - - write_group(2, str); /* The name */ - - write_group(8, "Meshes"); /* DXF Layer */ - write_group(70, "64"); /* DXF block flags */ - - write_group(10, "0.0"); /* X of base */ - write_group(20, "0.0"); /* Y of base */ - write_group(30, "0.0"); /* Z of base */ - - write_group(3, str); /* The name (again) */ - - write_group(0, "POLYLINE"); /* Start the mesh */ - write_group(66, "1"); /* Vertices follow flag */ - write_group(8,"Meshes"); /* DXF Layer */ - - if (me->totcol) { - ma= me->mat[0]; - if(ma) { - sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b)); - write_group(62, str); /* Color index */ - } - } - - write_group(70, "64"); /* Polymesh mesh flag */ - - fprintf(fp, "71\n%d\n", me->totvert); /* Total vertices */ - fprintf(fp, "72\n%d\n", me->totface); /* Total faces */ - - /* Write the vertices */ - a= me->totvert; - mvert= me->mvert; - while(a--) { - write_group(0, "VERTEX"); /* Start a new vertex */ - write_group(8, "Meshes"); /* DXF Layer */ - fprintf (fp, "10\n%f\n", mvert->co[0]); /* X cord */ - fprintf (fp, "20\n%f\n", mvert->co[1]); /* Y cord */ - fprintf (fp, "30\n%f\n", mvert->co[2]); /* Z cord */ - write_group(70, "192"); /* Polymesh vertex flag */ - - mvert++; - } - - /* Write the face entries */ - a= me->totface; - mface= me->mface; - while(a--) { - write_group(0, "VERTEX"); /* Start a new face */ - write_group(8, "Meshes"); - - /* Write a face color */ - if (me->totcol) { - ma= me->mat[(int)mface->mat_nr]; - if(ma) { - sprintf(str,"%d",rgb_to_dxf_col(ma->r,ma->g,ma->b)); - write_group(62, str); /* Color index */ - } - } - else write_group(62, "254"); /* Color Index */ - - /* Not sure what this really corresponds too */ - write_group(10, "0.0"); /* X of base */ - write_group(20, "0.0"); /* Y of base */ - write_group(30, "0.0"); /* Z of base */ - - write_group(70, "128"); /* Polymesh face flag */ - - if(mface->v4) { - fprintf (fp, "71\n%d\n", mface->v1+1); - fprintf (fp, "72\n%d\n", mface->v2+1); - fprintf (fp, "73\n%d\n", mface->v3+1); - fprintf (fp, "74\n%d\n", mface->v4+1); - } else { - fprintf (fp, "71\n%d\n", mface->v1+1); - fprintf (fp, "72\n%d\n", mface->v2+1); - fprintf (fp, "73\n%d\n", mface->v3+1); - } - mface++; - } - - write_group(0, "SEQEND"); - - write_group(0, "ENDBLK"); -} - -static void write_object_dxf(FILE *fp, Object *ob, int layer) -{ - ID *id; - char str[32]; - - id= ob->data; - - write_group(0, "INSERT"); /* Start an insert group */ - - sprintf(str, "%d", layer); - write_group(8, str); - - replace_chars(str, id->name+2); - write_group(2, str); - - fprintf (fp, "10\n%f\n", ob->loc[0]); /* X of base */ - fprintf (fp, "20\n%f\n", ob->loc[1]); /* Y of base */ - fprintf (fp, "30\n%f\n", ob->loc[2]); /* Z of base */ - - fprintf (fp, "41\n%f\n", ob->size[0]); /* X scale */ - fprintf (fp, "42\n%f\n", ob->size[1]); /* Y scale */ - fprintf (fp, "43\n%f\n", ob->size[2]); /* Z scale */ - - fprintf (fp, "50\n%f\n", (float) ob->rot[2]*180/M_PI); /* Can only write the Z rot */ -} - -void write_dxf(struct Scene *scene, char *str) -{ - Mesh *me; - Base *base; - FILE *fp; - - /* XXX, operator needs to handle overwrite & rename */ - - fp= fopen(str, "w"); - - if(fp==NULL) { - //XXX error("Can't write file"); - return; - } - - //XXX waitcursor(1); - - /* The header part of the DXF */ - - write_group(0, "SECTION"); - write_group(2, "HEADER"); - write_group(0, "ENDSEC"); - - /* The blocks part of the DXF */ - - write_group(0, "SECTION"); - write_group(2, "BLOCKS"); - - - /* only write meshes we're using in this scene */ - flag_listbase_ids(&G.main->mesh, LIB_DOIT, 0); - - for(base= scene->base.first; base; base= base->next) - if(base->object->type== OB_MESH) - ((ID *)base->object->data)->flag |= LIB_DOIT; - - /* Write all the meshes */ - me= G.main->mesh.first; - while(me) { - if(me->id.flag & LIB_DOIT) { /* is the mesh used in this scene ? */ - write_mesh_dxf(fp, me); - } - me= me->id.next; - } - - write_group(0, "ENDSEC"); - - /* The entities part of the DXF */ - - write_group(0, "SECTION"); - write_group(2, "ENTITIES"); - - /* Write all the mesh objects */ - base= scene->base.first; - while(base) { - if(base->object->type== OB_MESH) { - write_object_dxf(fp, base->object, base->lay); - } - base= base->next; - } - - write_group(0, "ENDSEC"); - - /* Thats all */ - - write_group(0, "EOF"); - fclose(fp); - - //XXX waitcursor(0); -} - - -static int dxf_line= 0; -static FILE *dxf_fp= NULL; - -/* exotic.c(2863) : note C6311: c:/Program Files/Microsoft Visual - * Studio/VC98/include\ctype.h(268) : see previous definition of - * 'iswspace' */ -#define ton_iswspace(c) (c==' '||c=='\n'||c=='\t') - -static void clean_wspace (char *str) -{ - char *from, *to; - char t; - - from= str; - to=str; - - while (*from!=0) { - t= *from; - *to= t; - - if(!ton_iswspace(*from)) to++; - from++; - } - *to=0; -} - -static int all_wspace(char *str) -{ - while(*str != 0) { - if (!ton_iswspace(*str)) return 0; - str++; - } - - return 1; -} - -static int all_digits(char *str) -{ - while(*str != 0) { - if (!isdigit(*str)) return 0; - str++; - } - - return 1; -} - -static int dxf_get_layer_col(char *UNUSED(layer)) -{ - return 1; -} - -static int dxf_get_layer_num(Scene *scene, char *layer) -{ - int ret = 0; - - if (all_digits(layer) && atoi(layer)<(1<<20)) ret= atoi(layer); - if (ret == 0) ret = scene->lay; - - return ret; -} - -static void dos_clean(char *str) -{ - while (*str) { - if (*str == 0x0d) { - *str='\n'; - *(++str)= 0; - break; - } - str++; - } -} - -static void myfgets(char *str, int len, FILE *fp) -{ - char c; - - while(len>0 && (c=getc(dxf_fp)) ) { - *str= c; - str++; - len--; - /* three types of enters, \n \r and \r\n */ - if(c == '\n') break; - if(c=='\r') { - c= getc(fp); // read the linefeed from stream - if(c != 10) ungetc(c, fp); // put back, if it's not one... - break; - } - } -} - -static int read_groupf(char *str) -{ - short c; - int ret=-1; - char tmp[256]; - - strcpy(str, " "); - - while ((c=getc(dxf_fp)) && ton_iswspace(c)); - ungetc(c, dxf_fp); - if (c==EOF) return -1; - - myfgets(tmp, 255, dxf_fp); - - dos_clean(tmp); - - if(sscanf(tmp, "%d\n", &ret)!=1) return -2; - - myfgets(tmp, 255, dxf_fp); - - dos_clean(tmp); - - if (!all_wspace(tmp)) { - if (sscanf(tmp, "%s\n", str)!=1) return -2; - } - - clean_wspace(str); - dxf_line+=2; - - return ret; -} - -//XXX error() is now printf until we have a callback error -#define id_test(id) if(id<0) {char errmsg[128];fclose(dxf_fp); if(id==-1) sprintf(errmsg, "Error inputting dxf, near line %d", dxf_line); else if(id==-2) sprintf(errmsg, "Error reading dxf, near line %d", dxf_line);printf("%s", errmsg); return;} - -#define read_group(id,str) {id= read_groupf(str); id_test(id);} - -#define group_is(idtst,str) (id==idtst&&strcmp(val,str)==0) -#define group_isnt(idtst,str) (id!=idtst||strcmp(val,str)!=0) -#define id_check(idtst,str) if(group_isnt(idtst,str)) { fclose(dxf_fp); printf("Error parsing dxf, near line %d", dxf_line); return;} - -static int id; -static char val[256]; - -static short error_exit=0; -static short hasbumped=0; - -static int is_dxf(const char *str) -{ - dxf_line=0; - - dxf_fp= fopen(str, "r"); - if (dxf_fp==NULL) return 0; - - id= read_groupf(val); - if ((id==0 && strcmp(val, "SECTION")==0)||id==999) return 1; - - fclose(dxf_fp); - - return 0; -} - -/* NOTES ON THE READER */ -/* - -- - It turns out that most DXF writers like (LOVE) to - write meshes as a long string of 3DFACE entities. - This means the natural way to read a DXF file - (every entity corresponds to an object) is completely - unusable, reading in 10,000 faces each as an - object just doesn't cut it. Thus the 3DFACE - entry reader holds state, and only finalizes to - an object when a) the layer name changes, b) the - entry type changes, c) we are done reading. - - PS... I decided to do the same thing with LINES, - apparently the same thing happens sometimes as - well. - - PPS... I decided to do the same thing with everything. - Now it is all really nasty and should be rewritten. - -- - - Added circular and elliptical arcs and lwpolylines. - These are all self-contained and have the size known - in advance, and so I haven't used the held state. -- martin -*/ - -static void dxf_add_mat (Object *ob, Mesh *me, float color[3], char *layer) -{ - Material *ma; - - if (!me) return; - - if(ob) { - ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat"); - ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits"); - ob->actcol= 1; - } - - me->totcol= 1; - me->mat= MEM_callocN(sizeof(void *)*1, "me->mat"); - - if (color[0]<0) { - if (strlen(layer)) dxf_col_to_rgb(dxf_get_layer_col(layer), &color[0], &color[1], &color[2]); - color[0]= color[1]= color[2]= 0.8f; - } - - ma= G.main->mat.first; - while(ma) { - if(ma->mtex[0]==NULL) { - if(color[0]==ma->r && color[1]==ma->g && color[2]==ma->b) { - me->mat[0]= ma; - ma->id.us++; - break; - } - } - ma= ma->id.next; - } - if(ma==NULL) { - ma= add_material("ext"); - me->mat[0]= ma; - ma->r= color[0]; - ma->g= color[1]; - ma->b= color[2]; - automatname(ma); - } -} - - /* General DXF vars */ -static float cent[3]={0.0, 0.0, 0.0}; -static char layname[32]=""; -static char entname[32]=""; -static float color[3]={-1.0, -1.0, -1.0}; -static float *vcenter; -static float zerovec[3]= {0.0, 0.0, 0.0}; - -#define reset_vars cent[0]= cent[1]= cent[2]=0.0; strcpy(layname, ""); color[0]= color[1]= color[2]= -1.0 - - -static void dxf_get_mesh(Scene *scene, Mesh** m, Object** o, int noob) -{ - Mesh *me = NULL; - Object *ob; - - if (!noob) { - *o = add_object(scene, OB_MESH); - ob = *o; - - if (entname[0]) new_id(&G.main->object, (ID *)ob, entname); - else if (layname[0]) new_id(&G.main->object, (ID *)ob, layname); - - if (layname[0]) ob->lay= dxf_get_layer_num(scene, layname); - else ob->lay= scene->lay; - // not nice i know... but add_object() sets active base, which needs layer setting too (ton) - scene->basact->lay= ob->lay; - - *m = ob->data; - me= *m; - - vcenter= ob->loc; - } - else { - *o = NULL; - *m = add_mesh("Mesh"); - - me = *m; - ob = *o; - - ((ID *)me)->us=0; - - if (entname[0]) new_id(&G.main->mesh, (ID *)me, entname); - else if (layname[0]) new_id(&G.main->mesh, (ID *)me, layname); - - vcenter = zerovec; - } - me->totvert=0; - me->totface=0; - me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, 0); - me->mface= CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0); -} - -static void dxf_read_point(Scene *scene, int noob) { - /* Blender vars */ - Object *ob; - Mesh *me; - MVert *mvert; - - reset_vars; - - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - cent[0]= (float) atof(val); - } else if (id==20) { - cent[1]= (float) atof(val); - } else if (id==30) { - cent[2]= (float) atof(val); - } else if (id==60) { - /* short invisible= atoi(val); */ - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } - read_group(id, val); - } - - dxf_get_mesh(scene, &me, &ob, noob); - me->totvert= 1; - me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - - dxf_add_mat (ob, me, color, layname); - - mvert= me->mvert; - mvert->co[0]= mvert->co[1]= mvert->co[2]= 0; - - if (ob) VECCOPY(ob->loc, cent); - - hasbumped=1; -} - - /* Line state vars */ -static Object *linehold=NULL; -static Mesh *linemhold=NULL; - -static char oldllay[32]; -static short lwasline=0; /* last was face 3d? */ - -static void dxf_close_line(void) -{ - linemhold=NULL; - if (linehold==NULL) return; - - linehold=NULL; -} - -static void dxf_read_line(Scene *scene, int noob) { - /* Entity specific vars */ - float epoint[3]={0.0, 0.0, 0.0}; - short vspace=0; /* Whether or not coords are relative */ - - /* Blender vars */ - Object *ob; - Mesh *me; - MVert *mvert, *vtmp; - MFace *mface, *ftmp; - - reset_vars; - - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - cent[0]= (float) atof(val); - } else if (id==20) { - cent[1]= (float) atof(val); - } else if (id==30) { - cent[2]= (float) atof(val); - } else if (id==11) { - epoint[0]= (float) atof(val); - } else if (id==21) { - epoint[1]= (float) atof(val); - } else if (id==31) { - epoint[2]= (float) atof(val); - } else if (id==60) { - /* short invisible= atoi(val); */ - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } - read_group(id, val); - } - - /* Check to see if we need to make a new object */ - - if(!lwasline || strcmp(layname, oldllay)!=0) - dxf_close_line(); - if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) - dxf_close_line(); - - if (linemhold==NULL) { - dxf_get_mesh(scene, &me, &ob, noob); - - if(ob) VECCOPY(ob->loc, cent); - - dxf_add_mat (ob, me, color, layname); - - linehold= ob; - linemhold= me; - } else { - ob= linehold; - me= linemhold; - } - - me->totvert+= 2; - me->totface++; - - vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface"); - - if(me->mvert) { - memcpy(vtmp, me->mvert, (me->totvert-2)*sizeof(MVert)); - MEM_freeN(me->mvert); - } - me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp); - vtmp=NULL; - - if(me->mface) { - memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace)); - MEM_freeN(me->mface); - } - me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp); - ftmp=NULL; - - mvert= &me->mvert[(me->totvert-2)]; - - sub_v3_v3v3(mvert->co, cent, vcenter); - mvert++; - if (vspace) { VECCOPY(mvert->co, epoint); - } else sub_v3_v3v3(mvert->co, epoint, vcenter); - - mface= &(((MFace*)me->mface)[me->totface-1]); - mface->v1= me->totvert-2; - mface->v2= me->totvert-1; - mface->mat_nr= 0; - - hasbumped=1; -} - - /* 2D Polyline state vars */ -static Object *p2dhold=NULL; -static Mesh *p2dmhold=NULL; -static char oldplay[32]; -static short lwasp2d=0; - -static void dxf_close_2dpoly(void) -{ - p2dmhold= NULL; - if (p2dhold==NULL) return; - - p2dhold=NULL; -} - -static void dxf_read_ellipse(Scene *scene, int noob) -{ - - /* - * The Parameter option of the ELLIPSE command uses the following equation to define an elliptical arc. - * - * p(u)=c+a*cos(u)+b*sin(u) - * - * The variables a, b, c are determined when you select the endpoints for the - * first axis and the distance for the second axis. a is the negative of 1/2 - * of the major axis length, b is the negative of 1/2 the minor axis length, - * and c is the center point (2-D) of the ellipse. - * - * Because this is actually a vector equation and the variable c is actually - * a point with X and Y values, it really should be written as: - * - * p(u)=(Cx+a*cos(u))*i+(Cy+b*sin(u))*j - * - * where - * - * Cx is the X value of the point c - * Cy is the Y value of the point c - * a is -(1/2 of the major axis length) - * b is -(1/2 of the minor axis length) - * i and j represent unit vectors in the X and Y directions - * - * http://astronomy.swin.edu.au/~pbourke/geomformats/dxf2000/ellipse_command39s_parameter_option_dxf_06.htm - * (reproduced with permission) - * - * NOTE: The start and end angles ('parameters') are in radians, whereas those for the circular arc are - * in degrees. The 'sense' of u appears to be determined by the extrusion direction (see more detailed comment - * in the code) - * - * TODO: The code is specific to ellipses in the x-y plane right now. - * - */ - - /* Entity specific vars */ - float epoint[3]={0.0, 0.0, 0.0}; - float center[3]={0.0, 0.0, 0.0}; - float extrusion[3]={0.0, 0.0, 1.0}; - float axis_endpoint[3] = {0.0, 0.0, 0.0}; /* major axis endpoint */ - short vspace=0; /* Whether or not coords are relative */ - float a, b, x, y, z; - float phid = 0.0f, phi = 0.0f, theta = 0.0f; - float start_angle = 0.0f; - float end_angle = 2*M_PI; - float axis_ratio = 1.0f; - float temp; - int v, tot; - int isArc=0; - /* Blender vars */ - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mface; - - reset_vars; - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - center[0]= (float) atof(val); - } else if (id==20) { - center[1]= (float) atof(val); - } else if (id==30) { - center[2]= (float) atof(val); - } else if (id==11) { - axis_endpoint[0]= (float) atof(val); - } else if (id==21) { - axis_endpoint[1]= (float) atof(val); - } else if (id==31) { - axis_endpoint[2]= (float) atof(val); - } else if (id==40) { - axis_ratio = (float) atof(val); - } else if (id==41) { - printf("dxf: start = %f", atof(val) * 180/M_PI); - start_angle = -atof(val) + M_PI_2; - } else if (id==42) { - printf("dxf: end = %f", atof(val) * 180/M_PI); - end_angle = -atof(val) + M_PI_2; - } else if (id==62) { - int colorid= atoi(val); - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } else if (id==100) { - isArc = 1; - } else if (id==210) { - extrusion[0] = atof(val); - } else if (id==220) { - extrusion[1] = atof(val); - } else if (id==230) { - extrusion[2] = atof(val); - } - read_group(id, val); - } - - if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line(); - if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) - dxf_close_line(); - - /* The 'extrusion direction' seems akin to a face normal, - * insofar as it determines the direction of increasing phi. - * This is again x-y plane specific; it should be fixed at - * some point. */ - - if (extrusion[2] < 0) { - temp = start_angle; - start_angle = M_PI - end_angle; - end_angle = M_PI - temp; - } - - if(end_angle > start_angle) - end_angle -= 2 * M_PI; - - phi = start_angle; - - x = axis_endpoint[0]; - y = axis_endpoint[1]; - z = axis_endpoint[2]; - a = sqrt(x*x + y*y + z*z); - b = a * axis_ratio; - - theta = atan2(y, x); - - x = a * sin(phi); - y = b * cos(phi); - -#ifndef DEBUG_CENTER - epoint[0] = center[0] + x*cos(theta) - y*sin(theta); - epoint[1] = center[1] + x*sin(theta) + y*cos(theta); - epoint[2] = center[2]; - - - cent[0]= epoint[0]; - cent[1]= epoint[1]; - cent[2]= epoint[2]; -#else - cent[0]= center[0]; - cent[1]= center[1]; - cent[2]= center[2]; -#endif - - dxf_get_mesh(scene, &me, &ob, noob); - strcpy(oldllay, layname); - if(ob) VECCOPY(ob->loc, cent); - dxf_add_mat (ob, me, color, layname); - - tot = 32; /* # of line segments to divide the arc into */ - - phid = (end_angle - start_angle)/tot; - - me->totvert += tot+1; - me->totface += tot+1; - - me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface"); - - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - CustomData_set_layer(&me->fdata, CD_MFACE, me->mface); - - printf("vertex and face buffers allocated\n"); - - for(v = 0; v <= tot; v++) { - - x = a * sin(phi); - y = b * cos(phi); - epoint[0] = center[0] + x*cos(theta) - y*sin(theta); - epoint[1] = center[1] + x*sin(theta) + y*cos(theta); - epoint[2] = center[2]; - - mvert= &me->mvert[v]; - - if (vspace) { - VECCOPY(mvert->co, epoint); - } else { - sub_v3_v3v3(mvert->co, epoint, vcenter); - } - - if (v > 0) { - mface= &(((MFace*)me->mface)[v-1]); - mface->v1 = v-1; - mface->v2 = v; - mface->mat_nr = 0; - } - - hasbumped = 1; - - VECCOPY(cent, epoint); - phi+=phid; - } -} - -static void dxf_read_arc(Scene *scene, int noob) -{ - /* Entity specific vars */ - float epoint[3]={0.0, 0.0, 0.0}; - float center[3]={0.0, 0.0, 0.0}; - float extrusion[3]={0.0, 0.0, 1.0}; - short vspace=0; /* Whether or not coords are relative */ - float dia = 0.0f; - float phid = 0.0f, phi = 0.0f; - float start_angle = 0.0f; - float end_angle = 2*M_PI; - float temp; - int v, tot = 32; - int isArc=0; - /* Blender vars */ - Object *ob; - Mesh *me; - MVert *mvert; - MFace *mface; - - reset_vars; - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - center[0]= (float) atof(val); - } else if (id==20) { - center[1]= (float) atof(val); - } else if (id==30) { - center[2]= (float) atof(val); - } else if (id==40) { - dia = (float) atof(val); - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } else if (id==100) { - isArc = 1; - } else if (id==50) { - start_angle = (90 - atoi(val)) * M_PI/180.0; - } else if (id==51) { - end_angle = (90 - atoi(val)) * M_PI/180.0; - } else if (id==210) { - extrusion[0] = atof(val); - } else if (id==220) { - extrusion[1] = atof(val); - } else if (id==230) { - extrusion[2] = atof(val); - } - read_group(id, val); - } - - if(!lwasline || strcmp(layname, oldllay)!=0) dxf_close_line(); - if(linemhold != NULL && linemhold->totvert>MESH_MAX_VERTS) - dxf_close_line(); - - /* Same xy-plane-specific extrusion direction code as in read_ellipse - * (read_arc and read_ellipse should ideally be rewritten to share code) - */ - - if (extrusion[2] < 0) { - temp = start_angle; - start_angle = M_PI - end_angle; - end_angle = M_PI - temp; - } - - phi = start_angle; - if(end_angle > start_angle) - end_angle -= 2 * M_PI; - - cent[0]= center[0]+dia*sin(phi); - cent[1]= center[1]+dia*cos(phi); - cent[2]= center[2]; - - dxf_get_mesh(scene, &me, &ob, noob); - BLI_strncpy(oldllay, layname, sizeof(oldllay)); - if(ob) VECCOPY(ob->loc, cent); - dxf_add_mat (ob, me, color, layname); - - tot = 32; /* # of line segments to divide the arc into */ - phid = (end_angle - start_angle)/tot; /* fix so that arcs have the same 'resolution' as circles? */ - - me->totvert += tot+1; - me->totface += tot+1; - - me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface"); - - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - CustomData_set_layer(&me->fdata, CD_MFACE, me->mface); - - for(v = 0; v <= tot; v++) { - - epoint[0]= center[0]+dia*sin(phi); - epoint[1]= center[1]+dia*cos(phi); - epoint[2]= center[2]; - - mvert= &me->mvert[v]; - - if (vspace) { - VECCOPY(mvert->co, epoint); - } else { - sub_v3_v3v3(mvert->co, epoint, vcenter); - } - - if (v > 0) { - mface= &(((MFace*)me->mface)[v-1]); - mface->v1 = v-1; - mface->v2 = v; - mface->mat_nr = 0; - } - - hasbumped=1; - - VECCOPY(cent, epoint); - phi+=phid; - } -} - -static void dxf_read_polyline(Scene *scene, int noob) { - /* Entity specific vars */ - short vspace=0; /* Whether or not coords are relative */ - int flag=0; - int vflags=0; - int vids[4]; - int nverts; - - /* Blender vars */ - Object *ob; - Mesh *me; - float vert[3] = {0}; - - MVert *mvert, *vtmp; - MFace *mface, *ftmp; - - reset_vars; - - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - cent[0]= (float) atof(val); - } else if (id==20) { - cent[1]= (float) atof(val); - } else if (id==30) { - cent[2]= (float) atof(val); - } else if (id==60) { - /* short invisible= atoi(val); */ - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } else if (id==70) { - flag= atoi(val); - } - read_group(id, val); - } - - if (flag & 9) { // 1= closed curve, 8= 3d curve - if(!lwasp2d || strcmp(layname, oldplay)!=0) dxf_close_2dpoly(); - if(p2dmhold != NULL && p2dmhold->totvert>MESH_MAX_VERTS) - dxf_close_2dpoly(); - - if (p2dmhold==NULL) { - dxf_get_mesh(scene, &me, &ob, noob); - - strcpy(oldplay, layname); - - if(ob) VECCOPY(ob->loc, cent); - - dxf_add_mat (ob, me, color, layname); - - p2dhold= ob; - p2dmhold= me; - } - else { - ob= p2dhold; - me= p2dmhold; - } - - nverts=0; - while (group_is(0, "VERTEX")) { - read_group(id, val); - while(id!=0) { - if (id==10) { - vert[0]= (float) atof(val); - } else if (id==20) { - vert[1]= (float) atof(val); - } else if (id==30) { - vert[2]= (float) atof(val); - } - read_group(id, val); - } - nverts++; - me->totvert++; - - vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - - if (me->mvert) { - memcpy (vtmp, me->mvert, (me->totvert-1)*sizeof(MVert)); - MEM_freeN(me->mvert); - } - me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp); - vtmp= NULL; - - mvert= &me->mvert[me->totvert-1]; - - if (vspace) { VECCOPY(mvert->co, vert); - } else sub_v3_v3v3(mvert->co, vert, vcenter); - } - - /* make edges */ - if(nverts>1) { - int a, oldtotface; - - oldtotface= me->totface; - me->totface+= nverts-1; - - ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface"); - - if(me->mface) { - memcpy(ftmp, me->mface, oldtotface*sizeof(MFace)); - MEM_freeN(me->mface); - } - me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp); - ftmp=NULL; - - mface= me->mface; - mface+= oldtotface; - - for(a=1; a<nverts; a++, mface++) { - mface->v1= (me->totvert-nverts)+a-1; - mface->v2= (me->totvert-nverts)+a; - mface->mat_nr= 0; - } - } - - lwasp2d=1; - } - else if (flag&64) { - dxf_get_mesh(scene, &me, &ob, noob); - - if(ob) VECCOPY(ob->loc, cent); - - dxf_add_mat (ob, me, color, layname); - - while (group_is(0, "VERTEX")) { - vflags= 0; - vids[0]= vids[1]= vids[2]= vids[3]= 0; - - vflags=0; - read_group(id, val); - while(id!=0) { - if(id==8) { - ; /* Layer def, skip */ - } else if (id==10) { - vert[0]= (float) atof(val); - } else if (id==20) { - vert[1]= (float) atof(val); - } else if (id==30) { - vert[2]= (float) atof(val); - } else if (id==70) { - vflags= atoi(val); - } else if (id==71) { - vids[0]= abs(atoi(val)); - } else if (id==72) { - vids[1]= abs(atoi(val)); - } else if (id==73) { - vids[2]= abs(atoi(val)); - } else if (id==74) { - vids[3]= abs(atoi(val)); - } - read_group(id, val); - } - - if (vflags & 128 && vflags & 64) { - me->totvert++; - - /* If we are nearing the limit scan to the next entry */ - if(me->totvert > MESH_MAX_VERTS) - while(group_isnt(0, "SEQEND")) read_group(id, val); - - vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - - if(me->mvert) { - memcpy(vtmp, me->mvert, (me->totvert-1)*sizeof(MVert)); - MEM_freeN(me->mvert); - } - me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp); - vtmp=NULL; - - mvert= &me->mvert[(me->totvert-1)]; - - if (vspace) { VECCOPY(mvert->co, vert); - } else sub_v3_v3v3(mvert->co, vert, vcenter); - - } else if (vflags & 128) { - if(vids[2]==0) { - //XXX error("(PL) Error parsing dxf, not enough vertices near line %d", dxf_line); - - error_exit=1; - fclose(dxf_fp); - return; - } - - me->totface++; - - ftmp= MEM_callocN(me->totface*sizeof(MFace), "mfaces"); - - if(me->mface) { - memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace)); - MEM_freeN(me->mface); - } - me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp); - ftmp=NULL; - - mface= &(((MFace*)me->mface)[me->totface-1]); - mface->v1= vids[0]-1; - mface->v2= vids[1]-1; - mface->v3= vids[2]-1; - - if(vids[3] && vids[3]!=vids[0]) { - mface->v4= vids[3]-1; - test_index_face(mface, NULL, 0, 4); - } - else test_index_face(mface, NULL, 0, 3); - - mface->mat_nr= 0; - - } else { - //XXX error("Error parsing dxf, unknown polyline information near %d", dxf_line); - - error_exit=1; - fclose(dxf_fp); - return; - } - - } - } -} - -static void dxf_read_lwpolyline(Scene *scene, int noob) { - /* Entity specific vars */ - short vspace=0; /* Whether or not coords are relative */ - int flag=0; - int nverts=0; - int v; - - /* Blender vars */ - Object *ob; - Mesh *me; - float vert[3] = {0}; - - MVert *mvert; - MFace *mface; - - reset_vars; - - id = -1; - - /* block structure is - * {...} - * 90 => nverts - * 70 => flags - * nverts.times { 10 => x, 20 => y } - */ - while(id!=70) { - read_group(id, val); - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==38) { - vert[2]= (float) atof(val); - } else if (id==60) { - /* short invisible= atoi(val); */ - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } else if (id==70) { - flag= atoi(val); - } else if (id==90) { - nverts= atoi(val); - } - } - printf("nverts %d\n", nverts); - if (nverts == 0) - return; - - dxf_get_mesh(scene, &me, &ob, noob); - strcpy(oldllay, layname); - if(ob) VECCOPY(ob->loc, cent); - dxf_add_mat (ob, me, color, layname); - - me->totvert += nverts; - me->totface += nverts; - - me->mvert = (MVert*) MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - me->mface = (MFace*) MEM_callocN(me->totface*sizeof(MVert), "mface"); - - CustomData_set_layer(&me->vdata, CD_MVERT, me->mvert); - CustomData_set_layer(&me->fdata, CD_MFACE, me->mface); - - for (v = 0; v < nverts; v++) { - read_group(id,val); - if (id == 10) { - vert[0]= (float) atof(val); - } else { - //XXX error("Error parsing dxf, expected (10, <x>) at line %d", dxf_line); - } - - read_group(id,val); - if (id == 20) { - vert[1]= (float) atof(val); - } else { - //XXX error("Error parsing dxf, expected (20, <y>) at line %d", dxf_line); - } - - mvert = &me->mvert[v]; - - if (vspace) { - VECCOPY(mvert->co, vert); - } else { - sub_v3_v3v3(mvert->co, vert, vcenter); - } - - if (v > 0) { - mface= &(((MFace*)me->mface)[v-1]); - mface->v1 = v-1; - mface->v2 = v; - mface->mat_nr = 0; - } - } - - /* flag & 1 -> closed polyline - * TODO: give the polyline actual 2D faces if it is closed */ - - if (flag&1) { - if(me->mface) { - mface= &(((MFace*)me->mface)[nverts - 1]); - mface->v1 = nverts-1; - mface->v2 = 0; - mface->mat_nr = 0; - } - } -} - - - /* 3D Face state vars */ -static Object *f3dhold=NULL; -static Mesh *f3dmhold=NULL; -static char oldflay[32]; -static short lwasf3d=0; /* last was face 3d? */ - -/* how can this function do anything useful (ton)? */ -static void dxf_close_3dface(void) -{ - f3dmhold= NULL; - if (f3dhold==NULL) return; - - f3dhold=NULL; -} - -static void dxf_read_3dface(Scene *scene, int noob) -{ - /* Entity specific vars */ - float vert2[3]={0.0, 0.0, 0.0}; - float vert3[3]={0.0, 0.0, 0.0}; - float vert4[3]={0.0, 0.0, 0.0}; - short vspace=0; - - int nverts=0; - - /* Blender vars */ - Object *ob; - Mesh *me; - MVert *mvert, *vtmp; - MFace *mface, *ftmp; - - reset_vars; - - read_group(id, val); - while(id!=0) { - if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - - /* First vert/origin */ - } else if (id==10) { - cent[0]= (float) atof(val); - if (nverts<1)nverts++; - } else if (id==20) { - cent[1]= (float) atof(val); - if (nverts<1)nverts++; - } else if (id==30) { - cent[2]= (float) atof(val); - if (nverts<1)nverts++; - - /* Second vert */ - } else if (id==11) { - vert2[0]= (float) atof(val); - if (nverts<2)nverts++; - } else if (id==21) { - vert2[1]= (float) atof(val); - if (nverts<2)nverts++; - } else if (id==31) { - vert2[2]= (float) atof(val); - if (nverts<2)nverts++; - - /* Third vert */ - } else if (id==12) { - vert3[0]= (float) atof(val); - if (nverts<3)nverts++; - } else if (id==22) { - vert3[1]= (float) atof(val); - if (nverts<3)nverts++; - } else if (id==32) { - vert3[2]= (float) atof(val); - if (nverts<3)nverts++; - - /* Fourth vert */ - } else if (id==13) { - vert4[0]= (float) atof(val); - if (nverts<4)nverts++; - } else if (id==23) { - vert4[1]= (float) atof(val); - if (nverts<4)nverts++; - } else if (id==33) { - vert4[2]= (float) atof(val); - if (nverts<4)nverts++; - - /* Other */ - } else if (id==60) { - /* short invisible= atoi(val); */ - } else if (id==62) { - int colorid= atoi(val); - - CLAMP(colorid, 1, 255); - dxf_col_to_rgb(colorid, &color[0], &color[1], &color[2]); - } else if (id==67) { - vspace= atoi(val); - } - read_group(id, val); - } - - /* Check to see if we need to make a new object */ - - if(!lwasf3d || strcmp(layname, oldflay)!=0) dxf_close_3dface(); - if(f3dmhold != NULL && f3dmhold->totvert>MESH_MAX_VERTS) - dxf_close_3dface(); - - if(nverts<3) { - //XXX error("(3DF) Error parsing dxf, not enough vertices near line %d", dxf_line); - - error_exit=1; - fclose(dxf_fp); - return; - } - - if (f3dmhold==NULL) { - dxf_get_mesh(scene, &me, &ob, noob); - - strcpy(oldflay, layname); - - if(ob) VECCOPY(ob->loc, cent); - - dxf_add_mat (ob, me, color, layname); - - f3dhold= ob; - f3dmhold= me; - } else { - ob= f3dhold; - me= f3dmhold; - } - - me->totvert+= nverts; - me->totface++; - - vtmp= MEM_callocN(me->totvert*sizeof(MVert), "mverts"); - ftmp= MEM_callocN(me->totface*sizeof(MFace), "mface"); - - if(me->mvert) { - memcpy(vtmp, me->mvert, (me->totvert-nverts)*sizeof(MVert)); - MEM_freeN(me->mvert); - } - me->mvert= CustomData_set_layer(&me->vdata, CD_MVERT, vtmp); - vtmp=NULL; - - if(me->mface) { - memcpy(ftmp, me->mface, (me->totface-1)*sizeof(MFace)); - MEM_freeN(me->mface); - } - me->mface= CustomData_set_layer(&me->fdata, CD_MFACE, ftmp); - ftmp=NULL; - - mvert= &me->mvert[(me->totvert-nverts)]; - sub_v3_v3v3(mvert->co, cent, vcenter); - - mvert++; - if (vspace) { VECCOPY(mvert->co, vert2); - } else sub_v3_v3v3(mvert->co, vert2, vcenter); - - mvert++; - if (vspace) { VECCOPY(mvert->co, vert3); - } else sub_v3_v3v3(mvert->co, vert3, vcenter); - - if (nverts==4) { - mvert++; - if (vspace) { VECCOPY(mvert->co, vert4); - } else sub_v3_v3v3(mvert->co, vert4, vcenter); - } - - mface= &(((MFace*)me->mface)[me->totface-1]); - mface->v1= (me->totvert-nverts)+0; - mface->v2= (me->totvert-nverts)+1; - mface->v3= (me->totvert-nverts)+2; - - if (nverts==4) - mface->v4= (me->totvert-nverts)+3; - - mface->mat_nr= 0; - - test_index_face(mface, NULL, 0, nverts); - - hasbumped=1; -} - -static void dxf_read(Scene *scene, const char *filename) -{ - Mesh *lastMe = G.main->mesh.last; - - /* clear ugly global variables, that can hang because on error the code - below returns... tsk (ton) */ - dxf_line=0; - dxf_close_3dface(); - dxf_close_2dpoly(); - dxf_close_line(); - - dxf_fp= fopen(filename, "r"); - if (dxf_fp==NULL) return; - - while (1) { - read_group(id, val); - if (group_is(0, "EOF")) break; - - if (id==999) continue; - id_check(0, "SECTION"); - - read_group(id, val); - if (group_is(2, "HEADER")) { - } else if (group_is(2, "TABLES")) { - } else if (group_is(2, "OBJECTS")) { - } else if (group_is(2, "CLASSES")) { - } else if (group_is(2, "BLOCKS")) { - while(1) { - read_group(id, val); - if (group_is(0, "BLOCK")) { - while(group_isnt(0, "ENDBLK")) { - read_group(id, val); - - if(id==2) { - BLI_strncpy(entname, val, sizeof(entname)); - } else if (id==3) { - /* Now the object def should follow */ - if(strlen(entname)==0) { - //XXX error("Error parsing dxf, no mesh name near %d", dxf_line); - fclose(dxf_fp); - return; - } - - /* Now the object def should follow */ - while(group_isnt(0, "ENDBLK")) { - read_group(id, val); - - if(group_is(0, "POLYLINE")) { - dxf_read_polyline(scene, 1); - if(error_exit) return; - lwasf3d=0; - lwasline=0; - - while(group_isnt(0, "SEQEND")) read_group(id, val); - - } else if(group_is(0, "LWPOLYLINE")) { - dxf_read_lwpolyline(scene, 1); - if(error_exit) return; - lwasf3d=0; - lwasline=0; - - while(group_isnt(0, "SEQEND")) read_group(id, val); - } else if(group_is(0, "ATTRIB")) { - while(group_isnt(0, "SEQEND")) read_group(id, val); - lwasf3d=0; - lwasp2d=0; - lwasline=0; - } else if(group_is(0, "POINT")) { - dxf_read_point(scene, 1); - if(error_exit) return; - lwasf3d=0; - lwasp2d=0; - lwasline=0; - } else if(group_is(0, "LINE")) { - dxf_read_line(scene, 1); - if(error_exit) return; - lwasline=1; - lwasp2d=0; - lwasf3d=0; - } else if(group_is(0, "3DFACE")) { - dxf_read_3dface(scene, 1); - if(error_exit) return; - lwasf3d=1; - lwasp2d=0; - lwasline=0; - } else if (group_is(0, "CIRCLE")) { - dxf_read_arc(scene, 1); - } else if (group_is(0, "ELLIPSE")) { - dxf_read_ellipse(scene, 1); - } else if (group_is(0, "ENDBLK")) { - break; - } - } - } else if (group_is(0, "ENDBLK")) { - break; - } - } - while(id!=0) read_group(id, val); - - } else if(group_is(0, "ENDSEC")) { - break; - } - } - } else if (group_is(2, "ENTITIES")) { - while(group_isnt(0, "ENDSEC")) { - char obname[32]=""; - char layname[32]=""; - float cent[3]={0.0, 0.0, 0.0}; - float obsize[3]={1.0, 1.0, 1.0}; - float obrot[3]={0.0, 0.0, 0.0}; - - if(!hasbumped) read_group(id, val); - hasbumped=0; - if (group_is(0, "INSERT")) { - Base *base; - Object *ob; - void *obdata; - - read_group(id, val); - - while(id!=0) { - if(id==2) { - BLI_strncpy(obname, val, sizeof(obname)); - } else if (id==8) { - BLI_strncpy(layname, val, sizeof(layname)); - } else if (id==10) { - cent[0]= (float) atof(val); - } else if (id==20) { - cent[1]= (float) atof(val); - } else if (id==30) { - cent[2]= (float) atof(val); - } else if (id==41) { - obsize[0]= (float) atof(val); - } else if (id==42) { - obsize[1]= (float) atof(val); - } else if (id==43) { - obsize[2]= (float) atof(val); - } else if (id==50) { - obrot[2]= (float) (atof(val)*M_PI/180.0); - } else if (id==60) { - /* short invisible= atoi(val); */ - } - - read_group(id, val); - - } - - if(strlen(obname)==0) { - //XXX error("Error parsing dxf, no object name near %d", dxf_line); - fclose(dxf_fp); - return; - } - - obdata= find_id("ME", obname); - - if (obdata) { - ob= alloc_libblock(&G.main->object, ID_OB, obname); - - ob->type= OB_MESH; - - ob->dt= OB_TEXTURE; - - ob->trackflag= OB_POSY; - ob->upflag= OB_POSZ; - - ob->ipoflag = OB_OFFS_OB+OB_OFFS_PARENT; - - ob->dupon= 1; ob->dupoff= 0; - ob->dupsta= 1; ob->dupend= 100; - ob->recalc= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; /* needed because of weird way of adding libdata directly */ - - ob->data= obdata; - ((ID*)ob->data)->us++; - - VECCOPY(ob->loc, cent); - VECCOPY(ob->size, obsize); - VECCOPY(ob->rot, obrot); - - ob->mat= MEM_callocN(sizeof(void *)*1, "ob->mat"); - ob->matbits= MEM_callocN(sizeof(char)*1, "ob->matbits"); - ob->totcol= (unsigned char) ((Mesh*)ob->data)->totcol; - ob->actcol= 1; - - /* note: materials are either linked to mesh or object, if both then - you have to increase user counts. below line is not needed. - I leave it commented out here as warning (ton) */ - //for (i=0; i<ob->totcol; i++) ob->mat[i]= ((Mesh*)ob->data)->mat[i]; - - if (layname[0]) ob->lay= dxf_get_layer_num(scene, layname); - else ob->lay= scene->lay; - - /* link to scene */ - base= MEM_callocN( sizeof(Base), "add_base"); - BLI_addhead(&scene->base, base); - - base->lay= ob->lay; - - base->object= ob; - } - - hasbumped=1; - - lwasf3d=0; - lwasp2d=0; - lwasline=0; - } else if(group_is(0, "POLYLINE")) { - dxf_read_polyline(scene, 0); - if(error_exit) return; - lwasf3d=0; - lwasline=0; - - while(group_isnt(0, "SEQEND")) read_group(id, val); - - } else if(group_is(0, "LWPOLYLINE")) { - dxf_read_lwpolyline(scene, 0); - if(error_exit) return; - lwasf3d=0; - lwasline=0; - //while(group_isnt(0, "SEQEND")) read_group(id, val); - - } else if(group_is(0, "ATTRIB")) { - while(group_isnt(0, "SEQEND")) read_group(id, val); - lwasf3d=0; - lwasp2d=0; - lwasline=0; - } else if(group_is(0, "POINT")) { - dxf_read_point(scene, 0); - if(error_exit) return; - lwasf3d=0; - lwasp2d=0; - lwasline=0; - } else if(group_is(0, "LINE")) { - dxf_read_line(scene, 0); - if(error_exit) return; - lwasline=1; - lwasp2d=0; - lwasf3d=0; - } else if(group_is(0, "3DFACE")) { - dxf_read_3dface(scene, 0); - if(error_exit) return; - lwasline=0; - lwasp2d=0; - lwasf3d=1; - } else if (group_is(0, "CIRCLE") || group_is(0, "ARC")) { - dxf_read_arc(scene, 0); - } else if (group_is(0, "ELLIPSE")) { - dxf_read_ellipse(scene, 0); - } else if(group_is(0, "ENDSEC")) { - break; - } - } - } - - while(group_isnt(0, "ENDSEC")) read_group(id, val); - } - id_check(0, "EOF"); - - fclose (dxf_fp); - - /* Close any remaining state held stuff */ - dxf_close_3dface(); - dxf_close_2dpoly(); - dxf_close_line(); - - if (lastMe) { - lastMe = lastMe->id.next; - } else { - lastMe = G.main->mesh.first; - } - for (; lastMe; lastMe=lastMe->id.next) { - mesh_add_normals_flags(lastMe); - make_edges(lastMe, 0); - } -} diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index f8003c656bf..1931946f0cf 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -67,69 +67,61 @@ static ListBase ttfdata= {NULL, NULL}; /* UTF-8 <-> wchar transformations */ -void -chtoutf8(unsigned long c, char *o) +size_t chtoutf8(const unsigned long c, char o[4]) { // Variables and initialization -/* memset(o, 0, 16); */ +/* memset(o, 0, 4); */ // Create the utf-8 string - if (c < 0x80) - { + if (c < 0x80) { o[0] = (char) c; + return 1; } - else if (c < 0x800) - { + else if (c < 0x800) { o[0] = (0xC0 | (c>>6)); o[1] = (0x80 | (c & 0x3f)); + return 2; } - else if (c < 0x10000) - { + else if (c < 0x10000) { o[0] = (0xe0 | (c >> 12)); o[1] = (0x80 | (c >>6 & 0x3f)); o[2] = (0x80 | (c & 0x3f)); + return 3; } - else if (c < 0x200000) - { - o[0] = (0xf0 | (c>>18)); - o[1] = (0x80 | (c >>12 & 0x3f)); - o[2] = (0x80 | (c >> 6 & 0x3f)); - o[3] = (0x80 | (c & 0x3f)); + else if (c < 0x200000) { + o[0] = (0xf0 | (c>>18)); + o[1] = (0x80 | (c >>12 & 0x3f)); + o[2] = (0x80 | (c >> 6 & 0x3f)); + o[3] = (0x80 | (c & 0x3f)); + return 4; } + + /* should we assert here? */ + return 0; } -void -wcs2utf8s(char *dst, wchar_t *src) +void wcs2utf8s(char *dst, const wchar_t *src) { - /* NULL terminator not needed */ - char ch[4]; - - while(*src) - { - memset(ch, 0, sizeof(ch)); - chtoutf8(*src++, ch); - dst= strncat(dst, ch, sizeof(ch)); + while(*src) { + dst += chtoutf8(*src++, dst); } + + *dst= '\0'; } -int -wcsleninu8(wchar_t *src) +size_t wcsleninu8(wchar_t *src) { - char ch[16]; - int len = 0; + char ch_dummy[4]; + size_t len = 0; - while(*src) - { - memset(ch, 0, 16); - chtoutf8(*src++, ch); - len = len + strlen(ch); + while(*src) { + len += chtoutf8(*src++, ch_dummy); } return len; } -static int -utf8slen(const char *strc) +static size_t utf8slen(const char *strc) { int len=0; @@ -172,7 +164,7 @@ only a single input character is consumed. */ -int utf8towchar(wchar_t *w, char *c) +size_t utf8towchar(wchar_t *w, const char *c) { int len=0; @@ -394,7 +386,7 @@ VFont *load_vfont(const char *name) vfont->data = vfd; /* if there's a font name, use it for the ID name */ - if (strcmp(vfd->name, "")!=0) { + if (vfd->name[0] != '\0') { BLI_strncpy(vfont->id.name+2, vfd->name, sizeof(vfont->id.name)-2); } BLI_strncpy(vfont->name, name, sizeof(vfont->name)); diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c index 67be3e71101..04fc41e41cc 100644 --- a/source/blender/blenkernel/intern/idprop.c +++ b/source/blender/blenkernel/intern/idprop.c @@ -78,9 +78,12 @@ IDProperty *IDP_NewIDPArray(const char *name) IDProperty *IDP_CopyIDPArray(IDProperty *array) { - IDProperty *narray = MEM_dupallocN(array), *tmp; + /* dont use MEM_dupallocN because this may be part of an array */ + IDProperty *narray = MEM_mallocN(sizeof(IDProperty), "IDP_CopyIDPArray"), *tmp; int i; - + + *narray= *array; + narray->data.pointer = MEM_dupallocN(array->data.pointer); for (i=0; i<narray->len; i++) { /*ok, the copy functions always allocate a new structure, @@ -423,35 +426,30 @@ static IDProperty *IDP_CopyGroup(IDProperty *prop) * When values name and types match, copy the values, else ignore */ void IDP_SyncGroupValues(IDProperty *dest, IDProperty *src) { - IDProperty *loop, *prop; + IDProperty *other, *prop; for (prop=src->data.group.first; prop; prop=prop->next) { - for (loop=dest->data.group.first; loop; loop=loop->next) { - if (strcmp(loop->name, prop->name)==0) { - if(prop->type==loop->type) { - - switch (prop->type) { - case IDP_INT: - case IDP_FLOAT: - case IDP_DOUBLE: - loop->data= prop->data; - break; - case IDP_GROUP: - IDP_SyncGroupValues(loop, prop); - break; - default: - { - IDProperty *tmp= loop; - IDProperty *copy= IDP_CopyProperty(prop); - - BLI_insertlinkafter(&dest->data.group, loop, copy); - BLI_remlink(&dest->data.group, tmp); - - IDP_FreeProperty(tmp); - MEM_freeN(tmp); - } - } + other= BLI_findstring(&dest->data.group, prop->name, offsetof(IDProperty, name)); + if (other && prop->type==other->type) { + switch (prop->type) { + case IDP_INT: + case IDP_FLOAT: + case IDP_DOUBLE: + other->data= prop->data; + break; + case IDP_GROUP: + IDP_SyncGroupValues(other, prop); + break; + default: + { + IDProperty *tmp= other; + IDProperty *copy= IDP_CopyProperty(prop); + + BLI_insertlinkafter(&dest->data.group, other, copy); + BLI_remlink(&dest->data.group, tmp); + + IDP_FreeProperty(tmp); + MEM_freeN(tmp); } - break; } } } diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c44634fed34..22d19c5484f 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -675,8 +675,10 @@ void BKE_image_all_free_anim_ibufs(int cfra) int BKE_imtype_to_ftype(int imtype) { - if(imtype==0) + if(imtype==R_TARGA) return TGA; + else if(imtype==R_RAWTGA) + return RAWTGA; else if(imtype== R_IRIS) return IMAGIC; #ifdef WITH_HDR @@ -703,10 +705,6 @@ int BKE_imtype_to_ftype(int imtype) else if (imtype==R_DPX) return DPX; #endif - else if (imtype==R_TARGA) - return TGA; - else if(imtype==R_RAWTGA) - return RAWTGA; #ifdef WITH_OPENJPEG else if(imtype==R_JP2) return JP2; @@ -880,7 +878,7 @@ typedef struct StampData { char rendertime[64]; } StampData; -static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) +static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int do_prefix) { char text[256]; struct tm *tl; @@ -959,14 +957,14 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } if (scene->r.stamp & R_STAMP_CAMERA) { - BLI_snprintf(stamp_data->camera, sizeof(stamp_data->camera), do_prefix ? "Camera %s":"%s", scene->camera ? scene->camera->id.name+2 : "<none>"); + BLI_snprintf(stamp_data->camera, sizeof(stamp_data->camera), do_prefix ? "Camera %s":"%s", camera ? camera->id.name+2 : "<none>"); } else { stamp_data->camera[0] = '\0'; } if (scene->r.stamp & R_STAMP_CAMERALENS) { - if (scene->camera && scene->camera->type == OB_CAMERA) { - BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)scene->camera->data)->lens); + if (camera && camera->type == OB_CAMERA) { + BLI_snprintf(text, sizeof(text), "%.2f", ((Camera *)camera->data)->lens); } else strcpy(text, "<none>"); @@ -1006,18 +1004,21 @@ static void stampdata(Scene *scene, StampData *stamp_data, int do_prefix) } } -void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, int height, int channels) +void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rectf, int width, int height, int channels) { struct StampData stamp_data; float w, h, pad; - int x, y; + int x, y, y_ofs; float h_fixed; const int mono= blf_mono_font_render; // XXX - + +#define BUFF_MARGIN_X 2 +#define BUFF_MARGIN_Y 1 + if (!rect && !rectf) return; - stampdata(scene, &stamp_data, 1); + stampdata(scene, camera, &stamp_data, 1); /* TODO, do_versions */ if(scene->r.stamp_font_id < 8) @@ -1028,15 +1029,11 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_buffer(mono, rectf, rect, width, height, channels); BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0); - pad= BLF_width(mono, "--"); + pad= BLF_width_max(mono); /* use 'h_fixed' rather then 'h', aligns better */ - // BLF_width_and_height(mono, "^|/_AgPpJjlYy", &w, &h_fixed); - { - rctf box; - BLF_boundbox(mono, "^|/_AgPpJjlYy", &box); - h_fixed= box.ymax - box.ymin; - } + h_fixed= BLF_height_max(mono); + y_ofs = -BLF_descender(mono); x= 0; y= height; @@ -1047,14 +1044,14 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i y -= h; /* also a little of space to the background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, w+3, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); /* and draw the text. */ - BLF_position(mono, x, y, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.file); /* the extra pixel for background. */ - y -= 4; + y -= BUFF_MARGIN_Y * 2; } /* Top left corner, below File */ @@ -1063,13 +1060,13 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); - BLF_position(mono, x, y+1, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.note); /* the extra pixel for background. */ - y -= 4; + y -= BUFF_MARGIN_Y * 2; } /* Top left corner, below File (or Note) */ @@ -1078,13 +1075,13 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); - BLF_position(mono, x, y, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.date); /* the extra pixel for background. */ - y -= 4; + y -= BUFF_MARGIN_Y * 2; } /* Top left corner, below File, Date or Note */ @@ -1093,9 +1090,9 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i y -= h; /* and space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-3, w+3, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, 0, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); - BLF_position(mono, x, y, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.rendertime); } @@ -1107,10 +1104,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_width_and_height(mono, stamp_data.marker, &w, &h); h= h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, w+2, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); /* and pad the text. */ - BLF_position(mono, x, y+3, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.marker); /* space width. */ @@ -1122,10 +1119,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_width_and_height(mono, stamp_data.time, &w, &h); h= h_fixed; /* extra space for background */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); /* and pad the text. */ - BLF_position(mono, x, y+3, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.time); /* space width. */ @@ -1136,10 +1133,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_width_and_height(mono, stamp_data.frame, &w, &h); h= h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); /* and pad the text. */ - BLF_position(mono, x, y+3, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.frame); /* space width. */ @@ -1150,8 +1147,8 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_width_and_height(mono, stamp_data.camera, &w, &h); h= h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2); - BLF_position(mono, x, y+3, 0.0); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.camera); /* space width. */ @@ -1162,8 +1159,8 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i BLF_width_and_height(mono, stamp_data.cameralens, &w, &h); h= h_fixed; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+2, y+h+2); - BLF_position(mono, x, y+3, 0.0); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.cameralens); } @@ -1174,10 +1171,10 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i x= width - w - 2; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y, x+w+3, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); /* and pad the text. */ - BLF_position(mono, x, y+3, 0.0); + BLF_position(mono, x, y+y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.scene); } @@ -1189,24 +1186,27 @@ void BKE_stamp_buf(Scene *scene, unsigned char *rect, float *rectf, int width, i y= height - h; /* extra space for background. */ - buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x, y-3, x+w+pad, y+h+2); + buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, x-BUFF_MARGIN_X, y-BUFF_MARGIN_Y, x+w+BUFF_MARGIN_X, y+h+BUFF_MARGIN_Y); - BLF_position(mono, x, y, 0.0); + BLF_position(mono, x, y + y_ofs, 0.0); BLF_draw_buffer(mono, stamp_data.strip); } /* cleanup the buffer. */ BLF_buffer(mono, NULL, NULL, 0, 0, 0); + +#undef BUFF_MARGIN_X +#undef BUFF_MARGIN_Y } -void BKE_stamp_info(Scene *scene, struct ImBuf *ibuf) +void BKE_stamp_info(Scene *scene, Object *camera, struct ImBuf *ibuf) { struct StampData stamp_data; if (!ibuf) return; /* fill all the data values, no prefix */ - stampdata(scene, &stamp_data, 0); + stampdata(scene, camera, &stamp_data, 0); if (stamp_data.file[0]) IMB_metadata_change_field (ibuf, "File", stamp_data.file); if (stamp_data.note[0]) IMB_metadata_change_field (ibuf, "Note", stamp_data.note); @@ -1244,7 +1244,7 @@ int BKE_alphatest_ibuf(ImBuf *ibuf) return FALSE; } -int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality) +int BKE_write_ibuf(ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality) { int ok; (void)subimtype; /* quies unused warnings */ @@ -1339,9 +1339,6 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int } BLI_make_existing_file(name); - - if(scene && scene->r.stamp & R_STAMP_ALL) - BKE_stamp_info(scene, ibuf); ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat); if (ok == 0) { @@ -1351,6 +1348,14 @@ int BKE_write_ibuf(Scene *scene, ImBuf *ibuf, const char *name, int imtype, int return(ok); } +int BKE_write_ibuf_stamp(Scene *scene, struct Object *camera, ImBuf *ibuf, const char *name, int imtype, int subimtype, int quality) +{ + if(scene && scene->r.stamp & R_STAMP_ALL) + BKE_stamp_info(scene, camera, ibuf); + + return BKE_write_ibuf(ibuf, name, imtype, subimtype, quality); +} + void BKE_makepicstring(char *string, const char *base, int frame, int imtype, const short use_ext, const short use_frames) { @@ -1660,8 +1665,15 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame) /* read ibuf */ ibuf = IMB_loadiffname(name, flag); - if(G.f & G_DEBUG) printf("loaded %s\n", name); - + +#if 0 + if(ibuf) { + printf(AT" loaded %s\n", name); + } else { + printf(AT" missed %s\n", name); + } +#endif + if (ibuf) { #ifdef WITH_OPENEXR /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */ @@ -2217,21 +2229,19 @@ void BKE_image_release_ibuf(Image *ima, void *lock) /* warning, this can allocate generated images */ ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser) { + /* here (+fie_ima/2-1) makes sure that division happens correctly */ return BKE_image_acquire_ibuf(ima, iuser, NULL); } -void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) +int BKE_image_user_get_frame(const ImageUser *iuser, int cfra, int fieldnr) { - int len; - - /* here (+fie_ima/2-1) makes sure that division happens correctly */ - len= (iuser->fie_ima*iuser->frames)/2; - + const int len= (iuser->fie_ima*iuser->frames)/2; + if(len==0) { - iuser->framenr= 0; + return 0; } else { - int imanr; + int framenr; cfra= cfra - iuser->sfra+1; /* cyclic */ @@ -2240,31 +2250,38 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) if(cfra < 0) cfra+= len; if(cfra==0) cfra= len; } - + if(cfra<0) cfra= 0; else if(cfra>len) cfra= len; - + /* convert current frame to current field */ cfra= 2*(cfra); if(fieldnr) cfra++; - + /* transform to images space */ - imanr= (cfra+iuser->fie_ima-2)/iuser->fie_ima; - if(imanr>iuser->frames) imanr= iuser->frames; - imanr+= iuser->offset; - + framenr= (cfra+iuser->fie_ima-2)/iuser->fie_ima; + if(framenr>iuser->frames) framenr= iuser->frames; + framenr+= iuser->offset; + if(iuser->cycl) { - imanr= ( (imanr) % len ); - while(imanr < 0) imanr+= len; - if(imanr==0) imanr= len; + framenr= ( (framenr) % len ); + while(framenr < 0) framenr+= len; + if(framenr==0) framenr= len; } - - /* allows image users to handle redraws */ - if(iuser->flag & IMA_ANIM_ALWAYS) - if(imanr!=iuser->framenr) - iuser->flag |= IMA_ANIM_REFRESHED; - - iuser->framenr= imanr; - if(iuser->ok==0) iuser->ok= 1; + + return framenr; } } + +void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) +{ + const int framenr= BKE_image_user_get_frame(iuser, cfra, fieldnr); + + /* allows image users to handle redraws */ + if(iuser->flag & IMA_ANIM_ALWAYS) + if(framenr!=iuser->framenr) + iuser->flag |= IMA_ANIM_REFRESHED; + + iuser->framenr= framenr; + if(iuser->ok==0) iuser->ok= 1; +} diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c index 8f6408f1939..5b237665290 100644 --- a/source/blender/blenkernel/intern/image_gen.c +++ b/source/blender/blenkernel/intern/image_gen.c @@ -80,10 +80,10 @@ void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int widt int checkerwidth= 32, dark= 1; int x, y; - + unsigned char *rect_orig= rect; float *rect_float_orig= rect_float; - + float h=0.0, hoffs=0.0, hue=0.0, s=0.9, v=0.9, r, g, b; @@ -191,7 +191,7 @@ static void checker_board_color_fill(unsigned char *rect, float *rect_float, int for(y= 0; y < height; y++) { - + val= 0.1 + (y * (0.4 / height)); /* use a number lower then 1.0 else its too bright */ for(x= 0; x < width; x++) { @@ -316,17 +316,17 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width BLF_size(mono, 54, 72); /* hard coded size! */ BLF_buffer(mono, rect_float, rect, width, height, 4); - + for(y= 0; y < height; y+=step) { text[1]= '1'; - + for(x= 0; x < width; x+=step) { /* hard coded offset */ pen_x = x + 33; pen_y = y + 44; - + /* terribly crappy outline font! */ BLF_buffer_col(mono, 1.0, 1.0, 1.0, 1.0); @@ -338,7 +338,7 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width BLF_draw_buffer(mono, text); BLF_position(mono, pen_x, pen_y+outline, 0.0); BLF_draw_buffer(mono, text); - + BLF_position(mono, pen_x-outline, pen_y-outline, 0.0); BLF_draw_buffer(mono, text); BLF_position(mono, pen_x+outline, pen_y+outline, 0.0); @@ -351,12 +351,12 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width BLF_buffer_col(mono, 0.0, 0.0, 0.0, 1.0); BLF_position(mono, pen_x, pen_y, 0.0); BLF_draw_buffer(mono, text); - + text[1]++; } text[0]++; } - + /* cleanup the buffer. */ BLF_buffer(mono, NULL, NULL, 0, 0, 0); } diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index 7f0292b2f22..099661f7914 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -50,7 +50,7 @@ #include "BKE_global.h" -#define CLOTH_OPENMP_LIMIT 25 +#define CLOTH_OPENMP_LIMIT 512 #ifdef _WIN32 #include <windows.h> @@ -939,7 +939,7 @@ static int cg_filtered(lfVector *ldV, fmatrix3x3 *lA, lfVector *lB, lfVector *z s = dot_lfvector(r, r, numverts); starget = s * sqrt(conjgrad_epsilon); - while((s>starget && conjgrad_loopcount < conjgrad_looplimit)) + while(s>starget && conjgrad_loopcount < conjgrad_looplimit) { // Mul(q,A,d); // q = A*d; mul_bfmatrix_lfvector(q, lA, d); @@ -1749,15 +1749,93 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect del_lfvector(dFdXmV); } +/*computes where the cloth would be if it were subject to perfectly stiff edges + (edge distance constraints) in a lagrangian solver. then add forces to help + guide the implicit solver to that state. this function is called after + collisions*/ +int cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt) +{ + Cloth *cloth= clmd->clothObject; + float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces"); + float *masses = MEM_callocN(sizeof(float)*cloth->numverts, "cos cloth_calc_helper_forces"); + LinkNode *node; + ClothSpring *spring; + ClothVertex *cv; + int i, steps; + + cv = cloth->verts; + for (i=0; i<cloth->numverts; i++, cv++) { + copy_v3_v3(cos[i], cv->tx); + + if (cv->goal == 1.0f || len_v3v3(initial_cos[i], cv->tx) != 0.0) { + masses[i] = 1e+10; + } else { + masses[i] = cv->mass; + } + } + + steps = 55; + for (i=0; i<steps; i++) { + for (node=cloth->springs; node; node=node->next) { + ClothVertex *cv1, *cv2; + int v1, v2; + float len, c, l, vec[3]; + + spring = node->link; + if (spring->type != CLOTH_SPRING_TYPE_STRUCTURAL && spring->type != CLOTH_SPRING_TYPE_SHEAR) + continue; + + v1 = spring->ij; v2 = spring->kl; + cv1 = cloth->verts + v1; + cv2 = cloth->verts + v2; + len = len_v3v3(cos[v1], cos[v2]); + + sub_v3_v3v3(vec, cos[v1], cos[v2]); + normalize_v3(vec); + + c = (len - spring->restlen); + if (c == 0.0) + continue; + + l = c / ((1.0/masses[v1]) + (1.0/masses[v2])); + + mul_v3_fl(vec, -(1.0/masses[v1])*l); + add_v3_v3(cos[v1], vec); + + sub_v3_v3v3(vec, cos[v2], cos[v1]); + normalize_v3(vec); + + mul_v3_fl(vec, -(1.0/masses[v2])*l); + add_v3_v3(cos[v2], vec); + } + } + + cv = cloth->verts; + for (i=0; i<cloth->numverts; i++, cv++) { + float vec[3]; + + /*compute forces*/ + sub_v3_v3v3(vec, cos[i], cv->tx); + mul_v3_fl(vec, cv->mass*dt*20.0); + add_v3_v3(cv->tv, vec); + //copy_v3_v3(cv->tx, cos[i]); + } + + MEM_freeN(cos); + MEM_freeN(masses); + + return 1; +} int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase *effectors) { unsigned int i=0; float step=0.0f, tf=clmd->sim_parms->timescale; Cloth *cloth = clmd->clothObject; - ClothVertex *verts = cloth->verts; + ClothVertex *verts = cloth->verts, *cv; unsigned int numverts = cloth->numverts; float dt = clmd->sim_parms->timescale / clmd->sim_parms->stepsPerFrame; float spf = (float)clmd->sim_parms->stepsPerFrame / clmd->sim_parms->timescale; + float (*initial_cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "initial_cos implicit.c"); Implicit_Data *id = cloth->implicit; int do_extra_solve; @@ -1817,15 +1895,26 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase VECCOPY(verts[i].v, verts[i].tv); } + for (i=0, cv=cloth->verts; i<cloth->numverts; i++, cv++) { + copy_v3_v3(initial_cos[i], cv->tx); + } + // call collision function // TODO: check if "step" or "step+dt" is correct - dg do_extra_solve = cloth_bvh_objcollision(ob, clmd, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale); - + // copy corrected positions back to simulation for(i = 0; i < numverts; i++) { // correct velocity again, just to be sure we had to change it due to adaptive collisions VECSUB(verts[i].tv, verts[i].tx, id->X[i]); + } + + //if (do_extra_solve) + // cloth_calc_helper_forces(ob, clmd, initial_cos, step/clmd->sim_parms->timescale, dt/clmd->sim_parms->timescale); + + for(i = 0; i < numverts; i++) + { if(do_extra_solve) { @@ -1886,6 +1975,8 @@ int implicit_solver (Object *ob, float frame, ClothModifierData *clmd, ListBase } } + MEM_freeN(initial_cos); + return 1; } diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 08e0ad4f3ff..4f921f005f4 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -1372,7 +1372,7 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve * * This does not assume that any ID or AnimData uses it, but does assume that * it is given two lists, which it will perform driver/animation-data separation. */ -static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence * seq, ListBase *animgroups, ListBase *anim, ListBase *drivers) +static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], Sequence *seq, ListBase *animgroups, ListBase *anim, ListBase *drivers) { IpoCurve *icu; @@ -1416,8 +1416,7 @@ static void ipo_to_animato (ID *id, Ipo *ipo, char actname[], char constname[], /* if this IPO block doesn't have any users after this one, free... */ ipo->id.us--; - if ( (ipo->id.us == 0) || ((ipo->id.us == 1) && (ipo->id.flag & LIB_FAKEUSER)) ) - { + if (ID_REAL_USERS(ipo) <= 0) { IpoCurve *icn; for (icu= ipo->curve.first; icu; icu= icn) { @@ -1668,7 +1667,6 @@ void do_versions_ipos_to_animato(Main *main) { ListBase drivers = {NULL, NULL}; ID *id; - AnimData *adt; if (main == NULL) { printf("Argh! Main is NULL in do_versions_ipos_to_animato() \n"); @@ -1697,7 +1695,7 @@ void do_versions_ipos_to_animato(Main *main) /* check if object has any animation data */ if (ob->nlastrips.first) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + BKE_id_add_animdata(id); /* IPO first to take into any non-NLA'd Object Animation */ if (ob->ipo) { @@ -1720,7 +1718,7 @@ void do_versions_ipos_to_animato(Main *main) } else if ((ob->ipo) || (ob->action)) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Action first - so that Action name get conserved */ if (ob->action) { @@ -1804,6 +1802,13 @@ void do_versions_ipos_to_animato(Main *main) BLI_freelinkN(&ob->constraintChannels, conchan); } } + + /* object's action will always be object-rooted */ + { + AnimData *adt= BKE_animdata_from_id(id); + if (adt && adt->action) + adt->action->idroot = ID_OB; + } } /* shapekeys */ @@ -1818,10 +1823,14 @@ void do_versions_ipos_to_animato(Main *main) */ if (key->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Shapekey data... */ ipo_to_animdata(id, key->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = key->ipo->blocktype; + key->ipo->id.us--; key->ipo= NULL; } @@ -1836,10 +1845,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (ma->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Material data... */ ipo_to_animdata(id, ma->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = ma->ipo->blocktype; + ma->ipo->id.us--; ma->ipo= NULL; } @@ -1854,10 +1867,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (wo->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert World data... */ ipo_to_animdata(id, wo->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = wo->ipo->blocktype; + wo->ipo->id.us--; wo->ipo= NULL; } @@ -1870,7 +1887,7 @@ void do_versions_ipos_to_animato(Main *main) if (ed && ed->seqbasep) { Sequence * seq; - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); SEQ_BEGIN(ed, seq) { IpoCurve *icu = (seq->ipo) ? seq->ipo->curve.first : NULL; @@ -1904,6 +1921,10 @@ void do_versions_ipos_to_animato(Main *main) /* convert IPO */ ipo_to_animdata((ID *)scene, seq->ipo, NULL, NULL, seq); + + if (adt->action) + adt->action->idroot = ID_SCE; /* scene-rooted */ + seq->ipo->id.us--; seq->ipo = NULL; } @@ -1921,10 +1942,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (te->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Texture data... */ ipo_to_animdata(id, te->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = te->ipo->blocktype; + te->ipo->id.us--; te->ipo= NULL; } @@ -1939,10 +1964,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (ca->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Camera data... */ ipo_to_animdata(id, ca->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = ca->ipo->blocktype; + ca->ipo->id.us--; ca->ipo= NULL; } @@ -1957,10 +1986,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (la->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Lamp data... */ ipo_to_animdata(id, la->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = la->ipo->blocktype; + la->ipo->id.us--; la->ipo= NULL; } @@ -1975,10 +2008,14 @@ void do_versions_ipos_to_animato(Main *main) /* we're only interested in the IPO */ if (cu->ipo) { /* Add AnimData block */ - adt= BKE_id_add_animdata(id); + AnimData *adt= BKE_id_add_animdata(id); /* Convert Curve data... */ ipo_to_animdata(id, cu->ipo, NULL, NULL, NULL); + + if (adt->action) + adt->action->idroot = cu->ipo->blocktype; + cu->ipo->id.us--; cu->ipo= NULL; } @@ -2001,6 +2038,10 @@ void do_versions_ipos_to_animato(Main *main) if (G.f & G_DEBUG) printf("\tconverting action %s \n", id->name+2); + /* if old action, it will be object-only... */ + if (act->chanbase.first) + act->idroot = ID_OB; + /* be careful! some of the actions we encounter will be converted ones... */ action_to_animato(NULL, act, &act->groups, &act->curves, &drivers); } @@ -2018,6 +2059,7 @@ void do_versions_ipos_to_animato(Main *main) /* add a new action for this, and convert all data into that action */ new_act= add_empty_action("ConvIPO_Action"); // XXX need a better name... ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); + new_act->idroot = ipo->blocktype; } /* clear fake-users, and set user-count to zero to make sure it is cleared on file-save */ diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index a32ae68efdd..fece1b8fb02 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -220,7 +220,9 @@ Lattice *copy_lattice(Lattice *lt) ltn->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); copy_dverts(ltn->dvert, lt->dvert, tot); } - + + ltn->editlatt= NULL; + return ltn; } @@ -248,8 +250,8 @@ void free_lattice(Lattice *lt) void make_local_lattice(Lattice *lt) { + Main *bmain= G.main; Object *ob; - Lattice *ltn; int local=0, lib=0; /* - only lib users: do nothing @@ -261,39 +263,34 @@ void make_local_lattice(Lattice *lt) if(lt->id.us==1) { lt->id.lib= NULL; lt->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)lt, NULL); + new_id(&bmain->latt, (ID *)lt, NULL); return; } - ob= G.main->object.first; - while(ob) { + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { if(ob->data==lt) { if(ob->id.lib) lib= 1; else local= 1; } - ob= ob->id.next; } if(local && lib==0) { lt->id.lib= NULL; lt->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)lt, NULL); + new_id(&bmain->latt, (ID *)lt, NULL); } else if(local && lib) { - ltn= copy_lattice(lt); + Lattice *ltn= copy_lattice(lt); ltn->id.us= 0; - - ob= G.main->object.first; - while(ob) { + + for(ob= bmain->object.first; ob; ob= ob->id.next) { if(ob->data==lt) { - if(ob->id.lib==NULL) { ob->data= ltn; ltn->id.us++; lt->id.us--; } } - ob= ob->id.next; } } } diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index e3b0a342b3a..ad853915470 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -1157,7 +1157,7 @@ static int check_for_dupid(ListBase *lb, ID *id, char *name) int new_id(ListBase *lb, ID *id, const char *tname) { int result; - char name[22]; + char name[MAX_ID_NAME-2]; /* if library, don't rename */ if(id->lib) return 0; @@ -1381,7 +1381,7 @@ void text_idbutton(struct ID *id, char *text) if(id) { if(GS(id->name)==ID_SCE) strcpy(text, "SCE: "); - else if(GS(id->name)==ID_SCE) + else if(GS(id->name)==ID_SCR) strcpy(text, "SCR: "); else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes) strcpy(text, "NT: "); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index fa7709e3b33..fd58dc2dfc0 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -267,6 +267,14 @@ Material *localize_material(Material *ma) return man; } +static void extern_local_material(Material *ma) +{ + int i; + for(i=0; i < MAX_MTEX; i++) { + if(ma->mtex[i]) id_lib_extern((ID *)ma->mtex[i]->tex); + } +} + void make_local_material(Material *ma) { Main *bmain= G.main; @@ -286,11 +294,9 @@ void make_local_material(Material *ma) if(ma->id.us==1) { ma->id.lib= NULL; ma->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ma, NULL); - for(a=0; a<MAX_MTEX; a++) { - if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex); - } - + + new_id(&bmain->mat, (ID *)ma, NULL); + extern_local_material(ma); return; } @@ -350,12 +356,9 @@ void make_local_material(Material *ma) if(local && lib==0) { ma->id.lib= NULL; ma->id.flag= LIB_LOCAL; - - for(a=0; a<MAX_MTEX; a++) { - if(ma->mtex[a]) id_lib_extern((ID *)ma->mtex[a]->tex); - } - - new_id(NULL, (ID *)ma, NULL); + + new_id(&bmain->mat, (ID *)ma, NULL); + extern_local_material(ma); } else if(local && lib) { @@ -429,6 +432,15 @@ void make_local_material(Material *ma) } } +/* for curve, mball, mesh types */ +void extern_local_matarar(struct Material **matar, short totcol) +{ + short i; + for(i= 0; i < totcol; i++) { + id_lib_extern((ID *)matar[i]); + } +} + Material ***give_matarar(Object *ob) { Mesh *me; @@ -1314,12 +1326,12 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col) case MA_RAMP_SOFT: if (g){ float scr, scg, scb; - + /* first calculate non-fac based Screen mix */ scr = 1.0f - (1.0f - col[0]) * (1.0f - *r); scg = 1.0f - (1.0f - col[1]) * (1.0f - *g); scb = 1.0f - (1.0f - col[2]) * (1.0f - *b); - + *r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr)); *g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg)); *b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb)); diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c index e6e32be9634..555d35726bc 100644 --- a/source/blender/blenkernel/intern/mball.c +++ b/source/blender/blenkernel/intern/mball.c @@ -67,6 +67,7 @@ #include "BKE_displist.h" #include "BKE_mball.h" #include "BKE_object.h" +#include "BKE_material.h" /* Global variables */ @@ -132,14 +133,24 @@ MetaBall *copy_mball(MetaBall *mb) id_us_plus((ID *)mbn->mat[a]); } mbn->bb= MEM_dupallocN(mb->bb); + + mbn->editelems= NULL; + mbn->lastelem= NULL; return mbn; } +static void extern_local_mball(MetaBall *mb) +{ + if(mb->mat) { + extern_local_matarar(mb->mat, mb->totcol); + } +} + void make_local_mball(MetaBall *mb) { + Main *bmain= G.main; Object *ob; - MetaBall *mbn; int local=0, lib=0; /* - only lib users: do nothing @@ -151,43 +162,44 @@ void make_local_mball(MetaBall *mb) if(mb->id.us==1) { mb->id.lib= NULL; mb->id.flag= LIB_LOCAL; + new_id(&bmain->mball, (ID *)mb, NULL); + extern_local_mball(mb); + return; } - - ob= G.main->object.first; - while(ob) { - if(ob->data==mb) { + + for(ob= G.main->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + if(ob->data == mb) { if(ob->id.lib) lib= 1; else local= 1; } - ob= ob->id.next; } if(local && lib==0) { mb->id.lib= NULL; mb->id.flag= LIB_LOCAL; + + new_id(&bmain->mball, (ID *)mb, NULL); + extern_local_mball(mb); } else if(local && lib) { - mbn= copy_mball(mb); + MetaBall *mbn= copy_mball(mb); mbn->id.us= 0; - - ob= G.main->object.first; - while(ob) { - if(ob->data==mb) { - + + for(ob= G.main->object.first; ob; ob= ob->id.next) { + if(ob->data == mb) { if(ob->id.lib==NULL) { ob->data= mbn; mbn->id.us++; mb->id.us--; } } - ob= ob->id.next; } } } /* most simple meta-element adding function - * dont do context menipulation here (rna uses) */ + * don't do context manipulation here (rna uses) */ MetaElem *add_metaball_element(MetaBall *mb, const int type) { MetaElem *ml= MEM_callocN(sizeof(MetaElem), "metaelem"); @@ -237,14 +249,14 @@ MetaElem *add_metaball_element(MetaBall *mb, const int type) /** Compute bounding box of all MetaElems/MetaBalls. * * Bounding box is computed from polygonized surface. Object *ob is - * basic MetaBall (usaualy with name Meta). All other MetaBalls (whith + * basic MetaBall (usually with name Meta). All other MetaBalls (with * names Meta.001, Meta.002, etc) are included in this Bounding Box. */ void tex_space_mball(Object *ob) { DispList *dl; BoundBox *bb; - float *data, min[3], max[3], loc[3], size[3]; + float *data, min[3], max[3] /*, loc[3], size[3] */; int tot, doit=0; if(ob->bb==NULL) ob->bb= MEM_callocN(sizeof(BoundBox), "mb boundbox"); @@ -272,7 +284,7 @@ void tex_space_mball(Object *ob) min[0] = min[1] = min[2] = -1.0f; max[0] = max[1] = max[2] = 1.0f; } - + /* loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f; @@ -280,7 +292,7 @@ void tex_space_mball(Object *ob) size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f; - + */ boundbox_set_from_min_max(bb, min, max); } @@ -320,14 +332,14 @@ float *make_orco_mball(Object *ob, ListBase *dispbase) } /* Note on mball basis stuff 2.5x (this is a can of worms) - * This really needs a rewrite/refactorm its totally broken in anything other then basic cases + * This really needs a rewrite/refactor its totally broken in anything other then basic cases * Multiple Scenes + Set Scenes & mixing mball basis SHOULD work but fails to update the depsgraph on rename * and linking into scenes or removal of basis mball. so take care when changing this code. * * Main idiot thing here is that the system returns find_basis_mball() objects which fail a is_basis_mball() test. * - * Not only that but the depsgraph and ther areas depend on this behavior!, so making small fixes here isnt worth it. - * - campbell + * Not only that but the depsgraph and their areas depend on this behavior!, so making small fixes here isn't worth it. + * - Campbell */ @@ -725,7 +737,7 @@ void accum_mballfaces(int i1, int i2, int i3, int i4) cur= indices+4*curindex; - /* diplists now support array drawing, we treat trias as fake quad */ + /* displists now support array drawing, we treat tri's as fake quad */ cur[0]= i1; cur[1]= i2; @@ -1315,7 +1327,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2, dy = pos.y - neg.y; dz = pos.z - neg.z; -/* Aproximation by linear interpolation is faster then binary subdivision, +/* Approximation by linear interpolation is faster then binary subdivision, * but it results sometimes (mb->thresh < 0.2) into the strange results */ if((mb->thresh > 0.2f) && (f==1)){ if((dy == 0.0f) && (dz == 0.0f)){ @@ -1373,7 +1385,7 @@ void converge (MB_POINT *p1, MB_POINT *p2, float v1, float v2, p->x = 0.5f*(pos.x + neg.x); p->y = 0.5f*(pos.y + neg.y); p->z = 0.5f*(pos.z + neg.z); - + if (i++ == RES) return; if ((function(p->x, p->y, p->z)) > 0.0f){ @@ -1625,7 +1637,7 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */ } } - /* when metaball object hase zero scale, then MetaElem ot this MetaBall + /* when metaball object has zero scale, then MetaElem to this MetaBall * will not be put to mainb array */ if(bob->size[0]==0.0f || bob->size[1]==0.0f || bob->size[2]==0.0f) { zero_size= 1; @@ -1688,11 +1700,11 @@ float init_meta(Scene *scene, Object *ob) /* return totsize */ mul_m4_m4m4(temp2, bob->obmat, obinv); /* MetaBall transformation */ mul_m4_m4m4(mat, temp1, temp2); - + invert_m4_m4(imat,mat); - + mainb[a]->rad2= ml->rad*ml->rad; - + mainb[a]->mat= (float*) mat; mainb[a]->imat= (float*) imat; diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index e51aa4624b9..8c9240bb0f8 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -336,7 +336,7 @@ static void mesh_ensure_tesselation_customdata(Mesh *me) /*this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or mloopcol and mcol) have the same relative active/render/clone/mask indices.*/ -void mesh_update_linked_customdata(Mesh *me) +static void mesh_update_linked_customdata(Mesh *me) { int act; @@ -558,6 +558,8 @@ Mesh *copy_mesh(Mesh *me) } men->mselect= NULL; + men->edit_btmesh= NULL; + men->pv= NULL; /* looks like this is no-longer supported but NULL just incase */ men->bb= MEM_dupallocN(men->bb); @@ -579,7 +581,7 @@ BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob) return bm; } -void make_local_tface(Mesh *me) +static void make_local_tface(Main *bmain, Mesh *me) { MTFace *tface; MTexPoly *txface; @@ -615,7 +617,7 @@ void make_local_tface(Mesh *me) if(ima->id.lib) { ima->id.lib= NULL; ima->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ima, NULL); + new_id(&bmain->image, (ID *)ima, NULL); } } } @@ -624,58 +626,65 @@ void make_local_tface(Mesh *me) } +static void expand_local_mesh(Main *bmain, Mesh *me) +{ + id_lib_extern((ID *)me->texcomesh); + + if(me->mtface) { + /* why is this an exception? - should not really make local when extern'ing - campbell */ + make_local_tface(bmain, me); + } + + if(me->mat) { + extern_local_matarar(me->mat, me->totcol); + } +} + void make_local_mesh(Mesh *me) { Main *bmain= G.main; Object *ob; - Mesh *men; int local=0, lib=0; /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ - + * - only local users: set flag + * - mixed: make copy + */ + if(me->id.lib==NULL) return; if(me->id.us==1) { me->id.lib= NULL; me->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)me, NULL); - - if(me->mtface) make_local_tface(me); - + + new_id(&bmain->mesh, (ID *)me, NULL); + expand_local_mesh(bmain, me); return; } - - ob= bmain->object.first; - while(ob) { - if( me==get_mesh(ob) ) { + + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { + if(me == ob->data) { if(ob->id.lib) lib= 1; else local= 1; } - ob= ob->id.next; } - + if(local && lib==0) { me->id.lib= NULL; me->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)me, NULL); - - if(me->mtface) make_local_tface(me); - + + new_id(&bmain->mesh, (ID *)me, NULL); + expand_local_mesh(bmain, me); } else if(local && lib) { - men= copy_mesh(me); + Mesh *men= copy_mesh(me); men->id.us= 0; - - ob= bmain->object.first; - while(ob) { - if( me==get_mesh(ob) ) { + + for(ob= bmain->object.first; ob; ob= ob->id.next) { + if(me == ob->data) { if(ob->id.lib==NULL) { set_mesh(ob, men); } } - ob= ob->id.next; } } } @@ -2108,7 +2117,7 @@ void create_vert_edge_map(ListBase **map, IndexNode **mem, const MEdge *medge, c (*map) = MEM_callocN(sizeof(ListBase) * totvert, "vert edge map"); (*mem) = MEM_callocN(sizeof(IndexNode) * totedge * 2, "vert edge map mem"); node = *mem; - + /* Find the users */ for(i = 0; i < totedge; ++i){ for(j = 0; j < 2; ++j, ++node) { diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 70928ab7bbb..46bf47b13f5 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -307,7 +307,9 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), unsigned int totve int BKE_mesh_validate(Mesh *me, int do_verbose) { - printf("MESH: %s\n", me->id.name+2); + if(do_verbose) { + printf("MESH: %s\n", me->id.name+2); + } return BKE_mesh_validate_arrays(me, me->mvert, me->totvert, me->medge, me->totedge, me->mface, me->totface, do_verbose, TRUE); } diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 03fdcdd0c91..ae90d3df3e4 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -56,7 +56,6 @@ #include "BKE_fcurve.h" #include "BKE_node.h" #include "BKE_utildefines.h" -#include "BKE_node.h" #include "PIL_time.h" @@ -968,6 +967,11 @@ bNode *nodeAddNodeType(bNodeTree *ntree, int type, bNodeTree *ngroup, ID *id) } else ntype= node_get_type(ntree, type, id); + if(ntype == NULL) { + printf("nodeAddNodeType() error: '%d' type invalid\n", type); + return NULL; + } + node= MEM_callocN(sizeof(bNode), "new node"); BLI_addtail(&ntree->nodes, node); node->typeinfo= ntype; @@ -1189,7 +1193,9 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) newtree= MEM_dupallocN(ntree); copy_libblock_data(&newtree->id, &ntree->id, TRUE); /* copy animdata and ID props */ } - + + id_us_plus((ID *)newtree->gpd); + /* in case a running nodetree is copied */ newtree->init &= ~(NTREE_EXEC_INIT); newtree->threadstack= NULL; @@ -1431,6 +1437,8 @@ void ntreeFreeTree(bNodeTree *ntree) BKE_free_animdata((ID *)ntree); + id_us_min((ID *)ntree->gpd); + BLI_freelistN(&ntree->links); /* do first, then unlink_node goes fast */ for(node= ntree->nodes.first; node; node= next) { @@ -1998,11 +2006,23 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod if (ntree->type==NTREE_COMPOSIT) { bNodeSocket *sock; bNodeStack *ns; + + /* clear hasoutput on all local stack data, + * only the group output will be used from now on + */ + for (node=ntree->nodes.first; node; node=node->next) { + for (sock=node->outputs.first; sock; sock=sock->next) { + if (sock->stack_type==SOCK_STACK_LOCAL) { + ns= get_socket_stack(stack, sock, in); + ns->hasoutput = 0; + } + } + } + /* use the hasoutput flag to tag external sockets */ for (sock=ntree->outputs.first; sock; sock=sock->next) { - /* use the hasoutput flag to tag external sockets */ if (sock->stack_type==SOCK_STACK_LOCAL) { ns= get_socket_stack(stack, sock, in); - ns->hasoutput = 0; + ns->hasoutput = 1; } } /* now free all stacks that are not used from outside */ @@ -2010,11 +2030,9 @@ static void node_group_execute(bNodeStack *stack, void *data, bNode *gnode, bNod for (sock=node->outputs.first; sock; sock=sock->next) { if (sock->stack_type==SOCK_STACK_LOCAL ) { ns= get_socket_stack(stack, sock, in); - if (ns->hasoutput!=0 && ns->data) { + if (ns->hasoutput==0 && ns->data) { free_compbuf(ns->data); ns->data = NULL; - /* reset the flag */ - ns->hasoutput = 1; } } } @@ -2230,9 +2248,37 @@ static void group_tag_used_outputs(bNode *gnode, bNodeStack *stack, bNodeStack * } } + /* non-composite trees do all nodes by default */ + if (ntree->type!=NTREE_COMPOSIT) + node->need_exec = 1; + + for(sock= node->inputs.first; sock; sock= sock->next) { + bNodeStack *ns = get_socket_stack(stack, sock, gin); + if (ns) { + ns->hasoutput = 1; + + /* sock type is needed to detect rgba or value or vector types */ + if(sock->link && sock->link->fromsock) + ns->sockettype= sock->link->fromsock->type; + else + sock->ns.sockettype= sock->type; + } + + if(sock->link) { + bNodeLink *link= sock->link; + /* this is the test for a cyclic case */ + if(link->fromnode && link->tonode) { + if(link->fromnode->level >= link->tonode->level && link->tonode->level!=0xFFF); + else { + node->need_exec= 0; + } + } + } + } + /* set stack types (for local stack entries) */ for(sock= node->outputs.first; sock; sock= sock->next) { - bNodeStack *ns = get_socket_stack(stack, sock, NULL); + bNodeStack *ns = get_socket_stack(stack, sock, gin); if (ns) ns->sockettype = sock->type; } @@ -2282,13 +2328,18 @@ static void tex_end_exec(bNodeTree *ntree) bNodeStack *ns; int th, a; - if(ntree->threadstack) - for(th=0; th<BLENDER_MAX_THREADS; th++) - for(nts=ntree->threadstack[th].first; nts; nts=nts->next) - for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++) - if(ns->data) + if(ntree->threadstack) { + for(th=0; th<BLENDER_MAX_THREADS; th++) { + for(nts=ntree->threadstack[th].first; nts; nts=nts->next) { + for(ns= nts->stack, a=0; a<ntree->stacksize; a++, ns++) { + if(ns->data) { MEM_freeN(ns->data); - + ns->data= NULL; + } + } + } + } + } } void ntreeBeginExecTree(bNodeTree *ntree) @@ -2321,7 +2372,7 @@ void ntreeBeginExecTree(bNodeTree *ntree) for(node= ntree->nodes.first; node; node= node->next) { bNodeSocket *sock; - /* composite has own need_exec tag handling */ + /* non-composite trees do all nodes by default */ if(ntree->type!=NTREE_COMPOSIT) node->need_exec= 1; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index c761e9852bd..eb796b073d8 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -98,6 +98,7 @@ #include "BKE_scene.h" #include "BKE_sequencer.h" #include "BKE_softbody.h" +#include "BKE_material.h" #include "LBM_fluidsim.h" @@ -209,8 +210,8 @@ void object_link_modifiers(struct Object *ob, struct Object *from) BLI_addtail(&ob->modifiers, nmd); } - copy_object_particlesystems(from, ob); - copy_object_softbody(from, ob); + copy_object_particlesystems(ob, from); + copy_object_softbody(ob, from); // TODO: smoke?, cloth? } @@ -737,51 +738,45 @@ void make_local_camera(Camera *cam) { Main *bmain= G.main; Object *ob; - Camera *camn; int local=0, lib=0; /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ + * - only local users: set flag + * - mixed: make copy + */ if(cam->id.lib==NULL) return; if(cam->id.us==1) { cam->id.lib= NULL; cam->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)cam, NULL); + new_id(&bmain->camera, (ID *)cam, NULL); return; } - ob= bmain->object.first; - while(ob) { + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { if(ob->data==cam) { if(ob->id.lib) lib= 1; else local= 1; } - ob= ob->id.next; } if(local && lib==0) { cam->id.lib= NULL; cam->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)cam, NULL); + new_id(&bmain->camera, (ID *)cam, NULL); } else if(local && lib) { - camn= copy_camera(cam); + Camera *camn= copy_camera(cam); camn->id.us= 0; - ob= bmain->object.first; - while(ob) { - if(ob->data==cam) { - + for(ob= bmain->object.first; ob; ob= ob->id.next) { + if(ob->data == cam) { if(ob->id.lib==NULL) { ob->data= camn; camn->id.us++; cam->id.us--; } } - ob= ob->id.next; } } } @@ -898,7 +893,7 @@ void make_local_lamp(Lamp *la) if(la->id.us==1) { la->id.lib= NULL; la->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)la, NULL); + new_id(&bmain->lamp, (ID *)la, NULL); return; } @@ -914,7 +909,7 @@ void make_local_lamp(Lamp *la) if(local && lib==0) { la->id.lib= NULL; la->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)la, NULL); + new_id(&bmain->lamp, (ID *)la, NULL); } else if(local && lib) { lan= copy_lamp(la); @@ -1367,11 +1362,10 @@ Object *copy_object(Object *ob) return obn; } -void expand_local_object(Object *ob) +static void extern_local_object(Object *ob) { //bActionStrip *strip; ParticleSystem *psys; - int a; #if 0 // XXX old animation system id_lib_extern((ID *)ob->action); @@ -1379,10 +1373,11 @@ void expand_local_object(Object *ob) #endif // XXX old animation system id_lib_extern((ID *)ob->data); id_lib_extern((ID *)ob->dup_group); - - for(a=0; a<ob->totcol; a++) { - id_lib_extern((ID *)ob->mat[a]); - } + id_lib_extern((ID *)ob->poselib); + id_lib_extern((ID *)ob->gpd); + + extern_local_matarar(ob->mat, ob->totcol); + #if 0 // XXX old animation system for (strip=ob->nlastrips.first; strip; strip=strip->next) { id_lib_extern((ID *)strip->act); @@ -1395,16 +1390,15 @@ void expand_local_object(Object *ob) void make_local_object(Object *ob) { Main *bmain= G.main; - Object *obn; Scene *sce; Base *base; int local=0, lib=0; /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ - + * - only local users: set flag + * - mixed: make copy + */ + if(ob->id.lib==NULL) return; ob->proxy= ob->proxy_from= NULL; @@ -1412,31 +1406,23 @@ void make_local_object(Object *ob) if(ob->id.us==1) { ob->id.lib= NULL; ob->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ob, NULL); - + new_id(&bmain->object, (ID *)ob, NULL); } else { - sce= bmain->scene.first; - while(sce) { - base= sce->base.first; - while(base) { - if(base->object==ob) { - if(sce->id.lib) lib++; - else local++; - break; - } - base= base->next; + for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) { + if(object_in_scene(ob, sce)) { + if(sce->id.lib) lib= 1; + else local= 1; } - sce= sce->id.next; } - + if(local && lib==0) { ob->id.lib= NULL; ob->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)ob, NULL); + new_id(&bmain->object, (ID *)ob, NULL); } else if(local && lib) { - obn= copy_object(ob); + Object *obn= copy_object(ob); obn->id.us= 0; sce= bmain->scene.first; @@ -1457,7 +1443,7 @@ void make_local_object(Object *ob) } } - expand_local_object(ob); + extern_local_object(ob); } /* @@ -1565,7 +1551,10 @@ void object_make_proxy(Object *ob, Object *target, Object *gob) ob->rotmode= target->rotmode; mul_m4_m4m4(ob->obmat, target->obmat, gob->obmat); if(gob->dup_group) { /* should always be true */ - sub_v3_v3(ob->obmat[3], gob->dup_group->dupli_ofs); + float tvec[3]; + copy_v3_v3(tvec, gob->dup_group->dupli_ofs); + mul_mat3_m4_v3(ob->obmat, tvec); + sub_v3_v3(ob->obmat[3], tvec); } object_apply_mat4(ob, ob->obmat, FALSE, TRUE); } @@ -1615,6 +1604,10 @@ void object_make_proxy(Object *ob, Object *target, Object *gob) armature_set_id_extern(ob); } + else if (target->type == OB_EMPTY) { + ob->empty_drawtype = target->empty_drawtype; + ob->empty_drawsize = target->empty_drawsize; + } /* copy IDProperties */ if(ob->id.properties) { @@ -2284,7 +2277,7 @@ void what_does_parent(Scene *scene, Object *ob, Object *workob) workob->constraints.first = ob->constraints.first; workob->constraints.last = ob->constraints.last; - strcpy(workob->parsubstr, ob->parsubstr); + BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr)); where_is_object(scene, workob); } @@ -2832,6 +2825,16 @@ int object_insert_ptcache(Object *ob) return i; } +void object_camera_mode(RenderData *rd, Object *camera) +{ + rd->mode &= ~(R_ORTHO|R_PANORAMA); + if(camera && camera->type==OB_CAMERA) { + Camera *cam= camera->data; + if(cam->type == CAM_ORTHO) rd->mode |= R_ORTHO; + if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA; + } +} + /* 'lens' may be set for envmap only */ void object_camera_matrix( RenderData *rd, Object *camera, int winx, int winy, short field_second, @@ -2841,8 +2844,7 @@ void object_camera_matrix( Camera *cam=NULL; float pixsize; float shiftx=0.0, shifty=0.0, winside, viewfac; - - rd->mode &= ~(R_ORTHO|R_PANORAMA); + short is_ortho= FALSE; /* question mark */ (*ycor)= rd->yasp / rd->xasp; @@ -2852,8 +2854,9 @@ void object_camera_matrix( if(camera->type==OB_CAMERA) { cam= camera->data; - if(cam->type==CAM_ORTHO) rd->mode |= R_ORTHO; - if(cam->flag & CAM_PANORAMA) rd->mode |= R_PANORAMA; + if(cam->type == CAM_ORTHO) { + is_ortho= TRUE; + } /* solve this too... all time depending stuff is in convertblender.c? * Need to update the camera early because it's used for projection matrices @@ -2893,7 +2896,7 @@ void object_camera_matrix( } /* ortho only with camera available */ - if(cam && rd->mode & R_ORTHO) { + if(cam && is_ortho) { if(rd->xasp*winx >= rd->yasp*winy) { viewfac= winx; } @@ -2936,7 +2939,7 @@ void object_camera_matrix( (*viewdx)= pixsize; (*viewdy)= (*ycor) * pixsize; - if(rd->mode & R_ORTHO) + if(is_ortho) orthographic_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); else perspective_m4(winmat, viewplane->xmin, viewplane->xmax, viewplane->ymin, viewplane->ymax, *clipsta, *clipend); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e5d77355d5d..b603c1ec54b 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -266,17 +266,10 @@ static void psys_create_frand(ParticleSystem *psys) int psys_check_enabled(Object *ob, ParticleSystem *psys) { ParticleSystemModifierData *psmd; - Mesh *me; if(psys->flag & PSYS_DISABLED || psys->flag & PSYS_DELETE || !psys->part) return 0; - if(ob->type == OB_MESH) { - me= (Mesh*)ob->data; - if(me->mr && me->mr->current != 1) - return 0; - } - psmd= psys_get_modifier(ob, psys); if(psys->renderdata || G.rendering) { if(!(psmd->modifier.mode & eModifierMode_Render)) @@ -3039,7 +3032,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra) psys->totcached = totpart; - if(psys && psys->lattice){ + if(psys->lattice){ end_latt_deform(psys->lattice); psys->lattice= NULL; } @@ -3598,28 +3591,38 @@ ParticleSettings *psys_copy_settings(ParticleSettings *part) return partn; } +static void expand_local_particlesettings(ParticleSettings *part) +{ + int i; + id_lib_extern((ID *)part->dup_group); + + for(i=0; i<MAX_MTEX; i++) { + if(part->mtex[i]) id_lib_extern((ID *)part->mtex[i]->tex); + } +} + void make_local_particlesettings(ParticleSettings *part) { + Main *bmain= G.main; Object *ob; - ParticleSettings *par; int local=0, lib=0; /* - only lib users: do nothing - * - only local users: set flag - * - mixed: make copy - */ + * - only local users: set flag + * - mixed: make copy + */ if(part->id.lib==0) return; if(part->id.us==1) { part->id.lib= 0; part->id.flag= LIB_LOCAL; - new_id(0, (ID *)part, 0); + new_id(&bmain->particle, (ID *)part, 0); + expand_local_particlesettings(part); return; } - + /* test objects */ - ob= G.main->object.first; - while(ob) { + for(ob= bmain->object.first; ob && ELEM(0, lib, local); ob= ob->id.next) { ParticleSystem *psys=ob->particlesystem.first; for(; psys; psys=psys->next){ if(psys->part==part) { @@ -3627,31 +3630,28 @@ void make_local_particlesettings(ParticleSettings *part) else local= 1; } } - ob= ob->id.next; } if(local && lib==0) { part->id.lib= 0; part->id.flag= LIB_LOCAL; - new_id(0, (ID *)part, 0); + new_id(&bmain->particle, (ID *)part, 0); + expand_local_particlesettings(part); } else if(local && lib) { - - par= psys_copy_settings(part); - par->id.us= 0; + ParticleSettings *partn= psys_copy_settings(part); + partn->id.us= 0; /* do objects */ - ob= G.main->object.first; - while(ob) { - ParticleSystem *psys=ob->particlesystem.first; - for(; psys; psys=psys->next){ + for(ob= bmain->object.first; ob; ob= ob->id.next) { + ParticleSystem *psys; + for(psys= ob->particlesystem.first; psys; psys=psys->next){ if(psys->part==part && ob->id.lib==0) { - psys->part= par; - par->id.us++; + psys->part= partn; + partn->id.us++; part->id.us--; } } - ob= ob->id.next; } } } @@ -4373,7 +4373,7 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa float loc[3], nor[3], vec[3], side[3], len, obrotmat[4][4], qmat[4][4]; float xvec[3] = {-1.0, 0.0, 0.0}, q[4], nmat[3][3]; - sub_v3_v3v3(vec, (cache+cache->steps-1)->co, cache->co); + sub_v3_v3v3(vec, (cache+cache->steps)->co, cache->co); len= normalize_v3(vec); if(psys->part->rotmode) { @@ -4433,22 +4433,22 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3] xvec[0] = 1.0f; xvec[1] = 0.0f; xvec[2] = 0.0f; yvec[0] = 0.0f; yvec[1] = 1.0f; yvec[2] = 0.0f; - /* can happen with bad pointcache or physics calculation - * since this becomes geometry, nan's and inf's crash raytrace code. - * better not allow this. */ - if( !finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) || - !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) ) - { - zero_v3(bb->vec); - zero_v3(bb->vel); - - zero_v3(xvec); - zero_v3(yvec); - zero_v3(zvec); - zero_v3(center); - - return; - } + /* can happen with bad pointcache or physics calculation + * since this becomes geometry, nan's and inf's crash raytrace code. + * better not allow this. */ + if( !finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) || + !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) ) + { + zero_v3(bb->vec); + zero_v3(bb->vel); + + zero_v3(xvec); + zero_v3(yvec); + zero_v3(zvec); + zero_v3(center); + + return; + } if(bb->align < PART_BB_VIEW) onevec[bb->align]=1.0f; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index dbf2803ec18..701a34d1794 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -644,7 +644,7 @@ static void hammersley_create(float *out, int n, int seed, float amount) for (p = 0.5, kk = k; kk; p *= 0.5, kk >>= 1) if (kk & 1) /* kk mod 2 = 1 */ t += p; - + out[2*k + 0]= fmod((double)k/(double)n + offs[0], 1.0); out[2*k + 1]= fmod(t + offs[1], 1.0); } @@ -2552,7 +2552,7 @@ static void basic_integrate(ParticleSimulationData *sim, int p, float dfra, floa /* damp affects final velocity */ if(part->dampfac != 0.f) - mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp); + mul_v3_fl(pa->state.vel, 1.f - part->dampfac * efdata.ptex.damp * 25.f * dtime); //VECCOPY(pa->state.ave, states->ave); diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index a8447e2a12a..64893bb0b5b 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -938,7 +938,7 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p len = ptcache_path(pid, filename); newname += len; } - if(strcmp(pid->cache->name, "")==0 && (pid->cache->flag & PTCACHE_EXTERNAL)==0) { + if(pid->cache->name[0] == '\0' && (pid->cache->flag & PTCACHE_EXTERNAL)==0) { idname = (pid->ob->id.name+2); /* convert chars to hex so they are always a valid filename */ while('\0' != *idname) { @@ -1003,15 +1003,15 @@ static PTCacheFile *ptcache_file_open(PTCacheID *pid, int mode, int cfra) fp = fopen(filename, "rb+"); } - if (!fp) - return NULL; - + if (!fp) + return NULL; + pf= MEM_mallocN(sizeof(PTCacheFile), "PTCacheFile"); pf->fp= fp; pf->old_format = 0; pf->frame = cfra; - - return pf; + + return pf; } static void ptcache_file_close(PTCacheFile *pf) { @@ -1308,8 +1308,8 @@ static void ptcache_data_copy(void *from[], void *to[]) { int i; for(i=0; i<BPHYS_TOT_DATA; i++) { - /* note, durian file 03.4b_comp crashes if to[i] is not tested - * its NULL, not sure if this should be fixed elsewhere but for now its needed */ + /* note, durian file 03.4b_comp crashes if to[i] is not tested + * its NULL, not sure if this should be fixed elsewhere but for now its needed */ if(from[i] && to[i]) memcpy(to[i], from[i], ptcache_data_size[i]); } @@ -1373,14 +1373,16 @@ static void ptcache_find_frames_around(PTCacheID *pid, unsigned int frame, int * while(pm->next && pm->next->frame < frame) pm= pm->next; - if(pm2 && pm2->frame < frame) + if(pm2->frame < frame) { pm2 = NULL; + } else { - while(pm2->prev && pm2->prev->frame > frame) + while(pm2->prev && pm2->prev->frame > frame) { pm2= pm2->prev; + } } - if(pm && !pm2) { + if(!pm2) { *fra1 = 0; *fra2 = pm->frame; } @@ -1842,7 +1844,8 @@ static int ptcache_write(PTCacheID *pid, int cfra, int overwrite) if(cache->flag & PTCACHE_DISK_CACHE) { error += !ptcache_mem_frame_to_disk(pid, pm); - if(pm) { + // if(pm) /* pm is always set */ + { ptcache_data_free(pm); ptcache_extra_free(pm); MEM_freeN(pm); diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index ed3739e897d..f84d98a31b4 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -101,7 +101,7 @@ void BKE_report(ReportList *reports, ReportType type, const char *message) Report *report; int len; - /* in background mode always print otherwise there are cases the errors wont be displayed, + /* in background mode always print otherwise there are cases the errors wont be displayed, * but still add to the report list since this is used for python exception handling */ if(G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { printf("%s: %s\n", report_type_str(type), message); diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index ceafb06fce6..4ee7ee501e1 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -333,12 +333,12 @@ void free_actuator(bActuator *act) if(act->data) { switch (act->type) { - case ACT_SOUND: - sa = (bSoundActuator *) act->data; - if(sa->sound) - id_us_min((ID *) sa->sound); - break; - } + case ACT_SOUND: + sa = (bSoundActuator *) act->data; + if(sa->sound) + id_us_min((ID *) sa->sound); + break; + } MEM_freeN(act->data); } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index c4eefb16348..791d572d385 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -1080,23 +1080,23 @@ float get_render_aosss_error(RenderData *r, float error) /* helper function for the SETLOOPER macro */ Base *_setlooper_base_step(Scene **sce_iter, Base *base) { - if(base && base->next) { - /* common case, step to the next */ - return base->next; - } + if(base && base->next) { + /* common case, step to the next */ + return base->next; + } else if(base==NULL && (*sce_iter)->base.first) { - /* first time looping, return the scenes first base */ + /* first time looping, return the scenes first base */ return (Base *)(*sce_iter)->base.first; - } - else { - /* reached the end, get the next base in the set */ + } + else { + /* reached the end, get the next base in the set */ while((*sce_iter= (*sce_iter)->set)) { base= (Base *)(*sce_iter)->base.first; - if(base) { - return base; - } - } - } + if(base) { + return base; + } + } + } - return NULL; + return NULL; } diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 42beb055140..6f329433580 100755 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -237,9 +237,7 @@ void seq_stripelem_cache_put( key->cfra = cfra - seq->start; key->type = type; - /* Normally we want our own version, but start and end stills are duplicates of the original. */ - if(ELEM(type, SEQ_STRIPELEM_IBUF_STARTSTILL, SEQ_STRIPELEM_IBUF_ENDSTILL)==0) - IMB_refImBuf(i); + IMB_refImBuf(i); e = (seqCacheEntry*) BLI_mempool_alloc(entrypool); diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index 3dfef2e9d78..6f49155c0fd 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -37,7 +37,7 @@ #include <stdlib.h> #include "MEM_guardedalloc.h" -#include "PIL_dynlib.h" +#include "BLI_dynlib.h" #include "BLI_math.h" /* windows needs for M_PI */ #include "BLI_utildefines.h" @@ -138,18 +138,18 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname) pis->instance_private_data = NULL; /* clear the error list */ - PIL_dynlib_get_error_as_string(NULL); + BLI_dynlib_get_error_as_string(NULL); - /* if(pis->handle) PIL_dynlib_close(pis->handle); */ + /* if(pis->handle) BLI_dynlib_close(pis->handle); */ /* pis->handle= 0; */ /* open the needed object */ - pis->handle= PIL_dynlib_open(pis->name); + pis->handle= BLI_dynlib_open(pis->name); if(test_dlerr(pis->name, pis->name)) return; if (pis->handle != NULL) { /* find the address of the version function */ - version= (int (*)(void))PIL_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); + version= (int (*)(void))BLI_dynlib_find_symbol(pis->handle, "plugin_seq_getversion"); if (test_dlerr(pis->name, "plugin_seq_getversion")) return; if (version != NULL) { @@ -158,7 +158,7 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname) int (*info_func)(PluginInfo *); PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info"); - info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pis->handle, "plugin_getinfo"); + info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pis->handle, "plugin_getinfo"); if(info_func == NULL) error("No info func"); else { @@ -176,21 +176,21 @@ static void open_plugin_seq(PluginSeq *pis, const char *seqname) } MEM_freeN(info); - cp= PIL_dynlib_find_symbol(pis->handle, "seqname"); + cp= BLI_dynlib_find_symbol(pis->handle, "seqname"); if(cp) strncpy(cp, seqname, 21); } else { printf ("Plugin returned unrecognized version number\n"); return; } } - alloc_private = (void* (*)(void))PIL_dynlib_find_symbol( + alloc_private = (void* (*)(void))BLI_dynlib_find_symbol( pis->handle, "plugin_seq_alloc_private_data"); if (alloc_private) { pis->instance_private_data = alloc_private(); } pis->current_private_data = (void**) - PIL_dynlib_find_symbol( + BLI_dynlib_find_symbol( pis->handle, "plugin_private_data"); } } @@ -229,12 +229,12 @@ static void free_plugin_seq(PluginSeq *pis) { if(pis==NULL) return; - /* no PIL_dynlib_close: same plugin can be opened multiple times with 1 handle */ + /* no BLI_dynlib_close: same plugin can be opened multiple times with 1 handle */ if (pis->instance_private_data) { void (*free_private)(void *); - free_private = (void (*)(void *))PIL_dynlib_find_symbol( + free_private = (void (*)(void *))BLI_dynlib_find_symbol( pis->handle, "plugin_seq_free_private_data"); if (free_private) { free_private(pis->instance_private_data); @@ -301,7 +301,7 @@ static struct ImBuf * do_plugin_effect( if(seq->plugin->cfra) *(seq->plugin->cfra)= cfra; - cp = PIL_dynlib_find_symbol( + cp = BLI_dynlib_find_symbol( seq->plugin->handle, "seqname"); if(cp) strncpy(cp, seq->name+2, 22); @@ -1675,15 +1675,15 @@ float hyp3,hyp4,b4,b5 output = in_band(wipezone,width,hyp,facf0,1,1); else output = in_band(wipezone,width,hyp,facf0,0,1); - } + } else { if(b1 < b2) output = in_band(wipezone,width,hyp,facf0,0,1); else output = in_band(wipezone,width,hyp,facf0,1,1); - } + } break; - + case DO_DOUBLE_WIPE: if(!wipe->forward) facf0 = 1.0f-facf0; // Go the other direction @@ -1726,45 +1726,45 @@ float hyp3,hyp4,b4,b5 output = in_band(wipezone,hwidth,hyp2,facf0,1,1) * in_band(wipezone,hwidth,hyp,facf0,1,1); } if(!wipe->forward)output = 1-output; - break; - case DO_CLOCK_WIPE: + break; + case DO_CLOCK_WIPE: /* temp1: angle of effect center in rads temp2: angle of line through (halfx,halfy) and (x,y) in rads temp3: angle of low side of blur temp4: angle of high side of blur */ - output = 1.0f - facf0; - widthf = wipe->edgeWidth*2.0f*(float)M_PI; - temp1 = 2.0f * (float)M_PI * facf0; - - if(wipe->forward){ - temp1 = 2.0f*(float)M_PI - temp1; - } - - x = x - halfx; - y = y - halfy; - - temp2 = asin(abs(y)/sqrt(x*x + y*y)); - if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2; - else if(x<=0 && y <= 0) temp2 += (float)M_PI; - else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2; - - if(wipe->forward){ - temp3 = temp1-(widthf*0.5f)*facf0; - temp4 = temp1+(widthf*0.5f)*(1-facf0); - } else{ - temp3 = temp1-(widthf*0.5f)*(1-facf0); - temp4 = temp1+(widthf*0.5f)*facf0; + output = 1.0f - facf0; + widthf = wipe->edgeWidth*2.0f*(float)M_PI; + temp1 = 2.0f * (float)M_PI * facf0; + + if(wipe->forward){ + temp1 = 2.0f*(float)M_PI - temp1; + } + + x = x - halfx; + y = y - halfy; + + temp2 = asin(abs(y)/sqrt(x*x + y*y)); + if(x <= 0 && y >= 0) temp2 = (float)M_PI - temp2; + else if(x<=0 && y <= 0) temp2 += (float)M_PI; + else if(x >= 0 && y <= 0) temp2 = 2.0f*(float)M_PI - temp2; + + if(wipe->forward){ + temp3 = temp1-(widthf*0.5f)*facf0; + temp4 = temp1+(widthf*0.5f)*(1-facf0); + } else{ + temp3 = temp1-(widthf*0.5f)*(1-facf0); + temp4 = temp1+(widthf*0.5f)*facf0; } - if (temp3 < 0) temp3 = 0; - if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI; - - - if(temp2 < temp3) output = 0; - else if (temp2 > temp4) output = 1; - else output = (temp2-temp3)/(temp4-temp3); - if(x == 0 && y == 0) output = 1; + if (temp3 < 0) temp3 = 0; + if (temp4 > 2.0f*(float)M_PI) temp4 = 2.0f*(float)M_PI; + + + if(temp2 < temp3) output = 0; + else if (temp2 > temp4) output = 1; + else output = (temp2-temp3)/(temp4-temp3); + if(x == 0 && y == 0) output = 1; if(output != output) output = 1; if(wipe->forward) output = 1 - output; break; @@ -1840,12 +1840,12 @@ float hyp3,hyp4,b4,b5 hwidth = width*0.5f; temp1 = (halfx-(halfx)*facf0); - pointdist = sqrt(temp1*temp1 + temp1*temp1); - - temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); - if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1); - else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1); - + pointdist = sqrt(temp1*temp1 + temp1*temp1); + + temp2 = sqrt((halfx-x)*(halfx-x) + (halfy-y)*(halfy-y)); + if(temp2 > pointdist) output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,0,1); + else output = in_band(wipezone,hwidth,fabs(temp2-pointdist),facf0,1,1); + if(!wipe->forward) output = 1-output; break; diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 7a6eb1adc9f..e3639dd1c51 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -845,7 +845,7 @@ typedef struct SeqUniqueInfo { /* static void seqbase_unique_name(ListBase *seqbasep, Sequence *seq) { - BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR); + BLI_uniquename(seqbasep, seq, "Sequence", '.', offsetof(Sequence, name), SEQ_NAME_MAXSTR); }*/ static void seqbase_unique_name(ListBase *seqbasep, SeqUniqueInfo *sui) @@ -1720,16 +1720,25 @@ static ImBuf * copy_from_ibuf_still(SeqRenderData context, Sequence * seq, static void copy_to_ibuf_still(SeqRenderData context, Sequence * seq, float nr, ImBuf * ibuf) { - if (nr == 0) { - seq_stripelem_cache_put( - context, seq, seq->start, - SEQ_STRIPELEM_IBUF_STARTSTILL, IMB_dupImBuf(ibuf)); - } + if (nr == 0 || nr == seq->len - 1) { + /* we have to store a copy, since the passed ibuf + could be preprocessed afterwards (thereby silently + changing the cached image... */ + ibuf = IMB_dupImBuf(ibuf); - if (nr == seq->len - 1) { - seq_stripelem_cache_put( - context, seq, seq->start, - SEQ_STRIPELEM_IBUF_ENDSTILL, IMB_dupImBuf(ibuf)); + if (nr == 0) { + seq_stripelem_cache_put( + context, seq, seq->start, + SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); + } + + if (nr == seq->len - 1) { + seq_stripelem_cache_put( + context, seq, seq->start, + SEQ_STRIPELEM_IBUF_ENDSTILL, ibuf); + } + + IMB_freeImBuf(ibuf); } } @@ -1849,7 +1858,7 @@ static ImBuf * seq_render_scene_strip_impl( ImBuf * ibuf = NULL; float frame= seq->sfra + nr + seq->anim_startofs; float oldcfra; - Object *oldcamera; + Object *camera; ListBase oldmarkers; /* Old info: @@ -1887,59 +1896,65 @@ static ImBuf * seq_render_scene_strip_impl( int doseq; int doseq_gl= G.rendering ? /*(scene->r.seq_flag & R_SEQ_GL_REND)*/ 0 : /*(scene->r.seq_flag & R_SEQ_GL_PREV)*/ 1; int have_seq= FALSE; - Scene *sce= seq->scene; /* dont refer to seq->scene above this point!, it can be NULL */ - int sce_valid= FALSE; + Scene *scene; - if(sce) { - have_seq= (sce->r.scemode & R_DOSEQ) && sce->ed && sce->ed->seqbase.first; - sce_valid= (sce->camera || have_seq); + /* dont refer to seq->scene above this point!, it can be NULL */ + if(seq->scene == NULL) { + return NULL; } - if (!sce_valid) - return NULL; + scene= seq->scene; - oldcfra= seq->scene->r.cfra; - oldcamera= seq->scene->camera; + have_seq= (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first; + + oldcfra= scene->r.cfra; + scene->r.cfra= frame; + + if(seq->scene_camera) + camera= seq->scene_camera; + else { + scene_camera_switch_update(scene); + camera= scene->camera; + } + + if(have_seq==FALSE && camera==NULL) { + scene->r.cfra= oldcfra; + return NULL; + } /* prevent eternal loop */ doseq= context.scene->r.scemode & R_DOSEQ; context.scene->r.scemode &= ~R_DOSEQ; - seq->scene->r.cfra= frame; - if(seq->scene_camera) - seq->scene->camera= seq->scene_camera; - else - scene_camera_switch_update(seq->scene); - #ifdef DURIAN_CAMERA_SWITCH /* stooping to new low's in hackyness :( */ - oldmarkers= seq->scene->markers; - seq->scene->markers.first= seq->scene->markers.last= NULL; + oldmarkers= scene->markers; + scene->markers.first= scene->markers.last= NULL; #endif - if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (seq->scene == context.scene || have_seq==0) && seq->scene->camera) { + if(sequencer_view3d_cb && BLI_thread_is_main() && doseq_gl && (scene == context.scene || have_seq==0) && camera) { char err_out[256]= "unknown"; /* for old scened this can be uninitialized, should probably be added to do_versions at some point if the functionality stays */ if(context.scene->r.seq_prev_type==0) context.scene->r.seq_prev_type = 3 /* ==OB_SOLID */; /* opengl offscreen render */ - scene_update_for_newframe(context.bmain, seq->scene, seq->scene->lay); - ibuf= sequencer_view3d_cb(seq->scene, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out); + scene_update_for_newframe(context.bmain, scene, scene->lay); + ibuf= sequencer_view3d_cb(scene, camera, context.rectx, context.recty, IB_rect, context.scene->r.seq_prev_type, err_out); if(ibuf == NULL) { fprintf(stderr, "seq_render_scene_strip_impl failed to get opengl buffer: %s\n", err_out); } } else { - Render *re = RE_GetRender(sce->id.name); + Render *re = RE_GetRender(scene->id.name); RenderResult rres; /* XXX: this if can be removed when sequence preview rendering uses the job system */ - if(rendering || context.scene != sce) { + if(rendering || context.scene != scene) { if(re==NULL) - re= RE_NewRender(sce->id.name); + re= RE_NewRender(scene->id.name); - RE_BlenderFrame(re, context.bmain, sce, NULL, sce->lay, frame, FALSE); + RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE); /* restore previous state after it was toggled on & off by RE_BlenderFrame */ G.rendering = rendering; @@ -1972,14 +1987,14 @@ static ImBuf * seq_render_scene_strip_impl( /* restore */ context.scene->r.scemode |= doseq; - seq->scene->r.cfra = oldcfra; - seq->scene->camera= oldcamera; + scene->r.cfra = oldcfra; + if(frame != oldcfra) - scene_update_for_newframe(context.bmain, seq->scene, seq->scene->lay); + scene_update_for_newframe(context.bmain, scene, scene->lay); #ifdef DURIAN_CAMERA_SWITCH /* stooping to new low's in hackyness :( */ - seq->scene->markers= oldmarkers; + scene->markers= oldmarkers; #endif return ibuf; diff --git a/source/blender/blenkernel/intern/sketch.c b/source/blender/blenkernel/intern/sketch.c index 6e234a9d115..ec0f5d1316b 100644 --- a/source/blender/blenkernel/intern/sketch.c +++ b/source/blender/blenkernel/intern/sketch.c @@ -543,7 +543,7 @@ int sk_stroke_filtermval(SK_DrawData *dd) return retval; } -void sk_initDrawData(SK_DrawData *dd, short mval[2]) +void sk_initDrawData(SK_DrawData *dd, const short mval[2]) { dd->mval[0] = mval[0]; dd->mval[1] = mval[1]; diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index fbde1aeae22..814ad92e6e9 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1470,20 +1470,20 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) { - int totalCells = xres * yres * zres; - int amplifiedCells = totalCells * amplify * amplify * amplify; + int totalCells = xres * yres * zres; + int amplifiedCells = totalCells * amplify * amplify * amplify; - // print out memory requirements - long long int coarseSize = sizeof(float) * totalCells * 22 + - sizeof(unsigned char) * totalCells; + // print out memory requirements + long long int coarseSize = sizeof(float) * totalCells * 22 + + sizeof(unsigned char) * totalCells; - long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids - sizeof(float) * totalCells * 8 + // small grids - sizeof(float) * 128 * 128 * 128; // noise tile + long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids + sizeof(float) * totalCells * 8 + // small grids + sizeof(float) * 128 * 128 * 128; // noise tile - long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); + long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); - return totalMB; + return totalMB; } static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c index c44136f523d..23c0d875dee 100644 --- a/source/blender/blenkernel/intern/softbody.c +++ b/source/blender/blenkernel/intern/softbody.c @@ -1649,12 +1649,12 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow, static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow) { - SoftBody *sb = ob->soft; - ListBase *do_effector = NULL; + SoftBody *sb = ob->soft; + ListBase *do_effector = NULL; - do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights); - _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); - pdEndEffectors(&do_effector); + do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights); + _scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector); + pdEndEffectors(&do_effector); } static void *exec_scan_for_ext_spring_forces(void *data) @@ -2217,50 +2217,50 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo /* naive ball self collision */ /* needs to be done if goal snaps or not */ if(do_selfcollision){ - int attached; - BodyPoint *obp; - BodySpring *bs; - int c,b; - float velcenter[3],dvel[3],def[3]; - float distance; - float compare; - float bstune = sb->ballstiff; - - for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) { - compare = (obp->colball + bp->colball); - sub_v3_v3v3(def, bp->pos, obp->pos); - /* rather check the AABBoxes before ever calulating the real distance */ - /* mathematically it is completly nuts, but performace is pretty much (3) times faster */ - if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue; - distance = normalize_v3(def); - if (distance < compare ){ - /* exclude body points attached with a spring */ - attached = 0; - for(b=obp->nofsprings;b>0;b--){ - bs = sb->bspring + obp->springs[b-1]; - if (( ilast-bb == bs->v2) || ( ilast-bb == bs->v1)){ - attached=1; - continue;} - } - if (!attached){ - float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ; + int attached; + BodyPoint *obp; + BodySpring *bs; + int c,b; + float velcenter[3],dvel[3],def[3]; + float distance; + float compare; + float bstune = sb->ballstiff; + + for(c=sb->totpoint, obp= sb->bpoint; c>=ifirst+bb; c--, obp++) { + compare = (obp->colball + bp->colball); + sub_v3_v3v3(def, bp->pos, obp->pos); + /* rather check the AABBoxes before ever calulating the real distance */ + /* mathematically it is completly nuts, but performace is pretty much (3) times faster */ + if ((ABS(def[0]) > compare) || (ABS(def[1]) > compare) || (ABS(def[2]) > compare)) continue; + distance = normalize_v3(def); + if (distance < compare ){ + /* exclude body points attached with a spring */ + attached = 0; + for(b=obp->nofsprings;b>0;b--){ + bs = sb->bspring + obp->springs[b-1]; + if (( ilast-bb == bs->v2) || ( ilast-bb == bs->v1)){ + attached=1; + continue;} + } + if (!attached){ + float f = bstune/(distance) + bstune/(compare*compare)*distance - 2.0f*bstune/compare ; - mid_v3_v3v3(velcenter, bp->vec, obp->vec); - sub_v3_v3v3(dvel,velcenter,bp->vec); - mul_v3_fl(dvel,_final_mass(ob,bp)); + mid_v3_v3v3(velcenter, bp->vec, obp->vec); + sub_v3_v3v3(dvel,velcenter,bp->vec); + mul_v3_fl(dvel,_final_mass(ob,bp)); - Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def); - Vec3PlusStVec(bp->force,sb->balldamp,dvel); + Vec3PlusStVec(bp->force,f*(1.0f-sb->balldamp),def); + Vec3PlusStVec(bp->force,sb->balldamp,dvel); - /* exploit force(a,b) == -force(b,a) part2/2 */ - sub_v3_v3v3(dvel,velcenter,obp->vec); - mul_v3_fl(dvel,_final_mass(ob,bp)); + /* exploit force(a,b) == -force(b,a) part2/2 */ + sub_v3_v3v3(dvel,velcenter,obp->vec); + mul_v3_fl(dvel,_final_mass(ob,bp)); - Vec3PlusStVec(obp->force,sb->balldamp,dvel); - Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def); - } + Vec3PlusStVec(obp->force,sb->balldamp,dvel); + Vec3PlusStVec(obp->force,-f*(1.0f-sb->balldamp),def); } } + } } /* naive ball self collision done */ @@ -2931,7 +2931,7 @@ static void softbody_apply_forces(Object *ob, float forcetime, int mode, float * /* now we have individual masses */ /* claim a minimum mass for vertex */ if (_final_mass(ob,bp) > 0.009999f) timeovermass = forcetime/_final_mass(ob,bp); - else timeovermass = forcetime/0.009999f; + else timeovermass = forcetime/0.009999f; if(_final_goal(ob,bp) < SOFTGOALSNAP){ diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 13748bf10ca..2c0428b8597 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -79,6 +79,7 @@ static CCGDerivedMesh *getCCGDerivedMesh(CCGSubSurf *ss, int drawInteriorEdges, int useSubsurfUv, DerivedMesh *dm); +static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm); /// @@ -1392,7 +1393,7 @@ static void ccgDM_drawVerts(DerivedMesh *dm) { static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm) { - if(ccgdm->pbvh) { + if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) { CCGFace **faces; int totface; @@ -1777,8 +1778,10 @@ static void cgdm_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned cha } glShadeModel(GL_SMOOTH); - if(col1 && col2) + + if(col2) { glEnable(GL_CULL_FACE); + } glBegin(GL_QUADS); for (; !ccgFaceIterator_isStopped(fi); ccgFaceIterator_next(fi)) { @@ -2541,10 +2544,22 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm) return ccgdm->fmap; } +static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) +{ + MultiresModifierData *mmd= ccgdm->multires.mmd; + + /* both of multires and subsurm modifiers are CCG, but + grids should only be used when sculpting on multires */ + if(!mmd) + return 0; + + return 1; +} + static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) { CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; - int gridSize, numGrids; + int gridSize, numGrids, grid_pbvh; if(!ob) { ccgdm->pbvh= NULL; @@ -2554,13 +2569,17 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) if(!ob->sculpt) return NULL; + grid_pbvh= ccgDM_use_grid_pbvh(ccgdm); + if(ob->sculpt->pbvh) { - /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm - but this can be freed on ccgdm release, this updates the pointers - when the ccgdm gets remade, the assumption is that the topology - does not change. */ - ccgdm_create_grids(dm); - BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); + if(grid_pbvh) { + /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm + but this can be freed on ccgdm release, this updates the pointers + when the ccgdm gets remade, the assumption is that the topology + does not change. */ + ccgdm_create_grids(dm); + BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); + } ccgdm->pbvh = ob->sculpt->pbvh; } @@ -2571,14 +2590,21 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) /* no pbvh exists yet, we need to create one. only in case of multires we build a pbvh over the modified mesh, in other cases the base mesh is being sculpted, so we build a pbvh from that. */ - ccgdm_create_grids(dm); + if(grid_pbvh) { + ccgdm_create_grids(dm); - gridSize = ccgDM_getGridSize(dm); - numGrids = ccgDM_getNumGrids(dm); + gridSize = ccgDM_getGridSize(dm); + numGrids = ccgDM_getNumGrids(dm); - ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); - BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, - numGrids, gridSize, (void**)ccgdm->gridFaces); + ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); + BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, + numGrids, gridSize, (void**)ccgdm->gridFaces); + } else if(ob->type == OB_MESH) { + Mesh *me= ob->data; + ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); + BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert, + me->totface, me->totvert); + } return ccgdm->pbvh; } @@ -3108,7 +3134,7 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) int numFaces = ccgSubSurf_getVertNumFaces(v); float *co; int i; - + edge_sum[0]= edge_sum[1]= edge_sum[2]= 0.0; face_sum[0]= face_sum[1]= face_sum[2]= 0.0; diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c index 376f3fb031f..ba5d4282416 100644 --- a/source/blender/blenkernel/intern/text.c +++ b/source/blender/blenkernel/intern/text.c @@ -1348,9 +1348,19 @@ char *txt_sel_to_buf (Text *text) return buf; } +static void txt_shift_markers(Text *text, int lineno, int count) +{ + TextMarker *marker; + + for (marker=text->markers.first; marker; marker= marker->next) + if (marker->lineno>=lineno) { + marker->lineno+= count; + } +} + void txt_insert_buf(Text *text, const char *in_buffer) { - int i=0, l=0, j, u, len; + int i=0, l=0, j, u, len, lineno= -1, count= 0; TextLine *add; if (!text) return; @@ -1365,7 +1375,7 @@ void txt_insert_buf(Text *text, const char *in_buffer) /* Read the first line (or as close as possible */ while (in_buffer[i] && in_buffer[i]!='\n') { - txt_add_char(text, in_buffer[i]); + txt_add_raw_char(text, in_buffer[i]); i++; } @@ -1375,6 +1385,7 @@ void txt_insert_buf(Text *text, const char *in_buffer) /* Read as many full lines as we can */ len= strlen(in_buffer); + lineno= txt_get_span(text->lines.first, text->curl); while (i<len) { l=0; @@ -1387,14 +1398,25 @@ void txt_insert_buf(Text *text, const char *in_buffer) add= txt_new_linen(in_buffer +(i-l), l); BLI_insertlinkbefore(&text->lines, text->curl, add); i++; + count++; } else { + if(count) { + txt_shift_markers(text, lineno, count); + count= 0; + } + for (j= i-l; j<i && j<(int)strlen(in_buffer); j++) { - txt_add_char(text, in_buffer[j]); + txt_add_raw_char(text, in_buffer[j]); } break; } } - + + if(count) { + txt_shift_markers(text, lineno, count); + count= 0; + } + undoing= u; } @@ -2046,6 +2068,7 @@ void txt_do_redo(Text *text) linep= linep+(text->undo_buf[text->undo_pos]<<8); text->undo_pos++; linep= linep+(text->undo_buf[text->undo_pos]<<16); text->undo_pos++; linep= linep+(text->undo_buf[text->undo_pos]<<24); text->undo_pos++; + (void)linep; break; case UNDO_INDENT: @@ -2375,7 +2398,7 @@ static void txt_convert_tab_to_spaces (Text *text) txt_insert_buf(text, sb); } -int txt_add_char (Text *text, char add) +static int txt_add_char_intern (Text *text, char add, int replace_tabs) { int len, lineno; char *tmp; @@ -2390,7 +2413,7 @@ int txt_add_char (Text *text, char add) } /* insert spaces rather then tabs */ - if (add == '\t' && text->flags & TXT_TABSTOSPACES) { + if (add == '\t' && replace_tabs) { txt_convert_tab_to_spaces(text); return 1; } @@ -2428,6 +2451,16 @@ int txt_add_char (Text *text, char add) return 1; } +int txt_add_char (Text *text, char add) +{ + return txt_add_char_intern(text, add, text->flags & TXT_TABSTOSPACES); +} + +int txt_add_raw_char (Text *text, char add) +{ + return txt_add_char_intern(text, add, 0); +} + void txt_delete_selected(Text *text) { txt_delete_sel(text); @@ -2595,7 +2628,7 @@ void comment(Text *text) if (!text) return; if (!text->curl) return; - if (!text->sell) return;// Need to change this need to check if only one line is selected ot more then one + if (!text->sell) return;// Need to change this need to check if only one line is selected to more then one num = 0; while (TRUE) @@ -2719,11 +2752,12 @@ int setcurr_tab_spaces (Text *text, int space) int a, indent = 0; for(a=0; (a < text->curc) && (text->curl->line[a] != '\0'); a++) { - if (text->curl->line[a]=='#') { + char ch= text->curl->line[a]; + if (ch=='#') { break; - } else if (text->curl->line[a]==':') { + } else if (ch==':') { indent = 1; - } else if (text->curl->line[a]==']') { + } else if (ch==']' || ch=='}' || ch=='"' || ch=='\'') { indent = 0; } } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index a5412c6269e..9cd07de31dc 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -41,9 +41,8 @@ #include "MEM_guardedalloc.h" -#include "PIL_dynlib.h" - #include "BLI_blenlib.h" +#include "BLI_dynlib.h" #include "BLI_math.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" @@ -73,7 +72,7 @@ #include "BKE_icons.h" #include "BKE_node.h" #include "BKE_animsys.h" - +#include "BKE_colortools.h" /* ------------------------------------------------------------------------- */ @@ -82,7 +81,7 @@ int test_dlerr(const char *name, const char *symbol) { char *err; - err= PIL_dynlib_get_error_as_string(NULL); + err= BLI_dynlib_get_error_as_string(NULL); if(err) { printf("var1: %s, var2: %s, var3: %s\n", name, symbol, err); return 1; @@ -108,19 +107,19 @@ void open_plugin_tex(PluginTex *pit) pit->instance_init= NULL; /* clear the error list */ - PIL_dynlib_get_error_as_string(NULL); + BLI_dynlib_get_error_as_string(NULL); - /* no PIL_dynlib_close! multiple opened plugins... */ - /* if(pit->handle) PIL_dynlib_close(pit->handle); */ + /* no BLI_dynlib_close! multiple opened plugins... */ + /* if(pit->handle) BLI_dynlib_close(pit->handle); */ /* pit->handle= 0; */ /* open the needed object */ - pit->handle= PIL_dynlib_open(pit->name); + pit->handle= BLI_dynlib_open(pit->name); if(test_dlerr(pit->name, pit->name)) return; if (pit->handle != NULL) { /* find the address of the version function */ - version= (int (*)(void)) PIL_dynlib_find_symbol(pit->handle, "plugin_tex_getversion"); + version= (int (*)(void)) BLI_dynlib_find_symbol(pit->handle, "plugin_tex_getversion"); if (test_dlerr(pit->name, "plugin_tex_getversion")) return; if (version != NULL) { @@ -129,7 +128,7 @@ void open_plugin_tex(PluginTex *pit) int (*info_func)(PluginInfo *); PluginInfo *info= (PluginInfo*) MEM_mallocN(sizeof(PluginInfo), "plugin_info"); - info_func= (int (*)(PluginInfo *))PIL_dynlib_find_symbol(pit->handle, "plugin_getinfo"); + info_func= (int (*)(PluginInfo *))BLI_dynlib_find_symbol(pit->handle, "plugin_getinfo"); if (!test_dlerr(pit->name, "plugin_getinfo")) { info->instance_init = NULL; @@ -200,7 +199,7 @@ void free_plugin_tex(PluginTex *pit) { if(pit==NULL) return; - /* no PIL_dynlib_close: same plugin can be opened multiple times, 1 handle */ + /* no BLI_dynlib_close: same plugin can be opened multiple times, 1 handle */ MEM_freeN(pit); } @@ -762,9 +761,8 @@ Tex *copy_texture(Tex *tex) if(texn->coba) texn->coba= MEM_dupallocN(texn->coba); if(texn->env) texn->env= BKE_copy_envmap(texn->env); - if(texn->pd) texn->pd= MEM_dupallocN(texn->pd); + if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd); if(texn->vd) texn->vd= MEM_dupallocN(texn->vd); - if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview); if(tex->nodetree) { @@ -795,14 +793,7 @@ Tex *localize_texture(Tex *tex) texn->env= BKE_copy_envmap(texn->env); id_us_min(&texn->env->ima->id); } - if(texn->pd) { - texn->pd= MEM_dupallocN(texn->pd); - if(texn->pd->coba) { - texn->pd->point_tree = NULL; - texn->pd->coba= MEM_dupallocN(texn->pd->coba); - } - - } + if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd); if(texn->vd) { texn->vd= MEM_dupallocN(texn->vd); if(texn->vd->dataset) @@ -843,13 +834,13 @@ void make_local_texture(Tex *tex) if(tex->ima) { tex->ima->id.lib= NULL; tex->ima->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)tex->ima, NULL); + new_id(&bmain->image, (ID *)tex->ima, NULL); } if(tex->id.us==1) { tex->id.lib= NULL; tex->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)tex, NULL); + new_id(&bmain->tex, (ID *)tex, NULL); return; } @@ -906,7 +897,7 @@ void make_local_texture(Tex *tex) if(local && lib==0) { tex->id.lib= NULL; tex->id.flag= LIB_LOCAL; - new_id(NULL, (ID *)tex, NULL); + new_id(&bmain->tex, (ID *)tex, NULL); } else if(local && lib) { texn= copy_texture(tex); @@ -1367,6 +1358,13 @@ PointDensity *BKE_add_pointdensity(void) pd->object = NULL; pd->psys = 0; pd->psys_cache_space= TEX_PD_WORLDSPACE; + pd->falloff_curve = curvemapping_add(1, 0, 0, 1, 1); + + pd->falloff_curve->preset = CURVE_PRESET_LINE; + pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE; + curvemap_reset(pd->falloff_curve->cm, &pd->falloff_curve->clipr, pd->falloff_curve->preset, CURVEMAP_SLOPE_POSITIVE); + curvemapping_changed(pd->falloff_curve, 0); + return pd; } @@ -1378,7 +1376,7 @@ PointDensity *BKE_copy_pointdensity(PointDensity *pd) pdn->point_tree = NULL; pdn->point_data = NULL; if(pdn->coba) pdn->coba= MEM_dupallocN(pdn->coba); - + pdn->falloff_curve = curvemapping_copy(pdn->falloff_curve); /* can be NULL */ return pdn; } @@ -1396,6 +1394,8 @@ void BKE_free_pointdensitydata(PointDensity *pd) MEM_freeN(pd->coba); pd->coba = NULL; } + + curvemapping_free(pd->falloff_curve); /* can be NULL */ } void BKE_free_pointdensity(PointDensity *pd) diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c index 37e604fa0cb..b89e576a562 100644 --- a/source/blender/blenkernel/intern/unit.c +++ b/source/blender/blenkernel/intern/unit.c @@ -95,7 +95,7 @@ typedef struct bUnitDef { /* define a single unit */ typedef struct bUnitCollection { struct bUnitDef *units; - int base_unit; /* basic unit index (when user desn't specify unit explicitly) */ + int base_unit; /* basic unit index (when user doesn't specify unit explicitly) */ int flag; /* options for this system */ int length; /* to quickly find the last item */ } bUnitCollection; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index ff58e8bd0a4..7a76e61c17b 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -43,6 +43,8 @@ #include "DNA_scene_types.h" #include "DNA_texture_types.h" +#include "BLI_utildefines.h" + #include "BKE_world.h" #include "BKE_library.h" #include "BKE_animsys.h" @@ -134,7 +136,6 @@ void make_local_world(World *wrld) { Main *bmain= G.main; Scene *sce; - World *wrldn; int local=0, lib=0; /* - only lib users: do nothing @@ -150,34 +151,30 @@ void make_local_world(World *wrld) return; } - sce= bmain->scene.first; - while(sce) { - if(sce->world==wrld) { + for(sce= bmain->scene.first; sce && ELEM(0, lib, local); sce= sce->id.next) { + if(sce->world == wrld) { if(sce->id.lib) lib= 1; else local= 1; } - sce= sce->id.next; } - + if(local && lib==0) { wrld->id.lib= NULL; wrld->id.flag= LIB_LOCAL; new_id(NULL, (ID *)wrld, NULL); } else if(local && lib) { - wrldn= copy_world(wrld); + World *wrldn= copy_world(wrld); wrldn->id.us= 0; - sce= bmain->scene.first; - while(sce) { - if(sce->world==wrld) { + for(sce= bmain->scene.first; sce; sce= sce->id.next) { + if(sce->world == wrld) { if(sce->id.lib==NULL) { sce->world= wrldn; wrldn->id.us++; wrld->id.us--; } } - sce= sce->id.next; } } } diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index 73e23bd2a05..ba7f9bdd415 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -158,7 +158,7 @@ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportL avi = MEM_mallocN (sizeof(AviMovie), "avimovie"); /* RPW 11-21-2002 - if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB; + if (rd->imtype != AVI_FORMAT_MJPEG) format = AVI_FORMAT_AVI_RGB; */ if (rd->imtype != R_AVIJPEG ) format = AVI_FORMAT_AVI_RGB; else format = AVI_FORMAT_MJPEG; |