예제 #1
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;
}
예제 #2
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;
}
예제 #3
0
static bool isDisabled(ModifierData *md, int useRenderParams)
{
	ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md;
	ParticleSystem *psys;
	ModifierData *ob_md;
	
	if (!pimd->ob)
		return true;
	
	psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1);
	if (psys == NULL)
		return true;
	
	/* If the psys modifier is disabled we cannot use its data.
	 * First look up the psys modifier from the object, then check if it is enabled.
	 */
	for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) {
		if (ob_md->type == eModifierType_ParticleSystem) {
			ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md;
			if (psmd->psys == psys) {
				int required_mode;
				
				if (useRenderParams) required_mode = eModifierMode_Render;
				else required_mode = eModifierMode_Realtime;
				
				if (!modifier_isEnabled(md->scene, ob_md, required_mode))
					return true;
				
				break;
			}
		}
	}
	
	return false;
}
예제 #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
CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md,
                                    CustomDataMask dataMask, int required_mode,
                                    ModifierData *previewmd, CustomDataMask previewmask)
{
	CDMaskLink *dataMasks = NULL;
	CDMaskLink *curr, *prev;

	/* build a list of modifier data requirements in reverse order */
	for (; md; md = md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);

		curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink");
		
		if (modifier_isEnabled(scene, md, required_mode)) {
			if (mti->requiredDataMask)
				curr->mask = mti->requiredDataMask(ob, md);

			if (previewmd == md) {
				curr->mask |= previewmask;
			}
		}

		/* prepend new datamask */
		curr->next = dataMasks;
		dataMasks = curr;
	}

	/* build the list of required data masks - each mask in the list must
	 * include all elements of the masks that follow it
	 *
	 * note the list is currently in reverse order, so "masks that follow it"
	 * actually means "masks that precede it" at the moment
	 */
	for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
		if (prev) {
			CustomDataMask prev_mask = prev->mask;
			CustomDataMask curr_mask = curr->mask;

			curr->mask = curr_mask | prev_mask;
		}
		else {
			CustomDataMask curr_mask = curr->mask;

			curr->mask = curr_mask | dataMask;
		}
	}

	/* reverse the list so it's in the correct order */
	BLI_linklist_reverse((LinkNode **)&dataMasks);

	return dataMasks;
}
예제 #6
0
파일: modifier.c 프로젝트: nttputus/blensor
ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode)
{
    ModifierData *tmp_md = NULL;

    if (required_mode != eModifierMode_Realtime)
        return tmp_md;

    /* Find the latest modifier in stack generating preview. */
    for (; md; md = md->next) {
        if (modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md))
            tmp_md = md;
    }
    return tmp_md;
}
예제 #7
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;
}
예제 #8
0
LinkNode *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode)
{
	LinkNode *dataMasks = NULL;
	LinkNode *curr, *prev;

	/* build a list of modifier data requirements in reverse order */
	for(; md; md = md->next) {
		ModifierTypeInfo *mti = modifierType_getInfo(md->type);
		CustomDataMask mask = 0;

		if(modifier_isEnabled(scene, md, required_mode))
			if(mti->requiredDataMask)
				mask = mti->requiredDataMask(ob, md);

		BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask));
	}

	/* build the list of required data masks - each mask in the list must
	* include all elements of the masks that follow it
	*
	* note the list is currently in reverse order, so "masks that follow it"
	* actually means "masks that precede it" at the moment
	*/
	for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) {
		if(prev) {
			CustomDataMask prev_mask = (CustomDataMask)GET_INT_FROM_POINTER(prev->link);
			CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);

			curr->link = SET_INT_IN_POINTER(curr_mask | prev_mask);
		} else {
			CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link);

			curr->link = SET_INT_IN_POINTER(curr_mask | dataMask);
		}
	}

	/* reverse the list so it's in the correct order */
	BLI_linklist_reverse(&dataMasks);

	return dataMasks;
}
예제 #9
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;
	}
}
예제 #10
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);
}
예제 #11
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);
}
예제 #12
0
static int multiresbake_check(bContext *C, wmOperator *op)
{
	Scene *scene= CTX_data_scene(C);
	Object *ob;
	Mesh *me;
	MultiresModifierData *mmd;
	int ok= 1, a;

	CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) {
		ob= base->object;

		if(ob->type != OB_MESH) {
			BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh");

			ok= 0;
			break;
		}

		me= (Mesh*)ob->data;
		mmd= get_multires_modifier(scene, ob, 0);

		/* Multi-resolution should be and be last in the stack */
		if(ok && mmd) {
			ModifierData *md;

			ok= mmd->totlvl>0;

			for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) {
				if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) {
					ok= 0;
				}
			}
		} else ok= 0;

		if(!ok) {
			BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object");

			break;
		}

		if(!me->mtface) {
			BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking");

			ok= 0;
		} else {
			a= me->totface;
			while (ok && a--) {
				Image *ima= me->mtface[a].tpage;

				if(!ima) {
					BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker");

					ok= 0;
				} else {
					ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);

					if(!ibuf) {
						BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer");

						ok= 0;
					} else {
						if(ibuf->rect==NULL && ibuf->rect_float==NULL)
							ok= 0;

						if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4))
							ok= 0;

						if(!ok)
							BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type");
					}
				}
			}
		}

		if(!ok)
			break;
	}