Merge branch 'master' into blender2.8
This commit is contained in:
commit
6ab9af0083
|
@ -411,6 +411,7 @@ static void ExportCurveTrianglePlanes(Mesh *mesh, ParticleCurveData *CData,
|
|||
}
|
||||
}
|
||||
|
||||
mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size());
|
||||
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
|
||||
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
|
||||
mesh->add_face_normals();
|
||||
|
@ -434,8 +435,8 @@ static void ExportCurveTriangleGeometry(Mesh *mesh,
|
|||
if(CData->curve_keynum[curve] <= 1 || CData->curve_length[curve] == 0.0f)
|
||||
continue;
|
||||
|
||||
numverts += (CData->curve_keynum[curve] - 2)*2*resolution + resolution;
|
||||
numtris += (CData->curve_keynum[curve] - 2)*resolution;
|
||||
numverts += (CData->curve_keynum[curve] - 1)*resolution + resolution;
|
||||
numtris += (CData->curve_keynum[curve] - 1)*2*resolution;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,6 +546,7 @@ static void ExportCurveTriangleGeometry(Mesh *mesh,
|
|||
}
|
||||
}
|
||||
|
||||
mesh->resize_mesh(mesh->verts.size(), mesh->triangles.size());
|
||||
mesh->attributes.remove(ATTR_STD_VERTEX_NORMAL);
|
||||
mesh->attributes.remove(ATTR_STD_FACE_NORMAL);
|
||||
mesh->add_face_normals();
|
||||
|
@ -890,7 +892,7 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
|||
}
|
||||
|
||||
/* obtain general settings */
|
||||
bool use_curves = scene->curve_system_manager->use_curves;
|
||||
const bool use_curves = scene->curve_system_manager->use_curves;
|
||||
|
||||
if(!(use_curves && b_ob.mode() != b_ob.mode_PARTICLE_EDIT)) {
|
||||
if(!motion)
|
||||
|
@ -898,11 +900,11 @@ void BlenderSync::sync_curves(Mesh *mesh,
|
|||
return;
|
||||
}
|
||||
|
||||
int primitive = scene->curve_system_manager->primitive;
|
||||
int triangle_method = scene->curve_system_manager->triangle_method;
|
||||
int resolution = scene->curve_system_manager->resolution;
|
||||
size_t vert_num = mesh->verts.size();
|
||||
size_t tri_num = mesh->num_triangles();
|
||||
const int primitive = scene->curve_system_manager->primitive;
|
||||
const int triangle_method = scene->curve_system_manager->triangle_method;
|
||||
const int resolution = scene->curve_system_manager->resolution;
|
||||
const size_t vert_num = mesh->verts.size();
|
||||
const size_t tri_num = mesh->num_triangles();
|
||||
int used_res = 1;
|
||||
|
||||
/* extract particle hair data - should be combined with connecting to mesh later*/
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include <climits>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
|
||||
#include "util_sky_model.h"
|
||||
#include "util_foreach.h"
|
||||
#include "util_logging.h"
|
||||
#include "util_transform.h"
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
@ -1931,21 +1932,38 @@ GlossyBsdfNode::GlossyBsdfNode()
|
|||
void GlossyBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp glossy BSDF.";
|
||||
distribution = CLOSURE_BSDF_REFLECTION_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_REFLECTION_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX glossy with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
|
@ -1953,7 +1971,8 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
|
|||
bool GlossyBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void GlossyBsdfNode::compile(SVMCompiler& compiler)
|
||||
|
@ -2008,21 +2027,38 @@ GlassBsdfNode::GlassBsdfNode()
|
|||
void GlassBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp glass BSDF.";
|
||||
distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_SHARP_GLASS_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX glass with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
|
@ -2030,7 +2066,8 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
|
|||
bool GlassBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void GlassBsdfNode::compile(SVMCompiler& compiler)
|
||||
|
@ -2085,21 +2122,38 @@ RefractionBsdfNode::RefractionBsdfNode()
|
|||
void RefractionBsdfNode::simplify_settings(Scene *scene)
|
||||
{
|
||||
if(distribution_orig == NBUILTIN_CLOSURES) {
|
||||
roughness_orig = roughness;
|
||||
distribution_orig = distribution;
|
||||
}
|
||||
else {
|
||||
/* By default we use original values, so we don't worry about restoring
|
||||
* defaults later one and can only do override when needed.
|
||||
*/
|
||||
roughness = roughness_orig;
|
||||
distribution = distribution_orig;
|
||||
}
|
||||
Integrator *integrator = scene->integrator;
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(integrator->filter_glossy == 0.0f) {
|
||||
/* Fallback to Sharp closure for Roughness close to 0.
|
||||
* Note: Keep the epsilon in sync with kernel!
|
||||
*/
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
if(!roughness_input->link && roughness <= 1e-4f) {
|
||||
VLOG(1) << "Using sharp refraction BSDF.";
|
||||
distribution = CLOSURE_BSDF_REFRACTION_ID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Rollback to original distribution when filter glossy is used. */
|
||||
distribution = distribution_orig;
|
||||
/* If filter glossy is used we replace Sharp glossy with GGX so we can
|
||||
* benefit from closure blur to remove unwanted noise.
|
||||
*/
|
||||
if(roughness_input->link == NULL &&
|
||||
distribution == CLOSURE_BSDF_REFRACTION_ID)
|
||||
{
|
||||
VLOG(1) << "Using GGX refraction with filter glossy.";
|
||||
distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
roughness = 0.0f;
|
||||
}
|
||||
}
|
||||
closure = distribution;
|
||||
}
|
||||
|
@ -2107,7 +2161,8 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
|
|||
bool RefractionBsdfNode::has_integrator_dependency()
|
||||
{
|
||||
ShaderInput *roughness_input = input("Roughness");
|
||||
return !roughness_input->link && roughness <= 1e-4f;
|
||||
return !roughness_input->link &&
|
||||
(distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
|
||||
}
|
||||
|
||||
void RefractionBsdfNode::compile(SVMCompiler& compiler)
|
||||
|
|
|
@ -388,7 +388,7 @@ public:
|
|||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness;
|
||||
float roughness, roughness_orig;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
|
@ -400,7 +400,7 @@ public:
|
|||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness, IOR;
|
||||
float roughness, roughness_orig, IOR;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
|
@ -412,7 +412,7 @@ public:
|
|||
bool has_integrator_dependency();
|
||||
ClosureType get_closure_type() { return distribution; }
|
||||
|
||||
float roughness, IOR;
|
||||
float roughness, roughness_orig, IOR;
|
||||
ClosureType distribution, distribution_orig;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,8 +31,9 @@ __all__ = (
|
|||
import bpy as _bpy
|
||||
_user_preferences = _bpy.context.user_preferences
|
||||
|
||||
error_duplicates = False
|
||||
error_encoding = False
|
||||
# (name, file, path)
|
||||
error_duplicates = []
|
||||
addons_fake_modules = {}
|
||||
|
||||
|
||||
|
@ -57,12 +58,11 @@ def paths():
|
|||
|
||||
|
||||
def modules_refresh(module_cache=addons_fake_modules):
|
||||
global error_duplicates
|
||||
global error_encoding
|
||||
import os
|
||||
|
||||
error_duplicates = False
|
||||
error_encoding = False
|
||||
error_duplicates.clear()
|
||||
|
||||
path_list = paths()
|
||||
|
||||
|
@ -168,7 +168,7 @@ def modules_refresh(module_cache=addons_fake_modules):
|
|||
if mod.__file__ != mod_path:
|
||||
print("multiple addons with the same name:\n %r\n %r" %
|
||||
(mod.__file__, mod_path))
|
||||
error_duplicates = True
|
||||
error_duplicates.append((mod.bl_info["name"], mod.__file__, mod_path))
|
||||
|
||||
elif mod.__time__ != os.path.getmtime(mod_path):
|
||||
print("reloading addon:",
|
||||
|
|
|
@ -951,6 +951,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()
|
||||
|
||||
|
|
|
@ -1317,11 +1317,18 @@ class USERPREF_PT_addons(Panel):
|
|||
|
||||
# set in addon_utils.modules_refresh()
|
||||
if addon_utils.error_duplicates:
|
||||
self.draw_error(col,
|
||||
"Multiple addons using the same name found!\n"
|
||||
"likely a problem with the script search path.\n"
|
||||
"(see console for details)",
|
||||
)
|
||||
box = col.box()
|
||||
row = box.row()
|
||||
row.label("Multiple addons with the same name found!")
|
||||
row.label(icon='ERROR')
|
||||
box.label("Please delete one of each pair:")
|
||||
for (addon_name, addon_file, addon_path) in addon_utils.error_duplicates:
|
||||
box.separator()
|
||||
sub_col = box.column(align=True)
|
||||
sub_col.label(addon_name + ":")
|
||||
sub_col.label(" " + addon_file)
|
||||
sub_col.label(" " + addon_path)
|
||||
|
||||
|
||||
if addon_utils.error_encoding:
|
||||
self.draw_error(col,
|
||||
|
|
|
@ -222,7 +222,7 @@ typedef uint64_t hash_key;
|
|||
|
||||
typedef struct BArrayInfo {
|
||||
size_t chunk_stride;
|
||||
uint chunk_count;
|
||||
// uint chunk_count; /* UNUSED (other values are derived from this) */
|
||||
|
||||
/* pre-calculated */
|
||||
size_t chunk_byte_size;
|
||||
|
@ -425,12 +425,12 @@ static void bchunk_list_decref(
|
|||
static size_t bchunk_list_data_check(
|
||||
const BChunkList *chunk_list, const uchar *data)
|
||||
{
|
||||
size_t total_size = 0;
|
||||
size_t offset = 0;
|
||||
for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
|
||||
if (memcmp(&data[total_size], cref->link->data, cref->link->data_len) != 0) {
|
||||
if (memcmp(&data[offset], cref->link->data, cref->link->data_len) != 0) {
|
||||
return false;
|
||||
}
|
||||
total_size += cref->link->data_len;
|
||||
offset += cref->link->data_len;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -598,7 +598,6 @@ static void bchunk_list_append_data(
|
|||
{
|
||||
BLI_assert(data_len != 0);
|
||||
|
||||
// printf("data_len: %d\n", data_len);
|
||||
#ifdef USE_MERGE_CHUNKS
|
||||
BLI_assert(data_len <= info->chunk_byte_size_max);
|
||||
|
||||
|
@ -636,7 +635,7 @@ static void bchunk_list_append_data(
|
|||
/* don't run this, instead preemptively avoid creating a chunk only to merge it (above). */
|
||||
#if 0
|
||||
#ifdef USE_MERGE_CHUNKS
|
||||
bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list, chunk_size_min);
|
||||
bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -874,7 +873,7 @@ static void hash_accum_single(hash_key *hash_array, const size_t hash_array_len,
|
|||
|
||||
static hash_key key_from_chunk_ref(
|
||||
const BArrayInfo *info, const BChunkRef *cref,
|
||||
/* avoid reallicating each time */
|
||||
/* avoid reallocating each time */
|
||||
hash_key *hash_store, const size_t hash_store_len)
|
||||
{
|
||||
/* in C, will fill in a reusable array */
|
||||
|
@ -896,7 +895,7 @@ static hash_key key_from_chunk_ref(
|
|||
key = hash_store[0];
|
||||
|
||||
/* cache the key */
|
||||
if (key == HASH_TABLE_KEY_UNSET) {
|
||||
if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
|
||||
key = HASH_TABLE_KEY_FALLBACK;
|
||||
}
|
||||
chunk->key = key;
|
||||
|
@ -931,7 +930,7 @@ static const BChunkRef *table_lookup(
|
|||
size_t size_left = data_len - offset;
|
||||
hash_key key = table_hash_array[((offset - i_table_start) / info->chunk_stride)];
|
||||
size_t key_index = (size_t)(key % (hash_key)table_len);
|
||||
for (BTableRef *tref = table[key_index]; tref; tref = tref->next) {
|
||||
for (const BTableRef *tref = table[key_index]; tref; tref = tref->next) {
|
||||
const BChunkRef *cref = tref->cref;
|
||||
#ifdef USE_HASH_TABLE_KEY_CACHE
|
||||
if (cref->link->key == key)
|
||||
|
@ -1039,10 +1038,8 @@ static BChunkList *bchunk_list_from_data_merge(
|
|||
size_t i_prev = 0;
|
||||
|
||||
#ifdef USE_FASTPATH_CHUNKS_FIRST
|
||||
bool full_match = false;
|
||||
|
||||
{
|
||||
full_match = true;
|
||||
bool full_match = true;
|
||||
|
||||
const BChunkRef *cref = chunk_list_reference->chunk_refs.first;
|
||||
while (i_prev < data_len_original) {
|
||||
|
@ -1430,7 +1427,7 @@ BArrayStore *BLI_array_store_create(
|
|||
BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__);
|
||||
|
||||
bs->info.chunk_stride = stride;
|
||||
bs->info.chunk_count = chunk_count;
|
||||
// bs->info.chunk_count = chunk_count;
|
||||
|
||||
bs->info.chunk_byte_size = chunk_count * stride;
|
||||
#ifdef USE_MERGE_CHUNKS
|
||||
|
|
|
@ -5326,6 +5326,37 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
|||
MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md;
|
||||
msmcd->reader = NULL;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1837,6 +1837,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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1991,6 +1991,7 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
|
|||
case UICURVE_FUNC_HANDLE_AUTO_ANIM: /* set auto-clamped */
|
||||
curvemap_handle_set(cuma, HD_AUTO_ANIM);
|
||||
curvemapping_changed(cumap, false);
|
||||
break;
|
||||
case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
|
||||
cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
|
||||
curvemapping_changed(cumap, false);
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
#include "BKE_camera.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_constraint.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
|
@ -1366,7 +1367,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
|
|||
ob->proxy = NULL;
|
||||
|
||||
ob->parent = NULL;
|
||||
BLI_listbase_clear(&ob->constraints);
|
||||
BKE_constraints_free(&ob->constraints);
|
||||
ob->curve_cache = NULL;
|
||||
ob->transflag &= ~OB_DUPLI;
|
||||
|
||||
|
|
|
@ -181,6 +181,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);
|
||||
|
|
|
@ -2296,3 +2296,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);
|
||||
}
|
||||
|
|
|
@ -249,6 +249,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)
|
||||
|
|
|
@ -5364,8 +5364,12 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
|
|||
if (mmd)
|
||||
multires_force_update(ob);
|
||||
|
||||
if (flush_recalc || (ob->sculpt && ob->sculpt->bm))
|
||||
/* Always for now, so leaving sculpt mode always ensures scene is in
|
||||
* a consistent state.
|
||||
*/
|
||||
if (true || flush_recalc || (ob->sculpt && ob->sculpt->bm)) {
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
if (me->flag & ME_SCULPT_DYNAMIC_TOPOLOGY) {
|
||||
/* Dynamic topology must be disabled before exiting sculpt
|
||||
|
|
|
@ -944,6 +944,7 @@ static void tselem_draw_icon(uiBlock *block, int xmax, float x, float y, TreeSto
|
|||
ICON_DRAW(ICON_MOD_CAST);
|
||||
break;
|
||||
case eModifierType_MeshDeform:
|
||||
case eModifierType_SurfaceDeform:
|
||||
ICON_DRAW(ICON_MOD_MESHDEFORM);
|
||||
break;
|
||||
case eModifierType_Bevel:
|
||||
|
|
|
@ -87,6 +87,8 @@ typedef struct SnapObjectData {
|
|||
typedef struct SnapObjectData_Mesh {
|
||||
SnapObjectData sd;
|
||||
BVHTreeFromMesh *bvh_trees[3];
|
||||
MPoly *mpoly;
|
||||
bool poly_allocated;
|
||||
|
||||
} SnapObjectData_Mesh;
|
||||
|
||||
|
@ -1173,6 +1175,29 @@ static bool snapDerivedMesh(
|
|||
if (treedata->cached && !bvhcache_has_tree(dm->bvhCache, treedata->tree)) {
|
||||
free_bvhtree_from_mesh(treedata);
|
||||
}
|
||||
else {
|
||||
if (!treedata->vert_allocated) {
|
||||
treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
|
||||
}
|
||||
if ((tree_index == 1) && !treedata->edge_allocated) {
|
||||
treedata->edge = DM_get_edge_array(dm, &treedata->vert_allocated);
|
||||
}
|
||||
if (tree_index == 2) {
|
||||
if (!treedata->loop_allocated) {
|
||||
treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
|
||||
}
|
||||
if (!treedata->looptri_allocated) {
|
||||
if (!sod->poly_allocated) {
|
||||
sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
|
||||
}
|
||||
treedata->looptri = DM_get_looptri_array(
|
||||
dm, treedata->vert,
|
||||
sod->mpoly, dm->getNumPolys(dm),
|
||||
treedata->loop, dm->getNumLoops(dm),
|
||||
&treedata->looptri_allocated);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1855,6 +1880,9 @@ static void snap_object_data_free(void *sod_v)
|
|||
free_bvhtree_from_mesh(sod->bvh_trees[i]);
|
||||
}
|
||||
}
|
||||
if (sod->poly_allocated) {
|
||||
MEM_freeN(sod->mpoly);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SNAP_EDIT_MESH:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -606,6 +606,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[]);
|
||||
|
|
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
|
||||
}
|
||||
|
|
|
@ -36,15 +36,15 @@ static void print_mem_saved(const char *id, const BArrayStore *bs)
|
|||
/* -------------------------------------------------------------------- */
|
||||
/* Test Chunks (building data from list of chunks) */
|
||||
|
||||
typedef struct TestChunnk {
|
||||
struct TestChunnk *next, *prev;
|
||||
typedef struct TestChunk {
|
||||
struct TestChunk *next, *prev;
|
||||
const void *data;
|
||||
size_t data_len;
|
||||
} TestChunnk;
|
||||
} TestChunk;
|
||||
|
||||
static TestChunnk *testchunk_list_add(ListBase *lb, const void *data, size_t data_len)
|
||||
static TestChunk *testchunk_list_add(ListBase *lb, const void *data, size_t data_len)
|
||||
{
|
||||
TestChunnk *tc = (TestChunnk *)MEM_mallocN(sizeof(*tc), __func__);
|
||||
TestChunk *tc = (TestChunk *)MEM_mallocN(sizeof(*tc), __func__);
|
||||
tc->data = data;
|
||||
tc->data_len = data_len;
|
||||
BLI_addtail(lb, tc);
|
||||
|
@ -53,7 +53,7 @@ static TestChunnk *testchunk_list_add(ListBase *lb, const void *data, size_t dat
|
|||
}
|
||||
|
||||
#if 0
|
||||
static TestChunnk *testchunk_list_add_copydata(ListBase *lb, const void *data, size_t data_len)
|
||||
static TestChunk *testchunk_list_add_copydata(ListBase *lb, const void *data, size_t data_len)
|
||||
{
|
||||
void *data_copy = MEM_mallocN(data_len, __func__);
|
||||
memcpy(data_copy, data, data_len);
|
||||
|
@ -63,7 +63,7 @@ static TestChunnk *testchunk_list_add_copydata(ListBase *lb, const void *data, s
|
|||
|
||||
static void testchunk_list_free(ListBase *lb)
|
||||
{
|
||||
for (TestChunnk *tc = (TestChunnk *)lb->first, *tb_next; tc; tc = tb_next) {
|
||||
for (TestChunk *tc = (TestChunk *)lb->first, *tb_next; tc; tc = tb_next) {
|
||||
tb_next = tc->next;
|
||||
MEM_freeN((void *)tc->data);
|
||||
MEM_freeN(tc);
|
||||
|
@ -77,12 +77,12 @@ static char *testchunk_as_data(
|
|||
size_t *r_data_len)
|
||||
{
|
||||
size_t data_len = 0;
|
||||
for (TestChunnk *tc = (TestChunnk *)lb->first; tc; tc = tc->next) {
|
||||
for (TestChunk *tc = (TestChunk *)lb->first; tc; tc = tc->next) {
|
||||
data_len += tc->data_len;
|
||||
}
|
||||
char *data = (char *)MEM_mallocN(data_len, __func__);
|
||||
size_t i = 0;
|
||||
for (TestChunnk *tc = (TestChunnk *)lb->first; tc; tc = tc->next) {
|
||||
for (TestChunk *tc = (TestChunk *)lb->first; tc; tc = tc->next) {
|
||||
memcpy(&data[i], tc->data, tc->data_len);
|
||||
data_len += tc->data_len;
|
||||
i += tc->data_len;
|
||||
|
@ -95,7 +95,7 @@ static char *testchunk_as_data(
|
|||
#endif
|
||||
|
||||
static char *testchunk_as_data_array(
|
||||
TestChunnk **tc_array, int tc_array_len,
|
||||
TestChunk **tc_array, int tc_array_len,
|
||||
size_t *r_data_len)
|
||||
{
|
||||
size_t data_len = 0;
|
||||
|
@ -105,7 +105,7 @@ static char *testchunk_as_data_array(
|
|||
char *data = (char *)MEM_mallocN(data_len, __func__);
|
||||
size_t i = 0;
|
||||
for (int tc_index = 0; tc_index < tc_array_len; tc_index++) {
|
||||
TestChunnk *tc = tc_array[tc_index];
|
||||
TestChunk *tc = tc_array[tc_index];
|
||||
memcpy(&data[i], tc->data, tc->data_len);
|
||||
i += tc->data_len;
|
||||
}
|
||||
|
@ -677,9 +677,9 @@ static void random_chunk_mutate_helper(
|
|||
ListBase random_chunks;
|
||||
BLI_listbase_clear(&random_chunks);
|
||||
random_chunk_generate(&random_chunks, chunks_per_buffer, stride, chunk_count, random_seed);
|
||||
TestChunnk **chunks_array = (TestChunnk **)MEM_mallocN(chunks_per_buffer * sizeof(TestChunnk *), __func__);
|
||||
TestChunk **chunks_array = (TestChunk **)MEM_mallocN(chunks_per_buffer * sizeof(TestChunk *), __func__);
|
||||
{
|
||||
TestChunnk *tc = (TestChunnk *)random_chunks.first;
|
||||
TestChunk *tc = (TestChunk *)random_chunks.first;
|
||||
for (int i = 0; i < chunks_per_buffer; i++, tc = tc->next) {
|
||||
chunks_array[i] = tc;
|
||||
}
|
||||
|
@ -692,7 +692,7 @@ static void random_chunk_mutate_helper(
|
|||
{
|
||||
RNG *rng = BLI_rng_new(random_seed);
|
||||
for (int i = 0; i < items_total; i++) {
|
||||
BLI_rng_shuffle_array(rng, chunks_array, sizeof(TestChunnk *), chunks_per_buffer);
|
||||
BLI_rng_shuffle_array(rng, chunks_array, sizeof(TestChunk *), chunks_per_buffer);
|
||||
size_t data_len;
|
||||
char *data = testchunk_as_data_array(chunks_array, chunks_per_buffer, &data_len);
|
||||
BLI_assert(data_len == chunks_per_buffer * chunk_count * stride);
|
||||
|
|
Loading…
Reference in New Issue