/*------------------------------------------------------------------------------*/ GW_Vertex* GW_Mesh::InsertVertexInFace( GW_Face& Face, GW_Float x, GW_Float y, GW_Float z ) { GW_Vertex* pVert0 = Face.GetVertex(0); GW_Vertex* pVert1 = Face.GetVertex(1); GW_Vertex* pVert2 = Face.GetVertex(2); GW_ASSERT( pVert0!=NULL ); GW_ASSERT( pVert1!=NULL ); GW_ASSERT( pVert2!=NULL ); /* create two new-faces */ GW_Face* pFace1 = &this->CreateNewFace(); GW_Face* pFace2 = &this->CreateNewFace(); this->SetNbrFace( this->GetNbrFace()+2 ); this->SetFace( this->GetNbrFace()-2, pFace1 ); this->SetFace( this->GetNbrFace()-1, pFace2 ); /* create one new vertex */ GW_Vertex* pNewVert = &this->CreateNewVertex(); GW_Vector3D pos = pVert0->GetPosition()*x + pVert1->GetPosition()*y + pVert2->GetPosition()*z; pNewVert->SetPosition( pos ); pNewVert->BuildRawNormal(); this->SetNbrVertex( this->GetNbrVertex()+1 ); this->SetVertex( this->GetNbrVertex()-1, pNewVert ); /* assign vertex to faces */ pFace1->SetVertex( *pVert0, *pVert1, *pNewVert ); pFace2->SetVertex( *pNewVert, *pVert1, *pVert2 ); Face.SetVertex( *pVert0, *pNewVert, *pVert2 ); /* assign dependance vertex->mother face */ pNewVert->SetFace( Face ); pVert0->SetFace( Face ); pVert1->SetFace( *pFace1 ); pVert2->SetFace( Face ); /* outer faces */ if( Face.GetFaceNeighbor(2)!=NULL ) { GW_I32 nEdgeNumber = Face.GetFaceNeighbor(2)->GetEdgeNumber( Face ); GW_ASSERT( nEdgeNumber>=0 ); Face.GetFaceNeighbor(2)->SetFaceNeighbor( pFace1, nEdgeNumber ); } if( Face.GetFaceNeighbor(0)!=NULL ) { GW_I32 nEdgeNumber = Face.GetFaceNeighbor(0)->GetEdgeNumber( Face ); GW_ASSERT( nEdgeNumber>=0 ); Face.GetFaceNeighbor(0)->SetFaceNeighbor( pFace2, nEdgeNumber ); } /* build connectivity of inner faces */ pFace1->SetFaceNeighbor( pFace2, &Face, Face.GetFaceNeighbor(2) ); pFace2->SetFaceNeighbor( Face.GetFaceNeighbor(0), &Face, pFace1 ); GW_Face* pTempFace = Face.GetFaceNeighbor(1); Face.SetFaceNeighbor( pFace2, pTempFace, pFace1 ); return pNewVert; }
/*------------------------------------------------------------------------------*/ GW_Vertex* GW_Mesh::InsertVertexInEdge( GW_Vertex& Vert1, GW_Vertex& Vert2, GW_Float x, GW_Bool& bIsNewVertCreated ) { if( x<GW_EPSILON ) { bIsNewVertCreated = GW_False; return &Vert2; } if( x>1-GW_EPSILON ) { bIsNewVertCreated = GW_False; return &Vert1; } bIsNewVertCreated = GW_True; /* create the new vertex */ GW_Vertex* pNewVert = &this->CreateNewVertex(); this->SetNbrVertex( this->GetNbrVertex()+1 ); this->SetVertex( this->GetNbrVertex()-1, pNewVert ); /* set position */ pNewVert->SetPosition( Vert1.GetPosition()*x + Vert2.GetPosition()*(1-x) ); /* retrieve the neigbor faces face */ GW_Face* pFace1 = NULL; GW_Face* pFace2 = NULL; Vert1.GetFaces( Vert2, pFace1, pFace2 ); GW_ASSERT( pFace1!=NULL || pFace2!=NULL ); /* assign the face of new vertex */ if( pFace1!=NULL ) pNewVert->SetFace( *pFace1 ); else if( pFace2!=NULL ) pNewVert->SetFace( *pFace2 ); GW_I32 nVert1Num1, nVert1Num2, nVert1Num3, nVert2Num1, nVert2Num2, nVert2Num3; GW_Face* pNewFace1 = NULL; GW_Face* pNewFace2 = NULL; if( pFace1!=NULL ) { nVert1Num1 = pFace1->GetEdgeNumber( Vert1 ); GW_ASSERT( nVert1Num1>=0 ); nVert1Num2 = pFace1->GetEdgeNumber( Vert2 ); GW_ASSERT( nVert1Num2>=0 ); nVert1Num3 = 3-nVert1Num2-nVert1Num1; pNewFace1 = &this->CreateNewFace(); this->SetNbrFace( this->GetNbrFace()+1 ); this->SetFace( this->GetNbrFace()-1, pNewFace1 ); pNewFace1->SetVertex( *pFace1->GetVertex(nVert1Num3), nVert1Num3 ); pNewFace1->SetVertex( Vert2, nVert1Num2 ); pNewFace1->SetVertex( *pNewVert, nVert1Num1 ); /* connectivity between Face1 and new face */ GW_Face* pFaceNeighbor = pFace1->GetFaceNeighbor(nVert1Num1); pNewFace1->SetFaceNeighbor( pFaceNeighbor, nVert1Num1 ); pNewFace1->SetFaceNeighbor( pFace1, nVert1Num2 ); if( pFaceNeighbor!=NULL ) { GW_I32 nNum = pFaceNeighbor->GetEdgeNumber( Vert2, *pFace1->GetVertex(nVert1Num3) ); GW_ASSERT( nNum>=0 ); pFaceNeighbor->SetFaceNeighbor( pNewFace1, nNum ); } /* connectivity for face 1 */ pFace1->SetFaceNeighbor( pNewFace1, nVert1Num1 ); pFace1->SetVertex( *pNewVert, nVert1Num2 ); /* reassign vertex 2 */ Vert2.SetFace( *pNewFace1 ); } if( pFace2!=NULL ) { nVert2Num1 = pFace2->GetEdgeNumber( Vert1 ); GW_ASSERT( nVert2Num1>=0 ); nVert2Num2 = pFace2->GetEdgeNumber( Vert2 ); GW_ASSERT( nVert2Num2>=0 ); nVert2Num3 = 3-nVert2Num2-nVert2Num1; pNewFace2 = &this->CreateNewFace(); this->SetNbrFace( this->GetNbrFace()+1 ); this->SetFace( this->GetNbrFace()-1, pNewFace2 ); pNewFace2->SetVertex( *pFace2->GetVertex(nVert2Num3), nVert2Num3 ); pNewFace2->SetVertex( Vert2, nVert2Num2 ); pNewFace2->SetVertex( *pNewVert, nVert2Num1 ); /* connectivity between Face2 and new face */ GW_Face* pFaceNeighbor = pFace2->GetFaceNeighbor(nVert2Num1); pNewFace2->SetFaceNeighbor( pFaceNeighbor, nVert2Num1 ); pNewFace2->SetFaceNeighbor( pFace2, nVert2Num2 ); if( pFaceNeighbor!=NULL ) { GW_I32 nNum = pFaceNeighbor->GetEdgeNumber( Vert2, *pFace2->GetVertex(nVert2Num3) ); GW_ASSERT( nNum>=0 ); pFaceNeighbor->SetFaceNeighbor( pNewFace2, nNum ); } /* connectivity for face 1 */ pFace2->SetFaceNeighbor( pNewFace2, nVert2Num1 ); pFace2->SetVertex( *pNewVert, nVert2Num2 ); /* reassign vertex 2 */ Vert2.SetFace( *pNewFace2 ); } /* set inter connectivity */ if( pNewFace1!=NULL ) pNewFace1->SetFaceNeighbor( pNewFace2, nVert1Num3 ); if( pNewFace2!=NULL ) pNewFace2->SetFaceNeighbor( pNewFace1, nVert2Num3 ); /* last thing : compute normal */ pNewVert->BuildRawNormal(); return pNewVert; }
GW_I32 GW_ASELoader::Load(GW_Mesh& Mesh, const char *name, GW_I32 bits) { FILE *strm = fopen(name, "r"); if (!strm) return GW_Error_Opening_File; Release(); want = bits; GetInfo(strm); Allocate(); GetData(strm); fclose(strm); if (want & kNormals) MakeNormals(); if (want & kTexCoord && numTexVerts) Align(); else if (want & kTexCoord && !numTexVerts) return 0; numIndex = numFaces * 3; /* retrieve information */ Mesh.SetNbrVertex( this->GetNumVerts() ); Mesh.SetNbrFace( this->GetNumFaces() ); GW_U32* pFace = this->GetFaces(); GW_Real32* pVert = this->GetVerts(); GW_Real32* pNormal = this->GetVertNormals(); GW_Real32* pTexture = this->GetTexture(); GW_Vertex* pCurVert = NULL; GW_Vector3D Pos, Normal; std::map<int, int> VertCorrespondance; /* load vertex */ for( GW_I32 i=0; i<this->GetNumVerts(); ++i ) { Pos = GW_Vector3D( pVert[3*i], pVert[3*i+1], pVert[3*i+2] ); /* this is to avoid an annoying problem of vertex duplication */ for( GW_I32 j=0; j<i; ++j ) { if( GW_ABS(pVert[3*i+0] - pVert[3*j+0])<GW_EPSILON && GW_ABS(pVert[3*i+1] - pVert[3*j+1])<GW_EPSILON && GW_ABS(pVert[3*i+2] - pVert[3*j+2])<GW_EPSILON ) VertCorrespondance[j] = i; } if( pNormal!=NULL ) Normal = GW_Vector3D( pNormal[3*i], pNormal[3*i+1], pNormal[3*i+2] ); pCurVert = &Mesh.CreateNewVertex(); pCurVert->SetPosition( Pos ); pCurVert->SetNormal( Normal ); if( want & kTexCoord ) { for( GW_U32 s=0; s<1; ++s ) { if( pTexture[2*i+s]<0 ) pTexture[2*i+s] += 1; if( pTexture[2*i+s]>1 ) pTexture[2*i+s] -= 1; } pCurVert->SetTexCoords( pTexture[2*i+0], pTexture[2*i+1] ); } Mesh.SetVertex( i, pCurVert ); } /* load faces */ GW_Face* pCurFace = NULL; for( GW_I32 i=0; i<this->GetNumFaces(); ++i ) { pCurFace = &Mesh.CreateNewFace(); GW_U32 FaceNumber[3]; for( GW_U32 s=0; s<3; ++s ) { FaceNumber[s] = pFace[3*i+s]; if( VertCorrespondance.find(FaceNumber[s])!=VertCorrespondance.end() ) FaceNumber[s] = VertCorrespondance[FaceNumber[s]]; } pCurFace->SetVertex( *Mesh.GetVertex(FaceNumber[0]), *Mesh.GetVertex(FaceNumber[1]), *Mesh.GetVertex(FaceNumber[2]) ); Mesh.SetFace( i, pCurFace ); } return GW_OK; }