//----------------------------------------------------------------------------- // Purpose: // Input : pSolid - // pData - // Output : Returns TRUE to continue enumerating. //----------------------------------------------------------------------------- static BOOL FindDuplicateFaceIDs(CMapSolid *pSolid, FindDuplicateFaceIDs_t *pData) { int nFaceCount = pSolid->GetFaceCount(); for (int i = 0; i < nFaceCount; i++) { CMapFace *pFace = pSolid->GetFace(i); if (pData->All.FindFaceID(pFace->GetFaceID()) != -1) { if (pData->Duplicates.FindFaceID(pFace->GetFaceID()) != -1) { pData->Duplicates.AddToTail(pFace); } } else { pData->All.AddToTail(pFace); } } return(TRUE); }
//----------------------------------------------------------------------------- // Purpose: // Input : List - //----------------------------------------------------------------------------- void CMapSideList::RemoveFacesNotInList(CMapObjectList &List) { if (m_Faces.Count() > 0) { for (int i = m_Faces.Count() - 1; i >= 0; i--) { CMapFace *pFace = m_Faces.Element(i); if (FindFaceIDInList(pFace->GetFaceID(), List) == NULL) { CMapSolid *pSolid = (CMapSolid *)pFace->GetParent(); UpdateDependency(pSolid, NULL); m_Faces.FastRemove(i); } } } }
//----------------------------------------------------------------------------- // Purpose: Called from OnClone and OnPaste, updates references to face IDs // in the one solid with references to corresponding face IDs in // another solid. // Input : pOrigSolid - Solid with faces to find. // pNewSolid - Solid with faces to replace with. // Output : Returns true if it replaced at least one face. //----------------------------------------------------------------------------- bool CMapSideList::ReplaceSolidFaces(CMapSolid *pOrigSolid, CMapSolid *pNewSolid) { bool bDidSomething = false; for (int i = 0; i < pOrigSolid->GetFaceCount(); i++) { CMapFace *pFace = pOrigSolid->GetFace(i); int nIndex = m_Faces.FindFaceID(pFace->GetFaceID()); if (nIndex != -1) { // // Replace the element in our face list and unlink // us from the original solid, relinking us to the new solid. // m_Faces.Element(nIndex) = pNewSolid->GetFace(i); UpdateDependency(pOrigSolid, pNewSolid); bDidSomething = true; } } return(bDidSomething); }
//----------------------------------------------------------------------------- // Purpose: // Input : pObject - // eNotifyType - //----------------------------------------------------------------------------- void CMapSideList::OnNotifyDependent(CMapClass *pObject, Notify_Dependent_t eNotifyType) { if (eNotifyType == Notify_Removed) { // // Check for a solid that we refer to via face ID going away. // CMapSolid *pSolid = dynamic_cast<CMapSolid *>(pObject); if ((pSolid != NULL) && (m_Faces.Count() > 0)) { // // Remove faces from our list that are in this solid. // Do it backwards so we can remove them as we go. Also, add // the face IDs to our list of lost IDs so that we can reacquire // the face in our list if the solid comes back later. // for (int i = m_Faces.Count() - 1; i >= 0; i--) { CMapFace *pFace = m_Faces.Element(i); if (pFace != NULL) { CMapSolid *pParent = (CMapSolid *)pFace->GetParent(); if (pParent == pSolid) { m_LostFaceIDs.AddToTail(pFace->GetFaceID()); m_Faces.FastRemove(i); } } } // // Submit the updated face list to our parent entity. // UpdateParentKey(); } } }
void CSSolid::FromMapSolid(CMapSolid *p, bool bSkipDisplacementFaces) { // so we can pass NULL (default) or another solid (to copy): CMapSolid *pSolid; if(p) pSolid = p; else pSolid = m_pMapSolid; m_nFaces = 0; m_nEdges = 0; m_nVertices = 0; // Create vertices, edges, faces. int nSolidFaces = pSolid->GetFaceCount(); for(int i = 0; i < nSolidFaces; i++) { CMapFace *pSolidFace = pSolid->GetFace(i); if (bSkipDisplacementFaces) { if (pSolidFace->HasDisp()) continue; } // Add a face CSSFace *pFace = AddFace(); memcpy(pFace->PlanePts, pSolidFace->plane.planepts, sizeof(Vector) * 3); pFace->texture = pSolidFace->texture; pFace->normal = pSolidFace->plane.normal; pFace->m_nFaceID = pSolidFace->GetFaceID(); // Displacement. if ( pSolidFace->HasDisp() ) { pFace->m_hDisp = EditDispMgr()->Create(); CMapDisp *pDisp = EditDispMgr()->GetDisp( pFace->m_hDisp ); CMapDisp *pSolidDisp = EditDispMgr()->GetDisp( pSolidFace->GetDisp() ); pDisp->CopyFrom( pSolidDisp, false ); } // Convert vertices and edges int nFacePoints = pSolidFace->nPoints; Vector *pFacePoints = pSolidFace->Points; SSHANDLE hLastVertex = 0; // valid IDs start at 1 SSHANDLE hThisVertex, hFirstVertex; for(int pt = 0; pt <= nFacePoints; pt++) { int iVertex; if(pt < nFacePoints) { // YWB: Change leniency from 1.0 down to 0.1 iVertex = GetVertexIndex(pFacePoints[pt], 0.1f); if (iVertex == -1) { // not found - add the vertex CSSVertex *pVertex = AddVertex(&iVertex); pVertex->pos = pFacePoints[pt]; } // assign this vertex handle hThisVertex = m_Vertices[iVertex].id; if (pt == 0) hFirstVertex = hThisVertex; } else { // connect last to first hThisVertex = hFirstVertex; } if (hLastVertex) { // create the edge from the last vertex to current vertex. // first check to see if this edge already exists.. int iEdge = GetEdgeIndex(hLastVertex, hThisVertex); CSSEdge *pEdge; if (iEdge == -1) { // not found - add new edge pEdge = AddEdge(&iEdge); pEdge->hvStart = hLastVertex; pEdge->hvEnd = hThisVertex; // make sure edge center is valid: CalcEdgeCenter(pEdge); } else { pEdge = &m_Edges[iEdge]; } // add the edge to the face pFace->Edges[pFace->nEdges++] = pEdge->id; // set edge's face array if(!pEdge->Faces[0]) pEdge->Faces[0] = pFace->id; else if(!pEdge->Faces[1]) pEdge->Faces[1] = pFace->id; else { // YWB try filling in front side // rather than ASSERT(0) crash pEdge->Faces[0] = pFace->id; AfxMessageBox("Edge with both face id's already filled, skipping..."); } } hLastVertex = hThisVertex; } } }