Example #1
0
static int main_relations_create_idlink_cb(void *user_data,
                                           ID *id_self,
                                           ID **id_pointer,
                                           int cb_flag)
{
  MainIDRelations *rel = user_data;

  if (*id_pointer) {
    MainIDRelationsEntry *entry, **entry_p;

    entry = BLI_mempool_alloc(rel->entry_pool);
    if (BLI_ghash_ensure_p(rel->id_user_to_used, id_self, (void ***)&entry_p)) {
      entry->next = *entry_p;
    }
    else {
      entry->next = NULL;
    }
    entry->id_pointer = id_pointer;
    entry->usage_flag = cb_flag;
    *entry_p = entry;

    entry = BLI_mempool_alloc(rel->entry_pool);
    if (BLI_ghash_ensure_p(rel->id_used_to_user, *id_pointer, (void ***)&entry_p)) {
      entry->next = *entry_p;
    }
    else {
      entry->next = NULL;
    }
    entry->id_pointer = (ID **)id_self;
    entry->usage_flag = cb_flag;
    *entry_p = entry;
  }

  return IDWALK_RET_NOP;
}
Example #2
0
static bool ghash_insert_link(
        GHash *gh, void *key, void *val, bool use_test,
        MemArena *mem_arena)
{
	void           **ls_base_p;
	struct LinkBase *ls_base;
	LinkNode *ls;

	if (!BLI_ghash_ensure_p(gh, key, &ls_base_p)) {
		ls_base = *ls_base_p = BLI_memarena_alloc(mem_arena, sizeof(*ls_base));
		ls_base->list     = NULL;
		ls_base->list_len = 0;
	}
	else {
		ls_base = *ls_base_p;
		if (use_test && (BLI_linklist_index(ls_base->list, val) != -1)) {
			return false;
		}
	}

	ls = BLI_memarena_alloc(mem_arena, sizeof(*ls));
	ls->next = ls_base->list;
	ls->link = val;
	ls_base->list = ls;
	ls_base->list_len += 1;

	return true;
}
Example #3
0
void BKE_outliner_treehash_add_element(void *treehash, TreeStoreElem *elem)
{
	TseGroup *group;
	void **val_p;

	if (!BLI_ghash_ensure_p(treehash, elem, &val_p)) {
		*val_p = tse_group_create();
	}
	group = *val_p;
	tse_group_add(group, elem);
}
Example #4
0
void BKE_icon_set(int icon_id, struct Icon *icon)
{
	void **val_p;

	if (BLI_ghash_ensure_p(gIcons, SET_INT_IN_POINTER(icon_id), &val_p)) {
		printf("%s: Internal error, icon already set: %d\n", __func__, icon_id);
		return;
	}

	*val_p = icon;
}
Example #5
0
static short layer_collection_sync(ViewLayer *view_layer,
                                   const ListBase *lb_scene,
                                   ListBase *lb_layer,
                                   ListBase *new_object_bases,
                                   short parent_exclude,
                                   short parent_restrict,
                                   short parent_layer_restrict)
{
  /* TODO: support recovery after removal of intermediate collections, reordering, ..
   * For local edits we can make editing operating do the appropriate thing, but for
   * linking we can only sync after the fact. */

  /* Remove layer collections that no longer have a corresponding scene collection. */
  for (LayerCollection *lc = lb_layer->first; lc;) {
    /* Note ID remap can set lc->collection to NULL when deleting collections. */
    LayerCollection *lc_next = lc->next;
    Collection *collection = (lc->collection) ?
                                 BLI_findptr(lb_scene,
                                             lc->collection,
                                             offsetof(CollectionChild, collection)) :
                                 NULL;

    if (!collection) {
      if (lc == view_layer->active_collection) {
        view_layer->active_collection = NULL;
      }

      /* Free recursively. */
      layer_collection_free(view_layer, lc);
      BLI_freelinkN(lb_layer, lc);
    }

    lc = lc_next;
  }

  /* Add layer collections for any new scene collections, and ensure order is the same. */
  ListBase new_lb_layer = {NULL, NULL};
  short runtime_flag = 0;

  for (const CollectionChild *child = lb_scene->first; child; child = child->next) {
    Collection *collection = child->collection;
    LayerCollection *lc = BLI_findptr(lb_layer, collection, offsetof(LayerCollection, collection));

    if (lc) {
      BLI_remlink(lb_layer, lc);
      BLI_addtail(&new_lb_layer, lc);
    }
    else {
      lc = layer_collection_add(&new_lb_layer, collection);
      lc->flag = parent_exclude;
    }

    /* Collection restrict is inherited. */
    short child_restrict = parent_restrict;
    short child_layer_restrict = parent_layer_restrict;
    if (!(collection->flag & COLLECTION_IS_MASTER)) {
      child_restrict |= collection->flag;
      child_layer_restrict |= lc->flag;
    }

    /* Sync child collections. */
    short child_runtime_flag = layer_collection_sync(view_layer,
                                                     &collection->children,
                                                     &lc->layer_collections,
                                                     new_object_bases,
                                                     lc->flag,
                                                     child_restrict,
                                                     child_layer_restrict);

    /* Layer collection exclude is not inherited. */
    if (lc->flag & LAYER_COLLECTION_EXCLUDE) {
      lc->runtime_flag = 0;
      continue;
    }
    else {
      lc->runtime_flag = child_runtime_flag;
    }

    if (((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) &&
        ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0)) {
      lc->runtime_flag |= LAYER_COLLECTION_VISIBLE;
    }

    /* Sync objects, except if collection was excluded. */
    for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
      if (cob->ob == NULL) {
        continue;
      }

      void **base_p;
      Base *base;
      if (BLI_ghash_ensure_p(view_layer->object_bases_hash, cob->ob, &base_p)) {
        /* Move from old base list to new base list. Base might have already
         * been moved to the new base list and the first/last test ensure that
         * case also works. */
        base = *base_p;
        if (!ELEM(base, new_object_bases->first, new_object_bases->last)) {
          BLI_remlink(&view_layer->object_bases, base);
          BLI_addtail(new_object_bases, base);
        }
      }
      else {
        /* Create new base. */
        base = object_base_new(cob->ob);
        *base_p = base;
        BLI_addtail(new_object_bases, base);
      }

      if ((child_restrict & COLLECTION_RESTRICT_VIEWPORT) == 0) {
        base->flag_from_collection |= BASE_ENABLED_VIEWPORT;
        if ((child_layer_restrict & LAYER_COLLECTION_HIDE) == 0) {
          base->flag_from_collection |= BASE_VISIBLE;
          if (((child_restrict & COLLECTION_RESTRICT_SELECT) == 0)) {
            base->flag_from_collection |= BASE_SELECTABLE;
          }
        }
      }

      if ((child_restrict & COLLECTION_RESTRICT_RENDER) == 0) {
        base->flag_from_collection |= BASE_ENABLED_RENDER;
      }

      /* Holdout and indirect only */
      if (lc->flag & LAYER_COLLECTION_HOLDOUT) {
        base->flag_from_collection |= BASE_HOLDOUT;
      }
      if (lc->flag & LAYER_COLLECTION_INDIRECT_ONLY) {
        base->flag_from_collection |= BASE_INDIRECT_ONLY;
      }

      lc->runtime_flag |= LAYER_COLLECTION_HAS_OBJECTS;

      /* Make sure flags on base are usable right away. */
      BKE_base_eval_flags(base);
    }

    runtime_flag |= lc->runtime_flag;
  }

  /* Replace layer collection list with new one. */
  *lb_layer = new_lb_layer;
  BLI_assert(BLI_listbase_count(lb_scene) == BLI_listbase_count(lb_layer));

  return runtime_flag;
}
Example #6
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;
	}