ModelPart* AssimpModelImporter::CreateModelPart(aiMesh* mesh) const { vector<Vector3f> positions = ExtractPositions(mesh); vector<Vector3f> normals = ExtractNormals(mesh); vector<Vector2f> texCoords = ExtractTexCoords(mesh, 0); vector<Vector4i> joints; vector<Vector4f> weights; vector<ModelPartBone> bones; ExtractJointsAndWeights(mesh, joints, weights, bones); vector<U32> indices = ExtractIndices(mesh); Geometry* geometry = new Geometry(); geometry->SetPositions(begin(positions), end(positions)); geometry->SetNormals(begin(normals), end(normals)); geometry->SetTexCoords(begin(texCoords), end(texCoords)); geometry->SetJoints(begin(joints), end(joints)); geometry->SetWeights(begin(weights), end(weights)); geometry->SetIndices(begin(indices), end(indices), D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); VertexData* vertexData = nullptr; if (scene->HasAnimations()) { vertexData = new VertexData(P0N0T0A0Builder(geometry)); } else { vertexData = new VertexData(P0N0T0Builder(geometry)); } string meshName = mesh->mName.C_Str(); if (meshName.empty()) { meshName = FindNodeName(FindMeshIndex(mesh)); } ModelPart* modelPart = new ModelPart(meshName, vertexData, GetMaterialByName(meshName), geometry->GetTriangles(), bones); return modelPart; }
void OrderDownwindForDofDist(SmartPtr<DoFDistribution> dd, ConstSmartPtr<TDomain> domain, SmartPtr<UserData<MathVector<TDomain::dim>, TDomain::dim> > spVelocity, number time, int si, number threshold) { static const int dim = TDomain::dim; const size_t num_ind = dd->num_indices(); typedef typename std::pair<MathVector<dim>, size_t> pos_type; typedef typename std::vector<std::vector<size_t> > adjacency_type; // get positions of indices typename std::vector<pos_type> vPositions; ExtractPositions(domain, dd, vPositions); // get adjacency vector of vectors adjacency_type vvConnections; dd->get_connections(vvConnections); // Check vector sizes match if (vvConnections.size() != num_ind) UG_THROW("OrderDownstreamForDofDist: " "Adjacency list of dimension " << num_ind << " expected, got "<< vvConnections.size()); if (vPositions.size() != num_ind) UG_THROW("OrderDownstreamForDofDist: " "Position list of dimension " << num_ind << " expected, got "<< vPositions.size()); // init helper structures std::vector<size_t> vNewIndex(num_ind, 0); std::vector<size_t> vAncestorsCount(num_ind, 0); std::vector<bool> vVisited(num_ind, false); // remove connections that are not in stream direction adjacency_type::iterator VertexIter; std::vector<size_t>::iterator AdjIter; std::vector<size_t> vAdjacency; // count how many vertex were kept / removed per adjacency vector size_t initialcount, kept, removed = 0; MathVector<TDomain::dim> vVel1, vPos1, vPos2, vDir1_2; size_t i; for (VertexIter = vvConnections.begin(), i=0; VertexIter != vvConnections.end(); VertexIter++, i++) { UG_DLOG(LIB_DISC_ORDER, 2, "Filtering vertex " << i << " adjacency vector." <<std::endl); initialcount = VertexIter->size(); kept = 0; removed = 0; // get position and velocity of first trait vPos1 = vPositions.at(i).first; (*spVelocity)(vVel1, vPos1, time, si); if (VecLengthSq(vVel1) == 0 ) { // if the velocity is zero at this trait it does not interfere with others // NOTE: otherwise this trait would be downwind-connected to all of it's neighbors // NOTE: VertexIter-> will access inner vector functions (*VertexIter) is the inner vector. removed = VertexIter->size(); VertexIter->clear(); } else { AdjIter = VertexIter->begin(); while (AdjIter != VertexIter->end()) { // get position of second trait vPos2 = vPositions.at(*AdjIter).first; // get difference vector as direction vector VecSubtract(vDir1_2, vPos2, vPos1); // compute angle between velocity and direction vector number anglex1_2 = VecAngle(vDir1_2, vVel1); // if angle is smaller then threshold continue else remove connection if (anglex1_2 <= threshold && i != *AdjIter) { vAncestorsCount.at(*AdjIter) += 1; ++AdjIter; kept++; } else { AdjIter = VertexIter->erase(AdjIter); removed++; } } } UG_DLOG(LIB_DISC_ORDER, 2, "Kept: " << kept << ", removed: " << removed << " of " << initialcount << " entries in adjacency matrix." << std::endl << std::endl); } // calculate downwindorder // Find vertexes without any ancestors and start NumeriereKnoten on them. size_t v,N; for (v=0, N=0; v < vvConnections.size(); v++) { if (vAncestorsCount[v] == 0 && !vVisited[v]) { NumeriereKnoten(vvConnections, vVisited, vAncestorsCount, vNewIndex, N, v); } } // sanity check if (N < vvConnections.size()){ size_t fails = 0; for (v=0; v < vvConnections.size(); v++) { if (!vVisited[v]) { UG_DLOG(LIB_DISC_ORDER, 2, v << "was not visited, has unresolved ancestors: " << vAncestorsCount[v] << std::endl); fails ++; } } UG_THROW("OrderDownwindForDist failed, " << fails << " traits unvisited." << std::endl); } // reorder traits dd->permute_indices(vNewIndex); }