Cleanup: spaces around operators in DNA headers
[blender.git] / source / blender / makesdna / DNA_particle_types.h
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) 2007 by Janne Karhu.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup DNA
22  */
23
24 #ifndef __DNA_PARTICLE_TYPES_H__
25 #define __DNA_PARTICLE_TYPES_H__
26
27 #include "DNA_defs.h"
28 #include "DNA_ID.h"
29 #include "DNA_boid_types.h"
30
31 struct AnimData;
32
33 typedef struct HairKey {
34         /** Location of hair vertex. */
35         float co[3];
36         /** Time along hair, default 0-100. */
37         float time;
38         /** Softbody weight. */
39         float weight;
40         /** Saved particled edit mode flags. */
41         short editflag;
42         char _pad[2];
43         float world_co[3];
44 } HairKey;
45
46 typedef struct ParticleKey {    /* when changed update size of struct to copy_particleKey()!! */
47         /** Location. */
48         float co[3];
49         /** Velocity. */
50         float vel[3];
51         /** Rotation quaternion. */
52         float rot[4];
53         /** Angular velocity. */
54         float ave[3];
55         /** When this key happens. */
56         float time;
57 } ParticleKey;
58
59 typedef struct BoidParticle {
60         struct Object *ground;
61         struct BoidData data;
62         float gravity[3];
63         float wander[3];
64         float rt;
65 } BoidParticle;
66
67 typedef struct ParticleSpring {
68         float rest_length;
69         unsigned int particle_index[2], delete_flag;
70 } ParticleSpring;
71
72 /* Child particles are created around or between parent particles */
73 typedef struct ChildParticle {
74         /** Num is face index on the final derived mesh. */
75         int num, parent;
76         /** Nearest particles to the child, used for the interpolation. */
77         int pa[4];
78         /** Interpolation weights for the above particles. */
79         float w[4];
80         /** Face vertex weights and offset. */
81         float fuv[4], foffset;
82         float rt;
83 } ChildParticle;
84
85 typedef struct ParticleTarget {
86         struct ParticleTarget *next, *prev;
87         struct Object *ob;
88         int psys;
89         short flag, mode;
90         float time, duration;
91 } ParticleTarget;
92
93 typedef struct ParticleDupliWeight {
94         struct ParticleDupliWeight *next, *prev;
95         struct Object *ob;
96         short count;
97         short flag;
98         /** Only updated on file save and used on file load. */
99         short index, rt;
100 } ParticleDupliWeight;
101
102 typedef struct ParticleData {
103         /** Current global coordinates. */
104         ParticleKey state;
105
106         /** Previous state. */
107         ParticleKey prev_state;
108
109         /** Hair vertices. */
110         HairKey *hair;
111
112         /** Keyed keys. */
113         ParticleKey *keys;
114
115         /** Boids data. */
116         BoidParticle *boid;
117
118         /** Amount of hair or keyed key.s*/
119         int totkey;
120
121         /** Dietime is not necessarily time+lifetime as. */
122         float time, lifetime;
123         /** Particles can die unnaturally (collision). */
124         float dietime;
125
126         /**
127          * WARNING! Those two indices,
128          * when not affected to vertices, are for !!! TESSELLATED FACES !!!, not POLYGONS!
129          */
130         /** Index to vert/edge/face. */
131         int num;
132         /** Index to derived mesh data (face) to avoid slow lookups. */
133         int num_dmcache;
134
135         /** Coordinates on face/edge number "num" and depth alon.g*/
136         float fuv[4], foffset;
137                                                         /* face normal for volume emission. */
138
139         /** Size and multiplier so that we can update size when ever. */
140         float size;
141
142         /** Density of sph particle. */
143         float sphdensity;
144         char _pad[4];
145
146         int hair_index;
147         short flag;
148         /** The life state of a particle. */
149         short alive;
150 } ParticleData;
151
152 typedef struct SPHFluidSettings {
153         /*Particle Fluid*/
154         float radius, spring_k, rest_length;
155         float plasticity_constant, yield_ratio;
156         float plasticity_balance, yield_balance;
157         float viscosity_omega, viscosity_beta;
158         float stiffness_k, stiffness_knear, rest_density;
159         float buoyancy;
160         int flag, spring_frames;
161         short solver;
162         char _pad[6];
163 } SPHFluidSettings;
164
165 /* fluid->flag */
166 #define SPH_VISCOELASTIC_SPRINGS        1
167 #define SPH_CURRENT_REST_LENGTH         2
168 #define SPH_FAC_REPULSION                       4
169 #define SPH_FAC_DENSITY                         8
170 #define SPH_FAC_RADIUS                          16
171 #define SPH_FAC_VISCOSITY                       32
172 #define SPH_FAC_REST_LENGTH                     64
173
174 /* fluid->solver (numerical ID field, not bitfield) */
175 #define SPH_SOLVER_DDR                                  0
176 #define SPH_SOLVER_CLASSICAL                    1
177
178 typedef struct ParticleSettings {
179         ID id;
180         struct AnimData *adt;
181
182         struct BoidSettings *boids;
183         struct SPHFluidSettings *fluid;
184
185         struct EffectorWeights *effector_weights;
186         struct Collection *collision_group;
187
188         int flag, rt;
189         short type, from, distr, texact;
190         /* physics modes */
191         short phystype, rotmode, avemode, reactevent;
192         int draw;
193         float draw_size;
194         short draw_as, childtype;
195         char _pad2[4];
196         short ren_as, subframes, draw_col;
197         /* number of path segments, power of 2 except */
198         short draw_step, ren_step;
199         short hair_step, keys_step;
200
201         /* adaptive path rendering */
202         short adapt_angle, adapt_pix;
203
204         short disp, omat, interpolation, integrator;
205         short rotfrom DNA_DEPRECATED;
206         short kink, kink_axis;
207
208         /* billboards */
209         short bb_align, bb_uv_split, bb_anim, bb_split_offset DNA_DEPRECATED;
210         float bb_tilt, bb_rand_tilt, bb_offset[2], bb_size[2], bb_vel_head, bb_vel_tail DNA_DEPRECATED;
211
212         /* draw color */
213         float color_vec_max;
214
215         /* time and emission */
216         float sta, end, lifetime, randlife;
217         float timetweak, courant_target;
218         float jitfac, eff_hair, grid_rand, ps_offset[1];
219         int totpart, userjit, grid_res, effector_amount;
220         short time_flag;
221         char _pad0[6];
222
223         /* initial velocity factors */
224         float normfac, obfac, randfac, partfac, tanfac, tanphase, reactfac;
225         float ob_vel[3];
226         float avefac, phasefac, randrotfac, randphasefac;
227         /* physical properties */
228         float mass, size, randsize;
229         /* global physical properties */
230         float acc[3], dragfac, brownfac, dampfac;
231         /* length */
232         float randlength;
233         /* children */
234         int child_flag;
235         char _pad3[4];
236         int child_nbr, ren_child_nbr;
237         float parents, childsize, childrandsize;
238         float childrad, childflat;
239         /* clumping */
240         float clumpfac, clumppow;
241         /* kink */
242         float kink_amp, kink_freq, kink_shape, kink_flat;
243         float kink_amp_clump;
244         int kink_extra_steps;
245         char _pad4[4];
246         float kink_axis_random, kink_amp_random;
247         /* rough */
248         float rough1, rough1_size;
249         float rough2, rough2_size, rough2_thres;
250         float rough_end, rough_end_shape;
251         /* length */
252         float clength, clength_thres;
253         /* parting */
254         float parting_fac;
255         float parting_min, parting_max;
256         /* branching */
257         float branch_thres;
258         /* drawing stuff */
259         float draw_line[2];
260         float path_start, path_end;
261         int trail_count;
262         /* keyed particles */
263         int keyed_loops;
264         struct CurveMapping *clumpcurve;
265         struct CurveMapping *roughcurve;
266         float clump_noise_size;
267
268         /* hair dynamics */
269         float bending_random;
270
271         /** MAX_MTEX. */
272         struct MTex *mtex[18];
273
274         struct Collection *instance_collection;
275         struct ListBase instance_weights;
276         struct Collection *eff_group  DNA_DEPRECATED;           // deprecated
277         struct Object *instance_object;
278         struct Object *bb_ob;
279         /** Old animation system, deprecated for 2.5. */
280         struct Ipo *ipo  DNA_DEPRECATED;
281         struct PartDeflect *pd;
282         struct PartDeflect *pd2;
283
284         /* modified dm support */
285         short use_modifier_stack;
286         char _pad5[2];
287
288         /* hair shape */
289         short shape_flag;
290         char _pad6[2];
291
292         float twist;
293         char _pad8[4];
294
295         /* hair thickness shape */
296         float shape;
297         float rad_root, rad_tip, rad_scale;
298
299         struct CurveMapping *twistcurve;
300         void *_pad7;
301 } ParticleSettings;
302
303 typedef struct ParticleSystem {
304         /* note1: make sure all (runtime) are NULL's in 'copy_particlesystem' XXX,
305          * this function is no more! - need to invstigate */
306
307         /* note2: make sure any uses of this struct in DNA are
308          * accounted for in 'BKE_object_copy_particlesystems' */
309
310         struct ParticleSystem *next, *prev;
311
312         /** Particle settings. */
313         ParticleSettings *part;
314
315         /** (parent) particles. */
316         ParticleData *particles;
317         /** Child particles. */
318         ChildParticle *child;
319
320         /** Particle editmode (runtime). */
321         struct PTCacheEdit *edit;
322         /** Free callback. */
323         void (*free_edit)(struct PTCacheEdit *edit);
324
325         /** Path cache (runtime). */
326         struct ParticleCacheKey **pathcache;
327         /** Child cache (runtime). */
328         struct ParticleCacheKey **childcache;
329         /** Buffers for the above. */
330         ListBase pathcachebufs, childcachebufs;
331
332         /** Cloth simulation for hair. */
333         struct ClothModifierData *clmd;
334         /** Input/output for cloth simulation. */
335         struct Mesh *hair_in_mesh, *hair_out_mesh;
336
337         struct Object *target_ob;
338
339         /** Run-time only lattice deformation data. */
340         struct LatticeDeformData *lattice_deform_data;
341
342         /** Particles from global space -> parent space. */
343         struct Object *parent;
344
345         /** Used for keyed and boid physics. */
346         struct ListBase targets;
347
348         /** Particle system name, MAX_NAME. */
349         char name[64];
350
351         /** Used for instancing. */
352         float imat[4][4];
353         float cfra, tree_frame, bvhtree_frame;
354         int seed, child_seed;
355         int flag, totpart, totunexist, totchild, totcached, totchildcache;
356         /* NOTE: Recalc is one of ID_RECALC_PSYS_ALL flags.
357          *
358          * TODO(sergey): Use part->id.recalc instead of this duplicated flag
359          * somehow. */
360         int recalc;
361         short target_psys, totkeyed, bakespace;
362         char _pad1[6];
363
364         /** Billboard uv name, MAX_CUSTOMDATA_LAYER_NAME. */
365         char bb_uvname[3][64] DNA_DEPRECATED;
366
367         /* if you change these remember to update array lengths to PSYS_TOT_VG! */
368         /** Vertex groups, 0==disable, 1==starting index. */
369         short vgroup[13], vg_neg, rt3;
370         char _pad[6];
371
372         /* point cache */
373         struct PointCache *pointcache;
374         struct ListBase ptcaches;
375
376         struct ListBase *effectors;
377
378         ParticleSpring *fluid_springs;
379         int tot_fluidsprings, alloc_fluidsprings;
380
381         /** Used for interactions with self and other systems. */
382         struct KDTree *tree;
383         /** Used for interactions with self and other systems. */
384         struct BVHTree *bvhtree;
385
386         struct ParticleDrawData *pdd;
387
388         /** Current time step, as a fraction of a frame. */
389         float dt_frac;
390         /** Influence of the lattice modifier. */
391         float lattice_strength;
392
393         void *batch_cache;
394
395         /* Set by dependency graph's copy-on-write, allows to quickly go
396          * from evaluated particle system to original one.
397          *
398          * Original system will have this set to NULL.
399          *
400          * Use psys_orig_get() function to access,
401          */
402         struct ParticleSystem *orig_psys;
403 } ParticleSystem;
404
405 typedef enum eParticleDrawFlag {
406         PART_DRAW_VEL           = (1 << 0),
407         PART_DRAW_GLOBAL_OB         = (1 << 1),
408         PART_DRAW_SIZE          = (1 << 2),
409 #ifdef DNA_DEPRECATED
410         PART_DRAW_EMITTER       = (1 << 3),  /* render emitter also */ /* DEPRECATED */
411 #endif
412         PART_DRAW_HEALTH        = (1 << 4),
413         PART_ABS_PATH_TIME      = (1 << 5),
414         PART_DRAW_COUNT_GR      = (1 << 6),
415         PART_DRAW_BB_LOCK       = (1 << 7), /* used with billboards */ /* DEPRECATED */
416         PART_DRAW_ROTATE_OB     = (1 << 7), /* used with instance object/collection */
417         PART_DRAW_PARENT        = (1 << 8),
418         PART_DRAW_NUM           = (1 << 9),
419         PART_DRAW_RAND_GR       = (1 << 10),
420         PART_DRAW_REN_ADAPT     = (1 << 11),
421         PART_DRAW_VEL_LENGTH    = (1 << 12),
422         PART_DRAW_MAT_COL       = (1 << 13), /* deprecated, but used in do_versions */
423         PART_DRAW_WHOLE_GR      = (1 << 14),
424         PART_DRAW_REN_STRAND    = (1 << 15),
425         PART_DRAW_NO_SCALE_OB   = (1 << 16), /* used with instance object/collection */
426         PART_DRAW_GUIDE_HAIRS   = (1 << 17),
427         PART_DRAW_HAIR_GRID     = (1 << 18),
428 } eParticleDrawFlag;
429
430 /* part->type */
431 /* hair is always baked static in object/geometry space */
432 /* other types (normal particles) are in global space and not static baked */
433 #define PART_EMITTER            0
434 //#define PART_REACTOR          1
435 #define PART_HAIR                       2
436 #define PART_FLUID                      3
437
438 /* part->flag */
439 #define PART_REACT_STA_END      1
440 #define PART_REACT_MULTIPLE     2
441
442 //#define PART_LOOP                     4       /* not used anymore */
443                 /* for dopesheet */
444 #define PART_DS_EXPAND          8
445
446 #define PART_HAIR_REGROW        16      /* regrow hair for each frame */
447
448 #define PART_UNBORN                     32      /*show unborn particles*/
449 #define PART_DIED                       64      /*show died particles*/
450
451 #define PART_TRAND                      128
452 #define PART_EDISTR                     256     /* particle/face from face areas */
453
454 #define PART_ROTATIONS          512     /* calculate particle rotations (and store them in pointcache) */
455 #define PART_DIE_ON_COL         (1 << 12)
456 #define PART_SIZE_DEFL          (1 << 13) /* swept sphere deflections */
457 #define PART_ROT_DYN            (1 << 14)       /* dynamic rotation */
458 #define PART_SIZEMASS           (1 << 16)
459
460 #define PART_HIDE_ADVANCED_HAIR (1 << 15)
461
462 //#define PART_ABS_TIME         (1 << 17)
463 //#define PART_GLOB_TIME                (1 << 18)
464
465 #define PART_BOIDS_2D           (1 << 19)
466
467 //#define PART_BRANCHING                (1 << 20)
468 //#define PART_ANIM_BRANCHING   (1 << 21)
469
470 #define PART_HAIR_BSPLINE       1024
471
472 #define PART_GRID_HEXAGONAL     (1 << 24)
473 #define PART_GRID_INVERT        (1 << 26)
474
475 #define PART_CHILD_EFFECT               (1 << 27)
476 #define PART_CHILD_LONG_HAIR    (1 << 28)
477 /* #define PART_CHILD_RENDER            (1 << 29) */ /*UNUSED*/
478 #define PART_CHILD_GUIDE                (1 << 30)
479
480 #define PART_SELF_EFFECT        (1 << 22)
481
482 /* part->from */
483 #define PART_FROM_VERT          0
484 #define PART_FROM_FACE          1
485 #define PART_FROM_VOLUME        2
486 /* #define PART_FROM_PARTICLE   3  deprecated! */
487 #define PART_FROM_CHILD         4
488
489 /* part->distr */
490 #define PART_DISTR_JIT          0
491 #define PART_DISTR_RAND         1
492 #define PART_DISTR_GRID         2
493
494 /* part->phystype */
495 #define PART_PHYS_NO            0
496 #define PART_PHYS_NEWTON        1
497 #define PART_PHYS_KEYED         2
498 #define PART_PHYS_BOIDS         3
499 #define PART_PHYS_FLUID         4
500
501 /* part->kink */
502 typedef enum eParticleKink {
503         PART_KINK_NO            = 0,
504         PART_KINK_CURL          = 1,
505         PART_KINK_RADIAL        = 2,
506         PART_KINK_WAVE          = 3,
507         PART_KINK_BRAID         = 4,
508         PART_KINK_SPIRAL        = 5,
509 } eParticleKink;
510
511 /* part->child_flag */
512 typedef enum eParticleChildFlag {
513         PART_CHILD_USE_CLUMP_NOISE  = (1 << 0),
514         PART_CHILD_USE_CLUMP_CURVE  = (1 << 1),
515         PART_CHILD_USE_ROUGH_CURVE  = (1 << 2),
516         PART_CHILD_USE_TWIST_CURVE  = (1 << 3),
517 } eParticleChildFlag;
518
519 /* part->shape_flag */
520 typedef enum eParticleShapeFlag {
521         PART_SHAPE_CLOSE_TIP     = (1 << 0),
522 } eParticleShapeFlag;
523
524 /* part->draw_col */
525 #define PART_DRAW_COL_NONE              0
526 #define PART_DRAW_COL_MAT               1
527 #define PART_DRAW_COL_VEL               2
528 #define PART_DRAW_COL_ACC               3
529
530 /* part->time_flag */
531 #define PART_TIME_AUTOSF        1 /* Automatic subframes */
532
533 /* part->draw_as */
534 /* part->ren_as*/
535 #define PART_DRAW_NOT           0
536 #define PART_DRAW_DOT           1
537 #define PART_DRAW_HALO          1
538 #define PART_DRAW_CIRC          2
539 #define PART_DRAW_CROSS         3
540 #define PART_DRAW_AXIS          4
541 #define PART_DRAW_LINE          5
542 #define PART_DRAW_PATH          6
543 #define PART_DRAW_OB            7
544 #define PART_DRAW_GR            8
545 #define PART_DRAW_BB            9 /* deprecated */
546 #define PART_DRAW_REND          10
547
548 /* part->integrator */
549 #define PART_INT_EULER          0
550 #define PART_INT_MIDPOINT       1
551 #define PART_INT_RK4            2
552 #define PART_INT_VERLET         3
553
554 /* part->rotmode */
555 #define PART_ROT_NOR            1
556 #define PART_ROT_VEL            2
557 #define PART_ROT_GLOB_X         3
558 #define PART_ROT_GLOB_Y         4
559 #define PART_ROT_GLOB_Z         5
560 #define PART_ROT_OB_X           6
561 #define PART_ROT_OB_Y           7
562 #define PART_ROT_OB_Z           8
563 #define PART_ROT_NOR_TAN        9
564
565 /* part->avemode */
566 #define PART_AVE_VELOCITY       1
567 #define PART_AVE_RAND           2
568 #define PART_AVE_HORIZONTAL     3
569 #define PART_AVE_VERTICAL       4
570 #define PART_AVE_GLOBAL_X       5
571 #define PART_AVE_GLOBAL_Y       6
572 #define PART_AVE_GLOBAL_Z       7
573
574 /* part->reactevent */
575 #define PART_EVENT_DEATH        0
576 #define PART_EVENT_COLLIDE      1
577 #define PART_EVENT_NEAR         2
578
579 /* part->childtype */
580 #define PART_CHILD_PARTICLES    1
581 #define PART_CHILD_FACES                2
582
583 /* psys->flag */
584 #define PSYS_CURRENT            1
585 #define PSYS_GLOBAL_HAIR        2
586 #define PSYS_HAIR_DYNAMICS      4
587 #define PSYS_KEYED_TIMING       8
588 //#define PSYS_ENABLED          16      /* deprecated */
589 #define PSYS_HAIR_UPDATED       32  /* signal for updating hair particle mode */
590 /* #define PSYS_DRAWING         64 */ /* deprecated */
591 /* #define PSYS_USE_IMAT                128 */ /* deprecated */
592 #define PSYS_DELETE                     256     /* remove particlesystem as soon as possible */
593 #define PSYS_HAIR_DONE          512
594 #define PSYS_KEYED                      1024
595 #define PSYS_EDITED                     2048
596 //#define PSYS_PROTECT_CACHE    4096 /* deprecated */
597 #define PSYS_DISABLED                   8192
598 #define PSYS_OB_ANIM_RESTORE    16384 /* runtime flag */
599 #define PSYS_SHARED_CACHES              32768
600
601 /* pars->flag */
602 #define PARS_UNEXIST            1
603 #define PARS_NO_DISP            2
604 //#define PARS_STICKY                   4 /* deprecated */
605 #define PARS_REKEY                      8
606
607 /* pars->alive */
608 //#define PARS_KILLED                   0 /* deprecated */
609 #define PARS_DEAD                       1
610 #define PARS_UNBORN                     2
611 #define PARS_ALIVE                      3
612 #define PARS_DYING                      4
613
614 /* ParticleDupliWeight->flag */
615 #define PART_DUPLIW_CURRENT     1
616
617 /* psys->vg */
618 #define PSYS_TOT_VG                     13
619
620 #define PSYS_VG_DENSITY         0
621 #define PSYS_VG_VEL                     1
622 #define PSYS_VG_LENGTH          2
623 #define PSYS_VG_CLUMP           3
624 #define PSYS_VG_KINK            4
625 #define PSYS_VG_ROUGH1          5
626 #define PSYS_VG_ROUGH2          6
627 #define PSYS_VG_ROUGHE          7
628 #define PSYS_VG_SIZE            8
629 #define PSYS_VG_TAN                     9
630 #define PSYS_VG_ROT                     10
631 #define PSYS_VG_EFFECTOR        11
632 #define PSYS_VG_TWIST   12
633
634 /* ParticleTarget->flag */
635 #define PTARGET_CURRENT         1
636 #define PTARGET_VALID           2
637
638 /* ParticleTarget->mode */
639 #define PTARGET_MODE_NEUTRAL    0
640 #define PTARGET_MODE_FRIEND             1
641 #define PTARGET_MODE_ENEMY              2
642
643 /* mapto */
644 typedef enum eParticleTextureInfluence {
645         /* init */
646         PAMAP_TIME              = (1 << 0),     /* emission time */
647         PAMAP_LIFE              = (1 << 1),     /* life time */
648         PAMAP_DENS              = (1 << 2),     /* density */
649         PAMAP_SIZE              = (1 << 3),     /* physical size */
650         PAMAP_INIT              = (PAMAP_TIME | PAMAP_LIFE | PAMAP_DENS | PAMAP_SIZE),
651         /* reset */
652         PAMAP_IVEL              = (1 << 5),     /* initial velocity */
653         /* physics */
654         PAMAP_FIELD             = (1 << 6),     /* force fields */
655         PAMAP_GRAVITY   = (1 << 10),
656         PAMAP_DAMP              = (1 << 11),
657         PAMAP_PHYSICS   = (PAMAP_FIELD | PAMAP_GRAVITY | PAMAP_DAMP),
658         /* children */
659         PAMAP_CLUMP             = (1 << 7),
660         PAMAP_KINK_FREQ = (1 << 8),
661         PAMAP_KINK_AMP  = (1 << 12),
662         PAMAP_ROUGH             = (1 << 9),
663         PAMAP_LENGTH    = (1 << 4),
664         PAMAP_TWIST     = (1 << 13),
665         PAMAP_CHILD             = (PAMAP_CLUMP | PAMAP_KINK_FREQ | PAMAP_KINK_AMP | PAMAP_ROUGH | PAMAP_LENGTH | PAMAP_TWIST),
666 } eParticleTextureInfluence;
667
668 #endif