void MxHeap::downheap(unsigned int i) { MxHeapable *moving = ref(i); uint index = i; uint l = left(i); uint r = right(i); uint largest; while( l<length() ) { if( r<length() && ref(l)->heap_key() < ref(r)->heap_key() ) largest = r; else largest = l; if( moving->heap_key() < ref(largest)->heap_key() ) { place(ref(largest), index); index = largest; l = left(index); r = right(index); } else break; } if( index != i ) place(moving, index); }
void MxHeap::upheap(unsigned int i) { MxHeapable *moving = ref(i); uint index = i; uint p = parent(i); while( index>0 && moving->heap_key() > ref(p)->heap_key() ) { place(ref(p), index); index = p; p = parent(p); } if( index != i ) place(moving, index); }
bool MxPropSlim::decimate(unsigned int target, float max_error, void* cb_params) { MxPairContraction conx; max_error += EDGE_BASE_ERROR; while( valid_faces > target ) { MxHeapable *top = heap.top(); if( !top ) { return false; } if( -top->heap_key()>max_error ) { return true; } edge_info *info = (edge_info *)heap.extract(); MxVertexID v1 = info->v1; MxVertexID v2 = info->v2; if( m->vertex_is_valid(v1) && m->vertex_is_valid(v2) ){ m->compute_contraction (v1, v2, &conx); conx.dv1[0] = float(info->target[0] - m->vertex(v1)[0]); conx.dv1[1] = float(info->target[1] - m->vertex(v1)[1]); conx.dv1[2] = float(info->target[2] - m->vertex(v1)[2]); conx.dv2[0] = float(info->target[0] - m->vertex(v2)[0]); conx.dv2[1] = float(info->target[1] - m->vertex(v2)[1]); conx.dv2[2] = float(info->target[2] - m->vertex(v2)[2]); if( contraction_callback ) (*contraction_callback)(conx, -(info->heap_key()+EDGE_BASE_ERROR), cb_params); apply_contraction(conx, info); } xr_delete(info); } return true; }