Ejemplo n.º 1
0
static int editsource_exec(bContext *C, wmOperator *op)
{
  uiBut *but = UI_context_active_but_get(C);

  if (but) {
    GHashIterator ghi;
    struct uiEditSourceButStore *but_store = NULL;

    ARegion *ar = CTX_wm_region(C);
    int ret;

    /* needed else the active button does not get tested */
    UI_screen_free_active_but(C, CTX_wm_screen(C));

    // printf("%s: begin\n", __func__);

    /* take care not to return before calling ui_editsource_active_but_clear */
    ui_editsource_active_but_set(but);

    /* redraw and get active button python info */
    ED_region_do_layout(C, ar);
    ED_region_do_draw(C, ar);
    ar->do_draw = false;

    for (BLI_ghashIterator_init(&ghi, ui_editsource_info->hash);
         BLI_ghashIterator_done(&ghi) == false;
         BLI_ghashIterator_step(&ghi)) {
      uiBut *but_key = BLI_ghashIterator_getKey(&ghi);
      if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) {
        but_store = BLI_ghashIterator_getValue(&ghi);
        break;
      }
    }

    if (but_store) {
      if (but_store->py_dbg_ln != -1) {
        ret = editsource_text_edit(C, op, but_store->py_dbg_fn, but_store->py_dbg_ln);
      }
      else {
        BKE_report(
            op->reports, RPT_ERROR, "Active button is not from a script, cannot edit source");
        ret = OPERATOR_CANCELLED;
      }
    }
    else {
      BKE_report(op->reports, RPT_ERROR, "Active button match cannot be found");
      ret = OPERATOR_CANCELLED;
    }

    ui_editsource_active_but_clear();

    // printf("%s: end\n", __func__);

    return ret;
  }
  else {
    BKE_report(op->reports, RPT_ERROR, "Active button not found");
    return OPERATOR_CANCELLED;
  }
}
Ejemplo n.º 2
0
static char *gpu_generate_function_prototyps(GHash *hash)
{
	DynStr *ds = BLI_dynstr_new();
	GHashIterator *ghi;
	GPUFunction *function;
	char *name, *prototypes;
	int a;
	
	/* automatically generate function prototypes to add to the top of the
	 * generated code, to avoid have to add the actual code & recompile all */
	ghi = BLI_ghashIterator_new(hash);

	for (; !BLI_ghashIterator_done(ghi); BLI_ghashIterator_step(ghi)) {
		name = BLI_ghashIterator_getValue(ghi);
		function = BLI_ghashIterator_getValue(ghi);

		BLI_dynstr_appendf(ds, "void %s(", name);
		for (a = 0; a < function->totparam; a++) {
			if (function->paramqual[a] == FUNCTION_QUAL_OUT)
				BLI_dynstr_append(ds, "out ");
			else if (function->paramqual[a] == FUNCTION_QUAL_INOUT)
				BLI_dynstr_append(ds, "inout ");

			if (function->paramtype[a] == GPU_TEX2D)
				BLI_dynstr_append(ds, "sampler2D");
			else if (function->paramtype[a] == GPU_SHADOW2D)
				BLI_dynstr_append(ds, "sampler2DShadow");
			else
				BLI_dynstr_append(ds, GPU_DATATYPE_STR[function->paramtype[a]]);
#  if 0
			BLI_dynstr_appendf(ds, " param%d", a);
#  endif

			if (a != function->totparam-1)
				BLI_dynstr_append(ds, ", ");
		}
		BLI_dynstr_append(ds, ");\n");
	}

	BLI_dynstr_append(ds, "\n");

	prototypes = BLI_dynstr_get_cstring(ds);
	BLI_dynstr_free(ds);

	return prototypes;
}
Ejemplo n.º 3
0
void WM_uilisttype_free(void)
{
	GHashIterator gh_iter;

	GHASH_ITER (gh_iter, uilisttypes_hash) {
		uiListType *ult = BLI_ghashIterator_getValue(&gh_iter);
		if (ult->ext.free) {
			ult->ext.free(ult->ext.data);
		}
	}
Ejemplo n.º 4
0
static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
{
	GHashIterator gh_iter;
	GHASH_ITER (gh_iter, verts) {
		void *key = BLI_ghashIterator_getKey(&gh_iter);
		BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
		unsigned int id = GET_INT_FROM_POINTER(key);
		BMVert *v = bm_log_vert_from_id(log, id);

		/* Ensure the log has the final values of the vertex before
		 * deleting it */
		bm_log_vert_bmvert_copy(bm, lv, v);

		BM_vert_kill(bm, v);
	}
Ejemplo n.º 5
0
void free_sss(Render *re)
{
	if (re->sss_hash) {
		GHashIterator *it= BLI_ghashIterator_new(re->sss_hash);

		while (!BLI_ghashIterator_done(it)) {
			sss_free_tree(BLI_ghashIterator_getValue(it));
			BLI_ghashIterator_step(it);
		}

		BLI_ghashIterator_free(it);
		BLI_ghash_free(re->sss_hash, NULL, NULL);
		re->sss_hash= NULL;
	}
}
Ejemplo n.º 6
0
Archivo: wm.c Proyecto: mik0001/Blender
void WM_menutype_free(void)
{
	GHashIterator *iter= BLI_ghashIterator_new(menutypes_hash);

	for( ; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
		MenuType *mt= BLI_ghashIterator_getValue(iter);
		if(mt->ext.free) {
			mt->ext.free(mt->ext.data);
		}
	}
	BLI_ghashIterator_free(iter);

	BLI_ghash_free(menutypes_hash, NULL, (GHashValFreeFP)MEM_freeN);
	menutypes_hash= NULL;
}
Ejemplo n.º 7
0
void WM_uilisttype_free(void)
{
	GHashIterator *iter = BLI_ghashIterator_new(uilisttypes_hash);

	for (; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
		uiListType *ult = BLI_ghashIterator_getValue(iter);
		if (ult->ext.free) {
			ult->ext.free(ult->ext.data);
		}
	}
	BLI_ghashIterator_free(iter);

	BLI_ghash_free(uilisttypes_hash, NULL, MEM_freeN);
	uilisttypes_hash = NULL;
}
Ejemplo n.º 8
0
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
	GHashIterator iter;

	for (WM_operatortype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);

		if (BLI_strcasestr(ot->name, str)) {
			if (WM_operator_poll((bContext *)C, ot)) {
				
				if (false == UI_search_item_add(items, ot->name, ot, 0))
					break;
			}
		}
	}
}
Ejemplo n.º 9
0
static PyObject *pyop_dir(PyObject *UNUSED(self))
{
	GHashIterator *iter = WM_operatortype_iter();
	PyObject *list = PyList_New(0), *name;

	for ( ; !BLI_ghashIterator_done(iter); BLI_ghashIterator_step(iter)) {
		wmOperatorType *ot = BLI_ghashIterator_getValue(iter);

		name = PyUnicode_FromString(ot->idname);
		PyList_Append(list, name);
		Py_DECREF(name);
	}
	BLI_ghashIterator_free(iter);

	return list;
}
Ejemplo n.º 10
0
static PyObject *pyop_dir(PyObject *UNUSED(self))
{
	GHashIterator iter;
	PyObject *list;
	int i;

	WM_operatortype_iter(&iter);
	list = PyList_New(BLI_ghash_len(iter.gh));

	for (i = 0; !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter), i++) {
		wmOperatorType *ot = BLI_ghashIterator_getValue(&iter);
		PyList_SET_ITEM(list, i, PyUnicode_FromString(ot->idname));
	}

	return list;
}
Ejemplo n.º 11
0
static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
{
	const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK);

	GHashIterator gh_iter;
	GHASH_ITER (gh_iter, verts) {
		void *key = BLI_ghashIterator_getKey(&gh_iter);
		BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
		unsigned int id = GET_UINT_FROM_POINTER(key);
		BMVert *v = bm_log_vert_from_id(log, id);

		/* Ensure the log has the final values of the vertex before
		 * deleting it */
		bm_log_vert_bmvert_copy(lv, v, cd_vert_mask_offset);

		BM_vert_kill(bm, v);
	}
Ejemplo n.º 12
0
static void operator_search_cb(const struct bContext *C, void *UNUSED(arg), const char *str, uiSearchItems *items)
{
	GHashIterator *iter = WM_operatortype_iter();

	for (; !BLI_ghashIterator_isDone(iter); BLI_ghashIterator_step(iter)) {
		wmOperatorType *ot = BLI_ghashIterator_getValue(iter);

		if (BLI_strcasestr(ot->name, str)) {
			if (WM_operator_poll((bContext *)C, ot)) {
				
				if (0 == uiSearchItemAdd(items, ot->name, ot, 0))
					break;
			}
		}
	}
	BLI_ghashIterator_free(iter);
}
Ejemplo n.º 13
0
void BKE_sim_debug_data_clear_category(const char *category)
{
	int category_hash = (int)BLI_ghashutil_strhash_p(category);
	
	if (!_sim_debug_data)
		return;
	
	if (_sim_debug_data->gh) {
		GHashIterator iter;
		BLI_ghashIterator_init(&iter, _sim_debug_data->gh);
		while (!BLI_ghashIterator_done(&iter)) {
			const SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
			BLI_ghashIterator_step(&iter); /* removing invalidates the current iterator, so step before removing */
			
			if (elem->category_hash == category_hash)
				BLI_ghash_remove(_sim_debug_data->gh, elem, NULL, debug_element_free);
		}
	}
}
Ejemplo n.º 14
0
void IMB_moviecache_cleanup(MovieCache *cache, bool (cleanup_check_cb) (ImBuf *ibuf, void *userkey, void *userdata), void *userdata)
{
	GHashIterator *iter;

	check_unused_keys(cache);

	iter = BLI_ghashIterator_new(cache->hash);
	while (!BLI_ghashIterator_done(iter)) {
		MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
		MovieCacheItem *item = BLI_ghashIterator_getValue(iter);

		BLI_ghashIterator_step(iter);

		if (cleanup_check_cb(item->ibuf, key->userkey, userdata)) {
			PRINT("%s: cache '%s' remove item %p\n", __func__, cache->name, item);

			BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
		}
	}

	BLI_ghashIterator_free(iter);
}
Ejemplo n.º 15
0
static void check_unused_keys(MovieCache *cache)
{
	GHashIterator *iter;

	iter = BLI_ghashIterator_new(cache->hash);
	while (!BLI_ghashIterator_done(iter)) {
		MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
		MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
		int remove = 0;

		BLI_ghashIterator_step(iter);

		remove = !item->ibuf;

		if (remove) {
			PRINT("%s: cache '%s' remove item %p without buffer\n", __func__, cache->name, item);
		}

		if (remove)
			BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
	}

	BLI_ghashIterator_free(iter);
}
Ejemplo n.º 16
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
                                  DerivedMesh *derivedData,
                                  ModifierApplyFlag UNUSED(flag))
{
	MaskModifierData *mmd = (MaskModifierData *)md;
	DerivedMesh *dm = derivedData, *result = NULL;
	GHash *vertHash = NULL, *edgeHash, *polyHash;
	GHashIterator *hashIter;
	MDeformVert *dvert = NULL, *dv;
	int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
	int maxVerts, maxEdges, maxPolys;
	int i;

	MPoly *mpoly;
	MLoop *mloop;

	MPoly *mpoly_new;
	MLoop *mloop_new;
	MEdge *medge_new;
	MVert *mvert_new;


	int *loop_mapping;

	/* Overview of Method:
	 *	1. Get the vertices that are in the vertexgroup of interest 
	 *	2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
	 *	3. Make a new mesh containing only the mapping data
	 */
	
	/* get original number of verts, edges, and faces */
	maxVerts = dm->getNumVerts(dm);
	maxEdges = dm->getNumEdges(dm);
	maxPolys = dm->getNumPolys(dm);
	
	/* check if we can just return the original mesh 
	 *	- must have verts and therefore verts assigned to vgroups to do anything useful
	 */
	if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
	    (maxVerts == 0) || (ob->defbase.first == NULL) )
	{
		return derivedData;
	}
	
	/* if mode is to use selected armature bones, aggregate the bone groups */
	if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
		Object *oba = mmd->ob_arm;
		bPoseChannel *pchan;
		bDeformGroup *def;
		char *bone_select_array;
		int bone_select_tot = 0;
		const int defbase_tot = BLI_countlist(&ob->defbase);
		
		/* check that there is armature object with bones to use, otherwise return original mesh */
		if (ELEM3(NULL, oba, oba->pose, ob->defbase.first))
			return derivedData;
		
		/* determine whether each vertexgroup is associated with a selected bone or not 
		 * - each cell is a boolean saying whether bone corresponding to the ith group is selected
		 * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
		 */
		bone_select_array = MEM_mallocN(defbase_tot * sizeof(char), "mask array");
		
		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
			pchan = BKE_pose_channel_find_name(oba->pose, def->name);
			if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
				bone_select_array[i] = TRUE;
				bone_select_tot++;
			}
			else {
				bone_select_array[i] = FALSE;
			}
		}
		
		/* if no dverts (i.e. no data for vertex groups exists), we've got an
		 * inconsistent situation, so free hashes and return oirginal mesh
		 */
		dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
		if (dvert == NULL) {
			MEM_freeN(bone_select_array);
			return derivedData;
		}
		
		/* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
		 * key = oldindex, value = newindex
		 */
		vertHash = BLI_ghash_int_new("mask vert gh");
		
		/* add vertices which exist in vertexgroups into vertHash for filtering 
		 * - dv = for each vertex, what vertexgroups does it belong to
		 * - dw = weight that vertex was assigned to a vertexgroup it belongs to
		 */
		for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
			MDeformWeight *dw = dv->dw;
			short found = 0;
			int j;
			
			/* check the groups that vertex is assigned to, and see if it was any use */
			for (j = 0; j < dv->totweight; j++, dw++) {
				if (dw->def_nr < defbase_tot) {
					if (bone_select_array[dw->def_nr]) {
						if (dw->weight != 0.0f) {
							found = TRUE;
							break;
						}
					}
				}
			}
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (found) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!found) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
		
		/* free temp hashes */
		MEM_freeN(bone_select_array);
	}
	else {  /* --- Using Nominated VertexGroup only --- */
		int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
		
		/* get dverts */
		if (defgrp_index != -1)
			dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
			
		/* if no vgroup (i.e. dverts) found, return the initial mesh */
		if ((defgrp_index == -1) || (dvert == NULL))
			return dm;
			
		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash = BLI_ghash_int_new("mask vert2 bh");
		
		/* add vertices which exist in vertexgroup into ghash for filtering */
		for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
			const int weight_set = defvert_find_weight(dv, defgrp_index) != 0.0f;
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (weight_set) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!weight_set) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
	}

	/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
	edgeHash = BLI_ghash_int_new("mask ed2 gh");
	polyHash = BLI_ghash_int_new("mask fa2 gh");
	
	mpoly = dm->getPolyArray(dm);
	mloop = dm->getLoopArray(dm);

	loop_mapping = MEM_callocN(sizeof(int) * maxPolys, "mask loopmap"); /* overalloc, assume all polys are seen */

	/* loop over edges and faces, and do the same thing to 
	 * ensure that they only reference existing verts 
	 */
	for (i = 0; i < maxEdges; i++) {
		MEdge me;
		dm->getEdge(dm, i, &me);
		
		/* only add if both verts will be in new mesh */
		if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
		    BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
		{
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
			numEdges++;
		}
	}
	for (i = 0; i < maxPolys; i++) {
		MPoly *mp = &mpoly[i];
		MLoop *ml = mloop + mp->loopstart;
		int ok = TRUE;
		int j;
		
		for (j = 0; j < mp->totloop; j++, ml++) {
			if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v))) {
				ok = FALSE;
				break;
			}
		}
		
		/* all verts must be available */
		if (ok) {
			BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys));
			loop_mapping[numPolys] = numLoops;
			numPolys++;
			numLoops += mp->totloop;
		}
	}
	
	
	/* now we know the number of verts, edges and faces, 
	 * we can create the new (reduced) mesh
	 */
	result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys);
	
	mpoly_new = CDDM_get_polys(result);
	mloop_new = CDDM_get_loops(result);
	medge_new = CDDM_get_edges(result);
	mvert_new = CDDM_get_verts(result);
	
	/* using ghash-iterators, map data into new mesh */
	/* vertices */
	for (hashIter = BLI_ghashIterator_new(vertHash);
	     !BLI_ghashIterator_isDone(hashIter);
	     BLI_ghashIterator_step(hashIter) )
	{
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getVert(dm, oldIndex, &source);
		dest = &mvert_new[newIndex];
		
		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
		
	/* edges */
	for (hashIter = BLI_ghashIterator_new(edgeHash);
	     !BLI_ghashIterator_isDone(hashIter);
	     BLI_ghashIterator_step(hashIter))
	{
		MEdge source;
		MEdge *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getEdge(dm, oldIndex, &source);
		dest = &medge_new[newIndex];
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		
		DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
	
	/* faces */
	for (hashIter = BLI_ghashIterator_new(polyHash);
	     !BLI_ghashIterator_isDone(hashIter);
	     BLI_ghashIterator_step(hashIter) )
	{
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		MPoly *source = &mpoly[oldIndex];
		MPoly *dest = &mpoly_new[newIndex];
		int oldLoopIndex = source->loopstart;
		int newLoopIndex = loop_mapping[newIndex];
		MLoop *source_loop = &mloop[oldLoopIndex];
		MLoop *dest_loop = &mloop_new[newLoopIndex];
		
		DM_copy_poly_data(dm, result, oldIndex, newIndex, 1);
		DM_copy_loop_data(dm, result, oldLoopIndex, newLoopIndex, source->totloop);

		*dest = *source;
		dest->loopstart = newLoopIndex;
		for (i = 0; i < source->totloop; i++) {
			dest_loop[i].v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source_loop[i].v)));
			dest_loop[i].e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(source_loop[i].e)));
		}
	}

	BLI_ghashIterator_free(hashIter);

	MEM_freeN(loop_mapping);

	/* why is this needed? - campbell */
	/* recalculate normals */
	CDDM_calc_normals(result);
	
	/* free hashes */
	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	BLI_ghash_free(polyHash, NULL, NULL);

	/* return the new mesh */
	return result;
}
Ejemplo n.º 17
0
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
                                  DerivedMesh *derivedData,
                                  ModifierApplyFlag UNUSED(flag))
{
	DerivedMesh *dm = derivedData;
	DerivedMesh *result;
	BuildModifierData *bmd = (BuildModifierData *) md;
	int i, j, k;
	int numFaces_dst, numEdges_dst, numLoops_dst = 0;
	int *vertMap, *edgeMap, *faceMap;
	float frac;
	MPoly *mpoly_dst;
	MLoop *ml_dst, *ml_src /*, *mloop_dst */;
	GHashIterator *hashIter;
	/* maps vert indices in old mesh to indices in new mesh */
	GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
	/* maps edge indices in new mesh to indices in old mesh */
	GHash *edgeHash = BLI_ghash_int_new("build ed apply gh");
	GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");

	const int numVert_src = dm->getNumVerts(dm);
	const int numEdge_src = dm->getNumEdges(dm);
	const int numPoly_src = dm->getNumPolys(dm);
	MPoly *mpoly_src = dm->getPolyArray(dm);
	MLoop *mloop_src = dm->getLoopArray(dm);
	MEdge *medge_src = dm->getEdgeArray(dm);
	MVert *mvert_src = dm->getVertArray(dm);


	vertMap = MEM_mallocN(sizeof(*vertMap) * numVert_src, "build modifier vertMap");
	edgeMap = MEM_mallocN(sizeof(*edgeMap) * numEdge_src, "build modifier edgeMap");
	faceMap = MEM_mallocN(sizeof(*faceMap) * numPoly_src, "build modifier faceMap");

#pragma omp parallel sections if (numVert_src + numEdge_src + numPoly_src >= DM_OMP_LIMIT)
	{
#pragma omp section
		{ range_vn_i(vertMap, numVert_src, 0); }
#pragma omp section
		{ range_vn_i(edgeMap, numEdge_src, 0); }
#pragma omp section
		{ range_vn_i(faceMap, numPoly_src, 0); }
	}

	frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length;
	CLAMP(frac, 0.0f, 1.0f);

	numFaces_dst = numPoly_src * frac;
	numEdges_dst = numEdge_src * frac;

	/* if there's at least one face, build based on faces */
	if (numFaces_dst) {
		MPoly *mpoly, *mp;
		MLoop *ml, *mloop;
		MEdge *medge;
		
		if (bmd->randomize) {
			BLI_array_randomize(faceMap, sizeof(*faceMap),
			                    numPoly_src, bmd->seed);
		}

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		mpoly = mpoly_src;
		mloop = mloop_src;
		for (i = 0; i < numFaces_dst; i++) {
			mp = mpoly + faceMap[i];
			ml = mloop + mp->loopstart;

			for (j = 0; j < mp->totloop; j++, ml++) {
				if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml->v)))
					BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(ml->v),
					                 SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			}
			
			numLoops_dst += mp->totloop;
		}

		/* get the set of edges that will be in the new mesh (i.e. all edges
		 * that have both verts in the new mesh)
		 */
		medge = medge_src;
		for (i = 0; i < numEdge_src; i++) {
			MEdge *me = medge + i;

			if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) &&
			    BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2)))
			{
				j = BLI_ghash_size(edgeHash);
				
				BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j),
				                 SET_INT_IN_POINTER(i));
				BLI_ghash_insert(edgeHash2, SET_INT_IN_POINTER(i),
				                 SET_INT_IN_POINTER(j));
			}
		}
	}
	else if (numEdges_dst) {
		MEdge *medge, *me;

		if (bmd->randomize)
			BLI_array_randomize(edgeMap, sizeof(*edgeMap),
			                    numEdge_src, bmd->seed);

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		medge = medge_src;
		for (i = 0; i < numEdges_dst; i++) {
			me = medge + edgeMap[i];

			if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1))) {
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v1),
				                 SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			}
			if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2))) {
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me->v2), SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			}
		}

		/* get the set of edges that will be in the new mesh */
		for (i = 0; i < numEdges_dst; i++) {
			j = BLI_ghash_size(edgeHash);
			
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j),
			                 SET_INT_IN_POINTER(edgeMap[i]));
			BLI_ghash_insert(edgeHash2,  SET_INT_IN_POINTER(edgeMap[i]),
			                 SET_INT_IN_POINTER(j));
		}
	}
	else {
		int numVerts = numVert_src * frac;

		if (bmd->randomize) {
			BLI_array_randomize(vertMap, sizeof(*vertMap),
			                    numVert_src, bmd->seed);
		}

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		for (i = 0; i < numVerts; i++) {
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
		}
	}

	/* now we know the number of verts, edges and faces, we can create
	 * the mesh
	 */
	result = CDDM_from_template(dm, BLI_ghash_size(vertHash),
	                            BLI_ghash_size(edgeHash), 0, numLoops_dst, numFaces_dst);

	/* copy the vertices across */
	for (hashIter = BLI_ghashIterator_new(vertHash);
	     BLI_ghashIterator_done(hashIter) == false;
	     BLI_ghashIterator_step(hashIter)
	     )
	{
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));

		source = mvert_src[oldIndex];
		dest = CDDM_get_vert(result, newIndex);

		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
	
	/* copy the edges across, remapping indices */
	for (i = 0; i < BLI_ghash_size(edgeHash); i++) {
		MEdge source;
		MEdge *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
		
		source = medge_src[oldIndex];
		dest = CDDM_get_edge(result, i);
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		
		DM_copy_edge_data(dm, result, oldIndex, i, 1);
		*dest = source;
	}

	mpoly_dst = CDDM_get_polys(result);
	/* mloop_dst = */ ml_dst = CDDM_get_loops(result);
	
	/* copy the faces across, remapping indices */
	k = 0;
	for (i = 0; i < numFaces_dst; i++) {
		MPoly *source;
		MPoly *dest;
		
		source = mpoly_src + faceMap[i];
		dest = mpoly_dst + i;
		DM_copy_poly_data(dm, result, faceMap[i], i, 1);
		
		*dest = *source;
		dest->loopstart = k;
		
		DM_copy_loop_data(dm, result, source->loopstart, dest->loopstart, dest->totloop);

		ml_src = mloop_src + source->loopstart;
		for (j = 0; j < source->totloop; j++, k++, ml_src++, ml_dst++) {
			ml_dst->v = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(ml_src->v)));
			ml_dst->e = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash2, SET_INT_IN_POINTER(ml_src->e)));
		}
	}

	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	BLI_ghash_free(edgeHash2, NULL, NULL);
	
	MEM_freeN(vertMap);
	MEM_freeN(edgeMap);
	MEM_freeN(faceMap);

	if (dm->dirty & DM_DIRTY_NORMALS) {
		result->dirty |= DM_DIRTY_NORMALS;
	}

	return result;
}
Ejemplo n.º 18
0
static GHash *text_autocomplete_build(Text *text)
{
	GHash *gh;
	int seek_len = 0;
	const char *seek;
	texttool_text_clear();

	texttool_text_set_active(text);

	/* first get the word we're at */
	{
		const int i = text_find_identifier_start(text->curl->line, text->curc);
		seek_len = text->curc - i;
		seek = text->curl->line + i;

		// BLI_strncpy(seek, seek_ptr, seek_len);
	}

	/* now walk over entire doc and suggest words */
	{
		TextLine *linep;

		gh = BLI_ghash_str_new(__func__);

		for (linep = text->lines.first; linep; linep = linep->next) {
			size_t i_start = 0;
			size_t i_end = 0;
			size_t i_pos = 0;

			while (i_start < linep->len) {
				/* seek identifier beginning */
				i_pos = i_start;
				while ((i_start < linep->len) &&
				       (!text_check_identifier_nodigit_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_start], &i_pos))))
				{
					i_start = i_pos;
				}
				i_pos = i_end = i_start;
				while ((i_end < linep->len) &&
				       (text_check_identifier_unicode(BLI_str_utf8_as_unicode_and_size_safe(&linep->line[i_end], &i_pos))))
				{
					i_end = i_pos;
				}

				if ((i_start != i_end) &&
				    /* check we're at the beginning of a line or that the previous char is not an identifier
				     * this prevents digits from being added */
				    ((i_start < 1) || !text_check_identifier_unicode(BLI_str_utf8_as_unicode(&linep->line[i_start - 1]))))
				{
					char *str_sub = &linep->line[i_start];
					const int choice_len = i_end - i_start;

					if ((choice_len > seek_len) &&
					    (seek_len == 0 || STREQLEN(seek, str_sub, seek_len)) &&
					    (seek != str_sub))
					{
						// printf("Adding: %s\n", s);
						char str_sub_last = str_sub[choice_len];
						str_sub[choice_len] = '\0';
						if (!BLI_ghash_lookup(gh, str_sub)) {
							char *str_dup = BLI_strdupn(str_sub, choice_len);
							BLI_ghash_insert(gh, str_dup, str_dup);  /* A 'set' would make more sense here */
						}
						str_sub[choice_len] = str_sub_last;
					}
				}
				if (i_end != i_start) {
					i_start = i_end;
				}
				else {
					/* highly unlikely, but prevent eternal loop */
					i_start++;
				}
			}
		}

		{
			GHashIterator gh_iter;

			/* get the formatter for highlighting */
			TextFormatType *tft;
			tft = ED_text_format_get(text);

			GHASH_ITER (gh_iter, gh) {
				const char *s = BLI_ghashIterator_getValue(&gh_iter);
				texttool_suggest_add(s, tft->format_identifier(s));
			}
		}
	}

	texttool_suggest_prefix(seek, seek_len);

	return gh;
}
Ejemplo n.º 19
0
/* get segments of cached frames. useful for debugging cache policies */
void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
{
	*totseg_r = 0;
	*points_r = NULL;

	if (!cache->getdatafp)
		return;

	if (cache->proxy != proxy || cache->render_flags != render_flags) {
		if (cache->points)
			MEM_freeN(cache->points);

		cache->points = NULL;
	}

	if (cache->points) {
		*totseg_r = cache->totseg;
		*points_r = cache->points;
	}
	else {
		int totframe = BLI_ghash_size(cache->hash);
		int *frames = MEM_callocN(totframe * sizeof(int), "movieclip cache frames");
		int a, totseg = 0;
		GHashIterator *iter;

		iter = BLI_ghashIterator_new(cache->hash);
		a = 0;
		while (!BLI_ghashIterator_done(iter)) {
			MovieCacheKey *key = BLI_ghashIterator_getKey(iter);
			MovieCacheItem *item = BLI_ghashIterator_getValue(iter);
			int framenr, curproxy, curflags;

			if (item->ibuf) {
				cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);

				if (curproxy == proxy && curflags == render_flags)
					frames[a++] = framenr;
			}

			BLI_ghashIterator_step(iter);
		}

		BLI_ghashIterator_free(iter);

		qsort(frames, totframe, sizeof(int), compare_int);

		/* count */
		for (a = 0; a < totframe; a++) {
			if (a && frames[a] - frames[a - 1] != 1)
				totseg++;

			if (a == totframe - 1)
				totseg++;
		}

		if (totseg) {
			int b, *points;

			points = MEM_callocN(2 * sizeof(int) * totseg, "movieclip cache segments");

			/* fill */
			for (a = 0, b = 0; a < totframe; a++) {
				if (a == 0)
					points[b++] = frames[a];

				if (a && frames[a] - frames[a - 1] != 1) {
					points[b++] = frames[a - 1];
					points[b++] = frames[a];
				}

				if (a == totframe - 1)
					points[b++] = frames[a];
			}

			*totseg_r = totseg;
			*points_r = points;

			cache->totseg = totseg;
			cache->points = points;
			cache->proxy = proxy;
			cache->render_flags = render_flags;
		}

		MEM_freeN(frames);
	}
}
Ejemplo n.º 20
0
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
						DerivedMesh *derivedData,
						int UNUSED(useRenderParams),
						int UNUSED(isFinalCalc))
{
	DerivedMesh *dm = derivedData;
	DerivedMesh *result;
	BuildModifierData *bmd = (BuildModifierData*) md;
	int i;
	int numFaces, numEdges;
	int *vertMap, *edgeMap, *faceMap;
	float frac;
	GHashIterator *hashIter;
	/* maps vert indices in old mesh to indices in new mesh */
	GHash *vertHash = BLI_ghash_new(BLI_ghashutil_inthash,
					BLI_ghashutil_intcmp, "build ve apply gh");
	/* maps edge indices in new mesh to indices in old mesh */
	GHash *edgeHash = BLI_ghash_new(BLI_ghashutil_inthash,
					BLI_ghashutil_intcmp, "build ed apply gh");

	const int maxVerts= dm->getNumVerts(dm);
	const int maxEdges= dm->getNumEdges(dm);
	const int maxFaces= dm->getNumFaces(dm);

	vertMap = MEM_callocN(sizeof(*vertMap) * maxVerts, "build modifier vertMap");
	for(i = 0; i < maxVerts; ++i) vertMap[i] = i;
	edgeMap = MEM_callocN(sizeof(*edgeMap) * maxEdges, "build modifier edgeMap");
	for(i = 0; i < maxEdges; ++i) edgeMap[i] = i;
	faceMap = MEM_callocN(sizeof(*faceMap) * maxFaces, "build modifier faceMap");
	for(i = 0; i < maxFaces; ++i) faceMap[i] = i;

	frac = (BKE_curframe(md->scene) - bmd->start) / bmd->length;
	CLAMP(frac, 0.0f, 1.0f);

	numFaces = dm->getNumFaces(dm) * frac;
	numEdges = dm->getNumEdges(dm) * frac;

	/* if there's at least one face, build based on faces */
	if(numFaces) {
		if(bmd->randomize)
			BLI_array_randomize(faceMap, sizeof(*faceMap),
						maxFaces, bmd->seed);

		/* get the set of all vert indices that will be in the final mesh,
		* mapped to the new indices
		*/
		for(i = 0; i < numFaces; ++i) {
			MFace mf;
			dm->getFace(dm, faceMap[i], &mf);

			if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v1),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v2),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v3),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			if(mf.v4 && !BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(mf.v4),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
		}

		/* get the set of edges that will be in the new mesh (i.e. all edges
		* that have both verts in the new mesh)
		*/
		for(i = 0; i < maxEdges; ++i) {
			MEdge me;
			dm->getEdge(dm, i, &me);

			if(BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1))
						&& BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
				BLI_ghash_insert(edgeHash,
					SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)), SET_INT_IN_POINTER(i));
		}
	} else if(numEdges) {
		if(bmd->randomize)
			BLI_array_randomize(edgeMap, sizeof(*edgeMap),
						maxEdges, bmd->seed);

		/* get the set of all vert indices that will be in the final mesh,
		* mapped to the new indices
		*/
		for(i = 0; i < numEdges; ++i) {
			MEdge me;
			dm->getEdge(dm, edgeMap[i], &me);

			if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v1),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
			if(!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)))
				BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(me.v2),
					SET_INT_IN_POINTER(BLI_ghash_size(vertHash)));
		}

		/* get the set of edges that will be in the new mesh
		*/
		for(i = 0; i < numEdges; ++i) {
			MEdge me;
			dm->getEdge(dm, edgeMap[i], &me);

			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(BLI_ghash_size(edgeHash)),
					 SET_INT_IN_POINTER(edgeMap[i]));
		}
	} else {
		int numVerts = dm->getNumVerts(dm) * frac;

		if(bmd->randomize)
			BLI_array_randomize(vertMap, sizeof(*vertMap),
						maxVerts, bmd->seed);

		/* get the set of all vert indices that will be in the final mesh,
		* mapped to the new indices
		*/
		for(i = 0; i < numVerts; ++i)
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
	}

	/* now we know the number of verts, edges and faces, we can create
	* the mesh
	*/
	result = CDDM_from_template(dm, BLI_ghash_size(vertHash),
					BLI_ghash_size(edgeHash), numFaces);

	/* copy the vertices across */
	for(	hashIter = BLI_ghashIterator_new(vertHash);
			!BLI_ghashIterator_isDone(hashIter);
			BLI_ghashIterator_step(hashIter)
	) {
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));

		dm->getVert(dm, oldIndex, &source);
		dest = CDDM_get_vert(result, newIndex);

		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
	
	/* copy the edges across, remapping indices */
	for(i = 0; i < BLI_ghash_size(edgeHash); ++i) {
		MEdge source;
		MEdge *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_INT_IN_POINTER(i)));
		
		dm->getEdge(dm, oldIndex, &source);
		dest = CDDM_get_edge(result, i);
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		
		DM_copy_edge_data(dm, result, oldIndex, i, 1);
		*dest = source;
	}

	/* copy the faces across, remapping indices */
	for(i = 0; i < numFaces; ++i) {
		MFace source;
		MFace *dest;
		int orig_v4;
		
		dm->getFace(dm, faceMap[i], &source);
		dest = CDDM_get_face(result, i);
		
		orig_v4 = source.v4;
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
		if(source.v4)
			source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
		
		DM_copy_face_data(dm, result, faceMap[i], i, 1);
		*dest = source;
		
		test_index_face(dest, &result->faceData, i, (orig_v4 ? 4 : 3));
	}

	CDDM_calc_normals(result);
	
	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	
	MEM_freeN(vertMap);
	MEM_freeN(edgeMap);
	MEM_freeN(faceMap);
	
	return result;
}
Ejemplo n.º 21
0
ImBuf *IMB_moviecacheIter_getImBuf(struct MovieCacheIter *iter)
{
	MovieCacheItem *item = BLI_ghashIterator_getValue((GHashIterator *) iter);
	return item->ibuf;
}
Ejemplo n.º 22
0
static DerivedMesh *applyModifier(
        ModifierData *md, Object *ob,
        DerivedMesh *dm,
        ModifierApplyFlag UNUSED(flag))
{
	MaskModifierData *mmd = (MaskModifierData *)md;
	const bool found_test = (mmd->flag & MOD_MASK_INV) == 0;
	DerivedMesh *result = NULL;
	GHash *vertHash = NULL, *edgeHash, *polyHash;
	GHashIterator gh_iter;
	MDeformVert *dvert, *dv;
	int numPolys = 0, numLoops = 0, numEdges = 0, numVerts = 0;
	int maxVerts, maxEdges, maxPolys;
	int i;

	const MVert *mvert_src;
	const MEdge *medge_src;
	const MPoly *mpoly_src;
	const MLoop *mloop_src;

	MPoly *mpoly_dst;
	MLoop *mloop_dst;
	MEdge *medge_dst;
	MVert *mvert_dst;

	int *loop_mapping;

	dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
	if (dvert == NULL) {
		return found_test ? CDDM_from_template(dm, 0, 0, 0, 0, 0) : dm;
	}

	/* Overview of Method:
	 *	1. Get the vertices that are in the vertexgroup of interest
	 *	2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
	 *	3. Make a new mesh containing only the mapping data
	 */

	/* get original number of verts, edges, and faces */
	maxVerts = dm->getNumVerts(dm);
	maxEdges = dm->getNumEdges(dm);
	maxPolys = dm->getNumPolys(dm);

	/* check if we can just return the original mesh
	 *	- must have verts and therefore verts assigned to vgroups to do anything useful
	 */
	if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
	    (maxVerts == 0) || BLI_listbase_is_empty(&ob->defbase))
	{
		return dm;
	}

	/* if mode is to use selected armature bones, aggregate the bone groups */
	if (mmd->mode == MOD_MASK_MODE_ARM) { /* --- using selected bones --- */
		Object *oba = mmd->ob_arm;
		bPoseChannel *pchan;
		bDeformGroup *def;
		bool *bone_select_array;
		int bone_select_tot = 0;
		const int defbase_tot = BLI_listbase_count(&ob->defbase);

		/* check that there is armature object with bones to use, otherwise return original mesh */
		if (ELEM(NULL, oba, oba->pose, ob->defbase.first))
			return dm;

		/* determine whether each vertexgroup is associated with a selected bone or not
		 * - each cell is a boolean saying whether bone corresponding to the ith group is selected
		 * - groups that don't match a bone are treated as not existing (along with the corresponding ungrouped verts)
		 */
		bone_select_array = MEM_malloc_arrayN((size_t)defbase_tot, sizeof(char), "mask array");

		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
			pchan = BKE_pose_channel_find_name(oba->pose, def->name);
			if (pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED)) {
				bone_select_array[i] = true;
				bone_select_tot++;
			}
			else {
				bone_select_array[i] = false;
			}
		}

		/* verthash gives mapping from original vertex indices to the new indices (including selected matches only)
		 * key = oldindex, value = newindex
		 */
		vertHash = BLI_ghash_int_new_ex("mask vert gh", (unsigned int)maxVerts);

		/* add vertices which exist in vertexgroups into vertHash for filtering
		 * - dv = for each vertex, what vertexgroups does it belong to
		 * - dw = weight that vertex was assigned to a vertexgroup it belongs to
		 */
		for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
			MDeformWeight *dw = dv->dw;
			bool found = false;
			int j;

			/* check the groups that vertex is assigned to, and see if it was any use */
			for (j = 0; j < dv->totweight; j++, dw++) {
				if (dw->def_nr < defbase_tot) {
					if (bone_select_array[dw->def_nr]) {
						if (dw->weight != 0.0f) {
							found = true;
							break;
						}
					}
				}
			}

			if (found_test != found) {
				continue;
			}

			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}

		/* free temp hashes */
		MEM_freeN(bone_select_array);
	}
	else {  /* --- Using Nominated VertexGroup only --- */
		int defgrp_index = defgroup_name_index(ob, mmd->vgroup);

		/* if no vgroup (i.e. dverts) found, return the initial mesh */
		if (defgrp_index == -1)
			return dm;

		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash = BLI_ghash_int_new_ex("mask vert2 bh", (unsigned int)maxVerts);

		/* add vertices which exist in vertexgroup into ghash for filtering */
		for (i = 0, dv = dvert; i < maxVerts; i++, dv++) {
			const bool found = defvert_find_weight(dv, defgrp_index) != 0.0f;
			if (found_test != found) {
				continue;
			}

			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
	}

	/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
	edgeHash = BLI_ghash_int_new_ex("mask ed2 gh", (unsigned int)maxEdges);
	polyHash = BLI_ghash_int_new_ex("mask fa2 gh", (unsigned int)maxPolys);

	mvert_src = dm->getVertArray(dm);
	medge_src = dm->getEdgeArray(dm);
	mpoly_src = dm->getPolyArray(dm);
	mloop_src = dm->getLoopArray(dm);

	/* overalloc, assume all polys are seen */
	loop_mapping = MEM_malloc_arrayN((size_t)maxPolys, sizeof(int), "mask loopmap");

	/* loop over edges and faces, and do the same thing to
	 * ensure that they only reference existing verts
	 */
	for (i = 0; i < maxEdges; i++) {
		const MEdge *me = &medge_src[i];

		/* only add if both verts will be in new mesh */
		if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) &&
		    BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2)))
		{
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
			numEdges++;
		}
	}
	for (i = 0; i < maxPolys; i++) {
		const MPoly *mp_src = &mpoly_src[i];
		const MLoop *ml_src = &mloop_src[mp_src->loopstart];
		bool ok = true;
		int j;

		for (j = 0; j < mp_src->totloop; j++, ml_src++) {
			if (!BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(ml_src->v))) {
				ok = false;
				break;
			}
		}

		/* all verts must be available */
		if (ok) {
			BLI_ghash_insert(polyHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numPolys));
			loop_mapping[numPolys] = numLoops;
			numPolys++;
			numLoops += mp_src->totloop;
		}
	}


	/* now we know the number of verts, edges and faces,
	 * we can create the new (reduced) mesh
	 */
	result = CDDM_from_template(dm, numVerts, numEdges, 0, numLoops, numPolys);

	mpoly_dst = CDDM_get_polys(result);
	mloop_dst = CDDM_get_loops(result);
	medge_dst = CDDM_get_edges(result);
	mvert_dst = CDDM_get_verts(result);

	/* using ghash-iterators, map data into new mesh */
	/* vertices */
	GHASH_ITER (gh_iter, vertHash) {
		const MVert *v_src;
		MVert *v_dst;
		const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
		const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));

		v_src = &mvert_src[i_src];
		v_dst = &mvert_dst[i_dst];

		*v_dst = *v_src;
		DM_copy_vert_data(dm, result, i_src, i_dst, 1);
	}

	/* edges */
	GHASH_ITER (gh_iter, edgeHash) {
		const MEdge *e_src;
		MEdge *e_dst;
		const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
		const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));

		e_src = &medge_src[i_src];
		e_dst = &medge_dst[i_dst];

		DM_copy_edge_data(dm, result, i_src, i_dst, 1);
		*e_dst = *e_src;
		e_dst->v1 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v1)));
		e_dst->v2 = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(e_src->v2)));
	}

	/* faces */
	GHASH_ITER (gh_iter, polyHash) {
		const int i_src = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
		const int i_dst = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));
		const MPoly *mp_src = &mpoly_src[i_src];
		MPoly *mp_dst = &mpoly_dst[i_dst];
		const int i_ml_src = mp_src->loopstart;
		const int i_ml_dst = loop_mapping[i_dst];
		const MLoop *ml_src = &mloop_src[i_ml_src];
		MLoop *ml_dst = &mloop_dst[i_ml_dst];

		DM_copy_poly_data(dm, result, i_src, i_dst, 1);
		DM_copy_loop_data(dm, result, i_ml_src, i_ml_dst, mp_src->totloop);

		*mp_dst = *mp_src;
		mp_dst->loopstart = i_ml_dst;
		for (i = 0; i < mp_src->totloop; i++) {
			ml_dst[i].v = GET_UINT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_UINT_IN_POINTER(ml_src[i].v)));
			ml_dst[i].e = GET_UINT_FROM_POINTER(BLI_ghash_lookup(edgeHash, SET_UINT_IN_POINTER(ml_src[i].e)));
		}
	}

	MEM_freeN(loop_mapping);

	/* why is this needed? - campbell */
	/* recalculate normals */
	result->dirty |= DM_DIRTY_NORMALS;

	/* free hashes */
	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	BLI_ghash_free(polyHash, NULL, NULL);

	/* return the new mesh */
	return result;
}
Ejemplo n.º 23
0
static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
                                  DerivedMesh *derivedData,
                                  ModifierApplyFlag UNUSED(flag))
{
	DerivedMesh *dm = derivedData;
	DerivedMesh *result;
	BuildModifierData *bmd = (BuildModifierData *) md;
	int i, j, k;
	int numFaces_dst, numEdges_dst, numLoops_dst = 0;
	int *vertMap, *edgeMap, *faceMap;
	float frac;
	MPoly *mpoly_dst;
	MLoop *ml_dst, *ml_src /*, *mloop_dst */;
	GHashIterator gh_iter;
	/* maps vert indices in old mesh to indices in new mesh */
	GHash *vertHash = BLI_ghash_int_new("build ve apply gh");
	/* maps edge indices in new mesh to indices in old mesh */
	GHash *edgeHash = BLI_ghash_int_new("build ed apply gh");
	GHash *edgeHash2 = BLI_ghash_int_new("build ed apply gh");

	const int numVert_src = dm->getNumVerts(dm);
	const int numEdge_src = dm->getNumEdges(dm);
	const int numPoly_src = dm->getNumPolys(dm);
	MPoly *mpoly_src = dm->getPolyArray(dm);
	MLoop *mloop_src = dm->getLoopArray(dm);
	MEdge *medge_src = dm->getEdgeArray(dm);
	MVert *mvert_src = dm->getVertArray(dm);


	vertMap = MEM_malloc_arrayN(numVert_src, sizeof(*vertMap), "build modifier vertMap");
	edgeMap = MEM_malloc_arrayN(numEdge_src, sizeof(*edgeMap), "build modifier edgeMap");
	faceMap = MEM_malloc_arrayN(numPoly_src, sizeof(*faceMap), "build modifier faceMap");

	range_vn_i(vertMap, numVert_src, 0);
	range_vn_i(edgeMap, numEdge_src, 0);
	range_vn_i(faceMap, numPoly_src, 0);

	frac = (BKE_scene_frame_get(md->scene) - bmd->start) / bmd->length;
	CLAMP(frac, 0.0f, 1.0f);
	
	if (bmd->flag & MOD_BUILD_FLAG_REVERSE) {
		frac = 1.0f - frac;
	}
	
	numFaces_dst = numPoly_src * frac;
	numEdges_dst = numEdge_src * frac;

	/* if there's at least one face, build based on faces */
	if (numFaces_dst) {
		MPoly *mpoly, *mp;
		MLoop *ml, *mloop;
		MEdge *medge;
		uintptr_t hash_num, hash_num_alt;
		
		if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
			BLI_array_randomize(faceMap, sizeof(*faceMap),
			                    numPoly_src, bmd->seed);
		}

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		mpoly = mpoly_src;
		mloop = mloop_src;
		hash_num = 0;
		for (i = 0; i < numFaces_dst; i++) {
			mp = mpoly + faceMap[i];
			ml = mloop + mp->loopstart;

			for (j = 0; j < mp->totloop; j++, ml++) {
				void **val_p;
				if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(ml->v), &val_p)) {
					*val_p = (void *)hash_num;
					hash_num++;
				}
			}

			numLoops_dst += mp->totloop;
		}
		BLI_assert(hash_num == BLI_ghash_len(vertHash));

		/* get the set of edges that will be in the new mesh (i.e. all edges
		 * that have both verts in the new mesh)
		 */
		medge = medge_src;
		hash_num = 0;
		hash_num_alt = 0;
		for (i = 0; i < numEdge_src; i++, hash_num_alt++) {
			MEdge *me = medge + i;

			if (BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v1)) &&
			    BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me->v2)))
			{
				BLI_ghash_insert(edgeHash, (void *)hash_num, (void *)hash_num_alt);
				BLI_ghash_insert(edgeHash2, (void *)hash_num_alt, (void *)hash_num);
				hash_num++;
			}
		}
	}
	else if (numEdges_dst) {
		MEdge *medge, *me;
		uintptr_t hash_num;

		if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE)
			BLI_array_randomize(edgeMap, sizeof(*edgeMap),
			                    numEdge_src, bmd->seed);

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		medge = medge_src;
		hash_num = 0;
		BLI_assert(hash_num == BLI_ghash_len(vertHash));
		for (i = 0; i < numEdges_dst; i++) {
			void **val_p;
			me = medge + edgeMap[i];

			if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(me->v1), &val_p)) {
				*val_p = (void *)hash_num;
				hash_num++;
			}
			if (!BLI_ghash_ensure_p(vertHash, SET_INT_IN_POINTER(me->v2), &val_p)) {
				*val_p = (void *)hash_num;
				hash_num++;
			}
		}
		BLI_assert(hash_num == BLI_ghash_len(vertHash));

		/* get the set of edges that will be in the new mesh */
		for (i = 0; i < numEdges_dst; i++) {
			j = BLI_ghash_len(edgeHash);
			
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(j),
			                 SET_INT_IN_POINTER(edgeMap[i]));
			BLI_ghash_insert(edgeHash2,  SET_INT_IN_POINTER(edgeMap[i]),
			                 SET_INT_IN_POINTER(j));
		}
	}
	else {
		int numVerts = numVert_src * frac;

		if (bmd->flag & MOD_BUILD_FLAG_RANDOMIZE) {
			BLI_array_randomize(vertMap, sizeof(*vertMap),
			                    numVert_src, bmd->seed);
		}

		/* get the set of all vert indices that will be in the final mesh,
		 * mapped to the new indices
		 */
		for (i = 0; i < numVerts; i++) {
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(vertMap[i]), SET_INT_IN_POINTER(i));
		}
	}

	/* now we know the number of verts, edges and faces, we can create
	 * the mesh
	 */
	result = CDDM_from_template(dm, BLI_ghash_len(vertHash),
	                            BLI_ghash_len(edgeHash), 0, numLoops_dst, numFaces_dst);

	/* copy the vertices across */
	GHASH_ITER (gh_iter, vertHash) {
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(&gh_iter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(&gh_iter));

		source = mvert_src[oldIndex];
		dest = CDDM_get_vert(result, newIndex);

		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
Ejemplo n.º 24
0
static void draw_sim_debug_elements(SimDebugData *debug_data, float imat[4][4])
{
	GHashIterator iter;
	
	/**** dots ****/
	
	glPointSize(3.0f);
	glBegin(GL_POINTS);
	for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
		if (elem->type != SIM_DEBUG_ELEM_DOT)
			continue;
		
		glColor3f(elem->color[0], elem->color[1], elem->color[2]);
		glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
	}
	glEnd();
	
	/**** circles ****/
	
	{
		float circle[16][2] = {
		    {0.000000, 1.000000}, {0.382683, 0.923880}, {0.707107, 0.707107}, {0.923880, 0.382683},
		    {1.000000, -0.000000}, {0.923880, -0.382683}, {0.707107, -0.707107}, {0.382683, -0.923880},
		    {-0.000000, -1.000000}, {-0.382683, -0.923880}, {-0.707107, -0.707107}, {-0.923879, -0.382684},
		    {-1.000000, 0.000000}, {-0.923879, 0.382684}, {-0.707107, 0.707107}, {-0.382683, 0.923880} };
		for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
			SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
			float radius = elem->v2[0];
			float co[3];
			int i;
			
			if (elem->type != SIM_DEBUG_ELEM_CIRCLE)
				continue;
			
			glColor3f(elem->color[0], elem->color[1], elem->color[2]);
			glBegin(GL_LINE_LOOP);
			for (i = 0; i < 16; ++i) {
				co[0] = radius * circle[i][0];
				co[1] = radius * circle[i][1];
				co[2] = 0.0f;
				mul_mat3_m4_v3(imat, co);
				add_v3_v3(co, elem->v1);
				
				glVertex3f(co[0], co[1], co[2]);
			}
			glEnd();
		}
	}
	
	/**** lines ****/
	
	glBegin(GL_LINES);
	for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
		if (elem->type != SIM_DEBUG_ELEM_LINE)
			continue;
		
		glColor3f(elem->color[0], elem->color[1], elem->color[2]);
		glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
		glVertex3f(elem->v2[0], elem->v2[1], elem->v2[2]);
	}
	glEnd();
	
	/**** vectors ****/
	
	glPointSize(2.0f);
	glBegin(GL_POINTS);
	for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
		if (elem->type != SIM_DEBUG_ELEM_VECTOR)
			continue;
		
		glColor3f(elem->color[0], elem->color[1], elem->color[2]);
		glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
	}
	glEnd();
	
	glBegin(GL_LINES);
	for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
		float t[3];
		if (elem->type != SIM_DEBUG_ELEM_VECTOR)
			continue;
		
		glColor3f(elem->color[0], elem->color[1], elem->color[2]);
		glVertex3f(elem->v1[0], elem->v1[1], elem->v1[2]);
		add_v3_v3v3(t, elem->v1, elem->v2);
		glVertex3f(t[0], t[1], t[2]);
	}
	glEnd();
	
	/**** strings ****/
	
	for (BLI_ghashIterator_init(&iter, debug_data->gh); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
		SimDebugElement *elem = BLI_ghashIterator_getValue(&iter);
		if (elem->type != SIM_DEBUG_ELEM_STRING)
			continue;
		
		unsigned char col[4];
		rgb_float_to_uchar(col, elem->color);
		col[3] = 255;
		view3d_cached_text_draw_add(elem->v1, elem->str, strlen(elem->str),
		                            0, V3D_CACHE_TEXT_GLOBALSPACE, col);
	}
}
Ejemplo n.º 25
0
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
						DerivedMesh *derivedData,
						int UNUSED(useRenderParams),
						int UNUSED(isFinalCalc))
{
	MaskModifierData *mmd= (MaskModifierData *)md;
	DerivedMesh *dm= derivedData, *result= NULL;
	GHash *vertHash=NULL, *edgeHash, *faceHash;
	GHashIterator *hashIter;
	MDeformVert *dvert= NULL, *dv;
	int numFaces=0, numEdges=0, numVerts=0;
	int maxVerts, maxEdges, maxFaces;
	int i;
	
	/* Overview of Method:
	 *	1. Get the vertices that are in the vertexgroup of interest 
	 *	2. Filter out unwanted geometry (i.e. not in vertexgroup), by populating mappings with new vs old indices
	 *	3. Make a new mesh containing only the mapping data
	 */
	
	/* get original number of verts, edges, and faces */
	maxVerts= dm->getNumVerts(dm);
	maxEdges= dm->getNumEdges(dm);
	maxFaces= dm->getNumFaces(dm);
	
	/* check if we can just return the original mesh 
	 *	- must have verts and therefore verts assigned to vgroups to do anything useful
	 */
	if ( !(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) ||
		 (maxVerts == 0) || (ob->defbase.first == NULL) )
	{
		return derivedData;
	}
	
	/* if mode is to use selected armature bones, aggregate the bone groups */
	if (mmd->mode == MOD_MASK_MODE_ARM) /* --- using selected bones --- */
	{
		GHash *vgroupHash;
		Object *oba= mmd->ob_arm;
		bPoseChannel *pchan;
		bDeformGroup *def;
		char *bone_select_array;
		int bone_select_tot= 0;
		
		/* check that there is armature object with bones to use, otherwise return original mesh */
		if (ELEM3(NULL, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
			return derivedData;

		bone_select_array= MEM_mallocN(BLI_countlist(&ob->defbase) * sizeof(char), "mask array");

		for (i = 0, def = ob->defbase.first; def; def = def->next, i++)
		{
			if (((pchan= get_pose_channel(oba->pose, def->name)) && pchan->bone && (pchan->bone->flag & BONE_SELECTED)))
			{
				bone_select_array[i]= TRUE;
				bone_select_tot++;
			}
			else {
				bone_select_array[i]= FALSE;
			}
		}

		/* hashes for finding mapping of:
		 * 	- vgroups to indices -> vgroupHash  (string, int)
		 *	- bones to vgroup indices -> boneHash (index of vgroup, dummy)
		 */
		vgroupHash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "mask vgroup gh");
		
		/* build mapping of names of vertex groups to indices */
		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) 
			BLI_ghash_insert(vgroupHash, def->name, SET_INT_IN_POINTER(i));
		
		/* if no bones selected, free hashes and return original mesh */
		if (bone_select_tot == 0)
		{
			BLI_ghash_free(vgroupHash, NULL, NULL);
			MEM_freeN(bone_select_array);
			
			return derivedData;
		}
		
		/* repeat the previous check, but for dverts */
		dvert= dm->getVertDataArray(dm, CD_MDEFORMVERT);
		if (dvert == NULL)
		{
			BLI_ghash_free(vgroupHash, NULL, NULL);
			MEM_freeN(bone_select_array);
			
			return derivedData;
		}
		
		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert gh");
		
		/* add vertices which exist in vertexgroups into vertHash for filtering */
		for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
		{
			MDeformWeight *dw= dv->dw;
			int j;

			for (j= dv->totweight; j > 0; j--, dw++)
			{
				if (bone_select_array[dw->def_nr])
				{
					if(dw->weight != 0.0f) {
						break;
					}
				}
			}
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (dw) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!dw) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
		
		/* free temp hashes */
		BLI_ghash_free(vgroupHash, NULL, NULL);
		MEM_freeN(bone_select_array);
	}
	else		/* --- Using Nominated VertexGroup only --- */ 
	{
		int defgrp_index = defgroup_name_index(ob, mmd->vgroup);
		
		/* get dverts */
		if (defgrp_index >= 0)
			dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT);
			
		/* if no vgroup (i.e. dverts) found, return the initial mesh */
		if ((defgrp_index < 0) || (dvert == NULL))
			return dm;
			
		/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
		vertHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask vert2 bh");
		
		/* add vertices which exist in vertexgroup into ghash for filtering */
		for (i= 0, dv= dvert; i < maxVerts; i++, dv++)
		{
			const int weight_set= defvert_find_weight(dv, defgrp_index) != 0.0f;
			
			/* check if include vert in vertHash */
			if (mmd->flag & MOD_MASK_INV) {
				/* if this vert is in the vgroup, don't include it in vertHash */
				if (weight_set) continue;
			}
			else {
				/* if this vert isn't in the vgroup, don't include it in vertHash */
				if (!weight_set) continue;
			}
			
			/* add to ghash for verts (numVerts acts as counter for mapping) */
			BLI_ghash_insert(vertHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numVerts));
			numVerts++;
		}
	}
	
	/* hashes for quickly providing a mapping from old to new - use key=oldindex, value=newindex */
	edgeHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask ed2 gh");
	faceHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "mask fa2 gh");
	
	/* loop over edges and faces, and do the same thing to 
	 * ensure that they only reference existing verts 
	 */
	for (i = 0; i < maxEdges; i++) 
	{
		MEdge me;
		dm->getEdge(dm, i, &me);
		
		/* only add if both verts will be in new mesh */
		if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v1)) &&
			 BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(me.v2)) )
		{
			BLI_ghash_insert(edgeHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numEdges));
			numEdges++;
		}
	}
	for (i = 0; i < maxFaces; i++) 
	{
		MFace mf;
		dm->getFace(dm, i, &mf);
		
		/* all verts must be available */
		if ( BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v1)) &&
			 BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v2)) &&
			 BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v3)) &&
			(mf.v4==0 || BLI_ghash_haskey(vertHash, SET_INT_IN_POINTER(mf.v4))) )
		{
			BLI_ghash_insert(faceHash, SET_INT_IN_POINTER(i), SET_INT_IN_POINTER(numFaces));
			numFaces++;
		}
	}
	
	
	/* now we know the number of verts, edges and faces, 
	 * we can create the new (reduced) mesh
	 */
	result = CDDM_from_template(dm, numVerts, numEdges, numFaces);
	
	
	/* using ghash-iterators, map data into new mesh */
		/* vertices */
	for ( hashIter = BLI_ghashIterator_new(vertHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		MVert source;
		MVert *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getVert(dm, oldIndex, &source);
		dest = CDDM_get_vert(result, newIndex);
		
		DM_copy_vert_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
		
		/* edges */
	for ( hashIter = BLI_ghashIterator_new(edgeHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		MEdge source;
		MEdge *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		
		dm->getEdge(dm, oldIndex, &source);
		dest = CDDM_get_edge(result, newIndex);
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		
		DM_copy_edge_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
	}
	BLI_ghashIterator_free(hashIter);
	
		/* faces */
	for ( hashIter = BLI_ghashIterator_new(faceHash);
		  !BLI_ghashIterator_isDone(hashIter);
		  BLI_ghashIterator_step(hashIter) ) 
	{
		MFace source;
		MFace *dest;
		int oldIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getKey(hashIter));
		int newIndex = GET_INT_FROM_POINTER(BLI_ghashIterator_getValue(hashIter));
		int orig_v4;
		
		dm->getFace(dm, oldIndex, &source);
		dest = CDDM_get_face(result, newIndex);
		
		orig_v4 = source.v4;
		
		source.v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v1)));
		source.v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v2)));
		source.v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v3)));
		if (source.v4)
		   source.v4 = GET_INT_FROM_POINTER(BLI_ghash_lookup(vertHash, SET_INT_IN_POINTER(source.v4)));
		
		DM_copy_face_data(dm, result, oldIndex, newIndex, 1);
		*dest = source;
		
		test_index_face(dest, &result->faceData, newIndex, (orig_v4 ? 4 : 3));
	}
	BLI_ghashIterator_free(hashIter);
	
	/* recalculate normals */
	CDDM_calc_normals(result);
	
	/* free hashes */
	BLI_ghash_free(vertHash, NULL, NULL);
	BLI_ghash_free(edgeHash, NULL, NULL);
	BLI_ghash_free(faceHash, NULL, NULL);
	
	/* return the new mesh */
	return result;
}