/************************************************************************ * * * Since one the polygon's vertex has been changed, we need to rebuild * * 'yedge'. * * */ ReactionType Polygon::resize_done(short, short) { int index = FindDuplicateVertex(aperture/2); if (index >= 0) { if (closed && index < npnts || (!closed) && index < npnts - 1) { erase(); DeleteVertex(index); draw(); } } build_yedge(); some_info(FALSE); return REACTION_NONE; }
bool Graph::EdgeCollapse(long v1, long v2) { long edgeToDelete = GetEdgeID(v1, v2); if (edgeToDelete >= 0) { // delete the edge (v1, v2) DeleteEdge(edgeToDelete); // add v2 to v1 ancestors m_vertices[v1].m_ancestors.push_back(v2); // add v2's ancestors to v1's ancestors m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), m_vertices[v2].m_ancestors.begin(), m_vertices[v2].m_ancestors.end()); // update adjacency information SArray<long, SARRAY_DEFAULT_MIN_SIZE> & v1Edges = m_vertices[v1].m_edges; long b = -1; long idEdge; for(size_t ed = 0; ed < m_vertices[v2].m_edges.Size(); ++ed) { idEdge = m_vertices[v2].m_edges[ed]; if (m_edges[idEdge].m_v1 == v2) { b = m_edges[idEdge].m_v2; } else { b = m_edges[idEdge].m_v1; } if (GetEdgeID(v1, b) >= 0) { m_edges[idEdge].m_deleted = true; m_vertices[b].DeleteEdge(idEdge); m_nE--; } else { m_edges[idEdge].m_v1 = v1; m_edges[idEdge].m_v2 = b; v1Edges.Insert(idEdge); } } // delete the vertex v2 DeleteVertex(v2); return true; } return false; }
bool Graph::EdgeCollapse(long v1, long v2) { long edgeToDelete = GetEdgeID(v1, v2); if (edgeToDelete >= 0) { // delete the edge (v1, v2) DeleteEdge(edgeToDelete); // add v2 to v1 ancestors m_vertices[v1].m_ancestors.push_back(v2); // add v2's ancestors to v1's ancestors m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), m_vertices[v2].m_ancestors.begin(), m_vertices[v2].m_ancestors.end()); // update adjacency information std::set<long> & v1Edges = m_vertices[v1].m_edges; std::set<long>::const_iterator ed(m_vertices[v2].m_edges.begin()); std::set<long>::const_iterator itEnd(m_vertices[v2].m_edges.end()); long b = -1; for(; ed != itEnd; ++ed) { if (m_edges[*ed].m_v1 == v2) { b = m_edges[*ed].m_v2; } else { b = m_edges[*ed].m_v1; } if (GetEdgeID(v1, b) >= 0) { m_edges[*ed].m_deleted = true; m_vertices[b].DeleteEdge(*ed); m_nE--; } else { m_edges[*ed].m_v1 = v1; m_edges[*ed].m_v2 = b; v1Edges.insert(*ed); } } // delete the vertex v2 DeleteVertex(v2); return true; } return false; }
//******************************************** // DeleteVertex at the end that are flagged with // sequence_number >= sequence_number //******************************************** int CPath3d::RemovePathEnd(int sequence_number, int ID, double x, double y, double z) { int n = m_ArrayVertex.GetSize()-1; // first verify that the line number is there while (n>=0) { int SeqNum = GetVertex(n)->Get_sequence_number(); if (SeqNum == sequence_number) break; n--; } if (n<0) return 1; // now delete until we find the sequence_number n = m_ArrayVertex.GetSize()-1; while (n>=0) { if (GetVertex(n)->Get_sequence_number() == sequence_number) break; DeleteVertex(n); n--; } if (n<0) return 1; // find which segment we nearly pass through by // finding the minimum distance to all of them double mindist=1e99; int mini=0; n = m_ArrayVertex.GetSize()-2; CVertex3d Point(x,y,z); while (n>=0) { double dist = FindDistPointToSegment(GetVertex(n),&Point,GetVertex(n+1)); if (dist < mindist) { mindist = dist; mini = n; } if (GetVertex(n)->Get_sequence_number() != sequence_number || GetVertex(n)->GetID() == ID) break; n--; } // now delete all of the line number // or until we find the ID n = m_ArrayVertex.GetSize()-1; while (n>=0) { if (GetVertex(n)->Get_sequence_number() != sequence_number || GetVertex(n)->GetID() == ID) break; if (n == mini+1) { // instead of deleting the last segment // that goes through the point // modify it to go to the new point GetVertex(n)->Set(x,y,z); break; } DeleteVertex(n); n--; } if (n<0) return 1; return 0; }
block* complex::Merge(node* n) { list<block*> sub_blocks; Recurse(n,&sub_blocks,0); list<block*>::iterator sbit=sub_blocks.begin(); // if (sbit==sub_blocks.end()) // exit(1); block* b=new block(BC(*sbit),this); // block* b=new block(*((*sbit)->bc),this); // assert(b->bdry_verts.Empty()); // (b->bc)->SetAs(BC(*sbit)); BC(b).SetAs(BC(*sbit)); for(int i=0;i<DIM;++i) BC(b)++; int level=(cube_bits-BC(b).Bits())/DIM; for(int i=0;i<level*DIM;++i) BC(b)--; BC(b).Coordinates(min); for(int i=0;i<level*DIM;++i) BC(b)++; vertex* v; int vc[DIM]; int flag=1; cell_iter bvit; cell_iter cit; cobdry_iter cbit; while(sbit!=sub_blocks.end()) { bvit=(*sbit)->bdry_verts.Begin(); while(bvit!=(*sbit)->bdry_verts.End()) { v=(vertex*)(*bvit); v->bc->Coordinates(vc); flag=1; for (int i=0; i<DIM; ++i) flag*=(((min[i]<vc[i])&&(vc[i]<min[i]+Power2(level)))||((vc[i]==0)||(vc[i]==Power2(cube_bits/DIM)))); if (flag) { if (!(v->Interior())) { v->MarkInterior(); DeleteVertex(v); b->cells[0].InsertUniqueSort(v); } } else b->bdry_verts.InsertUniqueSort(v); ++bvit; } for(int i=0;i<DIM;++i) { cit=(*sbit)->cells[i].Begin(); while(cit!=(*sbit)->cells[i].End()) { b->cells[i].InsertUniqueSort(Ptr(cit)); ++cit; } } ++sbit; } cit=b->cells[0].Begin(); while(cit!=b->cells[0].End()) { cbit=((vertex*)(*cit))->Cobdry()->Begin(); // cout << "size " << (*cit)->Cobdry()->Size() << endl; while(cbit!=((vertex*)(*cit))->Cobdry()->End()) { ((edge*)Ptr(cbit))->MarkInterior(); // b->cells[1].InsertUniqueSort(Ptr(cbit)); if (b->cells[1].Find(Ptr(cbit))==b->cells[1].End()) { b->cells[1].InsertUniqueSort(Ptr(cbit)); } ++cbit; } ++cit; } cit=b->cells[1].Begin(); while(cit!=b->cells[1].End()) { cbit=((edge*)(*cit))->Cobdry()->Begin(); // cout << "size " << (*cit)->Cobdry()->Size() << endl; while(cbit!=((edge*)(*cit))->Cobdry()->End()) { ((ncell*)Ptr(cbit))->MarkInterior(); // b->cells[2].InsertUniqueSort(Ptr(cbit)); if (b->cells[2].Find(Ptr(cbit))==b->cells[2].End()) { b->cells[2].InsertUniqueSort(Ptr(cbit)); } ++cbit; } ++cit; } for(int i=3;i<DIM;++i) { cit=b->cells[i-1].Begin(); while(cit!=b->cells[i-1].End()) { cbit=((ncell*)(*cit))->Cobdry()->Begin(); // cout << "size " << (*cit)->Cobdry()->Size() << endl; while(cbit!=((ncell*)(*cit))->Cobdry()->End()) { ((ncell*)Ptr(cbit))->MarkInterior(); // b->cells[i].InsertUniqueSort(Ptr(cbit)); if (b->cells[i].Find(Ptr(cbit))==b->cells[i].End()) { b->cells[i].InsertUniqueSort(Ptr(cbit)); } ++cbit; } ++cit; } } if (n==cubes.Root) cubes.Root=b; else { node* parent=n->Parent; if (parent->Left==n) parent->Left=b; else parent->Right=b; b->Parent=parent; } Delete(n,0); return(b); }
//******************************************** // DeleteVertex at the end that are flagged with // sequence_number >= sequence_number //******************************************** int CPath3d::RemovePathEnd(int sequence_number, int ID, double x, double y, double z) { if (TheFrame) TheFrame->GViewDlg.m_view.OpenGLMutex->Lock(); int n = m_ArrayVertex.GetSize()-1; setup_pointer p=TheFrame->GCodeDlg.Interpreter->p_setup; float xtool = p->tool_table[p->selected_tool_slot].xoffset; float ytool = p->tool_table[p->selected_tool_slot].yoffset; float ztool = p->tool_table[p->selected_tool_slot].length; x -= xtool; y -= ytool; z -= ztool; // first verify that the line number is there while (n>=0) { int SeqNum = GetVertex(n)->Get_sequence_number(); if (SeqNum == sequence_number) break; n--; } if (n<0) { if (TheFrame) TheFrame->GViewDlg.m_view.OpenGLMutex->Unlock(); return 1; } // now delete until we find the sequence_number n = m_ArrayVertex.GetSize()-1; while (n>=0) { if (GetVertex(n)->Get_sequence_number() == sequence_number) break; DeleteVertex(n); n--; } if (n<0) { if (TheFrame) TheFrame->GViewDlg.m_view.OpenGLMutex->Unlock(); return 1; } // find which segment we nearly pass through by // finding the minimum distance to all of them double mindist=1e99; int mini=0; n = m_ArrayVertex.GetSize()-2; CVertex3dFast Point(x,y,z); while (n>=0) { double dist = FindDistPointToSegment(GetVertex(n),&Point,GetVertex(n+1)); if (dist < mindist) { mindist = dist; mini = n; } if (GetVertex(n)->Get_sequence_number() != sequence_number || GetVertex(n)->GetID() == ID) break; n--; } // now delete all of the line number // or until we find the ID n = m_ArrayVertex.GetSize()-1; while (n>=0) { if (GetVertex(n)->Get_sequence_number() != sequence_number || GetVertex(n)->GetID() == ID) break; if (n == mini+1) { // instead of deleting the last segment // that goes through the point // modify it to go to the new point GetVertex(n)->Set(x,y,z); break; } DeleteVertex(n); n--; } if (TheFrame) TheFrame->GViewDlg.m_view.OpenGLMutex->Unlock(); if (n<0) return 1; return 0; }
VOID DeleteDuplicateVertices(LEVEL_DATA *pLevel, BOOL bSelOnly) { #if 0 INT i, j; DWORD dwSize; ROUNDED_VERTEX huge *pRoundedVertex; if (pLevel->nVertices > 0) { dwSize = (DWORD)pLevel->nVertices * (DWORD)sizeof(ROUNDED_VERTEX); pRoundedVertex = (ROUNDED_VERTEX *)GlobalAllocPtr(GPTR, dwSize); if (pRoundedVertex == NULL) { MsgBox( hwndMDIClient, MB_ICONEXCLAMATION, "Out of memory" ); return; } for(i = 0; i < pLevel->nVertices; ++i) { pRoundedVertex[i].x = (long)Round(pLevel->pVertexData[i].x); pRoundedVertex[i].y = (long)Round(pLevel->pVertexData[i].y); pRoundedVertex[i].z = (long)Round(pLevel->pVertexData[i].z); } for(i = 0; i < pLevel->nVertices - 1; ++i) { for(j = i + 1; j < pLevel->nVertices; ++j) { if ( pRoundedVertex[i].x == pRoundedVertex[j].x && pRoundedVertex[i].y == pRoundedVertex[j].y && pRoundedVertex[i].z == pRoundedVertex[j].z ) { if ((pLevel->pVertexData + j)->flags & VF_SELECTED) { (pLevel->pVertexData + i)->flags |= VF_SELECTED; } ReplaceVertex(pLevel, j, i); DeleteVertex(pLevel, j); pLevel->bRebuildZone = TRUE; while(j < pLevel->nVertices) { pRoundedVertex[j].x = pRoundedVertex[j+1].x; pRoundedVertex[j].y = pRoundedVertex[j+1].y; pRoundedVertex[j].z = pRoundedVertex[j+1].z; ++j; } break; } } } GlobalFreePtr(pRoundedVertex); } #else INT i, j, n, num_deleted_vertices, num_deleted_polygons; double dx, dy, dz; HCURSOR hcurSave; hcurSave = SetCursor(LoadCursor(NULL, IDC_WAIT)); num_deleted_vertices = 0; num_deleted_polygons = 0; if (bSelOnly) { n = pLevel->nVertices; } else { n = pLevel->nVertices - 1; } if (pLevel->nVertices > 0) { for(i = 0; i < n; ++i) { if (bSelOnly) { if (((pLevel->pVertexData + i)->flags & VF_SELECTED) == 0) { continue; } j = 0; } else { j = i + 1; } while(j < pLevel->nVertices) { if (i != j) { dx = (double)(pLevel->pVertexData + i)->x - (double)(pLevel->pVertexData + j)->x; dy = (double)(pLevel->pVertexData + i)->y - (double)(pLevel->pVertexData + j)->y; dz = (double)(pLevel->pVertexData + i)->z - (double)(pLevel->pVertexData + j)->z; if (dx * dx + dy * dy + dz * dz < 4.0) { if ((pLevel->pVertexData + j)->flags & VF_SELECTED) { (pLevel->pVertexData + i)->flags |= VF_SELECTED; } num_deleted_vertices += 1; num_deleted_polygons += ReplaceVertex(pLevel, j, i); DeleteVertex(pLevel, j); pLevel->bRebuildZone = TRUE; break; } } ++j; } } } if (num_deleted_vertices == 1) { MsgBox( hwndMDIClient, MB_ICONINFORMATION, "1 duplicate vertex has been deleted" ); } else if (num_deleted_vertices > 1) { MsgBox( hwndMDIClient, MB_ICONINFORMATION, "%d duplicate vertices have been deleted", num_deleted_vertices ); } if (num_deleted_polygons == 1) { MsgBox( hwndMDIClient, MB_ICONINFORMATION, "1 polygon with duplicated vertices has been deleted" ); } else if (num_deleted_polygons > 1) { MsgBox( hwndMDIClient, MB_ICONINFORMATION, "%d polygons with duplicated vertices have been deleted", num_deleted_polygons ); } #endif SetCursor(hcurSave); return; } // DeleteDuplicateVertices
VOID DeleteSelections(LEVEL_DATA *pLevel) { INT i, j, n; POLYGON huge *p; HCURSOR hcurSave; hcurSave = SetCursor(LoadCursor(NULL, IDC_WAIT)); // // If any polygon uses a selected vertex then select it also. // p = pLevel->pPolygonData; for(i = 0; i < pLevel->nPolygons; ++i) { if ((p->flags & PF_SELECTED) == 0) { n = (p->flags & 7) + 3; for(j = 0; j < n; ++j) { if ((pLevel->pVertexData + p->vertices[j])->flags & VF_SELECTED) { p->flags |= PF_SELECTED; break; } } } ++p; } // // Unlink any polygon that is linked to a selected polygon. // p = pLevel->pPolygonData; for(i = 0; i < pLevel->nPolygons; ++i) { if (p->flags & PF_LINKED) { if ((pLevel->pPolygonData + p->polygon_link)->flags & PF_SELECTED) { p->flags &= ~PF_LINKED; } } ++p; } // // Delete selected polygons. // for(i = pLevel->nPolygons - 1; i >= 0; --i) { if ((pLevel->pPolygonData + i)->flags & PF_SELECTED) { DeletePolygon(pLevel, i); } } // // Delete the selected vertices. // for(i = pLevel->nVertices - 1; i >= 0; --i) { if ((pLevel->pVertexData + i)->flags & VF_SELECTED) { DeleteVertex(pLevel, i); } } SetCursor(hcurSave); return; } // DeleteSelections
int TopologicalGraph::MakeConnectedVertex() //returns the initial number of connected components {if(debug())DebugPrintf(" CheckPropConnected"); if(Set().exist(PROP_CONNECTED))return 1; Prop1<int>is_connected(Set(),PROP_CONNECTED); if(!nv()) return 0; if(debug())DebugPrintf("Executing MakeConnectedVertex"); bool simple = Set().exist(PROP_SIMPLE); bool bipartite = Set().exist(PROP_BIPARTITE); tvertex v,w; tbrin b,b0; int ncc = 0; svector<tvertex> stack(1,nv()); stack.SetName("TP:stack"); svector<tvertex> comp(0,nv()+1); comp.clear(); comp.SetName("TP:Comp"); int rank =0; int max_rank = 0; tvertex v0 = 1; tvertex previous_root = 1; int n = nv(); int m = ne(); tvertex vv = NewVertex(); NewEdge(vv,v0); comp[vv] = v0; while (max_rank < n) {while (comp[v0]!=0) v0++; comp[v0] = v0; ++ncc; if(ncc > 1) NewEdge(vv,v0); previous_root = v0; ++max_rank; stack[rank + 1] = v0; while(rank < max_rank) {v = stack[++rank]; b = b0 = pbrin[v]; if (b0!=0) do {w = vin[-b]; if(!comp[w]) {comp[w] = previous_root; stack[++max_rank] = w; } }while((b = cir[b])!= b0); } } if(ne() == m+1)// the graph was connected { DeleteVertex(vv); if(debug())DebugPrintf("End MakeConnectedVertex m=%d",ne()); return 1; } if(simple)Prop1<int> simple(Set(),PROP_SIMPLE); if(bipartite)Prop1<int> bipartite(Set(),PROP_BIPARTITE); if(Set(tvertex()).exist(PROP_COORD)) // Geometric Graph {Prop<Tpoint> vcoord(Set(tvertex()),PROP_COORD); int deg; tvertex w; Tpoint p(.0,.0); deg = 0; Forall_adj_brins_of_G(b,vv) {w = vin[-b]; ++deg; p += vcoord[w]; }
SSHANDLE * CSSolid::MergeSameVertices(int& nDeleted) { int nMerged = 0; nDeleted = 0; static SSHANDLE hDeletedList[128]; DoVertices: for(int v1 = 0; v1 < m_nVertices; v1++) { for(int v2 = 0; v2 < m_nVertices; v2++) { if(v1 == v2) continue; // no! if(!VectorCompare(m_Vertices[v1].pos, m_Vertices[v2].pos)) { // no match continue; } ++nMerged; // same vertices - kill v1, set edge refs to use v2. SSHANDLE hV1 = m_Vertices[v1].id; SSHANDLE hV2 = m_Vertices[v2].id; hDeletedList[nDeleted++] = hV1; DeleteVertex(v1); int nAffected; CSSEdge **ppEdges = FindAffectedEdges(&hV1, 1, nAffected); // run through edges and change references for(int e = 0; e < nAffected; e++) { if(ppEdges[e]->hvStart == hV1) ppEdges[e]->hvStart = hV2; if(ppEdges[e]->hvEnd == hV1) ppEdges[e]->hvEnd = hV2; CalcEdgeCenter(ppEdges[e]); } goto DoVertices; } } if(!nMerged) return NULL; int e; // kill edges that have same vertices for(e = 0; e < m_nEdges; e++) { CSSEdge &edge = m_Edges[e]; if(edge.hvStart != edge.hvEnd) continue; // edge is OK hDeletedList[nDeleted++] = edge.id; DeleteEdge(e); --e; } // kill similar edges (replace in faces too) DoEdges: for(e = 0; e < m_nEdges; e++) { CSSEdge &edge = m_Edges[e]; for(int e2 = 0; e2 < m_nEdges; e2++) { if(e == e2) continue; CSSEdge &edge2 = m_Edges[e2]; if(!((edge2.hvStart == edge.hvStart && edge2.hvEnd == edge.hvEnd) || (edge2.hvEnd == edge.hvStart && edge2.hvStart == edge.hvEnd))) continue; // we're going to delete edge2. SSHANDLE id2 = edge2.id; SSHANDLE id1 = edge.id; for(int f = 0; f < m_nFaces; f++) { CSSFace& face = m_Faces[f]; for(int ef = 0; ef < face.nEdges; ef++) { if(face.Edges[ef] == id2) { face.Edges[ef] = id1; break; } } } hDeletedList[nDeleted++] = id2; DeleteEdge(e2); goto DoEdges; } } // delete concurrent edge references in face for(int f = 0; f < m_nFaces; f++) { CSSFace& face = m_Faces[f]; DoConcurrentEdges: for(int ef1 = 0; ef1 < face.nEdges; ef1++) { for(int ef2 = 0; ef2 < face.nEdges; ef2++) { if(ef2 == ef1) continue; if(face.Edges[ef1] != face.Edges[ef2]) continue; // delete this ref memcpy(&face.Edges[ef2], &face.Edges[ef2+1], (face.nEdges-ef2) * sizeof(face.Edges[0])); --face.nEdges; goto DoConcurrentEdges; } } if(face.nEdges < 3) { // kill this face hDeletedList[nDeleted++] = face.id; DeleteFace(f); --f; } } return hDeletedList; }