예제 #1
0
static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode)
{
	ModifierData *md = modifiers_getVirtualModifierList(ob);
	ModifierData *preTesselatePoint;
	int required_mode;

	if(forRender) required_mode = eModifierMode_Render;
	else required_mode = eModifierMode_Realtime;

	if(editmode) required_mode |= eModifierMode_Editmode;

	preTesselatePoint = NULL;
	for (; md; md=md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		if (!modifier_isEnabled(scene, md, required_mode)) continue;
		if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint;

		if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) {
			preTesselatePoint = md;

			/* this modifiers are moving point of tesselation automatically
			   (some of them even can't be applied on tesselated curve), set flag
			   for incformation button in modifier's header */
			md->mode |= eModifierMode_ApplyOnSpline;
		} else if(md->mode&eModifierMode_ApplyOnSpline) {
			preTesselatePoint = md;
		}
	}

	return preTesselatePoint;
}
예제 #2
0
/* used for buttons, to find out if the 'draw deformed in editmode' option is
 * there
 * 
 * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
 * then is NULL) 
 * also used for some mesh tools to give warnings
 */
int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCageIndex_r, int virtual_)
{
	ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first;
	int i, cageIndex = -1;

	if(lastPossibleCageIndex_r) {
		/* ensure the value is initialized */
		*lastPossibleCageIndex_r= -1;
	}

	/* Find the last modifier acting on the cage. */
	for (i=0; md; i++,md=md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene= scene;

		if (!(md->mode & eModifierMode_Realtime)) continue;
		if (!(md->mode & eModifierMode_Editmode)) continue;
		if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
		if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
		if (md->mode & eModifierMode_DisableTemporary) continue;

		if (!modifier_supportsMapping(md))
			break;

		if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i;
		if (md->mode & eModifierMode_OnCage)
			cageIndex = i;
	}

	return cageIndex;
}
예제 #3
0
bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
{
	bDeformGroup *dg;
	ModifierData *md;
	bool *vgroup_validmap;
	GHash *gh;
	int i, step1 = 1;
	//int defbase_tot = BLI_countlist(&ob->defbase);

	if (ob->defbase.first == NULL) {
		return NULL;
	}

	gh = BLI_ghash_str_new("BKE_objdef_validmap_get gh");

	/* add all names to a hash table */
	for (dg = ob->defbase.first; dg; dg = dg->next) {
		BLI_ghash_insert(gh, dg->name, NULL);
	}

	BLI_assert(BLI_ghash_size(gh) == defbase_tot);

	/* now loop through the armature modifiers and identify deform bones */
	for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob) : md->next) {
		if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual)))
			continue;

		if (md->type == eModifierType_Armature) {
			ArmatureModifierData *amd = (ArmatureModifierData *) md;

			if (amd->object && amd->object->pose) {
				bPose *pose = amd->object->pose;
				bPoseChannel *chan;

				for (chan = pose->chanbase.first; chan; chan = chan->next) {
					if (chan->bone->flag & BONE_NO_DEFORM)
						continue;

					if (BLI_ghash_remove(gh, chan->name, NULL, NULL)) {
						BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1));
					}
				}
			}
		}
	}

	vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map");

	/* add all names to a hash table */
	for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
		vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
	}

	BLI_assert(i == BLI_ghash_size(gh));

	BLI_ghash_free(gh, NULL, NULL);

	return vgroup_validmap;
}
예제 #4
0
void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
	int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);

	if(totleft) {
		/* there are deformation modifier which doesn't support deformation matricies
		   calculation. Need additional crazyspace correction */

		float (*deformedVerts)[3]= *deformcos;
		float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
		float *quats= NULL;
		int i, deformed= 0;
		ModifierData *md= modifiers_getVirtualModifierList(ob);
		Mesh *me= (Mesh*)ob->data;

		for(; md; md= md->next) {
			ModifierTypeInfo *mti= modifierType_getInfo(md->type);

			if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;

			if(mti->type==eModifierTypeType_OnlyDeform) {
				/* skip leading modifiers which have been already
				   handled in sculpt_get_first_deform_matrices */
				if(mti->deformMatrices && !deformed)
					continue;

				mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
				deformed= 1;
			}
		}

		quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");

		crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);

		for(i=0; i<me->totvert; i++) {
			float qmat[3][3], tmat[3][3];

			quat_to_mat3(qmat, &quats[i*4]);
			mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
			copy_m3_m3((*deformmats)[i], tmat);
		}

		MEM_freeN(origVerts);
		MEM_freeN(quats);
	}

	if(!*deformmats) {
		int a, numVerts;
		Mesh *me= (Mesh*)ob->data;

		*deformcos= mesh_getVertexCos(me, &numVerts);
		*deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats");

		for(a=0; a<numVerts; a++)
			unit_m3((*deformmats)[a]);
	}
}
예제 #5
0
int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
	ModifierData *md;
	DerivedMesh *dm;
	int a, numVerts= 0;
	float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
	MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
	int has_multires = mmd != NULL && mmd->sculptlvl > 0;
	int numleft= 0;

	if(has_multires) {
		*deformmats= NULL;
		*deformcos= NULL;
		return numleft;
	}

	dm= NULL;
	md= modifiers_getVirtualModifierList(ob);

	for(; md; md= md->next) {
		ModifierTypeInfo *mti= modifierType_getInfo(md->type);

		if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;

		if(mti->type==eModifierTypeType_OnlyDeform) {
			if(!defmats) {
				Mesh *me= (Mesh*)ob->data;
				dm= mesh_create_derived(me, ob, NULL);
				deformedVerts= mesh_getVertexCos(me, &numVerts);
				defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");

				for(a=0; a<numVerts; a++)
					unit_m3(defmats[a]);
			}

			if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
			else break;
		}
	}

	for(; md; md= md->next) {
		ModifierTypeInfo *mti= modifierType_getInfo(md->type);

		if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;

		if(mti->type==eModifierTypeType_OnlyDeform)
			numleft++;
	}

	if(dm)
		dm->release(dm);

	*deformmats= defmats;
	*deformcos= deformedVerts;

	return numleft;
}
예제 #6
0
파일: modifier.c 프로젝트: nttputus/blensor
int modifiers_isCorrectableDeformed(Object *ob)
{
    ModifierData *md = modifiers_getVirtualModifierList(ob);

    for (; md; md = md->next) {
        if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ;
        else if (modifier_isCorrectableDeformed(md))
            return 1;
    }
    return 0;
}
예제 #7
0
static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender)
{
	/* this function represents logic of mesh's orcodm calculation */
	/* for displist-based objects */

	ModifierData *md = modifiers_getVirtualModifierList(ob);
	ModifierData *preTesselatePoint;
	Curve *cu= ob->data;
	int required_mode;
	int editmode = (!forRender && cu->editnurb);
	DerivedMesh *ndm, *orcodm= NULL;

	if(forRender) required_mode = eModifierMode_Render;
	else required_mode = eModifierMode_Realtime;

	preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);

	if(editmode) required_mode |= eModifierMode_Editmode;

	if (preTesselatePoint) {
		md = preTesselatePoint->next;
	}

	for (; md; md=md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene= scene;

		if ((md->mode & required_mode) != required_mode) continue;
		if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
		if (mti->type!=eModifierTypeType_Constructive) continue;

		if(!orcodm)
			orcodm= create_orco_dm(scene, ob);

		ndm = mti->applyModifier(md, ob, orcodm, forRender, 0);

		if(ndm) {
			/* if the modifier returned a new dm, release the old one */
			if(orcodm && orcodm != ndm) {
				orcodm->release(orcodm);
			}
			orcodm = ndm;
		}
	}

	/* add an orco layer if needed */
	add_orco_dm(scene, ob, derivedFinal, orcodm);

	if(orcodm)
		orcodm->release(orcodm);
}
예제 #8
0
int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
{
	ModifierData *md;
	DerivedMesh *dm;
	int i, a, numleft = 0, numVerts = 0;
	int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
	float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;

	modifiers_clearErrors(ob);

	dm = NULL;
	md = modifiers_getVirtualModifierList(ob);

	/* compute the deformation matrices and coordinates for the first
	   modifiers with on cage editing that are enabled and support computing
	   deform matrices */
	for(i = 0; md && i <= cageIndex; i++, md = md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		if(!editmesh_modifier_is_enabled(scene, md, dm))
			continue;

		if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
			if(!defmats) {
				dm= editmesh_get_derived(em, NULL);
				deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
				defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");

				for(a=0; a<numVerts; a++)
					unit_m3(defmats[a]);
			}

			mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
				numVerts);
		}
		else
			break;
	}

	for(; md && i <= cageIndex; md = md->next, i++)
		if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
			numleft++;

	if(dm)
		dm->release(dm);

	*deformmats= defmats;
	*deformcos= deformedVerts;

	return numleft;
}
예제 #9
0
int modifiers_usesArmature(Object *ob, bArmature *arm)
{
	ModifierData *md = modifiers_getVirtualModifierList(ob);

	for (; md; md=md->next) {
		if (md->type==eModifierType_Armature) {
			ArmatureModifierData *amd = (ArmatureModifierData*) md;
			if (amd->object && amd->object->data==arm) 
				return 1;
		}
	}

	return 0;
}
예제 #10
0
bool modifiers_usesArmature(Object *ob, bArmature *arm)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);

	for (; md; md = md->next) {
		if (md->type == eModifierType_Armature) {
			ArmatureModifierData *amd = (ArmatureModifierData *) md;
			if (amd->object && amd->object->data == arm)
				return true;
		}
	}

	return false;
}
예제 #11
0
파일: modifier.c 프로젝트: nttputus/blensor
/* Takes an object and returns its first selected lattice, else just its
 * lattice
 * This should work for multiple lattics per object
 */
Object *modifiers_isDeformedByLattice(Object *ob)
{
    ModifierData *md = modifiers_getVirtualModifierList(ob);
    LatticeModifierData *lmd = NULL;

    /* return the first selected lattice, this lets us use multiple lattices */
    for (; md; md = md->next) {
        if (md->type == eModifierType_Lattice) {
            lmd = (LatticeModifierData *) md;
            if (lmd->object && (lmd->object->flag & SELECT))
                return lmd->object;
        }
    }

    if (lmd) /* if were still here then return the last lattice */
        return lmd->object;

    return NULL;
}
예제 #12
0
파일: modifier.c 프로젝트: nttputus/blensor
/* Takes an object and returns its first selected armature, else just its
 * armature
 * This should work for multiple armatures per object
 */
Object *modifiers_isDeformedByArmature(Object *ob)
{
    ModifierData *md = modifiers_getVirtualModifierList(ob);
    ArmatureModifierData *amd = NULL;

    /* return the first selected armature, this lets us use multiple armatures */
    for (; md; md = md->next) {
        if (md->type == eModifierType_Armature) {
            amd = (ArmatureModifierData *) md;
            if (amd->object && (amd->object->flag & SELECT))
                return amd->object;
        }
    }

    if (amd) /* if were still here then return the last armature */
        return amd->object;

    return NULL;
}
예제 #13
0
bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	int required_mode = eModifierMode_Realtime;

	if (ob->mode == OB_MODE_EDIT)
		required_mode |= eModifierMode_Editmode;
	
	for (; md; md = md->next) {
		if (!modifier_isEnabled(scene, md, required_mode)) {
			/* pass */
		}
		else if (modifier_isCorrectableDeformed(md)) {
			return true;
		}
	}
	return false;
}
예제 #14
0
void BKE_lattice_modifiers_calc(Scene *scene, Object *ob)
{
	Lattice *lt = ob->data;
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	float (*vertexCos)[3] = NULL;
	int numVerts, editmode = (lt->editlatt != NULL);

	if (ob->curve_cache) {
		BKE_displist_free(&ob->curve_cache->disp);
	}
	else {
		ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice");
	}

	for (; md; md = md->next) {
		const ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene = scene;
		
		if (!(md->mode & eModifierMode_Realtime)) continue;
		if (editmode && !(md->mode & eModifierMode_Editmode)) continue;
		if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
		if (mti->type != eModifierTypeType_OnlyDeform) continue;

		if (!vertexCos) vertexCos = BKE_lattice_vertexcos_get(ob, &numVerts);
		mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0);
	}

	/* always displist to make this work like derivedmesh */
	if (!vertexCos) vertexCos = BKE_lattice_vertexcos_get(ob, &numVerts);
	
	{
		DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl");
		dl->type = DL_VERTS;
		dl->parts = 1;
		dl->nr = numVerts;
		dl->verts = (float *) vertexCos;
		
		BLI_addtail(&ob->curve_cache->disp, dl);
	}
}
예제 #15
0
/* Takes an object and returns its first selected curve, else just its curve
 * This should work for multiple curves per object
 */
Object *modifiers_isDeformedByCurve(Object *ob)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	CurveModifierData *cmd = NULL;
	
	/* return the first selected curve, this lets us use multiple curves */
	for (; md; md = md->next) {
		if (md->type == eModifierType_Curve) {
			cmd = (CurveModifierData *) md;
			if (cmd->object && (cmd->object->flag & SELECT))
				return cmd->object;
		}
	}
	
	if (cmd) /* if were still here then return the last curve */
		return cmd->object;
	
	return NULL;
}
예제 #16
0
/* used for buttons, to find out if the 'draw deformed in editmode' option is
 * there
 * 
 * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
 * then is NULL) 
 * also used for some mesh tools to give warnings
 */
int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first;
	int i, cageIndex = -1;

	if (r_lastPossibleCageIndex) {
		/* ensure the value is initialized */
		*r_lastPossibleCageIndex = -1;
	}

	/* Find the last modifier acting on the cage. */
	for (i = 0; md; i++, md = md->next) {
		const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
		bool supports_mapping;

		md->scene = scene;

		if (mti->isDisabled && mti->isDisabled(md, 0)) continue;
		if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue;
		if (md->mode & eModifierMode_DisableTemporary) continue;

		supports_mapping = modifier_supportsMapping(md);
		if (r_lastPossibleCageIndex && supports_mapping) {
			*r_lastPossibleCageIndex = i;
		}

		if (!(md->mode & eModifierMode_Realtime)) continue;
		if (!(md->mode & eModifierMode_Editmode)) continue;

		if (!supports_mapping)
			break;

		if (md->mode & eModifierMode_OnCage)
			cageIndex = i;
	}

	return cageIndex;
}
예제 #17
0
파일: displist.c 프로젝트: mgschwan/blensor
static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final,
                              const bool for_render, const bool use_render_resolution)
{
	/* this function represents logic of mesh's orcodm calculation
	 * for displist-based objects
	 */
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	ModifierData *pretessellatePoint;
	Curve *cu = ob->data;
	int required_mode;
	const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
	DerivedMesh *ndm, *orcodm = NULL;
	ModifierApplyFlag app_flag = MOD_APPLY_ORCO;

	if (use_render_resolution) {
		app_flag |= MOD_APPLY_RENDER;
		required_mode = eModifierMode_Render;
	}
	else
		required_mode = eModifierMode_Realtime;

	pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);

	if (editmode)
		required_mode |= eModifierMode_Editmode;

	if (pretessellatePoint) {
		md = pretessellatePoint->next;
	}

	/* If modifiers are disabled, we wouldn't be here because
	 * this function is only called if there're enabled constructive
	 * modifiers applied on the curve.
	 *
	 * This means we can create ORCO DM in advance and assume it's
	 * never NULL.
	 */
	orcodm = create_orco_dm(scene, ob);

	for (; md; md = md->next) {
		const ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene = scene;

		if (!modifier_isEnabled(scene, md, required_mode))
			continue;
		if (mti->type != eModifierTypeType_Constructive)
			continue;

		ndm = modwrap_applyModifier(md, ob, orcodm, app_flag);

		if (ndm) {
			/* if the modifier returned a new dm, release the old one */
			if (orcodm && orcodm != ndm) {
				orcodm->release(orcodm);
			}
			orcodm = ndm;
		}
	}

	/* add an orco layer if needed */
	add_orco_dm(ob, dm_final, orcodm);

	orcodm->release(orcodm);
}
예제 #18
0
static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r)
{
	ModifierData *md = modifiers_getVirtualModifierList(ob);
	ModifierData *preTesselatePoint;
	Curve *cu= ob->data;
	ListBase *nurb= BKE_curve_nurbs(cu);
	int numVerts = 0;
	int editmode = (!forRender && cu->editnurb);
	float (*originalVerts)[3] = NULL;
	float (*deformedVerts)[3] = NULL;
	float *keyVerts= NULL;
	int required_mode;

	if(forRender) required_mode = eModifierMode_Render;
	else required_mode = eModifierMode_Realtime;

	preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
	
	if(editmode) required_mode |= eModifierMode_Editmode;

	if(cu->editnurb==NULL) {
		keyVerts= do_ob_key(scene, ob);

		if(keyVerts) {
			/* split coords from key data, the latter also includes
			   tilts, which is passed through in the modifier stack.
			   this is also the reason curves do not use a virtual
			   shape key modifier yet. */
			deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
			originalVerts= MEM_dupallocN(deformedVerts);
		}
	}
	
	if (preTesselatePoint) {
		for (; md; md=md->next) {
			ModifierTypeInfo *mti = modifierType_getInfo(md->type);

			md->scene= scene;
			
			if ((md->mode & required_mode) != required_mode) continue;
			if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;
			if (mti->type!=eModifierTypeType_OnlyDeform) continue;

			if (!deformedVerts) {
				deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
				originalVerts = MEM_dupallocN(deformedVerts);
			}

			mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode);

			if (md==preTesselatePoint)
				break;
		}
	}

	if (deformedVerts)
		curve_applyVertexCos(cu, nurb, deformedVerts);
	if (keyVerts) /* these are not passed through modifier stack */
		curve_applyKeyVertexTilts(cu, nurb, keyVerts);

	if(keyVerts)
		MEM_freeN(keyVerts);

	*originalVerts_r = originalVerts;
	*deformedVerts_r = deformedVerts;
	*numVerts_r = numVerts;
}
예제 #19
0
static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase,
	DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3])
{
	ModifierData *md = modifiers_getVirtualModifierList(ob);
	ModifierData *preTesselatePoint;
	Curve *cu= ob->data;
	ListBase *nurb= BKE_curve_nurbs(cu);
	int required_mode = 0, totvert = 0;
	int editmode = (!forRender && cu->editnurb);
	DerivedMesh *dm= NULL, *ndm;
	float (*vertCos)[3] = NULL;

	if(forRender) required_mode = eModifierMode_Render;
	else required_mode = eModifierMode_Realtime;

	preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode);
	
	if(editmode) required_mode |= eModifierMode_Editmode;

	if (preTesselatePoint) {
		md = preTesselatePoint->next;
	}

	if (derivedFinal && *derivedFinal) {
		(*derivedFinal)->release (*derivedFinal);
	}

	for (; md; md=md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		md->scene= scene;

		if ((md->mode & required_mode) != required_mode) continue;
		if (mti->isDisabled && mti->isDisabled(md, forRender)) continue;

		if (mti->type == eModifierTypeType_OnlyDeform ||
				(mti->type == eModifierTypeType_DeformOrConstruct && !dm)) {
			if (dm) {
				if (!vertCos) {
					totvert = dm->getNumVerts(dm);
					vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
					dm->getVertCos(dm, vertCos);
				}

				mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode);
			} else {
				if (!vertCos) {
					vertCos= displist_get_allverts(dispbase, &totvert);
				}

				mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode);
			}
		} else {
			if (!derivedFinal) {
				/* makeDisplistCurveTypes could be used for beveling, where derived mesh */
				/* is totally unnecessary, so we could stop modifiers applying */
				/* when we found constructive modifier but derived mesh is unwanted result */
				break;
			}

			if (dm) {
				if (vertCos) {
					DerivedMesh *tdm = CDDM_copy(dm);
					dm->release(dm);
					dm = tdm;

					CDDM_apply_vert_coords(dm, vertCos);
					CDDM_calc_normals(dm);
				}
			} else {
				if (vertCos) {
					displist_apply_allverts(dispbase, vertCos);
				}

				if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
					curve_to_filledpoly(cu, nurb, dispbase);
				}

				dm= CDDM_from_curve_customDB(ob, dispbase);

				CDDM_calc_normals(dm);
			}

			if (vertCos) {
				/* Vertex coordinates were applied to necessary data, could free it */
				MEM_freeN(vertCos);
				vertCos= NULL;
			}

			ndm = mti->applyModifier(md, ob, dm, forRender, editmode);

			if (ndm) {
				/* Modifier returned a new derived mesh */

				if (dm && dm != ndm) /* Modifier  */
					dm->release (dm);
				dm = ndm;
			}
		}
	}

	if (vertCos) {
		if (dm) {
			DerivedMesh *tdm = CDDM_copy(dm);
			dm->release(dm);
			dm = tdm;

			CDDM_apply_vert_coords(dm, vertCos);
			CDDM_calc_normals(dm);
			MEM_freeN(vertCos);
		} else {
			displist_apply_allverts(dispbase, vertCos);
			MEM_freeN(vertCos);
			vertCos= NULL;
		}
	}

	if (derivedFinal) {
		(*derivedFinal) = dm;
	}

	if (deformedVerts) {
		curve_applyVertexCos(ob->data, nurb, originalVerts);
		MEM_freeN(originalVerts);
		MEM_freeN(deformedVerts);
	}
}
예제 #20
0
파일: displist.c 프로젝트: mgschwan/blensor
static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb,
                                      ListBase *dispbase, DerivedMesh **r_dm_final,
                                      const bool for_render, const bool use_render_resolution)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	ModifierData *pretessellatePoint;
	Curve *cu = ob->data;
	int required_mode = 0, totvert = 0;
	const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
	DerivedMesh *dm = NULL, *ndm;
	float (*vertCos)[3] = NULL;
	int useCache = !for_render;
	ModifierApplyFlag app_flag = 0;

	if (use_render_resolution) {
		app_flag |= MOD_APPLY_RENDER;
		required_mode = eModifierMode_Render;
	}
	else
		required_mode = eModifierMode_Realtime;

	pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);

	if (editmode)
		required_mode |= eModifierMode_Editmode;

	if (pretessellatePoint) {
		md = pretessellatePoint->next;
	}

	if (r_dm_final && *r_dm_final) {
		(*r_dm_final)->release(*r_dm_final);
	}

	for (; md; md = md->next) {
		const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
		ModifierApplyFlag appf = app_flag;

		md->scene = scene;

		if (!modifier_isEnabled(scene, md, required_mode))
			continue;

		if (mti->type == eModifierTypeType_OnlyDeform ||
		    (mti->type == eModifierTypeType_DeformOrConstruct && !dm))
		{
			if (editmode)
				appf |= MOD_APPLY_USECACHE;
			if (dm) {
				if (!vertCos) {
					totvert = dm->getNumVerts(dm);
					vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv");
					dm->getVertCos(dm, vertCos);
				}

				mti->deformVerts(md, ob, dm, vertCos, totvert, appf);
			}
			else {
				if (!vertCos) {
					vertCos = displist_get_allverts(dispbase, &totvert);
				}

				mti->deformVerts(md, ob, NULL, vertCos, totvert, appf);
			}
		}
		else {
			if (!r_dm_final) {
				/* makeDisplistCurveTypes could be used for beveling, where derived mesh
				 * is totally unnecessary, so we could stop modifiers applying
				 * when we found constructive modifier but derived mesh is unwanted result
				 */
				break;
			}

			if (dm) {
				if (vertCos) {
					DerivedMesh *tdm = CDDM_copy(dm);
					dm->release(dm);
					dm = tdm;

					CDDM_apply_vert_coords(dm, vertCos);
				}
			}
			else {
				if (vertCos) {
					displist_apply_allverts(dispbase, vertCos);
				}

				if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
					curve_to_filledpoly(cu, nurb, dispbase);
				}

				dm = CDDM_from_curve_displist(ob, dispbase);
			}

			if (vertCos) {
				/* Vertex coordinates were applied to necessary data, could free it */
				MEM_freeN(vertCos);
				vertCos = NULL;
			}

			if (useCache)
				appf |= MOD_APPLY_USECACHE;

			ndm = modwrap_applyModifier(md, ob, dm, appf);

			if (ndm) {
				/* Modifier returned a new derived mesh */

				if (dm && dm != ndm) /* Modifier  */
					dm->release(dm);
				dm = ndm;
			}
		}
	}

	if (vertCos) {
		if (dm) {
			DerivedMesh *tdm = CDDM_copy(dm);
			dm->release(dm);
			dm = tdm;

			CDDM_apply_vert_coords(dm, vertCos);
			CDDM_calc_normals_mapping(dm);
			MEM_freeN(vertCos);
		}
		else {
			displist_apply_allverts(dispbase, vertCos);
			MEM_freeN(vertCos);
			vertCos = NULL;
		}
	}

	if (r_dm_final) {
		if (dm) {
			/* see: mesh_calc_modifiers */
			if (dm->getNumTessFaces(dm) == 0) {
				dm->recalcTessellation(dm);
			}
			/* Even if tessellation is not needed, some modifiers might have modified CD layers
			 * (like mloopcol or mloopuv), hence we have to update those. */
			else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) {
				DM_update_tessface_data(dm);
			}

			if (dm->type == DM_TYPE_CDDM) {
				CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
			}
		}
		(*r_dm_final) = dm;
	}
}
예제 #21
0
파일: displist.c 프로젝트: mgschwan/blensor
static void curve_calc_modifiers_pre(Scene *scene, Object *ob, ListBase *nurb,
                                     const bool for_render, const bool use_render_resolution)
{
	VirtualModifierData virtualModifierData;
	ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
	ModifierData *pretessellatePoint;
	Curve *cu = ob->data;
	int numVerts = 0;
	const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
	ModifierApplyFlag app_flag = 0;
	float (*deformedVerts)[3] = NULL;
	float *keyVerts = NULL;
	int required_mode;

	modifiers_clearErrors(ob);

	if (editmode)
		app_flag |= MOD_APPLY_USECACHE;
	if (use_render_resolution) {
		app_flag |= MOD_APPLY_RENDER;
		required_mode = eModifierMode_Render;
	}
	else
		required_mode = eModifierMode_Realtime;

	pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode);

	if (editmode)
		required_mode |= eModifierMode_Editmode;

	if (!editmode) {
		keyVerts = BKE_key_evaluate_object(ob, &numVerts);

		if (keyVerts) {
			/* split coords from key data, the latter also includes
			 * tilts, which is passed through in the modifier stack.
			 * this is also the reason curves do not use a virtual
			 * shape key modifier yet. */
			deformedVerts = BKE_curve_nurbs_keyVertexCos_get(nurb, keyVerts);
			BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts);
		}
	}

	if (pretessellatePoint) {
		for (; md; md = md->next) {
			const ModifierTypeInfo *mti = modifierType_getInfo(md->type);

			md->scene = scene;

			if (!modifier_isEnabled(scene, md, required_mode))
				continue;
			if (mti->type != eModifierTypeType_OnlyDeform)
				continue;

			if (!deformedVerts) {
				deformedVerts = BKE_curve_nurbs_vertexCos_get(nurb, &numVerts);
			}

			mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, app_flag);

			if (md == pretessellatePoint)
				break;
		}
	}

	if (deformedVerts) {
		BK_curve_nurbs_vertexCos_apply(nurb, deformedVerts);
		MEM_freeN(deformedVerts);
	}
	if (keyVerts) /* these are not passed through modifier stack */
		BKE_curve_nurbs_keyVertexTilts_apply(nurb, keyVerts);

	if (keyVerts)
		MEM_freeN(keyVerts);
}