void MeshMender::BuildGroups( Triangle* tri, //the tri of interest TriangleList& possibleNeighbors, //all tris arround a vertex NeighborGroupList& neighborGroups, //the neighbor groups to be updated std::vector< Vertex >& theVerts, CanSmoothChecker* smoothChecker, const float& minCreaseAngle) { if( (!tri) || (tri->handled) ) return; Triangle* neighbor1 = NULL; Triangle* neighbor2 = NULL; FindNeighbors(tri, possibleNeighbors, &neighbor1, &neighbor2,theVerts); //see if I can join my first neighbors group if(neighbor1 && (neighbor1->group != NO_GROUP)) { if( smoothChecker->CanSmooth(tri,neighbor1, minCreaseAngle) ) { neighborGroups[neighbor1->group].push_back(tri->myID); tri->group = neighbor1->group; } } //see if I can join my second neighbors group if(neighbor2 && (neighbor2->group!= NO_GROUP)) { if( smoothChecker->CanSmooth(tri,neighbor2, minCreaseAngle) ) { neighborGroups[neighbor2->group].push_back(tri->myID); tri->group = neighbor2->group; } } //I either couldn't join, or they weren't in a group, so I think I'll //just go and start my own group...right here we go. if(tri->group == NO_GROUP) { tri->group = neighborGroups.size(); neighborGroups.push_back( TriangleList() ); neighborGroups.back().push_back(tri->myID); } assert((tri->group != NO_GROUP) && "error!: tri should have a group set"); tri->handled = true; //continue growing our group with each neighbor. BuildGroups(neighbor1,possibleNeighbors,neighborGroups,theVerts,smoothChecker,minCreaseAngle); BuildGroups(neighbor2,possibleNeighbors,neighborGroups,theVerts,smoothChecker,minCreaseAngle); }
BOOL CXTPRibbonBuilder::BuildCategories(CXTPPropExchange* pPX, CXTPRibbonBar* pRibbonBar) { CXTPPropExchangeEnumeratorPtr pEnumerator(pPX->GetEnumerator(_T("CATEGORY"))); POSITION pos = pEnumerator->GetPosition(0); while (pos) { CXTPPropExchangeSection pxTab(pEnumerator->GetNext(pos)); CString strElementName; PX_String(&pxTab, _T("ELEMENT_NAME"), strElementName); CCmdTarget* pElement = CreateElement(strElementName); if (pElement == NULL) continue; CXTPRibbonTab* pTab = DYNAMIC_DOWNCAST(CXTPRibbonTab, pElement); if (!pTab) { delete pElement; continue; } CString strName; PX_String(&pxTab, _T("NAME"), strName); pTab->SetCaption(strName); CString strKeys; PX_String(&pxTab, _T("KEYS"), strKeys); pTab->SetKeyboardTip(strKeys); pRibbonBar->InsertTab(pRibbonBar->GetTabCount(), pTab); m_arrImageLarge.RemoveAll(); m_arrImageSmall.RemoveAll(); CXTPPropExchangeSection pxPanels(pxTab->GetSection(_T("PANELS"))); BuildGroups(&pxPanels, pTab); LoadIcons(&pxTab); } return TRUE; }
void MeshMender::ProcessBinormals(TriangleList& possibleNeighbors, std::vector< Vertex >& theVerts, std::vector< unsigned int >& mappingNewToOldVert, D3DXVECTOR3 workingPosition) { NeighborGroupList neighborGroups;//a fresh group for each pass //reset each triangle to prepare for smoothing group building unsigned int i; for(i =0; i < possibleNeighbors.size(); ++i ) { m_Triangles[ possibleNeighbors[i] ].Reset(); } //now start building groups CanSmoothBinormalsChecker canSmoothBinormalsChecker; for(i =0; i < possibleNeighbors.size(); ++i ) { Triangle* currTri = &(m_Triangles[ possibleNeighbors[i] ]); assert(currTri); if(!currTri->handled) { BuildGroups(currTri,possibleNeighbors, neighborGroups, theVerts, &canSmoothBinormalsChecker ,MinBinormalsCreaseCosAngle ); } } std::vector<D3DXVECTOR3> groupBinormalVectors; for(i=0; i<neighborGroups.size(); ++i) { D3DXVECTOR3 gbinormal(0,0,0); for(unsigned int t = 0; t < neighborGroups[i].size(); ++t)//for each triangle in the group, { TriID tID = neighborGroups[i][t]; gbinormal+= m_Triangles[tID].binormal; } gbinormal = glm::normalize(gbinormal.GLMvec());//D3DXVec3Normalize( &gbinormal, &gbinormal ); groupBinormalVectors.push_back(gbinormal); } //next step, ensure that triangles in different groups are not //sharing vertices. and give the shared vertex their new group vector std::set<size_t> otherGroupsIndices; for( i = 0; i < neighborGroups.size(); ++i ) { TriangleList& curGroup = neighborGroups[ i ]; std::set<size_t> thisGroupIndices; for( size_t t = 0; t < curGroup.size(); ++t ) //for each tri { TriID tID = curGroup[ t ]; for(size_t indx = 0; indx < 3 ; ++indx)//for each vert in that tri { //if it is at the positions in question if( theVerts[ m_Triangles[tID].indices[indx] ].pos == workingPosition) { //see if another group is already using this vert if(otherGroupsIndices.find( m_Triangles[tID].indices[indx] ) != otherGroupsIndices.end() ) { //then we need to make a new vertex Vertex ov; ov = theVerts[ m_Triangles[tID].indices[indx] ]; ov.binormal = groupBinormalVectors[i]; size_t oldIndex = m_Triangles[tID].indices[indx]; size_t newIndex = theVerts.size(); theVerts.push_back(ov); AppendToMapping( oldIndex , m_originalNumVerts , mappingNewToOldVert); UpdateIndices(oldIndex,newIndex,curGroup); } else { //otherwise, just update it with the new vector theVerts[ m_Triangles[tID].indices[indx] ].binormal = groupBinormalVectors[i]; } //store that we have used this index, so other groups can check thisGroupIndices.insert(m_Triangles[tID].indices[indx]); } } } for(std::set<size_t>::iterator it = thisGroupIndices.begin(); it!= thisGroupIndices.end() ; ++it) { otherGroupsIndices.insert(*it); } } }