Compare commits
37 Commits
tmp-workbe
...
surface-de
Author | SHA1 | Date | |
---|---|---|---|
a2ed635a73 | |||
b3aead8fd7 | |||
733b5b8c66 | |||
5a17cb4c08 | |||
e5e44c01f2 | |||
a3e32e2ab5 | |||
e843f42e66 | |||
96f6ec07fb | |||
c38e19ca67 | |||
96d66c7e4d | |||
46821f072d | |||
f870343208 | |||
cf1a7e3944 | |||
cf660b2a02 | |||
6f3957770d | |||
7608f366c7 | |||
8c220c57f9 | |||
a300f80043 | |||
22ce298d73 | |||
3469aa47c1 | |||
097a560bc9 | |||
1b7623fc06 | |||
c546256563 | |||
5c263a9050 | |||
8745cd825a | |||
28622ae81e | |||
d6c7163c06 | |||
0bb57759ec | |||
5e1d438d5e | |||
0721bc0ac4 | |||
7ca0894a17 | |||
751496437b | |||
3014601f3b | |||
b80971ce10 | |||
68f5ce194b | |||
1e9003aea5 | |||
95701b0b04 |
@@ -947,6 +947,20 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
def SURFACE(self, layout, ob, md):
|
||||
layout.label(text="Settings are inside the Physics tab")
|
||||
|
||||
def SURFACE_DEFORM(self, layout, ob, md):
|
||||
col = layout.column()
|
||||
col.active = not md.is_bound
|
||||
|
||||
col.prop(md, "target")
|
||||
col.prop(md, "falloff")
|
||||
|
||||
layout.separator()
|
||||
|
||||
if md.is_bound:
|
||||
layout.operator("object.surfacedeform_bind", text="Unbind")
|
||||
else:
|
||||
layout.operator("object.surfacedeform_bind", text="Bind")
|
||||
|
||||
def UV_PROJECT(self, layout, ob, md):
|
||||
split = layout.split()
|
||||
|
||||
|
@@ -230,6 +230,7 @@ static MPoly *dm_dupPolyArray(DerivedMesh *dm)
|
||||
|
||||
static int dm_getNumLoopTri(DerivedMesh *dm)
|
||||
{
|
||||
DM_ensure_looptri(dm);
|
||||
return dm->looptris.num;
|
||||
}
|
||||
|
||||
|
@@ -1014,7 +1014,7 @@ static bool cloth_points_collision_response_static(ClothModifierData *clmd, Coll
|
||||
}
|
||||
|
||||
BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float p2[3], const float v0[3], const float v1[3], const float v2[3],
|
||||
float r_nor[3], float *r_lambda, float r_w[4])
|
||||
float r_nor[3], float *r_lambda, float r_w[3])
|
||||
{
|
||||
float edge1[3], edge2[3], p2face[3], p1p2[3], v0p2[3];
|
||||
float nor_v0p2, nor_p1p2;
|
||||
@@ -1026,7 +1026,7 @@ BLI_INLINE bool cloth_point_face_collision_params(const float p1[3], const float
|
||||
|
||||
nor_v0p2 = dot_v3v3(v0p2, r_nor);
|
||||
madd_v3_v3v3fl(p2face, p2, r_nor, -nor_v0p2);
|
||||
interp_weights_face_v3(r_w, v0, v1, v2, NULL, p2face);
|
||||
interp_weights_tri_v3(r_w, v0, v1, v2, p2face);
|
||||
|
||||
sub_v3_v3v3(p1p2, p2, p1);
|
||||
sub_v3_v3v3(v0p2, p2, v0);
|
||||
@@ -1085,7 +1085,7 @@ static CollPair *cloth_point_collpair(
|
||||
const float *co1 = mverts[bp1].co, *co2 = mverts[bp2].co, *co3 = mverts[bp3].co;
|
||||
float lambda /*, distance1 */, distance2;
|
||||
float facenor[3], v1p1[3], v1p2[3];
|
||||
float w[4];
|
||||
float w[3];
|
||||
|
||||
if (!cloth_point_face_collision_params(p1, p2, co1, co2, co3, facenor, &lambda, w))
|
||||
return collpair;
|
||||
|
@@ -3739,7 +3739,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
|
||||
|
||||
/* velocity brush, only do on main sample */
|
||||
if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss == 0 && brushVelocity) {
|
||||
float weights[4];
|
||||
float weights[3];
|
||||
float brushPointVelocity[3];
|
||||
float velocity[3];
|
||||
|
||||
@@ -3748,7 +3748,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
|
||||
const int v3 = mloop[mlooptri[hitTri].tri[2]].v;
|
||||
|
||||
/* calculate barycentric weights for hit point */
|
||||
interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, hitCoord);
|
||||
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, hitCoord);
|
||||
|
||||
/* simple check based on brush surface velocity,
|
||||
* todo: perhaps implement something that handles volume movement as well */
|
||||
|
@@ -621,10 +621,33 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
|
||||
static void emDM_recalcLoopTri(DerivedMesh *dm)
|
||||
{
|
||||
/* Nothing to do: emDM tessellation is known,
|
||||
* allocate and fill in with emDM_getLoopTriArray */
|
||||
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
|
||||
BMLoop *(*looptris)[3] = bmdm->em->looptris;
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = bmdm->em->tottri;
|
||||
int i;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
|
||||
|
||||
for (i = 0; i < tottri; i++) {
|
||||
BMLoop **ltri = looptris[i];
|
||||
MLoopTri *lt = &mlooptri[i];
|
||||
|
||||
ARRAY_SET_ITEMS(
|
||||
lt->tri,
|
||||
BM_elem_index_get(ltri[0]),
|
||||
BM_elem_index_get(ltri[1]),
|
||||
BM_elem_index_get(ltri[2]));
|
||||
lt->poly = BM_elem_index_get(ltri[0]->f);
|
||||
}
|
||||
}
|
||||
|
||||
static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
|
||||
@@ -633,32 +656,9 @@ static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
}
|
||||
else {
|
||||
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
|
||||
BMLoop *(*looptris)[3] = bmdm->em->looptris;
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = bmdm->em->tottri;
|
||||
int i;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
|
||||
|
||||
for (i = 0; i < tottri; i++) {
|
||||
BMLoop **ltri = looptris[i];
|
||||
MLoopTri *lt = &mlooptri[i];
|
||||
|
||||
ARRAY_SET_ITEMS(
|
||||
lt->tri,
|
||||
BM_elem_index_get(ltri[0]),
|
||||
BM_elem_index_get(ltri[1]),
|
||||
BM_elem_index_get(ltri[2]));
|
||||
lt->poly = BM_elem_index_get(ltri[0]->f);
|
||||
}
|
||||
dm->recalcLoopTri(dm);
|
||||
}
|
||||
|
||||
return dm->looptris.array;
|
||||
}
|
||||
|
||||
|
@@ -1909,19 +1909,19 @@ void BKE_mesh_calc_poly_center(
|
||||
const MVert *mvarray, float r_cent[3])
|
||||
{
|
||||
if (mpoly->totloop == 3) {
|
||||
cent_tri_v3(r_cent,
|
||||
mvarray[loopstart[0].v].co,
|
||||
mvarray[loopstart[1].v].co,
|
||||
mvarray[loopstart[2].v].co
|
||||
);
|
||||
mid_v3_v3v3v3(r_cent,
|
||||
mvarray[loopstart[0].v].co,
|
||||
mvarray[loopstart[1].v].co,
|
||||
mvarray[loopstart[2].v].co
|
||||
);
|
||||
}
|
||||
else if (mpoly->totloop == 4) {
|
||||
cent_quad_v3(r_cent,
|
||||
mvarray[loopstart[0].v].co,
|
||||
mvarray[loopstart[1].v].co,
|
||||
mvarray[loopstart[2].v].co,
|
||||
mvarray[loopstart[3].v].co
|
||||
);
|
||||
mid_v3_v3v3v3v3(r_cent,
|
||||
mvarray[loopstart[0].v].co,
|
||||
mvarray[loopstart[1].v].co,
|
||||
mvarray[loopstart[2].v].co,
|
||||
mvarray[loopstart[3].v].co
|
||||
);
|
||||
}
|
||||
else {
|
||||
mesh_calc_ngon_center(mpoly, loopstart, mvarray, r_cent);
|
||||
@@ -1978,7 +1978,7 @@ static float mesh_calc_poly_planar_area_centroid(
|
||||
tri_area = area_tri_signed_v3(v1, v2, v3, normal);
|
||||
total_area += tri_area;
|
||||
|
||||
cent_tri_v3(tri_cent, v1, v2, v3);
|
||||
mid_v3_v3v3v3(tri_cent, v1, v2, v3);
|
||||
madd_v3_v3fl(r_cent, tri_cent, tri_area);
|
||||
|
||||
copy_v3_v3(v2, v3);
|
||||
|
@@ -758,15 +758,14 @@ static void obstacles_from_derivedmesh_task_cb(void *userdata, const int z)
|
||||
/* find the nearest point on the mesh */
|
||||
if (BLI_bvhtree_find_nearest(data->tree->tree, ray_start, &nearest, data->tree->nearest_callback, data->tree) != -1) {
|
||||
const MLoopTri *lt = &data->looptri[nearest.index];
|
||||
float weights[4];
|
||||
float weights[3];
|
||||
int v1, v2, v3;
|
||||
|
||||
/* calculate barycentric weights for nearest point */
|
||||
v1 = data->mloop[lt->tri[0]].v;
|
||||
v2 = data->mloop[lt->tri[1]].v;
|
||||
v3 = data->mloop[lt->tri[2]].v;
|
||||
interp_weights_face_v3(
|
||||
weights, data->mvert[v1].co, data->mvert[v2].co, data->mvert[v3].co, NULL, nearest.co);
|
||||
interp_weights_tri_v3(weights, data->mvert[v1].co, data->mvert[v2].co, data->mvert[v3].co, nearest.co);
|
||||
|
||||
// DG TODO
|
||||
if (data->has_velocity)
|
||||
@@ -1454,7 +1453,7 @@ static void sample_derivedmesh(
|
||||
|
||||
/* find the nearest point on the mesh */
|
||||
if (BLI_bvhtree_find_nearest(treeData->tree, ray_start, &nearest, treeData->nearest_callback, treeData) != -1) {
|
||||
float weights[4];
|
||||
float weights[3];
|
||||
int v1, v2, v3, f_index = nearest.index;
|
||||
float n1[3], n2[3], n3[3], hit_normal[3];
|
||||
|
||||
@@ -1471,7 +1470,7 @@ static void sample_derivedmesh(
|
||||
v1 = mloop[mlooptri[f_index].tri[0]].v;
|
||||
v2 = mloop[mlooptri[f_index].tri[1]].v;
|
||||
v3 = mloop[mlooptri[f_index].tri[2]].v;
|
||||
interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co);
|
||||
interp_weights_tri_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, nearest.co);
|
||||
|
||||
if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && velocity_map) {
|
||||
/* apply normal directional velocity */
|
||||
|
@@ -4474,46 +4474,46 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
|
||||
/* Nothing to do: CCG handles creating its own tessfaces */
|
||||
}
|
||||
|
||||
static void ccgDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
|
||||
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
|
||||
{
|
||||
/* Nothing to do: CCG tessellation is known,
|
||||
* allocate and fill in with ccgDM_getLoopTriArray */
|
||||
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = dm->numPolyData * 2;
|
||||
int i, poly_index;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
|
||||
MLoopTri *lt;
|
||||
lt = &mlooptri[i];
|
||||
/* quad is (0, 3, 2, 1) */
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 2;
|
||||
lt->tri[2] = (poly_index * 4) + 3;
|
||||
lt->poly = poly_index;
|
||||
|
||||
lt = &mlooptri[i + 1];
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 1;
|
||||
lt->tri[2] = (poly_index * 4) + 2;
|
||||
lt->poly = poly_index;
|
||||
}
|
||||
BLI_rw_mutex_unlock(&loops_cache_rwlock);
|
||||
}
|
||||
|
||||
static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
|
||||
{
|
||||
BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
|
||||
if (dm->looptris.array) {
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
}
|
||||
else {
|
||||
MLoopTri *mlooptri;
|
||||
const int tottri = dm->numPolyData * 2;
|
||||
int i, poly_index;
|
||||
|
||||
DM_ensure_looptri_data(dm);
|
||||
mlooptri = dm->looptris.array;
|
||||
|
||||
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
|
||||
BLI_assert(tottri == dm->looptris.num);
|
||||
|
||||
for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
|
||||
MLoopTri *lt;
|
||||
lt = &mlooptri[i];
|
||||
/* quad is (0, 3, 2, 1) */
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 2;
|
||||
lt->tri[2] = (poly_index * 4) + 3;
|
||||
lt->poly = poly_index;
|
||||
|
||||
lt = &mlooptri[i + 1];
|
||||
lt->tri[0] = (poly_index * 4) + 0;
|
||||
lt->tri[1] = (poly_index * 4) + 1;
|
||||
lt->tri[2] = (poly_index * 4) + 2;
|
||||
lt->poly = poly_index;
|
||||
}
|
||||
dm->recalcLoopTri(dm);
|
||||
}
|
||||
BLI_rw_mutex_unlock(&loops_cache_rwlock);
|
||||
|
||||
return dm->looptris.array;
|
||||
}
|
||||
|
||||
|
@@ -44,9 +44,6 @@ extern "C" {
|
||||
|
||||
/********************************** Polygons *********************************/
|
||||
|
||||
void cent_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
|
||||
void cent_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
|
||||
|
||||
float normal_tri_v3(float r[3], const float a[3], const float b[3], const float c[3]);
|
||||
float normal_quad_v3(float r[3], const float a[3], const float b[3], const float c[3], const float d[3]);
|
||||
float normal_poly_v3(float r[3], const float verts[][3], unsigned int nr);
|
||||
@@ -85,6 +82,7 @@ float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3
|
||||
float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
|
||||
|
||||
bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
|
||||
bool is_poly_convex_v3(const float verts[][3], unsigned int nr);
|
||||
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
|
||||
bool is_poly_convex_v2(const float verts[][2], unsigned int nr);
|
||||
int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
|
||||
@@ -326,10 +324,8 @@ bool clip_segment_v3_plane_n(
|
||||
float r_p1[3], float r_p2[3]);
|
||||
|
||||
/****************************** Interpolation ********************************/
|
||||
|
||||
/* tri or quad, d can be NULL */
|
||||
void interp_weights_face_v3(float w[4],
|
||||
const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]);
|
||||
void interp_weights_tri_v3(float w[3], const float a[3], const float b[3], const float c[3], const float p[3]);
|
||||
void interp_weights_quad_v3(float w[4], const float a[3], const float b[3], const float c[3], const float d[3], const float p[3]);
|
||||
void interp_weights_poly_v3(float w[], float v[][3], const int n, const float co[3]);
|
||||
void interp_weights_poly_v2(float w[], float v[][2], const int n, const float co[2]);
|
||||
|
||||
@@ -394,6 +390,8 @@ void box_minmax_bounds_m4(float min[3], float max[3],
|
||||
|
||||
void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z);
|
||||
void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z);
|
||||
void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3]);
|
||||
void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], const float axis[3], const float angle);
|
||||
|
||||
/********************************** Normals **********************************/
|
||||
|
||||
|
@@ -234,6 +234,7 @@ void mid_v3_v3v3(float r[3], const float a[3], const float b[3]);
|
||||
void mid_v2_v2v2(float r[2], const float a[2], const float b[2]);
|
||||
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3]);
|
||||
void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3]);
|
||||
void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr);
|
||||
|
||||
void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3]);
|
||||
void mid_v3_angle_weighted(float r[3]);
|
||||
|
@@ -37,20 +37,6 @@
|
||||
|
||||
/********************************** Polygons *********************************/
|
||||
|
||||
void cent_tri_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3])
|
||||
{
|
||||
cent[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
|
||||
cent[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
|
||||
cent[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
|
||||
}
|
||||
|
||||
void cent_quad_v3(float cent[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
|
||||
{
|
||||
cent[0] = 0.25f * (v1[0] + v2[0] + v3[0] + v4[0]);
|
||||
cent[1] = 0.25f * (v1[1] + v2[1] + v3[1] + v4[1]);
|
||||
cent[2] = 0.25f * (v1[2] + v2[2] + v3[2] + v4[2]);
|
||||
}
|
||||
|
||||
void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
|
||||
{
|
||||
float n1[3], n2[3];
|
||||
@@ -2964,7 +2950,15 @@ static bool barycentric_weights(const float v1[3], const float v2[3], const floa
|
||||
}
|
||||
}
|
||||
|
||||
void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3])
|
||||
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
|
||||
{
|
||||
float n[3];
|
||||
|
||||
normal_tri_v3(n, v1, v2, v3);
|
||||
barycentric_weights(v1, v2, v3, co, n, w);
|
||||
}
|
||||
|
||||
void interp_weights_quad_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3])
|
||||
{
|
||||
float w2[3];
|
||||
|
||||
@@ -2977,7 +2971,7 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co
|
||||
w[1] = 1.0f;
|
||||
else if (equals_v3v3(co, v3))
|
||||
w[2] = 1.0f;
|
||||
else if (v4 && equals_v3v3(co, v4))
|
||||
else if (equals_v3v3(co, v4))
|
||||
w[3] = 1.0f;
|
||||
else {
|
||||
/* otherwise compute barycentric interpolation weights */
|
||||
@@ -2985,35 +2979,24 @@ void interp_weights_face_v3(float w[4], const float v1[3], const float v2[3], co
|
||||
bool degenerate;
|
||||
|
||||
sub_v3_v3v3(n1, v1, v3);
|
||||
if (v4) {
|
||||
sub_v3_v3v3(n2, v2, v4);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(n2, v2, v3);
|
||||
}
|
||||
sub_v3_v3v3(n2, v2, v4);
|
||||
cross_v3_v3v3(n, n1, n2);
|
||||
|
||||
/* OpenGL seems to split this way, so we do too */
|
||||
if (v4) {
|
||||
degenerate = barycentric_weights(v1, v2, v4, co, n, w);
|
||||
SWAP(float, w[2], w[3]);
|
||||
degenerate = barycentric_weights(v1, v2, v4, co, n, w);
|
||||
SWAP(float, w[2], w[3]);
|
||||
|
||||
if (degenerate || (w[0] < 0.0f)) {
|
||||
/* if w[1] is negative, co is on the other side of the v1-v3 edge,
|
||||
* so we interpolate using the other triangle */
|
||||
degenerate = barycentric_weights(v2, v3, v4, co, n, w2);
|
||||
if (degenerate || (w[0] < 0.0f)) {
|
||||
/* if w[1] is negative, co is on the other side of the v1-v3 edge,
|
||||
* so we interpolate using the other triangle */
|
||||
degenerate = barycentric_weights(v2, v3, v4, co, n, w2);
|
||||
|
||||
if (!degenerate) {
|
||||
w[0] = 0.0f;
|
||||
w[1] = w2[0];
|
||||
w[2] = w2[1];
|
||||
w[3] = w2[2];
|
||||
}
|
||||
if (!degenerate) {
|
||||
w[0] = 0.0f;
|
||||
w[1] = w2[0];
|
||||
w[2] = w2[1];
|
||||
w[3] = w2[2];
|
||||
}
|
||||
}
|
||||
else {
|
||||
barycentric_weights(v1, v2, v3, co, n, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4060,6 +4043,26 @@ void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const f
|
||||
}
|
||||
}
|
||||
|
||||
void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3])
|
||||
{
|
||||
float target[3] = {0.0f, 0.0f, 1.0f};
|
||||
float axis[3];
|
||||
|
||||
cross_v3_v3v3(axis, no, target);
|
||||
normalize_v3(axis);
|
||||
|
||||
map_to_plane_axis_angle_v2_v3v3fl(r_co, co, axis, angle_normalized_v3v3(no, target));
|
||||
}
|
||||
|
||||
void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], const float axis[3], const float angle)
|
||||
{
|
||||
float tmp[3];
|
||||
|
||||
rotate_normalized_v3_v3v3fl(tmp, co, axis, angle);
|
||||
|
||||
copy_v2_v2(r_co, tmp);
|
||||
}
|
||||
|
||||
/********************************* Normals **********************************/
|
||||
|
||||
void accumulate_vertex_normals_tri(
|
||||
@@ -4791,54 +4794,56 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
|
||||
*/
|
||||
bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
|
||||
{
|
||||
const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
|
||||
return is_poly_convex_v3(verts, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if polygon is convex
|
||||
*/
|
||||
bool is_poly_convex_v3(const float verts[][3], unsigned int nr)
|
||||
{
|
||||
const float *co_curr, *co_prev;
|
||||
float vec_curr[3], vec_prev[3];
|
||||
float normal[3];
|
||||
unsigned int i;
|
||||
|
||||
if (nr == 3)
|
||||
return true;
|
||||
|
||||
co_prev = verts[nr - 1];
|
||||
co_curr = verts[0];
|
||||
|
||||
/* Non-unit length normal, just to check angle directions */
|
||||
cross_poly_v3(normal, verts, nr);
|
||||
|
||||
sub_v3_v3v3(vec_prev, co_prev, verts[nr - 2]);
|
||||
|
||||
/**
|
||||
* Method projects points onto a plane and checks its convex using following method:
|
||||
*
|
||||
* - Create a plane from the cross-product of both diagonal vectors.
|
||||
* - Project all points onto the plane.
|
||||
* - Subtract for direction vectors.
|
||||
* - Return true if all corners cross-products point the direction of the plane.
|
||||
* Implementation note: there is no need to project the vertices onto the normal plane,
|
||||
* because even if the polygon is highly non-planar, the cross product between
|
||||
* adjacent edges will always point to the same side as the normal when convex,
|
||||
* and to the opposite side when concave.
|
||||
*/
|
||||
|
||||
/* non-unit length normal, used as a projection plane */
|
||||
float plane[3];
|
||||
for (i = 0; i < nr; i++) {
|
||||
float cross[3];
|
||||
|
||||
{
|
||||
float v13[3], v24[3];
|
||||
sub_v3_v3v3(vec_curr, co_curr, co_prev);
|
||||
|
||||
sub_v3_v3v3(v13, v1, v3);
|
||||
sub_v3_v3v3(v24, v2, v4);
|
||||
cross_v3_v3v3(cross, vec_prev, vec_curr);
|
||||
|
||||
cross_v3_v3v3(plane, v13, v24);
|
||||
|
||||
if (len_squared_v3(plane) < FLT_EPSILON) {
|
||||
if (dot_v3v3(cross, normal) < 0.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
copy_v3_v3(vec_prev, vec_curr);
|
||||
|
||||
co_prev = co_curr;
|
||||
co_curr += 3;
|
||||
}
|
||||
|
||||
const float *quad_coords[4] = {v1, v2, v3, v4};
|
||||
float quad_proj[4][3];
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
project_plane_v3_v3v3(quad_proj[i], quad_coords[i], plane);
|
||||
}
|
||||
|
||||
float quad_dirs[4][3];
|
||||
for (int i = 0, j = 3; i < 4; j = i++) {
|
||||
sub_v3_v3v3(quad_dirs[i], quad_proj[i], quad_proj[j]);
|
||||
}
|
||||
|
||||
float test_dir[3];
|
||||
|
||||
#define CROSS_SIGN(dir_a, dir_b) \
|
||||
((void)cross_v3_v3v3(test_dir, dir_a, dir_b), (dot_v3v3(plane, test_dir) > 0.0f))
|
||||
|
||||
return (CROSS_SIGN(quad_dirs[0], quad_dirs[1]) &&
|
||||
CROSS_SIGN(quad_dirs[1], quad_dirs[2]) &&
|
||||
CROSS_SIGN(quad_dirs[2], quad_dirs[3]) &&
|
||||
CROSS_SIGN(quad_dirs[3], quad_dirs[0]));
|
||||
|
||||
#undef CROSS_SIGN
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
|
||||
|
@@ -280,6 +280,16 @@ void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const flo
|
||||
v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
|
||||
}
|
||||
|
||||
void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr)
|
||||
{
|
||||
const float factor = 1.0f / (float)nbr;
|
||||
zero_v3(r);
|
||||
|
||||
for (unsigned int i = 0; i < nbr; i++) {
|
||||
madd_v3_v3fl(r, vec_arr[i], factor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialized function for calculating normals.
|
||||
* fastpath for:
|
||||
|
@@ -5302,6 +5302,37 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
csmd->delta_cache = NULL;
|
||||
csmd->delta_cache_num = 0;
|
||||
}
|
||||
else if (md->type == eModifierType_SurfaceDeform) {
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
||||
smd->verts = newdataadr(fd, smd->verts);
|
||||
|
||||
if (smd->verts) {
|
||||
for (int i = 0; i < smd->numverts; i++) {
|
||||
smd->verts[i].binds = newdataadr(fd, smd->verts[i].binds);
|
||||
|
||||
if (smd->verts[i].binds) {
|
||||
for (int j = 0; j < smd->verts[i].numbinds; j++) {
|
||||
smd->verts[i].binds[j].vert_inds = newdataadr(fd, smd->verts[i].binds[j].vert_inds);
|
||||
smd->verts[i].binds[j].vert_weights = newdataadr(fd, smd->verts[i].binds[j].vert_weights);
|
||||
|
||||
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
|
||||
if (smd->verts[i].binds[j].vert_inds)
|
||||
BLI_endian_switch_uint32_array(smd->verts[i].binds[j].vert_inds, smd->verts[i].binds[j].numverts);
|
||||
|
||||
if (smd->verts[i].binds[j].vert_weights) {
|
||||
if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
|
||||
smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI)
|
||||
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, 3);
|
||||
else
|
||||
BLI_endian_switch_float_array(smd->verts[i].binds[j].vert_weights, smd->verts[i].binds[j].numverts);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1830,6 +1830,32 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
|
||||
writedata(wd, DATA, sizeof(float[3]) * csmd->bind_coords_num, csmd->bind_coords);
|
||||
}
|
||||
}
|
||||
else if (md->type == eModifierType_SurfaceDeform) {
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
|
||||
|
||||
writestruct(wd, DATA, SDefVert, smd->numverts, smd->verts);
|
||||
|
||||
if (smd->verts) {
|
||||
for (int i = 0; i < smd->numverts; i++) {
|
||||
writestruct(wd, DATA, SDefBind, smd->verts[i].numbinds, smd->verts[i].binds);
|
||||
|
||||
if (smd->verts[i].binds) {
|
||||
for (int j = 0; j < smd->verts[i].numbinds; j++) {
|
||||
writedata(wd, DATA, sizeof(int) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_inds);
|
||||
|
||||
if (smd->verts[i].binds[j].mode == MOD_SDEF_MODE_CENTROID ||
|
||||
smd->verts[i].binds[j].mode == MOD_SDEF_MODE_LOOPTRI)
|
||||
{
|
||||
writedata(wd, DATA, sizeof(float) * 3, smd->verts[i].binds[j].vert_weights);
|
||||
}
|
||||
else {
|
||||
writedata(wd, DATA, sizeof(float) * smd->verts[i].binds[j].numverts, smd->verts[i].binds[j].vert_weights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -339,7 +339,7 @@ static bool mdisp_in_mdispquad(
|
||||
compute_mdisp_quad(l_dst, l_dst_f_center, v1, v2, v3, v4, e1, e2);
|
||||
|
||||
/* expand quad a bit */
|
||||
cent_quad_v3(c, v1, v2, v3, v4);
|
||||
mid_v3_v3v3v3v3(c, v1, v2, v3, v4);
|
||||
|
||||
sub_v3_v3(v1, c); sub_v3_v3(v2, c);
|
||||
sub_v3_v3(v3, c); sub_v3_v3(v4, c);
|
||||
|
@@ -186,6 +186,7 @@ void OBJECT_OT_skin_loose_mark_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
|
||||
|
||||
/* object_constraint.c */
|
||||
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
|
||||
|
@@ -2294,3 +2294,63 @@ void OBJECT_OT_laplaciandeform_bind(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
edit_modifier_properties(ot);
|
||||
}
|
||||
|
||||
/************************ sdef bind operator *********************/
|
||||
|
||||
static int surfacedeform_bind_poll(bContext *C)
|
||||
{
|
||||
if (edit_modifier_poll_generic(C, &RNA_SurfaceDeformModifier, 0)) {
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_SurfaceDeformModifier);
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)ptr.data;
|
||||
|
||||
return ((smd != NULL) && (smd->target != NULL));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int surfacedeform_bind_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_active_context(C);
|
||||
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform);
|
||||
|
||||
if (!smd)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (smd->flags & MOD_SDEF_BIND) {
|
||||
smd->flags &= ~MOD_SDEF_BIND;
|
||||
}
|
||||
else if (smd->target) {
|
||||
smd->flags |= MOD_SDEF_BIND;
|
||||
}
|
||||
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int surfacedeform_bind_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
|
||||
{
|
||||
if (edit_modifier_invoke_properties(C, op))
|
||||
return surfacedeform_bind_exec(C, op);
|
||||
else
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_surfacedeform_bind(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Surface Deform Bind";
|
||||
ot->description = "Bind mesh to target in surface deform modifier";
|
||||
ot->idname = "OBJECT_OT_surfacedeform_bind";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll = surfacedeform_bind_poll;
|
||||
ot->invoke = surfacedeform_bind_invoke;
|
||||
ot->exec = surfacedeform_bind_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
|
||||
edit_modifier_properties(ot);
|
||||
}
|
||||
|
@@ -255,6 +255,7 @@ void ED_operatortypes_object(void)
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_data_transfer);
|
||||
WM_operatortype_append(OBJECT_OT_datalayout_transfer);
|
||||
WM_operatortype_append(OBJECT_OT_surfacedeform_bind);
|
||||
}
|
||||
|
||||
void ED_operatormacros_object(void)
|
||||
|
@@ -1125,6 +1125,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
|
||||
case eModifierType_Cast:
|
||||
UI_icon_draw(x, y, ICON_MOD_CAST); break;
|
||||
case eModifierType_MeshDeform:
|
||||
case eModifierType_SurfaceDeform:
|
||||
UI_icon_draw(x, y, ICON_MOD_MESHDEFORM); break;
|
||||
case eModifierType_Bevel:
|
||||
UI_icon_draw(x, y, ICON_MOD_BEVEL); break;
|
||||
|
@@ -86,6 +86,7 @@ typedef enum ModifierType {
|
||||
eModifierType_NormalEdit = 50,
|
||||
eModifierType_CorrectiveSmooth = 51,
|
||||
eModifierType_MeshSequenceCache = 52,
|
||||
eModifierType_SurfaceDeform = 53,
|
||||
NUM_MODIFIER_TYPES
|
||||
} ModifierType;
|
||||
|
||||
@@ -1570,6 +1571,45 @@ enum {
|
||||
MOD_MESHSEQ_READ_COLOR = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct SDefBind {
|
||||
unsigned int *vert_inds;
|
||||
unsigned int numverts;
|
||||
int mode;
|
||||
float *vert_weights;
|
||||
float normal_dist;
|
||||
float influence;
|
||||
} SDefBind;
|
||||
|
||||
typedef struct SDefVert {
|
||||
SDefBind *binds;
|
||||
unsigned int numbinds;
|
||||
char pad[4];
|
||||
} SDefVert;
|
||||
|
||||
typedef struct SurfaceDeformModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct Object *target; /* bind target object */
|
||||
SDefVert *verts; /* vertex bind data */
|
||||
float falloff;
|
||||
unsigned int numverts, numpoly;
|
||||
int flags;
|
||||
} SurfaceDeformModifierData;
|
||||
|
||||
/* Surface Deform modifier flags */
|
||||
enum {
|
||||
MOD_SDEF_BIND = (1 << 0),
|
||||
MOD_SDEF_USES_LOOPTRI = (1 << 1),
|
||||
MOD_SDEF_HAS_CONCAVE = (1 << 2),
|
||||
};
|
||||
|
||||
/* Surface Deform vertex bind modes */
|
||||
enum {
|
||||
MOD_SDEF_MODE_LOOPTRI = 0,
|
||||
MOD_SDEF_MODE_NGON = 1,
|
||||
MOD_SDEF_MODE_CENTROID = 2,
|
||||
};
|
||||
|
||||
#define MOD_MESHSEQ_READ_ALL \
|
||||
(MOD_MESHSEQ_READ_VERT | MOD_MESHSEQ_READ_POLY | MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)
|
||||
|
||||
|
@@ -597,6 +597,7 @@ extern StructRNA RNA_StucciTexture;
|
||||
extern StructRNA RNA_SubsurfModifier;
|
||||
extern StructRNA RNA_SunLamp;
|
||||
extern StructRNA RNA_SurfaceCurve;
|
||||
extern StructRNA RNA_SurfaceDeformModifier;
|
||||
extern StructRNA RNA_SurfaceModifier;
|
||||
extern StructRNA RNA_TexMapping;
|
||||
extern StructRNA RNA_Text;
|
||||
|
@@ -105,6 +105,7 @@ EnumPropertyItem rna_enum_object_modifier_type_items[] = {
|
||||
{eModifierType_Shrinkwrap, "SHRINKWRAP", ICON_MOD_SHRINKWRAP, "Shrinkwrap", ""},
|
||||
{eModifierType_SimpleDeform, "SIMPLE_DEFORM", ICON_MOD_SIMPLEDEFORM, "Simple Deform", ""},
|
||||
{eModifierType_Smooth, "SMOOTH", ICON_MOD_SMOOTH, "Smooth", ""},
|
||||
{eModifierType_SurfaceDeform, "SURFACE_DEFORM", ICON_MOD_MESHDEFORM, "Surface Deform", ""},
|
||||
{eModifierType_Warp, "WARP", ICON_MOD_WARP, "Warp", ""},
|
||||
{eModifierType_Wave, "WAVE", ICON_MOD_WAVE, "Wave", ""},
|
||||
{0, "", 0, N_("Simulate"), ""},
|
||||
@@ -408,6 +409,8 @@ static StructRNA *rna_Modifier_refine(struct PointerRNA *ptr)
|
||||
return &RNA_CorrectiveSmoothModifier;
|
||||
case eModifierType_MeshSequenceCache:
|
||||
return &RNA_MeshSequenceCacheModifier;
|
||||
case eModifierType_SurfaceDeform:
|
||||
return &RNA_SurfaceDeformModifier;
|
||||
/* Default */
|
||||
case eModifierType_None:
|
||||
case eModifierType_ShapeKey:
|
||||
@@ -573,6 +576,7 @@ RNA_MOD_OBJECT_SET(MeshDeform, object, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(NormalEdit, target, OB_EMPTY);
|
||||
RNA_MOD_OBJECT_SET(Shrinkwrap, target, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(Shrinkwrap, auxTarget, OB_MESH);
|
||||
RNA_MOD_OBJECT_SET(SurfaceDeform, target, OB_MESH);
|
||||
|
||||
static void rna_HookModifier_object_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
@@ -1131,6 +1135,11 @@ static int rna_CorrectiveSmoothModifier_is_bind_get(PointerRNA *ptr)
|
||||
return (csmd->bind_coords != NULL);
|
||||
}
|
||||
|
||||
static int rna_SurfaceDeformModifier_is_bound_get(PointerRNA *ptr)
|
||||
{
|
||||
return (((SurfaceDeformModifierData *)ptr->data)->verts != NULL);
|
||||
}
|
||||
|
||||
static void rna_MeshSequenceCache_object_path_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
#ifdef WITH_ALEMBIC
|
||||
@@ -4702,6 +4711,33 @@ static void rna_def_modifier_normaledit(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
}
|
||||
|
||||
static void rna_def_modifier_surfacedeform(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "SurfaceDeformModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "SurfaceDeform Modifier", "blablabla");
|
||||
RNA_def_struct_sdna(srna, "SurfaceDeformModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_MOD_MESHDEFORM);
|
||||
|
||||
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Target", "Mesh object to deform with");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_SurfaceDeformModifier_target_set", NULL, "rna_Mesh_object_poll");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_dependency_update");
|
||||
|
||||
prop = RNA_def_property(srna, "falloff", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_range(prop, 2.0f, 16.0f);
|
||||
RNA_def_property_ui_text(prop, "Interpolation falloff", "Controls how much nearby polygons influence deformation");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop = RNA_def_property(srna, "is_bound", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_SurfaceDeformModifier_is_bound_get", NULL);
|
||||
RNA_def_property_ui_text(prop, "Bound", "Whether geometry has been bound to target mesh");
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
}
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@@ -4819,6 +4855,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
||||
rna_def_modifier_datatransfer(brna);
|
||||
rna_def_modifier_normaledit(brna);
|
||||
rna_def_modifier_meshseqcache(brna);
|
||||
rna_def_modifier_surfacedeform(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -93,6 +93,7 @@ set(SRC
|
||||
intern/MOD_solidify.c
|
||||
intern/MOD_subsurf.c
|
||||
intern/MOD_surface.c
|
||||
intern/MOD_surfacedeform.c
|
||||
intern/MOD_triangulate.c
|
||||
intern/MOD_util.c
|
||||
intern/MOD_uvwarp.c
|
||||
|
@@ -85,6 +85,7 @@ extern ModifierTypeInfo modifierType_DataTransfer;
|
||||
extern ModifierTypeInfo modifierType_NormalEdit;
|
||||
extern ModifierTypeInfo modifierType_CorrectiveSmooth;
|
||||
extern ModifierTypeInfo modifierType_MeshSequenceCache;
|
||||
extern ModifierTypeInfo modifierType_SurfaceDeform;
|
||||
|
||||
/* MOD_util.c */
|
||||
void modifier_type_init(ModifierTypeInfo *types[]);
|
||||
|
1189
source/blender/modifiers/intern/MOD_surfacedeform.c
Normal file
1189
source/blender/modifiers/intern/MOD_surfacedeform.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -287,5 +287,6 @@ void modifier_type_init(ModifierTypeInfo *types[])
|
||||
INIT_TYPE(NormalEdit);
|
||||
INIT_TYPE(CorrectiveSmooth);
|
||||
INIT_TYPE(MeshSequenceCache);
|
||||
INIT_TYPE(SurfaceDeform);
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
|
@@ -5572,9 +5572,14 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve
|
||||
co1= mesh->co[face[0]];
|
||||
co2= mesh->co[face[1]];
|
||||
co3= mesh->co[face[2]];
|
||||
co4= (face[3])? mesh->co[face[3]]: NULL;
|
||||
|
||||
interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co);
|
||||
if (face[3]) {
|
||||
co4= mesh->co[face[3]];
|
||||
interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co);
|
||||
}
|
||||
else {
|
||||
interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co);
|
||||
}
|
||||
|
||||
zero_v4(speed);
|
||||
madd_v4_v4fl(speed, winspeed[face[0]], w[0]);
|
||||
|
@@ -329,7 +329,7 @@ static void occ_face(const OccFace *face, float co[3], float normal[3], float *a
|
||||
if (vlr->v4)
|
||||
mid_v3_v3v3(co, vlr->v1->co, vlr->v3->co);
|
||||
else
|
||||
cent_tri_v3(co, vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
mid_v3_v3v3v3(co, vlr->v1->co, vlr->v2->co, vlr->v3->co);
|
||||
|
||||
if (obi->flag & R_TRANSFORMED)
|
||||
mul_m4_v3(obi->mat, co);
|
||||
@@ -1190,9 +1190,14 @@ static void sample_occ_surface(ShadeInput *shi)
|
||||
co1 = mesh->co[face[0]];
|
||||
co2 = mesh->co[face[1]];
|
||||
co3 = mesh->co[face[2]];
|
||||
co4 = (face[3]) ? mesh->co[face[3]] : NULL;
|
||||
|
||||
interp_weights_face_v3(w, co1, co2, co3, co4, strand->vert->co);
|
||||
if (face[3]) {
|
||||
co4 = mesh->co[face[3]];
|
||||
interp_weights_quad_v3(w, co1, co2, co3, co4, strand->vert->co);
|
||||
}
|
||||
else {
|
||||
interp_weights_tri_v3(w, co1, co2, co3, strand->vert->co);
|
||||
}
|
||||
|
||||
zero_v3(shi->ao);
|
||||
zero_v3(shi->env);
|
||||
@@ -1245,7 +1250,7 @@ static void *exec_strandsurface_sample(void *data)
|
||||
normal_quad_v3(n, co1, co2, co3, co4);
|
||||
}
|
||||
else {
|
||||
cent_tri_v3(co, co1, co2, co3);
|
||||
mid_v3_v3v3v3(co, co1, co2, co3);
|
||||
normal_tri_v3(n, co1, co2, co3);
|
||||
}
|
||||
negate_v3(n);
|
||||
|
Reference in New Issue
Block a user