void GnuplotExportModule::doOutput(TimeStep *tStep, bool forcedOutput) { if (!(testTimeStepOutput(tStep) || forcedOutput)) { return; } // Export the sum of reaction forces for each Dirichlet BC if(mExportReactionForces) { outputReactionForces(tStep); } Domain *domain = emodel->giveDomain(1); // Export output from boundary conditions if(mExportBoundaryConditions) { int numBC = domain->giveNumberOfBoundaryConditions(); for(int i = 1; i <= numBC; i++) { PrescribedGradient *presGradBC = dynamic_cast<PrescribedGradient*>( domain->giveBc(i) ); if(presGradBC != NULL) { outputBoundaryCondition(*presGradBC, tStep); } PrescribedGradientBCNeumann *presGradBCNeumann = dynamic_cast<PrescribedGradientBCNeumann*>( domain->giveBc(i) ); if(presGradBCNeumann != NULL) { outputBoundaryCondition(*presGradBCNeumann, tStep); } PrescribedGradientBCWeak *presGradBCWeak = dynamic_cast<PrescribedGradientBCWeak*>( domain->giveBc(i) ); if(presGradBCWeak != NULL) { outputBoundaryCondition(*presGradBCWeak, tStep); } } } mTimeHist.push_back( tStep->giveTargetTime() ); if(mExportXFEM) { if(domain->hasXfemManager()) { XfemManager *xMan = domain->giveXfemManager(); int numEI = xMan->giveNumberOfEnrichmentItems(); std::vector< std::vector<FloatArray> > points; for(int i = 1; i <= numEI; i++) { EnrichmentItem *ei = xMan->giveEnrichmentItem(i); ei->callGnuplotExportModule(*this, tStep); GeometryBasedEI *geoEI = dynamic_cast<GeometryBasedEI*>(ei); if(geoEI != NULL) { std::vector<FloatArray> eiPoints; geoEI->giveSubPolygon(eiPoints, 0.0, 1.0); points.push_back(eiPoints); } } outputXFEMGeometry(points); } } if(mExportMesh) { outputMesh(*domain); } if(mMonitorNodeIndex != -1) { DofManager *dMan = domain->giveDofManager(mMonitorNodeIndex); outputNodeDisp(*dMan, tStep); } }
void processMesh(std::string filename) { Assimp::Importer Importer; const aiScene* scene = Importer.ReadFile(filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_JoinIdenticalVertices | aiProcess_ImproveCacheLocality); if (!scene) { std::cout << "File " << filename << " not found." << std::endl; return; } for (uint32 meshID = 0; meshID < scene->mNumMeshes; ++meshID) { const aiMesh* mesh = scene->mMeshes[meshID]; mesh_header meshHeader = { 0 }; meshHeader.magicNumber = MESH_MAGIC_NUMBER; skeleton_header skelHeader = { 0 }; skelHeader.magicNumber = SKELETON_MAGIC_NUMBER; std::vector<vec3> positions; std::vector<vec2> texCoords; std::vector<vec3> normals; std::vector<vertex_weight> weights; std::vector<uint16> indices; positions.reserve(mesh->mNumVertices); texCoords.reserve(mesh->mNumVertices); normals.reserve(mesh->mNumVertices); weights.reserve(mesh->mNumVertices); indices.reserve(mesh->mNumFaces); meshHeader.vertexCount = mesh->mNumVertices; meshHeader.indexCount = mesh->mNumFaces * 3; for (uint32 i = 0; i < mesh->mNumVertices; i++) { if (mesh->HasPositions()) { meshHeader.hasPositions = true; const aiVector3D& pos = mesh->mVertices[i]; positions.push_back(vec3(pos.x, pos.y, pos.z)); } if (mesh->HasNormals()) { meshHeader.hasNormals = true; const aiVector3D& nor = mesh->mNormals[i]; normals.push_back(vec3(nor.x, nor.y, nor.z)); } if (mesh->HasTextureCoords(0)) { meshHeader.hasTexCoords = true; const aiVector3D& tex = mesh->mTextureCoords[0][i]; texCoords.push_back(vec2(tex.x, tex.y)); } } for (uint32 i = 0; i < mesh->mNumFaces; i++) { const aiFace &face = mesh->mFaces[i]; assert(face.mNumIndices == 3); indices.push_back((uint16)face.mIndices[0]); indices.push_back((uint16)face.mIndices[1]); indices.push_back((uint16)face.mIndices[2]); } if (mesh->HasBones()) { meshHeader.hasSkeleton = true; vertex_weight defaultWeight = { 0 }; weights.resize(mesh->mNumVertices, defaultWeight); std::map<std::string, bone_idx> boneNames; std::vector<bone_info> boneInfos; uint32 numberOfBones = mesh->mNumBones; for (bone_idx boneID = 0; boneID < (bone_idx)numberOfBones; ++boneID) { const aiBone* bone = mesh->mBones[boneID]; std::string boneName = bone->mName.C_Str(); boneNames[boneName] = boneID; bone_info boneInfo; boneInfo.invBindMatrix = readMatrix(bone->mOffsetMatrix); boneInfo.name = boneName; boneInfos.push_back(boneInfo); for (uint32 weightID = 0; weightID < bone->mNumWeights; ++weightID) { uint32 vertexID = bone->mWeights[weightID].mVertexId; float weight = bone->mWeights[weightID].mWeight; vertex_weight& vWeight = weights[vertexID]; // search first unused for (uint32 i = 0; i < 4; ++i) { if (vWeight.weights[i] == 0.f) { vWeight.joints[i] = boneID; vWeight.weights[i] = weight; break; } } } } // normalize weights -> sum up to 1 for (vertex_weight& vWeight : weights) { vec4 tmp(vWeight.weights[0], vWeight.weights[1], vWeight.weights[2], vWeight.weights[3]); normalize(tmp); vWeight.weights[0] = tmp.x; vWeight.weights[1] = tmp.y; vWeight.weights[2] = tmp.z; vWeight.weights[3] = tmp.w; } readSkeleton(scene->mRootNode, boneNames, boneInfos, NO_PARENT); skelHeader.jointCount = (bone_idx)boneInfos.size(); if (scene->HasAnimations()) { for (uint32 animationID = 0; animationID < scene->mNumAnimations; ++animationID) { std::vector<anim_channel> animChannels; const aiAnimation* animation = scene->mAnimations[animationID]; float ticksPerSecond = (float)animation->mTicksPerSecond; float normalizingFactor = (ticksPerSecond == 0.f) ? 1.f : 1.f / ticksPerSecond; bone_idx numberOfAnimatedBones = animation->mNumChannels; for (bone_idx channelID = 0; channelID < numberOfAnimatedBones; ++channelID) { const aiNodeAnim* channel = animation->mChannels[channelID]; std::string boneName = channel->mNodeName.C_Str(); if (boneNames.find(boneName) != boneNames.end()) { bone_idx boneID = boneNames[boneName]; anim_channel animChannel; animChannel.boneID = boneID; // for now assert(channel->mNumPositionKeys == channel->mNumRotationKeys && channel->mNumPositionKeys == channel->mNumScalingKeys); for (uint32 keyID = 0; keyID < channel->mNumPositionKeys; ++keyID) { key_frame keyframe; keyframe.time = (float)channel->mPositionKeys[keyID].mTime * normalizingFactor; keyframe.sqt.position = readVector(channel->mPositionKeys[keyID]); keyframe.sqt.rotation = readQuaternion(channel->mRotationKeys[keyID]); keyframe.sqt.scale = readVector(channel->mScalingKeys[keyID]).x; animChannel.keyframes.push_back(keyframe); } animChannels.push_back(animChannel); } } animation_header animHeader; animHeader.magicNumber = ANIMATION_MAGIC_NUMBER; animHeader.jointCount = (bone_idx)animChannels.size(); animHeader.length = (float)animation->mDuration * normalizingFactor; animHeader.looping = true; animHeader.skeleton = 0; std::sort(animChannels.begin(), animChannels.end(), [](const anim_channel& a, const anim_channel& b) { return a.boneID < b.boneID; }); // output animations std::string animationFileName; if (animation->mName.length == 0) { animationFileName = std::string("../Game/assets/animations/") + getFileName(filename) + ".anim"; } else { animationFileName = std::string("../Game/assets/animations/") + getAnimationFileName(animation->mName.C_Str()) + ".anim"; } outputAnimation(animationFileName, animHeader, animChannels); } } std::string skeletonFileName = std::string("../Game/assets/skeletons/") + getFileName(filename) + ".skeleton"; outputSkeleton(skeletonFileName, skelHeader, boneInfos); } std::string meshFileName = std::string("../Game/assets/models/") + getFileName(filename) + ".mesh"; outputMesh(meshFileName, meshHeader, positions, texCoords, normals, weights, indices); } }