Esempio n. 1
0
void mesh_foreachScreenEdge(
        ViewContext *vc,
        void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index),
        void *userData, eV3DProjTest clip_flag)
{
	foreachScreenEdge_userData data;
	DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);

	ED_view3d_check_mats_rv3d(vc->rv3d);

	data.vc = *vc;

	data.win_rect.xmin = 0;
	data.win_rect.ymin = 0;
	data.win_rect.xmax = vc->ar->winx;
	data.win_rect.ymax = vc->ar->winy;

	data.func = func;
	data.userData = userData;
	data.clip_flag = clip_flag;

	if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
		ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat);  /* for local clipping lookups */
	}

	EDBM_index_arrays_ensure(vc->em, BM_EDGE);
	dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data);

	dm->release(dm);
}
Esempio n. 2
0
static void make_duplis_verts(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
	VertexDupliData vdd;

	vdd.ctx = ctx;
	vdd.use_rotation = parent->transflag & OB_DUPLIROT;

	/* gather mesh info */
	{
		Mesh *me = parent->data;
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH);

		if (em)
			vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			vdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
		vdd.edit_btmesh = me->edit_btmesh;

		if (use_texcoords)
			vdd.orco = vdd.dm->getVertDataArray(vdd.dm, CD_ORCO);
		else
			vdd.orco = NULL;

		vdd.totvert = vdd.dm->getNumVerts(vdd.dm);
	}

	make_child_duplis(ctx, &vdd, make_child_duplis_verts);

	vdd.dm->release(vdd.dm);
}
Esempio n. 3
0
void mesh_foreachScreenFace(
        ViewContext *vc,
        void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
        void *userData, const eV3DProjTest clip_flag)
{
	foreachScreenFace_userData data;
	DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);

	ED_view3d_check_mats_rv3d(vc->rv3d);

	data.vc = *vc;
	data.func = func;
	data.userData = userData;
	data.clip_flag = clip_flag;

	EDBM_index_arrays_ensure(vc->em, BM_FACE);
	dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data);

	dm->release(dm);
}
Esempio n. 4
0
static void make_duplis_faces(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
	FaceDupliData fdd;

	fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0);

	/* gather mesh info */
	{
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);

		if (em)
			fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);

		if (use_texcoords) {
			CustomData *ml_data = fdd.dm->getLoopDataLayout(fdd.dm);
			const int uv_idx = CustomData_get_render_layer(ml_data, CD_MLOOPUV);
			fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO);
			fdd.mloopuv = CustomData_get_layer_n(ml_data, CD_MLOOPUV, uv_idx);
		}
		else {
			fdd.orco = NULL;
			fdd.mloopuv = NULL;
		}

		fdd.totface = fdd.dm->getNumPolys(fdd.dm);
		fdd.mpoly = fdd.dm->getPolyArray(fdd.dm);
		fdd.mloop = fdd.dm->getLoopArray(fdd.dm);
		fdd.mvert = fdd.dm->getVertArray(fdd.dm);
	}

	make_child_duplis(ctx, &fdd, make_child_duplis_faces);

	fdd.dm->release(fdd.dm);
}
Esempio n. 5
0
void mesh_foreachScreenVert(
        ViewContext *vc,
        void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
        void *userData, eV3DProjTest clip_flag)
{
	foreachScreenVert_userData data;
	DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);

	data.vc = *vc;
	data.func = func;
	data.userData = userData;
	data.clip_flag = clip_flag;

	if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
		ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat);  /* for local clipping lookups */
	}

	EDBM_index_arrays_ensure(vc->em, BM_VERT);
	dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data);

	dm->release(dm);
}
Esempio n. 6
0
static void make_duplis_faces(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool for_render = ctx->eval_ctx->for_render;
	FaceDupliData fdd;

	fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0);

	/* gather mesh info */
	{
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (for_render ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);

		if (em)
			fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);

		if (for_render) {
			fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO);
			fdd.mloopuv = fdd.dm->getLoopDataArray(fdd.dm, CD_MLOOPUV);
		}
		else {
			fdd.orco = NULL;
			fdd.mloopuv = NULL;
		}

		fdd.totface = fdd.dm->getNumPolys(fdd.dm);
		fdd.mpoly = fdd.dm->getPolyArray(fdd.dm);
		fdd.mloop = fdd.dm->getLoopArray(fdd.dm);
		fdd.mvert = fdd.dm->getVertArray(fdd.dm);
	}

	make_child_duplis(ctx, &fdd, make_child_duplis_faces);

	fdd.dm->release(fdd.dm);
}
Esempio n. 7
0
static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Mesh *me= par->data;
	Base *base = NULL;
	DerivedMesh *dm;
	vertexDupliData vdd;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject * go = NULL;
	BMEditMesh *em;
	float vec[3], no[3], pmat[4][4];
	int totvert, a, oblay;
	unsigned int lay;
	
	copy_m4_m4(pmat, par->obmat);
	
	/* simple preventing of too deep nested groups */
	if (level>MAX_DUPLI_RECUR) return;
	
	em = me->edit_btmesh;
	
	if (em) {
		dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
	}
	else
		dm= mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
	
	if (G.rendering) {
		vdd.orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, vdd.orco, me->totvert, 0);
	}
	else
		vdd.orco= NULL;
	
	totvert = dm->getNumVerts(dm);

	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	}
	else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		}
		else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while (ob) {
				if (ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					 * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					 */
					if (par_space_mat)
						mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat);
					else
						copy_m4_m4(vdd.obmat, ob->obmat);

					vdd.id= id;
					vdd.level= level;
					vdd.animated= animated;
					vdd.lb= lb;
					vdd.ob= ob;
					vdd.scene= scene;
					vdd.par= par;
					copy_m4_m4(vdd.pmat, pmat);
					
					/* mballs have a different dupli handling */
					if (ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					if (me->edit_btmesh) {
						dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void*) &vdd);
					}
					else {
						for (a=0; a<totvert; a++) {
							dm->getVertCo(dm, a, vec);
							dm->getVertNo(dm, a, no);
							
							vertex_dupli__mapFunc(&vdd, a, vec, no, NULL);
						}
					}
					if (sce) {
						/* Set proper layer in case of scene looping,
						 * in case of groups the object layer will be
						 * changed when it's duplicated due to the
						 * group duplication.
						 */
						ob->lay = vdd.par->lay;
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}

	if (vdd.orco)
		MEM_freeN(vdd.orco);
	dm->release(dm);
}
Esempio n. 8
0
static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int level, int animated)
{
	Object *ob, *ob_iter;
	Base *base = NULL;
	DupliObject *dob;
	DerivedMesh *dm;
	Mesh *me= par->data;
	MLoopUV *mloopuv;
	MPoly *mpoly, *mp;
	MLoop *mloop;
	MVert *mvert;
	float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w;
	int lay, oblay, totface, a;
	Scene *sce = NULL;
	Group *group = NULL;
	GroupObject *go = NULL;
	BMEditMesh *em;
	float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */
	
	/* simple preventing of too deep nested groups */
	if (level>MAX_DUPLI_RECUR) return;
	
	copy_m4_m4(pmat, par->obmat);
	em = me->edit_btmesh;

	if (em) {
		dm= editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
	}
	else {
		dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
	}

	totface= dm->getNumPolys(dm);
	mpoly= dm->getPolyArray(dm);
	mloop= dm->getLoopArray(dm);
	mvert= dm->getVertArray(dm);

	if (G.rendering) {

		orco= (float(*)[3])get_mesh_orco_verts(par);
		transform_mesh_orco_verts(me, orco, me->totvert, 0);
		mloopuv= me->mloopuv;
	}
	else {
		orco= NULL;
		mloopuv= NULL;
	}
	
	/* having to loop on scene OR group objects is NOT FUN */
	if (GS(id->name) == ID_SCE) {
		sce = (Scene *)id;
		lay= sce->lay;
		base= sce->base.first;
	}
	else {
		group = (Group *)id;
		lay= group->layer;
		go = group->gobject.first;
	}
	
	/* Start looping on Scene OR Group objects */
	while (base || go) { 
		if (sce) {
			ob_iter= base->object;
			oblay = base->lay;
		}
		else {
			ob_iter= go->ob;
			oblay = ob_iter->lay;
		}
		
		if (lay & oblay && scene->obedit!=ob_iter) {
			ob=ob_iter->parent;
			while (ob) {
				if (ob==par) {
					ob = ob_iter;
	/* End Scene/Group object loop, below is generic */
					
					/* par_space_mat - only used for groups so we can modify the space dupli's are in
					 * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat
					 */
					if (par_space_mat)
						mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat);
					else
						copy_m4_m4(ob__obmat, ob->obmat);
					
					copy_m3_m4(imat, ob->parentinv);
						
					/* mballs have a different dupli handling */
					if (ob->type!=OB_MBALL) ob->flag |= OB_DONE;	/* doesnt render */

					for (a=0, mp= mpoly; a<totface; a++, mp++) {
						int mv1;
						int mv2;
						int mv3;
						/* int mv4; */ /* UNUSED */
						float *v1;
						float *v2;
						float *v3;
						/* float *v4; */ /* UNUSED */
						float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
						MLoop *loopstart= mloop + mp->loopstart;

						if (mp->totloop < 3) {
							/* highly unlikely but to be safe */
							continue;
						}
						else {
							v1= mvert[(mv1= loopstart[0].v)].co;
							v2= mvert[(mv2= loopstart[1].v)].co;
							v3= mvert[(mv3= loopstart[2].v)].co;
#if 0
							if (mp->totloop > 3) {
								v4= mvert[(mv4= loopstart[3].v)].co;
							}
#endif
						}

						/* translation */
						mesh_calc_poly_center(mp, loopstart, mvert, cent);

						mul_m4_v3(pmat, cent);
						
						sub_v3_v3v3(cent, cent, pmat[3]);
						add_v3_v3(cent, ob__obmat[3]);
						
						copy_m4_m4(obmat, ob__obmat);
						
						copy_v3_v3(obmat[3], cent);
						
						/* rotation */
						tri_to_quat( quat,v1, v2, v3);
						quat_to_mat3( mat,quat);
						
						/* scale */
						if (par->transflag & OB_DUPLIFACES_SCALE) {
							float size= mesh_calc_poly_area(mp, loopstart, mvert, NULL);
							size= sqrtf(size) * par->dupfacesca;
							mul_m3_fl(mat, size);
						}
						
						copy_m3_m3(mat3, mat);
						mul_m3_m3m3(mat, imat, mat3);
						
						copy_m4_m4(tmat, obmat);
						mul_m4_m4m3(obmat, tmat, mat);
						
						dob= new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIFACES, animated);
						if (G.rendering) {
							w= 1.0f / (float)mp->totloop;

							if (orco) {
								int j;
								for (j = 0; j < mpoly->totloop; j++) {
									madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w);
								}
							}

							if (mloopuv) {
								int j;
								for (j = 0; j < mpoly->totloop; j++) {
									madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w);
								}
							}
						}
						
						if (ob->transflag & OB_DUPLI) {
							float tmpmat[4][4];
							copy_m4_m4(tmpmat, ob->obmat);
							copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */
							object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, level+1, animated);
							copy_m4_m4(ob->obmat, tmpmat);
						}
					}
					
					break;
				}
				ob= ob->parent;
			}
		}
		if (sce)	base= base->next;	/* scene loop */
		else		go= go->next;		/* group loop */
	}

	if (orco)
		MEM_freeN(orco);
	
	dm->release(dm);
}