Merge branch 'master' into issue_3165
commit
31b8d4710f
|
@ -1163,7 +1163,8 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||||
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
const std::vector<aiVector3D> &curVertices = shapeGeometry->GetVertices();
|
||||||
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
const std::vector<aiVector3D> &curNormals = shapeGeometry->GetNormals();
|
||||||
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
const std::vector<unsigned int> &curIndices = shapeGeometry->GetIndices();
|
||||||
animMesh->mName.Set(FixAnimMeshName(shapeGeometry->Name()));
|
//losing channel name if using shapeGeometry->Name()
|
||||||
|
animMesh->mName.Set(FixAnimMeshName(blendShapeChannel->Name()));
|
||||||
for (size_t j = 0; j < curIndices.size(); j++) {
|
for (size_t j = 0; j < curIndices.size(); j++) {
|
||||||
const unsigned int curIndex = curIndices.at(j);
|
const unsigned int curIndex = curIndices.at(j);
|
||||||
aiVector3D vertex = curVertices.at(j);
|
aiVector3D vertex = curVertices.at(j);
|
||||||
|
|
|
@ -722,7 +722,7 @@ template <class T>
|
||||||
void Accessor::ExtractData(T *&outData) {
|
void Accessor::ExtractData(T *&outData) {
|
||||||
uint8_t *data = GetPointer();
|
uint8_t *data = GetPointer();
|
||||||
if (!data) {
|
if (!data) {
|
||||||
throw DeadlyImportError("GLTF: data is NULL");
|
throw DeadlyImportError("GLTF2: data is nullptr.");
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t elemSize = GetElementSize();
|
const size_t elemSize = GetElementSize();
|
||||||
|
|
|
@ -468,6 +468,22 @@ namespace glTF2 {
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.AddMember("primitives", primitives, w.mAl);
|
obj.AddMember("primitives", primitives, w.mAl);
|
||||||
|
// targetNames
|
||||||
|
if (m.targetNames.size() > 0) {
|
||||||
|
Value extras;
|
||||||
|
extras.SetObject();
|
||||||
|
Value targetNames;
|
||||||
|
targetNames.SetArray();
|
||||||
|
targetNames.Reserve(unsigned(m.targetNames.size()), w.mAl);
|
||||||
|
for (unsigned int n = 0; n < m.targetNames.size(); ++n) {
|
||||||
|
std::string name = m.targetNames[n];
|
||||||
|
Value tname;
|
||||||
|
tname.SetString(name.c_str(), w.mAl);
|
||||||
|
targetNames.PushBack(tname, w.mAl);
|
||||||
|
}
|
||||||
|
extras.AddMember("targetNames", targetNames, w.mAl);
|
||||||
|
obj.AddMember("extras", extras, w.mAl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Write(Value& obj, Node& n, AssetWriter& w)
|
inline void Write(Value& obj, Node& n, AssetWriter& w)
|
||||||
|
|
|
@ -824,9 +824,14 @@ void glTF2Exporter::ExportMeshes()
|
||||||
|
|
||||||
/*************** Targets for blendshapes ****************/
|
/*************** Targets for blendshapes ****************/
|
||||||
if (aim->mNumAnimMeshes > 0) {
|
if (aim->mNumAnimMeshes > 0) {
|
||||||
|
bool bExportTargetNames = this->mProperties->HasPropertyBool("GLTF2_TARGETNAMES_EXP") &&
|
||||||
|
this->mProperties->GetPropertyBool("GLTF2_TARGETNAMES_EXP");
|
||||||
|
|
||||||
p.targets.resize(aim->mNumAnimMeshes);
|
p.targets.resize(aim->mNumAnimMeshes);
|
||||||
for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
|
for (unsigned int am = 0; am < aim->mNumAnimMeshes; ++am) {
|
||||||
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
|
aiAnimMesh *pAnimMesh = aim->mAnimMeshes[am];
|
||||||
|
if (bExportTargetNames)
|
||||||
|
m->targetNames.push_back(pAnimMesh->mName.data);
|
||||||
|
|
||||||
// position
|
// position
|
||||||
if (pAnimMesh->HasPositions()) {
|
if (pAnimMesh->HasPositions()) {
|
||||||
|
|
|
@ -416,6 +416,11 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||||
attr.color[c]->ExtractData(aim->mColors[c]);
|
attr.color[c]->ExtractData(aim->mColors[c]);
|
||||||
}
|
}
|
||||||
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
for (size_t tc = 0; tc < attr.texcoord.size() && tc < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++tc) {
|
||||||
|
if (!attr.texcoord[tc]) {
|
||||||
|
DefaultLogger::get()->warn("Texture coordinate accessor not found or non-contiguous texture coordinate sets.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (attr.texcoord[tc]->count != aim->mNumVertices) {
|
if (attr.texcoord[tc]->count != aim->mNumVertices) {
|
||||||
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
|
DefaultLogger::get()->warn("Texcoord stream size in mesh \"" + mesh.name +
|
||||||
"\" does not match the vertex count");
|
"\" does not match the vertex count");
|
||||||
|
|
|
@ -42,8 +42,8 @@ substituted by assertions ...):
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
from pyassimp import *
|
from pyassimp import load
|
||||||
scene = load('hello.3ds')
|
with load('hello.3ds') as scene:
|
||||||
|
|
||||||
assert len(scene.meshes)
|
assert len(scene.meshes)
|
||||||
mesh = scene.meshes[0]
|
mesh = scene.meshes[0]
|
||||||
|
@ -51,9 +51,6 @@ mesh = scene.meshes[0]
|
||||||
assert len(mesh.vertices)
|
assert len(mesh.vertices)
|
||||||
print(mesh.vertices[0])
|
print(mesh.vertices[0])
|
||||||
|
|
||||||
# don't forget this one, or you will leak!
|
|
||||||
release(scene)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Another example to list the 'top nodes' in a
|
Another example to list the 'top nodes' in a
|
||||||
|
@ -61,14 +58,12 @@ scene:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
|
|
||||||
from pyassimp import *
|
from pyassimp import load
|
||||||
scene = load('hello.3ds')
|
with load('hello.3ds') as scene:
|
||||||
|
|
||||||
for c in scene.rootnode.children:
|
for c in scene.rootnode.children:
|
||||||
print(str(c))
|
print(str(c))
|
||||||
|
|
||||||
release(scene)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
INSTALL
|
INSTALL
|
||||||
|
|
|
@ -49,8 +49,8 @@ substituted by assertions ...):
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
|
||||||
from pyassimp import *
|
from pyassimp import load
|
||||||
scene = load('hello.3ds')
|
with load('hello.3ds') as scene:
|
||||||
|
|
||||||
assert len(scene.meshes)
|
assert len(scene.meshes)
|
||||||
mesh = scene.meshes[0]
|
mesh = scene.meshes[0]
|
||||||
|
@ -58,21 +58,18 @@ substituted by assertions ...):
|
||||||
assert len(mesh.vertices)
|
assert len(mesh.vertices)
|
||||||
print(mesh.vertices[0])
|
print(mesh.vertices[0])
|
||||||
|
|
||||||
# don't forget this one, or you will leak!
|
|
||||||
release(scene)
|
|
||||||
|
|
||||||
Another example to list the 'top nodes' in a scene:
|
Another example to list the 'top nodes' in a scene:
|
||||||
|
|
||||||
.. code:: python
|
.. code:: python
|
||||||
|
|
||||||
|
|
||||||
from pyassimp import *
|
from pyassimp import load
|
||||||
scene = load('hello.3ds')
|
with load('hello.3ds') as scene:
|
||||||
|
|
||||||
for c in scene.rootnode.children:
|
for c in scene.rootnode.children:
|
||||||
print(str(c))
|
print(str(c))
|
||||||
|
|
||||||
release(scene)
|
|
||||||
|
|
||||||
INSTALL
|
INSTALL
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -14,10 +14,13 @@ if sys.version_info >= (3,0):
|
||||||
xrange = range
|
xrange = range
|
||||||
|
|
||||||
|
|
||||||
try: import numpy
|
try:
|
||||||
except ImportError: numpy = None
|
import numpy
|
||||||
|
except ImportError:
|
||||||
|
numpy = None
|
||||||
import logging
|
import logging
|
||||||
import ctypes
|
import ctypes
|
||||||
|
from contextlib import contextmanager
|
||||||
logger = logging.getLogger("pyassimp")
|
logger = logging.getLogger("pyassimp")
|
||||||
# attach default null handler to logger so it doesn't complain
|
# attach default null handler to logger so it doesn't complain
|
||||||
# even if you don't attach another handler to logger
|
# even if you don't attach another handler to logger
|
||||||
|
@ -272,6 +275,13 @@ def recur_pythonize(node, scene):
|
||||||
for c in node.children:
|
for c in node.children:
|
||||||
recur_pythonize(c, scene)
|
recur_pythonize(c, scene)
|
||||||
|
|
||||||
|
def release(scene):
|
||||||
|
'''
|
||||||
|
Release resources of a loaded scene.
|
||||||
|
'''
|
||||||
|
_assimp_lib.release(ctypes.pointer(scene))
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
def load(filename,
|
def load(filename,
|
||||||
file_type = None,
|
file_type = None,
|
||||||
processing = postprocess.aiProcess_Triangulate):
|
processing = postprocess.aiProcess_Triangulate):
|
||||||
|
@ -319,7 +329,10 @@ def load(filename,
|
||||||
raise AssimpError('Could not import file!')
|
raise AssimpError('Could not import file!')
|
||||||
scene = _init(model.contents)
|
scene = _init(model.contents)
|
||||||
recur_pythonize(scene.rootnode, scene)
|
recur_pythonize(scene.rootnode, scene)
|
||||||
return scene
|
try:
|
||||||
|
yield scene
|
||||||
|
finally:
|
||||||
|
release(scene)
|
||||||
|
|
||||||
def export(scene,
|
def export(scene,
|
||||||
filename,
|
filename,
|
||||||
|
@ -373,9 +386,6 @@ def export_blob(scene,
|
||||||
raise AssimpError('Could not export scene to blob!')
|
raise AssimpError('Could not export scene to blob!')
|
||||||
return exportBlobPtr
|
return exportBlobPtr
|
||||||
|
|
||||||
def release(scene):
|
|
||||||
_assimp_lib.release(ctypes.pointer(scene))
|
|
||||||
|
|
||||||
def _finalize_texture(tex, target):
|
def _finalize_texture(tex, target):
|
||||||
setattr(target, "achformathint", tex.achFormatHint)
|
setattr(target, "achformathint", tex.achFormatHint)
|
||||||
if numpy:
|
if numpy:
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -534,3 +534,10 @@ TEST_F(utglTF2ImportExport, norootnode_scenewithoutnodes) {
|
||||||
ASSERT_NE(scene, nullptr);
|
ASSERT_NE(scene, nullptr);
|
||||||
ASSERT_NE(scene->mRootNode, nullptr);
|
ASSERT_NE(scene->mRootNode, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shall not crash!
|
||||||
|
TEST_F(utglTF2ImportExport, norootnode_issue_3269) {
|
||||||
|
Assimp::Importer importer;
|
||||||
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/issue_3269/texcoord_crash.gltf", aiProcess_ValidateDataStructure);
|
||||||
|
ASSERT_EQ(scene, nullptr);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue