Page MenuHome

AMA-05-2.61-beta4.patch

File Metadata

Author
Fabio Russo (ruesp83)
Created
Nov 13 2013, 3:17 PM

AMA-05-2.61-beta4.patch

Index: release/scripts/startup/bl_ui/properties_data_modifier.py
===================================================================
--- release/scripts/startup/bl_ui/properties_data_modifier.py (revisione 43767)
+++ release/scripts/startup/bl_ui/properties_data_modifier.py (copia locale)
@@ -71,51 +71,209 @@
layout.prop(md, "use_multi_modifier")
def ARRAY(self, layout, ob, md):
+ row = layout.row()
+ row.prop(md, "type_array", expand=True)
+
+ if (md.type_array == "PATH"):
+ layout.prop(md, "curve")
+
layout.prop(md, "fit_type")
-
if md.fit_type == 'FIXED_COUNT':
layout.prop(md, "count")
elif md.fit_type == 'FIT_LENGTH':
layout.prop(md, "fit_length")
- elif md.fit_type == 'FIT_CURVE':
- layout.prop(md, "curve")
+ elif md.fit_type == 'FIT_BETWEEN':
+ layout.prop(md, "count", text = "Divider")
layout.separator()
-
split = layout.split()
-
col = split.column()
- col.prop(md, "use_constant_offset")
- sub = col.column()
- sub.active = md.use_constant_offset
- sub.prop(md, "constant_offset_displace", text="")
+ if ((md.type_array != "PATH") or (md.fit_type != 'FIT_BETWEEN')):
+ col.prop(md, "use_constant_offset")
+ sub = col.column()
+ sub.active = md.use_constant_offset
+ sub.prop(md, "constant_offset_displace", text="")
- col.separator()
+ if (md.type_array == "REGULAR"):
+ col.separator()
+ col.prop(md, "use_merge_vertices", text="Merge")
+ sub = col.column()
+ sub.active = md.use_merge_vertices
+ sub.prop(md, "use_merge_vertices_cap", text="First Last")
+ sub.prop(md, "merge_threshold", text="Distance")
+ else:
+ col.separator()
+ col.prop(md, "all_curve")
- col.prop(md, "use_merge_vertices", text="Merge")
- sub = col.column()
- sub.active = md.use_merge_vertices
- sub.prop(md, "use_merge_vertices_cap", text="First Last")
- sub.prop(md, "merge_threshold", text="Distance")
-
col = split.column()
- col.prop(md, "use_relative_offset")
- sub = col.column()
- sub.active = md.use_relative_offset
- sub.prop(md, "relative_offset_displace", text="")
+ if (md.type_array != "PATH") or (md.fit_type != 'FIT_BETWEEN'):
+ col.prop(md, "use_relative_offset")
+ sub = col.column()
+ sub.active = md.use_relative_offset
+ sub.prop(md, "relative_offset_displace", text="")
- col.separator()
+ if (md.type_array == "REGULAR"):
+ col.separator()
+ col.prop(md, "use_object_offset")
+ sub = col.column()
+ sub.active = md.use_object_offset
+ sub.prop(md, "offset_object", text="")
+ layout.separator()
- col.prop(md, "use_object_offset")
- sub = col.column()
- sub.active = md.use_object_offset
- sub.prop(md, "offset_object", text="")
+ layout.prop(md, "start_cap")
+ layout.prop(md, "mid_cap")
+ layout.prop(md, "end_cap")
+ else:
+ col.separator()
+ col.prop(md, "for_segment")
layout.separator()
- layout.prop(md, "start_cap")
- layout.prop(md, "end_cap")
+ if (not md.mid_cap is None):
+ col = layout.column()
+ box = col.box()
+ row = box.row()
+ if md.dis_advanced_mid_cap:
+ row.prop(md, "dis_advanced_mid_cap", text="", icon="DOWNARROW_HLT", emboss=False)
+ else:
+ row.prop(md, "dis_advanced_mid_cap", text="", icon="RIGHTARROW", emboss=False)
+ row.prop(md, "use_advanced_mid_cap", text="Advanced Mid Cap")
+ if (md.dis_advanced_mid_cap):
+ col = box.column()
+ if md.use_advanced_mid_cap:
+ col.active = True
+ else:
+ col.active = False
+ row = col.row()
+ row.prop(md, "dist_mid_cap", expand=True)
+ if md.dist_mid_cap == 'CURVE':
+ col.prop(md, "curve_cap")
+ col.prop(md, "count_mc")
+ if md.dist_mid_cap == 'CURVE':
+ split = col.split()
+ col = split.column()
+ col.active = False if md.start_cap is None else True
+ col.prop(md, "first_start_cap")
+ col = split.column()
+ col.active = False if md.end_cap is None else True
+ col.prop(md, "last_end_cap")
+ col = layout.column()
+ box = col.box()
+ row = box.row()
+ if md.dis_advanced:
+ row.prop(md, "dis_advanced", text="", icon="DOWNARROW_HLT", emboss=False)
+ else:
+ row.prop(md, "dis_advanced", text="", icon="RIGHTARROW", emboss=False)
+ row.prop(md, "use_advanced", text="Randomize Transform")
+ if (md.dis_advanced):
+ col = box.column()
+ if md.use_advanced:
+ col.active = True
+ else:
+ col.active = False
+ row = col.row()
+ row = row.split(percentage=0.9)
+ row.prop(md, "seed_t")
+ row.operator("object.array_rand_seed_t")
+ row = col.row()
+ row.prop(md, "lock_loc", text="Location")
+ row.prop(md, "lock_rot", text="Rotation")
+ row.prop(md, "lock_scale", text="Scale")
+ row = col.row()
+ sub = row.row()
+ sub.active = md.lock_loc
+ sub.column().prop(md, "location_offset", text="")
+ row = row.row()
+ sub = row.row()
+ sub.active = md.lock_rot
+ sub.column().prop(md, "rotation_offset", text="")
+ sub = row.row()
+ sub.active = md.lock_scale
+ if (md.proportion):
+ sub.prop(md, "scale", text="")
+ else:
+ sub.column().prop(md, "scale_offset", text="")
+ row = col.row()
+ row.prop(md, "local_rot", text="Local Rotation")
+ row.prop(md, "proportion", text="Scale")
+ row = col.row()
+ row.label(text="Offset:")
+ row.prop(md, "sign_p")
+ row.prop(md, "sign_l")
+
+ col = layout.column()
+ box = col.box()
+ row = box.row()
+ if (md.dis_advanced_clone):
+ row.prop(md, "dis_advanced_clone", text="", icon="DOWNARROW_HLT", emboss=False)
+ else:
+ row.prop(md, "dis_advanced_clone", text="", icon="RIGHTARROW", emboss=False)
+ row.prop(md, "use_advanced_clone", text="Advanced Cloning")
+ if (md.dis_advanced_clone):
+ col = box.column()
+ if md.use_advanced_clone:
+ col.active = True
+ else:
+ col.active = False
+ split = col.split()
+ col = split.column()
+ col.label(text="Dupli Group:")
+ col.prop(md, "array_group", text="")
+ sub = col.column()
+ sub.active = False if md.array_group is None else True
+ sub.prop(md, "rand_group")
+ sub = sub.split(percentage=0.8)
+ sub.prop(md, "seed_g")
+ sub.operator("object.array_rand_seed_g")
+ col = split.column()
+ col.label(text="Rays Direction:")
+ col.prop(md,"rays_dir", text="")
+ col.prop(md,"rays")
+
+ col = layout.column()
+ box = col.box()
+ row = box.row()
+ if (md.dis_advanced_material):
+ row.prop(md, "dis_advanced_material", text="", icon="DOWNARROW_HLT", emboss=False)
+ else:
+ row.prop(md, "dis_advanced_material", text="", icon="RIGHTARROW", emboss=False)
+ row.prop(md, "use_advanced_material", text="Randomize Material")
+ if (md.dis_advanced_material):
+ col = box.column()
+ if md.use_advanced_material:
+ col.active = True
+ else:
+ col.active = False
+ row = col.row()
+ row.prop(md, "material", expand=True)
+ row = col.row()
+ if md.material == 'SEQUENCE' :
+ row.prop(md, "cont_mat")
+ else:
+ row = row.split(percentage=0.9)
+ row.prop(md, "seed_m")
+ row.operator("object.array_rand_seed_m")
+ row = col.row()
+ col = row.column()
+ split = col.split()
+ col = split.column()
+ col.prop(md, "rand_mat_array")
+ col.separator()
+ sub = col.column()
+ sub.active = False if md.array_group is None else True
+ sub.prop(md, "rand_mat_group")
+ col = split.column()
+ sub = col.column()
+ sub.active = False if md.start_cap is None else True
+ sub.prop(md, "rand_mat_sc")
+ sub = col.column()
+ sub.active = False if md.mid_cap is None else True
+ sub.prop(md, "rand_mat_mc")
+ sub = col.column()
+ sub.active = False if md.end_cap is None else True
+ sub.prop(md, "rand_mat_ec")
+
def BEVEL(self, layout, ob, md):
split = layout.split()
Index: source/blender/blenkernel/BKE_ama.h
===================================================================
--- source/blender/blenkernel/BKE_ama.h (revisione 0)
+++ source/blender/blenkernel/BKE_ama.h (copia locale)
@@ -0,0 +1,88 @@
+/*
+ * ***** 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) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef BKE_AMA_H
+#define BKE_AMA_H
+
+/** \file BKE_ama.h
+ * \ingroup bke
+ */
+
+struct ArrayModifierData;
+struct Object;
+struct Scene;
+struct MVert;
+struct MFace;
+struct CustomData;
+
+typedef struct IndexMapEntry {
+ /* the new vert index that this old vert index maps to */
+ int new;
+ /* -1 if this vert isn't merged, otherwise the old vert index it
+ * should be replaced with
+ */
+ int merge;
+ /* 1 if this vert's first copy is merged with the last copy of its
+ * merge target, otherwise 0
+ */
+ short merge_final;
+} IndexMapEntry;
+
+
+/* calculations is in local space of deformed object
+ * so we store in latmat transform from path coord inside object
+ */
+typedef struct {
+ float dmin[3], dmax[3], dsize, dloc[3];
+ float curvespace[4][4], objectspace[4][4], objectspace3[3][3];
+ int no_rot_axis;
+} CurveDeform;
+
+typedef struct {
+ float loc[3];
+ float rot[3];
+ float scale[3];
+ int seed;
+} Temp;
+
+float vertarray_size(struct MVert *mvert, int numVerts, int axis);
+int test_index_face_maxvert(struct MFace *mface, struct CustomData *fdata, int mfindex, int nr, int maxvert);
+int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum);
+
+float length_fitcurve(struct ArrayModifierData *amd, struct Scene *scene);
+int length_to_count(float length, const float offset[3]);
+float count_to_length(int count, const float offset[3]);
+float f_rand_max(float max);
+
+void array_offset(const float max_off[3], float rit[3], int prop, int sign, int seed);
+void init_mat_oc(const int start, const int end, int *vet_mc);
+void init_offset(const int start, const int end, struct ArrayModifierData *ar);
+void create_offset(const int n, const int totmat, struct ArrayModifierData *ar, struct Object *ob);
+//void array_to_curve(struct Scene *scene, struct Object *cuOb, float (*vertexCos)[3], int numVerts);
+void array_to_curve(struct Scene *scene, struct Object *cuOb, struct Object *target, float *vertexCos, float *vec, float *cent);
+
+#endif
+
Index: source/blender/blenkernel/CMakeLists.txt
===================================================================
--- source/blender/blenkernel/CMakeLists.txt (revisione 43767)
+++ source/blender/blenkernel/CMakeLists.txt (copia locale)
@@ -66,6 +66,7 @@
intern/CCGSubSurf.c
intern/DerivedMesh.c
intern/action.c
+ intern/ama.c
intern/anim.c
intern/anim_sys.c
intern/armature.c
@@ -153,6 +154,7 @@
BKE_DerivedMesh.h
BKE_action.h
+ BKE_ama.h
BKE_anim.h
BKE_animsys.h
BKE_armature.h
Index: source/blender/blenkernel/intern/ama.c
===================================================================
--- source/blender/blenkernel/intern/ama.c (revisione 0)
+++ source/blender/blenkernel/intern/ama.c (copia locale)
@@ -0,0 +1,732 @@
+/*
+ * $Id: ama.c 36773 2011-08-13 13:46:00Z ruesp83 $
+ *
+ * ***** 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) Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Fabio Russo
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/ama.c
+ * \ingroup bke
+ */
+
+#include "MEM_guardedalloc.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+#include "BLI_rand.h"
+#include "BLI_listbase.h"
+#include "BLI_edgehash.h"
+#include "DNA_group_types.h"
+#include "DNA_object_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_scene_types.h"
+#include "BKE_object.h"
+#include "BKE_displist.h"
+#include "BKE_ama.h"
+#include "BKE_anim.h"
+#include "BKE_cdderivedmesh.h"
+#include "BKE_mesh.h"
+
+
+float vertarray_size(MVert *mvert, int numVerts, int axis)
+{
+ int i;
+ float min_co, max_co;
+
+ /* if there are no vertices, width is 0 */
+ if(numVerts == 0) return 0;
+
+ /* find the minimum and maximum coordinates on the desired axis */
+ min_co = max_co = mvert->co[axis];
+ ++mvert;
+ for(i = 1; i < numVerts; ++i, ++mvert) {
+ if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
+ if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
+ }
+
+ return max_co - min_co;
+}
+
+
+/* XXX This function fixes bad merging code, in some cases removing vertices creates indices > maxvert */
+int test_index_face_maxvert(MFace *mface, CustomData *fdata, int mfindex, int nr, int maxvert)
+{
+ if(mface->v1 >= maxvert) {
+ // printf("bad index in array\n");
+ mface->v1= maxvert - 1;
+ }
+ if(mface->v2 >= maxvert) {
+ // printf("bad index in array\n");
+ mface->v2= maxvert - 1;
+ }
+ if(mface->v3 >= maxvert) {
+ // printf("bad index in array\n");
+ mface->v3= maxvert - 1;
+ }
+ if(mface->v4 >= maxvert) {
+ // printf("bad index in array\n");
+ mface->v4= maxvert - 1;
+ }
+
+ return test_index_face(mface, fdata, mfindex, nr);
+}
+
+
+/* indexMap - an array of IndexMap entries
+ * oldIndex - the old index to map
+ * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
+ */
+int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
+{
+ if(indexMap[oldIndex].merge < 0) {
+ /* vert wasn't merged, so use copy of this vert */
+ return indexMap[oldIndex].new + copyNum;
+ } else if(indexMap[oldIndex].merge == oldIndex) {
+ /* vert was merged with itself */
+ return indexMap[oldIndex].new;
+ } else {
+ /* vert was merged with another vert */
+ /* follow the chain of merges to the end, or until we've passed
+ * a number of vertices equal to the copy number
+ */
+ if(copyNum <= 0)
+ return indexMap[oldIndex].new;
+ else
+ return calc_mapping(indexMap, indexMap[oldIndex].merge,
+ copyNum - 1);
+ }
+}
+
+
+float length_fitcurve(ArrayModifierData *amd, struct Scene *scene)
+{
+ float length = 0;
+
+ Curve *cu = amd->curve_ob->data;
+ if(cu) {
+ float tmp_mat[3][3];
+ float scale;
+
+ object_to_mat3(amd->curve_ob, tmp_mat);
+ scale = mat3_to_scale(tmp_mat);
+
+ if(!cu->path) {
+ cu->flag |= CU_PATH; // needed for path & bevlist
+ makeDispListCurveTypes(scene, amd->curve_ob, 0);
+ }
+ if(cu->path)
+ length = scale*cu->path->totdist;
+ }
+ return length;
+}
+
+
+int length_to_count(float length, const float offset[3])
+{
+ int count = 0;
+
+ float dist = sqrt(dot_v3v3(offset, offset));
+
+ if(dist > 1e-6f)
+ /* this gives length = first copy start to last copy end
+ add a tiny offset for floating point rounding errors */
+ count = (length + 1e-6f) / dist;
+ else
+ /* if the offset has no translation, just make one copy */
+ count = 1;
+ return count;
+}
+
+
+float count_to_length(int count, const float offset[3])
+{
+ float length = 0;
+ float dist = sqrt(dot_v3v3(offset, offset));
+
+ if(dist > 1e-6f)
+ /* this gives length = first copy start to last copy end
+ add a tiny offset for floating point rounding errors */
+ //count = (length + 1e-6f) / dist;
+ length = count * dist - 1e-6f;
+ else
+ /* if the offset has no translation, just make one copy */
+ length = 1;
+ return length;
+}
+
+
+//generates a psuedo-random float between 0.0 and max
+float f_rand_max(float max)
+{
+ return BLI_frand()*max;
+}
+
+
+void array_offset(const float max_off[3], float rit[3], int prop, int sign, int seed)
+{
+ int j;
+
+ BLI_srandom(seed);
+
+ rit[0] = f_rand_max(max_off[0]);
+ if (sign & MOD_ARR_SIGN_L) {
+ if (sign & MOD_ARR_SIGN_P) {
+ j = BLI_rand() % 2;
+ if (j == 0)
+ rit[0] = rit[0]*(-1);
+ }
+ else
+ rit[0] = rit[0]*(-1);
+ }
+
+ if (!(prop & MOD_ARR_PROP)) {
+ rit[1] = f_rand_max(max_off[1]);
+ if (sign & MOD_ARR_SIGN_L) {
+ if (sign & MOD_ARR_SIGN_P) {
+ j = BLI_rand() % 2;
+ if (j == 0)
+ rit[1] = rit[1]*(-1);
+ }
+ else
+ rit[1] = rit[1]*(-1);
+ }
+
+ rit[2] = f_rand_max(max_off[2]);
+ if (sign & MOD_ARR_SIGN_L) {
+ if (sign & MOD_ARR_SIGN_P) {
+ j = BLI_rand() % 2;
+ if (j == 0)
+ rit[2] = rit[2]*(-1);
+ }
+ else
+ rit[2] = rit[2]*(-1);
+ }
+ }
+ else {
+ rit[1] = rit[0];
+ rit[2] = rit[0];
+ }
+}
+
+void init_mat_oc(const int start, const int end, int *vet_mc)
+{
+ int i;
+
+ for (i=start; i<end; i++)
+ vet_mc[i] = 0;
+}
+
+
+void init_offset(const int start, const int end, ArrayModifierData *ar)
+{
+ int i;
+
+ for (i=start; i<end; i++) {
+ zero_v3(ar->Mem_Ob[i].rot);
+ ar->Mem_Ob[i].scale[0] = ar->Mem_Ob[i].scale[1] = ar->Mem_Ob[i].scale[2] = 1;
+ zero_v3(ar->Mem_Ob[i].loc);
+ zero_v3(ar->Mem_Ob[i].cu_cent);
+ zero_v4(ar->Mem_Ob[i].cu_loc);
+ ar->Mem_Ob[i].id_mat = 0;
+ ar->Mem_Ob[i].transform = 0;
+ ar->Mem_Ob[i].rand_group_obj = 0;
+ }
+}
+
+
+void create_offset(const int n, const int totmat, ArrayModifierData *ar, Object *ob)
+{
+ float loc[3];
+ float rot[3];
+ float scale[3];
+ int i, seed_t, seed_g, seed_m, act_mat = 0;
+ int cont_mat = ar->cont_mat-1;
+ Group *group = NULL;
+
+ if(ob->dup_group!=NULL)
+ group= ob->dup_group;
+
+ seed_t = ar->seed[0];
+ seed_g = ar->seed[1];
+ seed_m = ar->seed[2];
+ for (i=0; i < n-1; i++) {
+
+ loc[0]=loc[1]=loc[2]=0;
+ rot[0]=rot[1]=rot[2]=0;
+ scale[0]=scale[1]=scale[2]=1;
+
+ if (ar->mode & MOD_ARR_MOD_ADV) {
+ if (ar->lock & MOD_ARR_LOCK_ROT) {
+ if ((ar->rot_offset[0]!=0) || (ar->rot_offset[1]!=0) || (ar->rot_offset[2]!=0)) {
+ array_offset(ar->rot_offset, rot, !MOD_ARR_PROP, ar->sign, seed_t);
+ ar->Mem_Ob[i].transform = 1;
+ }
+ }
+ if (ar->lock & MOD_ARR_LOCK_SCALE) {
+ if ((ar->scale_offset[0]!=1) || (ar->scale_offset[1]!=1) || (ar->scale_offset[2]!=1)) {
+ array_offset(ar->scale_offset, scale, ar->flag_offset, ar->sign, seed_t);
+ ar->Mem_Ob[i].transform = 1;
+ }
+ }
+ if (ar->lock & MOD_ARR_LOCK_LOC) {
+ if ((ar->loc_offset[0]!=0) || (ar->loc_offset[1]!=0) || (ar->loc_offset[2]!=0)) {
+ array_offset(ar->loc_offset, loc, !MOD_ARR_PROP, ar->sign, seed_t);
+ ar->Mem_Ob[i].transform = 1;
+ }
+ }
+ if (ar->Mem_Ob[i].transform) {
+ /* Rotation */
+ if (ar->lock & MOD_ARR_LOCK_ROT)
+ copy_v3_v3(ar->Mem_Ob[i].rot, rot);
+ /* Scaling */
+ if (ar->lock & MOD_ARR_LOCK_SCALE)
+ copy_v3_v3(ar->Mem_Ob[i].scale, scale);
+ /* Location */
+ if (ar->lock & MOD_ARR_LOCK_LOC)
+ copy_v3_v3(ar->Mem_Ob[i].loc, loc);
+ }
+ }
+ if (ar->mode & MOD_ARR_MOD_ADV_CLONE) {
+ if(group!=NULL) {
+ if (ar->rand_group & MOD_ARR_RAND_GROUP) {
+ BLI_srandom(seed_g);
+ ar->Mem_Ob[i].rand_group_obj = BLI_rand() % BLI_countlist(&group->gobject);
+ ar->Mem_Ob[i].rand_group_obj++;
+ }
+ }
+ }
+ /* Random Material Clone */
+ if (ar->mode & MOD_ARR_MOD_ADV_MAT) {
+ if (totmat>1) {
+ /* Random */
+ if ((ar->rand_mat & MOD_ARR_MAT) && (ar->mat_ob & MOD_ARR_AR_MAT_RND)) {
+ BLI_srandom(seed_m);
+ ar->Mem_Ob[i].id_mat = BLI_rand() % totmat;
+ }
+ else { /* Sequence */
+ if (cont_mat == 0 ){
+ cont_mat = ar->cont_mat;
+ if (act_mat + 1 < totmat)
+ act_mat++;
+ else
+ act_mat = 0;
+ }
+ ar->Mem_Ob[i].id_mat = act_mat;
+ cont_mat--;
+ }
+ }
+ }
+ seed_t++;
+ seed_g++;
+ seed_m++;
+ }
+
+ /* Random Material Object Cap */
+ if (ar->mode & MOD_ARR_MOD_ADV_MAT) {
+ if (totmat>1) {
+ if ((ar->rand_mat & MOD_ARR_MAT) && (ar->mat_ob & MOD_ARR_SC_MAT_RND)) {
+ ar->Mem_Mat_Ob.start_cap = BLI_rand() % totmat;
+ }
+ if ((ar->rand_mat & MOD_ARR_MAT) && (ar->mat_ob & MOD_ARR_MC_MAT_RND)) {
+ int dim_mc;
+ if (ar->mode & MOD_ARR_MOD_ADV_MID)
+ dim_mc = ar->count_mc;
+ else
+ dim_mc = 1;
+ for (i=0; i < dim_mc; i++) {
+ ar->Mem_Mat_Ob.mid_cap[i] = BLI_rand() % totmat;
+ }
+ }
+ if ((ar->rand_mat & MOD_ARR_MAT) && (ar->mat_ob & MOD_ARR_EC_MAT_RND)) {
+ ar->Mem_Mat_Ob.end_cap = BLI_rand() % totmat;
+ }
+ }
+ }
+}
+
+
+static void init_curve_deform(Object *par, Object *ob, CurveDeform *cd, int dloc)
+{
+ invert_m4_m4(ob->imat, ob->obmat);
+ mult_m4_m4m4(cd->objectspace, ob->imat, par->obmat);
+ invert_m4_m4(cd->curvespace, cd->objectspace);
+ copy_m3_m4(cd->objectspace3, cd->objectspace);
+
+ // offset vector for 'no smear'
+ if(dloc) {
+ invert_m4_m4(par->imat, par->obmat);
+ mul_v3_m4v3(cd->dloc, par->imat, ob->obmat[3]);
+ }
+ else {
+ cd->dloc[0]=cd->dloc[1]=cd->dloc[2]= 0.0f;
+ }
+
+ cd->no_rot_axis= 0;
+}
+
+
+/* this makes sure we can extend for non-cyclic. *vec needs 4 items! */
+static int where_on_path_deform(Object *ob, float ctime, float *vec, float *dir, float *quat, float *radius) /* returns OK */
+{
+ Curve *cu= ob->data;
+ BevList *bl;
+ float ctime1;
+ int cycl=0;
+
+ /* test for cyclic */
+ bl= cu->bev.first;
+ if (!bl->nr) return 0;
+ if(bl && bl->poly> -1) cycl= 1;
+
+ if(cycl==0) {
+ ctime1= CLAMPIS(ctime, 0.0f, 1.0f);
+ }
+ else ctime1= ctime;
+
+ /* vec needs 4 items */
+ if(where_on_path(ob, ctime1, vec, dir, quat, radius, NULL)) {
+
+ if(cycl==0) {
+ Path *path= cu->path;
+ float dvec[3];
+
+ if(ctime < 0.0f) {
+ sub_v3_v3v3(dvec, path->data[1].vec, path->data[0].vec);
+ mul_v3_fl(dvec, ctime*(float)path->len);
+ add_v3_v3(vec, dvec);
+ if(quat) copy_qt_qt(quat, path->data[0].quat);
+ if(radius) *radius= path->data[0].radius;
+ print_v4("Vec", vec);
+ }
+ else if(ctime > 1.0f) {
+ sub_v3_v3v3(dvec, path->data[path->len-1].vec, path->data[path->len-2].vec);
+ mul_v3_fl(dvec, (ctime-1.0f)*(float)path->len);
+ add_v3_v3(vec, dvec);
+ if(quat) copy_qt_qt(quat, path->data[path->len-1].quat);
+ if(radius) *radius= path->data[path->len-1].radius;
+ /* weight - not used but could be added */
+ }
+
+ }
+ return 1;
+ }
+ return 0;
+}
+
+
+ /* for each point, rotate & translate to curve */
+ /* use path, since it has constant distances */
+ /* co: local coord, result local too */
+ /* returns quaternion for rotation, using cd->no_rot_axis */
+ /* axis is using another define!!! */
+static int calc_curve_deform(Scene *scene, Object *par, float *co, CurveDeform *cd, float *loc, float *cent)
+{
+ Curve *cu= par->data;
+ float fac, dir[3], new_quat[4], radius;
+ short /*upflag, */ index, axis = 1;
+
+ index= axis-1;
+ if(index>2)
+ index -= 3; /* negative */
+
+ /* to be sure, mostly after file load */
+ if(cu->path==NULL) {
+ makeDispListCurveTypes(scene, par, 0);
+ if(cu->path==NULL) return 0; // happens on append...
+ }
+
+ if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */
+ if(cu->flag & CU_STRETCH)
+ fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]);
+ else
+ fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist);
+ }
+ else {
+ if(cu->flag & CU_STRETCH)
+ fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]);
+ else
+ fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist);
+ }
+
+ if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */
+ float quat[4]; //, cent[3];
+ if(cd->no_rot_axis) { /* set by caller */
+
+ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than
+ * changing the axis before calculating the tilt but serves much the same purpose */
+ float dir_flat[3]={0,0,0}, q[4];
+ copy_v3_v3(dir_flat, dir);
+ dir_flat[cd->no_rot_axis-1]= 0.0f;
+
+ normalize_v3(dir);
+ normalize_v3(dir_flat);
+
+ rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */
+
+ mul_qt_qtqt(new_quat, q, new_quat);
+ }
+
+
+ /* Logic for 'cent' orientation *
+ *
+ * The way 'co' is copied to 'cent' may seem to have no meaning, but it does.
+ *
+ * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark.
+ * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise
+ * Notice X,Y,Z Up all have light colors and each ordered CCW.
+ *
+ * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell
+ *
+ * note: moved functions into quat_apply_track/vec_apply_track
+ * */
+ copy_qt_qt(quat, new_quat);
+ copy_v3_v3(cent, co);
+
+ /* zero the axis which is not used,
+ * the big block of text above now applies to these 3 lines */
+ quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */
+ vec_apply_track(cent, axis-1);
+ cent[axis < 4 ? axis-1 : axis-4]= 0.0f;
+
+
+ /* scale if enabled */
+ if(cu->flag & CU_PATH_RADIUS)
+ mul_v3_fl(cent, radius);
+
+ /* local rotation */
+ normalize_qt(quat);
+ mul_qt_v3(quat, cent);
+
+ /* translation */
+ /*add_v3_v3v3(co, cent, loc);*/
+
+ return 1;
+ }
+ return 0;
+}
+
+
+void array_to_curve(Scene *scene, Object *cuOb, Object *target, float *vertexCos, float *vec, float *quat)
+{
+ Curve *cu;
+ CurveDeform cd;
+
+ if(cuOb->type != OB_CURVE)
+ return;
+ cu = cuOb->data;
+ cu->flag |= (CU_PATH|CU_FOLLOW);
+ init_curve_deform(cuOb, target, &cd, (cu->flag & CU_STRETCH)==0);
+ calc_curve_deform(scene, cuOb, vertexCos, &cd, vec, quat);
+}
+
+
+/** Divide the line segments associated with the currently selected
+ * curve nodes (Bezier or NURB). If there are no valid segment
+ * selections within the current selection, nothing happens.
+ */
+void dist_point_nurb(Object *obedit, int number_cuts)
+{
+ Curve *cu= obedit->data;
+ EditNurb *editnurb= cu->editnurb;
+ Nurb *nu;
+ BezTriple *prevbezt, *bezt, *beztnew, *beztn;
+ BPoint *bp, *prevbp, *bpnew, *bpn;
+ float vec[15];
+ int a, amount, i;
+ float factor;
+
+ for(nu= editnurb->nurbs.first; nu; nu= nu->next) {
+ amount= 0;
+ if(nu->type == CU_BEZIER) {
+ /*
+ Insert a point into a 2D Bezier curve.
+ Endpoints are preserved. Otherwise, all selected and inserted points are
+ newly created. Old points are discarded.
+ */
+ /* count */
+ if(nu->flagu & CU_NURB_CYCLIC) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ prevbezt = bezt+(a-1);
+ }
+ else {
+ a = nu->pntsu-1;
+ prevbezt = nu->bezt;
+ bezt = prevbezt+1;
+ }
+ /*while(a--) {
+ if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) amount+=number_cuts;
+ prevbezt= bezt;
+ bezt++;
+ }*/
+
+ if(amount) {
+ /* insert */
+ beztnew =
+ (BezTriple*)MEM_mallocN((amount + nu->pntsu) * sizeof(BezTriple), "subdivNurb");
+ /*beztn= beztnew;
+ if(nu->flagu & CU_NURB_CYCLIC) {
+ a = nu->pntsu;
+ bezt = nu->bezt;
+ prevbezt = bezt+(a-1);
+ }
+ else {
+ a = nu->pntsu-1;
+ prevbezt = nu->bezt;
+ bezt = prevbezt+1;
+ }*/
+ while(a--) {
+ memcpy(beztn, prevbezt, sizeof(BezTriple));
+ //keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
+ beztn++;
+
+ if( BEZSELECTED_HIDDENHANDLES(cu, prevbezt) && BEZSELECTED_HIDDENHANDLES(cu, bezt) ) {
+ float prevvec[3][3];
+
+ memcpy(prevvec, prevbezt->vec, sizeof(float) * 9);
+
+ for (i = 0; i < number_cuts; i++) {
+ factor = 1.0f / (number_cuts + 1 - i);
+
+ memcpy(beztn, bezt, sizeof(BezTriple));
+
+ /* midpoint subdividing */
+ interp_v3_v3v3(vec, prevvec[1], prevvec[2], factor);
+ interp_v3_v3v3(vec+3, prevvec[2], bezt->vec[0], factor);
+ interp_v3_v3v3(vec+6, bezt->vec[0], bezt->vec[1], factor);
+
+ interp_v3_v3v3(vec+9, vec, vec+3, factor);
+ interp_v3_v3v3(vec+12, vec+3, vec+6, factor);
+
+ /* change handle of prev beztn */
+ copy_v3_v3((beztn-1)->vec[2], vec);
+ /* new point */
+ copy_v3_v3(beztn->vec[0], vec+9);
+ interp_v3_v3v3(beztn->vec[1], vec+9, vec+12, factor);
+ copy_v3_v3(beztn->vec[2], vec+12);
+ /* handle of next bezt */
+ if(a==0 && i == number_cuts - 1 && (nu->flagu & CU_NURB_CYCLIC)) {copy_v3_v3(beztnew->vec[0], vec+6);}
+ else {copy_v3_v3(bezt->vec[0], vec+6);}
+
+ beztn->radius = (prevbezt->radius + bezt->radius)/2;
+ beztn->weight = (prevbezt->weight + bezt->weight)/2;
+
+ memcpy(prevvec, beztn->vec, sizeof(float) * 9);
+ beztn++;
+ }
+ }
+
+ prevbezt= bezt;
+ bezt++;
+ }
+ /* last point */
+ if((nu->flagu & CU_NURB_CYCLIC)==0) {
+ memcpy(beztn, prevbezt, sizeof(BezTriple));
+ //keyIndex_updateBezt(editnurb, prevbezt, beztn, 1);
+ }
+
+ MEM_freeN(nu->bezt);
+ nu->bezt= beztnew;
+ nu->pntsu+= amount;
+
+ //calchandlesNurb(nu);
+ }
+ } /* End of 'if(nu->type == CU_BEZIER)' */
+ else if (nu->pntsv==1) {
+ /*
+ All flat lines (ie. co-planar), except flat Nurbs. Flat NURB curves
+ are handled together with the regular NURB plane division, as it
+ should be. I split it off just now, let's see if it is
+ stable... nzc 30-5-'00
+ */
+ /* count */
+ if(nu->flagu & CU_NURB_CYCLIC) {
+ a= nu->pntsu;
+ bp= nu->bp;
+ prevbp= bp+(a-1);
+ }
+ else {
+ a= nu->pntsu-1;
+ prevbp= nu->bp;
+ bp= prevbp+1;
+ }
+ while(a--) {
+ if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) amount+=number_cuts;
+ prevbp= bp;
+ bp++;
+ }
+
+ if(amount) {
+ /* insert */
+ bpnew =
+ (BPoint*)MEM_mallocN((amount + nu->pntsu) * sizeof(BPoint), "subdivNurb2");
+ bpn= bpnew;
+
+ if(nu->flagu & CU_NURB_CYCLIC) {
+ a= nu->pntsu;
+ bp= nu->bp;
+ prevbp= bp+(a-1);
+ }
+ else {
+ a= nu->pntsu-1;
+ prevbp= nu->bp;
+ bp= prevbp+1;
+ }
+ while(a--) {
+ memcpy(bpn, prevbp, sizeof(BPoint));
+ //keyIndex_updateBP(editnurb, prevbp, bpn, 1);
+ bpn++;
+
+ if( (bp->f1 & SELECT) && (prevbp->f1 & SELECT) ) {
+ // printf("*** subdivideNurb: insert 'linear' point\n");
+ for (i = 0; i < number_cuts; i++) {
+ factor = (float)(i + 1) / (number_cuts + 1);
+
+ memcpy(bpn, bp, sizeof(BPoint));
+ interp_v4_v4v4(bpn->vec, prevbp->vec, bp->vec, factor);
+ bpn++;
+ }
+
+ }
+ prevbp= bp;
+ bp++;
+ }
+ if((nu->flagu & CU_NURB_CYCLIC)==0) { /* last point */
+ memcpy(bpn, prevbp, sizeof(BPoint));
+ //keyIndex_updateBP(editnurb, prevbp, bpn, 1);
+ }
+
+ MEM_freeN(nu->bp);
+ nu->bp= bpnew;
+ nu->pntsu+= amount;
+
+ if(nu->type & CU_NURBS) {
+ //nurbs_knot_calc_u(nu);
+ }
+ }
+ } /* End of 'else if(nu->pntsv==1)' */
+ }
+}
Index: source/blender/blenkernel/intern/anim.c
===================================================================
--- source/blender/blenkernel/intern/anim.c (revisione 43767)
+++ source/blender/blenkernel/intern/anim.c (copia locale)
@@ -31,6 +31,7 @@
#include <stdio.h>
+#include <time.h>
#include <math.h>
#include <string.h>
@@ -47,6 +48,7 @@
#include "DNA_group_types.h"
#include "DNA_key_types.h"
#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
#include "DNA_scene_types.h"
#include "DNA_vfont_types.h"
@@ -60,6 +62,7 @@
#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "BKE_particle.h"
@@ -754,6 +757,137 @@
}
}
+static void group_arrayduplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
+{
+ DupliObject *dob;
+ Group *group;
+ GroupObject *go;
+ float mat[4][4], tmat[4][4], offset[4][4], rot[4][4];
+ ModifierData *md;
+ int i, cont_rnd;
+ float d_alp, alpha=0;
+
+ if(ob->dup_group==NULL) return;
+ group= ob->dup_group;
+
+ /* simple preventing of too deep nested groups */
+ if(level>MAX_DUPLI_RECUR) return;
+
+ /* handles animated groups, and */
+ /* we need to check update for objects that are not in scene... */
+ group_handle_recalc_and_update(scene, ob, group);
+ animated= animated || group_is_animated(ob, group);
+
+ for(md=ob->modifiers.first; md; md=md->next) {
+ if(md->type == eModifierType_Array) {
+ if (md->mode&eModifierMode_Realtime || md->mode&eModifierMode_Render){
+ ArrayModifierData *amd = (ArrayModifierData*) md;
+
+ d_alp=0;
+ if (amd->rays > 1)
+ alpha = (float)6.2831 / amd->rays;
+ copy_m4_m4(offset, amd->delta);
+
+ for (i = 0; i < amd->count-1; i++) {
+ cont_rnd = 0;
+ for(go= group->gobject.first; go; go= go->next) {
+ cont_rnd++;
+ /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
+ if(go->ob!=ob) {
+ if (amd->rand_group & MOD_ARR_RAND_GROUP) {
+ if ((amd->Mem_Ob[i].rand_group_obj != 0) && (amd->Mem_Ob[i].rand_group_obj != cont_rnd))
+ continue;
+ } else if (amd->rand_group & MOD_ARR_RAND_MAT_GROUP) {
+ //assign_material(go->ob, *ob->mat, go->ob->totcol+1);
+ //go->ob->actcol = BLI_rand() % ob->totcol;
+
+ //printf("Totcol=%d\n", go->ob->totcol);
+ //printf("actcol=%d\n", go->ob->actcol);
+ }
+ /* Group Dupli Offset, should apply after everything else */
+ if (group->dupli_ofs[0] || group->dupli_ofs[1] || group->dupli_ofs[2]) {
+ copy_m4_m4(tmat, go->ob->obmat);
+ sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs);
+ mult_m4_m4m4(mat, ob->obmat, tmat);
+ } else {
+ mult_m4_m4m4(mat, ob->obmat, go->ob->obmat);
+ }
+
+ copy_m4_m4(tmat, mat);
+ if (amd->rays>1) {
+ unit_m4(rot);
+ if (amd->rays_dir == MOD_ARR_RAYS_X)
+ rotate_m4(rot,'X',d_alp);
+ else if (amd->rays_dir == MOD_ARR_RAYS_Y)
+ rotate_m4(rot,'Y',d_alp);
+ else
+ rotate_m4(rot,'Z',d_alp);
+ if (d_alp == 0){
+ mult_m4_m4m4(mat, tmat, offset);
+
+ copy_m4_m4(tmat, mat);
+ mult_m4_m4m4(mat, tmat, rot);
+ }
+ else{
+ mult_m4_m4m4(mat, tmat, offset);
+
+ copy_m4_m4(tmat, mat);
+ mult_m4_m4m4(mat, tmat, rot);
+ }
+ }
+ else {
+ mult_m4_m4m4(mat, tmat, offset);
+ }
+ /* Noise */
+ if (amd->mode & MOD_ARR_MOD_ADV) {
+ if (amd->Mem_Ob[i].transform == 1) {
+ float app[4][4];
+ unit_m4(app);
+ loc_eul_size_to_mat4(app, amd->Mem_Ob[i].loc, amd->Mem_Ob[i].rot, amd->Mem_Ob[i].scale);
+
+ copy_m4_m4(tmat, mat);
+ mult_m4_m4m4(mat, tmat, app);
+ }
+ }
+
+ dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIARRAY, animated);
+
+ if (!(md->mode&eModifierMode_Render))
+ dob->no_render = 1;
+ else
+ dob->no_render = 0;
+ /* check the group instance and object layers match, also that the object visible flags are ok. */
+ if(((dob->origlay & group->layer)==0 ||
+ (G.rendering==0 && dob->ob->restrictflag & OB_RESTRICT_VIEW) ||
+ (G.rendering && dob->ob->restrictflag & OB_RESTRICT_RENDER)) ||
+ !(md->mode&eModifierMode_Realtime) || (!(md->mode&eModifierMode_Editmode) && (ob->mode == OB_MODE_EDIT))) {
+ dob->no_draw= 1;
+ }
+ else {
+ dob->no_draw= 0;
+ }
+ if(go->ob->transflag & OB_DUPLI) {
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level+1, animated);
+ copy_m4_m4(dob->ob->obmat, dob->omat);
+ }
+ }
+ }
+ /* Increment for rays */
+ if (amd->rays>1) {
+ d_alp = d_alp + alpha;
+ if (d_alp>6.2831)
+ d_alp=0;
+ }
+ /* Offset for clone group */
+ if (d_alp == 0)
+ mult_m4_m4m4(offset, amd->delta, offset);
+ }
+ }
+ }
+ }
+}
+
static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated)
{
extern int enable_cu_speed; /* object.c */
@@ -1594,6 +1728,15 @@
if(dob->type == OB_DUPLIGROUP)
copy_m4_m4(dob->ob->obmat, dob->mat);
}
+ } else if(ob->transflag & OB_DUPLIARRAY) {
+ DupliObject *dob;
+
+ group_arrayduplilist(duplilist, scene, ob, level+1, animated);
+ if (level==0) {
+ for(dob= duplilist->first; dob; dob= dob->next)
+ if(dob->type == OB_DUPLIARRAY)
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ }
}
}
Index: source/blender/blenloader/intern/readfile.c
===================================================================
--- source/blender/blenloader/intern/readfile.c (revisione 43767)
+++ source/blender/blenloader/intern/readfile.c (copia locale)
@@ -4129,6 +4129,15 @@
}
}
+ {
+ ArrayModifierData *amd = (ArrayModifierData *)modifiers_findByType(ob, eModifierType_Array);
+
+ if(amd)
+ {
+ amd->arr_group = newlibadr(fd, ob->id.lib, amd->arr_group);
+ }
+ }
+
/* texture field */
if(ob->pd)
lib_link_partdeflect(fd, &ob->id, ob->pd);
@@ -4450,6 +4459,12 @@
if(wmd->cmap_curve)
direct_link_curvemapping(fd, wmd->cmap_curve);
}
+ else if (md->type==eModifierType_Array) {
+ ArrayModifierData *amd = (ArrayModifierData*) md;
+
+ amd->Mem_Ob = newdataadr(fd, amd->Mem_Ob);
+ amd->Mem_Mat_Ob.mid_cap = newdataadr(fd, amd->Mem_Mat_Ob.mid_cap);
+ }
}
}
Index: source/blender/blenloader/intern/writefile.c
===================================================================
--- source/blender/blenloader/intern/writefile.c (revisione 43767)
+++ source/blender/blenloader/intern/writefile.c (copia locale)
@@ -1395,6 +1395,12 @@
if (wmd->cmap_curve)
write_curvemapping(wd, wmd->cmap_curve);
}
+ else if (md->type==eModifierType_Array) {
+ ArrayModifierData *amd = (ArrayModifierData*) md;
+
+ writestruct(wd, DATA, "ArrayChangeObject", amd->count, amd->Mem_Ob);
+ writedata(wd, DATA, sizeof(int)*(amd->count_mc), amd->Mem_Mat_Ob.mid_cap);
+ }
}
}
Index: source/blender/editors/object/object_intern.h
===================================================================
--- source/blender/editors/object/object_intern.h (revisione 43767)
+++ source/blender/editors/object/object_intern.h (copia locale)
@@ -159,6 +159,9 @@
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
void OBJECT_OT_ocean_bake(struct wmOperatorType *ot);
+void OBJECT_OT_array_rand_seed_t(struct wmOperatorType *ot);
+void OBJECT_OT_array_rand_seed_g(struct wmOperatorType *ot);
+void OBJECT_OT_array_rand_seed_m(struct wmOperatorType *ot);
/* object_constraint.c */
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
Index: source/blender/editors/object/object_modifier.c
===================================================================
--- source/blender/editors/object/object_modifier.c (revisione 43767)
+++ source/blender/editors/object/object_modifier.c (copia locale)
@@ -31,6 +31,7 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include "MEM_guardedalloc.h"
@@ -48,6 +49,7 @@
#include "BLI_path_util.h"
#include "BLI_editVert.h"
#include "BLI_utildefines.h"
+#include "BLI_rand.h"
#include "BKE_animsys.h"
#include "BKE_curve.h"
@@ -201,6 +203,10 @@
else if(md->type == eModifierType_Smoke) {
ob->dt = OB_TEXTURE;
}
+ else if(md->type == eModifierType_Array) {
+ ob->transflag = 0;
+ ob->dup_group = NULL;
+ }
else if(md->type == eModifierType_Multires) {
int ok= 1;
Mesh *me= ob->data;
@@ -1669,3 +1675,80 @@
RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");
}
+
+/****************** array rand operator *********************/
+
+static int array_poll(bContext *C) {
+ return edit_modifier_poll_generic(C, &RNA_ArrayModifier, 0);
+}
+
+static int array_rand_exec(bContext *C, wmOperator *op) {
+ Object *ob = ED_object_active_context(C);
+ ArrayModifierData *amd = (ArrayModifierData *)edit_modifier_property_get(op, ob, eModifierType_Array);
+
+ if (!amd)
+ return OPERATOR_CANCELLED;
+
+ BLI_srandom(time(NULL)+1);
+ if (strcmp(op->idname, "OBJECT_OT_array_rand_seed_t") == 0)
+ amd->seed[0] = rand() % 10001;
+ if (strcmp(op->idname, "OBJECT_OT_array_rand_seed_g") == 0)
+ amd->seed[1] = rand() % 10001;
+ if (strcmp(op->idname, "OBJECT_OT_array_rand_seed_m") == 0)
+ amd->seed[2] = rand() % 10001;
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int array_rand_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) {
+ if (edit_modifier_invoke_properties(C, op))
+ return array_rand_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+
+void OBJECT_OT_array_rand_seed_t(wmOperatorType *ot) {
+ ot->name = "G";
+ ot->description = "Generates the Seed for the Randomize Transform";
+ ot->idname = "OBJECT_OT_array_rand_seed_t";
+
+ ot->poll = array_poll;
+ ot->invoke = array_rand_invoke;
+ ot->exec = array_rand_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ edit_modifier_properties(ot);
+}
+
+void OBJECT_OT_array_rand_seed_g(wmOperatorType *ot) {
+ ot->name = "G";
+ ot->description = "Generates the Seed for the Randomize Group";
+ ot->idname = "OBJECT_OT_array_rand_seed_g";
+
+ ot->poll = array_poll;
+ ot->invoke = array_rand_invoke;
+ ot->exec = array_rand_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ edit_modifier_properties(ot);
+}
+
+void OBJECT_OT_array_rand_seed_m(wmOperatorType *ot) {
+ ot->name = "G";
+ ot->description = "Generates the Seed for the Randomize Material";
+ ot->idname = "OBJECT_OT_array_rand_seed_m";
+
+ ot->poll = array_poll;
+ ot->invoke = array_rand_invoke;
+ ot->exec = array_rand_exec;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+ edit_modifier_properties(ot);
+}
\ No newline at end of file
Index: source/blender/editors/object/object_ops.c
===================================================================
--- source/blender/editors/object/object_ops.c (revisione 43767)
+++ source/blender/editors/object/object_ops.c (copia locale)
@@ -141,6 +141,9 @@
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
WM_operatortype_append(OBJECT_OT_explode_refresh);
WM_operatortype_append(OBJECT_OT_ocean_bake);
+ WM_operatortype_append(OBJECT_OT_array_rand_seed_t);
+ WM_operatortype_append(OBJECT_OT_array_rand_seed_g);
+ WM_operatortype_append(OBJECT_OT_array_rand_seed_m);
WM_operatortype_append(OBJECT_OT_constraint_add);
WM_operatortype_append(OBJECT_OT_constraint_add_with_targets);
Index: source/blender/makesdna/DNA_group_types.h
===================================================================
--- source/blender/makesdna/DNA_group_types.h (revisione 43767)
+++ source/blender/makesdna/DNA_group_types.h (copia locale)
@@ -43,6 +43,11 @@
typedef struct GroupObject {
struct GroupObject *next, *prev;
struct Object *ob;
+ /* rot - scale - loc: It is the information obtained from the AMA */
+ /* float rot[3];
+ float scale[3];
+ float loc[3];
+ int rand_group_obj;*/
void *lampren; /* used while render */
short recalc; /* copy of ob->recalc, used to set animated groups OK */
char pad[6];
@@ -59,6 +64,11 @@
* on the last used scene */
unsigned int layer;
float dupli_ofs[3];
+ /* It is the information obtained from the AMA */
+ /*float delta[4][4];
+ int count;
+ int rays;
+ int rays_dir;*/
} Group;
Index: source/blender/makesdna/DNA_modifier_types.h
===================================================================
--- source/blender/makesdna/DNA_modifier_types.h (revisione 43767)
+++ source/blender/makesdna/DNA_modifier_types.h (copia locale)
@@ -179,17 +179,53 @@
/* Mask Modifier -> flag */
#define MOD_MASK_INV (1<<0)
+
+typedef struct ArrayChangeObject {
+ float rot[3];
+ float scale[3];
+ float loc[3];
+
+ float cu_cent[3];
+ float cu_loc[4];
+ int transform; /* 0 not modified, 1 modified */
+ int id_mat;
+ int rand_group_obj;
+} ArrayChangeObject;
+
+/*typedef struct ObjectCap {
+ struct Object *ob_cap;
+ struct Object *curve;
+ int count;
+ int distribution;
+} ObjectCap;*/
+
+typedef struct Mat_ObCap {
+ int *mid_cap;
+ int start_cap;
+ int end_cap;
+} Mat_ObCap;
+
typedef struct ArrayModifierData {
ModifierData modifier;
/* the object with which to cap the start of the array */
struct Object *start_cap;
+ /* the object with which to cap the mid of the array */
+ struct Object *mid_cap;
/* the object with which to cap the end of the array */
struct Object *end_cap;
- /* the curve object to use for MOD_ARR_FITCURVE */
+ /* the curve object to use for MOD_ARR_MOD_CURVE */
struct Object *curve_ob;
+ /* the curve object to use for Object Cap */
+ struct Object *curve_cap;
/* the object to use for object offset */
struct Object *offset_ob;
+ /* stores information about objects subject to random */
+ struct ArrayChangeObject *Mem_Ob;
+ /* stores the material of the "Object Cap" */
+ struct Mat_ObCap Mem_Mat_Ob;
+ /* group linked to the modifier */
+ struct Group *arr_group;
/* a constant duplicate offset;
1 means the duplicates are 1 unit apart
*/
@@ -198,14 +234,20 @@
1 means the duplicates are 1 object-width apart
*/
float scale[3];
+ /* Offset for clone group */
+ float delta[4][4];
/* the length over which to distribute the duplicates */
float length;
/* the limit below which to merge vertices in adjacent duplicates */
float merge_dist;
+ /* randomize Offset */
+ float loc_offset[3];
+ float rot_offset[3];
+ float scale_offset[3];
/* determines how duplicate count is calculated; one of:
MOD_ARR_FIXEDCOUNT -> fixed
MOD_ARR_FITLENGTH -> calculated to fit a set length
- MOD_ARR_FITCURVE -> calculated to fit the length of a Curve object
+ MOD_ARR_FITBETWEEN -> Number of duplicates between two objects
*/
int fit_type;
/* flags specifying how total offset is calculated; binary OR of:
@@ -219,24 +261,129 @@
MOD_ARR_MERGE -> merge vertices in adjacent duplicates
*/
int flags;
+ /* The pseudo-random number generator is initialized using the argument passed as seed.
+ * seed[0] = transform
+ * seed[1] = group
+ * seed[2] = material
+ */
+ int seed[3];
/* the number of duplicates to generate for MOD_ARR_FIXEDCOUNT */
int count;
+ /* the number of duplicates of Mid Cap and type of distribution */
+ int count_mc;
+ int dist_mc;
+ /* Indicates whether you use a random material or the original*/
+ int mat_ob;
+ /* Indicates whether to use the Start Cap and End Cap on the curve of the Mid Cap */
+ int outer_cp;
+ /* number of rays and the direction of the Clones */
+ int rays;
+ int rays_dir;
+ /* Number of copies of the same material */
+ int cont_mat;
+ /* randomizes the materials */
+ int rand_mat;
+ /* lock the noise offset */
+ int lock;
+ /* Normal Mode - Advanced Mode - Advanced Material - Advanced MidCap - Advanced Cloning */
+ int mode;
+ int displays;
+ /* indicates how the modifier should be used */
+ int type;
+ /* direction Offset */
+ int sign;
+ /* keeps the ratio on the scale */
+ int flag_offset;
+ /* how to distribute the clones on a curve */
+ int dist_cu;
+ /* ability to randomization of objects belonging to the group linked */
+ int rand_group;
} ArrayModifierData;
/* ArrayModifierData->fit_type */
-#define MOD_ARR_FIXEDCOUNT 0
-#define MOD_ARR_FITLENGTH 1
-#define MOD_ARR_FITCURVE 2
+#define MOD_ARR_FIXEDCOUNT 0
+#define MOD_ARR_FITLENGTH 1
+#define MOD_ARR_FITBETWEEN 2
/* ArrayModifierData->offset_type */
-#define MOD_ARR_OFF_CONST (1<<0)
-#define MOD_ARR_OFF_RELATIVE (1<<1)
-#define MOD_ARR_OFF_OBJ (1<<2)
+#define MOD_ARR_OFF_CONST (1<<0)
+#define MOD_ARR_OFF_RELATIVE (1<<1)
+#define MOD_ARR_OFF_OBJ (1<<2)
/* ArrayModifierData->flags */
-#define MOD_ARR_MERGE (1<<0)
-#define MOD_ARR_MERGEFINAL (1<<1)
+#define MOD_ARR_MERGE (1<<0)
+#define MOD_ARR_MERGEFINAL (1<<1)
+/* ArrayModifierData->mat_ob */
+/* Array */
+#define MOD_ARR_AR_MAT_RND (1<<0)
+/* Start Cap */
+#define MOD_ARR_SC_MAT_RND (1<<1)
+#define MOD_ARR_SC_MAT_OR (1<<2)
+/* Mid Cap */
+#define MOD_ARR_MC_MAT_RND (1<<3)
+#define MOD_ARR_MC_MAT_OR (1<<4)
+/* End Cap */
+#define MOD_ARR_EC_MAT_RND (1<<5)
+#define MOD_ARR_EC_MAT_OR (1<<6)
+
+/* ArrayModifierData->type */
+#define MOD_ARR_MOD_NRM (1<<0)
+#define MOD_ARR_MOD_CURVE (1<<1)
+
+/* ArrayModifierData->outer_cp */
+#define MOD_ARR_CP_FIRST (1<<0)
+#define MOD_ARR_CP_LAST (1<<1)
+
+/* ArrayModifierData->mode */
+#define MOD_ARR_MOD_ADV (1<<0)
+#define MOD_ARR_MOD_ADV_MAT (1<<1)
+#define MOD_ARR_MOD_ADV_MID (1<<3)
+#define MOD_ARR_MOD_ADV_CLONE (1<<4)
+
+/* ArrayModifierData->displays */
+#define MOD_ARR_DIS_ADV (1<<0)
+#define MOD_ARR_DIS_ADV_MAT (1<<1)
+#define MOD_ARR_DIS_ADV_MID (1<<3)
+#define MOD_ARR_DIS_ADV_CLONE (1<<4)
+
+/* ArrayModifierData->sign */
+#define MOD_ARR_SIGN_P (1<<0)
+#define MOD_ARR_SIGN_L (1<<1)
+
+/* ArrayModifierData->lock */
+#define MOD_ARR_LOCK (4+8+16+32)
+#define MOD_ARR_LOCK_LOC 4
+#define MOD_ARR_LOCK_SCALE 8
+#define MOD_ARR_LOCK_ROT 16
+#define MOD_ARR_LOCK_MAT 32
+
+/* ArrayModifierData->flag_offset */
+#define MOD_ARR_PROP (1<<0)
+#define MOD_ARR_LOCAL (1<<1)
+
+/* ArrayModifierData->rand_mat */
+#define MOD_ARR_MAT (1<<0)
+#define MOD_ARR_SEQ (1<<1)
+
+/* ArrayModifierData->rays_dir */
+#define MOD_ARR_RAYS_X 0
+#define MOD_ARR_RAYS_Y 1
+#define MOD_ARR_RAYS_Z 2
+
+/* ArrayModifierData->rand_group */
+#define MOD_ARR_RAND_GROUP (1<<0)
+#define MOD_ARR_RAND_MAT_GROUP (1<<1)
+
+/* ArrayModifierData->dist_cu */
+#define MOD_ARR_DIST_EVENLY (1<<0)
+#define MOD_ARR_DIST_SEGMENT (1<<1)
+
+/* ArrayModifierData->dist_mc */
+#define MOD_ARR_DIST_SEQ (1<<0)
+#define MOD_ARR_DIST_HALF (1<<1)
+#define MOD_ARR_DIST_CURVE (1<<2)
+
typedef struct MirrorModifierData {
ModifierData modifier;
Index: source/blender/makesdna/DNA_object_types.h
===================================================================
--- source/blender/makesdna/DNA_object_types.h (revisione 43767)
+++ source/blender/makesdna/DNA_object_types.h (copia locale)
@@ -291,7 +291,10 @@
float orco[3], uv[2];
short type; /* from Object.transflag */
- char no_draw, animated;
+ short pad1;
+ char no_draw, no_render, animated;
+ char pad2;
+ int pad3;
} DupliObject;
/* **************** OBJECT ********************* */
@@ -339,7 +342,7 @@
/* (short) transflag */
/* flags 1 and 2 were unused or relics from past features */
#define OB_NEG_SCALE 4
-#define OB_DUPLI (8+16+256+512+2048)
+#define OB_DUPLI (8+16+256+512+2048+4096)
#define OB_DUPLIFRAMES 8
#define OB_DUPLIVERTS 16
#define OB_DUPLIROT 32
@@ -349,8 +352,9 @@
#define OB_DUPLIFACES 512
#define OB_DUPLIFACES_SCALE 1024
#define OB_DUPLIPARTS 2048
-#define OB_RENDER_DUPLI 4096
-#define OB_NO_CONSTRAINTS 8192 /* runtime constraints disable */
+#define OB_DUPLIARRAY 4096
+#define OB_RENDER_DUPLI 8192
+#define OB_NO_CONSTRAINTS 16384
/* (short) ipoflag */
/* XXX: many old flags for features removed due to incompatability
Index: source/blender/makesrna/intern/rna_modifier.c
===================================================================
--- source/blender/makesrna/intern/rna_modifier.c (revisione 43767)
+++ source/blender/makesrna/intern/rna_modifier.c (copia locale)
@@ -588,6 +588,16 @@
modifier_object_set(ptr->id.data, &((ArrayModifierData*)ptr->data)->end_cap, OB_MESH, value);
}
+static void rna_ArrayModifier_mid_cap_set(PointerRNA *ptr, PointerRNA value)
+{
+ modifier_object_set(ptr->id.data, &((ArrayModifierData*)ptr->data)->mid_cap, OB_MESH, value);
+}
+
+static void rna_ArrayModifier_curve_cap_set(PointerRNA *ptr, PointerRNA value)
+{
+ modifier_object_set(ptr->id.data, &((ArrayModifierData*)ptr->data)->curve_cap, OB_CURVE, value);
+}
+
static void rna_ArrayModifier_start_cap_set(PointerRNA *ptr, PointerRNA value)
{
modifier_object_set(ptr->id.data, &((ArrayModifierData*)ptr->data)->start_cap, OB_MESH, value);
@@ -1375,23 +1385,85 @@
RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
+/*static void rna_def_object_cap(BlenderRNA *brna)
+{
+ StructRNA *srna;
+ PropertyRNA *prop;
+ FunctionRNA *func;
+
+ static EnumPropertyItem prop_mid_cap_items[] = {
+ {MOD_ARR_DIST_SEQ, "SEQUENCE", 0, "Sequence", "Use the mid cap in sequence"},
+ {MOD_ARR_DIST_HALF, "HALF", 0, "Half", "Use the mid cap from the center"},
+ {MOD_ARR_DIST_CURVE, "CURVE", 0, "Curve", "Use the mid cap on points of the curve"},
+ {0, NULL, 0, NULL, NULL}};
+
+ srna= RNA_def_struct(brna, "ObjectCap", NULL);
+ RNA_def_struct_ui_text(srna, "Object Cap", "Object Cap");
+
+ prop= RNA_def_property(srna, "ob_cap", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Mid Cap", "Mesh object to use as a mid cap");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_mid_cap_set", NULL, "rna_Mesh_object_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "count", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 1000, 1, 0);
+ RNA_def_property_ui_text(prop, "Count Mid Cap", "Number of duplicates of Mid Cap");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dist_cap", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "distribution");
+ RNA_def_property_enum_items(prop, prop_mid_cap_items);
+ RNA_def_property_ui_text(prop, "Offset Mid Cap", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+}*/
+
static void rna_def_modifier_array(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ static EnumPropertyItem prop_type_items[] = {
+ {MOD_ARR_MOD_NRM, "REGULAR", 0, "Regular", "Standart Array"},
+ {MOD_ARR_MOD_CURVE, "PATH", 0, "Path", "Array along a path"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_material_items[] = {
+ {MOD_ARR_MAT, "RANDOM", 0, "Random", "Use a random material"},
+ {MOD_ARR_SEQ, "SEQUENCE", 0, "Sequence", "Use the materials in sequence"},
+ {0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_mid_cap_items[] = {
+ {MOD_ARR_DIST_SEQ, "SEQUENCE", 0, "Sequence", "Use the mid cap in sequence"},
+ {MOD_ARR_DIST_HALF, "HALF", 0, "Half", "Use the mid cap from the center"},
+ {MOD_ARR_DIST_CURVE, "CURVE", 0, "Curve", "Use the mid cap on points of the curve"},
+ {0, NULL, 0, NULL, NULL}};
+
static EnumPropertyItem prop_fit_type_items[] = {
{MOD_ARR_FIXEDCOUNT, "FIXED_COUNT", 0, "Fixed Count", "Duplicate the object a certain number of times"},
{MOD_ARR_FITLENGTH, "FIT_LENGTH", 0, "Fit Length", "Duplicate the object as many times as fits in a certain length"},
- {MOD_ARR_FITCURVE, "FIT_CURVE", 0, "Fit Curve", "Fit the duplicated objects to a curve"},
+ {MOD_ARR_FITBETWEEN, "FIT_BETWEEN", 0, "Fit Between", "Number of duplicates between two objects"},
{0, NULL, 0, NULL, NULL}};
+ static EnumPropertyItem prop_rays_dir_items[] = {
+ {MOD_ARR_RAYS_X, "X", 0, "X", "Rays Direction X"},
+ {MOD_ARR_RAYS_Y, "Y", 0, "Y", "Rays Direction Y"},
+ {MOD_ARR_RAYS_Z, "Z", 0, "Z", "Rays Direction Z"},
+ {0, NULL, 0, NULL, NULL}};
+
srna= RNA_def_struct(brna, "ArrayModifier", "Modifier");
RNA_def_struct_ui_text(srna, "Array Modifier", "Array duplication modifier");
RNA_def_struct_sdna(srna, "ArrayModifierData");
RNA_def_struct_ui_icon(srna, ICON_MOD_ARRAY);
/* Length parameters */
+ prop= RNA_def_property(srna, "type_array", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "type");
+ RNA_def_property_enum_items(prop, prop_type_items);
+ RNA_def_property_ui_text(prop, "Type Array", "Select if you want to do blender’s standart array or a array along a path");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop= RNA_def_property(srna, "fit_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, prop_fit_type_items);
RNA_def_property_ui_text(prop, "Fit Type", "Array length calculation method");
@@ -1468,6 +1540,11 @@
RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+ /*prop= RNA_def_property(srna, "use_between_offset", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "offset_type", MOD_ARR_OFF_BETW);
+ RNA_def_property_ui_text(prop, "Between Offset", "Number of duplicates between two objects");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");*/
+
/* Caps */
prop= RNA_def_property(srna, "start_cap", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "Start Cap", "Mesh object to use as a start cap");
@@ -1475,11 +1552,247 @@
RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+ /*prop= RNA_def_property(srna, "mid_cap", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "mid_cap");
+ RNA_def_property_struct_type(prop, "ObjectCap");
+ RNA_def_property_ui_text(prop, "Mid Cap", "Mesh object to use as a mid cap");*/
+
+ prop= RNA_def_property(srna, "mid_cap", PROP_POINTER, PROP_NONE);
+ RNA_def_property_ui_text(prop, "Mid Cap", "Mesh object to use as a mid cap");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_mid_cap_set", NULL, "rna_Mesh_object_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "count_mc", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 1000, 1, 0);
+ RNA_def_property_ui_text(prop, "Count Mid Cap", "Number of duplicates of Mid Cap");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dist_mid_cap", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "dist_mc");
+ RNA_def_property_enum_items(prop, prop_mid_cap_items);
+ RNA_def_property_ui_text(prop, "Offset Mid Cap", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "curve_cap", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "curve_cap");
+ RNA_def_property_ui_text(prop, "Curve Cap", "Curve to distribute Mid Cap");
+ RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_curve_cap_set", NULL, "rna_Curve_object_poll");
+ RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
+ RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop= RNA_def_property(srna, "first_start_cap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "outer_cp", MOD_ARR_CP_FIRST);
+ RNA_def_property_ui_text(prop, "First Start Cap", "Use Start Cap on the first control point");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "last_end_cap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "outer_cp", MOD_ARR_CP_LAST);
+ RNA_def_property_ui_text(prop, "Last End Cap", "Use End Cap on the last control point");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "use_advanced_mid_cap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", MOD_ARR_MOD_ADV_MID);
+ RNA_def_property_ui_text(prop, "Advanced MidCap", "Settings of the mid cap in an array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dis_advanced_mid_cap", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "displays", MOD_ARR_DIS_ADV_MID);
+ RNA_def_property_ui_text(prop, "Advanced MidCap", "Settings of the mid cap in an array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
prop= RNA_def_property(srna, "end_cap", PROP_POINTER, PROP_NONE);
RNA_def_property_ui_text(prop, "End Cap", "Mesh object to use as an end cap");
RNA_def_property_pointer_funcs(prop, NULL, "rna_ArrayModifier_end_cap_set", NULL, "rna_Mesh_object_poll");
RNA_def_property_flag(prop, PROP_EDITABLE|PROP_ID_SELF_CHECK);
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
+
+ prop= RNA_def_property(srna, "rand_mat_array", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "mat_ob", MOD_ARR_AR_MAT_RND);
+ RNA_def_property_ui_text(prop, "Array", "Material random to Array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rand_mat_sc", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "mat_ob", MOD_ARR_SC_MAT_RND);
+ RNA_def_property_ui_text(prop, "Start Cap", "Material random to Start Cap");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rand_mat_mc", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "mat_ob", MOD_ARR_MC_MAT_RND);
+ RNA_def_property_ui_text(prop, "Mid Cap", "Material random to Mid Cap");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rand_mat_ec", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "mat_ob", MOD_ARR_EC_MAT_RND);
+ RNA_def_property_ui_text(prop, "End Cap", "Material random to End Cap");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ /* Advanced parameters */
+ prop= RNA_def_property(srna, "use_advanced", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", MOD_ARR_MOD_ADV);
+ RNA_def_property_ui_text(prop, "Advanced", "Use Advanced Array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dis_advanced", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "displays", MOD_ARR_DIS_ADV);
+ RNA_def_property_ui_text(prop, "Advanced", "Use Advanced Array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "sign_p", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "sign", MOD_ARR_SIGN_P);
+ RNA_def_property_ui_text(prop, "+", "Random Sign Between + and -");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "sign_l", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "sign", MOD_ARR_SIGN_L);
+ RNA_def_property_ui_text(prop, "-", "Random Sign Between + and -");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "seed_t", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_range(prop, 1, 10000, 1, 0);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_int_sdna(prop, NULL, "seed[0]");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "seed_g", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_range(prop, 1, 10000, 1, 0);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_int_sdna(prop, NULL, "seed[1]");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "seed_m", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_ui_range(prop, 1, 10000, 1, 0);
+ RNA_def_property_range(prop, 1, 10000);
+ RNA_def_property_int_sdna(prop, NULL, "seed[2]");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Random Seed", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "location_offset", PROP_FLOAT, PROP_TRANSLATION);
+ RNA_def_property_float_sdna(prop, NULL, "loc_offset");
+ RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_ui_range(prop, 0, FLT_MAX, 1, 5);
+ RNA_def_property_ui_text(prop, "Location Offset Displacement", "Add a location offset to vertices or object");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rotation_offset", PROP_FLOAT, PROP_EULER);
+ RNA_def_property_float_sdna(prop, NULL, "rot_offset");
+ RNA_def_property_ui_text(prop, "Rotation Offset Displacement", "Add a rotation offset to vertices or object");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "scale_offset", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "scale_offset");
+ RNA_def_property_range(prop, 0, 10);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Scale Offset Displacement", "Add a scale offset to vertices or object");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "lock_loc", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "lock", MOD_ARR_LOCK_LOC);
+ RNA_def_property_ui_text(prop, "Lock location", "Lock location");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "lock_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "lock", MOD_ARR_LOCK_SCALE);
+ RNA_def_property_ui_text(prop, "Lock scale", "Lock scale");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "lock_rot", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "lock", MOD_ARR_LOCK_ROT);
+ RNA_def_property_ui_text(prop, "Lock rotation", "Lock rotation");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
+ RNA_def_property_float_sdna(prop, NULL, "scale_offset[0]");
+ RNA_def_property_range(prop, 0, 10);
+ RNA_def_property_ui_range(prop, 0, 10, 1, 3);
+ RNA_def_property_ui_text(prop, "Scale Offset Displacement", "Add a scale offset to vertices or object");
+ RNA_def_property_update(prop, NC_OBJECT|ND_TRANSFORM, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "proportion", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag_offset", MOD_ARR_PROP);
+ RNA_def_property_ui_text(prop, "Constrain Proportions", "Constrain Proportions");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "local_rot", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag_offset", MOD_ARR_LOCAL);
+ RNA_def_property_ui_text(prop, "Local Rotation Offset Displacement", "Add a local rotation offset to vertices or object");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "material", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "rand_mat");
+ RNA_def_property_enum_items(prop, prop_material_items);
+ RNA_def_property_ui_text(prop, "Offset Material", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "cont_mat", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, INT_MAX);
+ RNA_def_property_ui_range(prop, 1, 1000, 1, 0);
+ RNA_def_property_ui_text(prop, "Count Material", "Repetition of material");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "use_advanced_clone", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", MOD_ARR_MOD_ADV_CLONE);
+ RNA_def_property_ui_text(prop, "Advanced Clone", "Set other types of Cloning");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dis_advanced_clone", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "displays", MOD_ARR_DIS_ADV_CLONE);
+ RNA_def_property_ui_text(prop, "Advanced Clone", "Set other types of Cloning");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rays", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 1, 365);
+ RNA_def_property_ui_range(prop, 1, 365, 1,0);
+ RNA_def_property_ui_text(prop, "Rays", "Rays");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rays_dir", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, prop_rays_dir_items);
+ RNA_def_property_ui_text(prop, "Rays Direction", "");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "array_group", PROP_POINTER, PROP_NONE);
+ RNA_def_property_pointer_sdna(prop, NULL, "arr_group");
+ RNA_def_property_struct_type(prop, "Group");
+ RNA_def_property_flag(prop, PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Dupli Group", "Show Group");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rand_group", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "rand_group", MOD_ARR_RAND_GROUP);
+ RNA_def_property_ui_text(prop, "Rand Object", "Object random group");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "rand_mat_group", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "rand_group", MOD_ARR_RAND_MAT_GROUP);
+ RNA_def_property_ui_text(prop, "Dupli Group", "Material random to Dupli Group");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "all_curve", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "dist_cu", MOD_ARR_DIST_EVENLY);
+ RNA_def_property_ui_text(prop, "Spread Evenly", "Spread evenly on a curve");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "for_segment", PROP_BOOLEAN, PROP_TRANSLATION);
+ RNA_def_property_boolean_sdna(prop, NULL, "dist_cu", MOD_ARR_DIST_SEGMENT);
+ RNA_def_property_ui_text(prop, "For Segment", "Spread evenly for all segments");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "use_advanced_material", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "mode", MOD_ARR_MOD_ADV_MAT);
+ RNA_def_property_ui_text(prop, "Advanced Material", "Settings of the material in an array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop= RNA_def_property(srna, "dis_advanced_material", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "displays", MOD_ARR_DIS_ADV_MAT);
+ RNA_def_property_ui_text(prop, "Advanced Material", "Settings of the material in an array");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_edgesplit(BlenderRNA *brna)
@@ -3140,6 +3453,7 @@
rna_def_modifier_hook(brna);
rna_def_modifier_softbody(brna);
rna_def_modifier_boolean(brna);
+ //rna_def_object_cap(brna);
rna_def_modifier_array(brna);
rna_def_modifier_edgesplit(brna);
rna_def_modifier_displace(brna);
Index: source/blender/modifiers/intern/MOD_array.c
===================================================================
--- source/blender/modifiers/intern/MOD_array.c (revisione 43767)
+++ source/blender/modifiers/intern/MOD_array.c (copia locale)
@@ -35,6 +35,8 @@
/* Array modifier: duplicates the object multiple times along an axis */
+#include <time.h>
+#include <math.h>
#include "MEM_guardedalloc.h"
#include "BLI_math.h"
@@ -43,6 +45,7 @@
#include "BLI_edgehash.h"
#include "DNA_curve_types.h"
+#include "DNA_group_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@@ -51,9 +54,12 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_anim.h"
+//#include "BLI_rand.h"
+
#include "depsgraph_private.h"
-
+#include "BKE_ama.h"
#include "MOD_util.h"
static void initData(ModifierData *md)
@@ -63,7 +69,7 @@
/* default to 2 duplicates distributed along the x-axis by an
offset of 1 object-width
*/
- amd->start_cap = amd->end_cap = amd->curve_ob = amd->offset_ob = NULL;
+ amd->start_cap = amd->mid_cap = amd->end_cap = amd->curve_cap = amd->curve_ob = amd->offset_ob = NULL;
amd->count = 2;
amd->offset[0] = amd->offset[1] = amd->offset[2] = 0;
amd->scale[0] = 1;
@@ -73,6 +79,29 @@
amd->fit_type = MOD_ARR_FIXEDCOUNT;
amd->offset_type = MOD_ARR_OFF_RELATIVE;
amd->flags = 0;
+ amd->seed[0] = amd->seed[1] = amd->seed[2] = 0;
+ amd->type = MOD_ARR_MOD_NRM;
+ amd->mode = !MOD_ARR_MOD_ADV;
+ amd->displays = !MOD_ARR_DIS_ADV;
+ amd->loc_offset[0] = amd->loc_offset[1] = amd->loc_offset[2] = 0;
+ amd->rot_offset[0] = amd->rot_offset[1] = amd->rot_offset[2] = 0;
+ amd->scale_offset[0] = amd->scale_offset[1] = amd->scale_offset[2] = 1;
+ amd->sign = MOD_ARR_SIGN_P + MOD_ARR_SIGN_L;
+ amd->lock = MOD_ARR_LOCK;
+ amd->flag_offset = MOD_ARR_PROP + MOD_ARR_LOCAL;
+ amd->rays = 1;
+ amd->rand_mat = MOD_ARR_MAT;
+ amd->mat_ob = MOD_ARR_AR_MAT_RND;
+ amd->cont_mat = 1;
+ amd->count_mc = 1;
+ amd->dist_mc = MOD_ARR_DIST_SEQ;
+ amd->rays_dir = MOD_ARR_RAYS_X;
+ amd->arr_group = NULL;
+ amd->rand_group = !MOD_ARR_RAND_GROUP;
+ amd->dist_cu = MOD_ARR_DIST_EVENLY;
+ amd->outer_cp = !MOD_ARR_CP_FIRST;
+ amd->Mem_Mat_Ob.start_cap = 0;
+ amd->Mem_Mat_Ob.end_cap = 0;
}
static void copyData(ModifierData *md, ModifierData *target)
@@ -81,7 +110,9 @@
ArrayModifierData *tamd = (ArrayModifierData*) target;
tamd->start_cap = amd->start_cap;
+ tamd->mid_cap = amd->mid_cap;
tamd->end_cap = amd->end_cap;
+ tamd->curve_cap = amd->curve_cap;
tamd->curve_ob = amd->curve_ob;
tamd->offset_ob = amd->offset_ob;
tamd->count = amd->count;
@@ -92,6 +123,31 @@
tamd->fit_type = amd->fit_type;
tamd->offset_type = amd->offset_type;
tamd->flags = amd->flags;
+ copy_v3_v3_int(tamd->seed, amd->seed);
+ tamd->type = amd->type;
+ tamd->mode = amd->mode;
+ tamd->displays = amd->displays;
+ copy_v3_v3(tamd->loc_offset, amd->loc_offset);
+ copy_v3_v3(tamd->rot_offset, amd->rot_offset);
+ copy_v3_v3(tamd->scale_offset, amd->scale_offset);
+ tamd->sign = amd->sign;
+ tamd->lock = amd->lock;
+ tamd->flag_offset = amd->flag_offset;
+ tamd->rays = amd->rays;
+ tamd->Mem_Ob = MEM_dupallocN(amd->Mem_Ob);
+ tamd->Mem_Mat_Ob.start_cap = amd->Mem_Mat_Ob.start_cap;
+ tamd->Mem_Mat_Ob.end_cap = amd->Mem_Mat_Ob.end_cap;
+ tamd->Mem_Mat_Ob.mid_cap = MEM_dupallocN(amd->Mem_Mat_Ob.mid_cap);
+ tamd->rand_mat = amd->rand_mat;
+ tamd->mat_ob = amd->mat_ob;
+ tamd->cont_mat = amd->cont_mat;
+ tamd->count_mc = amd->count_mc;
+ tamd->dist_mc = amd->dist_mc;
+ tamd->rays_dir = amd->rays_dir;
+ tamd->arr_group = amd->arr_group;
+ tamd->rand_group = amd->rand_group;
+ tamd->dist_cu = amd->dist_cu;
+ tamd->outer_cp = amd->outer_cp;
}
static void foreachObjectLink(
@@ -102,8 +158,10 @@
ArrayModifierData *amd = (ArrayModifierData*) md;
walk(userData, ob, &amd->start_cap);
+ walk(userData, ob, &amd->mid_cap);
walk(userData, ob, &amd->end_cap);
walk(userData, ob, &amd->curve_ob);
+ walk(userData, ob, &amd->curve_cap);
walk(userData, ob, &amd->offset_ob);
}
@@ -118,6 +176,12 @@
dag_add_relation(forest, curNode, obNode,
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
}
+ if (amd->mid_cap) {
+ DagNode *curNode = dag_get_node(forest, amd->mid_cap);
+
+ dag_add_relation(forest, curNode, obNode,
+ DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
+ }
if (amd->end_cap) {
DagNode *curNode = dag_get_node(forest, amd->end_cap);
@@ -130,6 +194,12 @@
dag_add_relation(forest, curNode, obNode,
DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
}
+ if (amd->curve_cap) {
+ DagNode *curNode = dag_get_node(forest, amd->curve_cap);
+
+ dag_add_relation(forest, curNode, obNode,
+ DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Array Modifier");
+ }
if (amd->offset_ob) {
DagNode *curNode = dag_get_node(forest, amd->offset_ob);
@@ -138,105 +208,29 @@
}
}
-static float vertarray_size(MVert *mvert, int numVerts, int axis)
-{
- int i;
- float min_co, max_co;
-
- /* if there are no vertices, width is 0 */
- if(numVerts == 0) return 0;
-
- /* find the minimum and maximum coordinates on the desired axis */
- min_co = max_co = mvert->co[axis];
- ++mvert;
- for(i = 1; i < numVerts; ++i, ++mvert) {
- if(mvert->co[axis] < min_co) min_co = mvert->co[axis];
- if(mvert->co[axis] > max_co) max_co = mvert->co[axis];
- }
-
- return max_co - min_co;
-}
-
-/* XXX This function fixes bad merging code, in some cases removing vertices creates indices > maxvert */
-
-static int test_index_face_maxvert(MFace *mface, CustomData *fdata, int mfindex, int nr, int maxvert)
-{
- if(mface->v1 >= maxvert) {
- // printf("bad index in array\n");
- mface->v1= maxvert - 1;
- }
- if(mface->v2 >= maxvert) {
- // printf("bad index in array\n");
- mface->v2= maxvert - 1;
- }
- if(mface->v3 >= maxvert) {
- // printf("bad index in array\n");
- mface->v3= maxvert - 1;
- }
- if(mface->v4 >= maxvert) {
- // printf("bad index in array\n");
- mface->v4= maxvert - 1;
- }
-
- return test_index_face(mface, fdata, mfindex, nr);
-}
-
-typedef struct IndexMapEntry {
- /* the new vert index that this old vert index maps to */
- int new;
- /* -1 if this vert isn't merged, otherwise the old vert index it
- * should be replaced with
- */
- int merge;
- /* 1 if this vert's first copy is merged with the last copy of its
- * merge target, otherwise 0
- */
- short merge_final;
-} IndexMapEntry;
-
-/* indexMap - an array of IndexMap entries
- * oldIndex - the old index to map
- * copyNum - the copy number to map to (original = 0, first copy = 1, etc.)
- */
-static int calc_mapping(IndexMapEntry *indexMap, int oldIndex, int copyNum)
-{
- if(indexMap[oldIndex].merge < 0) {
- /* vert wasn't merged, so use copy of this vert */
- return indexMap[oldIndex].new + copyNum;
- } else if(indexMap[oldIndex].merge == oldIndex) {
- /* vert was merged with itself */
- return indexMap[oldIndex].new;
- } else {
- /* vert was merged with another vert */
- /* follow the chain of merges to the end, or until we've passed
- * a number of vertices equal to the copy number
- */
- if(copyNum <= 0)
- return indexMap[oldIndex].new;
- else
- return calc_mapping(indexMap, indexMap[oldIndex].merge,
- copyNum - 1);
- }
-}
-
static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
struct Scene *scene, Object *ob, DerivedMesh *dm,
int initFlags)
{
- int i, j;
/* offset matrix */
float offset[4][4];
float final_offset[4][4];
- float tmp_mat[4][4];
+ float mid_offset[4][4], half_offset[4][4];
+ float tmp_mat[4][4], prec_mid[4][4];
float length = amd->length;
+ float alpha = 0, d_alp = 0, circle;
+ float f_o;
+ int i, j;
+ int start, start_mc;
int count = amd->count;
int numVerts, numEdges, numFaces;
int maxVerts, maxEdges, maxFaces;
int finalVerts, finalEdges, finalFaces;
- DerivedMesh *result, *start_cap = NULL, *end_cap = NULL;
+ DerivedMesh *result, *start_cap = NULL, *mid_cap = NULL, *end_cap = NULL;
MVert *mvert, *src_mvert;
MEdge *medge;
MFace *mface;
+ Nurb *nu = NULL;
IndexMapEntry *indexMap;
@@ -245,8 +239,13 @@
/* need to avoid infinite recursion here */
if(amd->start_cap && amd->start_cap != ob)
start_cap = amd->start_cap->derivedFinal;
+ if(amd->mid_cap && amd->mid_cap != ob)
+ mid_cap = amd->mid_cap->derivedFinal;
if(amd->end_cap && amd->end_cap != ob)
end_cap = amd->end_cap->derivedFinal;
+
+ if (amd->count_mc < 1)
+ amd->count_mc = 1;
unit_m4(offset);
@@ -279,69 +278,199 @@
NULL, NULL, NULL, NULL, NULL);
copy_m4_m4(offset, result_mat);
}
+
+ if ((amd->type & MOD_ARR_MOD_CURVE) && (amd->curve_ob))
+ length = length_fitcurve(amd, scene);
- if(amd->fit_type == MOD_ARR_FITCURVE && amd->curve_ob) {
- Curve *cu = amd->curve_ob->data;
- if(cu) {
- float tmp_mat[3][3];
- float scale;
-
- object_to_mat3(amd->curve_ob, tmp_mat);
- scale = mat3_to_scale(tmp_mat);
-
- if(!cu->path) {
- cu->flag |= CU_PATH; // needed for path & bevlist
- makeDispListCurveTypes(scene, amd->curve_ob, 0);
- }
- if(cu->path)
- length = scale*cu->path->totdist;
+ /* calculate the maximum number of copies which will fit within the
+ prescribed length */
+ if (amd->fit_type & MOD_ARR_FITLENGTH) { // || (amd->type & MOD_ARR_MOD_CURVE)) {
+ if (amd->type & MOD_ARR_MOD_NRM) {
+ count = length_to_count(length, offset[3]);
+ amd->count = count;
}
+ else {
+ count = length_to_count(amd->length, offset[3]);
+ amd->count = count;
+ }
}
+ else {
+ if ((amd->type & MOD_ARR_MOD_CURVE) && (amd->curve_ob)) {
+ amd->length = length;
+ }
+ else {
+ amd->length = count_to_length(count, offset[3]);
+ length = amd->length;
+ }
+ }
- /* calculate the maximum number of copies which will fit within the
- prescribed length */
- if(amd->fit_type == MOD_ARR_FITLENGTH
- || amd->fit_type == MOD_ARR_FITCURVE) {
- float dist = sqrt(dot_v3v3(offset[3], offset[3]));
-
- if(dist > 1e-6f)
- /* this gives length = first copy start to last copy end
- add a tiny offset for floating point rounding errors */
- count = (length + 1e-6f) / dist;
- else
- /* if the offset has no translation, just make one copy */
- count = 1;
+ if (amd->fit_type & MOD_ARR_FITBETWEEN) {
+ count = count + 2;
+ if (amd->type & MOD_ARR_MOD_NRM) {
+ if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
+ //float dist = sqrt(dot_v3v3(amd->offset_ob->obmat[3], amd->offset_ob->obmat[3]));
+ offset[3][0] = amd->offset_ob->obmat[3][0] / (count - 1);
+ offset[3][1] = amd->offset_ob->obmat[3][1] / (count - 1);
+ offset[3][2] = amd->offset_ob->obmat[3][2] / (count - 1);
+ }
+ else {
+ offset[3][0] = offset[3][0] / (count - 1);
+ offset[3][1] = offset[3][1] / (count - 1);
+ offset[3][2] = offset[3][2] / (count - 1);
+ }
+ }
+ else { /* amd->type & MOD_ARR_MOD_CURVE*/
+ Curve *cu = amd->curve_ob->data;
+ nu = cu->nurb.first;
+ if (nu->bezt)
+ copy_v3_v3(offset[3], nu->bezt[nu->pntsu - 1].vec[1]);
+ else
+ copy_v3_v3(offset[3], nu->bp[nu->pntsu * nu->pntsv - 1].vec);
+ offset[3][0] = offset[3][0] / (count - 1);
+ offset[3][1] = offset[3][1] / (count - 1);
+ offset[3][2] = offset[3][2] / (count - 1);
+ }
}
if(count < 1)
count = 1;
+
+ /**/
+ if ((amd->dist_mc & MOD_ARR_DIST_CURVE) && (amd->curve_cap)){
+ int dec = 0;
+ Curve *cu = amd->curve_cap->data;
+ nu = cu->nurb.first;
+ unit_m4(mid_offset);
+ if (amd->outer_cp & MOD_ARR_CP_FIRST && amd->start_cap)
+ dec = dec + 1;
+ if (amd->outer_cp & MOD_ARR_CP_LAST && amd->end_cap)
+ dec = dec + 1;
+ if (nu->bezt) {
+ if (amd->outer_cp & MOD_ARR_CP_FIRST && amd->start_cap)
+ copy_v3_v3(mid_offset[3], nu->bezt[1].vec[1]);
+ else
+ copy_v3_v3(mid_offset[3], nu->bezt[0].vec[1]);
+ if (amd->count_mc > (nu->pntsu - dec))
+ amd->count_mc = nu->pntsu - dec;
+ }
+ else {
+ if (amd->outer_cp & MOD_ARR_CP_FIRST && amd->start_cap)
+ copy_v3_v3(mid_offset[3], nu->bp[1].vec);
+ else
+ copy_v3_v3(mid_offset[3], nu->bp[0].vec);
+ if (amd->count_mc > (nu->pntsu * nu->pntsv - dec))
+ amd->count_mc = nu->pntsu * nu->pntsv - dec;
+ }
+ }
+ else
+ if (amd->count_mc >= count)
+ amd->count_mc = count - 1;
/* allocate memory for count duplicates (including original) plus
- * start and end caps
+ * start, mid and end caps
*/
finalVerts = dm->getNumVerts(dm) * count;
finalEdges = dm->getNumEdges(dm) * count;
finalFaces = dm->getNumFaces(dm) * count;
+
if(start_cap) {
finalVerts += start_cap->getNumVerts(start_cap);
finalEdges += start_cap->getNumEdges(start_cap);
finalFaces += start_cap->getNumFaces(start_cap);
}
+ if(mid_cap) {
+ finalVerts += mid_cap->getNumVerts(mid_cap) * amd->count_mc;
+ finalEdges += mid_cap->getNumEdges(mid_cap) * amd->count_mc;
+ finalFaces += mid_cap->getNumFaces(mid_cap) * amd->count_mc;
+ }
if(end_cap) {
finalVerts += end_cap->getNumVerts(end_cap);
finalEdges += end_cap->getNumEdges(end_cap);
finalFaces += end_cap->getNumFaces(end_cap);
}
+
result = CDDM_from_template(dm, finalVerts, finalEdges, finalFaces);
+
+ if ((amd->mode & MOD_ARR_MOD_ADV) || (amd->mode & MOD_ARR_MOD_ADV_MAT)) {
+ start = 0;
+ start_mc = 0;
+ if (!amd->Mem_Ob)
+ amd->Mem_Ob = MEM_callocN(sizeof(*amd->Mem_Ob) * count, "Mem_Ob");
+ else {
+ int dim = 0;
+ dim = MEM_allocN_len(amd->Mem_Ob) / sizeof(*amd->Mem_Ob);
+ if (dim != count) {
+ amd->Mem_Ob = MEM_reallocN(amd->Mem_Ob, sizeof(*amd->Mem_Ob) * count);
+ if (dim < count)
+ start = dim;
+ else if (dim > count)
+ start = amd->count;
+ }
+ }
+ if (!amd->Mem_Mat_Ob.mid_cap)
+ amd->Mem_Mat_Ob.mid_cap = MEM_callocN(sizeof(int) * (amd->count_mc), "Mem_Mat_Ob");
+ else {
+ int dim = 0;
+ dim = MEM_allocN_len(amd->Mem_Mat_Ob.mid_cap) / sizeof(*amd->Mem_Mat_Ob.mid_cap);
+ if (dim != amd->count_mc) {
+ amd->Mem_Mat_Ob.mid_cap = MEM_reallocN(amd->Mem_Mat_Ob.mid_cap, sizeof(*amd->Mem_Mat_Ob.mid_cap) * amd->count_mc);
+ if (dim < amd->count_mc)
+ start_mc = dim;
+ else if (dim > amd->count_mc)
+ start_mc = amd->count_mc;
+ }
+ }
+ //Inizializzare i nuovi cloni creati
+ if (amd->Mem_Mat_Ob.mid_cap) {
+ if ((start_mc != 0) && (start_mc != amd->count_mc))
+ init_mat_oc(start_mc, amd->count_mc, amd->Mem_Mat_Ob.mid_cap);
+ }
+ if ((start != 0) && (start != count))
+ init_offset(start, count, amd);
+ create_offset(count, ob->totcol, amd, ob);
+ }
+
+ f_o = count-1;
+
+ if (amd->rays>1) {
+ alpha = (float)6.2831 / amd->rays;
+ circle = (float)(count - 1) / amd->rays;
+ f_o = ceil(circle);
+ }
+
/* calculate the offset matrix of the final copy (for merging) */
unit_m4(final_offset);
-
- for(j=0; j < count - 1; j++) {
+ for(j=0; j < f_o; j++) {
mult_m4_m4m4(tmp_mat, offset, final_offset);
copy_m4_m4(final_offset, tmp_mat);
}
-
+
+ if (amd->dist_mc & MOD_ARR_DIST_SEQ){
+ copy_m4_m4(mid_offset, offset);
+ mid_offset[3][0] = mid_offset[3][0] / 2;
+ mid_offset[3][1] = mid_offset[3][1] / 2;
+ mid_offset[3][2] = mid_offset[3][2] / 2;
+ if (amd->mode & MOD_ARR_MOD_ADV) {
+ if (amd->Mem_Ob[0].transform) {
+ float app[4][4];
+ unit_m4(app);
+ loc_eul_size_to_mat4(app, amd->Mem_Ob[0].loc, amd->Mem_Ob[0].rot, amd->Mem_Ob[0].scale);
+ copy_m4_m4(prec_mid, mid_offset);
+ copy_m4_m4(tmp_mat, mid_offset);
+ mult_m4_m4m4(mid_offset, tmp_mat, app);
+ }
+ }
+ }
+ else if (amd->dist_mc & MOD_ARR_DIST_HALF){
+ copy_m4_m4(half_offset, final_offset);
+ half_offset[3][0] = half_offset[3][0] / (amd->count_mc + 1);
+ half_offset[3][1] = half_offset[3][1] / (amd->count_mc + 1);
+ half_offset[3][2] = half_offset[3][2] / (amd->count_mc + 1);
+ copy_m4_m4(mid_offset, half_offset);
+ }
+
+ copy_m4_m4(amd->delta, offset);
numVerts = numEdges = numFaces = 0;
mvert = CDDM_get_verts(result);
@@ -397,18 +526,130 @@
}
}
}
-
/* if no merging, generate copies of this vert */
if(indexMap[i].merge < 0) {
+ if (amd->rays>1)
+ d_alp=0;
+
for(j=0; j < count - 1; j++) {
+ float rot[4][4];
mv2 = &mvert[numVerts];
DM_copy_vert_data(result, result, numVerts - 1, numVerts, 1);
*mv2 = *mv;
numVerts++;
+ /*//Aggiungendo questa parte ed eliminando 1) e 2)
+ //si ottiene una spirale
+ mul_m4_v3(offset, co);
+ copy_v3_v3(mv2->co, co);*/
+
+ if ((amd->mode & MOD_ARR_MOD_ADV_CLONE) && (amd->rays>1)) {
+ float ro[3];
+ unit_m4(rot);
+ if (amd->rays_dir == MOD_ARR_RAYS_X)
+ rotate_m4(rot,'X',d_alp);
+ else if (amd->rays_dir == MOD_ARR_RAYS_Y)
+ rotate_m4(rot,'Y',d_alp);
+ else
+ rotate_m4(rot,'Z',d_alp);
+ if (d_alp == 0){
+ /*1)*/
+ mul_m4_v3(offset, co);
+ copy_v3_v3(mv2->co, co);
+ /******/
+ copy_v3_v3(ro, mv2->co);
+ mul_m4_v3(rot, ro);
+ copy_v3_v3(mv2->co, ro);
+ }
+ else {
+ copy_v3_v3(ro,co);
+ mul_m4_v3(rot, ro);
+ copy_v3_v3(mv2->co, ro);
+ }
+ d_alp = d_alp + alpha;
+ if (d_alp>6.2831)
+ d_alp=0;
+ }
+ else {
+ /*2)*/
+ mul_m4_v3(offset, co);
+ copy_v3_v3(mv2->co, co);
+ /******/
+ }
- mul_m4_v3(offset, co);
- copy_v3_v3(mv2->co, co);
+ if (amd->mode & MOD_ARR_MOD_ADV) {
+ if (amd->Mem_Ob[j].transform) {
+ float fo[3];
+ float app[4][4];
+ unit_m4(app);
+
+ if (amd->flag_offset & MOD_ARR_LOCAL) {
+ float loc[4][4];
+
+ /* copy of the original coordinates */
+ copy_v3_v3(fo, mv->co);
+ copy_v3_v3(app[3], fo);
+ loc_eul_size_to_mat4(app, amd->Mem_Ob[j].loc, amd->Mem_Ob[j].rot, amd->Mem_Ob[j].scale);
+ mul_m4_v3(app, fo);
+ /* recalculates the offset of the clone */
+ copy_m4_m4(loc, offset);
+ mul_v3_fl(loc[3], j+1);
+ //unit_m4(loc);
+ //copy_v3_v3(loc[3], mv2->co);
+ /* calculates the new coordinates of the clone */
+ //mult_m4_m4m4(loc, loc, app);
+
+ //print_m4("loc", loc);
+ //print_v3("fo", fo);
+ mul_m4_v3(loc, fo);
+ //print_v3("fo-r", fo);
+ copy_v3_v3(mv2->co, fo);
+ }
+ else {
+ loc_eul_size_to_mat4(app, amd->Mem_Ob[j].loc, amd->Mem_Ob[j].rot, amd->Mem_Ob[j].scale);
+ copy_v3_v3(fo, mv2->co);
+ mul_m4_v3(app, fo);
+ copy_v3_v3(mv2->co, fo);
+ }
+ }
+ }
+
+ if ((amd->type & MOD_ARR_MOD_CURVE) && (amd->curve_ob)) {
+ if (amd->dist_cu & MOD_ARR_DIST_EVENLY) {
+ /*if (i==0){
+ float fo[3];
+ float cent[3];
+ float loc[4];
+ float app[4][4];
+
+ unit_m4(app);
+ copy_v3_v3(fo, mv2->co);
+ array_to_curve(scene, amd->curve_ob, ob, fo, loc, cent);
+ copy_v3_v3(amd->Mem_Ob[j].cu_cent, cent);
+ copy_v4_v4(amd->Mem_Ob[j].cu_loc, loc);
+ copy_v3_v3(app[3], amd->Mem_Ob[j].cu_loc);
+ mul_m4_v3(app, fo);
+ //add_v3_v3v3(fo, cent, loc);
+ copy_v3_v3(mv2->co, fo);
+ }
+ else {
+ float fo[3];
+ float app[4][4];
+ unit_m4(app);
+ copy_v3_v3(fo, mv2->co);
+ /*print_v3("cent", amd->Mem_Ob[j].cu_cent);
+ print_v4("loc", amd->Mem_Ob[j].cu_loc);*/
+ /* add_v3_v3v3(fo, amd->Mem_Ob[j].cu_cent, amd->Mem_Ob[j].cu_loc); */
+ /* copy_v3_v3(app[3], amd->Mem_Ob[j].cu_loc);
+ mul_m4_v3(app, fo);
+ print_v3("fo", fo);
+ copy_v3_v3(mv2->co, fo);
+ }*/
+ }
+ else { /* MOD_ARR_DIST_SEGMENT */
+
+ }
+ }
}
} else if(indexMap[i].merge != i && indexMap[i].merge_final) {
/* if this vert is not merging with itself, and it is merging
@@ -553,6 +794,9 @@
numFaces++;
+ /*Rand Material*/
+ if ((amd->mode & MOD_ARR_MOD_ADV_MAT) && (amd->mat_ob & MOD_ARR_AR_MAT_RND) && (ob->totcol>1))
+ mf2->mat_nr = amd->Mem_Ob[j-1].id_mat;
/* if the face has fewer than 3 vertices, don't create it */
if(test_index_face_maxvert(mf2, &result->faceData, numFaces-1, inMF.v4?4:3, numVerts) < 3) {
numFaces--;
@@ -561,7 +805,7 @@
}
}
- /* add start and end caps */
+ /* add start, mid and end caps */
if(start_cap) {
float startoffset[4][4];
MVert *cap_mvert;
@@ -580,6 +824,14 @@
invert_m4_m4(startoffset, offset);
+ if (amd->dist_mc & MOD_ARR_DIST_CURVE) {
+ if (amd->outer_cp & MOD_ARR_CP_FIRST && amd->start_cap && amd->curve_cap) {
+ if (nu->bezt)
+ copy_v3_v3(startoffset[3], nu->bezt[0].vec[1]);
+ else
+ copy_v3_v3(startoffset[3], nu->bp[0].vec);
+ }
+ }
vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
"arrayModifier_doArray vert_map");
@@ -653,7 +905,8 @@
test_index_face(&mface[numFaces], &result->faceData,
numFaces, 3);
}
-
+ if ((amd->mode & MOD_ARR_MOD_ADV_MAT) && (amd->mat_ob & MOD_ARR_SC_MAT_RND) && (ob->totcol>1))
+ mface[numFaces].mat_nr = amd->Mem_Mat_Ob.start_cap;
origindex[numFaces] = ORIGINDEX_NONE;
numFaces++;
@@ -662,7 +915,183 @@
MEM_freeN(vert_map);
start_cap->release(start_cap);
}
+
+ if ((mid_cap) && ((amd->dist_mc & MOD_ARR_DIST_SEQ) || (amd->dist_mc & MOD_ARR_DIST_HALF) ||
+ ((amd->dist_mc & MOD_ARR_DIST_CURVE) && (amd->curve_cap)))) {
+ MVert *cap_mvert;
+ MEdge *cap_medge;
+ MFace *cap_mface;
+ float d_alp_md, alpha_md;
+ int *origindex;
+ int *vert_map;
+ int capVerts, capEdges, capFaces;
+ int inc, c_mc;
+ capVerts = mid_cap->getNumVerts(mid_cap);
+ capEdges = mid_cap->getNumEdges(mid_cap);
+ capFaces = mid_cap->getNumFaces(mid_cap);
+ cap_mvert = mid_cap->getVertArray(mid_cap);
+ cap_medge = mid_cap->getEdgeArray(mid_cap);
+ cap_mface = mid_cap->getFaceArray(mid_cap);
+
+ /*d_alp_md = 0;
+ if (amd->rays > 1)
+ alpha_md = (float)6.2831 / amd->rays;*/
+ if (amd->mode & MOD_ARR_MOD_ADV_MID)
+ c_mc = amd->count_mc;
+ else {
+ c_mc = 1;
+ copy_m4_m4(mid_offset, offset);
+ mid_offset[3][0] = mid_offset[3][0] / 2;
+ mid_offset[3][1] = mid_offset[3][1] / 2;
+ mid_offset[3][2] = mid_offset[3][2] / 2;
+ }
+
+ vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
+ "arrayModifier_doArray vert_map");
+ for(j=0; j < c_mc; j++) {
+
+ origindex = result->getVertDataArray(result, CD_ORIGINDEX);
+ for(i = 0; i < capVerts; i++) {
+ MVert *mv = &cap_mvert[i];
+ short merged = 0;
+
+ if(amd->flags & MOD_ARR_MERGE) {
+ float tmp_co[3];
+ MVert *in_mv;
+ int k;
+
+ copy_v3_v3(tmp_co, mv->co);
+ mul_m4_v3(mid_offset, tmp_co);
+ for(k = 0; k < maxVerts; k++) {
+ in_mv = &src_mvert[k];
+ /* if this vert is within merge limit, merge */
+ if(compare_len_v3v3(tmp_co, in_mv->co, amd->merge_dist)) {
+ vert_map[i] = calc_mapping(indexMap, k, 0);
+ merged = 1;
+ break;
+ }
+ }
+ }
+
+ if(!merged) {
+ DM_copy_vert_data(mid_cap, result, i, numVerts, 1);
+ mvert[numVerts] = *mv;
+ mul_m4_v3(mid_offset, mvert[numVerts].co);
+ origindex[numVerts] = ORIGINDEX_NONE;
+ vert_map[i] = numVerts;
+ numVerts++;
+ }
+ }
+
+ origindex = result->getEdgeDataArray(result, CD_ORIGINDEX);
+ for(i = 0; i < capEdges; i++) {
+ int v1, v2;
+
+ v1 = vert_map[cap_medge[i].v1];
+ v2 = vert_map[cap_medge[i].v2];
+
+ if(!BLI_edgehash_haskey(edges, v1, v2)) {
+ DM_copy_edge_data(mid_cap, result, i, numEdges, 1);
+ medge[numEdges] = cap_medge[i];
+ medge[numEdges].v1 = v1;
+ medge[numEdges].v2 = v2;
+ origindex[numEdges] = ORIGINDEX_NONE;
+
+ numEdges++;
+ }
+ }
+
+ origindex = result->getFaceDataArray(result, CD_ORIGINDEX);
+ for(i = 0; i < capFaces; i++) {
+ DM_copy_face_data(mid_cap, result, i, numFaces, 1);
+ mface[numFaces] = cap_mface[i];
+ mface[numFaces].v1 = vert_map[mface[numFaces].v1];
+ mface[numFaces].v2 = vert_map[mface[numFaces].v2];
+ mface[numFaces].v3 = vert_map[mface[numFaces].v3];
+ if(mface[numFaces].v4) {
+ mface[numFaces].v4 = vert_map[mface[numFaces].v4];
+
+ test_index_face_maxvert(&mface[numFaces], &result->faceData,
+ numFaces, 4, numVerts);
+ }
+ else
+ {
+ test_index_face(&mface[numFaces], &result->faceData,
+ numFaces, 3);
+ }
+ if ((amd->mode & MOD_ARR_MOD_ADV_MAT) && (amd->mat_ob & MOD_ARR_MC_MAT_RND) && (ob->totcol>1))
+ mface[numFaces].mat_nr = amd->Mem_Mat_Ob.mid_cap[j];
+ origindex[numFaces] = ORIGINDEX_NONE;
+ numFaces++;
+ }
+
+ if (amd->dist_mc & MOD_ARR_DIST_SEQ){
+ /********/
+ /*if (amd->rays>1) {
+ float rot[4][4];
+ unit_m4(rot);
+ if (amd->rays_dir == MOD_ARR_RAYS_X)
+ rotate_m4(rot,'X',d_alp_md);
+ else if (amd->rays_dir == MOD_ARR_RAYS_Y)
+ rotate_m4(rot,'Y',d_alp_md);
+ else
+ rotate_m4(rot,'Z',d_alp_md);
+ if (d_alp_md == 0){
+ mult_m4_m4m4(mid_offset, tmat, offset);
+
+ copy_m4_m4(tmat, mid_offset);
+ mult_m4_m4m4(mid_offset, tmat, rot);
+ }
+ else{
+ mult_m4_m4m4(mid_offset, tmat, offset);
+
+ copy_m4_m4(tmat, mid_offset);
+ mult_m4_m4m4(mid_offset, tmat, rot);
+ }
+ }
+ else {
+ mult_m4_m4m4(mid_offset, tmat, offset);
+ }*/
+ /********/
+ if (amd->mode & MOD_ARR_MOD_ADV) {
+ if (amd->Mem_Ob[j+1].transform)
+ copy_m4_m4(mid_offset, prec_mid);
+ }
+ mult_m4_m4m4(tmp_mat, offset, mid_offset);
+ copy_m4_m4(mid_offset, tmp_mat);
+ if (amd->mode & MOD_ARR_MOD_ADV) {
+ if (amd->Mem_Ob[j+1].transform) {
+ float app[4][4];
+ unit_m4(app);
+ loc_eul_size_to_mat4(app, amd->Mem_Ob[j+1].loc, amd->Mem_Ob[j+1].rot, amd->Mem_Ob[j+1].scale);
+ copy_m4_m4(prec_mid, mid_offset);
+ copy_m4_m4(tmp_mat, mid_offset);
+ mult_m4_m4m4(mid_offset, tmp_mat, app);
+ }
+ }
+ }
+ else if (amd->dist_mc & MOD_ARR_DIST_HALF){
+ mult_m4_m4m4(tmp_mat, half_offset, mid_offset);
+ copy_m4_m4(mid_offset, tmp_mat);
+ }
+ else if (amd->dist_mc & MOD_ARR_DIST_CURVE){
+ if (amd->outer_cp & MOD_ARR_CP_FIRST && amd->start_cap)
+ inc = 1;
+ else
+ inc = 0;
+ if (j+1 < amd->count_mc){
+ if (nu->bezt)
+ copy_v3_v3(mid_offset[3], nu->bezt[j+1+inc].vec[1]);
+ else
+ copy_v3_v3(mid_offset[3], nu->bp[j+1+inc].vec);
+ }
+ }
+ }
+ MEM_freeN(vert_map);
+ mid_cap->release(mid_cap);
+ }
+
if(end_cap) {
float endoffset[4][4];
MVert *cap_mvert;
@@ -680,7 +1109,14 @@
cap_mface = end_cap->getFaceArray(end_cap);
mult_m4_m4m4(endoffset, offset, final_offset);
-
+ if (amd->dist_mc & MOD_ARR_DIST_CURVE) {
+ if (amd->outer_cp & MOD_ARR_CP_LAST && amd->end_cap && amd->curve_cap) {
+ if (nu->bezt)
+ copy_v3_v3(endoffset[3], nu->bezt[nu->pntsu - 1].vec[1]);
+ else
+ copy_v3_v3(endoffset[3], nu->bp[nu->pntsu * nu->pntsv - 1].vec);
+ }
+ }
vert_map = MEM_callocN(sizeof(*vert_map) * capVerts,
"arrayModifier_doArray vert_map");
@@ -754,6 +1190,8 @@
test_index_face(&mface[numFaces], &result->faceData,
numFaces, 3);
}
+ if ((amd->mode & MOD_ARR_MOD_ADV_MAT) && (amd->mat_ob & MOD_ARR_EC_MAT_RND) && (ob->totcol>1))
+ mface[numFaces].mat_nr = amd->Mem_Mat_Ob.end_cap;
origindex[numFaces] = ORIGINDEX_NONE;
numFaces++;
@@ -763,6 +1201,12 @@
end_cap->release(end_cap);
}
+ /*if ((amd->type & MOD_ARR_MOD_CURVE) && (amd->curve_ob)) {
+ if (amd->dist_cu & MOD_ARR_DIST_EVENLY){
+ array_to_curve(scene, amd->curve_ob, ob, mvert, numVerts);
+ }
+ }*/
+
BLI_edgehash_free(edges, NULL);
MEM_freeN(indexMap);
@@ -783,9 +1227,24 @@
result = arrayModifier_doArray(amd, md->scene, ob, dm, 0);
- if(result != dm)
+ if(result != dm) {
CDDM_calc_normals(result);
-
+
+ if(amd->arr_group!=NULL) {
+ if (amd->mode & MOD_ARR_MOD_ADV_CLONE) {
+ ob->transflag = OB_DUPLIARRAY;
+ ob->dup_group = amd->arr_group;
+ }
+ else {
+ ob->transflag = 0;
+ ob->dup_group = NULL;
+ }
+ }
+ else {
+ ob->transflag = 0;
+ ob->dup_group = NULL;
+ }
+ }
return result;
}
@@ -796,6 +1255,16 @@
return applyModifier(md, ob, dm, 0, 1);
}
+static void freeData(ModifierData *md)
+{
+ ArrayModifierData *amd = (ArrayModifierData*) md;
+
+ if (amd)
+ {
+ if (amd->Mem_Ob)
+ MEM_freeN(amd->Mem_Ob);
+ }
+}
ModifierTypeInfo modifierType_Array = {
/* name */ "Array",
@@ -817,12 +1286,11 @@
/* applyModifierEM */ applyModifierEM,
/* initData */ initData,
/* requiredDataMask */ NULL,
- /* freeData */ NULL,
+ /* freeData */ freeData,
/* isDisabled */ NULL,
/* updateDepgraph */ updateDepgraph,
/* dependsOnTime */ NULL,
/* dependsOnNormals */ NULL,
/* foreachObjectLink */ foreachObjectLink,
/* foreachIDLink */ NULL,
- /* foreachTexLink */ NULL,
};
Index: source/blender/render/intern/source/convertblender.c
===================================================================
--- source/blender/render/intern/source/convertblender.c (revisione 43767)
+++ source/blender/render/intern/source/convertblender.c (copia locale)
@@ -4721,7 +4721,8 @@
/* override not showing object when duplis are used with particles */
if(ob->transflag & OB_DUPLIPARTS)
; /* let particle system(s) handle showing vs. not showing */
- else if((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES))
+ else if((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES) &&
+ !(ob->transflag & OB_DUPLIARRAY))
return 0;
/* don't add non-basic meta objects, ends up having renderobjects with no geometry */
@@ -4825,6 +4826,8 @@
/* simple preventing of too deep nested groups */
if(level>MAX_DUPLI_RECUR) return;
+ //if((ob->transflag == OB_DUPLIARRAY) && dob->no_render)
+ // return;
/* recursively go into dupligroups to find objects with OB_RENDER_DUPLI
* that were not created yet */
for(go= group->gobject.first; go; go= go->next) {
@@ -4913,10 +4916,14 @@
Object *obd= dob->ob;
copy_m4_m4(obd->obmat, dob->mat);
-
+
+ if(!(obd->transflag & OB_DUPLIARRAY) && dob->no_render)
+ continue;
+
/* group duplis need to set ob matrices correct, for deform. so no_draw is part handled */
- if(!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw)
- continue;
+ if (obd->transflag & OB_DUPLIARRAY)
+ if(!(obd->transflag & OB_RENDER_DUPLI) && dob->no_draw)
+ continue;
if(obd->restrictflag & OB_RESTRICT_RENDER)
continue;

Event Timeline