void CAdjacent::generateTriangles(ushort*idx,uint count){

	Triangle t;
	for (short i=0;i<count;i+=3)
	{
		Index3 ix(idx[i],idx[i+1],idx[i+2]);
		ushort xyz[3]={0};
		getEdgesIncr(ix,xyz);
		uint h=HashEdge(xyz[0],xyz[1]); 
		t.e1=m_edgeIDMap[h];
		h=HashEdge(xyz[0],xyz[2]); 
		t.e2=m_edgeIDMap[h];
		h=HashEdge(xyz[1],xyz[2]); 
		t.e3=m_edgeIDMap[h];

		m_triangles.push_back(t);
	}
	int ent=0;
	for (int i=0;i<m_triangles.size();i++)
	{
		Triangle &t=m_triangles[i];
		for (int j=i+1;j<m_triangles.size();j++)
		{
			Triangle &t2=m_triangles[j];
			if( t.e1==t2.e1 || 
				t.e1==t2.e2 || 
				t.e1==t2.e3 || 

				t.e2==t2.e1 || 
				t.e2==t2.e2 || 
				t.e2==t2.e3 ||

				t.e3==t2.e1 || 
				t.e3==t2.e2 || 
				t.e3==t2.e3  )
			{
				m_TriMap[i].insert(j);
				m_TriMap[j].insert(i);
				ent++;
			}
		}
	}
}
示例#2
0
static void
AddHashEdge(unsigned v1, unsigned v2, unsigned i)
{
    hashedge_t *he = AllocMem(OTHER, sizeof(hashedge_t), true);
    unsigned slot = HashEdge(v1, v2);
    
    he->i = i;
    he->next = hashedges[slot];
    hashedges[slot] = he;
}
void CAdjacent::generateEdges(ushort*idx,uint count){
	for (short i=0;i<count;i+=3)
	{
		Index3 ix(idx[i],idx[i+1],idx[i+2]);
		ushort xyz[3]={0};
		getEdgesIncr(ix,xyz);
		Edge e;
		e.i1=xyz[0];
		e.i2=xyz[1];
		m_edgeMap[e.i1].insert(e.i2);
		m_edgeMap[e.i2].insert(e.i1);
		e.i2=xyz[2];
		m_edgeMap[e.i1].insert(e.i2);
		m_edgeMap[e.i2].insert(e.i1);
		e.i1=xyz[1];
		m_edgeMap[e.i1].insert(e.i2);
		m_edgeMap[e.i2].insert(e.i1);
	}

	shortSetMap::iterator it=m_edgeMap.begin();
	Edge e;
	for (;it!=m_edgeMap.end();++it)
	{
		e.i1=it->first;
		shortSet&s=it->second;
		shortSet::iterator it2=s.begin();
		for (;it2!=s.end();it2++)
		{
			e.i2=*it2;
			if(e.i1<e.i2){
				m_edgeIDMap[HashEdge(e.i1,e.i2)]=m_edges.size();
				m_edges.push_back(e);
			}
		}
	}
}
示例#4
0
void ComplexMesh::Load(const BaseMesh &Mesh)
{
    FreeMemory();
    
    _Vertices.Allocate(Mesh.VertexCount());
    _Triangles.Allocate(Mesh.FaceCount());
    _HalfEdges.Allocate(Mesh.FaceCount() * 3);
    _FullEdges.FreeMemory();

    for(UINT i = 0; i < _Vertices.Length(); i++)
    {
        _Vertices[i].Pos() = Mesh.Vertices()[i].Pos;
        _Vertices[i].TexCoords() = Mesh.Vertices()[i].TexCoord;
        _Vertices[i].Boundary() = false;
        _Vertices[i]._Index = i;
    }

    InitHashTable(_Vertices.Length());

    for(UINT TriangleIndex = 0; TriangleIndex < _Triangles.Length(); TriangleIndex++)
    {
        Triangle &CurTriangle = _Triangles[TriangleIndex];
        UINT LocalIndices[3];
        LocalIndices[0] = Mesh.Indices()[TriangleIndex * 3 + 0];
        LocalIndices[1] = Mesh.Indices()[TriangleIndex * 3 + 1];
        LocalIndices[2] = Mesh.Indices()[TriangleIndex * 3 + 2];
        CurTriangle._Index = TriangleIndex;
        for(UINT LocalEdgeIndex = 0; LocalEdgeIndex < 3; LocalEdgeIndex++)
        {
            Vertex *SearchV[2];

            CurTriangle._HalfEdges[LocalEdgeIndex] = &_HalfEdges[TriangleIndex * 3 + LocalEdgeIndex];
            CurTriangle._Vertices[LocalEdgeIndex] = &_Vertices[LocalIndices[LocalEdgeIndex]];
            _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._NextEdge = &_HalfEdges[TriangleIndex * 3 + (LocalEdgeIndex + 1) % 3];

            SearchV[0] = &_Vertices[LocalIndices[(LocalEdgeIndex + 1) % 3]];
            SearchV[1] = &_Vertices[LocalIndices[(LocalEdgeIndex + 2) % 3]];
            if(SearchV[0]->Index() > SearchV[1]->Index())
            {
                Utility::Swap(SearchV[0], SearchV[1]);
            }
            FullEdge &Target = FindFullEdge(SearchV);
            if(Target != FullEdge::NotFound)
            {
                PersistentAssert(Target.GetTriangle(1) == Triangle::Boundary, "Duplicate edge; 2-manifold criterion violated.");
                //PersistentAssert(Target.GetTriangle(1) == Triangle::Boundary,
                //                 String("Duplicate edge; 2-manifold criterion violated: ") + String(SearchV[0]->Index()) + String(", ") + String(SearchV[1]->Index()));

                _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._AcrossEdge = &Target;
                Target._Triangles[1] = &CurTriangle;
            }
            else
            {
                FullEdge *NewEdge = new FullEdge;
                Assert(NewEdge != NULL, "Out of memory");
                NewEdge->_Index = _FullEdges.Length();
                NewEdge->_Triangles[0] = &CurTriangle;
                NewEdge->_Triangles[1] = &Triangle::Boundary;
                NewEdge->_Vertices[0] = SearchV[0];
                NewEdge->_Vertices[1] = SearchV[1];
                _HalfEdges[TriangleIndex * 3 + LocalEdgeIndex]._AcrossEdge = NewEdge;

                _FullEdges.PushEnd(NewEdge);
                HashEdge(*NewEdge);
            }
        }
    }

    for(UINT TriangleIndex = 0; TriangleIndex < _Triangles.Length(); TriangleIndex++)
    {
        Triangle &CurTriangle = _Triangles[TriangleIndex];
        for(UINT AdjacentTriangleIndex = 0; AdjacentTriangleIndex < 3; AdjacentTriangleIndex++)
        {
            Triangle &AdjTriangle = CurTriangle.GetNeighboringTriangle(AdjacentTriangleIndex);
        }
    }

    ClearHashTable();
    
    for(UINT i = 0; i < _FullEdges.Length(); i++)
    {
        if(_FullEdges[i]->Boundary())
        {
            _FullEdges[i]->GetVertex(0).Boundary() = true;
            _FullEdges[i]->GetVertex(1).Boundary() = true;
            _FullEdges[i]->OrientMatchingBoundary();
        }
    }

    PrepareTopology();

    /*if(!Oriented())
    {
        Orient();
    }
    PersistentAssert(Oriented(), "Mesh not oriented");*/

}
示例#5
0
/*
==================
GetEdge

Don't allow four way edges
==================
*/
static int
GetEdge(mapentity_t *entity, const vec3_t p1, const vec3_t p2,
        const face_t *face)
{
    struct lumpdata *edges = &entity->lumps[LUMP_EDGES];
    int v1, v2;
    int i;
    unsigned edge_hash_key;
    hashedge_t *he;

    if (!face->contents[0])
        Error("Face with 0 contents (%s)", __func__);

    v1 = GetVertex(entity, p1);
    v2 = GetVertex(entity, p2);

    edge_hash_key = HashEdge(v1, v2);

    if (options.BSPVersion == BSPVERSION) {
        bsp29_dedge_t *edge;

        for (he = hashedges[edge_hash_key]; he; he = he->next) {
            i = he->i;
            edge = (bsp29_dedge_t *)edges->data + i;
            if (v1 == edge->v[1] && v2 == edge->v[0]
                && pEdgeFaces1[i] == NULL
                && pEdgeFaces0[i]->contents[0] == face->contents[0]) {
                pEdgeFaces1[i] = face;
                return -(i + cStartEdge);
            }
        }

        /* emit an edge */
        i = edges->index;
        edge = (bsp29_dedge_t *)edges->data + i;
        if (edges->index >= edges->count)
            Error("Internal error: didn't allocate enough edges?");
        edge->v[0] = v1;
        edge->v[1] = v2;
    } else {
        bsp2_dedge_t *edge = (bsp2_dedge_t *)edges->data;

        for (he = hashedges[edge_hash_key]; he; he = he->next) {
            i = he->i;
            edge = (bsp2_dedge_t *)edges->data + i;
            if (v1 == edge->v[1] && v2 == edge->v[0]
                && pEdgeFaces1[i] == NULL
                && pEdgeFaces0[i]->contents[0] == face->contents[0]) {
                pEdgeFaces1[i] = face;
                return -(i + cStartEdge);
            }
        }

        /* emit an edge */
        i = edges->index;
        edge = (bsp2_dedge_t *)edges->data + i;
        if (edges->index >= edges->count)
            Error("Internal error: didn't allocate enough edges?");
        edge->v[0] = v1;
        edge->v[1] = v2;
    }

    AddHashEdge(v1, v2, edges->index);

    edges->index++;
    map.cTotal[LUMP_EDGES]++;
    pEdgeFaces0[i] = face;
    return i + cStartEdge;
}