Пример #1
0
void multiresModifier_join(Object *ob)
{
    Base *base = NULL;
    int highest_lvl = 0;

    /* First find the highest level of subdivision */
    base = FIRSTBASE;
    while(base) {
        if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) {
            ModifierData *md;
            for(md = base->object->modifiers.first; md; md = md->next) {
                if(md->type == eModifierType_Multires) {
                    int totlvl = ((MultiresModifierData*)md)->totlvl;
                    if(totlvl > highest_lvl)
                        highest_lvl = totlvl;

                    /* Ensure that all updates are processed */
                    multires_force_update(base->object);
                }
            }
        }
        base = base->next;
    }

    /* No multires meshes selected */
    if(highest_lvl == 0)
        return;

    /* Subdivide all the displacements to the highest level */
    base = FIRSTBASE;
    while(base) {
        if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) {
            ModifierData *md = NULL;
            MultiresModifierData *mmd = NULL;

            for(md = base->object->modifiers.first; md; md = md->next) {
                if(md->type == eModifierType_Multires)
                    mmd = (MultiresModifierData*)md;
            }

            /* If the object didn't have multires enabled, give it a new modifier */
            if(!mmd) {
                md = base->object->modifiers.first;

                while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
                    md = md->next;

                mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires);
                BLI_insertlinkbefore(&base->object->modifiers, md, mmd);
                modifier_unique_name(&base->object->modifiers, mmd);
            }

            if(mmd)
                multiresModifier_subdivide(mmd, base->object, highest_lvl - mmd->totlvl, 0, 0);
        }
        base = base->next;
    }
}
Пример #2
0
static void rna_FluidSettings_update_type(Main *bmain, Scene *scene, PointerRNA *ptr)
{
	Object *ob = (Object*)ptr->id.data;
	FluidsimModifierData *fluidmd;
	ParticleSystemModifierData *psmd;
	ParticleSystem *psys;
	ParticleSettings *part;
	
	fluidmd = (FluidsimModifierData*)modifiers_findByType(ob, eModifierType_Fluidsim);
	fluidmd->fss->flag &= ~OB_FLUIDSIM_REVERSE; /* clear flag */

	/* remove fluidsim particle system */
	if (fluidmd->fss->type & OB_FLUIDSIM_PARTICLE) {
		for (psys = ob->particlesystem.first; psys; psys = psys->next)
			if (psys->part->type == PART_FLUID)
				break;

		if (ob->type == OB_MESH && !psys) {
			/* add particle system */
			part = psys_new_settings("ParticleSettings", bmain);
			psys = MEM_callocN(sizeof(ParticleSystem), "particle_system");

			part->type = PART_FLUID;
			psys->part = part;
			psys->pointcache = BKE_ptcache_add(&psys->ptcaches);
			psys->flag |= PSYS_ENABLED;
			BLI_strncpy(psys->name, "FluidParticles", sizeof(psys->name));
			BLI_addtail(&ob->particlesystem,psys);

			/* add modifier */
			psmd = (ParticleSystemModifierData*)modifier_new(eModifierType_ParticleSystem);
			BLI_strncpy(psmd->modifier.name, "FluidParticleSystem", sizeof(psmd->modifier.name));
			psmd->psys = psys;
			BLI_addtail(&ob->modifiers, psmd);
			modifier_unique_name(&ob->modifiers, (ModifierData *)psmd);
		}
	}
	else {
		for (psys = ob->particlesystem.first; psys; psys = psys->next) {
			if (psys->part->type == PART_FLUID) {
				/* clear modifier */
				psmd = psys_get_modifier(ob, psys);
				BLI_remlink(&ob->modifiers, psmd);
				modifier_free((ModifierData *)psmd);

				/* clear particle system */
				BLI_remlink(&ob->particlesystem, psys);
				psys_free(ob, psys);
			}
		}
	}

	rna_fluid_update(bmain, scene, ptr);
}
Пример #3
0
int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
{
	ModifierData *nmd;
	
	nmd = modifier_new(md->type);
	modifier_copyData(md, nmd);
	BLI_insertlink(&ob->modifiers, md, nmd);
	modifier_unique_name(&ob->modifiers, nmd);

	return 1;
}
Пример #4
0
static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode)
{
	ModifierData *md=NULL;
	HookModifierData *hmd = NULL;
	float cent[3];
	int tot, ok, *indexar;
	char name[32];
	
	ok = object_hook_index_array(obedit, &tot, &indexar, name, cent);
	
	if (!ok) return;	// XXX error("Requires selected vertices or active Vertex Group");
	
	if (mode==OBJECT_ADDHOOK_NEWOB && !ob) {
		
		ob = add_hook_object_new(scene, obedit);
		
		/* transform cent to global coords for loc */
		mul_v3_m4v3(ob->loc, obedit->obmat, cent);
	}
	
	md = obedit->modifiers.first;
	while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) {
		md = md->next;
	}
	
	hmd = (HookModifierData*) modifier_new(eModifierType_Hook);
	BLI_insertlinkbefore(&obedit->modifiers, md, hmd);
	BLI_snprintf(hmd->modifier.name, sizeof(hmd->modifier.name), "Hook-%s", ob->id.name+2);
	modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd);
	
	hmd->object= ob;
	hmd->indexar= indexar;
	copy_v3_v3(hmd->cent, cent);
	hmd->totindex= tot;
	BLI_strncpy(hmd->name, name, sizeof(hmd->name));
	
	/* matrix calculus */
	/* vert x (obmat x hook->imat) x hook->obmat x ob->imat */
	/*        (parentinv         )                          */
	where_is_object(scene, ob);
	
	invert_m4_m4(ob->imat, ob->obmat);
	/* apparently this call goes from right to left... */
	mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, 
				 NULL, NULL, NULL, NULL, NULL);
	
	DAG_scene_sort(bmain, scene);
}
Пример #5
0
ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *scene, Object *ob, const char *name, int type)
{
	ModifierData *md=NULL, *new_md=NULL;
	ModifierTypeInfo *mti = modifierType_getInfo(type);
	
	/* only geometry objects should be able to get modifiers [#25291] */
	if(!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
		BKE_reportf(reports, RPT_WARNING, "Modifiers cannot be added to Object '%s'", ob->id.name+2);
		return NULL;
	}
	
	if(mti->flags&eModifierTypeFlag_Single) {
		if(modifiers_findByType(ob, type)) {
			BKE_report(reports, RPT_WARNING, "Only one modifier of this type allowed");
			return NULL;
		}
	}
	
	if(type == eModifierType_ParticleSystem) {
		/* don't need to worry about the new modifier's name, since that is set to the number
		 * of particle systems which shouldn't have too many duplicates 
		 */
		new_md = object_add_particle_system(scene, ob, name);
	}
	else {
		/* get new modifier data to add */
		new_md= modifier_new(type);
		
		if(mti->flags&eModifierTypeFlag_RequiresOriginalData) {
			md = ob->modifiers.first;
			
			while(md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform)
				md = md->next;
			
			BLI_insertlinkbefore(&ob->modifiers, md, new_md);
		}
		else
			BLI_addtail(&ob->modifiers, new_md);

		if(name)
			BLI_strncpy(new_md->name, name, sizeof(new_md->name));

		/* make sure modifier data has unique name */

		modifier_unique_name(&ob->modifiers, new_md);
		
		/* special cases */
		if(type == eModifierType_Softbody) {
			if(!ob->soft) {
				ob->soft= sbNew(scene);
				ob->softflag |= OB_SB_GOAL|OB_SB_EDGES;
			}
		}
		else if(type == eModifierType_Collision) {
			if(!ob->pd)
				ob->pd= object_add_collision_fields(0);
			
			ob->pd->deflect= 1;
			DAG_scene_sort(bmain, scene);
		}
		else if(type == eModifierType_Surface)
			DAG_scene_sort(bmain, scene);
		else if(type == eModifierType_Multires)
			/* set totlvl from existing MDISPS layer if object already had it */
			multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
	}

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);

	return new_md;
}
/* single_psys_from is optional, if NULL all psys of ob_from are copied */
static bool copy_particle_systems_to_object(Scene *scene, Object *ob_from, ParticleSystem *single_psys_from, Object *ob_to, int space)
{
	ModifierData *md;
	ParticleSystem *psys_start = NULL, *psys, *psys_from;
	ParticleSystem **tmp_psys;
	DerivedMesh *final_dm;
	CustomDataMask cdmask;
	int i, totpsys;
	
	if (ob_to->type != OB_MESH)
		return false;
	if (!ob_to->data || ((ID *)ob_to->data)->lib)
		return false;
	
	/* For remapping we need a valid DM.
	 * Because the modifiers are appended at the end it's safe to use
	 * the final DM of the object without particles.
	 * However, when evaluating the DM all the particle modifiers must be valid,
	 * i.e. have the psys assigned already.
	 * To break this hen/egg problem we create all psys separately first (to collect required customdata masks),
	 * then create the DM, then add them to the object and make the psys modifiers ...
	 */
	#define PSYS_FROM_FIRST (single_psys_from ? single_psys_from : ob_from->particlesystem.first)
	#define PSYS_FROM_NEXT(cur) (single_psys_from ? NULL : (cur)->next)
	totpsys = single_psys_from ? 1 : BLI_listbase_count(&ob_from->particlesystem);
	
	tmp_psys = MEM_mallocN(sizeof(ParticleSystem*) * totpsys, "temporary particle system array");
	
	cdmask = 0;
	for (psys_from = PSYS_FROM_FIRST, i = 0;
	     psys_from;
	     psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
		
		psys = BKE_object_copy_particlesystem(psys_from);
		tmp_psys[i] = psys;
		
		if (psys_start == NULL)
			psys_start = psys;
		
		cdmask |= psys_emitter_customdata_mask(psys);
	}
	/* to iterate source and target psys in sync,
	 * we need to know where the newly added psys start
	 */
	psys_start = totpsys > 0 ? tmp_psys[0] : NULL;
	
	/* get the DM (psys and their modifiers have not been appended yet) */
	final_dm = mesh_get_derived_final(scene, ob_to, cdmask);
	
	/* now append psys to the object and make modifiers */
	for (i = 0, psys_from = PSYS_FROM_FIRST;
	     i < totpsys;
	     ++i, psys_from = PSYS_FROM_NEXT(psys_from)) {
		
		ParticleSystemModifierData *psmd;
		
		psys = tmp_psys[i];
		
		/* append to the object */
		BLI_addtail(&ob_to->particlesystem, psys);
		
		/* add a particle system modifier for each system */
		md = modifier_new(eModifierType_ParticleSystem);
		psmd = (ParticleSystemModifierData *)md;
		/* push on top of the stack, no use trying to reproduce old stack order */
		BLI_addtail(&ob_to->modifiers, md);
		
		BLI_snprintf(md->name, sizeof(md->name), "ParticleSystem %i", i);
		modifier_unique_name(&ob_to->modifiers, (ModifierData *)psmd);
		
		psmd->psys = psys;
		psmd->dm = CDDM_copy(final_dm);
		CDDM_calc_normals(psmd->dm);
		DM_ensure_tessface(psmd->dm);
		
		if (psys_from->edit)
			copy_particle_edit(scene, ob_to, psys, psys_from);
	}
	MEM_freeN(tmp_psys);
	
	/* note: do this after creating DM copies for all the particle system modifiers,
	 * the remapping otherwise makes final_dm invalid!
	 */
	for (psys = psys_start, psys_from = PSYS_FROM_FIRST, i = 0;
	     psys;
	     psys = psys->next, psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
		
		float (*from_mat)[4], (*to_mat)[4];
		
		switch (space) {
			case PAR_COPY_SPACE_OBJECT:
				from_mat = I;
				to_mat = I;
				break;
			case PAR_COPY_SPACE_WORLD:
				from_mat = ob_from->obmat;
				to_mat = ob_to->obmat;
				break;
			default:
				/* should not happen */
				from_mat = to_mat = NULL;
				BLI_assert(false);
				break;
		}
		
		remap_hair_emitter(scene, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
		
		/* tag for recalc */
//		psys->recalc |= PSYS_RECALC_RESET;
	}
	
	#undef PSYS_FROM_FIRST
	#undef PSYS_FROM_NEXT
	
	DAG_id_tag_update(&ob_to->id, OB_RECALC_DATA);
	WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, ob_to);
	return true;
}