Blender  V2.93
transform_convert_particle.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include "DNA_modifier_types.h"
25 #include "DNA_particle_types.h"
26 
27 #include "MEM_guardedalloc.h"
28 
29 #include "BLI_math.h"
30 
31 #include "BKE_context.h"
32 #include "BKE_particle.h"
33 #include "BKE_pointcache.h"
34 
35 #include "ED_particle.h"
36 
37 #include "transform.h"
38 #include "transform_snap.h"
39 
40 /* Own include. */
41 #include "transform_convert.h"
42 
43 /* -------------------------------------------------------------------- */
48 {
50 
51  TransData *td = NULL;
53  Object *ob = OBACT(t->view_layer);
54  ParticleEditSettings *pset = PE_settings(t->scene);
55  PTCacheEdit *edit = PE_get_current(t->depsgraph, t->scene, ob);
56  ParticleSystem *psys = NULL;
57  PTCacheEditPoint *point;
58  PTCacheEditKey *key;
59  float mat[4][4];
60  int i, k, transformparticle;
61  int count = 0, hasselected = 0;
62  const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
63 
64  if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) {
65  return;
66  }
67 
68  psys = edit->psys;
69 
70  for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
71  point->flag &= ~PEP_TRANSFORM;
72  transformparticle = 0;
73 
74  if ((point->flag & PEP_HIDE) == 0) {
75  for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
76  if ((key->flag & PEK_HIDE) == 0) {
77  if (key->flag & PEK_SELECT) {
78  hasselected = 1;
79  transformparticle = 1;
80  }
81  else if (is_prop_edit) {
82  transformparticle = 1;
83  }
84  }
85  }
86  }
87 
88  if (transformparticle) {
89  count += point->totkey;
90  point->flag |= PEP_TRANSFORM;
91  }
92  }
93 
94  /* note: in prop mode we need at least 1 selected */
95  if (hasselected == 0) {
96  return;
97  }
98 
99  tc->data_len = count;
100  td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
101 
102  if (t->mode == TFM_BAKE_TIME) {
103  tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension),
104  "Particle_TransExtension");
105  }
106  else {
107  tx = tc->data_ext = NULL;
108  }
109 
110  unit_m4(mat);
111 
112  invert_m4_m4(ob->imat, ob->obmat);
113 
114  for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
115  TransData *head, *tail;
116  head = tail = td;
117 
118  if (!(point->flag & PEP_TRANSFORM)) {
119  continue;
120  }
121 
122  if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
123  ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
125  ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat);
126  }
127 
128  for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
129  if (key->flag & PEK_USE_WCO) {
130  copy_v3_v3(key->world_co, key->co);
131  mul_m4_v3(mat, key->world_co);
132  td->loc = key->world_co;
133  }
134  else {
135  td->loc = key->co;
136  }
137 
138  copy_v3_v3(td->iloc, td->loc);
139  copy_v3_v3(td->center, td->loc);
140 
141  if (key->flag & PEK_SELECT) {
142  td->flag |= TD_SELECTED;
143  }
144  else if (!is_prop_edit) {
145  td->flag |= TD_SKIP;
146  }
147 
148  unit_m3(td->mtx);
149  unit_m3(td->smtx);
150 
151  /* don't allow moving roots */
152  if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR))) {
153  td->protectflag |= OB_LOCK_LOC;
154  }
155 
156  td->ob = ob;
157  td->ext = tx;
158  if (t->mode == TFM_BAKE_TIME) {
159  td->val = key->time;
160  td->ival = *(key->time);
161  /* abuse size and quat for min/max values */
162  td->flag |= TD_NO_EXT;
163  if (k == 0) {
164  tx->size = NULL;
165  }
166  else {
167  tx->size = (key - 1)->time;
168  }
169 
170  if (k == point->totkey - 1) {
171  tx->quat = NULL;
172  }
173  else {
174  tx->quat = (key + 1)->time;
175  }
176  }
177 
178  td++;
179  if (tx) {
180  tx++;
181  }
182  tail++;
183  }
184  if (is_prop_edit && head != tail) {
185  calc_distanceCurveVerts(head, tail - 1, false);
186  }
187  }
188  }
189 }
190 
193 /* -------------------------------------------------------------------- */
198 {
200  Scene *scene = t->scene;
201  ViewLayer *view_layer = t->view_layer;
202  Object *ob = OBACT(view_layer);
203  PTCacheEdit *edit = PE_get_current(t->depsgraph, scene, ob);
204  ParticleSystem *psys = edit->psys;
205  PTCacheEditPoint *point;
206  PTCacheEditKey *key;
207  TransData *td;
208  float mat[4][4], imat[4][4], co[3];
209  int i, k;
210  const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
211 
212  /* we do transform in world space, so flush world space position
213  * back to particle local space (only for hair particles) */
214  td = tc->data;
215  for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
216  if (!(point->flag & PEP_TRANSFORM)) {
217  continue;
218  }
219 
220  if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
221  ParticleSystemModifierData *psmd_eval = edit->psmd_eval;
223  ob, psmd_eval->mesh_final, psys->part->from, psys->particles + i, mat);
224  invert_m4_m4(imat, mat);
225 
226  for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
227  copy_v3_v3(co, key->world_co);
228  mul_m4_v3(imat, co);
229 
230  /* optimization for proportional edit */
231  if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
232  copy_v3_v3(key->co, co);
233  point->flag |= PEP_EDIT_RECALC;
234  }
235  }
236  }
237  else {
238  point->flag |= PEP_EDIT_RECALC;
239  }
240  }
241 
242  PE_update_object(t->depsgraph, scene, OBACT(view_layer), 1);
245  }
246 }
247 
250 /* -------------------------------------------------------------------- */
255 {
256  if (t->state != TRANS_CANCEL) {
257  applyProject(t);
258  }
260 }
261 
void psys_mat_hair_to_global(struct Object *ob, struct Mesh *mesh, short from, struct ParticleData *pa, float hairmat[4][4])
Definition: particle.c:3909
void BKE_particle_batch_cache_dirty_tag(struct ParticleSystem *psys, int mode)
Definition: particle.c:5243
@ BKE_PARTICLE_BATCH_DIRTY_ALL
Definition: BKE_particle.h:620
#define PEK_HIDE
#define PEP_EDIT_RECALC
#define PEP_TRANSFORM
#define PEP_HIDE
#define PEK_SELECT
#define PEK_USE_WCO
void unit_m3(float m[3][3])
Definition: math_matrix.c:58
void unit_m4(float m[4][4])
Definition: rct.c:1140
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1278
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
MINLINE bool compare_v3v3(const float a[3], const float b[3], const float limit) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
void DEG_id_tag_update(struct ID *id, int flag)
@ ID_RECALC_PSYS_REDO
Definition: DNA_ID.h:618
@ OB_LOCK_LOC
#define PSYS_GLOBAL_HAIR
#define SCE_SELECT_PATH
#define OBACT(_view_layer)
#define PE_LOCK_FIRST
struct ParticleEditSettings * PE_settings(struct Scene *scene)
void PE_update_object(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, int useflag)
struct PTCacheEdit * PE_get_current(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob)
@ TFM_BAKE_TIME
Definition: ED_transform.h:70
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
double time
Scene scene
int count
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
float imat[4][4]
float obmat[4][4]
struct PTCacheEditKey * keys
PTCacheEditPoint * points
struct ParticleSystem * psys
struct ParticleSystemModifierData * psmd_eval
ParticleData * particles
ParticleSettings * part
float smtx[3][3]
short protectflag
float mtx[3][3]
TransDataExtension * ext
float * val
struct Object * ob
@ T_PROP_EDIT
Definition: transform.h:111
@ TRANS_CANCEL
Definition: transform.h:193
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition: transform.h:813
void calc_distanceCurveVerts(TransData *head, TransData *tail, bool cyclic)
conversion and adaptation of different datablocks to a common struct.
void recalcData_particles(TransInfo *t)
static void flushTransParticles(TransInfo *t)
void createTransParticleVerts(TransInfo *t)
@ TD_NO_EXT
@ TD_SELECTED
@ TD_SKIP
void applyProject(TransInfo *t)