Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
{
	Mesh *tmpmesh;
	CustomDataMask mask = CD_MASK_MESH;
	Mesh *mesh = (Mesh *)ob->data;
	DerivedMesh *dm = NULL;
	if (apply_modifiers) {
		switch (export_mesh_type) {
			case BC_MESH_TYPE_VIEW:
			{
				dm = mesh_create_derived_view(scene, ob, mask);
				break;
			}
			case BC_MESH_TYPE_RENDER:
			{
				dm = mesh_create_derived_render(scene, ob, mask);
				break;
			}
		}
	}
	else {
		dm = mesh_create_derived((Mesh *)ob->data, NULL);
	}

	tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
	DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH, true);
	tmpmesh->flag = mesh->flag;

	if (triangulate) {
		bc_triangulate_mesh(tmpmesh);
	}
	BKE_mesh_tessface_ensure(tmpmesh);
	return tmpmesh;
}
Пример #2
0
/* mostly a copy from convertblender.c */
static void dupli_render_particle_set(Scene *scene, Object *ob, int level, int enable)
{
	/* ugly function, but we need to set particle systems to their render
	 * settings before calling object_duplilist, to get render level duplis */
	Group *group;
	GroupObject *go;
	ParticleSystem *psys;
	DerivedMesh *dm;
	float mat[4][4];

	unit_m4(mat);

	if (level >= MAX_DUPLI_RECUR)
		return;
	
	if (ob->transflag & OB_DUPLIPARTS) {
		for (psys = ob->particlesystem.first; psys; psys = psys->next) {
			if (ELEM(psys->part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
				if (enable)
					psys_render_set(ob, psys, mat, mat, 1, 1, 0.f);
				else
					psys_render_restore(ob, psys);
			}
		}

		if (enable) {
			/* this is to make sure we get render level duplis in groups:
			 * the derivedmesh must be created before init_render_mesh,
			 * since object_duplilist does dupliparticles before that */
			dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL);
			dm->release(dm);

			for (psys = ob->particlesystem.first; psys; psys = psys->next)
				psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
		}
	}

	if (ob->dup_group == NULL) return;
	group = ob->dup_group;

	for (go = group->gobject.first; go; go = go->next)
		dupli_render_particle_set(scene, go->ob, level + 1, enable);
}
Пример #3
0
static void pointdensity_cache_object(Scene *scene, PointDensity *pd, Object *ob)
{
	int i;
	DerivedMesh *dm;
	MVert *mvert = NULL;

	dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);
	mvert = dm->getVertArray(dm);	/* local object space */

	pd->totpoints = dm->getNumVerts(dm);
	if (pd->totpoints == 0) {
		return;
	}

	pd->point_tree = BLI_bvhtree_new(pd->totpoints, 0.0, 4, 6);

	for (i = 0; i < pd->totpoints; i++, mvert++) {
		float co[3];

		copy_v3_v3(co, mvert->co);

		switch (pd->ob_cache_space) {
			case TEX_PD_OBJECTSPACE:
				break;
			case TEX_PD_OBJECTLOC:
				mul_m4_v3(ob->obmat, co);
				sub_v3_v3(co, ob->loc);
				break;
			case TEX_PD_WORLDSPACE:
			default:
				mul_m4_v3(ob->obmat, co);
				break;
		}

		BLI_bvhtree_insert(pd->point_tree, i, co, 1);
	}

	BLI_bvhtree_balance(pd->point_tree);
	dm->release(dm);

}
Пример #4
0
static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, ParticleSystem *psys)
{
	DerivedMesh* dm;
	ParticleKey state;
	ParticleSimulationData sim= {NULL};
	ParticleData *pa=NULL;
	float cfra = BKE_curframe(re->scene);
	int i, childexists;
	int total_particles, offset=0;
	int data_used = point_data_used(pd);
	float partco[3];
	float obview[4][4];
	
	/* init everything */
	if (!psys || !ob || !pd) return;

	mul_m4_m4m4(obview, re->viewinv, ob->obmat);
	
	/* Just to create a valid rendering context for particles */
	psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, 0);
	
	dm = mesh_create_derived_render(re->scene, ob,CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL);
	
	if ( !psys_check_enabled(ob, psys)) {
		psys_render_restore(ob, psys);
		return;
	}
	
	sim.scene= re->scene;
	sim.ob= ob;
	sim.psys= psys;

	/* in case ob->imat isn't up-to-date */
	invert_m4_m4(ob->imat, ob->obmat);
	
	total_particles = psys->totpart+psys->totchild;
	psys->lattice=psys_get_lattice(&sim);
	
	pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
	alloc_point_data(pd, total_particles, data_used);
	pd->totpoints = total_particles;
	if (data_used & POINT_DATA_VEL) offset = pd->totpoints*3;
	
	if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
		childexists = 1;
	
	for (i=0, pa=psys->particles; i < total_particles; i++, pa++) {

		state.time = cfra;
		if(psys_get_particle_state(&sim, i, &state, 0)) {
			
			VECCOPY(partco, state.co);
			
			if (pd->psys_cache_space == TEX_PD_OBJECTSPACE)
				mul_m4_v3(ob->imat, partco);
			else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
				sub_v3_v3(partco, ob->loc);
			} else {
				/* TEX_PD_WORLDSPACE */
			}
			
			BLI_bvhtree_insert(pd->point_tree, i, partco, 1);
			
			if (data_used & POINT_DATA_VEL) {
				pd->point_data[i*3 + 0] = state.vel[0];
				pd->point_data[i*3 + 1] = state.vel[1];
				pd->point_data[i*3 + 2] = state.vel[2];
			} 
			if (data_used & POINT_DATA_LIFE) {
				float pa_time;
				
				if (i < psys->totpart) {
					pa_time = (cfra - pa->time)/pa->lifetime;
				} else {
					ChildParticle *cpa= (psys->child + i) - psys->totpart;
					float pa_birthtime, pa_dietime;
					
					pa_time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
				}
				
				pd->point_data[offset + i] = pa_time;
				
			}
		}
	}
	
	BLI_bvhtree_balance(pd->point_tree);
	dm->release(dm);
	
	if(psys->lattice){
		end_latt_deform(psys->lattice);
		psys->lattice=0;
	}
	
	psys_render_restore(ob, psys);
}
Пример #5
0
void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
                                   Scene *scene,
                                   Object *ob)
{
	ID *data_id = (ID *)ob->data;
	AnimData *adt = BKE_animdata_from_id(data_id);
	Key *key;
	float ctime = BKE_scene_frame_get(scene);

	if (G.debug & G_DEBUG_DEPSGRAPH)
		printf("recalcdata %s\n", ob->id.name + 2);

	/* TODO(sergey): Only used by legacy depsgraph. */
	if (adt) {
		/* evaluate drivers - datalevel */
		/* XXX: for mesh types, should we push this to derivedmesh instead? */
		BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* TODO(sergey): Only used by legacy depsgraph. */
	key = BKE_key_from_object(ob);
	if (key && key->block.first) {
		if (!(ob->shapeflag & OB_SHAPE_LOCK))
			BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* includes all keys and modifiers */
	switch (ob->type) {
		case OB_MESH:
		{
			BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
			uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
#ifdef WITH_FREESTYLE
			/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
			if (eval_ctx->mode != DAG_EVAL_VIEWPORT) {
				data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
			}
#endif
			if (em) {
				makeDerivedMesh(scene, ob, em,  data_mask, false); /* was CD_MASK_BAREMESH */
			}
			else {
				makeDerivedMesh(scene, ob, NULL, data_mask, false);
			}
			break;
		}
		case OB_ARMATURE:
			if (ob->id.lib && ob->proxy_from) {
				if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
					printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
					       ob->id.name + 2, ob->proxy_from->id.name + 2);
				}
			}
			else {
				BKE_pose_where_is(scene, ob);
			}
			break;

		case OB_MBALL:
			BKE_displist_make_mball(eval_ctx, scene, ob);
			break;

		case OB_CURVE:
		case OB_SURF:
		case OB_FONT:
			BKE_displist_make_curveTypes(scene, ob, 0);
			break;

		case OB_LATTICE:
			BKE_lattice_modifiers_calc(scene, ob);
			break;

		case OB_EMPTY:
			if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data)
				if (BKE_image_is_animated(ob->data))
					BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0);
			break;
	}

	/* related materials */
	/* XXX: without depsgraph tagging, this will always need to be run, which will be slow!
	 * However, not doing anything (or trying to hack around this lack) is not an option
	 * anymore, especially due to Cycles [#31834]
	 */
	if (ob->totcol) {
		int a;
		if (ob->totcol != 0) {
			BLI_mutex_lock(&material_lock);
			for (a = 1; a <= ob->totcol; a++) {
				Material *ma = give_current_material(ob, a);
				if (ma) {
					/* recursively update drivers for this material */
					material_drivers_update(scene, ma, ctime);
				}
			}
			BLI_mutex_unlock(&material_lock);
		}
	}
	else if (ob->type == OB_LAMP)
		lamp_drivers_update(scene, ob->data, ctime);

	/* particles */
	if (ob != scene->obedit && ob->particlesystem.first) {
		ParticleSystem *tpsys, *psys;
		DerivedMesh *dm;
		ob->transflag &= ~OB_DUPLIPARTS;
		psys = ob->particlesystem.first;
		while (psys) {
			/* ensure this update always happens even if psys is disabled */
			if (psys->recalc & PSYS_RECALC_TYPE) {
				psys_changed_type(ob, psys);
			}

			if (psys_check_enabled(ob, psys)) {
				/* check use of dupli objects here */
				if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) &&
				    ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) ||
				     (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
				{
					ob->transflag |= OB_DUPLIPARTS;
				}

				particle_system_update(scene, ob, psys);
				psys = psys->next;
			}
			else if (psys->flag & PSYS_DELETE) {
				tpsys = psys->next;
				BLI_remlink(&ob->particlesystem, psys);
				psys_free(ob, psys);
				psys = tpsys;
			}
			else
				psys = psys->next;
		}

		if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) {
			/* this is to make sure we get render level duplis in groups:
			 * the derivedmesh must be created before init_render_mesh,
			 * since object_duplilist does dupliparticles before that */
			CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL;
			dm = mesh_create_derived_render(scene, ob, data_mask);
			dm->release(dm);

			for (psys = ob->particlesystem.first; psys; psys = psys->next)
				psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
		}
	}

	/* quick cache removed */
}
Пример #6
0
/* settings: 0 - preview, 1 - render */
Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_modifiers, int settings)
{
	Mesh *tmpmesh;
	Curve *tmpcu = NULL;
	Object *tmpobj = NULL;
	int render = settings == eModifierMode_Render, i;
	int cage = !apply_modifiers;

	/* perform the mesh extraction based on type */
	switch (ob->type) {
	case OB_FONT:
	case OB_CURVE:
	case OB_SURF:

		/* copies object and modifiers (but not the data) */
		tmpobj= copy_object(ob);
		tmpcu = (Curve *)tmpobj->data;
		tmpcu->id.us--;

		/* if getting the original caged mesh, delete object modifiers */
		if( cage )
			object_free_modifiers(tmpobj);

		/* copies the data */
		tmpobj->data = copy_curve( (Curve *) ob->data );

#if 0
		/* copy_curve() sets disp.first null, so currently not need */
		{
			Curve *cu;
			cu = (Curve *)tmpobj->data;
			if( cu->disp.first )
				MEM_freeN( cu->disp.first );
			cu->disp.first = NULL;
		}
	
#endif

		/* get updated display list, and convert to a mesh */
		makeDispListCurveTypes( sce, tmpobj, 0 );
		nurbs_to_mesh( tmpobj );
		
		/* nurbs_to_mesh changes the type to a mesh, check it worked */
		if (tmpobj->type != OB_MESH) {
			free_libblock_us( &(G.main->object), tmpobj );
			BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?");
			return NULL;
		}
		tmpmesh = tmpobj->data;
		free_libblock_us( &G.main->object, tmpobj );
		break;

	case OB_MBALL: {
		/* metaballs don't have modifiers, so just convert to mesh */
		Object *basis_ob = find_basis_mball(sce, ob);
		/* todo, re-generatre for render-res */
		/* metaball_polygonize(scene, ob) */

		if(ob != basis_ob)
			return NULL; /* only do basis metaball */

		tmpmesh = add_mesh("Mesh");
			
		if(render) {
			ListBase disp = {NULL, NULL};
			makeDispListMBall_forRender(sce, ob, &disp);
			mball_to_mesh(&disp, tmpmesh);
			freedisplist(&disp);
		}
		else
			mball_to_mesh(&ob->disp, tmpmesh);
		break;

	}
	case OB_MESH:
		/* copies object and modifiers (but not the data) */
		if (cage) {
			/* copies the data */
			tmpmesh = copy_mesh( ob->data );
		/* if not getting the original caged mesh, get final derived mesh */
		} else {
			/* Make a dummy mesh, saves copying */
			DerivedMesh *dm;
			/* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
			CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
												   for example, needs CD_MASK_MDEFORMVERT */
			
			/* Write the display mesh into the dummy mesh */
			if (render)
				dm = mesh_create_derived_render( sce, ob, mask );
			else
				dm = mesh_create_derived_view( sce, ob, mask );
			
			tmpmesh = add_mesh( "Mesh" );
			DM_to_mesh( dm, tmpmesh );
			dm->release( dm );
		}
		
		break;
	default:
		BKE_report(reports, RPT_ERROR, "Object does not have geometry data");
		return NULL;
	}

	/* Copy materials to new mesh */
	switch (ob->type) {
	case OB_SURF:
	case OB_FONT:
	case OB_CURVE:
		tmpmesh->totcol = tmpcu->totcol;		
		
		/* free old material list (if it exists) and adjust user counts */
		if( tmpcu->mat ) {
			for( i = tmpcu->totcol; i-- > 0; ) {
				/* are we an object material or data based? */

				tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];

				if (tmpmesh->mat[i]) {
					tmpmesh->mat[i]->id.us++;
				}
			}
		}
		break;

#if 0
	/* Crashes when assigning the new material, not sure why */
	case OB_MBALL:
		tmpmb = (MetaBall *)ob->data;
		tmpmesh->totcol = tmpmb->totcol;
		
		/* free old material list (if it exists) and adjust user counts */
		if( tmpmb->mat ) {
			for( i = tmpmb->totcol; i-- > 0; ) {
				tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
				if (tmpmesh->mat[i]) {
					tmpmb->mat[i]->id.us++;
				}
			}
		}
		break;
#endif

	case OB_MESH:
		if (!cage) {
			Mesh *origmesh= ob->data;
			tmpmesh->flag= origmesh->flag;
			tmpmesh->mat = MEM_dupallocN(origmesh->mat);
			tmpmesh->totcol = origmesh->totcol;
			tmpmesh->smoothresh= origmesh->smoothresh;
			if( origmesh->mat ) {
				for( i = origmesh->totcol; i-- > 0; ) {
					/* are we an object material or data based? */
					tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];

					if (tmpmesh->mat[i]) {
						tmpmesh->mat[i]->id.us++;
					}
				}
			}
		}
		break;
	} /* end copy materials */

	/* we don't assign it to anything */
	tmpmesh->id.us--;
	
	/* make sure materials get updated in objects */
	test_object_materials( ( ID * ) tmpmesh );

	return tmpmesh;
}
Пример #7
0
static void pointdensity_cache_psys(Scene *scene,
                                    PointDensity *pd,
                                    Object *ob,
                                    ParticleSystem *psys,
                                    float viewmat[4][4],
                                    float winmat[4][4],
                                    int winx, int winy)
{
	DerivedMesh *dm;
	ParticleKey state;
	ParticleCacheKey *cache;
	ParticleSimulationData sim = {NULL};
	ParticleData *pa = NULL;
	float cfra = BKE_scene_frame_get(scene);
	int i /*, childexists*/ /* UNUSED */;
	int total_particles, offset = 0;
	int data_used = point_data_used(pd);
	float partco[3];

	/* init everything */
	if (!psys || !ob || !pd) {
		return;
	}

	/* Just to create a valid rendering context for particles */
	psys_render_set(ob, psys, viewmat, winmat, winx, winy, 0);

	dm = mesh_create_derived_render(scene, ob, CD_MASK_BAREMESH | CD_MASK_MTFACE | CD_MASK_MCOL);

	if ( !psys_check_enabled(ob, psys)) {
		psys_render_restore(ob, psys);
		return;
	}

	sim.scene = scene;
	sim.ob = ob;
	sim.psys = psys;
	sim.psmd = psys_get_modifier(ob, psys);

	/* in case ob->imat isn't up-to-date */
	invert_m4_m4(ob->imat, ob->obmat);

	total_particles = psys->totpart + psys->totchild;
	psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);

	pd->point_tree = BLI_bvhtree_new(total_particles, 0.0, 4, 6);
	alloc_point_data(pd, total_particles, data_used);
	pd->totpoints = total_particles;
	if (data_used & POINT_DATA_VEL) {
		offset = pd->totpoints * 3;
	}

#if 0 /* UNUSED */
	if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT))
		childexists = 1;
#endif

	for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) {

		if (psys->part->type == PART_HAIR) {
			/* hair particles */
			if (i < psys->totpart && psys->pathcache)
				cache = psys->pathcache[i];
			else if (i >= psys->totpart && psys->childcache)
				cache = psys->childcache[i - psys->totpart];
			else
				continue;

			cache += cache->segments; /* use endpoint */

			copy_v3_v3(state.co, cache->co);
			zero_v3(state.vel);
			state.time = 0.0f;
		}
		else {
			/* emitter particles */
			state.time = cfra;

			if (!psys_get_particle_state(&sim, i, &state, 0))
				continue;

			if (data_used & POINT_DATA_LIFE) {
				if (i < psys->totpart) {
					state.time = (cfra - pa->time) / pa->lifetime;
				}
				else {
					ChildParticle *cpa = (psys->child + i) - psys->totpart;
					float pa_birthtime, pa_dietime;

					state.time = psys_get_child_time(psys, cpa, cfra, &pa_birthtime, &pa_dietime);
				}
			}
		}

		copy_v3_v3(partco, state.co);

		if (pd->psys_cache_space == TEX_PD_OBJECTSPACE)
			mul_m4_v3(ob->imat, partco);
		else if (pd->psys_cache_space == TEX_PD_OBJECTLOC) {
			sub_v3_v3(partco, ob->loc);
		}
		else {
			/* TEX_PD_WORLDSPACE */
		}

		BLI_bvhtree_insert(pd->point_tree, i, partco, 1);

		if (data_used & POINT_DATA_VEL) {
			pd->point_data[i * 3 + 0] = state.vel[0];
			pd->point_data[i * 3 + 1] = state.vel[1];
			pd->point_data[i * 3 + 2] = state.vel[2];
		}
		if (data_used & POINT_DATA_LIFE) {
			pd->point_data[offset + i] = state.time;
		}
	}

	BLI_bvhtree_balance(pd->point_tree);
	dm->release(dm);

	if (psys->lattice_deform_data) {
		end_latt_deform(psys->lattice_deform_data);
		psys->lattice_deform_data = NULL;
	}

	psys_render_restore(ob, psys);
}