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);
    }
}
Esempio n. 2
0
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);
	}

	
}