Merge commit 'master@6ed15c5a41130b55cb57a43a8a9470a91d38c3d5' into blender2.8
# Conflicts: # source/blender/alembic/intern/abc_exporter.cc
This commit is contained in:
commit
dc27d31a21
|
@ -73,10 +73,9 @@ elseif(WIN32)
|
|||
endif()
|
||||
elseif(APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
|
||||
apple_check_quicktime()
|
||||
# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
|
||||
# apple_check_quicktime()
|
||||
endif()
|
||||
|
|
|
@ -74,10 +74,9 @@ elseif(WIN32)
|
|||
endif()
|
||||
elseif(APPLE)
|
||||
set(WITH_JACK ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
|
||||
set(WITH_CODEC_QUICKTIME ON CACHE BOOL "" FORCE)
|
||||
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
|
||||
apple_check_quicktime()
|
||||
# include("${CMAKE_CURRENT_SOURCE_DIR}/../platform/platform_apple_xcode.cmake")
|
||||
# apple_check_quicktime()
|
||||
endif()
|
||||
|
|
|
@ -121,6 +121,7 @@ struct DerivedMesh *ABC_read_mesh(struct CacheReader *reader,
|
|||
const char **err_str,
|
||||
int flags);
|
||||
|
||||
void CacheReader_incref(struct CacheReader *reader);
|
||||
void CacheReader_free(struct CacheReader *reader);
|
||||
|
||||
struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *handle,
|
||||
|
|
|
@ -68,7 +68,7 @@ static IArchive open_archive(const std::string &filename,
|
|||
#else
|
||||
/* Inspect the file to see whether it's really a HDF5 file. */
|
||||
char header[4]; /* char(0x89) + "HDF" */
|
||||
std::ifstream the_file(filename, std::ios::in | std::ios::binary);
|
||||
std::ifstream the_file(filename.c_str(), std::ios::in | std::ios::binary);
|
||||
if (!the_file) {
|
||||
std::cerr << "Unable to open " << filename << std::endl;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ static bool object_is_smoke_sim(Object *ob)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool object_is_shape(Object *ob)
|
||||
static bool object_type_is_exportable(Object *ob)
|
||||
{
|
||||
switch (ob->type) {
|
||||
case OB_MESH:
|
||||
|
@ -117,6 +117,7 @@ static bool object_is_shape(Object *ob)
|
|||
}
|
||||
|
||||
return true;
|
||||
case OB_EMPTY:
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
case OB_CAMERA:
|
||||
|
@ -387,7 +388,7 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Base *ob_base, O
|
|||
return;
|
||||
}
|
||||
|
||||
if (object_is_shape(ob)) {
|
||||
if (object_type_is_exportable(ob)) {
|
||||
createTransformWriter(ob, parent, dupliObParent);
|
||||
}
|
||||
|
||||
|
@ -557,7 +558,7 @@ void AbcExporter::createShapeWriter(Base *ob_base, Object *dupliObParent)
|
|||
{
|
||||
Object *ob = ob_base->object;
|
||||
|
||||
if (!object_is_shape(ob)) {
|
||||
if (!object_type_is_exportable(ob)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -241,7 +241,6 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
|
|||
invert_m4_m4_safe(inv_mat, m_object->obmat);
|
||||
|
||||
MTFace *mtface = static_cast<MTFace *>(CustomData_get_layer(&dm->faceData, CD_MTFACE));
|
||||
MFace *mface = dm->getTessFaceArray(dm);
|
||||
MVert *mverts = dm->getVertArray(dm);
|
||||
|
||||
ParticleCacheKey **cache = m_psys->childcache;
|
||||
|
@ -253,12 +252,25 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
|
|||
path = cache[p];
|
||||
|
||||
if (part->from == PART_FROM_FACE) {
|
||||
const int num = pc->num;
|
||||
if (part->childtype == PART_CHILD_PARTICLES || !mtface) {
|
||||
/* Face index is unknown for these particles, so just take info
|
||||
* from the parent. */
|
||||
uv_values.push_back(uv_values[pc->parent]);
|
||||
norm_values.push_back(norm_values[pc->parent]);
|
||||
}
|
||||
else {
|
||||
const int num = pc->num;
|
||||
if (num < 0) {
|
||||
ABC_LOG(m_settings.logger)
|
||||
<< "Warning, child particle of hair system " << m_psys->name
|
||||
<< " has unknown face index of geometry of "<< (m_object->id.name + 2)
|
||||
<< ", skipping child hair." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, num, CD_MFACE));
|
||||
MTFace *tface = mtface + num;
|
||||
MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, num, CD_MFACE));
|
||||
MTFace *tface = mtface + num;
|
||||
|
||||
if (mface && mtface) {
|
||||
float r_uv[2], tmpnor[3], mapfw[4], vec[3];
|
||||
|
||||
psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv);
|
||||
|
@ -270,6 +282,14 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
|
|||
norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1]));
|
||||
}
|
||||
}
|
||||
else {
|
||||
ABC_LOG(m_settings.logger)
|
||||
<< "Unknown particle type " << part->from
|
||||
<< " for child hair of system " << m_psys->name
|
||||
<< std::endl;
|
||||
uv_values.push_back(uv_values[pc->parent]);
|
||||
norm_values.push_back(norm_values[pc->parent]);
|
||||
}
|
||||
|
||||
int steps = path->segments + 1;
|
||||
hvertices.push_back(steps);
|
||||
|
|
|
@ -369,4 +369,5 @@ void AbcObjectReader::incref()
|
|||
void AbcObjectReader::decref()
|
||||
{
|
||||
--m_refcount;
|
||||
BLI_assert(m_refcount >= 0);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
|
|||
void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
|
||||
AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
|
||||
|
||||
BLI_strncpy(abc_path->path, object.getFullName().c_str(), PATH_MAX);
|
||||
BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
|
||||
BLI_addtail(object_paths, abc_path);
|
||||
}
|
||||
|
||||
|
@ -377,6 +377,7 @@ bool ABC_export(
|
|||
std::swap(job->settings.frame_start, job->settings.frame_end);
|
||||
}
|
||||
|
||||
bool export_ok = false;
|
||||
if (as_background_job) {
|
||||
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
|
||||
CTX_wm_window(C),
|
||||
|
@ -399,9 +400,12 @@ bool ABC_export(
|
|||
|
||||
export_startjob(job, &stop, &do_update, &progress);
|
||||
export_endjob(job);
|
||||
export_ok = job->export_ok;
|
||||
|
||||
MEM_freeN(job);
|
||||
}
|
||||
|
||||
return job->export_ok;
|
||||
return export_ok;
|
||||
}
|
||||
|
||||
/* ********************** Import file ********************** */
|
||||
|
@ -560,7 +564,7 @@ static std::pair<bool, AbcObjectReader *> visit_object(
|
|||
|
||||
AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
|
||||
MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
|
||||
BLI_strncpy(abc_path->path, full_name.c_str(), PATH_MAX);
|
||||
BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
|
||||
BLI_addtail(&settings.cache_file->object_paths, abc_path);
|
||||
|
||||
/* We can now assign this reader as parent for our children. */
|
||||
|
@ -903,13 +907,14 @@ bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence
|
|||
|
||||
G.is_break = false;
|
||||
|
||||
bool import_ok = false;
|
||||
if (as_background_job) {
|
||||
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
|
||||
CTX_wm_window(C),
|
||||
job->scene,
|
||||
"Alembic Import",
|
||||
WM_JOB_PROGRESS,
|
||||
WM_JOB_TYPE_ALEMBIC);
|
||||
CTX_wm_window(C),
|
||||
job->scene,
|
||||
"Alembic Import",
|
||||
WM_JOB_PROGRESS,
|
||||
WM_JOB_TYPE_ALEMBIC);
|
||||
|
||||
/* setup job */
|
||||
WM_jobs_customdata_set(wm_job, job, import_freejob);
|
||||
|
@ -925,9 +930,12 @@ bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence
|
|||
|
||||
import_startjob(job, &stop, &do_update, &progress);
|
||||
import_endjob(job);
|
||||
import_ok = job->import_ok;
|
||||
|
||||
import_freejob(job);
|
||||
}
|
||||
|
||||
return job->import_ok;
|
||||
return import_ok;
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
@ -1012,6 +1020,12 @@ void CacheReader_free(CacheReader *reader)
|
|||
}
|
||||
}
|
||||
|
||||
void CacheReader_incref(CacheReader *reader)
|
||||
{
|
||||
AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
|
||||
abc_reader->incref();
|
||||
}
|
||||
|
||||
CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
|
||||
{
|
||||
if (object_path[0] == '\0') {
|
||||
|
|
|
@ -4387,19 +4387,17 @@ static void transformcache_copy(bConstraint *con, bConstraint *srccon)
|
|||
BLI_strncpy(dst->object_path, src->object_path, sizeof(dst->object_path));
|
||||
dst->cache_file = src->cache_file;
|
||||
|
||||
if (dst->cache_file) {
|
||||
id_us_plus(&dst->cache_file->id);
|
||||
#ifdef WITH_ALEMBIC
|
||||
if (dst->reader) {
|
||||
CacheReader_incref(dst->reader);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void transformcache_free(bConstraint *con)
|
||||
{
|
||||
bTransformCacheConstraint *data = con->data;
|
||||
|
||||
if (data->cache_file) {
|
||||
id_us_min(&data->cache_file->id);
|
||||
}
|
||||
|
||||
if (data->reader) {
|
||||
#ifdef WITH_ALEMBIC
|
||||
CacheReader_free(data->reader);
|
||||
|
|
|
@ -47,10 +47,12 @@ enum {
|
|||
CACHEFILE_KEYFRAME_DRAWN = (1 << 0),
|
||||
};
|
||||
|
||||
/* Representation of an object's path inside the Alembic file.
|
||||
* Note that this is not a file path. */
|
||||
typedef struct AlembicObjectPath {
|
||||
struct AlembicObjectPath *next, *prev;
|
||||
|
||||
char path[4096]; /* 4096 = PATH_MAX */
|
||||
char path[4096];
|
||||
} AlembicObjectPath;
|
||||
|
||||
typedef struct CacheFile {
|
||||
|
@ -64,7 +66,7 @@ typedef struct CacheFile {
|
|||
* CacheFile. */
|
||||
ListBase object_paths;
|
||||
|
||||
char filepath[4096]; /* 4096 = PATH_MAX */
|
||||
char filepath[1024]; /* 1024 = FILE_MAX */
|
||||
|
||||
char is_sequence;
|
||||
char forward_axis;
|
||||
|
|
|
@ -85,7 +85,7 @@ class SimpleImportTest(unittest.TestCase):
|
|||
for ob in bpy.data.objects:
|
||||
self.assertEqual('Cube' in ob.name, ob.select_get())
|
||||
|
||||
def test_change_path(self):
|
||||
def test_change_path_constraint(self):
|
||||
import math
|
||||
|
||||
fname = 'cube-rotating1.abc'
|
||||
|
@ -122,6 +122,32 @@ class SimpleImportTest(unittest.TestCase):
|
|||
self.assertAlmostEqual(y, 0)
|
||||
self.assertAlmostEqual(z, 0)
|
||||
|
||||
def test_change_path_modifier(self):
|
||||
import math
|
||||
|
||||
fname = 'animated-mesh.abc'
|
||||
abc = self.testdir / fname
|
||||
relpath = bpy.path.relpath(str(abc))
|
||||
|
||||
res = bpy.ops.wm.alembic_import(filepath=str(abc), as_background_job=False)
|
||||
self.assertEqual({'FINISHED'}, res)
|
||||
cube = bpy.context.active_object
|
||||
|
||||
# Check that the file loaded ok.
|
||||
bpy.context.scene.frame_set(6)
|
||||
self.assertAlmostEqual(-1, cube.data.vertices[0].co.x)
|
||||
self.assertAlmostEqual(-1, cube.data.vertices[0].co.y)
|
||||
self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[0].co.z)
|
||||
|
||||
# Change path from absolute to relative. This should not break the animation.
|
||||
bpy.context.scene.frame_set(1)
|
||||
bpy.data.cache_files[fname].filepath = relpath
|
||||
bpy.context.scene.frame_set(6)
|
||||
|
||||
self.assertAlmostEqual(1, cube.data.vertices[3].co.x)
|
||||
self.assertAlmostEqual(1, cube.data.vertices[3].co.y)
|
||||
self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[3].co.z)
|
||||
|
||||
def test_import_long_names(self):
|
||||
# This file contains very long names. The longest name is 4047 chars.
|
||||
bpy.ops.wm.alembic_import(
|
||||
|
|
Loading…
Reference in New Issue