static void laplacian_system_construct_end(LaplacianSystem *sys) { int (*face)[3]; int a, totvert = sys->totvert, totface = sys->totface; laplacian_begin_solve(sys, 0); sys->varea = MEM_callocN(sizeof(float) * totvert, "LaplacianSystemVarea"); sys->edgehash = BLI_edgehash_new_ex(__func__, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(sys->totface)); for (a = 0, face = sys->faces; a < sys->totface; a++, face++) { laplacian_increase_edge_count(sys->edgehash, (*face)[0], (*face)[1]); laplacian_increase_edge_count(sys->edgehash, (*face)[1], (*face)[2]); laplacian_increase_edge_count(sys->edgehash, (*face)[2], (*face)[0]); } if (sys->areaweights) for (a = 0, face = sys->faces; a < sys->totface; a++, face++) laplacian_triangle_area(sys, (*face)[0], (*face)[1], (*face)[2]); for (a = 0; a < totvert; a++) { if (sys->areaweights) { if (sys->varea[a] != 0.0f) sys->varea[a] = 0.5f / sys->varea[a]; } else sys->varea[a] = 1.0f; /* for heat weighting */ if (sys->heat.H) EIG_linear_solver_matrix_add(sys->context, a, a, sys->heat.H[a]); } if (sys->storeweights) sys->fweights = MEM_callocN(sizeof(float) * 3 * totface, "LaplacianFWeight"); for (a = 0, face = sys->faces; a < totface; a++, face++) laplacian_triangle_weights(sys, a, (*face)[0], (*face)[1], (*face)[2]); MEM_freeN(sys->faces); sys->faces = NULL; if (sys->varea) { MEM_freeN(sys->varea); sys->varea = NULL; } BLI_edgehash_free(sys->edgehash, NULL); sys->edgehash = NULL; }
/** * Specialized function to use when we _know_ existing edges don't overlap with poly edges. */ static void make_edges_mdata_extend( MEdge **r_alledge, int *r_totedge, const MPoly *mpoly, MLoop *mloop, const int totpoly) { int totedge = *r_totedge; int totedge_new; EdgeHash *eh; unsigned int eh_reserve; const MPoly *mp; int i; eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly)); eh = BLI_edgehash_new_ex(__func__, eh_reserve); for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart); } totedge_new = BLI_edgehash_len(eh); #ifdef DEBUG /* ensure that there's no overlap! */ if (totedge_new) { MEdge *medge = *r_alledge; for (i = 0; i < totedge; i++, medge++) { BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false); } } #endif if (totedge_new) { EdgeHashIterator *ehi; MEdge *medge; unsigned int e_index = totedge; *r_alledge = medge = (*r_alledge ? MEM_reallocN(*r_alledge, sizeof(MEdge) * (totedge + totedge_new)) : MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__)); medge += totedge; totedge += totedge_new; /* --- */ for (ehi = BLI_edgehashIterator_new(eh); BLI_edgehashIterator_isDone(ehi) == false; BLI_edgehashIterator_step(ehi), ++medge, e_index++) { BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2); BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index)); medge->crease = medge->bweight = 0; medge->flag = ME_EDGEDRAW | ME_EDGERENDER; } BLI_edgehashIterator_free(ehi); *r_totedge = totedge; for (i = 0, mp = mpoly; i < totpoly; i++, mp++) { MLoop *l = &mloop[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; for (j = 0; j < mp->totloop; j++, l++) { /* lookup hashed edge index */ l_prev->e = POINTER_AS_UINT(BLI_edgehash_lookup(eh, l_prev->v, l->v)); l_prev = l; } } } BLI_edgehash_free(eh, NULL); }