void TriMesh::computeFaceGrad(const VectorXd& vertForm, std::vector<Vec3>& faceVector) const
{
    faceVector.resize(numFaces());
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVert;
        getFaceVerts(face, fVert);
        assert(fVert.size() == 3);

        Vec3 pos[3];
        double val[3];
        for (unsigned i = 0; i < 3; ++i) 
        {
            val[i] = vertForm(fVert[i]);
            pos[i] = getVertPos(fVert[i]);
        }

        Vec3 X = Vec3::Zero();
        for (unsigned i = 0; i < 3; ++i) 
        {
            unsigned j = (i + 1) % 3;
            unsigned k = (i + 2) % 3;
            X += val[i] * (pos[k] - pos[j]);
        }

        Vec3 n = (pos[1]-pos[0]).cross(pos[2]-pos[1]);
        double twice_area = n.norm();
        n /= twice_area;

        faceVector[face] = n.cross(X) / twice_area;
    }
}
Пример #2
0
void extractInternalFaces(const Dune::CpGrid& grid,
                          Eigen::Array<int, Eigen::Dynamic, 1>& internal_faces,
                          Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor>& nbi)
{
    // Extracts the internal faces of the grid.
    // These are stored in internal_faces.
    int nf=numFaces(grid);
    int num_internal=0;
    for(int f=0; f<nf; ++f)
    {
        if(grid.faceCell(f, 0)<0 || grid.faceCell(f, 1)<0)
            continue;
        ++num_internal;
    }
    // std::cout << num_internal << " internal faces." << std::endl;
    nbi.resize(num_internal, 2);
    internal_faces.resize(num_internal);
    int fi = 0;

    for (int f = 0; f < nf; ++f) {
        if(grid.faceCell(f, 0)>=0 && grid.faceCell(f, 1)>=0) {
            internal_faces[fi] = f;
            nbi(fi,0) = grid.faceCell(f, 0);
            nbi(fi,1) = grid.faceCell(f, 1);
            ++fi;
        }
    }
}
Пример #3
0
void extractInternalFaces(const UnstructuredGrid& grid,
                          Eigen::Array<int, Eigen::Dynamic, 1>& internal_faces,
                          Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor>& nbi)
{
    typedef Eigen::Array<bool, Eigen::Dynamic, 1> OneColBool;
    typedef Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColInt;
    typedef Eigen::Array<bool, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColBool;
    TwoColInt nb = faceCells(grid);
    // std::cout << "nb = \n" << nb << std::endl;
    // Extracts the internal faces of the grid.
    // These are stored in internal_faces.
    TwoColBool nbib = nb >= 0;
    OneColBool ifaces = nbib.rowwise().all();
    const int num_internal = ifaces.cast<int>().sum();
    // std::cout << num_internal << " internal faces." << std::endl;
    nbi.resize(num_internal, 2);
    internal_faces.resize(num_internal);
    int fi = 0;
    int nf = numFaces(grid);

    for (int f = 0; f < nf; ++f) {
        if (ifaces[f]) {
            internal_faces[fi] = f;
            nbi.row(fi) = nb.row(f);
            ++fi;
        }
    }
}
double TriMesh::computeTotalArea() const
{
    double sum = 0.0;
    for (unsigned face = 0; face < numFaces(); ++face) 
        sum += computeFaceArea(face);
    return sum;
}
Пример #5
0
void OBJGroup::addFace( const OBJFace& face )
{
    m_faces.push_back( face );

    const std::string& lastMaterial = m_materialNames.back();
    m_facesByMaterial[ lastMaterial ].push_back( numFaces() - 1 );
}
Пример #6
0
// for each face according to its vertices orientation
void Mesh::compute_normals_per_facet()
{
	for(int i = 0; i < numFaces(); ++i)
	{
		Face &face = m_face[i];
		face.computeNormal();
	}
}
Пример #7
0
void Mesh::Vertex::computeNormal()
{
	for(int i = 0; i < numFaces(); ++i)
	{
		Face_handle v = face(i);
		m_normal += v->normal();
	}
	m_normal.unitize();
}
Пример #8
0
	bool BspSceneFile::loadFaces(std::istream& bspStream, const Q3Bsp::DirEntry& facesEntry) {
		if (!bspStream.seekg(facesEntry.offset, std::ios::beg)) {
			return false;
		}
		
		std::size_t numFaces(facesEntry.length / sizeof(Q3Bsp::Face));
		m_faces.reserve(numFaces);

		if (!bspStream.read(reinterpret_cast<char*>(&m_faces[0]), facesEntry.length)) {
			return false;
		}
		return true;
	}
Пример #9
0
void Mesh::buildEdges()
{
	TSmallLargeEdgeI edgeMap; 

	edgeMap.clear();
	// map small index to map large index to the edge in the m_edge list
	for(int fi = 0; fi < numFaces(); ++fi)
	{
		//printf("%d- ", fi);
		Face &face = m_face[fi];

		int v0i = face.vertexIndex(0);
		int v1i = face.vertexIndex(1);
		int v2i = face.vertexIndex(2);

		int e0i = addEdgeOnceUsing(v0i, v1i, edgeMap, &Mesh::addEdge);
		int e1i = addEdgeOnceUsing(v1i, v2i, edgeMap, &Mesh::addEdge);
		int e2i = addEdgeOnceUsing(v2i, v0i, edgeMap, &Mesh::addEdge);

		face.m_edges[0] = e0i;
		face.m_edges[1] = e1i;
		face.m_edges[2] = e2i;

/*		Vertex_handle v0 = find_vertex(v0i);
		v0->m_edges.append(e0i);
		v0->m_edges.append(e2i);
		Vertex_handle v1 = find_vertex(v1i);
		v1->m_edges.append(e0i);
		v1->m_edges.append(e1i);
		Vertex_handle v2 = find_vertex(v2i);
		v2->m_edges.append(e1i);
		v2->m_edges.append(e2i);*/

		///printf("%d %d %d\n", e0i, e1i, e2i);

		find_edge(e0i)->m_faces.append(fi);
		find_edge(e1i)->m_faces.append(fi);;
		find_edge(e2i)->m_faces.append(fi);

		// don't keep pointers since the vector might be reallocated
		// make sure the shortest one is in edges[0]
		/*if (e2->length() < e1->length())
			qSwap(e2, e1);
		if (e1->length() < e0)->length())
			qSwap(e1, e0);
		if (find_edge(e2)->length() < find_edge(e1)->length())
			qSwap(e2, e1); don't need that */ 


	}
}
void TriMesh::computeVertArea(VectorXd& vertArea) const
{
    vertArea = VectorXd::Zero(numVerts());
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVert;
        getFaceVerts(face, fVert);
        assert(fVert.size() == 3);

        double faceArea = computeFaceArea(face);
        for (unsigned i = 0; i < 3; ++i) vertArea(fVert[i]) += faceArea;
    }
    vertArea /= 3.0;
}
Пример #11
0
//reads in an object from a .obj file
BasicObject::BasicObject(const std::string &filename, const float _shininess){

	shininess    = _shininess;

	_numVerticies = numVertices(filename.c_str());
	_numFaces 	  = numFaces(filename.c_str());
	_indexCount   = _numFaces * 3;

	verticies 	  = getVertices(filename.c_str(), _numVerticies);
	normals 	  = getNormals(filename.c_str(), _numVerticies);
	faces 		  = getFaces(filename.c_str(), _numFaces);
	texCoords 	  = getTextureCoords(filename.c_str(), _numVerticies);

}
Пример #12
0
void Mesh::commitRemove()
{
	// first go over all the points and tell them where they go
	int count = 0;
	for(int i = 0; i < numVtx(); ++i)
	{
		Vertex_handle v = find_vertex(i);
		if (v->m_tran == -1)
			v->m_index = count++;
		else
			v->m_index = -1; // to be removed
		v->m_tran = -1;
	}
	// no go over the faces and transfer their point references
	count = 0;
	for(int i = 0; i < numFaces(); ++i)
	{
		Face_handle f = find_facet(i);
		bool remove = false;
		for(int ii = 0; ii < f->size(); ++ii)
		{
			int newvi = find_vertex(f->m_pi[ii])->m_index;
			f->m_pi[ii] = newvi;
			remove |= (newvi == -1);
		}
		if (!remove)
			f->m_index = count++;
		else 
			f->m_index = -1;
	}
	// actually remove the vertices
	Vertex_iterator vit = vertices_begin();
	while(vit != vertices_end())
	{
		if (vit->m_index == -1)
			vit = m_vtx.erase(vit);
		else
			++vit;
	}

	// remove faces
	Face_iterator fit = faces_begin();
	while(fit != faces_end())
	{
		if (fit->m_index == -1)
			fit = m_face.erase(fit);
		else
			++fit;
	}
}
Пример #13
0
void Mesh::buildVerticesInFaces()
{
	for(int i = 0; i < numVtx(); ++i)
	{
		Vertex &v = m_vtx[i];
		v.faceIndexs().clear();
	}
	for(int fi = 0; fi < numFaces(); ++fi)
	{
		Face &face = m_face[fi];
		for(int i = 0; i < face.size(); ++i)
		{
			m_vtx[face.vertexIndex(i)].faceIndexs().push_back(fi);
		}
	}
}
Пример #14
0
float Mesh::compute_triangle_surfaces()
{
	m_totalSurface = 0.0;
	for(int i = 0; i < numFaces(); ++i)
	{
		Face &face = m_face[i];

		Vec3 v1(face.vertex(1)->point(), face.vertex(0)->point());
		Vec3 v2(face.vertex(2)->point(), face.vertex(0)->point());
		Vec3 cross = Vec3::crossProd(v1, v2);
	
		face.surface() = cross.length() / 2.0f;
		m_totalSurface += face.surface();
	}

	return m_totalSurface;
}
Пример #15
0
// only triangles
Mesh::TIndexList Mesh::Vertex::neiVertices() const
{
	TIndexList ret;

	for(int i = 0; i < numFaces(); ++i)
	{
		Face_const_handle f = face(i);
		for(int vi = 0; vi < f->size(); ++vi)
		{
			int cv = f->vertexIndex(vi);
			if (cv != index() && !ret.contains(cv)) 
				ret.append(cv);
		}

	}
	return ret;
}
void TriMesh::computeDivergence(const std::vector<Vec3>& faceVector, VectorXd& vertForm) const
{
    vertForm = VectorXd::Zero(numVerts());
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVert;
        getFaceVerts(face, fVert);
        assert(fVert.size() == 3);
        
        Vec3 n = computeFaceNormal(face);
        for (unsigned i = 0; i < 3; ++i) 
        {
            Vec3 p1 = getVertPos(fVert[(i+1)%3]);
            Vec3 p2 = getVertPos(fVert[(i+2)%3]);
            vertForm[fVert[i]] += 0.5*faceVector[face].dot(n.cross(p2-p1));
        }
    }
}
double TriMesh::computeMaxEdgeLength() const
{
    double maxLen = 0.0;
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVerts;
        getFaceVerts(face, fVerts);
        assert(fVerts.size() == 3);

        for (unsigned i = 0; i < 3; ++i) 
        {
            unsigned vert0 = fVerts[(i+1)%3];
            unsigned vert1 = fVerts[(i+2)%3];
            double len = computeEdgeLength(vert0, vert1);
            maxLen = std::max(maxLen, len);
        }
    }
    return maxLen;
}
void TriMesh::buildHeatKernel(SparseMatrix& A, double timestep) const
{
    VectorXd diag;
    computeVertArea(diag);
    std::map< std::pair<unsigned,unsigned>, double > offdiag; 
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVert;
        getFaceVerts(face, fVert);
        assert(fVert.size() == 3);

        for (unsigned i = 0; i < 3; ++i)
        {
            unsigned vert0 = fVert[(i+1)%3];
            unsigned vert1 = fVert[(i+2)%3];
            if (vert0 > vert1) std::swap(vert0, vert1);
            std::pair<unsigned,unsigned> edge(vert0,vert1);

            double value = timestep * 0.5 * computeFaceCotan(face, i);
            diag(vert0) += value;
            diag(vert1) += value;
            if (offdiag.find(edge) == offdiag.end())
                offdiag[edge] = -value;
            else
                offdiag[edge] -= value;
        }
    }

    std::vector<Triplet> triplet;
    for(unsigned i = 0; i < diag.size(); ++i)
    {
        triplet.push_back(Triplet(i,i,diag(i)));
    }
    for(std::map< std::pair<unsigned,unsigned>, double >::const_iterator 
        it = offdiag.begin(); it != offdiag.end(); ++it)
    {
        triplet.push_back(Triplet(it->first.first,it->first.second,it->second));
        triplet.push_back(Triplet(it->first.second,it->first.first,it->second));        
    } 
    
    A.resize(numVerts(), numVerts());
    A.setFromTriplets(triplet.begin(),triplet.end());
}
Пример #19
0
void Mesh::makeClosenessEdges()
{
	int hasCount = 0;
	TSmallLargeEdgeI makec;
	for(int fi = 0; fi < numFaces(); ++fi)
	{
		Face_const_handle f = find_facet(fi);
		const TIndexList& clsf = f->closeFaces();
		if (clsf.size() == 0)
			continue;

		++hasCount;
		for(int cfi = 0; cfi < clsf.size(); ++cfi)
		{
			addEdgeOnceUsing(fi, clsf[cfi], makec, &Mesh::addCloseEdge);
		}
	}

	printf("Faces with close edges=%d\n", hasCount);

}
void TriMesh::computeVertNormals(std::vector<Vec3>& vertNormal) const
{
    vertNormal = std::vector<Vec3>(numVerts(), Vec3::Zero());
    
    for (unsigned face = 0; face < numFaces(); ++face) 
    {
        std::vector<unsigned> fVert;
        getFaceVerts(face, fVert);
        assert(fVert.size() == 3);

        double faceArea = computeFaceArea(face);
        Vec3 faceNormal = computeFaceNormal(face);
        for (unsigned i = 0; i < 3; ++i) 
            vertNormal[fVert[i]] += faceArea * faceNormal;
    }

    for (unsigned vert = 0; vert < numVerts(); ++vert) 
    {
        vertNormal[vert].normalize();
    }
}
Пример #21
0
Vec3 Mesh::centerOfMass()
{
	// compute for every face
	for(int i = 0; i < numFaces(); ++i)
	{
		Face &f = m_face[i];
		f.m_center.clear();
		for(int i = 0; i <  f.size(); ++i)
			f.m_center += f.vertex(i)->point();
		f.m_center /=  f.size();
	}

	// now for all of the mess seperatly.
	Vec3 centerOfMass(0,0,0);
	for (Mesh::Vertex_iterator v = this->vertices_begin(); v != this->vertices_end(); v++)
	{
		centerOfMass = centerOfMass + (v->point()); // - CGAL::ORIGIN);
	}

	unsigned int size = this->size_of_vertices();
	m_computedCenterOfMass = Vec3(centerOfMass.x/size, centerOfMass.y/size, centerOfMass.z/size);

	return m_computedCenterOfMass;
}
Пример #22
0
void Mesh::saveSubMesh(const QString& filename, const TIndexList& facesList) const
{
	QFile file(filename);
	file.open(QFile::WriteOnly | QFile::Truncate);
	file.setTextModeEnabled(true);
	QTextStream out(&file);

	out << "OFF\n";

	int nVtx = numVtx();
	int newIndexCounter = 0;
	// do we need only a subset of the vertices?
	QVector<int> newToOld;
	QHash<int, int> oldToNew; // old index -> new index.
	if (facesList.size() != numFaces())
	{
		for(TIndexList::const_iterator pfi = facesList.constBegin(); pfi != facesList.constEnd(); ++pfi)
		{
			Face_const_handle f = find_facet(*pfi);
			for(int vfi = 0; vfi < f->size(); ++vfi)
			{
				int vi = f->vertexIndex(vfi);
				if (!oldToNew.contains(vi))
					oldToNew.insert(vi, newIndexCounter++);
			}
		}
		newToOld.resize(newIndexCounter);

		// invert the map because we want a map from new to old
		for(QHash<int, int>::iterator hit = oldToNew.begin(); hit != oldToNew.end(); ++hit)
		{
			newToOld[hit.value()] = hit.key();
		}

		nVtx = newIndexCounter;

	}

	// number of vertices, faces, 0
	out << nVtx << " " << facesList.size() << " 0\n";
	for(int i = 0; i < nVtx; ++i)
	{
		Vertex_const_handle v;
		if (newIndexCounter > 0)
			v = find_vertex(newToOld[i]);
		else
			v = find_vertex(i);
		const Vec3 &p = v->point();
		out << p.x << " " << p.y << " " << p.z << "\n";
	}

	for(TIndexList::const_iterator pfi = facesList.constBegin(); pfi != facesList.constEnd(); ++pfi)
	{
		Face_const_handle f = find_facet(*pfi);
		out << f->size();
		for(int vfi = 0; vfi < f->size(); ++vfi)
		{
			int fii = f->vertexIndex(vfi);
			if (newIndexCounter > 0)
				fii = oldToNew[fii];
			out << " " << fii;
		}
		out << "\n";
	}

}
Пример #23
0
SparseTableView face2Vertices(const UnstructuredGrid& grid)
{
    return SparseTableView(grid.face_nodes, grid.face_nodepos, numFaces(grid));
}