Changeset View
Changeset View
Standalone View
Standalone View
source/blender/modifiers/intern/MOD_gpencilarray.c
- This file was added.
| /* | |||||
| * ***** 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) 2005 by the Blender Foundation. | |||||
| * All rights reserved. | |||||
| * | |||||
| * Contributor(s): Antonio Vazquez | |||||
| * | |||||
| * ***** END GPL LICENSE BLOCK ***** | |||||
| * | |||||
| */ | |||||
| /** \file blender/modifiers/intern/MOD_gpencilarray.c | |||||
| * \ingroup modifiers | |||||
| */ | |||||
| #include <stdio.h> | |||||
| #include "DNA_scene_types.h" | |||||
| #include "DNA_object_types.h" | |||||
| #include "DNA_gpencil_types.h" | |||||
| #include "BLI_utildefines.h" | |||||
| #include "BLI_math_vector.h" | |||||
| #include "BKE_DerivedMesh.h" | |||||
| #include "BKE_gpencil.h" | |||||
| #include "BKE_context.h" | |||||
| #include "BKE_object.h" | |||||
| #include "BKE_main.h" | |||||
| #include "BKE_scene.h" | |||||
| #include "BKE_layer.h" | |||||
| #include "BKE_collection.h" | |||||
| #include "DEG_depsgraph.h" | |||||
| #include "DEG_depsgraph_build.h" | |||||
| #include "MOD_modifiertypes.h" | |||||
| static void initData(ModifierData *md) | |||||
| { | |||||
| GpencilArrayModifierData *gpmd = (GpencilArrayModifierData *)md; | |||||
| gpmd->count[0] = 1; | |||||
| gpmd->count[1] = 1; | |||||
| gpmd->count[2] = 1; | |||||
| gpmd->offset[0] = 1.0f; | |||||
| gpmd->offset[1] = 1.0f; | |||||
| gpmd->offset[2] = 1.0f; | |||||
| gpmd->shift[0] = 0.0f; | |||||
| gpmd->shift[2] = 0.0f; | |||||
| gpmd->shift[3] = 0.0f; | |||||
| gpmd->scale[0] = 1.0f; | |||||
| gpmd->scale[1] = 1.0f; | |||||
| gpmd->scale[2] = 1.0f; | |||||
| gpmd->rnd_rot = 0.5f; | |||||
| gpmd->rnd_size = 0.5f; | |||||
| gpmd->lock_axis |= GP_LOCKAXIS_X; | |||||
| /* fill random values */ | |||||
| BKE_gpencil_fill_random_array(gpmd->rnd, 20); | |||||
| gpmd->rnd[0] = 1; | |||||
| BKE_gpencil_batch_cache_alldirty(); | |||||
| } | |||||
| static void copyData(ModifierData *md, ModifierData *target) | |||||
| { | |||||
| modifier_copyData_generic(md, target); | |||||
| } | |||||
| /* helper to create a new object */ | |||||
| static Object *object_add_type(bContext *C, int UNUSED(type), const char *UNUSED(name), Object *from_ob) | |||||
| { | |||||
| Main *bmain = CTX_data_main(C); | |||||
| Scene *scene = CTX_data_scene(C); | |||||
| Object *ob; | |||||
| const float loc[3] = { 0, 0, 0 }; | |||||
| const float rot[3] = { 0, 0, 0 }; | |||||
| ob = BKE_object_copy(bmain, from_ob); | |||||
| BKE_collection_object_add_from(scene, from_ob, ob); | |||||
| copy_v3_v3(ob->loc, loc); | |||||
| copy_v3_v3(ob->rot, rot); | |||||
| DEG_id_type_tag(bmain, ID_OB); | |||||
| DEG_relations_tag_update(bmain); | |||||
| DEG_id_tag_update(&scene->id, 0); | |||||
| return ob; | |||||
| } | |||||
campbellbarton: Why is this needed? adding new objects within applyModifier is quite strange. | |||||
sergeyUnsubmitted Not Done Inline ActionsThere must be NO dependency graph changes from within modifier stack. Period. sergey: There must be NO dependency graph changes from within modifier stack. Period. | |||||
| static DerivedMesh *applyModifier( | |||||
| ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, | |||||
| DerivedMesh *UNUSED(dm), | |||||
| ModifierApplyFlag UNUSED(flag)) | |||||
| { | |||||
| GpencilArrayModifierData *mmd = (GpencilArrayModifierData *)md; | |||||
| ModifierData *fmd; | |||||
| bContext *C = (bContext *)mmd->C; | |||||
| Main *bmain = CTX_data_main(C); | |||||
Not Done Inline ActionsYou must not use bContext from inside modifier. It is undefined. sergey: You must not use bContext from inside modifier. It is undefined. | |||||
| Object *newob = NULL; | |||||
Not Done Inline ActionsNo bmain access either, only access data which is used by modifier itself. sergey: No bmain access either, only access data which is used by modifier itself. | |||||
| int xyz[3], sh; | |||||
| float mat[4][4], finalmat[4][4]; | |||||
| float rot[3]; | |||||
| if ((!ob) || (!ob->gpd)) { | |||||
| return NULL; | |||||
| } | |||||
| /* reset random */ | |||||
| mmd->rnd[0] = 1; | |||||
| for (int x = 0; x < mmd->count[0]; ++x) { | |||||
| for (int y = 0; y < mmd->count[1]; ++y) { | |||||
| for (int z = 0; z < mmd->count[2]; ++z) { | |||||
| ARRAY_SET_ITEMS(xyz, x, y, z); | |||||
| if ((x == 0) && (y == 0) && (z == 0)) { | |||||
| continue; | |||||
| } | |||||
| BKE_gpencil_array_modifier(0, mmd, ob, xyz, mat); | |||||
| mul_m4_m4m4(finalmat, mat, ob->obmat); | |||||
| /* create a new object and new gp datablock */ | |||||
| newob = object_add_type(C, OB_GPENCIL, md->name, ob); | |||||
| id_us_min((ID *)ob->gpd); | |||||
| newob->gpd = BKE_gpencil_data_duplicate(bmain, ob->gpd, false); | |||||
| /* remove array on destination object */ | |||||
| fmd = (ModifierData *) BLI_findstring(&newob->modifiers, md->name, offsetof(ModifierData, name)); | |||||
| if (fmd) { | |||||
| BLI_remlink(&newob->modifiers, fmd); | |||||
| modifier_free(fmd); | |||||
| } | |||||
| /* moves to new origin */ | |||||
| sh = x; | |||||
| if (mmd->lock_axis == GP_LOCKAXIS_Y) { | |||||
| sh = y; | |||||
| } | |||||
| if (mmd->lock_axis == GP_LOCKAXIS_Z) { | |||||
| sh = z; | |||||
| } | |||||
| madd_v3_v3fl(finalmat[3], mmd->shift, sh); | |||||
| copy_v3_v3(newob->loc, finalmat[3]); | |||||
| /* apply rotation */ | |||||
| mat4_to_eul(rot, finalmat); | |||||
| copy_v3_v3(newob->rot, rot); | |||||
| /* apply scale */ | |||||
| ARRAY_SET_ITEMS(newob->size, finalmat[0][0], finalmat[1][1], finalmat[2][2]); | |||||
| } | |||||
| } | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| ModifierTypeInfo modifierType_GpencilArray = { | |||||
| /* name */ "Array", | |||||
| /* structName */ "GpencilArrayModifierData", | |||||
| /* structSize */ sizeof(GpencilArrayModifierData), | |||||
| /* type */ eModifierTypeType_Gpencil, | |||||
| /* flags */ eModifierTypeFlag_GpencilMod, | |||||
| /* copyData */ copyData, | |||||
| /* deformVerts */ NULL, | |||||
| /* deformMatrices */ NULL, | |||||
| /* deformVertsEM */ NULL, | |||||
| /* deformMatricesEM */ NULL, | |||||
| /* applyModifier */ applyModifier, | |||||
| /* applyModifierEM */ NULL, | |||||
| /* initData */ initData, | |||||
| /* requiredDataMask */ NULL, | |||||
| /* freeData */ NULL, | |||||
| /* isDisabled */ NULL, | |||||
| /* updateDepsgraph */ NULL, | |||||
| /* dependsOnTime */ NULL, | |||||
| /* dependsOnNormals */ NULL, | |||||
| /* foreachObjectLink */ NULL, | |||||
| /* foreachIDLink */ NULL, | |||||
| /* foreachTexLink */ NULL, | |||||
| }; | |||||
Why is this needed? adding new objects within applyModifier is quite strange.