Пример #1
0
/* When no longer needed, duplilist should be freed with Object.free_duplilist */
static void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, int settings)
{
	bool for_render = (settings == DAG_EVAL_RENDER);
	EvaluationContext eval_ctx;
	DEG_evaluation_context_init(&eval_ctx, settings);

	if (!(ob->transflag & OB_DUPLI)) {
		BKE_report(reports, RPT_ERROR, "Object does not have duplis");
		return;
	}

	/* free duplilist if a user forgets to */
	if (ob->duplilist) {
		BKE_report(reports, RPT_WARNING, "Object.dupli_list has not been freed");

		free_object_duplilist(ob->duplilist);
		ob->duplilist = NULL;
	}
	if (for_render)
		dupli_render_particle_set(sce, ob, 0, 1);
	ob->duplilist = object_duplilist(&eval_ctx, sce, ob);
	if (for_render)
		dupli_render_particle_set(sce, ob, 0, 0);
	/* ob->duplilist should now be freed with Object.free_duplilist */
}
Пример #2
0
static void rna_Object_free_duplilist(Object *ob)
{
	if (ob->duplilist) {
		free_object_duplilist(ob->duplilist);
		ob->duplilist = NULL;
	}
}
Пример #3
0
/* When no longer needed, duplilist should be freed with Object.free_duplilist */
void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce)
{
	if (!(ob->transflag & OB_DUPLI)) {
		BKE_report(reports, RPT_ERROR, "Object does not have duplis");
		return;
	}

	/* free duplilist if a user forgets to */
	if (ob->duplilist) {
		BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed");

		free_object_duplilist(ob->duplilist);
		ob->duplilist= NULL;
	}
	if(G.rendering)
		dupli_render_particle_set(sce, ob, 0, 1);
	ob->duplilist= object_duplilist(sce, ob);
	if(G.rendering)
		dupli_render_particle_set(sce, ob, 0, 0);
	/* ob->duplilist should now be freed with Object.free_duplilist */
}
Пример #4
0
static void view3d_select_loop(ViewContext *vc, Scene *scene, View3D *v3d, ARegion *ar, bool use_obedit_skip)
{
	short code = 1;
	char dt;
	short dtx;

	if (vc->obedit && vc->obedit->type == OB_MBALL) {
		draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
	}
	else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
		/* if not drawing sketch, draw bones */
		if (!BDR_drawSketchNames(vc)) {
			draw_object(scene, ar, v3d, BASACT, DRAW_PICKING | DRAW_CONSTCOLOR);
		}
	}
	else {
		Base *base;

		v3d->xray = true;  /* otherwise it postpones drawing */
		for (base = scene->base.first; base; base = base->next) {
			if (base->lay & v3d->lay) {

				if ((base->object->restrictflag & OB_RESTRICT_SELECT) ||
				    (use_obedit_skip && (scene->obedit->data == base->object->data)))
				{
					base->selcol = 0;
				}
				else {
					base->selcol = code;

					if (GPU_select_load_id(code)) {
						draw_object(scene, ar, v3d, base, DRAW_PICKING | DRAW_CONSTCOLOR);

						/* we draw duplicators for selection too */
						if ((base->object->transflag & OB_DUPLI)) {
							ListBase *lb;
							DupliObject *dob;
							Base tbase;

							tbase.flag = OB_FROMDUPLI;
							lb = object_duplilist(G.main->eval_ctx, scene, base->object);

							for (dob = lb->first; dob; dob = dob->next) {
								float omat[4][4];

								tbase.object = dob->ob;
								copy_m4_m4(omat, dob->ob->obmat);
								copy_m4_m4(dob->ob->obmat, dob->mat);

								/* extra service: draw the duplicator in drawtype of parent */
								/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
								dt = tbase.object->dt;   tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
								dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;

								draw_object(scene, ar, v3d, &tbase, DRAW_PICKING | DRAW_CONSTCOLOR);

								tbase.object->dt = dt;
								tbase.object->dtx = dtx;

								copy_m4_m4(dob->ob->obmat, omat);
							}
							free_object_duplilist(lb);
						}
					}
					code++;
				}
			}
		}
		v3d->xray = false;  /* restore */
	}
}
Пример #5
0
/* used by metaballs
 * doesnt return the original duplicated object, only dupli's
 */
int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
{
	static ListBase *duplilist = NULL;
	static DupliObject *dupob;
	static int fase = F_START, in_next_object = 0;
	int run_again = 1;
	
	/* init */
	if (val == 0) {
		fase = F_START;
		dupob = NULL;
		
		/* XXX particle systems with metas+dupligroups call this recursively */
		/* see bug #18725 */
		if (in_next_object) {
			printf("ERROR: Metaball generation called recursively, not supported\n");
			
			return F_ERROR;
		}
	}
	else {
		in_next_object = 1;
		
		/* run_again is set when a duplilist has been ended */
		while (run_again) {
			run_again = 0;

			/* the first base */
			if (fase == F_START) {
				*base = (*scene)->base.first;
				if (*base) {
					*ob = (*base)->object;
					fase = F_SCENE;
				}
				else {
					/* exception: empty scene */
					while ((*scene)->set) {
						(*scene) = (*scene)->set;
						if ((*scene)->base.first) {
							*base = (*scene)->base.first;
							*ob = (*base)->object;
							fase = F_SCENE;
							break;
						}
					}
				}
			}
			else {
				if (*base && fase != F_DUPLI) {
					*base = (*base)->next;
					if (*base) *ob = (*base)->object;
					else {
						if (fase == F_SCENE) {
							/* (*scene) is finished, now do the set */
							while ((*scene)->set) {
								(*scene) = (*scene)->set;
								if ((*scene)->base.first) {
									*base = (*scene)->base.first;
									*ob = (*base)->object;
									break;
								}
							}
						}
					}
				}
			}
			
			if (*base == NULL) fase = F_START;
			else {
				if (fase != F_DUPLI) {
					if ( (*base)->object->transflag & OB_DUPLI) {
						/* groups cannot be duplicated for mballs yet, 
						 * this enters eternal loop because of 
						 * makeDispListMBall getting called inside of group_duplilist */
						if ((*base)->object->dup_group == NULL) {
							duplilist = object_duplilist((*scene), (*base)->object, FALSE);
							
							dupob = duplilist->first;

							if (!dupob)
								free_object_duplilist(duplilist);
						}
					}
				}
				/* handle dupli's */
				if (dupob) {
					
					copy_m4_m4(dupob->ob->obmat, dupob->mat);
					
					(*base)->flag |= OB_FROMDUPLI;
					*ob = dupob->ob;
					fase = F_DUPLI;
					
					dupob = dupob->next;
				}
				else if (fase == F_DUPLI) {
					fase = F_SCENE;
					(*base)->flag &= ~OB_FROMDUPLI;
					
					for (dupob = duplilist->first; dupob; dupob = dupob->next) {
						copy_m4_m4(dupob->ob->obmat, dupob->omat);
					}
					
					free_object_duplilist(duplilist);
					duplilist = NULL;
					run_again = 1;
				}
			}
		}
	}

#if 0
	if (ob && *ob) {
		printf("Scene: '%s', '%s'\n", (*scene)->id.name + 2, (*ob)->id.name + 2);
	}
#endif

	/* reset recursion test */
	in_next_object = 0;
	
	return fase;
}
Пример #6
0
/* Warning: be sure to account for a negative return value
*   This is an error, "Too many objects in select buffer"
*   and no action should be taken (can crash blender) if this happens
*/
short view3d_opengl_select(ViewContext *vc, unsigned int *buffer, unsigned int bufsize, rcti *input)
{
	Scene *scene= vc->scene;
	View3D *v3d= vc->v3d;
	ARegion *ar= vc->ar;
	rctf rect;
	short code, hits;
	char dt, dtx;
	
	G.f |= G_PICKSEL;
	
	/* case not a border select */
	if(input->xmin==input->xmax) {
		rect.xmin= input->xmin-12;	// seems to be default value for bones only now
		rect.xmax= input->xmin+12;
		rect.ymin= input->ymin-12;
		rect.ymax= input->ymin+12;
	}
	else {
		rect.xmin= input->xmin;
		rect.xmax= input->xmax;
		rect.ymin= input->ymin;
		rect.ymax= input->ymax;
	}
	
	setwinmatrixview3d(ar, v3d, &rect);
	mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if(v3d->drawtype > OB_WIRE) {
		v3d->zbuf= TRUE;
		glEnable(GL_DEPTH_TEST);
	}
	
	if(vc->rv3d->rflag & RV3D_CLIPPING)
		view3d_set_clipping(vc->rv3d);
	
	glSelectBuffer( bufsize, (GLuint *)buffer);
	glRenderMode(GL_SELECT);
	glInitNames();	/* these two calls whatfor? It doesnt work otherwise */
	glPushName(-1);
	code= 1;
	
	if(vc->obedit && vc->obedit->type==OB_MBALL) {
		draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
	}
	else if((vc->obedit && vc->obedit->type==OB_ARMATURE)) {
		/* if not drawing sketch, draw bones */
		if(!BDR_drawSketchNames(vc)) {
			draw_object(scene, ar, v3d, BASACT, DRAW_PICKING|DRAW_CONSTCOLOR);
		}
	}
	else {
		Base *base;
		
		v3d->xray= TRUE;	// otherwise it postpones drawing
		for(base= scene->base.first; base; base= base->next) {
			if(base->lay & v3d->lay) {
				
				if (base->object->restrictflag & OB_RESTRICT_SELECT)
					base->selcol= 0;
				else {
					base->selcol= code;
					glLoadName(code);
					draw_object(scene, ar, v3d, base, DRAW_PICKING|DRAW_CONSTCOLOR);
					
					/* we draw group-duplicators for selection too */
					if((base->object->transflag & OB_DUPLI) && base->object->dup_group) {
						ListBase *lb;
						DupliObject *dob;
						Base tbase;
						
						tbase.flag= OB_FROMDUPLI;
						lb= object_duplilist(scene, base->object);
						
						for(dob= lb->first; dob; dob= dob->next) {
							tbase.object= dob->ob;
							copy_m4_m4(dob->ob->obmat, dob->mat);
							
							/* extra service: draw the duplicator in drawtype of parent */
							/* MIN2 for the drawtype to allow bounding box objects in groups for lods */
							dt= tbase.object->dt;	tbase.object->dt= MIN2(tbase.object->dt, base->object->dt);
							dtx= tbase.object->dtx; tbase.object->dtx= base->object->dtx;

							draw_object(scene, ar, v3d, &tbase, DRAW_PICKING|DRAW_CONSTCOLOR);
							
							tbase.object->dt= dt;
							tbase.object->dtx= dtx;

							copy_m4_m4(dob->ob->obmat, dob->omat);
						}
						free_object_duplilist(lb);
					}
					code++;
				}				
			}
		}
		v3d->xray= FALSE;	// restore
	}
	
	glPopName();	/* see above (pushname) */
	hits= glRenderMode(GL_RENDER);
	
	G.f &= ~G_PICKSEL;
	setwinmatrixview3d(ar, v3d, NULL);
	mult_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
	
	if(v3d->drawtype > OB_WIRE) {
		v3d->zbuf= 0;
		glDisable(GL_DEPTH_TEST);
	}
// XXX	persp(PERSP_WIN);
	
	if(vc->rv3d->rflag & RV3D_CLIPPING)
		view3d_clr_clipping();
	
	if(hits<0) printf("Too many objects in select buffer\n");	// XXX make error message
	
	return hits;
}
Пример #7
0
/* used by metaballs
 * doesn't return the original duplicated object, only dupli's
 */
int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
                             Scene **scene, int val, Base **base, Object **ob)
{
	int run_again = 1;
	
	/* init */
	if (val == 0) {
		iter->fase = F_START;
		iter->dupob = NULL;
		iter->duplilist = NULL;
	}
	else {
		/* run_again is set when a duplilist has been ended */
		while (run_again) {
			run_again = 0;

			/* the first base */
			if (iter->fase == F_START) {
				*base = (*scene)->base.first;
				if (*base) {
					*ob = (*base)->object;
					iter->fase = F_SCENE;
				}
				else {
					/* exception: empty scene */
					while ((*scene)->set) {
						(*scene) = (*scene)->set;
						if ((*scene)->base.first) {
							*base = (*scene)->base.first;
							*ob = (*base)->object;
							iter->fase = F_SCENE;
							break;
						}
					}
				}
			}
			else {
				if (*base && iter->fase != F_DUPLI) {
					*base = (*base)->next;
					if (*base) {
						*ob = (*base)->object;
					}
					else {
						if (iter->fase == F_SCENE) {
							/* (*scene) is finished, now do the set */
							while ((*scene)->set) {
								(*scene) = (*scene)->set;
								if ((*scene)->base.first) {
									*base = (*scene)->base.first;
									*ob = (*base)->object;
									break;
								}
							}
						}
					}
				}
			}
			
			if (*base == NULL) {
				iter->fase = F_START;
			}
			else {
				if (iter->fase != F_DUPLI) {
					if ( (*base)->object->transflag & OB_DUPLI) {
						/* groups cannot be duplicated for mballs yet, 
						 * this enters eternal loop because of 
						 * makeDispListMBall getting called inside of group_duplilist */
						if ((*base)->object->dup_group == NULL) {
							iter->duplilist = object_duplilist_ex(eval_ctx, (*scene), (*base)->object, false);
							
							iter->dupob = iter->duplilist->first;

							if (!iter->dupob)
								free_object_duplilist(iter->duplilist);
						}
					}
				}
				/* handle dupli's */
				if (iter->dupob) {
					
					copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->mat);
					
					(*base)->flag |= OB_FROMDUPLI;
					*ob = iter->dupob->ob;
					iter->fase = F_DUPLI;
					
					iter->dupob = iter->dupob->next;
				}
				else if (iter->fase == F_DUPLI) {
					iter->fase = F_SCENE;
					(*base)->flag &= ~OB_FROMDUPLI;
					
					for (iter->dupob = iter->duplilist->first; iter->dupob; iter->dupob = iter->dupob->next) {
						copy_m4_m4(iter->dupob->ob->obmat, iter->dupob->omat);
					}
					
					free_object_duplilist(iter->duplilist);
					iter->duplilist = NULL;
					run_again = 1;
				}
			}
		}
	}

#if 0
	if (ob && *ob) {
		printf("Scene: '%s', '%s'\n", (*scene)->id.name + 2, (*ob)->id.name + 2);
	}
#endif

	return iter->fase;
}