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++; } } } }
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); } } } }
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");*/ }
/* ================== 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; }