Merge branch 'master' into export_3mf

pull/1598/head
Kim Kulling 2017-11-20 22:36:50 +01:00
commit 9ca7b00280
104 changed files with 3496 additions and 472 deletions

View File

@ -43,9 +43,24 @@ if [ $ANDROID ]; then
ant -v -Dmy.dir=${TRAVIS_BUILD_DIR} -f ${TRAVIS_BUILD_DIR}/port/jassimp/build.xml ndk-jni
fi
if [ "$TRAVIS_OS_NAME" = "linux" ]; then
if [ $ANALYZE = "ON" ] ; then
if [ "$CC" = "clang" ]; then
scan-build cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS=OFF -DASSIMP_BUILD_TESTS=OFF
scan-build --status-bugs make -j2
else
cppcheck --version
generate \
&& cppcheck --error-exitcode=1 -j2 -Iinclude -Icode code 2> cppcheck.txt
if [ -s cppcheck.txt ]; then
cat cppcheck.txt
exit 1
fi
fi
else
generate \
&& make -j4 \
&& sudo make install \
&& sudo ldconfig \
&& (cd test/unit; ../../bin/unit)
fi
fi

View File

@ -4,7 +4,7 @@ language: cpp
cache: ccache
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get update -qq && sudo apt-get install cmake cppcheck && sudo apt-get install cmake python3 && sudo apt-get install -qq freeglut3-dev libxmu-dev libxi-dev ; echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- ; fi
- 'if [ "$TRAVIS_OS_NAME" = "osx" ]; then
if brew ls --versions cmake > /dev/null; then
echo cmake already installed.;
@ -34,11 +34,8 @@ env:
matrix:
include:
- os: linux
compiler: gcc
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
- os: linux
compiler: gcc
env: SHARED_BUILD=ON
compiler: clang
env: ANALYZE=ON
- os: linux
compiler: clang
env: ASAN=ON
@ -48,6 +45,15 @@ matrix:
- os: linux
compiler: clang
env: SHARED_BUILD=ON
- os: linux
compiler: gcc
env: ANALYZE=ON
- os: linux
compiler: gcc
env: DISABLE_EXPORTERS=YES ENABLE_COVERALLS=ON
- os: linux
compiler: gcc
env: SHARED_BUILD=ON
install:
- if [ $ANDROID ]; then wget -c http://dl.google.com/android/ndk/android-ndk-${PV}-${PLATF}.tar.bz2 && tar xf android-ndk-${PV}-${PLATF}.tar.bz2 ; fi

View File

@ -183,8 +183,11 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX )
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
IF( ${OPERATING_SYSTEM} MATCHES "Android")
ELSE()
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
#ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF()
ENDIF()
# Use GNUInstallDirs for Unix predefined directories

View File

@ -310,7 +310,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
message("MD5: ${GCOV_SRC_PATH} = ${GCOV_CONTENTS_MD5}")
# Loads the gcov file as a list of lines.
# (We first open the file and replace all occurences of [] with _
# (We first open the file and replace all occurrences of [] with _
# because CMake will fail to parse a line containing unmatched brackets...
# also the \ to escaped \n in macros screws up things.)
# https://public.kitware.com/Bug/view.php?id=15369
@ -329,7 +329,7 @@ foreach (GCOV_FILE ${GCOV_FILES})
# Instead of trying to parse the source from the
# gcov file, simply read the file contents from the source file.
# (Parsing it from the gcov is hard because C-code uses ; in many places
# which also happens to be the same as the CMake list delimeter).
# which also happens to be the same as the CMake list delimiter).
file(READ ${GCOV_SRC_PATH} GCOV_FILE_SOURCE)
string(REPLACE "\\" "\\\\" GCOV_FILE_SOURCE "${GCOV_FILE_SOURCE}")

View File

@ -249,7 +249,7 @@ private:
/// \fn size_t PostprocessHelper_GetTextureID_Or_Create(const std::string& pID_R, const std::string& pID_G, const std::string& pID_B, const std::string& pID_A)
/// Return converted texture ID which related to specified source textures ID's. If converted texture does not exist then it will be created and ID on new
/// converted texture will be returned. Convertion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
/// converted texture will be returned. Conversion: set of textures from \ref CAMFImporter_NodeElement_Texture to one \ref SPP_Texture and place it
/// to converted textures list.
/// Any of source ID's can be absent(empty string) or even one ID only specified. But at least one ID must be specified.
/// \param [in] pID_R - ID of source "red" texture.
@ -378,7 +378,7 @@ private:
void XML_CheckNode_MustHaveChildren();
/// \fn bool XML_CheckNode_NameEqual(const std::string& pNodeName)
/// Chek if current node name is equal to pNodeName.
/// Check if current node name is equal to pNodeName.
/// \param [in] pNodeName - name for checking.
/// return true if current node name is equal to pNodeName, else - false.
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }

View File

@ -137,7 +137,7 @@ struct CAMFImporter_NodeElement_Instance : public CAMFImporter_NodeElement
{
/****************** Variables ******************/
std::string ObjectID;///< ID of object for instanciation.
std::string ObjectID;///< ID of object for instantiation.
/// \var Delta - The distance of translation in the x, y, or z direction, respectively, in the referenced object's coordinate system, to
/// create an instance of the object in the current constellation.
aiVector3D Delta;

View File

@ -281,8 +281,11 @@ size_t AMFImporter::PostprocessHelper_GetTextureID_Or_Create(const std::string&
{
if(!pID.empty())
{
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++)
converted_texture.Data[idx_target] = src_texture[pSrcTexNum]->Data.at(idx_src);
for(size_t idx_target = pOffset, idx_src = 0; idx_target < tex_size; idx_target += pStep, idx_src++) {
CAMFImporter_NodeElement_Texture* tex = src_texture[pSrcTexNum];
ai_assert(tex);
converted_texture.Data[idx_target] = tex->Data.at(idx_src);
}
}
};// auto CopyTextureData = [&](const size_t pOffset, const size_t pStep, const uint8_t pSrcTexNum) -> void

View File

@ -1021,6 +1021,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
// convert bones, if existing
if (!mesh.mBones.empty()) {
ai_assert(avOutputBones);
// check whether there is a vertex weight for this vertex index
if (iIndex2 < mesh.mBoneVertices.size()) {

View File

@ -171,6 +171,7 @@ inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
t += Write<float>(stream,v.x);
t += Write<float>(stream,v.y);
t += Write<float>(stream,v.z);
ai_assert(t == 16);
return 16;
}

View File

@ -102,7 +102,7 @@ namespace Assimp {
offset += Copy(&data[offset], header.size);
offset += Copy(&data[offset], header.reserved1);
offset += Copy(&data[offset], header.reserved2);
offset += Copy(&data[offset], header.offset);
Copy(&data[offset], header.offset);
file->Write(data, Header::header_size, 1);
}
@ -122,7 +122,7 @@ namespace Assimp {
offset += Copy(&data[offset], dib.x_resolution);
offset += Copy(&data[offset], dib.y_resolution);
offset += Copy(&data[offset], dib.nb_colors);
offset += Copy(&data[offset], dib.nb_important_colors);
Copy(&data[offset], dib.nb_important_colors);
file->Write(data, DIB::dib_size, 1);
}

View File

@ -92,6 +92,12 @@ struct Error : DeadlyImportError {
* descendents. It serves as base class for all data structure fields. */
// -------------------------------------------------------------------------------
struct ElemBase {
ElemBase()
: dna_type(nullptr)
{
// empty
}
virtual ~ElemBase() {
// empty
}

View File

@ -59,7 +59,9 @@ template <> void Structure :: Convert<Object> (
{
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
int temp = 0;
ReadField<ErrorPolicy_Fail>(temp,"type",db);
dest.type = static_cast<Assimp::Blender::Object::Type>(temp);
ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
@ -100,14 +102,21 @@ template <> void Structure :: Convert<MTex> (
) const
{
ReadField<ErrorPolicy_Igno>((short&)dest.mapto,"mapto",db);
ReadField<ErrorPolicy_Igno>((int&)dest.blendtype,"blendtype",db);
int temp_short = 0;
ReadField<ErrorPolicy_Igno>(temp_short,"mapto",db);
dest.mapto = static_cast<Assimp::Blender::MTex::MapType>(temp_short);
int temp = 0;
ReadField<ErrorPolicy_Igno>(temp,"blendtype",db);
dest.blendtype = static_cast<Assimp::Blender::MTex::BlendType>(temp);
ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
ReadFieldPtr<ErrorPolicy_Igno>(dest.tex,"*tex",db);
ReadFieldArray<ErrorPolicy_Igno>(dest.uvname,"uvname",db);
ReadField<ErrorPolicy_Igno>((int&)dest.projx,"projx",db);
ReadField<ErrorPolicy_Igno>((int&)dest.projy,"projy",db);
ReadField<ErrorPolicy_Igno>((int&)dest.projz,"projz",db);
ReadField<ErrorPolicy_Igno>(temp,"projx",db);
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
ReadField<ErrorPolicy_Igno>(temp,"projy",db);
dest.projy = static_cast<Assimp::Blender::MTex::Projection>(temp);
ReadField<ErrorPolicy_Igno>(temp,"projz",db);
dest.projx = static_cast<Assimp::Blender::MTex::Projection>(temp);
ReadField<ErrorPolicy_Igno>(dest.mapping,"mapping",db);
ReadFieldArray<ErrorPolicy_Igno>(dest.ofs,"ofs",db);
ReadFieldArray<ErrorPolicy_Igno>(dest.size,"size",db);
@ -190,7 +199,9 @@ template <> void Structure :: Convert<Lamp> (
{
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
int temp = 0;
ReadField<ErrorPolicy_Fail>(temp,"type",db);
dest.type = static_cast<Assimp::Blender::Lamp::Type>(temp);
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
@ -204,7 +215,8 @@ template <> void Structure :: Convert<Lamp> (
ReadField<ErrorPolicy_Igno>(dest.spotblend,"spotblend",db);
ReadField<ErrorPolicy_Igno>(dest.att1,"att1",db);
ReadField<ErrorPolicy_Igno>(dest.att2,"att2",db);
ReadField<ErrorPolicy_Igno>((int&)dest.falloff_type,"falloff_type",db);
ReadField<ErrorPolicy_Igno>(temp,"falloff_type",db);
dest.falloff_type = static_cast<Assimp::Blender::Lamp::FalloffType>(temp);
ReadField<ErrorPolicy_Igno>(dest.sun_brightness,"sun_brightness",db);
ReadField<ErrorPolicy_Igno>(dest.area_size,"area_size",db);
ReadField<ErrorPolicy_Igno>(dest.area_sizey,"area_sizey",db);
@ -693,8 +705,12 @@ template <> void Structure :: Convert<Tex> (
const FileDatabase& db
) const
{
ReadField<ErrorPolicy_Igno>((short&)dest.imaflag,"imaflag",db);
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
short temp_short = 0;
ReadField<ErrorPolicy_Igno>(temp_short,"imaflag",db);
dest.imaflag = static_cast<Assimp::Blender::Tex::ImageFlags>(temp_short);
int temp = 0;
ReadField<ErrorPolicy_Fail>(temp,"type",db);
dest.type = static_cast<Assimp::Blender::Tex::Type>(temp);
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
db.reader->IncPtr(size);
@ -708,8 +724,11 @@ template <> void Structure :: Convert<Camera> (
{
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
int temp = 0;
ReadField<ErrorPolicy_Warn>(temp,"type",db);
dest.type = static_cast<Assimp::Blender::Camera::Type>(temp);
ReadField<ErrorPolicy_Warn>(temp,"flag",db);
dest.flag = static_cast<Assimp::Blender::Camera::Type>(temp);
ReadField<ErrorPolicy_Warn>(dest.lens,"lens",db);
ReadField<ErrorPolicy_Warn>(dest.sensor_x,"sensor_x",db);
ReadField<ErrorPolicy_Igno>(dest.clipsta,"clipsta",db);

View File

@ -225,6 +225,14 @@ struct TFace : ElemBase {
// -------------------------------------------------------------------------------
struct MTFace : ElemBase {
MTFace()
: flag(0)
, mode(0)
, tile(0)
, unwrap(0)
{
}
float uv[4][2] FAIL;
char flag;
short mode;

View File

@ -141,6 +141,9 @@ void ColladaExporter::WriteFile()
WriteControllerLibrary();
WriteSceneLibrary();
// customized, Writes the animation library
WriteAnimationsLibrary();
// useless Collada fu at the end, just in case we haven't had enough indirections, yet.
mOutput << startstr << "<scene>" << endstr;
@ -1129,6 +1132,7 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
case FloatType_Color: floatsPerElement = 3; break;
case FloatType_Mat4x4: floatsPerElement = 16; break;
case FloatType_Weight: floatsPerElement = 1; break;
case FloatType_Time: floatsPerElement = 1; break;
default:
return;
}
@ -1205,7 +1209,13 @@ void ColladaExporter::WriteFloatArray( const std::string& pIdString, FloatDataTy
case FloatType_Weight:
mOutput << startstr << "<param name=\"WEIGHT\" type=\"float\" />" << endstr;
break;
}
// customized, add animation related
case FloatType_Time:
mOutput << startstr << "<param name=\"TIME\" type=\"float\" />" << endstr;
break;
}
PopTag();
mOutput << startstr << "</accessor>" << endstr;
@ -1235,7 +1245,172 @@ void ColladaExporter::WriteSceneLibrary()
PopTag();
mOutput << startstr << "</library_visual_scenes>" << endstr;
}
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationLibrary(size_t pIndex)
{
const aiAnimation * anim = mScene->mAnimations[pIndex];
if ( anim->mNumChannels == 0 && anim->mNumMeshChannels == 0 && anim->mNumMorphMeshChannels ==0 )
return;
const std::string animation_name_escaped = XMLEscape( anim->mName.C_Str() );
std::string idstr = anim->mName.C_Str();
std::string ending = std::string( "AnimId" ) + to_string(pIndex);
if (idstr.length() >= ending.length()) {
if (0 != idstr.compare (idstr.length() - ending.length(), ending.length(), ending)) {
idstr = idstr + ending;
}
} else {
idstr = idstr + ending;
}
const std::string idstrEscaped = XMLEscape(idstr);
mOutput << startstr << "<animation id=\"" + idstrEscaped + "\" name=\"" + animation_name_escaped + "\">" << endstr;
PushTag();
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a];
// sanity check
if ( nodeAnim->mNumPositionKeys != nodeAnim->mNumScalingKeys || nodeAnim->mNumPositionKeys != nodeAnim->mNumRotationKeys ) continue;
{
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-input");
std::vector<ai_real> frames;
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
frames.push_back(nodeAnim->mPositionKeys[i].mTime);
}
WriteFloatArray( node_idstr , FloatType_Time, (const ai_real*) frames.data(), frames.size());
frames.clear();
}
{
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-output");
std::vector<ai_real> keyframes;
keyframes.reserve(nodeAnim->mNumPositionKeys * 16);
for( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
aiVector3D Scaling = nodeAnim->mScalingKeys[i].mValue;
aiMatrix4x4 ScalingM; // identity
ScalingM[0][0] = Scaling.x; ScalingM[1][1] = Scaling.y; ScalingM[2][2] = Scaling.z;
aiQuaternion RotationQ = nodeAnim->mRotationKeys[i].mValue;
aiMatrix4x4 s = aiMatrix4x4( RotationQ.GetMatrix() );
aiMatrix4x4 RotationM(s.a1, s.a2, s.a3, 0, s.b1, s.b2, s.b3, 0, s.c1, s.c2, s.c3, 0, 0, 0, 0, 1);
aiVector3D Translation = nodeAnim->mPositionKeys[i].mValue;
aiMatrix4x4 TranslationM; // identity
TranslationM[0][3] = Translation.x; TranslationM[1][3] = Translation.y; TranslationM[2][3] = Translation.z;
// Combine the above transformations
aiMatrix4x4 mat = TranslationM * RotationM * ScalingM;
for( size_t j = 0; j < 4; ++j) {
keyframes.insert(keyframes.end(), mat[j], mat[j] + 4);
}
}
WriteFloatArray( node_idstr, FloatType_Mat4x4, (const ai_real*) keyframes.data(), keyframes.size() / 16);
}
{
std::vector<std::string> names;
for ( size_t i = 0; i < nodeAnim->mNumPositionKeys; ++i) {
if ( nodeAnim->mPreState == aiAnimBehaviour_DEFAULT
|| nodeAnim->mPreState == aiAnimBehaviour_LINEAR
|| nodeAnim->mPreState == aiAnimBehaviour_REPEAT
) {
names.push_back( "LINEAR" );
} else if (nodeAnim->mPostState == aiAnimBehaviour_CONSTANT) {
names.push_back( "STEP" );
}
}
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-interpolation");
std::string arrayId = node_idstr + "-array";
mOutput << startstr << "<source id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
PushTag();
// source array
mOutput << startstr << "<Name_array id=\"" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\"> ";
for( size_t a = 0; a < names.size(); ++a ) {
mOutput << names[a] << " ";
}
mOutput << "</Name_array>" << endstr;
mOutput << startstr << "<technique_common>" << endstr;
PushTag();
mOutput << startstr << "<accessor source=\"#" << XMLEscape(arrayId) << "\" count=\"" << names.size() << "\" stride=\"" << 1 << "\">" << endstr;
PushTag();
mOutput << startstr << "<param name=\"INTERPOLATION\" type=\"name\"></param>" << endstr;
PopTag();
mOutput << startstr << "</accessor>" << endstr;
PopTag();
mOutput << startstr << "</technique_common>" << endstr;
PopTag();
mOutput << startstr << "</source>" << endstr;
}
}
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a];
{
// samplers
const std::string node_idstr = nodeAnim->mNodeName.data + std::string("_matrix-sampler");
mOutput << startstr << "<sampler id=\"" << XMLEscape(node_idstr) << "\">" << endstr;
PushTag();
mOutput << startstr << "<input semantic=\"INPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-input") ) << "\"/>" << endstr;
mOutput << startstr << "<input semantic=\"OUTPUT\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-output") ) << "\"/>" << endstr;
mOutput << startstr << "<input semantic=\"INTERPOLATION\" source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-interpolation") ) << "\"/>" << endstr;
PopTag();
mOutput << startstr << "</sampler>" << endstr;
}
}
for (size_t a = 0; a < anim->mNumChannels; ++a) {
const aiNodeAnim * nodeAnim = anim->mChannels[a];
{
// channels
mOutput << startstr << "<channel source=\"#" << XMLEscape( nodeAnim->mNodeName.data + std::string("_matrix-sampler") ) << "\" target=\"" << XMLEscape(nodeAnim->mNodeName.data) << "/matrix\"/>" << endstr;
}
}
PopTag();
mOutput << startstr << "</animation>" << endstr;
}
// ------------------------------------------------------------------------------------------------
void ColladaExporter::WriteAnimationsLibrary()
{
const std::string scene_name_escaped = XMLEscape(mScene->mRootNode->mName.C_Str());
if ( mScene->mNumAnimations > 0 ) {
mOutput << startstr << "<library_animations>" << endstr;
PushTag();
// start recursive write at the root node
for( size_t a = 0; a < mScene->mNumAnimations; ++a)
WriteAnimationLibrary( a );
PopTag();
mOutput << startstr << "</library_animations>" << endstr;
}
}
// ------------------------------------------------------------------------------------------------
// Helper to find a bone by name in the scene
aiBone* findBone( const aiScene* scene, const char * name) {
@ -1251,6 +1426,59 @@ aiBone* findBone( const aiScene* scene, const char * name) {
return NULL;
}
// ------------------------------------------------------------------------------------------------
const aiNode * findBoneNode( const aiNode* aNode, const aiBone* bone)
{
if ( aNode && bone && aNode->mName == bone->mName ) {
return aNode;
}
if ( aNode && bone ) {
for (unsigned int i=0; i < aNode->mNumChildren; ++i) {
aiNode * aChild = aNode->mChildren[i];
const aiNode * foundFromChild = 0;
if ( aChild ) {
foundFromChild = findBoneNode( aChild, bone );
if ( foundFromChild ) return foundFromChild;
}
}
}
return NULL;
}
const aiNode * findSkeletonRootNode( const aiScene* scene, const aiMesh * mesh)
{
std::set<const aiNode*> topParentBoneNodes;
if ( mesh && mesh->mNumBones > 0 ) {
for (unsigned int i=0; i < mesh->mNumBones; ++i) {
aiBone * bone = mesh->mBones[i];
const aiNode * node = findBoneNode( scene->mRootNode, bone);
if ( node ) {
while ( node->mParent && findBone(scene, node->mParent->mName.C_Str() ) != 0 ) {
node = node->mParent;
}
topParentBoneNodes.insert( node );
}
}
}
if ( !topParentBoneNodes.empty() ) {
const aiNode * parentBoneNode = *topParentBoneNodes.begin();
if ( topParentBoneNodes.size() == 1 ) {
return parentBoneNode;
} else {
for (auto it : topParentBoneNodes) {
if ( it->mParent ) return it->mParent;
}
return parentBoneNode;
}
}
return NULL;
}
// ------------------------------------------------------------------------------------------------
// Recursively writes the given node
void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
@ -1278,12 +1506,22 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
}
const std::string node_name_escaped = XMLEscape(pNode->mName.data);
/* // customized, Note! the id field is crucial for inter-xml look up, it cannot be replaced with sid ?!
mOutput << startstr
<< "<node ";
if(is_skeleton_root)
mOutput << "id=\"" << "skeleton_root" << "\" "; // For now, only support one skeleton in a scene.
mOutput << (is_joint ? "s" : "") << "id=\"" << node_name_escaped;
mOutput << "\" name=\"" << node_name_escaped
*/
mOutput << startstr << "<node ";
if(is_skeleton_root) {
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"" : "") ; // For now, only support one skeleton in a scene.
mFoundSkeletonRootNodeID = node_name_escaped;
} else {
mOutput << "id=\"" << node_name_escaped << "\" " << (is_joint ? "sid=\"" + node_name_escaped +"\"": "") ;
}
mOutput << " name=\"" << node_name_escaped
<< "\" type=\"" << node_type
<< "\">" << endstr;
PushTag();
@ -1291,7 +1529,11 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
// write transformation - we can directly put the matrix there
// TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards
const aiMatrix4x4& mat = pNode->mTransformation;
mOutput << startstr << "<matrix sid=\"transform\">";
// customized, sid should be 'matrix' to match with loader code.
//mOutput << startstr << "<matrix sid=\"transform\">";
mOutput << startstr << "<matrix sid=\"matrix\">";
mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " ";
mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " ";
mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " ";
@ -1319,7 +1561,7 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
for( size_t a = 0; a < pNode->mNumMeshes; ++a )
{
const aiMesh* mesh = mScene->mMeshes[pNode->mMeshes[a]];
// do not instanciate mesh if empty. I wonder how this could happen
// do not instantiate mesh if empty. I wonder how this could happen
if( mesh->mNumFaces == 0 || mesh->mNumVertices == 0 )
continue;
@ -1335,7 +1577,13 @@ void ColladaExporter::WriteNode( const aiScene* pScene, aiNode* pNode)
<< endstr;
PushTag();
mOutput << startstr << "<skeleton>#skeleton_root</skeleton>" << endstr;
// note! this mFoundSkeletonRootNodeID some how affects animation, it makes the mesh attaches to armature skeleton root node.
// use the first bone to find skeleton root
const aiNode * skeletonRootBoneNode = findSkeletonRootNode( pScene, mesh );
if ( skeletonRootBoneNode ) {
mFoundSkeletonRootNodeID = XMLEscape( skeletonRootBoneNode->mName.C_Str() );
}
mOutput << startstr << "<skeleton>#" << mFoundSkeletonRootNodeID << "</skeleton>" << endstr;
}
mOutput << startstr << "<bind_material>" << endstr;
PushTag();

View File

@ -114,7 +114,9 @@ protected:
/// Writes the given mesh
void WriteGeometry( size_t pIndex);
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
//enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight };
// customized to add animation related type
enum FloatDataType { FloatType_Vector, FloatType_TexCoord2, FloatType_TexCoord3, FloatType_Color, FloatType_Mat4x4, FloatType_Weight, FloatType_Time };
/// Writes a float array of the given type
void WriteFloatArray( const std::string& pIdString, FloatDataType pType, const ai_real* pData, size_t pElementCount);
@ -122,6 +124,11 @@ protected:
/// Writes the scene library
void WriteSceneLibrary();
// customized, Writes the animation library
void WriteAnimationsLibrary();
void WriteAnimationLibrary( size_t pIndex);
std::string mFoundSkeletonRootNodeID = "skeleton_root"; // will be replaced by found node id in the WriteNode call.
/// Recursively writes the given node
void WriteNode( const aiScene* scene, aiNode* pNode);

View File

@ -302,7 +302,7 @@ struct Accessor
size_t mOffset; // in number of values
size_t mStride; // Stride in number of values
std::vector<std::string> mParams; // names of the data streams in the accessors. Empty string tells to ignore.
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, thats XYZ, for a color RGBA and so on.
size_t mSubOffset[4]; // Suboffset inside the object for the common 4 elements. For a vector, that's XYZ, for a color RGBA and so on.
// For example, SubOffset[0] denotes which of the values inside the object is the vector X component.
std::string mSource; // URL of the source array
mutable const Data* mData; // Pointer to the source array, if resolved. NULL else

View File

@ -1619,7 +1619,7 @@ void ColladaLoader::FillMaterials( const ColladaParser& pParser, aiScene* /*pSce
mat.AddProperty( &effect.mRefractIndex, 1, AI_MATKEY_REFRACTI);
// transparency, a very hard one. seemingly not all files are following the
// specification here (1.0 transparency => completly opaque)...
// specification here (1.0 transparency => completely opaque)...
// therefore, we let the opportunity for the user to manually invert
// the transparency if necessary and we add preliminary support for RGB_ZERO mode
if(effect.mTransparency >= 0.f && effect.mTransparency <= 1.f) {

View File

@ -224,7 +224,7 @@ void ColladaParser::ReadStructure()
}
// ------------------------------------------------------------------------------------------------
// Reads asset informations such as coordinate system informations and legal blah
// Reads asset information such as coordinate system information and legal blah
void ColladaParser::ReadAssetInfo()
{
if( mReader->isEmptyElement())

View File

@ -77,7 +77,7 @@ namespace Assimp
/** Reads the structure of the file */
void ReadStructure();
/** Reads asset informations such as coordinate system informations and legal blah */
/** Reads asset information such as coordinate system information and legal blah */
void ReadAssetInfo();
/** Reads the animation library */

View File

@ -49,7 +49,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h>
#include <stdlib.h>
#ifdef __unix__
#include <sys/param.h>
#include <stdlib.h>

View File

@ -422,7 +422,6 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor,
return true;
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -566,7 +566,6 @@ void Converter::ConvertNodes( uint64_t id, aiNode& parent, const aiMatrix4x4& pa
if ( !name_carrier ) {
nodes_chain.push_back( new aiNode( original_name ) );
name_carrier = nodes_chain.back();
}
//setup metadata on newest node
@ -645,7 +644,6 @@ void Converter::ConvertCameras( const Model& model )
}
}
void Converter::ConvertLight( const Model& model, const Light& light )
{
lights.push_back( new aiLight() );
@ -783,7 +781,6 @@ const char* Converter::NameTransformationComp( TransformationComp comp )
return NULL;
}
const char* Converter::NameTransformationCompProperty( TransformationComp comp )
{
switch ( comp )
@ -2239,9 +2236,17 @@ void Converter::ConvertAnimations()
}
}
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name ) {
if ( node_names.find( fixed_name ) == node_names.end() ) {
FBXImporter::LogError( "Cannot rename node " + fixed_name + ", not existing.");
return;
}
if ( node_names.find( new_name ) != node_names.end() ) {
FBXImporter::LogError( "Cannot rename node " + fixed_name + " to " + new_name +", name already existing." );
return;
}
void Converter::RenameNode( const std::string& fixed_name, const std::string& new_name )
{
ai_assert( node_names.find( fixed_name ) != node_names.end() );
ai_assert( node_names.find( new_name ) == node_names.end() );

View File

@ -45,13 +45,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
#include "FIReader.hpp"
#include "StringUtils.h"
// Workaround for issue #1361
// https://github.com/assimp/assimp/issues/1361
#ifdef __ANDROID__
#define _GLIBCXX_USE_C99 1
# define _GLIBCXX_USE_C99 1
#endif
#include "FIReader.hpp"
#include "Exceptional.h"
#include <assimp/IOStream.hpp>
#include <assimp/types.h>
@ -485,7 +487,9 @@ struct FIFloatDecoder: public FIDecoder {
value.reserve(numFloats);
for (size_t i = 0; i < numFloats; ++i) {
int v = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
value.push_back(*(float*)&v);
float f;
memcpy(&f, &v, 4);
value.push_back(f);
data += 4;
}
return FIFloatValue::create(std::move(value));
@ -503,7 +507,9 @@ struct FIDoubleDecoder: public FIDecoder {
for (size_t i = 0; i < numDoubles; ++i) {
long long b0 = data[0], b1 = data[1], b2 = data[2], b3 = data[3], b4 = data[4], b5 = data[5], b6 = data[6], b7 = data[7];
long long v = (b0 << 56) | (b1 << 48) | (b2 << 40) | (b3 << 32) | (b4 << 24) | (b5 << 16) | (b6 << 8) | b7;
value.push_back(*(double*)&v);
double f;
memcpy(&f, &v, 8);
value.push_back(f);
data += 8;
}
return FIDoubleValue::create(std::move(value));
@ -685,7 +691,7 @@ public:
if (intValue) {
return intValue->value.size() == 1 ? intValue->value.front() : 0;
}
return stoi(attr->value->toString());
return atoi(attr->value->toString().c_str());
}
virtual int getAttributeValueAsInt(int idx) const /*override*/ {
@ -696,7 +702,7 @@ public:
if (intValue) {
return intValue->value.size() == 1 ? intValue->value.front() : 0;
}
return stoi(attributes[idx].value->toString());
return atoi(attributes[idx].value->toString().c_str());
}
virtual float getAttributeValueAsFloat(const char* name) const /*override*/ {
@ -708,7 +714,7 @@ public:
if (floatValue) {
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
}
return stof(attr->value->toString());
return atof(attr->value->toString().c_str());
}
virtual float getAttributeValueAsFloat(int idx) const /*override*/ {
@ -719,7 +725,7 @@ public:
if (floatValue) {
return floatValue->value.size() == 1 ? floatValue->value.front() : 0;
}
return stof(attributes[idx].value->toString());
return atof(attributes[idx].value->toString().c_str());
}
virtual const char* getNodeName() const /*override*/ {
@ -984,13 +990,13 @@ private:
if (index < 32) {
FIDecoder *decoder = defaultDecoder[index];
if (!decoder) {
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
}
return decoder->decode(dataP, len);
}
else {
if (index - 32 >= vocabulary.encodingAlgorithmTable.size()) {
throw DeadlyImportError("Invalid encoding algorithm index " + std::to_string(index));
throw DeadlyImportError("Invalid encoding algorithm index " + to_string(index));
}
std::string uri = vocabulary.encodingAlgorithmTable[index - 32];
auto it = decoderMap.find(uri);
@ -1014,12 +1020,12 @@ private:
alphabet = "0123456789-:TZ ";
break;
default:
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
}
}
else {
if (index - 16 >= vocabulary.restrictedAlphabetTable.size()) {
throw DeadlyImportError("Invalid restricted alphabet index " + std::to_string(index));
throw DeadlyImportError("Invalid restricted alphabet index " + to_string(index));
}
alphabet = vocabulary.restrictedAlphabetTable[index - 16];
}
@ -1027,7 +1033,7 @@ private:
utf8::utf8to32(alphabet.begin(), alphabet.end(), back_inserter(alphabetUTF32));
std::string::size_type alphabetLength = alphabetUTF32.size();
if (alphabetLength < 2) {
throw DeadlyImportError("Invalid restricted alphabet length " + std::to_string(alphabetLength));
throw DeadlyImportError("Invalid restricted alphabet length " + to_string(alphabetLength));
}
std::string::size_type bitsPerCharacter = 1;
while ((1ull << bitsPerCharacter) <= alphabetLength) {

View File

@ -46,11 +46,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_FI_READER_H
#define INCLUDED_AI_FI_READER_H
#include <irrXML.h>
#include <memory>
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
//#include <wchar.h>
#include <string>
#include <memory>
#include <cerrno>
#include <cwchar>
#include <vector>
#include <cstdint>
//#include <stdio.h>
//#include <cstdint>
#include <irrXML.h>
namespace Assimp {
@ -154,7 +160,7 @@ class IOStream;
class FIReader: public irr::io::IIrrXMLReader<char, irr::io::IXMLBase> {
public:
virtual ~FIReader();
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(int idx) const = 0;
virtual std::shared_ptr<const FIValue> getAttributeEncodedValue(const char *name) const = 0;
@ -167,6 +173,13 @@ public:
};// class IFIReader
inline
FIReader::~FIReader() {
// empty
}
}// namespace Assimp
#endif // #ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
#endif // INCLUDED_AI_FI_READER_H

View File

@ -56,98 +56,138 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
FindDegeneratesProcess::FindDegeneratesProcess()
: configRemoveDegenerates (false)
{}
: mConfigRemoveDegenerates( false )
, mConfigCheckAreaOfTriangle( false ){
// empty
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
FindDegeneratesProcess::~FindDegeneratesProcess()
{
FindDegeneratesProcess::~FindDegeneratesProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const
{
bool FindDegeneratesProcess::IsActive( unsigned int pFlags) const {
return 0 != (pFlags & aiProcess_FindDegenerates);
}
// ------------------------------------------------------------------------------------------------
// Setup import configuration
void FindDegeneratesProcess::SetupProperties(const Importer* pImp)
{
void FindDegeneratesProcess::SetupProperties(const Importer* pImp) {
// Get the current value of AI_CONFIG_PP_FD_REMOVE
configRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
mConfigRemoveDegenerates = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_REMOVE,0));
mConfigCheckAreaOfTriangle = ( 0 != pImp->GetPropertyInteger(AI_CONFIG_PP_FD_CHECKAREA) );
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void FindDegeneratesProcess::Execute( aiScene* pScene)
{
void FindDegeneratesProcess::Execute( aiScene* pScene) {
DefaultLogger::get()->debug("FindDegeneratesProcess begin");
for (unsigned int i = 0; i < pScene->mNumMeshes;++i){
ExecuteOnMesh( pScene->mMeshes[i]);
ExecuteOnMesh( pScene->mMeshes[ i ] );
}
DefaultLogger::get()->debug("FindDegeneratesProcess finished");
}
static ai_real heron( ai_real a, ai_real b, ai_real c ) {
ai_real s = (a + b + c) / 2;
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), 0.5 );
return area;
}
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB ) {
const ai_real lx = ( vB.x - vA.x );
const ai_real ly = ( vB.y - vA.y );
const ai_real lz = ( vB.z - vA.z );
ai_real a = lx*lx + ly*ly + lz*lz;
ai_real d = pow( a, 0.5 );
return d;
}
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
ai_real area = 0;
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
ai_real a( distance3D( vA, vB ) );
ai_real b( distance3D( vB, vC ) );
ai_real c( distance3D( vC, vA ) );
area = heron( a, b, c );
return area;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported mesh
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh)
{
void FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
mesh->mPrimitiveTypes = 0;
std::vector<bool> remove_me;
if (configRemoveDegenerates)
remove_me.resize(mesh->mNumFaces,false);
if (mConfigRemoveDegenerates) {
remove_me.resize( mesh->mNumFaces, false );
}
unsigned int deg = 0, limit;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{
for ( unsigned int a = 0; a < mesh->mNumFaces; ++a ) {
aiFace& face = mesh->mFaces[a];
bool first = true;
// check whether the face contains degenerated entries
for (unsigned int i = 0; i < face.mNumIndices; ++i)
{
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
// Polygons with more than 4 points are allowed to have double points, that is
// simulating polygons with holes just with concave polygons. However,
// double points may not come directly after another.
limit = face.mNumIndices;
if (face.mNumIndices > 4)
limit = std::min(limit,i+2);
if (face.mNumIndices > 4) {
limit = std::min( limit, i+2 );
}
for (unsigned int t = i+1; t < limit; ++t)
{
if (mesh->mVertices[face.mIndices[i]] == mesh->mVertices[face.mIndices[t]])
{
for (unsigned int t = i+1; t < limit; ++t) {
if (mesh->mVertices[face.mIndices[ i ] ] == mesh->mVertices[ face.mIndices[ t ] ]) {
// we have found a matching vertex position
// remove the corresponding index from the array
--face.mNumIndices;--limit;
for (unsigned int m = t; m < face.mNumIndices; ++m)
{
face.mIndices[m] = face.mIndices[m+1];
--face.mNumIndices;
--limit;
for (unsigned int m = t; m < face.mNumIndices; ++m) {
face.mIndices[ m ] = face.mIndices[ m+1 ];
}
--t;
// NOTE: we set the removed vertex index to an unique value
// to make sure the developer gets notified when his
// application attemps to access this data.
face.mIndices[face.mNumIndices] = 0xdeadbeef;
face.mIndices[ face.mNumIndices ] = 0xdeadbeef;
if(first)
{
if(first) {
++deg;
first = false;
}
if (configRemoveDegenerates) {
remove_me[a] = true;
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;
goto evil_jump_outside; // hrhrhrh ... yeah, this rocks baby!
}
}
}
if ( mConfigCheckAreaOfTriangle ) {
if ( face.mNumIndices == 3 ) {
ai_real area = calculateAreaOfTriangle( face, mesh );
if ( area < 1e-6 ) {
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;
goto evil_jump_outside;
}
// todo: check for index which is corrupt.
}
}
}
}
// We need to update the primitive flags array of the mesh.
@ -171,7 +211,7 @@ evil_jump_outside:
}
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
if (configRemoveDegenerates && deg) {
if (mConfigRemoveDegenerates && deg) {
unsigned int n = 0;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{

View File

@ -54,15 +54,11 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/** FindDegeneratesProcess: Searches a mesh for degenerated triangles.
*/
class ASSIMP_API FindDegeneratesProcess : public BaseProcess
{
class ASSIMP_API FindDegeneratesProcess : public BaseProcess {
public:
FindDegeneratesProcess();
~FindDegeneratesProcess();
public:
// -------------------------------------------------------------------
// Check whether step is active
bool IsActive( unsigned int pFlags) const;
@ -79,28 +75,53 @@ public:
// Execute step on a given mesh
void ExecuteOnMesh( aiMesh* mesh);
// -------------------------------------------------------------------
/// @brief Enable the instant removal of degenerated primitives
/// @param enabled true for enabled.
void EnableInstantRemoval(bool enabled);
// -------------------------------------------------------------------
/** @brief Enable the instant removal of degenerated primitives
* @param d hm ... difficult to guess what this means, hu!?
*/
void EnableInstantRemoval(bool d) {
configRemoveDegenerates = d;
}
/// @brief Check whether instant removal is currently enabled
/// @return The instant removal state.
bool IsInstantRemoval() const;
// -------------------------------------------------------------------
/** @brief Check whether instant removal is currently enabled
* @return ...
*/
bool IsInstantRemoval() const {
return configRemoveDegenerates;
}
/// @brief Enable the area check for triangles.
/// @param enabled true for enabled.
void EnableAreaCheck( bool enabled );
// -------------------------------------------------------------------
/// @brief Check whether the area check is enabled.
/// @return The area check state.
bool isAreaCheckEnabled() const;
private:
//! Configuration option: remove degenerates faces immediately
bool configRemoveDegenerates;
bool mConfigRemoveDegenerates;
//! Configuration option: check for area
bool mConfigCheckAreaOfTriangle;
};
inline
void FindDegeneratesProcess::EnableInstantRemoval(bool enabled) {
mConfigRemoveDegenerates = enabled;
}
inline
bool FindDegeneratesProcess::IsInstantRemoval() const {
return mConfigRemoveDegenerates;
}
inline
void FindDegeneratesProcess::EnableAreaCheck( bool enabled ) {
mConfigCheckAreaOfTriangle = enabled;
}
inline
bool FindDegeneratesProcess::isAreaCheckEnabled() const {
return mConfigCheckAreaOfTriangle;
}
} // Namespace Assimp
#endif // !! AI_FINDDEGENERATESPROCESS_H_INC

View File

@ -1499,7 +1499,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
IfcVector3 wall_extrusion;
bool do_connections = false, first = true;
bool first = true;
try {
@ -1527,7 +1527,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
if (first) {
first = false;
if (dot > 0.f) {
do_connections = true;
wall_extrusion = t.extrusionDir;
if (is_extruded_side) {
wall_extrusion = - wall_extrusion;
@ -1607,44 +1606,6 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
old_verts.swap(curmesh.verts);
old_vertcnt.swap(curmesh.vertcnt);
// add connection geometry to close the adjacent 'holes' for the openings
// this should only be done from one side of the wall or the polygons
// would be emitted twice.
if (false && do_connections) {
std::vector<IfcVector3> tmpvec;
for(ClipperLib::Polygon& opening : holes_union) {
ai_assert(ClipperLib::Orientation(opening));
tmpvec.clear();
for(ClipperLib::IntPoint& point : opening) {
tmpvec.push_back( minv * IfcVector3(
vmin.x + from_int64(point.X) * vmax.x,
vmin.y + from_int64(point.Y) * vmax.y,
coord));
}
for(size_t i = 0, size = tmpvec.size(); i < size; ++i) {
const size_t next = (i+1)%size;
curmesh.vertcnt.push_back(4);
const IfcVector3& in_world = tmpvec[i];
const IfcVector3& next_world = tmpvec[next];
// Assumptions: no 'partial' openings, wall thickness roughly the same across the wall
curmesh.verts.push_back(in_world);
curmesh.verts.push_back(in_world+wall_extrusion);
curmesh.verts.push_back(next_world+wall_extrusion);
curmesh.verts.push_back(next_world);
}
}
}
std::vector< std::vector<p2t::Point*> > contours;
for(ClipperLib::ExPolygon& clip : clipped) {

View File

@ -394,7 +394,7 @@ void IRRImporter::ComputeAnimations(Node* root, aiNode* real, std::vector<aiNode
angles[1] %= 360;
angles[2] %= 360;
if ( bool(angles[0]*angles[1]) && bool(angles[1]*angles[2]) )
if ( (angles[0]*angles[1]) != 0 && (angles[1]*angles[2]) != 0 )
{
FindSuitableMultiple(angles[0]);
FindSuitableMultiple(angles[1]);

View File

@ -274,10 +274,6 @@ aiReturn Importer::UnregisterLoader(BaseImporter* pImp)
if (it != pimpl->mImporter.end()) {
pimpl->mImporter.erase(it);
std::set<std::string> st;
pImp->GetExtensionList(st);
DefaultLogger::get()->info("Unregistering custom importer: ");
return AI_SUCCESS;
}

View File

@ -223,6 +223,7 @@ float ImproveCacheLocalityProcess::ProcessMesh( aiMesh* pMesh, unsigned int mesh
iMaxRefTris = std::max(iMaxRefTris,*piCur);
}
}
ai_assert(iMaxRefTris > 0);
unsigned int* piCandidates = new unsigned int[iMaxRefTris*3];
unsigned int iCacheMisses = 0;

View File

@ -446,8 +446,6 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
// Iterate through all three arrays at once - it's tricky, but
// rather interesting to implement.
double lasttime = std::min(envl_x->keys[0].time,std::min(envl_y->keys[0].time,envl_z->keys[0].time));
cur_x = envl_x->keys.begin();
cur_y = envl_y->keys.begin();
cur_z = envl_z->keys.begin();
@ -503,7 +501,7 @@ void AnimResolver::GetKeys(std::vector<aiVectorKey>& out,
InterpolateTrack(out,fill,(end_y ? (*cur_x) : (*cur_y)).time);
}
}
lasttime = fill.mTime;
double lasttime = fill.mTime;
out.push_back(fill);
if (lasttime >= (*cur_x).time) {

View File

@ -483,7 +483,7 @@ void LWOImporter::FindVCChannels(const LWO::Surface& surf, LWO::SortedRep& sorte
const LWO::VColorChannel& vc = layer.mVColorChannels[i];
if (surf.mVCMap == vc.name) {
// The vertex color map is explicitely requested by the surface so we need to take special care of it
// The vertex color map is explicitly requested by the surface so we need to take special care of it
for (unsigned int a = 0; a < std::min(next,AI_MAX_NUMBER_OF_COLOR_SETS-1u); ++a) {
out[a+1] = out[a];
}

View File

@ -471,7 +471,7 @@ void LWSImporter::BuildGraph(aiNode* nd, LWS::NodeDesc& src, std::vector<Attachm
// Determine the exact location of a LWO file
std::string LWSImporter::FindLWOFile(const std::string& in)
{
// insert missing directory seperator if necessary
// insert missing directory separator if necessary
std::string tmp;
if (in.length() > 3 && in[1] == ':'&& in[2] != '\\' && in[2] != '/')
{

View File

@ -274,11 +274,9 @@ void MD2Importer::InternReadFile( const std::string& pFile,
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// navigate to the begin of the frame data
BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
m_pcHeader + m_pcHeader->offsetFrames);
pcFrame += configFrameID;
// navigate to the begin of the current frame data
BE_NCONST MD2::Frame* pcFrame = (BE_NCONST MD2::Frame*) ((uint8_t*)
m_pcHeader + m_pcHeader->offsetFrames + (m_pcHeader->frameSize * configFrameID));
// navigate to the begin of the triangle data
MD2::Triangle* pcTriangles = (MD2::Triangle*) ((uint8_t*)

View File

@ -665,7 +665,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
if (0.0f != pcMatIn->Power)
{
iShadingMode = (int)aiShadingMode_Phong;
pcMatOut->AddProperty<float>(&pcMatIn->Power,1,AI_MATKEY_SHININESS);
// pcMatIn is packed, we can't form pointers to its members
float power = pcMatIn->Power;
pcMatOut->AddProperty<float>(&power,1,AI_MATKEY_SHININESS);
}
pcMatOut->AddProperty<int>(&iShadingMode,1,AI_MATKEY_SHADING_MODEL);
}

View File

@ -243,8 +243,6 @@ void NFFImporter::InternReadFile( const std::string& pFile,
if( !file.get())
throw DeadlyImportError( "Failed to open NFF file " + pFile + ".");
unsigned int m = (unsigned int)file->FileSize();
// allocate storage and copy the contents of the file to a memory buffer
// (terminate it with zero)
std::vector<char> mBuffer2;
@ -469,7 +467,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
for (unsigned int a = 0; a < numIdx;++a)
{
SkipSpaces(sz,&sz);
m = ::strtoul10(sz,&sz);
unsigned int m = ::strtoul10(sz,&sz);
if (m >= (unsigned int)tempPositions.size())
{
DefaultLogger::get()->error("NFF2: Vertex index overflow");
@ -635,7 +633,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
for (std::vector<unsigned int>::const_iterator it = tempIdx.begin(), end = tempIdx.end();
it != end;++it)
{
m = *it;
unsigned int m = *it;
// copy colors -vertex color specifications override polygon color specifications
if (hasColor)
@ -735,7 +733,7 @@ void NFFImporter::InternReadFile( const std::string& pFile,
sz = &line[1];out = currentMesh;
}
SkipSpaces(sz,&sz);
m = strtoul10(sz);
unsigned int m = strtoul10(sz);
// ---- flip the face order
out->vertices.resize(out->vertices.size()+m);
@ -1081,7 +1079,9 @@ void NFFImporter::InternReadFile( const std::string& pFile,
// generate the camera
if (hasCam)
{
aiNode* nd = *ppcChildren = new aiNode();
ai_assert(ppcChildren);
aiNode* nd = new aiNode();
*ppcChildren = nd;
nd->mName.Set("<NFF_Camera>");
nd->mParent = root;
@ -1105,13 +1105,15 @@ void NFFImporter::InternReadFile( const std::string& pFile,
// generate light sources
if (!lights.empty())
{
ai_assert(ppcChildren);
pScene->mNumLights = (unsigned int)lights.size();
pScene->mLights = new aiLight*[pScene->mNumLights];
for (unsigned int i = 0; i < pScene->mNumLights;++i,++ppcChildren)
{
const Light& l = lights[i];
aiNode* nd = *ppcChildren = new aiNode();
aiNode* nd = new aiNode();
*ppcChildren = nd;
nd->mParent = root;
nd->mName.length = ::ai_snprintf(nd->mName.data,1024,"<NFF_Light%u>",i);
@ -1128,7 +1130,8 @@ void NFFImporter::InternReadFile( const std::string& pFile,
if (!pScene->mNumMeshes)throw DeadlyImportError("NFF: No meshes loaded");
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials = pScene->mNumMeshes];
for (it = meshes.begin(), m = 0; it != end;++it)
unsigned int m = 0;
for (it = meshes.begin(); it != end;++it)
{
if ((*it).faces.empty())continue;

View File

@ -155,7 +155,7 @@ std::string ObjExporter :: GetMaterialLibName()
// ------------------------------------------------------------------------------------------------
std::string ObjExporter::GetMaterialLibFileName() {
// Remove existing .obj file extention so that the final material file name will be fileName.mtl and not fileName.obj.mtl
// Remove existing .obj file extension so that the final material file name will be fileName.mtl and not fileName.obj.mtl
size_t lastdot = filename.find_last_of('.');
if (lastdot != std::string::npos)
return filename.substr(0, lastdot) + MaterialExt;
@ -258,7 +258,6 @@ void ObjExporter::WriteMaterialFile()
}
}
// ------------------------------------------------------------------------------------------------
void ObjExporter::WriteGeometryFile(bool noMtl) {
WriteHeader(mOutput);
if (!noMtl)
@ -280,8 +279,10 @@ void ObjExporter::WriteGeometryFile(bool noMtl) {
mOutput << "# " << vp.size() << " vertex positions and colors" << endl;
size_t colIdx = 0;
for ( const aiVector3D& v : vp ) {
mOutput << "v " << v.x << " " << v.y << " " << v.z << " " << vc[ colIdx ].r << " " << vc[ colIdx ].g << " " << vc[ colIdx ].b << endl;
colIdx++;
if ( colIdx < vc.size() ) {
mOutput << "v " << v.x << " " << v.y << " " << v.z << " " << vc[ colIdx ].r << " " << vc[ colIdx ].g << " " << vc[ colIdx ].b << endl;
}
++colIdx;
}
}
mOutput << endl;

View File

@ -258,7 +258,7 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
ReadTechnique(Trim(techniqueName), ss, material);
}
// Read informations from a custom material
// Read information from a custom material
/** @todo This "set $x y" does not seem to be a official Ogre material system feature.
Materials can inherit other materials and override texture units by using the (unique)
parent texture unit name in your cloned material.

View File

@ -652,6 +652,8 @@ static void setMatrix( aiNode *node, DataArrayList *transformData ) {
i++;
}
ai_assert(i == 16);
node->mTransformation.a1 = m[ 0 ];
node->mTransformation.a2 = m[ 4 ];
node->mTransformation.a3 = m[ 8 ];

View File

@ -233,10 +233,12 @@ void OptimizeGraphProcess::CollectNewChildren(aiNode* nd, std::list<aiNode*>& no
nd->mNumChildren = static_cast<unsigned int>(child_nodes.size());
aiNode** tmp = nd->mChildren;
for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
aiNode* node = *tmp++ = *it;
node->mParent = nd;
if (nd->mChildren) {
aiNode** tmp = nd->mChildren;
for (std::list<aiNode*>::iterator it = child_nodes.begin(); it != child_nodes.end(); ++it) {
aiNode* node = *tmp++ = *it;
node->mParent = nd;
}
}
nodes_out += static_cast<unsigned int>(child_nodes.size());

View File

@ -671,7 +671,6 @@ bool PLY::ElementInstanceList::ParseInstanceList(
PLYImporter* loader)
{
ai_assert(NULL != pcElement);
const char* pCur = (const char*)&buffer[0];
// parse all elements
if (EEST_INVALID == pcElement->eSemantic || pcElement->alProperties.empty())
@ -683,11 +682,11 @@ bool PLY::ElementInstanceList::ParseInstanceList(
PLY::DOM::SkipComments(buffer);
PLY::DOM::SkipLine(buffer);
streamBuffer.getNextLine(buffer);
pCur = (buffer.empty()) ? NULL : (const char*)&buffer[0];
}
}
else
{
const char* pCur = (const char*)&buffer[0];
// be sure to have enough storage
for (unsigned int i = 0; i < pcElement->NumOccur; ++i)
{

View File

@ -260,7 +260,7 @@ void RAWImporter::InternReadFile( const std::string& pFile,
node = *cc = new aiNode();
node->mParent = pScene->mRootNode;
}
else node = *cc;++cc;
else node = *cc;
node->mName.Set(outGroup.name);
// add all meshes

View File

@ -145,6 +145,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
if (!abReferenced[i]) {
++unreferencedRemoved;
delete pScene->mMaterials[i];
pScene->mMaterials[i] = nullptr;
continue;
}
@ -158,6 +159,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
me = 0;
aiMappingTable[i] = aiMappingTable[a];
delete pScene->mMaterials[i];
pScene->mMaterials[i] = nullptr;
break;
}
}
@ -169,6 +171,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// If the new material count differs from the original,
// we need to rebuild the material list and remap mesh material indexes.
if (iNewNum != pScene->mNumMaterials) {
ai_assert(iNewNum > 0);
aiMaterial** ppcMaterials = new aiMaterial*[iNewNum];
::memset(ppcMaterials,0,sizeof(void*)*iNewNum);
for (unsigned int p = 0; p < pScene->mNumMaterials;++p)

View File

@ -902,6 +902,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
// Add nodes for each object.
for (size_t n=0;n<sib.objs.size();n++)
{
ai_assert(root->mChildren);
SIBObject& obj = sib.objs[n];
aiNode* node = new aiNode;
root->mChildren[childIdx++] = node;
@ -926,6 +927,7 @@ void SIBImporter::InternReadFile(const std::string& pFile,
// (no transformation as the light is already in world space)
for (size_t n=0;n<sib.lights.size();n++)
{
ai_assert(root->mChildren);
aiLight* light = sib.lights[n];
if ( nullptr != light ) {
aiNode* node = new aiNode;

View File

@ -334,7 +334,7 @@ bool STEP::StringToUTF8(std::string& s)
size_t j = basei, jend = s.size()-3;
for (; j < jend; ++j) {
if (s[j] == '\\' && s[j] == 'X' && s[j] == '0' && s[j] == '\\') {
if (s[j] == '\\' && s[j+1] == 'X' && s[j+2] == '0' && s[j+3] == '\\') {
break;
}
}

View File

@ -80,7 +80,9 @@ static bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
return false;
}
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
const char *facecount_pos = buffer + 80;
uint32_t faceCount( 0 );
::memcpy( &faceCount, facecount_pos, sizeof( uint32_t ) );
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
return expectedBinaryFileSize == fileSize;
@ -200,17 +202,11 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
if (IsBinarySTL(mBuffer, fileSize)) {
bMatClr = LoadBinaryFile();
} else if (IsAsciiSTL(mBuffer, fileSize)) {
LoadASCIIFile();
LoadASCIIFile( pScene->mRootNode );
} else {
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
}
// add all created meshes to the single node
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
pScene->mRootNode->mMeshes[i] = i;
// create a single default material, using a white diffuse color for consistency with
// other geometric types (e.g., PLY).
aiMaterial* pcMat = new aiMaterial();
@ -231,11 +227,12 @@ void STLImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
pScene->mMaterials = new aiMaterial*[1];
pScene->mMaterials[0] = pcMat;
}
// ------------------------------------------------------------------------------------------------
// Read an ASCII STL file
void STLImporter::LoadASCIIFile()
{
void STLImporter::LoadASCIIFile( aiNode *root ) {
std::vector<aiMesh*> meshes;
std::vector<aiNode*> nodes;
const char* sz = mBuffer;
const char* bufferEnd = mBuffer + fileSize;
std::vector<aiVector3D> positionBuffer;
@ -247,12 +244,15 @@ void STLImporter::LoadASCIIFile()
positionBuffer.reserve(sizeEstimate);
normalBuffer.reserve(sizeEstimate);
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz)))
{
while (IsAsciiSTL(sz, static_cast<unsigned int>(bufferEnd - sz))) {
std::vector<unsigned int> meshIndices;
aiMesh* pMesh = new aiMesh();
pMesh->mMaterialIndex = 0;
meshIndices.push_back( meshes.size() );
meshes.push_back(pMesh);
aiNode *node = new aiNode;
node->mParent = root;
nodes.push_back( node );
SkipSpaces(&sz);
ai_assert(!IsLineEnd(sz));
@ -265,20 +265,21 @@ void STLImporter::LoadASCIIFile()
size_t temp;
// setup the name of the node
if ((temp = (size_t)(sz-szMe))) {
if ((temp = (size_t)(sz-szMe))) {
if (temp >= MAXLEN) {
throw DeadlyImportError( "STL: Node name too long" );
}
pScene->mRootNode->mName.length = temp;
memcpy(pScene->mRootNode->mName.data,szMe,temp);
pScene->mRootNode->mName.data[temp] = '\0';
std::string name( szMe, temp );
node->mName.Set( name.c_str() );
//pScene->mRootNode->mName.length = temp;
//memcpy(pScene->mRootNode->mName.data,szMe,temp);
//pScene->mRootNode->mName.data[temp] = '\0';
} else {
pScene->mRootNode->mName.Set("<STL_ASCII>");
}
else pScene->mRootNode->mName.Set("<STL_ASCII>");
unsigned int faceVertexCounter = 3;
for ( ;; )
{
for ( ;; ) {
// go to the next token
if(!SkipSpacesAndLineEnd(&sz))
{
@ -300,9 +301,7 @@ void STLImporter::LoadASCIIFile()
SkipSpaces(&sz);
if (strncmp(sz,"normal",6)) {
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
}
else
{
} else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
@ -316,16 +315,11 @@ void STLImporter::LoadASCIIFile()
normalBuffer.push_back(*vn);
normalBuffer.push_back(*vn);
}
}
// vertex 1.50000 1.50000 0.00000
else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
{
} else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6))) { // vertex 1.50000 1.50000 0.00000
if (faceVertexCounter >= 3) {
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
++sz;
}
else
{
} else {
if (sz[6] == '\0') {
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
}
@ -340,17 +334,14 @@ void STLImporter::LoadASCIIFile()
sz = fast_atoreal_move<ai_real>(sz, (ai_real&)vn->z );
faceVertexCounter++;
}
}
else if (!::strncmp(sz,"endsolid",8)) {
} else if (!::strncmp(sz,"endsolid",8)) {
do {
++sz;
} while (!::IsLineEnd(*sz));
SkipSpacesAndLineEnd(&sz);
// finished!
break;
}
// else skip the whole identifier
else {
} else { // else skip the whole identifier
do {
++sz;
} while (!::IsSpaceOrNewLine(*sz));
@ -380,13 +371,22 @@ void STLImporter::LoadASCIIFile()
// now copy faces
addFacesToMesh(pMesh);
// assign the meshes to the current node
pushMeshesToNode( meshIndices, node );
}
// now add the loaded meshes
pScene->mNumMeshes = (unsigned int)meshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
for (size_t i = 0; i < meshes.size(); i++)
{
pScene->mMeshes[i] = meshes[i];
for (size_t i = 0; i < meshes.size(); i++) {
pScene->mMeshes[ i ] = meshes[i];
}
root->mNumChildren = nodes.size();
root->mChildren = new aiNode*[ root->mNumChildren ];
for ( size_t i=0; i<nodes.size(); ++i ) {
root->mChildren[ i ] = nodes[ i ];
}
}
@ -513,4 +513,18 @@ bool STLImporter::LoadBinaryFile()
return false;
}
void STLImporter::pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node ) {
ai_assert( nullptr != node );
if ( meshIndices.empty() ) {
return;
}
node->mNumMeshes = static_cast<unsigned int>( meshIndices.size() );
node->mMeshes = new unsigned int[ meshIndices.size() ];
for ( size_t i=0; i<meshIndices.size(); ++i ) {
node->mMeshes[ i ] = meshIndices[ i ];
}
meshIndices.clear();
}
#endif // !! ASSIMP_BUILD_NO_STL_IMPORTER

View File

@ -48,53 +48,61 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "BaseImporter.h"
#include <assimp/types.h>
namespace Assimp {
// Forward declarations
struct aiNode;
namespace Assimp {
// ---------------------------------------------------------------------------
/** Importer class for the sterolithography STL file format
*/
class STLImporter : public BaseImporter
{
/**
* @brief Importer class for the sterolithography STL file format.
*/
class STLImporter : public BaseImporter {
public:
/**
* @brief STLImporter, the class default constructor.
*/
STLImporter();
/**
* @brief The class destructor.
*/
~STLImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
/**
* @brief Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details.
*/
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const;
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const;
protected:
// -------------------------------------------------------------------
/** Return importer meta information.
* See #BaseImporter::GetInfo for the details
/**
* @brief Return importer meta information.
* See #BaseImporter::GetInfo for the details
*/
const aiImporterDesc* GetInfo () const;
// -------------------------------------------------------------------
/** Imports the given file into the given scene structure.
/**
* @brief Imports the given file into the given scene structure.
* See BaseImporter::InternReadFile() for details
*/
void InternReadFile( const std::string& pFile, aiScene* pScene,
IOSystem* pIOHandler);
// -------------------------------------------------------------------
/** Loads a binary .stl file
/**
* @brief Loads a binary .stl file
* @return true if the default vertex color must be used as material color
*/
*/
bool LoadBinaryFile();
// -------------------------------------------------------------------
/** Loads a ASCII text .stl file
*/
void LoadASCIIFile();
/**
* @brief Loads a ASCII text .stl file
*/
void LoadASCIIFile( aiNode *root );
void pushMeshesToNode( std::vector<unsigned int> &meshIndices, aiNode *node );
protected:

View File

@ -40,10 +40,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/** @file Defines a helper class to evaluate subdivision surfaces.*/
#pragma once
#ifndef AI_SUBDISIVION_H_INC
#define AI_SUBDISIVION_H_INC
#include <cstddef>
#include <assimp/types.h>
struct aiMesh;
namespace Assimp {
@ -52,8 +55,7 @@ namespace Assimp {
/** Helper class to evaluate subdivision surfaces. Different algorithms
* are provided for choice. */
// ------------------------------------------------------------------------------
class Subdivider
{
class ASSIMP_API Subdivider {
public:
/** Enumerates all supported subvidision algorithms */
@ -61,12 +63,7 @@ public:
CATMULL_CLARKE = 0x1
};
public:
virtual ~Subdivider() {
}
public:
virtual ~Subdivider();
// ---------------------------------------------------------------
/** Create a subdivider of a specific type
@ -119,9 +116,13 @@ public:
unsigned int num,
bool discard_input = false) = 0;
private:
};
inline
Subdivider::~Subdivider() {
// empty
}
} // end namespace Assimp

View File

@ -141,9 +141,6 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
throw DeadlyImportError( "TER: Magic string \'TERRAIN\' not found" );
unsigned int x = 0,y = 0,mode = 0;
float rad = 6370.f;
(void)rad;
aiNode* root = pScene->mRootNode = new aiNode();
root->mName.Set("<TERRAGEN.TERRAIN>");
@ -187,7 +184,7 @@ void TerragenImporter::InternReadFile( const std::string& pFile,
// mapping == 1: earth radius
else if (!::strncmp(head,AI_TERR_CHUNK_CRAD,4))
{
rad = reader.GetF4();
reader.GetF4();
}
// mapping mode
else if (!::strncmp(head,AI_TERR_CHUNK_CRVM,4))

View File

@ -317,7 +317,7 @@ void TextureTransformStep::Execute( aiScene* pScene)
info.lockedPos = AI_TT_UV_IDX_LOCK_TBD;
}
// Get all coresponding meshes
// Get all corresponding meshes
for (unsigned int n = 0; n < pScene->mNumMeshes;++n) {
aiMesh* mesh = pScene->mMeshes[n];
if (mesh->mMaterialIndex != i || !mesh->mTextureCoords[0])

View File

@ -334,28 +334,28 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
case 1:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
{
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimtiveTypes "
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
"does not report the POINT flag",i);
}
break;
case 2:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
{
ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimtiveTypes "
ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
"does not report the LINE flag",i);
}
break;
case 3:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
{
ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimtiveTypes "
ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
"does not report the TRIANGLE flag",i);
}
break;
default:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
{
this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimtiveTypes "
this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
"does not report the POLYGON flag",i);
}
break;

View File

@ -91,7 +91,7 @@ protected:
// -------------------------------------------------------------------
/** Report a validation warning. This won't throw an exception,
* control will return to the callera.
* control will return to the caller.
* @param msg Format string for sprintf().*/
void ReportWarning(const char* msg,...);

View File

@ -240,8 +240,12 @@ list<SAttribute> attr_list;
if((rotate_angle != 0) && (rotate_axis.Length() > 0))
attr_list.push_back({"rotation", Rotation2String(rotate_axis, rotate_angle)});
if(!scale.Equal({1, 1, 1})) attr_list.push_back({"scale", Vector2String(scale)});
if(translate.Length() > 0) attr_list.push_back({"translation", Vector2String(translate)});
if(!scale.Equal({1.0,1.0,1.0})) {
attr_list.push_back({"scale", Vector2String(scale)});
}
if(translate.Length() > 0) {
attr_list.push_back({"translation", Vector2String(translate)});
}
}
// Begin node if need.

View File

@ -27,7 +27,7 @@ namespace Assimp
///
/// Pay attention that X3D is format for interactive graphic and simulations for web browsers. aiScene can not contain all features of the X3D format.
/// Also, aiScene contain rasterized-like data. For example, X3D can describe circle all cylinder with one tag, but aiScene contain result of tesselation:
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but thats not good idea at all.
/// vertices, faces etc. Yes, you can use algorithm for detecting figures or shapes, but that's not a good idea at all.
///
/// Supported nodes:
/// Core component:
@ -96,7 +96,7 @@ private:
aiMatrix4x4 Matrix_GlobalToCurrent(const aiNode& pNode) const;
/// \fn void AttrHelper_CommaToPoint(std::string& pStringWithComma)
/// Convert commas in string to points. Thats need because "std::to_string" result depend on locale (regional settings).
/// Convert commas in string to points. That's needed because "std::to_string" result depends on locale (regional settings).
/// \param [in, out] pStringWithComma - reference to string, which must be modified.
void AttrHelper_CommaToPoint(std::string& pStringWithComma) { for(char& c: pStringWithComma) { if(c == ',') c = '.'; } }

View File

@ -176,7 +176,7 @@ namespace Assimp {
/// Ignored attributes: "creaseAngle", "convex", "solid".
///
/// Texture coordinates generating: only for Sphere, Cone, Cylinder. In all other case used PLANE mapping.
/// It's better that Assimp main code has powerfull texture coordinates generator. Then is not needed to
/// It's better that Assimp main code has powerful texture coordinates generator. Then is not needed to
/// duplicate this code in every importer.
///
/// Lighting limitations.
@ -401,10 +401,10 @@ private:
/************** Functions: XML set *************/
/***********************************************/
/// Chek if current node is empty: <node />. If not then exception will throwed.
/// Check if current node is empty: <node />. If not then exception will throwed.
void XML_CheckNode_MustBeEmpty();
/// Chek if current node name is equal to pNodeName.
/// Check if current node name is equal to pNodeName.
/// \param [in] pNodeName - name for checking.
/// return true if current node name is equal to pNodeName, else - false.
bool XML_CheckNode_NameEqual(const std::string& pNodeName) { return mReader->getNodeName() == pNodeName; }

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "X3DImporter.hpp"
// Header files, Assimp.
#include <assimp/ai_assert.h>
#include "StandardShapes.h"
#include "StringUtils.h"
@ -357,6 +358,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
@ -389,6 +391,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, tnemesh.CoordIndex, tnemesh.ColorIndex, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
@ -446,6 +449,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
@ -475,6 +479,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, true);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
@ -550,6 +555,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)
@ -584,6 +590,7 @@ void X3DImporter::Postprocess_BuildMesh(const CX3DImporter_NodeElement& pNodeEle
// copy additional information from children
for(std::list<CX3DImporter_NodeElement*>::iterator ch_it = tnemesh.Child.begin(); ch_it != tnemesh.Child.end(); ch_it++)
{
ai_assert(*pMesh);
if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_Color)
MeshGeometry_AddColor(**pMesh, ((CX3DImporter_NodeElement_Color*)*ch_it)->Value, tnemesh.ColorPerVertex);
else if((*ch_it)->Type == CX3DImporter_NodeElement::ENET_ColorRGBA)

View File

@ -65,14 +65,11 @@ struct Node;
/** The XFileImporter is a worker class capable of importing a scene from a
* DirectX file .x
*/
class XFileImporter : public BaseImporter
{
class XFileImporter : public BaseImporter {
public:
XFileImporter();
~XFileImporter();
public:
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.
* See BaseImporter::CanRead() for details. */

View File

@ -360,7 +360,7 @@ inline const char* fast_atoreal_move(const char* c, Real& out, bool check_comma
// The same but more human.
inline ai_real fast_atof(const char* c)
{
ai_real ret;
ai_real ret(0.0);
fast_atoreal_move<ai_real>(c, ret);
return ret;
}
@ -368,7 +368,7 @@ inline ai_real fast_atof(const char* c)
inline ai_real fast_atof( const char* c, const char** cout)
{
ai_real ret;
ai_real ret(0.0);
*cout = fast_atoreal_move<ai_real>(c, ret);
return ret;
@ -376,7 +376,7 @@ inline ai_real fast_atof( const char* c, const char** cout)
inline ai_real fast_atof( const char** inout)
{
ai_real ret;
ai_real ret(0.0);
*inout = fast_atoreal_move<ai_real>(*inout, ret);
return ret;

View File

@ -88,6 +88,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# endif
#endif
#include "StringUtils.h"
namespace glTF2
{
#ifdef ASSIMP_API
@ -190,15 +192,31 @@ namespace glTF2
#include "./../include/assimp/Compiler/pushpack1.h"
#endif
//! For binary .glb files
//! 12-byte header (+ the JSON + a "body" data section)
struct GLB_Header
{
uint8_t magic[4]; //!< Magic number: "glTF"
uint32_t version; //!< Version number (always 2 as of the last update)
uint32_t length; //!< Total length of the Binary glTF, including header, scene, and body, in bytes
} PACK_STRUCT;
struct GLB_Chunk
{
uint32_t chunkLength;
uint32_t chunkType;
} PACK_STRUCT;
#ifdef ASSIMP_API
#include "./../include/assimp/Compiler/poppack1.h"
#endif
//! Values for the GLB_Header::sceneFormat field
enum SceneFormat
//! Values for the GLB_Chunk::chunkType field
enum ChunkType
{
SceneFormat_JSON = 0
ChunkType_JSON = 0x4E4F534A,
ChunkType_BIN = 0x004E4942
};
//! Values for the mesh primitive modes
@ -239,7 +257,7 @@ namespace glTF2
case ComponentType_UNSIGNED_BYTE:
return 1;
default:
throw DeadlyImportError("GLTF: Unsupported Component Type " + std::to_string(t));
throw DeadlyImportError("GLTF: Unsupported Component Type " + to_string(t));
}
}
@ -418,7 +436,6 @@ namespace glTF2
{
Ref<BufferView> bufferView; //!< The ID of the bufferView. (required)
unsigned int byteOffset; //!< The offset relative to the start of the bufferView in bytes. (required)
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
ComponentType componentType; //!< The datatype of components in the attribute. (required)
unsigned int count; //!< The number of attributes referenced by this accessor. (required)
AttribType::Value type; //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
@ -609,6 +626,7 @@ namespace glTF2
Ref<Buffer> buffer; //! The ID of the buffer. (required)
size_t byteOffset; //! The offset into the buffer in bytes. (required)
size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)
BufferViewTarget target; //! The target that the WebGL buffer should be bound to.
@ -971,6 +989,8 @@ namespace glTF2
Ref<T> Create(const std::string& id)
{ return Create(id.c_str()); }
unsigned int Remove(const char* id);
inline unsigned int Size() const
{ return unsigned(mObjs.size()); }
@ -1082,7 +1102,10 @@ namespace glTF2
}
//! Main function
void Load(const std::string& file);
void Load(const std::string& file, bool isBinary = false);
//! Enables binary encoding on the asset
void SetAsBinary();
//! Search for an available name, starting from the given strings
std::string FindUniqueID(const std::string& str, const char* suffix);
@ -1091,6 +1114,8 @@ namespace glTF2
{ return mBodyBuffer; }
private:
void ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData);
void ReadExtensionsUsed(Document& doc);
IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);

View File

@ -193,6 +193,50 @@ inline void LazyDict<T>::DetachFromDocument()
mDict = 0;
}
template<class T>
unsigned int LazyDict<T>::Remove(const char* id)
{
id = T::TranslateId(mAsset, id);
typename IdDict::iterator it = mObjsById.find(id);
if (it == mObjsById.end()) {
throw DeadlyExportError("GLTF: Object with id \"" + std::string(id) + "\" is not found");
}
const unsigned int index = it->second;
mAsset.mUsedIds[id] = false;
mObjsById.erase(id);
mObjsByOIndex.erase(index);
mObjs.erase(mObjs.begin() + index);
//update index of object in mObjs;
for (size_t i = index; i < mObjs.size(); ++i) {
T *obj = mObjs[i];
obj->index = i;
}
for (IdDict::iterator it = mObjsById.begin(); it != mObjsById.end(); ++it) {
if (it->second <= index) {
continue;
}
mObjsById[it->first] = it->second - 1;
}
for (Dict::iterator it = mObjsByOIndex.begin(); it != mObjsByOIndex.end(); ++it) {
if (it->second <= index) {
continue;
}
mObjsByOIndex[it->first] = it->second - 1;
}
return index;
}
template<class T>
Ref<T> LazyDict<T>::Retrieve(unsigned int i)
{
@ -214,11 +258,11 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i)
Value &obj = (*mDict)[i];
if (!obj.IsObject()) {
throw DeadlyImportError("GLTF: Object at index \"" + std::to_string(i) + "\" is not a JSON object");
throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
}
T* inst = new T();
inst->id = std::string(mDictId) + "_" + std::to_string(i);
inst->id = std::string(mDictId) + "_" + to_string(i);
inst->oIndex = i;
ReadMember(obj, "name", inst->name);
inst->Read(obj, mAsset);
@ -468,6 +512,7 @@ inline void BufferView::Read(Value& obj, Asset& r)
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
byteLength = MemberOrDefault(obj, "byteLength", 0u);
byteStride = MemberOrDefault(obj, "byteStride", 0u);
}
//
@ -482,7 +527,6 @@ inline void Accessor::Read(Value& obj, Asset& r)
}
byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
byteStride = MemberOrDefault(obj, "byteStride", 0u);
componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
count = MemberOrDefault(obj, "count", 0u);
@ -557,7 +601,7 @@ bool Accessor::ExtractData(T*& outData)
const size_t elemSize = GetElementSize();
const size_t totalSize = elemSize * count;
const size_t stride = byteStride ? byteStride : elemSize;
const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;
const size_t targetElemSize = sizeof(T);
ai_assert(elemSize <= targetElemSize);
@ -597,7 +641,7 @@ inline Accessor::Indexer::Indexer(Accessor& acc)
: accessor(acc)
, data(acc.GetPointer())
, elemSize(acc.GetElementSize())
, stride(acc.byteStride ? acc.byteStride : elemSize)
, stride(acc.bufferView && acc.bufferView->byteStride ? acc.bufferView->byteStride : elemSize)
{
}
@ -993,7 +1037,72 @@ inline void AssetMetadata::Read(Document& doc)
// Asset methods implementation
//
inline void Asset::Load(const std::string& pFile)
inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
{
GLB_Header header;
if (stream.Read(&header, sizeof(header), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read the file header");
}
if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
throw DeadlyImportError("GLTF: Invalid binary glTF file");
}
AI_SWAP4(header.version);
asset.version = to_string(header.version);
if (header.version != 2) {
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
}
GLB_Chunk chunk;
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read JSON chunk");
}
AI_SWAP4(chunk.chunkLength);
AI_SWAP4(chunk.chunkType);
if (chunk.chunkType != ChunkType_JSON) {
throw DeadlyImportError("GLTF: JSON chunk missing");
}
// read the scene data
mSceneLength = chunk.chunkLength;
sceneData.resize(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
}
uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
if (padding > 0) {
stream.Seek(padding, aiOrigin_CUR);
}
AI_SWAP4(header.length);
mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
if (header.length >= mBodyOffset) {
if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
throw DeadlyImportError("GLTF: Unable to read BIN chunk");
}
AI_SWAP4(chunk.chunkLength);
AI_SWAP4(chunk.chunkType);
if (chunk.chunkType != ChunkType_BIN) {
throw DeadlyImportError("GLTF: BIN chunk missing");
}
mBodyLength = chunk.chunkLength;
}
else {
mBodyOffset = mBodyLength = 0;
}
}
inline void Asset::Load(const std::string& pFile, bool isBinary)
{
mCurrentAssetDir.clear();
int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
@ -1004,16 +1113,25 @@ inline void Asset::Load(const std::string& pFile)
throw DeadlyImportError("GLTF: Could not open file for reading");
}
mSceneLength = stream->FileSize();
mBodyLength = 0;
// is binary? then read the header
std::vector<char> sceneData;
if (isBinary) {
SetAsBinary(); // also creates the body buffer
ReadBinaryHeader(*stream, sceneData);
}
else {
mSceneLength = stream->FileSize();
mBodyLength = 0;
// read the scene data
std::vector<char> sceneData(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
// read the scene data
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
sceneData.resize(mSceneLength + 1);
sceneData[mSceneLength] = '\0';
if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
throw DeadlyImportError("GLTF: Could not read the file contents");
}
}
@ -1066,6 +1184,15 @@ inline void Asset::Load(const std::string& pFile)
}
}
inline void Asset::SetAsBinary()
{
if (!mBodyBuffer) {
mBodyBuffer = buffers.Create("binary_glTF");
mBodyBuffer->MarkAsSpecial();
}
}
inline void Asset::ReadExtensionsUsed(Document& doc)
{
Value* extsUsed = FindArray(doc, "extensionsUsed");

View File

@ -98,10 +98,6 @@ namespace glTF2 {
obj.AddMember("bufferView", a.bufferView->index, w.mAl);
obj.AddMember("byteOffset", a.byteOffset, w.mAl);
if (a.byteStride != 0) {
obj.AddMember("byteStride", a.byteStride, w.mAl);
}
obj.AddMember("componentType", int(a.componentType), w.mAl);
obj.AddMember("count", a.count, w.mAl);
obj.AddMember("type", StringRef(AttribType::ToString(a.type)), w.mAl);
@ -168,6 +164,9 @@ namespace glTF2 {
obj.AddMember("buffer", bv.buffer->index, w.mAl);
obj.AddMember("byteOffset", static_cast<uint64_t>(bv.byteOffset), w.mAl);
obj.AddMember("byteLength", static_cast<uint64_t>(bv.byteLength), w.mAl);
if (bv.byteStride != 0) {
obj.AddMember("byteStride", bv.byteStride, w.mAl);
}
obj.AddMember("target", int(bv.target), w.mAl);
}

View File

@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
#include <assimp/scene.h>
// Header files, standart library.
// Header files, standard library.
#include <memory>
#include <inttypes.h>
@ -170,13 +170,13 @@ inline Ref<Accessor> ExportData(Asset& a, std::string& meshName, Ref<Buffer>& bu
bv->buffer = buffer;
bv->byteOffset = unsigned(offset);
bv->byteLength = length; //! The target that the WebGL buffer should be bound to.
bv->byteStride = 0;
bv->target = isIndices ? BufferViewTarget_ELEMENT_ARRAY_BUFFER : BufferViewTarget_ARRAY_BUFFER;
// accessor
Ref<Accessor> acc = a.accessors.Create(a.FindUniqueID(meshName, "accessor"));
acc->bufferView = bv;
acc->byteOffset = 0;
acc->byteStride = 0;
acc->componentType = compType;
acc->count = count;
acc->type = typeOut;
@ -402,7 +402,7 @@ void glTF2Exporter::ExportMaterials()
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
const aiMaterial* mat = mScene->mMaterials[i];
std::string id = "material_" + std::to_string(i);
std::string id = "material_" + to_string(i);
Ref<Material> m = mAsset->materials.Create(id);
@ -800,9 +800,33 @@ void glTF2Exporter::MergeMeshes()
for (unsigned int m = nMeshes - 1; m >= 1; --m) {
Ref<Mesh> mesh = node->meshes.at(m);
firstMesh->primitives.insert(firstMesh->primitives.end(), mesh->primitives.begin(), mesh->primitives.end());
//append this mesh's primitives to the first mesh's primitives
firstMesh->primitives.insert(
firstMesh->primitives.end(),
mesh->primitives.begin(),
mesh->primitives.end()
);
node->meshes.erase(node->meshes.begin() + m);
//remove the mesh from the list of meshes
unsigned int removedIndex = mAsset->meshes.Remove(mesh->id.c_str());
//find the presence of the removed mesh in other nodes
for (unsigned int nn = 0; nn < mAsset->nodes.Size(); ++nn) {
Ref<Node> node = mAsset->nodes.Get(nn);
for (unsigned int mm = 0; mm < node->meshes.size(); ++mm) {
Ref<Mesh>& meshRef = node->meshes.at(mm);
unsigned int meshIndex = meshRef.GetIndex();
if (meshIndex == removedIndex) {
node->meshes.erase(node->meshes.begin() + mm);
} else if (meshIndex > removedIndex) {
Ref<Mesh> newMeshRef = mAsset->meshes.Get(meshIndex - 1);
meshRef = newMeshRef;
}
}
}
}
//since we were looping backwards, reverse the order of merged primitives to their original order

View File

@ -74,7 +74,7 @@ static const aiImporterDesc desc = {
"",
"",
"",
aiImporterFlags_SupportTextFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_LimitedSupport | aiImporterFlags_Experimental,
0,
0,
0,
@ -103,13 +103,13 @@ bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool
{
const std::string &extension = GetExtension(pFile);
if (extension != "gltf") // We currently can't read glTF2 binary files (.glb), yet
if (extension != "gltf" && extension != "glb")
return false;
if (checkSig && pIOHandler) {
glTF2::Asset asset(pIOHandler);
try {
asset.Load(pFile);
asset.Load(pFile, extension == "glb");
std::string version = asset.asset.version;
return !version.empty() && version[0] == '2';
} catch (...) {
@ -639,7 +639,7 @@ void glTF2Importer::InternReadFile(const std::string& pFile, aiScene* pScene, IO
// read the asset file
glTF2::Asset asset(pIOHandler);
asset.Load(pFile);
asset.Load(pFile, GetExtension(pFile) == "glb");
//
// Copy the data out

View File

@ -1282,7 +1282,7 @@ inline void Asset::ReadBinaryHeader(IOStream& stream)
}
AI_SWAP4(header.version);
asset.version = std::to_string(header.version);
asset.version = to_string(header.version);
if (header.version != 1) {
throw DeadlyImportError("GLTF: Unsupported binary glTF version");
}

View File

@ -56,7 +56,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
#include <assimp/scene.h>
// Header files, standart library.
// Header files, standard library.
#include <memory>
#include <inttypes.h>

View File

@ -820,6 +820,7 @@ namespace o3dgc
for (unsigned n = 0; n < data_symbols; n++)
total_count += (symbol_count[n] = (symbol_count[n] + 1) >> 1);
}
assert(total_count > 0);
// compute cumulative distribution, decoder table
unsigned k, sum = 0, s = 0;
unsigned scale = 0x80000000U / total_count;
@ -830,6 +831,7 @@ namespace o3dgc
sum += symbol_count[k];
}
else {
assert(decoder_table);
for (k = 0; k < data_symbols; k++) {
distribution[k] = (scale * sum) >> (31 - DM__LengthShift);
sum += symbol_count[k];

View File

@ -231,7 +231,8 @@ namespace o3dgc
float ReadFloat32Bin(unsigned long & position) const
{
unsigned long value = ReadUInt32Bin(position);
float fvalue = *((float *)(&value));
float fvalue;
memcpy(&fvalue, &value, 4);
return fvalue;
}
unsigned long ReadUInt32Bin(unsigned long & position) const
@ -261,7 +262,8 @@ namespace o3dgc
void WriteFloat32ASCII(float value)
{
unsigned long uiValue = *((unsigned long *)(&value));
unsigned long uiValue;
memcpy(&uiValue, &value, 4);
WriteUInt32ASCII(uiValue);
}
void WriteUInt32ASCII(unsigned long position, unsigned long value)
@ -314,7 +316,8 @@ namespace o3dgc
float ReadFloat32ASCII(unsigned long & position) const
{
unsigned long value = ReadUInt32ASCII(position);
float fvalue = *((float *)(&value));
float fvalue;
memcpy(&fvalue, &value, 4);
return fvalue;
}
unsigned long ReadUInt32ASCII(unsigned long & position) const

View File

@ -0,0 +1,96 @@
# Copyright (c) 2014, Pavel Rojtberg
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
# Usage:
# 1. place AndroidNdkGdb.cmake somewhere inside ${CMAKE_MODULE_PATH}
# 2. inside your project add
#
# include(AndroidNdkGdb)
# android_ndk_gdb_enable()
# # for each target
# add_library(MyLibrary ...)
# android_ndk_gdb_debuggable(MyLibrary)
# add gdbserver and general gdb configuration to project
# also create a mininal NDK skeleton so ndk-gdb finds the paths
#
# the optional parameter defines the path to the android project.
# uses PROJECT_SOURCE_DIR by default.
macro(android_ndk_gdb_enable)
if(ANDROID)
# create custom target that depends on the real target so it gets executed afterwards
add_custom_target(NDK_GDB ALL)
if(${ARGC})
set(ANDROID_PROJECT_DIR ${ARGV0})
else()
set(ANDROID_PROJECT_DIR ${PROJECT_SOURCE_DIR})
endif()
set(NDK_GDB_SOLIB_PATH ${ANDROID_PROJECT_DIR}/obj/local/${ANDROID_NDK_ABI_NAME}/)
file(MAKE_DIRECTORY ${NDK_GDB_SOLIB_PATH})
# 1. generate essential Android Makefiles
file(MAKE_DIRECTORY ${ANDROID_PROJECT_DIR}/jni)
if(NOT EXISTS ${ANDROID_PROJECT_DIR}/jni/Android.mk)
file(WRITE ${ANDROID_PROJECT_DIR}/jni/Android.mk "APP_ABI := ${ANDROID_NDK_ABI_NAME}\n")
endif()
if(NOT EXISTS ${ANDROID_PROJECT_DIR}/jni/Application.mk)
file(WRITE ${ANDROID_PROJECT_DIR}/jni/Application.mk "APP_ABI := ${ANDROID_NDK_ABI_NAME}\n")
endif()
# 2. generate gdb.setup
get_directory_property(PROJECT_INCLUDES DIRECTORY ${PROJECT_SOURCE_DIR} INCLUDE_DIRECTORIES)
string(REGEX REPLACE ";" " " PROJECT_INCLUDES "${PROJECT_INCLUDES}")
file(WRITE ${LIBRARY_OUTPUT_PATH}/gdb.setup "set solib-search-path ${NDK_GDB_SOLIB_PATH}\n")
file(APPEND ${LIBRARY_OUTPUT_PATH}/gdb.setup "directory ${PROJECT_INCLUDES}\n")
# 3. copy gdbserver executable
file(COPY ${ANDROID_NDK}/prebuilt/android-${ANDROID_ARCH_NAME}/gdbserver/gdbserver DESTINATION ${LIBRARY_OUTPUT_PATH})
endif()
endmacro()
# register a target for remote debugging
# copies the debug version to NDK_GDB_SOLIB_PATH then strips symbols of original
macro(android_ndk_gdb_debuggable TARGET_NAME)
if(ANDROID)
get_property(TARGET_LOCATION TARGET ${TARGET_NAME} PROPERTY LOCATION)
# create custom target that depends on the real target so it gets executed afterwards
add_dependencies(NDK_GDB ${TARGET_NAME})
# 4. copy lib to obj
add_custom_command(TARGET NDK_GDB POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different ${TARGET_LOCATION} ${NDK_GDB_SOLIB_PATH})
# 5. strip symbols
add_custom_command(TARGET NDK_GDB POST_BUILD COMMAND ${CMAKE_STRIP} ${TARGET_LOCATION})
endif()
endmacro()

View File

@ -0,0 +1,58 @@
# Copyright (c) 2014, Pavel Rojtberg
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
# contributors may be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
macro(android_ndk_import_module_cpufeatures)
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/cpufeatures)
add_library(cpufeatures ${ANDROID_NDK}/sources/android/cpufeatures/cpu-features.c)
target_link_libraries(cpufeatures dl)
endif()
endmacro()
macro(android_ndk_import_module_native_app_glue)
if(ANDROID)
include_directories(${ANDROID_NDK}/sources/android/native_app_glue)
add_library(native_app_glue ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
target_link_libraries(native_app_glue log)
endif()
endmacro()
macro(android_ndk_import_module_ndk_helper)
if(ANDROID)
android_ndk_import_module_cpufeatures()
android_ndk_import_module_native_app_glue()
include_directories(${ANDROID_NDK}/sources/android/ndk_helper)
file(GLOB _NDK_HELPER_SRCS ${ANDROID_NDK}/sources/android/ndk_helper/*.cpp ${ANDROID_NDK}/sources/android/ndk_helper/gl3stub.c)
add_library(ndk_helper ${_NDK_HELPER_SRCS})
target_link_libraries(ndk_helper log android EGL GLESv2 cpufeatures native_app_glue)
unset(_NDK_HELPER_SRCS)
endif()
endmacro()

View File

@ -0,0 +1,240 @@
# android-cmake
CMake is great, and so is Android. This is a collection of CMake scripts that may be useful to the Android NDK community. It is based on experience from porting OpenCV library to Android: http://opencv.org/platforms/android.html
Main goal is to share these scripts so that devs that use CMake as their build system may easily compile native code for Android.
## TL;DR
cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake \
-DANDROID_NDK=<ndk_path> \
-DCMAKE_BUILD_TYPE=Release \
-DANDROID_ABI="armeabi-v7a with NEON" \
<source_path>
cmake --build .
One-liner:
cmake -DCMAKE_TOOLCHAIN_FILE=android.toolchain.cmake -DANDROID_NDK=<ndk_path> -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="armeabi-v7a with NEON" <source_path> && cmake --build .
_android-cmake_ will search for your NDK install in the following order:
1. Value of `ANDROID_NDK` CMake variable;
1. Value of `ANDROID_NDK` environment variable;
1. Search under paths from `ANDROID_NDK_SEARCH_PATHS` CMake variable;
1. Search platform specific locations (home folder, Windows "Program Files", etc).
So if you have installed the NDK as `~/android-ndk-r10d` then _android-cmake_ will locate it automatically.
## Getting started
To build a cmake-based C/C++ project for Android you need:
* Android NDK (>= r5) http://developer.android.com/tools/sdk/ndk/index.html
* CMake (>= v2.6.3, >= v2.8.9 recommended) http://www.cmake.org/download
The _android-cmake_ is also capable to build with NDK from AOSP or Linaro Android source tree, but you may be required to manually specify path to `libm` binary to link with.
## Difference from traditional CMake
Folowing the _ndk-build_ the _android-cmake_ supports **only two build targets**:
* `-DCMAKE_BUILD_TYPE=Release`
* `-DCMAKE_BUILD_TYPE=Debug`
So don't even try other targets that can be found in CMake documentation and don't forget to explicitly specify `Release` or `Debug` because CMake builds without a build configuration by default.
## Difference from _ndk-build_
* Latest GCC available in NDK is used as the default compiler;
* `Release` builds with `-O3` instead of `-Os`;
* `Release` builds without debug info (without `-g`) (because _ndk-build_ always creates a stripped version but cmake delays this for `install/strip` target);
* `-fsigned-char` is added to compiler flags to make `char` signed by default as it is on x86/x86_64;
* GCC's stack protector is not used neither in `Debug` nor `Release` configurations;
* No builds for multiple platforms (e.g. building for both arm and x86 require to run cmake twice with different parameters);
* No file level Neon via `.neon` suffix;
The following features of _ndk-build_ are not supported by the _android-cmake_ yet:
* `armeabi-v7a-hard` ABI
* `libc++_static`/`libc++_shared` STL runtime
## Basic options
Similarly to the NDK build system _android-cmake_ allows to select between several compiler toolchains and target platforms. Most of the options can be set either as cmake arguments: `-D<NAME>=<VALUE>` or as environment variables:
* **ANDROID_NDK** - path to the Android NDK. If not set then _android-cmake_ will search for the most recent version of supported NDK in commonly used locations;
* **ANDROID_ABI** - specifies the target Application Binary Interface (ABI). This option nearly matches to the APP_ABI variable used by ndk-build tool from Android NDK. If not specified then set to `armeabi-v7a`. Possible target names are:
* `armeabi` - ARMv5TE based CPU with software floating point operations;
* **`armeabi-v7a`** - ARMv7 based devices with hardware FPU instructions (VFPv3_D16);
* `armeabi-v7a with NEON` - same as armeabi-v7a, but sets NEON as floating-point unit;
* `armeabi-v7a with VFPV3` - same as armeabi-v7a, but sets VFPv3_D32 as floating-point unit;
* `armeabi-v6 with VFP` - tuned for ARMv6 processors having VFP;
* `x86` - IA-32 instruction set
* `mips` - MIPS32 instruction set
* `arm64-v8a` - ARMv8 AArch64 instruction set - only for NDK r10 and newer
* `x86_64` - Intel64 instruction set (r1) - only for NDK r10 and newer
* `mips64` - MIPS64 instruction set (r6) - only for NDK r10 and newer
* **ANDROID_NATIVE_API_LEVEL** - level of android API to build for. Can be set either to full name (example: `android-8`) or a numeric value (example: `17`). The default API level depends on the target ABI:
* `android-8` for ARM;
* `android-9` for x86 and MIPS;
* `android-21` for 64-bit ABIs.
Building for `android-L` is possible only when it is explicitly selected.
* **ANDROID_TOOLCHAIN_NAME** - the name of compiler toolchain to be used. This option allows to select between different GCC and Clang versions. The list of possible values depends on the NDK version and will be printed by toolchain file if an invalid value is set. By default _android-cmake_ selects the most recent version of GCC which can build for specified `ANDROID_ABI`.
Example values are:
* `aarch64-linux-android-4.9`
* `aarch64-linux-android-clang3.5`
* `arm-linux-androideabi-4.8`
* `arm-linux-androideabi-4.9`
* `arm-linux-androideabi-clang3.5`
* `mips64el-linux-android-4.9`
* `mipsel-linux-android-4.8`
* `x86-4.9`
* `x86_64-4.9`
* etc.
* **ANDROID_STL** - the name of C++ runtime to use. The default is `gnustl_static`.
* `none` - do not configure the runtime.
* `system` - use the default minimal system C++ runtime library.
* Implies `-fno-rtti -fno-exceptions`.
* `system_re` - use the default minimal system C++ runtime library.
* Implies `-frtti -fexceptions`.
* `gabi++_static` - use the GAbi++ runtime as a static library.
* Implies `-frtti -fno-exceptions`.
* Available for NDK r7 and newer.
* `gabi++_shared` - use the GAbi++ runtime as a shared library.
* Implies `-frtti -fno-exceptions`.
* Available for NDK r7 and newer.
* `stlport_static` - use the STLport runtime as a static library.
* Implies `-fno-rtti -fno-exceptions` for NDK before r7.
* Implies `-frtti -fno-exceptions` for NDK r7 and newer.
* `stlport_shared` - use the STLport runtime as a shared library.
* Implies `-fno-rtti -fno-exceptions` for NDK before r7.
* Implies `-frtti -fno-exceptions` for NDK r7 and newer.
* **`gnustl_static`** - use the GNU STL as a static library.
* Implies `-frtti -fexceptions`.
* `gnustl_shared` - use the GNU STL as a shared library.
* Implies `-frtti -fno-exceptions`.
* Available for NDK r7b and newer.
* Silently degrades to `gnustl_static` if not available.
* **NDK_CCACHE** - path to `ccache` executable. If not set then initialized from `NDK_CCACHE` environment variable.
## Advanced _android-cmake_ options
Normally _android-cmake_ users are not supposed to touch these variables but they might be useful to workaround some build issues:
* **ANDROID_FORCE_ARM_BUILD** = `OFF` - generate 32-bit ARM instructions instead of Thumb. Applicable only for arm ABIs and is forced to be `ON` for `armeabi-v6 with VFP`;
* **ANDROID_NO_UNDEFINED** = `ON` - show all undefined symbols as linker errors;
* **ANDROID_SO_UNDEFINED** = `OFF` - allow undefined symbols in shared libraries;
* actually it is turned `ON` by default for NDK older than `r7`
* **ANDROID_STL_FORCE_FEATURES** = `ON` - automatically configure rtti and exceptions support based on C++ runtime;
* **ANDROID_NDK_LAYOUT** = `RELEASE` - inner layout of Android NDK, should be detected automatically. Possible values are:
* `RELEASE` - public releases from Google;
* `LINARO` - NDK from Linaro project;
* `ANDROID` - NDK from AOSP.
* **ANDROID_FUNCTION_LEVEL_LINKING** = `ON` - enables saparate putting each function and data items into separate sections and enable garbage collection of unused input sections at link time (`-fdata-sections -ffunction-sections -Wl,--gc-sections`);
* **ANDROID_GOLD_LINKER** = `ON` - use gold linker with GCC 4.6 for NDK r8b and newer (only for ARM and x86);
* **ANDROID_NOEXECSTACK** = `ON` - enables or disables stack execution protection code (`-Wl,-z,noexecstack`);
* **ANDROID_RELRO** = `ON` - Enables RELRO - a memory corruption mitigation technique (`-Wl,-z,relro -Wl,-z,now`);
* **ANDROID_LIBM_PATH** - path to `libm.so` (set to something like `$(TOP)/out/target/product/<product_name>/obj/lib/libm.so`) to workaround unresolved `sincos`.
## Fine-tuning `CMakeLists.txt` for _android-cmake_
### Recognizing Android build
_android-cmake_ defines `ANDROID` CMake variable which can be used to add Android-specific stuff:
if (ANDROID)
message(STATUS "Hello from Android build!")
endif()
The recommended way to identify ARM/MIPS/x86 architecture is examining `CMAKE_SYSTEM_PROCESSOR` which is set to the appropriate value:
* `armv5te` - for `armeabi` ABI
* `armv6` - for `armeabi-v6 with VFP` ABI
* `armv7-a` - for `armeabi-v7a`, `armeabi-v7a with VFPV3` and `armeabi-v7a with NEON` ABIs
* `aarch64` - for `arm64-v8a` ABI
* `i686` - for `x86` ABI
* `x86_64` - for `x86_64` ABI
* `mips` - for `mips` ABI
* `mips64` - for `mips64` ABI
Other variables that are set by _android-cmake_ and can be used for the fine-grained build configuration are:
* `NEON` - set if target ABI supports Neon;
* `ANDROID_NATIVE_API_LEVEL` - native Android API level we are building for (note: Java part of Andoid application can be built for another API level)
* `ANDROID_NDK_RELEASE` - version of the Android NDK
* `ANDROID_NDK_HOST_SYSTEM_NAME` - "windows", "linux-x86" or "darwin-x86" depending on the host platform
* `ANDROID_RTTI` - set if rtti is enabled by the runtime
* `ANDROID_EXCEPTIONS` - set if exceptions are enabled by the runtime
### Finding packages
When crosscompiling CMake `find_*` commands are normally expected to find libraries and packages belonging to the same build target. So _android-cmake_ configures CMake to search in Android-specific paths only and ignore your host system locations. So
find_package(ZLIB)
will surely find libz.so within the Android NDK.
However sometimes you need to locate a host package even when cross-compiling. For example you can be searching for your documentation generator. The _android-cmake_ recommends you to use `find_host_package` and `find_host_program` macro defined in the `android.toolchain.cmake`:
find_host_package(Doxygen)
find_host_program(PDFLATEX pdflatex)
However this will break regular builds so instead of wrapping package search into platform-specific logic you can copy the following snippet into your project (put it after your top-level `project()` command):
# Search packages for host system instead of packages for target system
# in case of cross compilation these macro should be defined by toolchain file
if(NOT COMMAND find_host_package)
macro(find_host_package)
find_package(${ARGN})
endmacro()
endif()
if(NOT COMMAND find_host_program)
macro(find_host_program)
find_program(${ARGN})
endmacro()
endif()
### Compiler flags recycling
Make sure to do the following in your scripts:
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}")
The flags will be prepopulated with critical flags, so don't loose them. Also be aware that _android-cmake_ also sets configuration-specific compiler and linker flags.
## Troubleshooting
### Building on Windows
First of all `cygwin` builds are **NOT supported** and will not be supported by _android-cmake_. To build natively on Windows you need a port of make but I recommend http://martine.github.io/ninja/ instead.
To build with Ninja you need:
* Ensure you are using CMake newer than 2.8.9;
* Download the latest Ninja from https://github.com/martine/ninja/releases;
* Put the `ninja.exe` into your PATH (or add path to `ninja.exe` to your PATH environment variable);
* Pass `-GNinja` to `cmake` alongside with other arguments (or choose Ninja generator in `cmake-gui`).
* Enjoy the fast native multithreaded build :)
But if you still want to stick to old make then:
* Get a Windows port of GNU Make:
* Android NDK r7 (and newer) already has `make.exe` on board;
* `mingw-make` should work as fine;
* Download some other port. For example, this one: http://gnuwin32.sourceforge.net/packages/make.htm.
* Add path to your `make.exe` to system PATH or always use full path;
* Pass `-G"MinGW Makefiles"` and `-DCMAKE_MAKE_PROGRAM="<full/path/to/>make.exe"`
* It must be `MinGW Makefiles` and not `Unix Makefiles` even if your `make.exe` is not a MinGW's make.
* Run `make.exe` or `cmake --build .` for single-threaded build.
### Projects with assembler files
The _android-cmake_ should correctly handle projects with assembler sources (`*.s` or `*.S`). But if you still facing problems with assembler then try to upgrade your CMake to version newer than 2.8.5
## Copying
_android-cmake_ is distributed under the terms of [BSD 3-Clause License](http://opensource.org/licenses/BSD-3-Clause)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,211 @@
============== r1 ============== (dead links)
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-windows.zip
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-darwin-x86.zip
* http://dl.google.com/android/ndk/android-ndk-1.5_r1-linux-x86.zip
============== r2 ==============
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-windows.zip
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-darwin-x86.zip
* http://dl.google.com/android/ndk/android-ndk-1.6_r1-linux-x86.zip
============== r3 ==============
* http://dl.google.com/android/ndk/android-ndk-r3-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r3-darwin-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r3-linux-x86.zip
============== r4 ==============
* http://dl.google.com/android/ndk/android-ndk-r4-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r4-darwin-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r4-linux-x86.zip
============== r4b ==============
* http://dl.google.com/android/ndk/android-ndk-r4b-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r4b-darwin-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r4b-linux-x86.zip
============== r5 ==============
* http://dl.google.com/android/ndk/android-ndk-r5-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r5-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r5-linux-x86.tar.bz2
============== r5b ==============
* http://dl.google.com/android/ndk/android-ndk-r5b-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r5b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r5b-linux-x86.tar.bz2
============== r5c ==============
* http://dl.google.com/android/ndk/android-ndk-r5c-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r5c-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r5c-linux-x86.tar.bz2
============== r6 ==============
* http://dl.google.com/android/ndk/android-ndk-r6-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r6-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r6-linux-x86.tar.bz2
============== r6b ==============
* http://dl.google.com/android/ndk/android-ndk-r6b-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r6b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r6b-linux-x86.tar.bz2
============== r7 ==============
* http://dl.google.com/android/ndk/android-ndk-r7-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r7-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r7-linux-x86.tar.bz2
============== r7b ==============
* http://dl.google.com/android/ndk/android-ndk-r7b-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r7b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r7b-linux-x86.tar.bz2
============== r7c ==============
* http://dl.google.com/android/ndk/android-ndk-r7c-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r7c-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r7c-linux-x86.tar.bz2
============== r8 ==============
* http://dl.google.com/android/ndk/android-ndk-r8-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r8-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8-linux-x86.tar.bz2
============== r8b ==============
* http://dl.google.com/android/ndk/android-ndk-r8b-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r8b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2
============== r8c ==============
* http://dl.google.com/android/ndk/android-ndk-r8c-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r8c-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8c-linux-x86.tar.bz2
============== r8d ==============
* http://dl.google.com/android/ndk/android-ndk-r8d-windows.zip
* http://dl.google.com/android/ndk/android-ndk-r8d-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8d-linux-x86.tar.bz2
============== r8e ==============
* http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r8e-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8e-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r8e-linux-x86_64.tar.bz2
============== r9 ==============
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86-legacy-toolchains.zip
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk-r9-windows-x86_64-legacy-toolchains.zip
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-darwin-x86_64-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9-linux-x86_64-legacy-toolchains.tar.bz2
============== r9b ==============
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86-legacy-toolchains.zip
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk-r9b-windows-x86_64-legacy-toolchains.zip
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-darwin-x86_64-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86-legacy-toolchains.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9b-linux-x86_64-legacy-toolchains.tar.bz2
============== r9c ==============
* http://dl.google.com/android/ndk/android-ndk-r9c-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r9c-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk-r9c-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9c-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9c-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9c-cxx-stl-libs-with-debugging-info.zip
============== r9d ==============
* http://dl.google.com/android/ndk/android-ndk-r9d-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r9d-cxx-stl-libs-with-debug-info.zip
============== r10 ==============
* http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk32-r10-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk32-r10-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk64-r10-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk64-r10-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r10-cxx-stl-libs-with-debug-info.zip
============== r10b ==============
* http://dl.google.com/android/ndk/android-ndk32-r10b-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk32-r10b-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk32-r10b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10b-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10b-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk32-r10b-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10b-windows-x86.zip
* http://dl.google.com/android/ndk/android-ndk64-r10b-windows-x86_64.zip
* http://dl.google.com/android/ndk/android-ndk64-r10b-darwin-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10b-darwin-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10b-linux-x86.tar.bz2
* http://dl.google.com/android/ndk/android-ndk64-r10b-linux-x86_64.tar.bz2
* http://dl.google.com/android/ndk/android-ndk-r10b-cxx-stl-libs-with-debug-info.zip
============== r10c ==============
* http://dl.google.com/android/ndk/android-ndk-r10c-windows-x86.exe
* http://dl.google.com/android/ndk/android-ndk-r10c-windows-x86_64.exe
* http://dl.google.com/android/ndk/android-ndk-r10c-darwin-x86.bin
* http://dl.google.com/android/ndk/android-ndk-r10c-darwin-x86_64.bin
* http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86.bin
* http://dl.google.com/android/ndk/android-ndk-r10c-linux-x86_64.bin
============== r10d ==============
* http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86.exe
* http://dl.google.com/android/ndk/android-ndk-r10d-windows-x86_64.exe
* http://dl.google.com/android/ndk/android-ndk-r10d-darwin-x86.bin
* http://dl.google.com/android/ndk/android-ndk-r10d-darwin-x86_64.bin
* http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86.bin
* http://dl.google.com/android/ndk/android-ndk-r10d-linux-x86_64.bin

View File

@ -43,6 +43,7 @@
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <cassert>
#include <cstring>
#include <cstdlib>
#include <ostream>
@ -2365,6 +2366,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
//ok, so far it looks like we're still in range of the horizontal edge
if ( e->xcurr == horzEdge->xtop && !eMaxPair )
{
assert(horzEdge->nextInLML);
if (SlopesEqual(*e, *horzEdge->nextInLML, m_UseFullRange))
{
//if output polygons share an edge, they'll need joining later ...
@ -2429,6 +2431,7 @@ void Clipper::ProcessHorizontal(TEdge *horzEdge)
if ( horzEdge->outIdx >= 0 )
IntersectEdges( horzEdge, eMaxPair,
IntPoint(horzEdge->xtop, horzEdge->ycurr), ipBoth);
assert(eMaxPair);
if (eMaxPair->outIdx >= 0) throw clipperException("ProcessHorizontal error");
DeleteFromAEL(eMaxPair);
DeleteFromAEL(horzEdge);

View File

@ -135,10 +135,9 @@ bool OpenDDLExport::writeToStream( const std::string &statement ) {
}
bool OpenDDLExport::writeNode( DDLNode *node, std::string &statement ) {
bool success( true );
writeNodeHeader( node, statement );
if (node->hasProperties()) {
success |= writeProperties( node, statement );
writeProperties( node, statement );
}
writeLineEnd( statement );
@ -360,11 +359,10 @@ bool OpenDDLExport::writeValueArray( DataArrayList *al, std::string &statement )
}
DataArrayList *nextDataArrayList = al ;
Value *nextValue( nextDataArrayList->m_dataList );
while (ddl_nullptr != nextDataArrayList) {
if (ddl_nullptr != nextDataArrayList) {
statement += "{ ";
nextValue = nextDataArrayList->m_dataList;
Value *nextValue( nextDataArrayList->m_dataList );
size_t idx( 0 );
while (ddl_nullptr != nextValue) {
if (idx > 0) {

View File

@ -27,6 +27,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <iostream>
#include <sstream>
#include <algorithm>
#include <memory>
#include <math.h>
#ifdef _WIN32
@ -275,22 +276,24 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
}
delete id;
Name *name(ddl_nullptr);
in = OpenDDLParser::parseName(in, end, &name);
Name *name_(ddl_nullptr);
in = OpenDDLParser::parseName(in, end, &name_);
std::unique_ptr<Name> name(name_);
if( ddl_nullptr != name && ddl_nullptr != node ) {
const std::string nodeName( name->m_id->m_buffer );
node->setName( nodeName );
delete name;
}
Property *first(ddl_nullptr);
std::unique_ptr<Property> first;
in = lookForNextToken(in, end);
if (*in == Grammar::OpenPropertyToken[0]) {
in++;
Property *prop(ddl_nullptr), *prev(ddl_nullptr);
std::unique_ptr<Property> prop, prev;
while (*in != Grammar::ClosePropertyToken[0] && in != end) {
in = OpenDDLParser::parseProperty(in, end, &prop);
Property *prop_(ddl_nullptr);
in = OpenDDLParser::parseProperty(in, end, &prop_);
prop.reset(prop_);
in = lookForNextToken(in, end);
if (*in != Grammar::CommaSeparator[0] && *in != Grammar::ClosePropertyToken[0]) {
@ -300,20 +303,20 @@ char *OpenDDLParser::parseHeader( char *in, char *end ) {
if (ddl_nullptr != prop && *in != Grammar::CommaSeparator[0]) {
if (ddl_nullptr == first) {
first = prop;
first = std::move(prop);
}
if (ddl_nullptr != prev) {
prev->m_next = prop;
prev->m_next = prop.release();
}
prev = prop;
prev = std::move(prop);
}
}
++in;
}
// set the properties
if (ddl_nullptr != first && ddl_nullptr != node) {
node->setProperties(first);
if (first && ddl_nullptr != node) {
node->setProperties(first.release());
}
}
@ -339,7 +342,6 @@ char *OpenDDLParser::parseStructure( char *in, char *end ) {
} else {
++in;
logInvalidTokenError( in, std::string( Grammar::OpenBracketToken ), m_logCallback );
error = true;
return ddl_nullptr;
}
in = lookForNextToken( in, end );

View File

@ -204,7 +204,7 @@ local int unzlocal_getShort (pzlib_filefunc_def,filestream,pX)
uLong *pX;
{
uLong x ;
int i;
int i = 0;
int err;
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
@ -232,7 +232,7 @@ local int unzlocal_getLong (pzlib_filefunc_def,filestream,pX)
uLong *pX;
{
uLong x ;
int i;
int i = 0;
int err;
err = unzlocal_getByte(pzlib_filefunc_def,filestream,&i);
@ -725,19 +725,15 @@ local int unzlocal_GetCurrentFileInfoInternal (file,
if (lSeek!=0)
{
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0;
else
if (ZSEEK(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)!=0)
err=UNZ_ERRNO;
}
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
if (ZREAD(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
err=UNZ_ERRNO;
lSeek+=file_info.size_file_comment - uSizeRead;
}
else
{
lSeek+=file_info.size_file_comment;
}
if ((err==UNZ_OK) && (pfile_info!=NULL))
@ -1129,7 +1125,7 @@ extern int ZEXPORT unzOpenCurrentFile3 (file, method, level, raw, password)
if ((s->cur_file_info.compression_method!=0) &&
(s->cur_file_info.compression_method!=Z_DEFLATED))
err=UNZ_BADZIPFILE;
return UNZ_BADZIPFILE;
pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
pfile_in_zip_read_info->crc32=0;

View File

@ -7,6 +7,8 @@
#ifndef ZCONF_H
#define ZCONF_H
/* #undef Z_PREFIX */
/* #undef Z_HAVE_UNISTD_H */
/*
* If you *really* need a unique prefix for all types and library functions,

View File

@ -1742,7 +1742,7 @@ UML_LOOK = NO
# the class node. If there are many fields or methods and many nodes the
# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS
# threshold limits the number of items for each type to make the size more
# managable. Set this to 0 for no limit. Note that the threshold may be
# manageable. Set this to 0 for no limit. Note that the threshold may be
# exceeded by 50% before the limit is enforced.
UML_LIMIT_NUM_FIELDS = 10

View File

@ -60,7 +60,7 @@ that it has not been implemented yet and some (most ...) formats lack proper spe
<b>Stanford Ply</b> ( <i>*.ply</i> )<br>
<b>TrueSpace</b> ( <i>*.cob, *.scn</i> )<sup>2</sup><br><br>
</tt>
See the @link importer_notes Importer Notes Page @endlink for informations, what a specific importer can do and what not.
See the @link importer_notes Importer Notes Page @endlink for information, what a specific importer can do and what not.
Note that although this paper claims to be the official documentation,
http://assimp.sourceforge.net/main_features_formats.html
<br>is usually the most up-to-date list of file formats supported by the library. <br>
@ -81,7 +81,7 @@ formats handle the required endian conversion correctly, so large parts of the l
The assimp linker library and viewer application are provided under the BSD 3-clause license. This basically means
that you are free to use it in open- or closed-source projects, for commercial or non-commercial purposes as you like
as long as you retain the license informations and take own responsibility for what you do with it. For details see
as long as you retain the license information and take own responsibility for what you do with it. For details see
the LICENSE file.
You can find test models for almost all formats in the <assimp_root>/test/models directory. Beware, they're *free*,
@ -1420,7 +1420,7 @@ IFC file properties (IfcPropertySet) are kept as per-node metadata, see aiNode::
This section contains implementations notes for the OgreXML importer.
@subsection overview Overview
Ogre importer is currently optimized for the Blender Ogre exporter, because thats the only one that I use. You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922
Ogre importer is currently optimized for the Blender Ogre exporter, because that's the only one that I use. You can find the Blender Ogre exporter at: http://www.ogre3d.org/forums/viewtopic.php?f=8&t=45922
@subsection what What will be loaded?
@ -1434,7 +1434,7 @@ Skeleton: Skeleton with Bone hierarchy (Position and Rotation, but no Scaling in
animations with rotation, translation and scaling keys.
@subsection export_Blender How to export Files from Blender
You can find informations about how to use the Ogreexporter by your own, so here are just some options that you need, so the assimp
You can find information about how to use the Ogreexporter by your own, so here are just some options that you need, so the assimp
importer will load everything correctly:
- Use either "Rendering Material" or "Custom Material" see @ref material
- do not use "Flip Up Axies to Y"
@ -1543,7 +1543,7 @@ Done! Please, share your loader that everyone can profit from it!
@section properties Properties
You can use properties to chance the behavior of you importer. In order to do so, you have to overide BaseImporter::SetupProperties, and specify
You can use properties to chance the behavior of you importer. In order to do so, you have to override BaseImporter::SetupProperties, and specify
you custom properties in config.h. Just have a look to the other AI_CONFIG_IMPORT_* defines and you will understand, how it works.
The properties can be set with Importer::SetProperty***() and can be accessed in your SetupProperties function with Importer::GetProperty***(). You can

View File

@ -266,6 +266,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_CONFIG_PP_FD_REMOVE \
"PP_FD_REMOVE"
// ---------------------------------------------------------------------------
/**
* @brief Configures the #aiProcess_FindDegenerates to check the area of a
* trinagle to be greates than e-6. If this is not the case the triangle will
* be removed if #AI_CONFIG_PP_FD_REMOVE is set to true.
*/
#define AI_CONFIG_PP_FD_CHECKAREA \
"PP_FD_CHECKAREA"
// ---------------------------------------------------------------------------
/** @brief Configures the #aiProcess_OptimizeGraph step to preserve nodes
* matching a name in a given list.
@ -903,7 +912,7 @@ enum aiComponent
/** @brief Set the tessellation for IFC cylindrical shapes.
*
* This is used by the IFC importer to determine the tessellation parameter
* for cylindrical shapes, i.e. the number of segments used to aproximate a circle.
* for cylindrical shapes, i.e. the number of segments used to approximate a circle.
* @note The default value is AI_IMPORT_IFC_DEFAULT_CYLINDRICAL_TESSELLATION and the
* accepted values are in range [3, 180].
* Property type: Integer.

View File

@ -65,11 +65,10 @@ template <typename TReal>
class aiVector3t
{
public:
aiVector3t () : x(), y(), z() {}
aiVector3t (TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t (const aiVector3t& o) : x(o.x), y(o.y), z(o.z) {}
aiVector3t() : x(), y(), z() {}
aiVector3t(TReal _x, TReal _y, TReal _z) : x(_x), y(_y), z(_z) {}
explicit aiVector3t (TReal _xyz ) : x(_xyz), y(_xyz), z(_xyz) {}
aiVector3t( const aiVector3t& o ) : x(o.x), y(o.y), z(o.z) {}
public:

View File

@ -206,7 +206,7 @@ class MeshKey(Structure):
("mTime", c_double),
# Index into the aiMesh::mAnimMeshes array of the
# mesh coresponding to the
# mesh corresponding to the
#aiMeshAnim hosting this
# key frame. The referenced anim mesh is evaluated
# according to the rules defined in the docs for

View File

@ -895,7 +895,7 @@ class PyAssimp3DViewer:
aspect = camera.aspect
u = 0.1 # unit size (in m)
l = 3 * u # lenght of the camera cone
l = 3 * u # length of the camera cone
f = 3 * u # aperture of the camera cone
glPushMatrix()

View File

@ -897,7 +897,7 @@ class PyAssimp3DViewer:
aspect = camera.aspect
u = 0.1 # unit size (in m)
l = 3 * u # lenght of the camera cone
l = 3 * u # length of the camera cone
f = 3 * u # aperture of the camera cone
glPushMatrix()

View File

@ -583,7 +583,7 @@ def clip_matrix(left, right, bottom, top, near, far, perspective=False):
orthographic canonical view volume (a box).
Homogeneous coordinates transformed by the perspective clip matrix
need to be dehomogenized (devided by w coordinate).
need to be dehomogenized (divided by w coordinate).
>>> frustrum = numpy.random.rand(6)
>>> frustrum[1] += frustrum[0]

View File

@ -51,7 +51,7 @@ import assimp.types;
extern ( C ) {
/*
* These limits are required to match the settings Assimp was compiled
* against. Therfore, do not redefine them unless you build the library
* against. Therefore, do not redefine them unless you build the library
* from source using the same definitions.
*/

View File

@ -1951,7 +1951,7 @@ error:
if (NULL == exception)
{
/* thats really a problem because we cannot throw in this case */
/* that's really a problem because we cannot throw in this case */
env->FatalError("could not throw java.io.IOException");
}
gLastErrorString = imp.GetErrorString();

View File

@ -114,7 +114,7 @@
%include "interface/IOSystem.i"
// We have to "instanciate" the templates used by the ASSSIMP_*_ARRAY macros
// We have to "instantiate" the templates used by the ASSSIMP_*_ARRAY macros
// here at the end to avoid running into forward reference issues (SWIG would
// spit out the helper functions before the header includes for the element
// types otherwise).

View File

@ -641,7 +641,7 @@ static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink,const CVTimeS
{
for(MeshHelper* helper in modelMeshes)
{
// Set up meterial state.
// Set up material state.
glCallList(helper.displayList);
}
}

View File

@ -179,7 +179,7 @@ extern void exit(int);
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
glutJoystickFunc, glutForceJoystickFunc (NOT FINALIZED!).
**/
#ifndef GLUT_API_VERSION /* allow this to be overriden */
#ifndef GLUT_API_VERSION /* allow this to be overridden */
#define GLUT_API_VERSION 3
#endif
@ -219,7 +219,7 @@ extern void exit(int);
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
**/
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overridden. */
#define GLUT_XLIB_IMPLEMENTATION 15
#endif

View File

@ -0,0 +1,28 @@
@echo off
set ASSIMP_PATH=D:\projects\asset-importer-lib\assimp
set CMAKE_PATH="C:\Program Files\CMake\bin\cmake.exe"
set ANDROID_NDK_PATH=C:\Users\kimkulling\AppData\Local\Android\Sdk\ndk-bundle
set ANDROID_CMAKE_PATH=contrib\android-cmake
pushd %ASSIMP_PATH%
rmdir /s /q build
mkdir build
cd build
%CMAKE_PATH% .. ^
-G"MinGW Makefiles" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_TOOLCHAIN_FILE=%ANDROID_CMAKE_PATH%\android.toolchain.cmake ^
-DCMAKE_MAKE_PROGRAM=%ANDROID_NDK_PATH%\prebuilt\windows-x86_64\bin\make.exe ^
-DANDROID_NDK=%ANDROID_NDK_PATH% ^
-DANDROID_NATIVE_API_LEVEL=android-9 ^
-DASSIMP_ANDROID_JNIIOSYSTEM=ON ^
-DANDROID_ABI=arm64-v8a ^
-DASSIMP_BUILD_ZLIB=ON ^
-DASSIMP_BUILD_TESTS=OFF
%CMAKE_PATH% --build .
popd

View File

@ -52,24 +52,55 @@ INCLUDE_DIRECTORIES(
# Assimp library can be found, even if it is not installed system-wide yet.
LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${AssetImporter_BINARY_DIR}/lib )
SOURCE_GROUP( unit FILES
unit/CCompilerTest.c
)
SET( TEST_SRCS
SET( COMMON
unit/utIOSystem.cpp
unit/utIOStreamBuffer.cpp
unit/utIssues.cpp
unit/utAnim.cpp
unit/AssimpAPITest.cpp
unit/utBatchLoader.cpp
unit/utDefaultIOStream.cpp
unit/utFastAtof.cpp
unit/utMetadata.cpp
unit/SceneDiffer.h
unit/SceneDiffer.cpp
unit/UTLogStream.h
unit/AbstractImportExportBase.cpp
unit/TestIOSystem.h
unit/TestModelFactory.h
unit/utTypes.cpp
unit/utVersion.cpp
unit/utProfiler.cpp
unit/utSharedPPData.cpp
unit/utStringUtils.cpp
)
SET( IMPORTERS
unit/utLWSImportExport.cpp
unit/utSMDImportExport.cpp
unit/utglTFImportExport.cpp
unit/utglTF2ImportExport.cpp
unit/utHMPImportExport.cpp
unit/utIFCImportExport.cpp
unit/utFBXImporterExporter.cpp
unit/utImporter.cpp
unit/ut3DImportExport.cpp
unit/ut3DSImportExport.cpp
unit/utACImportExport.cpp
unit/utAMFImportExport.cpp
unit/utASEImportExport.cpp
unit/utAnim.cpp
unit/AssimpAPITest.cpp
unit/utB3DImportExport.cpp
unit/utBatchLoader.cpp
unit/utD3MFImportExport.cpp
unit/utQ3DImportExport.cpp
unit/utSTLImportExport.cpp
unit/utXImporterExporter.cpp
unit/utX3DImportExport.cpp
unit/utDXFImporterExporter.cpp
unit/utPMXImporter.cpp
unit/utPLYImportExport.cpp
unit/utObjImportExport.cpp
unit/utObjTools.cpp
unit/utOpenGEXImportExport.cpp
unit/utSIBImporter.cpp
unit/utBlenderIntermediate.cpp
unit/utBlendImportAreaLight.cpp
unit/utBlenderImportExport.cpp
@ -79,77 +110,60 @@ SET( TEST_SRCS
unit/utColladaExportLight.cpp
unit/utColladaImportExport.cpp
unit/utCSMImportExport.cpp
unit/utDefaultIOStream.cpp
unit/utDXFImporterExporter.cpp
unit/utFastAtof.cpp
unit/utFBXImporterExporter.cpp
unit/utFindDegenerates.cpp
unit/utFindInvalidData.cpp
unit/utFixInfacingNormals.cpp
unit/utGenNormals.cpp
unit/utglTFImportExport.cpp
unit/utglTF2ImportExport.cpp
unit/utHMPImportExport.cpp
unit/utIFCImportExport.cpp
unit/utImporter.cpp
unit/utImproveCacheLocality.cpp
unit/utIOSystem.cpp
unit/utIOStreamBuffer.cpp
unit/utIssues.cpp
unit/utJoinVertices.cpp
unit/utLimitBoneWeights.cpp
unit/utLWSImportExport.cpp
unit/utB3DImportExport.cpp
)
SET( MATERIAL
unit/utMaterialSystem.cpp
)
SET( MATH
unit/utMatrix3x3.cpp
unit/utMatrix4x4.cpp
unit/utMetadata.cpp
unit/SceneDiffer.h
unit/SceneDiffer.cpp
unit/utSIBImporter.cpp
unit/utObjImportExport.cpp
unit/utObjTools.cpp
unit/utOpenGEXImportExport.cpp
unit/utPretransformVertices.cpp
unit/utPLYImportExport.cpp
unit/utPMXImporter.cpp
unit/utRemoveComments.cpp
unit/utRemoveComponent.cpp
unit/utScenePreprocessor.cpp
unit/utSceneCombiner.cpp
unit/utSharedPPData.cpp
unit/utStringUtils.cpp
unit/utSMDImportExport.cpp
unit/utSortByPType.cpp
unit/utSplitLargeMeshes.cpp
unit/utTargetAnimation.cpp
unit/utTextureTransform.cpp
unit/utTriangulate.cpp
unit/utTypes.cpp
unit/utVertexTriangleAdjacency.cpp
unit/utVersion.cpp
unit/utVector3.cpp
unit/utXImporterExporter.cpp
unit/utX3DImportExport.cpp
unit/utD3MFImportExport.cpp
unit/utQ3DImportExport.cpp
unit/utProfiler.cpp
)
SET( POST_PROCESSES
unit/utImproveCacheLocality.cpp
unit/utFixInfacingNormals.cpp
unit/utGenNormals.cpp
unit/utTriangulate.cpp
unit/utTextureTransform.cpp
unit/utRemoveRedundantMaterials.cpp
unit/utRemoveVCProcess.cpp
unit/utScaleProcess.cpp
unit/utJoinVertices.cpp
unit/utRemoveComments.cpp
unit/utRemoveComponent.cpp
unit/utVertexTriangleAdjacency.cpp
unit/utJoinVertices.cpp
unit/utSplitLargeMeshes.cpp
unit/utFindDegenerates.cpp
unit/utFindInvalidData.cpp
unit/utLimitBoneWeights.cpp
unit/utPretransformVertices.cpp
unit/utScenePreprocessor.cpp
unit/utTargetAnimation.cpp
unit/utSortByPType.cpp
unit/utSceneCombiner.cpp
)
SOURCE_GROUP( tests FILES ${TEST_SRCS} )
SOURCE_GROUP( tests/PostProcess FILES ${POST_PROCESSES})
SOURCE_GROUP( UnitTests\\Compiler FILES unit/CCompilerTest.c )
SOURCE_GROUP( UnitTests\\Common FILES ${COMMON} )
SOURCE_GROUP( UnitTests\\Importers FILES ${IMPORTERS} )
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
SOURCE_GROUP( UnitTests\\PostProcess FILES ${POST_PROCESSES})
add_executable( unit
../contrib/gtest/src/gtest-all.cc
unit/CCompilerTest.c
unit/Main.cpp
../code/Version.cpp
${TEST_SRCS}
${COMMON}
${IMPORTERS}
${MATERIAL}
${MATH}
${POST_PROCESSES}
)

View File

@ -32,7 +32,7 @@ L'utilizzo della Creative Commons non influisce su questo diritto.
************************************************
This model is released under Creative Commons Licence, Attribution 2.0
for informations see:
for information see:
http://creativecommons.org
http://creativecommons.org/licenses/by/2.0/
feel free to use and improve it.

View File

@ -1 +1 @@
Simple models for testing importer. No desription because models are simple and created by hands.
Simple models for testing importer. No description because models are simple and created by hand.

View File

@ -0,0 +1,18 @@
solid testTriangle_1
facet normal 0.0 0.0 1.0
outer loop
vertex 1.0 1.0 0.0
vertex -1.0 1.0 0.0
vertex 0.0 -1.0 0.0
endloop
endfacet
endsolid
solid testTriangle_2
facet normal 0.0 0.0 1.0
outer loop
vertex 3.0 3.0 0.0
vertex 2.0 3.0 0.0
vertex 0.0 2.0 0.0
endloop
endfacet
endsolid

View File

@ -58,8 +58,7 @@ protected:
};
// ------------------------------------------------------------------------------------------------
void FindDegeneratesProcessTest::SetUp()
{
void FindDegeneratesProcessTest::SetUp() {
mesh = new aiMesh();
process = new FindDegeneratesProcess();
@ -107,16 +106,12 @@ void FindDegeneratesProcessTest::SetUp()
mesh->mNumUVComponents[1] = numFaces;
}
// ------------------------------------------------------------------------------------------------
void FindDegeneratesProcessTest::TearDown()
{
void FindDegeneratesProcessTest::TearDown() {
delete mesh;
delete process;
}
// ------------------------------------------------------------------------------------------------
TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection)
{
TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection) {
process->EnableInstantRemoval(false);
process->ExecuteOnMesh(mesh);
@ -135,12 +130,18 @@ TEST_F(FindDegeneratesProcessTest, testDegeneratesDetection)
mesh->mPrimitiveTypes);
}
// ------------------------------------------------------------------------------------------------
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemoval)
{
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemoval) {
process->EnableAreaCheck(false);
process->EnableInstantRemoval(true);
process->ExecuteOnMesh(mesh);
EXPECT_EQ(mesh->mNumUVComponents[1], mesh->mNumFaces);
}
TEST_F(FindDegeneratesProcessTest, testDegeneratesRemovalWithAreaCheck) {
process->EnableAreaCheck(true);
process->EnableInstantRemoval(true);
process->ExecuteOnMesh(mesh);
EXPECT_EQ(mesh->mNumUVComponents[1]-100, mesh->mNumFaces);
}

View File

@ -294,12 +294,12 @@ TEST_F(utObjImportExport, relative_indices_Test) {
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mNumMeshes, 1);
EXPECT_EQ(scene->mNumMeshes, 1U);
const aiMesh *mesh = scene->mMeshes[0];
EXPECT_EQ(mesh->mNumVertices, 4);
EXPECT_EQ(mesh->mNumFaces, 1);
EXPECT_EQ(mesh->mNumVertices, 4U);
EXPECT_EQ(mesh->mNumFaces, 1U);
const aiFace face = mesh->mFaces[0];
EXPECT_EQ(face.mNumIndices, 4);
EXPECT_EQ(face.mNumIndices, 4U);
for (unsigned int i = 0; i < face.mNumIndices; ++i)
{
EXPECT_EQ(face.mIndices[i], i);
@ -318,12 +318,12 @@ TEST_F(utObjImportExport, homogeneous_coordinates_Test) {
const aiScene *scene = myimporter.ReadFileFromMemory(ObjModel.c_str(), ObjModel.size(), aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
EXPECT_EQ(scene->mNumMeshes, 1);
EXPECT_EQ(scene->mNumMeshes, 1U);
const aiMesh *mesh = scene->mMeshes[0];
EXPECT_EQ(mesh->mNumVertices, 3);
EXPECT_EQ(mesh->mNumFaces, 1);
EXPECT_EQ(mesh->mNumVertices, 3U);
EXPECT_EQ(mesh->mNumFaces, 1U);
const aiFace face = mesh->mFaces[0];
EXPECT_EQ(face.mNumIndices, 3);
EXPECT_EQ(face.mNumIndices, 3U);
const aiVector3D vertice = mesh->mVertices[0];
EXPECT_EQ(vertice.x, -1.0f);
EXPECT_EQ(vertice.y, 0.0f);

View File

@ -0,0 +1,68 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2017, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "SceneDiffer.h"
#include "AbstractImportExportBase.h"
#include <assimp/Importer.hpp>
using namespace Assimp;
class utSTLImporterExporter : public AbstractImportExportBase {
public:
virtual bool importerTest() {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", 0 );
return nullptr != scene;
}
};
TEST_F( utSTLImporterExporter, importXFromFileTest ) {
EXPECT_TRUE( importerTest() );
}
TEST_F( utSTLImporterExporter, test_with_two_solids ) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", 0 );
EXPECT_NE( nullptr, scene );
}

View File

@ -177,6 +177,17 @@ inline uint32_t Write<aiVector3D>(const aiVector3D& v)
return t;
}
// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline uint32_t Write<aiColor3D>(const aiColor3D& v)
{
uint32_t t = Write<float>(v.r);
t += Write<float>(v.g);
t += Write<float>(v.b);
return t;
}
// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
@ -198,6 +209,7 @@ inline uint32_t Write<aiQuaternion>(const aiQuaternion& v)
t += Write<float>(v.x);
t += Write<float>(v.y);
t += Write<float>(v.z);
ai_assert(t == 16);
return 16;
}
@ -565,9 +577,9 @@ uint32_t WriteBinaryLight(const aiLight* l)
len += Write<float>(l->mAttenuationQuadratic);
}
len += Write<aiVector3D>((const aiVector3D&)l->mColorDiffuse);
len += Write<aiVector3D>((const aiVector3D&)l->mColorSpecular);
len += Write<aiVector3D>((const aiVector3D&)l->mColorAmbient);
len += Write<aiColor3D>(l->mColorDiffuse);
len += Write<aiColor3D>(l->mColorSpecular);
len += Write<aiColor3D>(l->mColorAmbient);
if (l->mType == aiLightSource_SPOT) {
len += Write<float>(l->mAngleInnerCone);

View File

@ -561,7 +561,7 @@ void CGLView::Enable_Textures(const bool pEnable)
}
/********************************************************************/
/*********************** Overrided functions ************************/
/*********************** Override functions ************************/
/********************************************************************/
void CGLView::initializeGL()

Some files were not shown because too many files have changed in this diff Show More