Example #1
0
BMEditMesh *BKE_editmesh_copy(BMEditMesh *em)
{
	BMEditMesh *em_copy = MEM_callocN(sizeof(BMEditMesh), __func__);
	*em_copy = *em;

	em_copy->derivedCage = em_copy->derivedFinal = NULL;

	em_copy->derivedVertColor = NULL;
	em_copy->derivedVertColorLen = 0;
	em_copy->derivedFaceColor = NULL;
	em_copy->derivedFaceColorLen = 0;

	em_copy->bm = BM_mesh_copy(em->bm);

	/* The tessellation is NOT calculated on the copy here,
	 * because currently all the callers of this function use
	 * it to make a backup copy of the BMEditMesh to restore
	 * it in the case of errors in an operation. For perf
	 * reasons, in that case it makes more sense to do the
	 * tessellation only when/if that copy ends up getting
	 * used.*/
	em_copy->looptris = NULL;

	em_copy->presel_verts = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "PSV");
	em_copy->presel_edges = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "PSE");
	em_copy->presel_faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "PSF");

	em_copy->prop3d_faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "PPF");
	em_copy->prop2d_faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "PPF");

	return em_copy;
}
Example #2
0
/**
 * \brief Reset Walker
 *
 * Frees all states from the worklist, resetting the walker
 * for reuse in a new walk.
 */
void BMW_reset(BMWalker *walker)
{
	while (BMW_current_state(walker)) {
		BMW_state_remove(walker);
	}
	walker->depth = 0;
	BLI_ghash_free(walker->visithash, NULL, NULL);
	BLI_ghash_free(walker->secvisithash, NULL, NULL);
	walker->visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh walkers 1");
	walker->secvisithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh walkers sec 1");
}
Example #3
0
FModifierStackStorage *evaluate_fmodifiers_storage_new(ListBase *modifiers)
{
	FModifier *fcm;

	/* Sanity checks. */
	if (ELEM(NULL, modifiers, modifiers->last)) {
		return NULL;
	}

	for (fcm = modifiers->last; fcm; fcm = fcm->prev) {
		FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);

		if (fmi == NULL) {
			continue;
		}

		if (fmi->requires & FMI_REQUIRES_STORAGE) {
			return (FModifierStackStorage *) BLI_ghash_new(BLI_ghashutil_ptrhash,
			                                               BLI_ghashutil_ptrcmp,
			                                               "fmodifier stack temp storage");
		}
	}

	return NULL;
}
Example #4
0
/* presumed to be called when no threads are running */
void IMB_tile_cache_params(int totthread, int maxmem)
{
	int a;

	/* always one cache for non-threaded access */
	totthread++;

	/* lazy initialize cache */
	if(GLOBAL_CACHE.totthread == totthread && GLOBAL_CACHE.maxmem == maxmem)
		return;

	imb_tile_cache_exit();

	memset(&GLOBAL_CACHE, 0, sizeof(ImGlobalTileCache));

	GLOBAL_CACHE.tilehash= BLI_ghash_new(imb_global_tile_hash, imb_global_tile_cmp, "tile_cache_params gh");

	GLOBAL_CACHE.memarena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "ImTileCache arena");
	BLI_memarena_use_calloc(GLOBAL_CACHE.memarena);

	GLOBAL_CACHE.maxmem= maxmem*1024*1024;

	GLOBAL_CACHE.totthread= totthread;
	for(a=0; a<totthread; a++)
		imb_thread_cache_init(&GLOBAL_CACHE.thread_cache[a]);

	BLI_mutex_init(&GLOBAL_CACHE.mutex);
}
Example #5
0
void BKE_icons_init(int first_dyn_id)
{
	gNextIconId = first_dyn_id;
	gFirstIconId = first_dyn_id;

	if (!gIcons)
		gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "icons_init gh");
}
Example #6
0
void seq_stripelem_cache_init(void)
{
	hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
	limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );

	entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0);
	keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0);
}
Example #7
0
/**
 * \brief Init Walker
 *
 * Allocates and returns a new mesh walker of
 * a given type. The elements visited are filtered
 * by the bitmask 'searchmask'.
 */
void BMW_init(BMWalker *walker, BMesh *bm, int type,
              short mask_vert, short mask_edge, short mask_face,
              BMWFlag flag,
              int layer)
{
	memset(walker, 0, sizeof(BMWalker));

	walker->layer = layer;
	walker->flag = flag;
	walker->bm = bm;

	walker->mask_vert = mask_vert;
	walker->mask_edge = mask_edge;
	walker->mask_face = mask_face;

	walker->visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh walkers 1");
	walker->secvisithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh walkers sec 1");

	if (UNLIKELY(type >= BMW_MAXWALKERS || type < 0)) {
		fprintf(stderr,
		        "Invalid walker type in BMW_init; type: %d, "
		        "searchmask: (v:%d, e:%d, f:%d), flag: %d, layer: %d\n",
		        type, mask_vert, mask_edge, mask_face, flag, layer);
		BMESH_ASSERT(0);
	}
	
	if (type != BMW_CUSTOM) {
		walker->begin = bm_walker_types[type]->begin;
		walker->yield = bm_walker_types[type]->yield;
		walker->step = bm_walker_types[type]->step;
		walker->structsize = bm_walker_types[type]->structsize;
		walker->order = bm_walker_types[type]->order;
		walker->valid_mask = bm_walker_types[type]->valid_mask;

		/* safety checks */
		/* if this raises an error either the caller is wrong or
		 * 'bm_walker_types' needs updating */
		BLI_assert(mask_vert == 0 || (walker->valid_mask & BM_VERT));
		BLI_assert(mask_edge == 0 || (walker->valid_mask & BM_EDGE));
		BLI_assert(mask_face == 0 || (walker->valid_mask & BM_FACE));
	}
	
	walker->worklist = BLI_mempool_create(walker->structsize, 100, 100, BLI_MEMPOOL_SYSMALLOC);
	walker->states.first = walker->states.last = NULL;
}
Example #8
0
void make_pose_channels_hash(bPose *pose) 
{
	if(!pose->chanhash) {
		bPoseChannel *pchan;

		pose->chanhash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "make_pose_chan gh");
		for(pchan=pose->chanbase.first; pchan; pchan=pchan->next)
			BLI_ghash_insert(pose->chanhash, pchan->name, pchan);
	}
}
Example #9
0
/** Generate the mappings between used IDs and their users, and vice-versa. */
void BKE_main_relations_create(Main *bmain)
{
  if (bmain->relations != NULL) {
    BKE_main_relations_free(bmain);
  }

  bmain->relations = MEM_mallocN(sizeof(*bmain->relations), __func__);
  bmain->relations->id_used_to_user = BLI_ghash_new(
      BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
  bmain->relations->id_user_to_used = BLI_ghash_new(
      BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
  bmain->relations->entry_pool = BLI_mempool_create(
      sizeof(MainIDRelationsEntry), 128, 128, BLI_MEMPOOL_NOP);

  ID *id;
  FOREACH_MAIN_ID_BEGIN (bmain, id) {
    BKE_library_foreach_ID_link(
        NULL, id, main_relations_create_idlink_cb, bmain->relations, IDWALK_READONLY);
  }
BME_TransData_Head *BME_init_transdata(int bufsize) {
	BME_TransData_Head *td;

	td = MEM_callocN(sizeof(BME_TransData_Head), "BMesh transdata header");
	td->gh = BLI_ghash_new(BLI_ghashutil_ptrhash,BLI_ghashutil_ptrcmp, "BME_init_transdata gh");
	td->ma = BLI_memarena_new(bufsize, "BME_TransData arena");
	BLI_memarena_use_calloc(td->ma);

	return td;
}
Example #11
0
bArgs *BLI_argsInit(int argc, const char **argv)
{
	bArgs *ba = MEM_callocN(sizeof(bArgs), "bArgs");
	ba->passes = MEM_callocN(sizeof(int) * argc, "bArgs passes");
	ba->items = BLI_ghash_new(keyhash, keycmp, "bArgs passes gh");
	ba->docs.first = ba->docs.last = NULL;
	ba->argc = argc;
	ba->argv = argv;

	return ba;
}
Example #12
0
static void ui_editsource_active_but_set(uiBut *but)
{
	BLI_assert(ui_editsource_info == NULL);

	ui_editsource_info= MEM_callocN(sizeof(uiEditSourceStore), __func__);
	memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut));

	ui_editsource_info->hash = BLI_ghash_new(BLI_ghashutil_ptrhash,
	                                         BLI_ghashutil_ptrcmp,
	                                         __func__);
}
Example #13
0
GPUFunction *GPU_lookup_function(const char *name)
{
	if(!FUNCTION_HASH) {
		FUNCTION_HASH = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "GPU_lookup_function gh");
		gpu_parse_functions_string(FUNCTION_HASH, datatoc_gpu_shader_material_glsl);
		/*FUNCTION_PROTOTYPES = gpu_generate_function_prototyps(FUNCTION_HASH);
		FUNCTION_LIB = GPU_shader_create_lib(datatoc_gpu_shader_material_glsl);*/
	}

	return (GPUFunction*)BLI_ghash_lookup(FUNCTION_HASH, (void *)name);
}
Example #14
0
void BKE_sim_debug_data_set_enabled(bool enable)
{
	if (enable) {
		if (!_sim_debug_data) {
			_sim_debug_data = MEM_callocN(sizeof(SimDebugData), "sim debug data");
			_sim_debug_data->gh = BLI_ghash_new(debug_element_hash, debug_element_compare, "sim debug element hash");
		}
	}
	else {
		BKE_sim_debug_data_free();
	}
}
Example #15
0
File: sss.c Project: jinjoh/NOOR
void make_sss_tree(Render *re)
{
	Material *mat;
	
	re->sss_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);

	re->i.infostr= "SSS preprocessing";
	re->stats_draw(re->sdh, &re->i);
	
	for(mat= G.main->mat.first; mat; mat= mat->id.next)
		if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS))
			sss_create_tree_mat(re, mat);
}
Example #16
0
static void imb_thread_cache_init(ImThreadTileCache *cache)
{
	ImThreadTile *ttile;
	int a;

	memset(cache, 0, sizeof(ImThreadTileCache));

	cache->tilehash= BLI_ghash_new(imb_thread_tile_hash, imb_thread_tile_cmp, "imb_thread_cache_init gh");

	/* pre-allocate all thread local tiles in unused list */
	for(a=0; a<IB_THREAD_CACHE_SIZE; a++) {
		ttile= BLI_memarena_alloc(GLOBAL_CACHE.memarena, sizeof(ImThreadTile));
		BLI_addtail(&cache->unused, ttile);
	}
}
Example #17
0
void seq_stripelem_cache_cleanup(void)
{
	if (!entrypool) {
		seq_stripelem_cache_init();
	}

	/* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
	   ibufs_in, ibufs_rem); */

	BLI_ghash_free(hash, HashKeyFree, HashValFree);
	hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");

	/* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
	   ibufs_in, ibufs_rem); */

}
Example #18
0
static void view_layer_bases_hash_create(ViewLayer *view_layer)
{
  static ThreadMutex hash_lock = BLI_MUTEX_INITIALIZER;

  if (view_layer->object_bases_hash == NULL) {
    BLI_mutex_lock(&hash_lock);

    if (view_layer->object_bases_hash == NULL) {
      view_layer->object_bases_hash = BLI_ghash_new(
          BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);

      for (Base *base = view_layer->object_bases.first; base; base = base->next) {
        if (base->object) {
          BLI_ghash_insert(view_layer->object_bases_hash, base->object, base);
        }
      }
    }

    BLI_mutex_unlock(&hash_lock);
  }
}
Example #19
0
MovieCache *IMB_moviecache_create(const char *name, int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp)
{
	MovieCache *cache;

	PRINT("%s: cache '%s' create\n", __func__, name);

	cache = MEM_callocN(sizeof(MovieCache), "MovieCache");

	BLI_strncpy(cache->name, name, sizeof(cache->name));

	cache->keys_pool = BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
	cache->items_pool = BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
	cache->userkeys_pool = BLI_mempool_create(keysize, 64, 64, 0);
	cache->hash = BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");

	cache->keysize = keysize;
	cache->hashfp = hashfp;
	cache->cmpfp = cmpfp;
	cache->proxy = -1;

	return cache;
}
Example #20
0
void make_sss_tree(Render *re)
{
	Material *mat;
	
	re->sss_hash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_sss_tree gh");

	re->i.infostr= "SSS preprocessing";
	re->stats_draw(re->sdh, &re->i);
	
	for(mat= re->main->mat.first; mat; mat= mat->id.next)
		if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS))
			sss_create_tree_mat(re, mat);
	
	/* XXX preview exception */
	/* localizing preview render data is not fun for node trees :( */
	if(re->main!=G.main) {
		for(mat= G.main->mat.first; mat; mat= mat->id.next)
			if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS))
				sss_create_tree_mat(re, mat);
	}
	
}
Example #21
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;
}
Example #22
0
GHash *BLI_ghash_pair_new(const char *info)
{
	return BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info);
}
Example #23
0
GHash *BLI_ghash_int_new(const char *info)
{
	return BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, info);
}
Example #24
0
static void codegen_set_unique_ids(ListBase *nodes)
{
	GHash *bindhash, *definehash;
	GPUNode *node;
	GPUInput *input;
	GPUOutput *output;
	int id = 1, texid = 0;

	bindhash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "codegen_set_unique_ids1 gh");
	definehash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "codegen_set_unique_ids2 gh");

	for (node=nodes->first; node; node=node->next) {
		for (input=node->inputs.first; input; input=input->next) {
			/* set id for unique names of uniform variables */
			input->id = id++;
			input->bindtex = 0;
			input->definetex = 0;

			/* set texid used for settings texture slot with multitexture */
			if (codegen_input_has_texture(input) &&
				((input->source == GPU_SOURCE_TEX) || (input->source == GPU_SOURCE_TEX_PIXEL))) {
				if (input->link) {
					/* input is texture from buffer, assign only one texid per
					   buffer to avoid sampling the same texture twice */
					if (!BLI_ghash_haskey(bindhash, input->link)) {
						input->texid = texid++;
						input->bindtex = 1;
						BLI_ghash_insert(bindhash, input->link, SET_INT_IN_POINTER(input->texid));
					}
					else
						input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->link));
				}
				else if(input->ima) {
					/* input is texture from image, assign only one texid per
					   buffer to avoid sampling the same texture twice */
					if (!BLI_ghash_haskey(bindhash, input->ima)) {
						input->texid = texid++;
						input->bindtex = 1;
						BLI_ghash_insert(bindhash, input->ima, SET_INT_IN_POINTER(input->texid));
					}
					else
						input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->ima));
				}
				else {
					if (!BLI_ghash_haskey(bindhash, input->tex)) {
						/* input is user created texture, check tex pointer */
						input->texid = texid++;
						input->bindtex = 1;
						BLI_ghash_insert(bindhash, input->tex, SET_INT_IN_POINTER(input->texid));
					}
					else
						input->texid = GET_INT_FROM_POINTER(BLI_ghash_lookup(bindhash, input->tex));
				}

				/* make sure this pixel is defined exactly once */
				if (input->source == GPU_SOURCE_TEX_PIXEL) {
					if(input->ima) {
						if (!BLI_ghash_haskey(definehash, input->ima)) {
							input->definetex = 1;
							BLI_ghash_insert(definehash, input->ima, SET_INT_IN_POINTER(input->texid));
						}
					}
					else {
						if (!BLI_ghash_haskey(definehash, input->link)) {
							input->definetex = 1;
							BLI_ghash_insert(definehash, input->link, SET_INT_IN_POINTER(input->texid));
						}
					}
				}
			}
		}

		for (output=node->outputs.first; output; output=output->next)
			/* set id for unique names of tmp variables storing output */
			output->id = id++;
	}

	BLI_ghash_free(bindhash, NULL, NULL);
	BLI_ghash_free(definehash, NULL, NULL);
}
/** 
 * Move here pose function for game engine so that we can mix with GE objects
 * Principle is as follow:
 * Use Blender structures so that BKE_pose_where_is can be used unchanged
 * Copy the constraint so that they can be enabled/disabled/added/removed at runtime
 * Don't copy the constraints for the pose used by the Action actuator, it does not need them.
 * Scan the constraint structures so that the KX equivalent of target objects are identified and 
 * stored in separate list.
 * When it is about to evaluate the pose, set the KX object position in the obmat of the corresponding
 * Blender objects and restore after the evaluation.
 */
static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
{
	bPose *out;
	bPoseChannel *pchan, *outpchan;
	GHash *ghash;
	
	/* the game engine copies the current armature pose and then swaps
	 * the object pose pointer. this makes it possible to change poses
	 * without affecting the original blender data. */

	if (!src) {
		*dst=NULL;
		return;
	}
	else if (*dst==src) {
		printf("game_copy_pose source and target are the same\n");
		*dst=NULL;
		return;
	}
	
	out= (bPose*)MEM_dupallocN(src);
	out->chanhash = NULL;
	out->agroups.first= out->agroups.last= NULL;
	out->ikdata = NULL;
	out->ikparam = MEM_dupallocN(src->ikparam);
	out->flag |= POSE_GAME_ENGINE;
	BLI_duplicatelist(&out->chanbase, &src->chanbase);

	/* remap pointers */
	ghash= BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "game_copy_pose gh");

	pchan= (bPoseChannel *)src->chanbase.first;
	outpchan= (bPoseChannel *)out->chanbase.first;
	for (; pchan; pchan=pchan->next, outpchan=outpchan->next)
		BLI_ghash_insert(ghash, pchan, outpchan);

	for (pchan = (bPoseChannel *)out->chanbase.first; pchan; pchan = pchan->next) {
		pchan->parent= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->parent);
		pchan->child= (bPoseChannel *)BLI_ghash_lookup(ghash, pchan->child);

		if (copy_constraint) {
			ListBase listb;
			// copy all constraint for backward compatibility
			// BKE_constraints_copy NULLs listb, no need to make extern for this operation.
			BKE_constraints_copy(&listb, &pchan->constraints, false);
			pchan->constraints= listb;
		}
		else {
			BLI_listbase_clear(&pchan->constraints);
		}

		if (pchan->custom) {
			id_us_plus(&pchan->custom->id);
		}

		// fails to link, props are not used in the BGE yet.
#if 0
		if (pchan->prop)
			pchan->prop= IDP_CopyProperty(pchan->prop);
#endif
		pchan->prop= NULL;
	}

	BLI_ghash_free(ghash, NULL, NULL);
	// set acceleration structure for channel lookup
	BKE_pose_channels_hash_make(out);
	*dst=out;
}
Example #26
0
File: wm.c Project: mik0001/Blender
/* called on initialize WM_init() */
void WM_menutype_init(void)
{
	menutypes_hash= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "menutypes_hash gh");
}
Example #27
0
static void _build_translations_cache(PyObject *py_messages, const char *locale)
{
	PyObject *uuid, *uuid_dict;
	Py_ssize_t pos = 0;
	char *language = NULL, *language_country = NULL, *language_variant = NULL;

	/* For each py dict, we'll search for full locale, then language+country, then language+variant,
	 * then only language keys... */
	BLT_lang_locale_explode(locale, &language, NULL, NULL, &language_country, &language_variant);

	/* Clear the cached ghash if needed, and create a new one. */
	_clear_translations_cache();
	_translations_cache = BLI_ghash_new(_ghashutil_keyhash, _ghashutil_keycmp, __func__);

	/* Iterate over all py dicts. */
	while (PyDict_Next(py_messages, &pos, &uuid, &uuid_dict)) {
		PyObject *lang_dict;

#if 0
		PyObject_Print(uuid_dict, stdout, 0);
		printf("\n");
#endif

		/* Try to get first complete locale, then language+country, then language+variant, then only language */
		lang_dict = PyDict_GetItemString(uuid_dict, locale);
		if (!lang_dict && language_country) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_country);
			locale = language_country;
		}
		if (!lang_dict && language_variant) {
			lang_dict = PyDict_GetItemString(uuid_dict, language_variant);
			locale = language_variant;
		}
		if (!lang_dict && language) {
			lang_dict = PyDict_GetItemString(uuid_dict, language);
			locale = language;
		}

		if (lang_dict) {
			PyObject *pykey, *trans;
			Py_ssize_t ppos = 0;

			if (!PyDict_Check(lang_dict)) {
				printf("WARNING! In translations' dict of \"");
				PyObject_Print(uuid, stdout, Py_PRINT_RAW);
				printf("\":\n");
				printf("    Each language key must have a dictionary as value, \"%s\" is not valid, skipping: ",
				       locale);
				PyObject_Print(lang_dict, stdout, Py_PRINT_RAW);
				printf("\n");
				continue;
			}

			/* Iterate over all translations of the found language dict, and populate our ghash cache. */
			while (PyDict_Next(lang_dict, &ppos, &pykey, &trans)) {
				const char *msgctxt = NULL, *msgid = NULL;
				bool invalid_key = false;

				if ((PyTuple_CheckExact(pykey) == false) || (PyTuple_GET_SIZE(pykey) != 2)) {
					invalid_key = true;
				}
				else {
					PyObject *tmp = PyTuple_GET_ITEM(pykey, 0);
					if (tmp == Py_None) {
						msgctxt = BLT_I18NCONTEXT_DEFAULT_BPYRNA;
					}
					else if (PyUnicode_Check(tmp)) {
						msgctxt = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}

					tmp = PyTuple_GET_ITEM(pykey, 1);
					if (PyUnicode_Check(tmp)) {
						msgid = _PyUnicode_AsString(tmp);
					}
					else {
						invalid_key = true;
					}
				}

				if (invalid_key) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\", %s language:\n", locale);
					printf("    Keys must be tuples of (msgctxt [string or None], msgid [string]), "
					       "this one is not valid, skipping: ");
					PyObject_Print(pykey, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}
				if (PyUnicode_Check(trans) == false) {
					printf("WARNING! In translations' dict of \"");
					PyObject_Print(uuid, stdout, Py_PRINT_RAW);
					printf("\":\n");
					printf("    Values must be strings, this one is not valid, skipping: ");
					PyObject_Print(trans, stdout, Py_PRINT_RAW);
					printf("\n");
					continue;
				}

				/* Do not overwrite existing keys! */
				if (BPY_app_translations_py_pgettext(msgctxt, msgid) == msgid) {
					GHashKey *key = _ghashutil_keyalloc(msgctxt, msgid);
					BLI_ghash_insert(_translations_cache, key, BLI_strdup(_PyUnicode_AsString(trans)));
				}
			}
		}
	}

	/* Clean up! */
	MEM_SAFE_FREE(language);
	MEM_SAFE_FREE(language_country);
	MEM_SAFE_FREE(language_variant);
}
Example #28
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, *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 --- */
		GHash *vgroupHash;
		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, mmd->ob_arm, mmd->ob_arm->pose, ob->defbase.first))
			return derivedData;

		bone_select_array= MEM_mallocN(defbase_tot * sizeof(char), "mask array");

		for (i = 0, def = ob->defbase.first; def; def = def->next, i++) {
			pchan = get_pose_channel(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;
			}
		}

		/* 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 (dw->def_nr < defbase_tot) {
					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");
	polyHash= BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "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;
}
Example #29
0
/* Iterate over the CSG Output Descriptors and create a new DerivedMesh
   from them */
static DerivedMesh *ConvertCSGDescriptorsToDerivedMesh(
	CSG_FaceIteratorDescriptor *face_it,
	CSG_VertexIteratorDescriptor *vertex_it,
	float parinv[][4],
	float mapmat[][4],
	Material **mat,
	int *totmat,
	DerivedMesh *dm1,
	Object *ob1,
	DerivedMesh *dm2,
	Object *ob2)
{
	DerivedMesh *result, *orig_dm;
	GHash *material_hash = NULL;
	Mesh *me1= (Mesh*)ob1->data;
	Mesh *me2= (Mesh*)ob2->data;
	int i;

	// create a new DerivedMesh
	result = CDDM_new(vertex_it->num_elements, 0, face_it->num_elements);
	CustomData_merge(&dm1->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
					  CD_DEFAULT, face_it->num_elements); 
	CustomData_merge(&dm2->faceData, &result->faceData, CD_MASK_DERIVEDMESH,
					  CD_DEFAULT, face_it->num_elements); 

	// step through the vertex iterators:
	for (i = 0; !vertex_it->Done(vertex_it->it); i++) {
		CSG_IVertex csgvert;
		MVert *mvert = CDDM_get_vert(result, i);

		// retrieve a csg vertex from the boolean module
		vertex_it->Fill(vertex_it->it, &csgvert);
		vertex_it->Step(vertex_it->it);

		// we have to map the vertex coordinates back in the coordinate frame
		// of the resulting object, since it was computed in world space
		mul_v3_m4v3(mvert->co, parinv, csgvert.position);
	}

	// a hash table to remap materials to indices
	if (mat) {
		material_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "CSG_mat gh");
		*totmat = 0;
	}

	// step through the face iterators
	for(i = 0; !face_it->Done(face_it->it); i++) {
		Mesh *orig_me;
		Object *orig_ob;
		Material *orig_mat;
		CSG_IFace csgface;
		MFace *mface;
		int orig_index, mat_nr;

		// retrieve a csg face from the boolean module
		face_it->Fill(face_it->it, &csgface);
		face_it->Step(face_it->it);

		// find the original mesh and data
		orig_ob = (csgface.orig_face < dm1->getNumFaces(dm1))? ob1: ob2;
		orig_dm = (csgface.orig_face < dm1->getNumFaces(dm1))? dm1: dm2;
		orig_me = (orig_ob == ob1)? me1: me2;
		orig_index = (orig_ob == ob1)? csgface.orig_face: csgface.orig_face - dm1->getNumFaces(dm1);

		// copy all face layers, including mface
		CustomData_copy_data(&orig_dm->faceData, &result->faceData, orig_index, i, 1);

		// set mface
		mface = CDDM_get_face(result, i);
		mface->v1 = csgface.vertex_index[0];
		mface->v2 = csgface.vertex_index[1];
		mface->v3 = csgface.vertex_index[2];
		mface->v4 = (csgface.vertex_number == 4)? csgface.vertex_index[3]: 0;

		// set material, based on lookup in hash table
		orig_mat= give_current_material(orig_ob, mface->mat_nr+1);

		if (mat && orig_mat) {
			if (!BLI_ghash_haskey(material_hash, orig_mat)) {
				mat[*totmat] = orig_mat;
				mat_nr = mface->mat_nr = (*totmat)++;
				BLI_ghash_insert(material_hash, orig_mat, SET_INT_IN_POINTER(mat_nr));
			}
			else
				mface->mat_nr = GET_INT_FROM_POINTER(BLI_ghash_lookup(material_hash, orig_mat));
		}
		else
			mface->mat_nr = 0;

		InterpCSGFace(result, orig_dm, i, orig_index, csgface.vertex_number,
					  (orig_me == me2)? mapmat: NULL);

		test_index_face(mface, &result->faceData, i, csgface.vertex_number);
	}

	if (material_hash)
		BLI_ghash_free(material_hash, NULL, NULL);

	CDDM_calc_edges(result);
	CDDM_calc_normals(result);

	return result;
}