mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 11:26:11 +00:00
added handling of border vertices with the
new data structure.ongoing debugging
This commit is contained in:
parent
a0fd13ec5f
commit
72b5dab6be
@ -429,7 +429,8 @@ void OcmeEditPlugin::loadOcm(){
|
||||
|
||||
UpdateBoundingBox();
|
||||
setTrackBall();
|
||||
mm = gla->meshDoc->addNewMesh("Ocm patch");
|
||||
mm = gla->meshDoc->addNewMesh("Ocm patch");
|
||||
// mm ->cm.bbox = ocme_bbox;
|
||||
ocme_loaded = true;
|
||||
updateButtonsState();
|
||||
|
||||
|
||||
@ -59,6 +59,8 @@ struct GIndex{
|
||||
/* GISet is the set of GIndex corresponding to the same vertex*/
|
||||
struct GISet{
|
||||
std::map<CellKey,unsigned int > giset;
|
||||
unsigned int bi;
|
||||
typedef std::map<CellKey,unsigned int >::iterator CopiesIterator;
|
||||
typedef std::map<CellKey,unsigned int >::iterator iterator;
|
||||
|
||||
void Add(GIndex gi){
|
||||
@ -71,7 +73,7 @@ struct GISet{
|
||||
iterator begin(){return giset.begin();}
|
||||
iterator end(){return giset.end();}
|
||||
|
||||
const bool & operator < (const GISet & o) const {
|
||||
const bool operator < (const GISet & o) const {
|
||||
return giset<o.giset;
|
||||
}
|
||||
|
||||
@ -82,6 +84,8 @@ struct GISet{
|
||||
giset.erase((*i).first);
|
||||
}
|
||||
|
||||
unsigned int & BI(){return bi;}
|
||||
|
||||
int Index(CellKey ck){
|
||||
iterator gi = giset.find(ck);
|
||||
if(gi==giset.end()) return -1;
|
||||
@ -130,10 +134,19 @@ struct Box4{
|
||||
bool operator ==(const Box4 & b) const {return (bbox3==b.bbox3) && (sr==b.sr);}
|
||||
};
|
||||
|
||||
struct BorderIndex{
|
||||
BorderIndex(){}
|
||||
BorderIndex(unsigned int _vi,unsigned int _bi):vi(_vi),bi(_bi){}
|
||||
unsigned int
|
||||
vi, // pointer to a border vertex in the cell
|
||||
bi; // its incremental mark
|
||||
};
|
||||
|
||||
/* per cell auxiliary data structure for edit& commit */
|
||||
struct EditCommitAuxData{
|
||||
BoolVector deleted_face;
|
||||
BoolVector deleted_vertex;
|
||||
BoolVector deleted_border;
|
||||
|
||||
FBool is_in_kernel;
|
||||
FBool locked;
|
||||
@ -209,6 +222,9 @@ struct Cell{
|
||||
/* all the vertices assigned to this cell. NOTE: this is a shortcut, "vert" is also in this->elements */
|
||||
Chain<OVertex> *vert;
|
||||
|
||||
/* border vertices */
|
||||
Chain<BorderIndex> *border;
|
||||
|
||||
// auxiliary data needed for edit/Commit
|
||||
EditCommitAuxData * ecd;
|
||||
|
||||
|
||||
@ -279,12 +279,11 @@ main (int argc,char **argv )
|
||||
// printf("SIZE OF vcgMesh: %d\n",sizeof(vcgMesh));
|
||||
// printf("SIZE OF Impostor: %d\n",sizeof(Impostor));
|
||||
|
||||
SimpleDb::Index tp;
|
||||
tp.SetIFile(0);
|
||||
tp.SetISeg(10);
|
||||
unsigned int j = tp.ISeg();
|
||||
// _CrtSetBreakAlloc(1281429);
|
||||
|
||||
struct stat buf;
|
||||
|
||||
|
||||
|
||||
{
|
||||
int c;
|
||||
|
||||
@ -49,45 +49,6 @@ double CS(const int & h){ return cellsizes[15+h]; }
|
||||
int COff(const int & h){ return 15+h; }
|
||||
|
||||
|
||||
std::pair < OCME::CellsIterator ,bool > CachedMap::insert( const std::pair< CellKey,Cell*> & toinsert){
|
||||
return allcells.insert(toinsert);
|
||||
}
|
||||
|
||||
Cell* CachedMap::find(const CellKey & ck){
|
||||
CellsIterator ci ;
|
||||
|
||||
cache_access.lock();
|
||||
ci = cache.find(ck);// look in the cache
|
||||
if(ci!=cache.end()){
|
||||
cache_access.unlock();
|
||||
return (*ci).second; // found! return it
|
||||
}
|
||||
|
||||
ci = allcells.find(ck); // look in allcells
|
||||
if(ci==allcells.end()){
|
||||
cache_access.unlock();
|
||||
return 0; // if there is not, return
|
||||
}
|
||||
// lgn->Append("in cells");lgn->Push();
|
||||
|
||||
assert(ci != allcells.end());
|
||||
|
||||
if(cache.size()>100) cache.clear();
|
||||
|
||||
cache.insert(std::pair<CellKey,Cell*>(ck,(*ci).second));
|
||||
cache_access.unlock();
|
||||
return (*ci).second;
|
||||
}
|
||||
void CachedMap::erase( const CellKey & ck){
|
||||
cache_access.lock();
|
||||
cache.erase(ck);
|
||||
allcells.erase(ck);
|
||||
cache_access.unlock();
|
||||
}
|
||||
|
||||
OCME::CellsIterator CachedMap::begin() { return allcells.begin();}
|
||||
OCME::CellsIterator CachedMap::end() { return allcells.end();}
|
||||
size_t CachedMap::size() { return allcells.size();}
|
||||
|
||||
|
||||
|
||||
@ -97,6 +58,7 @@ OCME::OCME(){
|
||||
this->oce.AddNameTypeBound<GIndex>("GIndex");
|
||||
this->oce.AddNameTypeBound<OFace>("OFace");
|
||||
this->oce.AddNameTypeBound<OVertex>("OVertex");
|
||||
this->oce.AddNameTypeBound<BorderIndex>("BIndex");
|
||||
|
||||
this->oce.AddNameTypeBound<vcg::Point3f>("Coord3f");
|
||||
this->oce.AddNameTypeBound<vcg::Color4b>("Color4b");
|
||||
@ -107,6 +69,7 @@ OCME::OCME(){
|
||||
// InitRender();
|
||||
//this->oce.CreateFromString_UserTypes = &ocme_types_allocator;
|
||||
|
||||
gbi = 1;
|
||||
|
||||
params.side_factor = 50;
|
||||
kernelSetMark = 1;
|
||||
@ -307,8 +270,9 @@ Cell* OCME::GetCell(const CellKey & key,bool ifnot_create){
|
||||
if(!c){
|
||||
if(ifnot_create) {
|
||||
Cell * newc = NewCell(key);;
|
||||
newc->face = AddElement<OFace> ("f",newc);
|
||||
newc->vert = AddElement<OVertex> ("v",newc);
|
||||
newc->face = AddElement<OFace> ("f",newc);
|
||||
newc->vert = AddElement<OVertex> ("v",newc);
|
||||
newc->border = AddElement<BorderIndex> ("b",newc);
|
||||
if(this->record_cells_set_modification) {
|
||||
this->added_cells.push_back(key);
|
||||
this->touched_cells.push_back(key);
|
||||
@ -320,7 +284,7 @@ Cell* OCME::GetCell(const CellKey & key,bool ifnot_create){
|
||||
} else { assert(key== c->key);return c;}
|
||||
}
|
||||
|
||||
Impostor* GetImpostor(const CellKey & key, bool ifnot_create = true){
|
||||
Impostor* GetImpostor(const CellKey & , bool ifnot_create = true){
|
||||
assert(0);
|
||||
return 0;// not implemented yet
|
||||
ifnot_create = false;
|
||||
@ -335,8 +299,9 @@ Cell* OCME::GetCellC(const CellKey & key,bool ifnot_create){
|
||||
|
||||
if(ifnot_create) {
|
||||
Cell * newc = NewCell(key);;
|
||||
newc->face = AddElement<OFace> ("f",newc);
|
||||
newc->vert = AddElement<OVertex> ("v",newc);
|
||||
newc->face = AddElement<OFace> ("f",newc);
|
||||
newc->vert = AddElement<OVertex> ("v",newc);
|
||||
newc->border = AddElement<BorderIndex> ("b",newc);
|
||||
newc->impostor->InitDataCumulate(key.BBox3f());
|
||||
if(this->record_cells_set_modification) {
|
||||
this->added_cells.push_back(key);
|
||||
@ -482,14 +447,16 @@ int OCME::SizeOf(){
|
||||
for( i = this->cells.begin(); i != this->cells.end(); ++i){
|
||||
size+=(*i).second->SizeOf();
|
||||
}
|
||||
return size + 2 * sizeof(int);// one integer to indicate the number of cells
|
||||
return size + 3 * sizeof(int);// side factor, number of cells, gbi
|
||||
}
|
||||
|
||||
char * OCME::Serialize ( char * const buf){
|
||||
char * ptr = buf;
|
||||
CellsIterator i;
|
||||
*((int*)ptr) = (int) this->params.side_factor; ptr+=sizeof(int);
|
||||
*((int*)ptr) = (int) this->cells.size(); ptr+=sizeof(int);
|
||||
*((int*)ptr) = (int) this->params.side_factor; ptr+=sizeof(int);
|
||||
*((int*)ptr) = (int) this->cells.size(); ptr+=sizeof(int);
|
||||
*((int*)ptr) = (int) gbi; ptr+=sizeof(int);
|
||||
|
||||
for( i = this->cells.begin(); i != this->cells.end(); ++i)
|
||||
ptr = (*i).second->Serialize(ptr);
|
||||
return ptr;
|
||||
@ -499,6 +466,7 @@ char * OCME::DeSerialize ( char * const buf ){
|
||||
char *ptr = buf;
|
||||
this->params.side_factor = * (int*) ptr; ptr+=sizeof(int);
|
||||
int n_cells = * (int*) ptr; ptr+=sizeof(int);
|
||||
gbi = * (int*) ptr; ptr+=sizeof(int);
|
||||
|
||||
MemDbg::SetPoint(0);
|
||||
for(int i = 0 ; i< n_cells;++i){
|
||||
@ -509,7 +477,7 @@ char * OCME::DeSerialize ( char * const buf ){
|
||||
|
||||
/* here the attribute names have been loaded and
|
||||
the chains in lmc have been loaded, but all the
|
||||
pair in c.elements have NULL as cell pointer.
|
||||
pair in c.elements have NULL as chain pointer.
|
||||
Here we reconnect them.
|
||||
*/
|
||||
std::map<std::string, ChainBase * >::iterator ai;
|
||||
@ -519,9 +487,11 @@ char * OCME::DeSerialize ( char * const buf ){
|
||||
assert(chain!=NULL);
|
||||
(*ai).second = chain;
|
||||
|
||||
/* set face and vertex if needed */
|
||||
/* set face, vertex and border if needed */
|
||||
if((*ai).first == std::string("f")) c.face = (Chain<OFace>*)chain; else
|
||||
if((*ai).first == std::string("v")) c.vert = (Chain<OVertex>*)chain;
|
||||
if((*ai).first == std::string("v")) c.vert = (Chain<OVertex>*)chain;else
|
||||
if((*ai).first == std::string("b")) c.border = (Chain<BorderIndex>*)chain;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -531,6 +501,14 @@ char * OCME::DeSerialize ( char * const buf ){
|
||||
assert(chain!=NULL);
|
||||
(*ai).second = chain;
|
||||
}
|
||||
for( ai = c.perFace_attributes.begin(); ai != c.perFace_attributes.end(); ++ai){
|
||||
std::string name_of_chain = NameOfChain(c.key,(*ai).first);
|
||||
ChainBase * chain = oce.GetChain(name_of_chain);
|
||||
assert(chain!=NULL);
|
||||
(*ai).second = chain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
return ptr;
|
||||
|
||||
@ -208,6 +208,18 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
|
||||
}
|
||||
|
||||
StopRecordCellsSetModification();
|
||||
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
if(gPos[*vi].giset.size() > 1){
|
||||
for(GISet::CopiesIterator ci = gPos[*vi].giset.begin(); ci != gPos[*vi].giset.end();++ci){
|
||||
Cell * c = GetCell((*ci).first);
|
||||
assert(c);
|
||||
c->border->AddElem(BorderIndex((*ci).second, gbi ));
|
||||
}
|
||||
gbi++;
|
||||
}
|
||||
|
||||
|
||||
vcg::tri::Allocator<MeshType>::template DeletePerVertexAttribute (m,gPos);
|
||||
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ void OCME::FindRemovedElements( MeshType & m,
|
||||
|
||||
typename MeshType::FaceIterator fi;
|
||||
typename MeshType::VertexIterator vi;
|
||||
unsigned int i;
|
||||
|
||||
|
||||
std::vector<GIndex> committing_faces;
|
||||
std::vector<GISet> committing_vertices;
|
||||
@ -26,17 +26,17 @@ void OCME::FindRemovedElements( MeshType & m,
|
||||
/*
|
||||
find the GIndex being committed
|
||||
*/
|
||||
i = 0;
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi,++i)
|
||||
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
{
|
||||
GISet gposv = gPosV [i];
|
||||
GISet gposv = gPosV [*vi];
|
||||
if(!gposv.IsUnassigned() )
|
||||
committing_vertices.push_back(gposv);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for(fi = m.face.begin(); fi != m.face.end(); ++fi,++i){
|
||||
GIndex gposf = gPosF [i];
|
||||
|
||||
for(fi = m.face.begin(); fi != m.face.end(); ++fi ){
|
||||
GIndex gposf = gPosF [*fi];
|
||||
if(!gposf.IsUnassigned() )
|
||||
committing_faces.push_back(gposf);
|
||||
}
|
||||
@ -58,7 +58,7 @@ void OCME::FindRemovedElements( MeshType & m,
|
||||
std::vector<GISet> deleted_vertices;
|
||||
|
||||
SetDifference(edited_vertices,committing_vertices,deleted_vertices);
|
||||
for( i = 0; i < deleted_vertices.size(); ++i)
|
||||
for(unsigned int i = 0; i < deleted_vertices.size(); ++i)
|
||||
for(GISet::iterator di = deleted_vertices[i].begin(); di != deleted_vertices[i].end();++di )
|
||||
{
|
||||
Cell* c = GetCell((*di).first,false);
|
||||
@ -84,6 +84,11 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
|
||||
If this operation fails it means you are trying to commit something you did not take
|
||||
in edit with Edit(). In this case the function return, you should have called AddMesh.
|
||||
*/
|
||||
// create an attibute that will store the address in ocme
|
||||
typename MeshType::template PerVertexAttributeHandle<GISet> gPosVNew =
|
||||
vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<GISet> (m,"gposNew");
|
||||
|
||||
|
||||
typename MeshType::template PerVertexAttributeHandle<GISet> gPosV =
|
||||
vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<GISet> (m,"ocme_gindex");
|
||||
assert(vcg::tri::Allocator<MeshType>::IsValidHandle(m,gPosV));
|
||||
@ -105,20 +110,10 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
|
||||
vcg::tri::Allocator<MeshType>::template GetPerFaceAttribute<unsigned char> (m,"ocme_locked");
|
||||
assert(vcg::tri::Allocator<MeshType>::IsValidHandle(m,lockedF));
|
||||
|
||||
/* we will temporarily need a copy of the vertex position */
|
||||
// vcg::SimpleTempData<typename MeshType::VertContainer,GISet> gPosVNew(m.vert); // create the temporary data
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
gPosVNew[vi].Clear() ; // set the vertex as unassigned (i.e. to process)
|
||||
|
||||
|
||||
////////// check
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
for( GISet::iterator gi = gPosV[*vi].begin(); gi != gPosV[*vi].end();++gi){
|
||||
Cell *c = GetCell((*gi).first,false);
|
||||
assert(c);
|
||||
assert(c->vert->Size() > (*gi).second);
|
||||
}
|
||||
|
||||
|
||||
FindRemovedElements(m,gPosV,gPosF);
|
||||
FindRemovedElements(m,gPosV,gPosF);
|
||||
|
||||
|
||||
RecordCellsSetModification();
|
||||
@ -221,15 +216,15 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
|
||||
*/
|
||||
int vIndex[3];
|
||||
for(int i = 0; i < 3 ; ++i){
|
||||
vIndex[i] = gPosV[(*fi).V(i)].Index(ck);
|
||||
vIndex[i] = gPosVNew[(*fi).V(i)].Index(ck);
|
||||
assert(c->key == ck);
|
||||
assert(vIndex[i] < (int) c->vert->Size());
|
||||
// get the index of the vertx in this cell (or -1)
|
||||
// get the index of the vertex in this cell (or -1)
|
||||
if(vIndex[i]==-1){ // this vertex was not in ck at edit time
|
||||
vIndex[i] = c-> AddVertex(OVertex(*(*fi).V(i)) ); // no: add the vertex to it
|
||||
gPosV[(*fi).V(i)].Add(GIndex(ck,vIndex[i])); // record to index
|
||||
vIndex[i] = c-> AddVertex(OVertex(*(*fi).V(i)) ); // no: add the vertex to it
|
||||
gPosVNew[(*fi).V(i)].Add(GIndex(ck,vIndex[i])); // record to index
|
||||
}
|
||||
attr_map.ImportVertex(c,*(*fi).V(i),vIndex[i]); // import all the attributes specified
|
||||
attr_map.ImportVertex(c,*(*fi).V(i),vIndex[i]); // import all the attributes specified
|
||||
(*c->face)[gposf.i][i] = vIndex[i];
|
||||
assert(vIndex[i] < (int) c->vert->Size());
|
||||
}
|
||||
@ -238,27 +233,47 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
|
||||
c->bbox.Add(facebox,sr);
|
||||
}
|
||||
|
||||
// lgn->Append(" deleting vertices moved from cell");
|
||||
// {
|
||||
// unsigned int ii = 0;
|
||||
// for(vi = m.vert.begin(); vi != m.vert.end(); ++vi,++ii)
|
||||
// if(lockedV[*vi]==0) // skip if the vertex is not editable
|
||||
// {
|
||||
// GISet gposv = gPosV[*vi];
|
||||
// GISet gposv_old = gPosVOld[*vi];
|
||||
// gposv_old.sub(gposv);
|
||||
// for(GISet::iterator dvi = gposv_old.begin(); dvi != gposv_old.end(); ++dvi){
|
||||
// Cell * dvc = GetCell((*dvi).first,false);
|
||||
// assert(dvc);
|
||||
// dvc->ecd->deleted_vertex.SetAsVectorOfMarked();
|
||||
// dvc->ecd->deleted_vertex.SetMarked((*dvi).second,true);
|
||||
// toCleanUpCells.push_back(dvc);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// compare gPosV e gPosVNew to update the borders
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi){
|
||||
if(gPosVNew[*vi].giset.size() > 1) { // it is a border vertex
|
||||
unsigned int bi;
|
||||
GISet fresh_added = gPosVNew[*vi];
|
||||
|
||||
if(gPosV[*vi].giset.size() > 1) { // it also was a border vertex
|
||||
fresh_added.sub(gPosV[*vi]); // copies added by this commit
|
||||
bi = gPosV[*vi].BI(); // take its global border index
|
||||
}
|
||||
else
|
||||
bi = gbi++; // it is a new border vertex, create a new gbi
|
||||
|
||||
for(GISet::CopiesIterator ci = fresh_added.giset.begin(); ci != fresh_added.giset.end();++ci){
|
||||
Cell * c = GetCell((*ci).first);
|
||||
assert(c);
|
||||
c->border->AddElem(BorderIndex((*ci).second, bi ));
|
||||
assert((*ci).second < c->vert->Size());
|
||||
}
|
||||
}
|
||||
if(gPosV[*vi].giset.size() > 1) { // it WAS a border vertex
|
||||
GISet removed = gPosV[*vi];
|
||||
removed.sub(gPosVNew[*vi]); // cells for which vi USED to be a border vertex
|
||||
unsigned int bi = removed.BI();
|
||||
for(GISet::CopiesIterator ci = removed.giset.begin(); ci != removed.giset.end();++ci){
|
||||
Cell * c = GetCell((*ci).first);
|
||||
toCleanUpCells.push_back(c);
|
||||
assert(c);
|
||||
for(unsigned int ii = 0; ii < c->border->Size(); ++ii)// linear search! [to redo faster]
|
||||
if((*(c->border))[ii].bi == bi){
|
||||
c->ecd->deleted_border.SetAsVectorOfMarked();
|
||||
c->ecd->deleted_border.SetMarked(ii,true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!toCleanUpCells.empty()){
|
||||
RemoveDuplicates(toCleanUpCells);
|
||||
RemoveDeletedBorder(toCleanUpCells);
|
||||
RemoveDeletedFaces(toCleanUpCells);
|
||||
RemoveDeletedVertices(toCleanUpCells);
|
||||
}
|
||||
@ -286,6 +301,8 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
|
||||
RemoveCell((*ci)->key);
|
||||
}
|
||||
|
||||
vcg::tri::Allocator<MeshType>::template DeletePerVertexAttribute (m,gPosVNew);
|
||||
|
||||
StopRecordCellsSetModification();
|
||||
|
||||
this->ClearImpostors(this->touched_cells); // clear the part of the hierarchy containing the touched cells
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "ocme_definition.h"
|
||||
|
||||
void OCME::Verify(){ ;}
|
||||
|
||||
bool OCME::CheckFaceVertDeletions(Cell *c){ return true;
|
||||
|
||||
c->ecd->deleted_face.SetAsVectorOfBool();
|
||||
@ -35,6 +37,6 @@ bool OCME::CheckFaceVertexAdj(Cell *c){
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OCME:: CheckDependentSet(std::vector<Cell*> & dep){return true;
|
||||
bool OCME:: CheckDependentSet(std::vector<Cell*> & ){return true;
|
||||
|
||||
}
|
||||
|
||||
@ -44,22 +44,6 @@ std::string ToString(CellKey key);
|
||||
extern Logging * lgn;
|
||||
|
||||
|
||||
struct CachedMap{
|
||||
typedef std::map<CellKey,Cell*> CellsContainer;
|
||||
typedef CellsContainer::iterator CellsIterator;
|
||||
QMutex cache_access;
|
||||
CellsContainer allcells;
|
||||
CellsContainer cache;
|
||||
|
||||
std::pair < CellsIterator ,bool > insert( const std::pair< CellKey,Cell*> & toinsert);
|
||||
Cell * find ( const CellKey & ck);
|
||||
void erase( const CellKey & ck);
|
||||
CellsIterator begin();
|
||||
CellsIterator end() ;
|
||||
size_t size() ;
|
||||
|
||||
};
|
||||
|
||||
struct OCME{
|
||||
|
||||
OCME();
|
||||
@ -122,7 +106,6 @@ struct OCME{
|
||||
}
|
||||
};
|
||||
Statistics stat;
|
||||
|
||||
OOCEnv oce;
|
||||
|
||||
struct HashFunctor : public std::unary_function<CellKey, size_t>
|
||||
@ -163,6 +146,9 @@ struct OCME{
|
||||
// true if modification to the set of cells are recorded
|
||||
bool record_cells_set_modification;
|
||||
|
||||
// progressive mark to identify copies of the same vertex in different cells
|
||||
unsigned int gbi;
|
||||
|
||||
// cell added since record_cells_set_modification was set to true
|
||||
std::vector<CellKey> touched_cells;
|
||||
|
||||
@ -472,10 +458,8 @@ struct OCME{
|
||||
Note: this is because currently faces are not pointed by anyone
|
||||
*/
|
||||
void RemoveDeletedFaces( std::vector<Cell*> & cells);
|
||||
|
||||
/*
|
||||
*/
|
||||
void RemoveDeletedVertices( std::vector<Cell*> cells);
|
||||
void RemoveDeletedBorder(std::vector<Cell*> & cells);
|
||||
void RemoveDeletedVertices( std::vector<Cell*> cells);
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@ -4,13 +4,13 @@
|
||||
#include <vcg/complex/trimesh/update/normal.h>
|
||||
|
||||
|
||||
int CellDisk::get(CellToken *token){
|
||||
int CellDisk::get(CellToken * /*token*/){
|
||||
return 1;
|
||||
}
|
||||
int CellDisk::drop(CellToken *token){
|
||||
int CellDisk::drop(CellToken * /*token*/){
|
||||
return 1;
|
||||
}
|
||||
int CellDisk::size(CellToken *token){
|
||||
int CellDisk::size(CellToken * /*token*/){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -36,9 +36,9 @@ int CellRAM::size(CellToken *token){
|
||||
return c->SizeInRAM();
|
||||
}
|
||||
|
||||
int CellVideo::get(CellToken *token){return 1;}
|
||||
int CellVideo::drop(CellToken *token){return 1;}
|
||||
int CellVideo::size(CellToken *token){return 1;}
|
||||
int CellVideo::get(CellToken * /*token*/){return 1;}
|
||||
int CellVideo::drop(CellToken * /*token*/){return 1;}
|
||||
int CellVideo::size(CellToken * /*token*/){return 1;}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -19,14 +19,17 @@ struct Joiner{
|
||||
|
||||
class RemoveDuplicateVert_Compare{
|
||||
public:
|
||||
typename MeshType::template PerVertexAttributeHandle<unsigned int > * biV;
|
||||
inline bool operator()(VertexPointer const &a, VertexPointer const &b)
|
||||
{
|
||||
return (*a).cP() < (*b).cP();
|
||||
return (*biV)[a] < (*biV)[b];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static void JoinDuplicateVertex( MeshType & m, typename MeshType::template PerVertexAttributeHandle<GISet> & gPosV )
|
||||
static void JoinBorderVertices( MeshType & m,
|
||||
typename MeshType::template PerVertexAttributeHandle<GISet> & gPosV,
|
||||
typename MeshType::template PerVertexAttributeHandle<unsigned int > & biV)
|
||||
{
|
||||
if(m.vert.size()==0 || m.vn==0) return;
|
||||
|
||||
@ -36,11 +39,15 @@ static void JoinDuplicateVertex( MeshType & m, typename MeshType::template PerVe
|
||||
int deleted=0;
|
||||
int k=0;
|
||||
size_t num_vert = m.vert.size();
|
||||
std::vector<VertexPointer> perm(num_vert);
|
||||
std::vector<VertexPointer> perm;
|
||||
for(vi=m.vert.begin(); vi!=m.vert.end(); ++vi, ++k)
|
||||
perm[k] = &(*vi);
|
||||
if(biV[*vi] != 0)
|
||||
perm.push_back(&(*vi));
|
||||
|
||||
if(perm.empty()) return;
|
||||
|
||||
RemoveDuplicateVert_Compare c_obj;
|
||||
c_obj.biV = & biV;
|
||||
|
||||
std::sort(perm.begin(),perm.end(),c_obj);
|
||||
|
||||
@ -48,18 +55,18 @@ static void JoinDuplicateVertex( MeshType & m, typename MeshType::template PerVe
|
||||
i = j;
|
||||
mp[perm[i]] = perm[j];
|
||||
++i;
|
||||
for(;i!=num_vert;)
|
||||
for(;i!=perm.size();)
|
||||
{
|
||||
if( (! (*perm[i]).IsD()) &&
|
||||
(! (*perm[j]).IsD()) &&
|
||||
(*perm[i]).P() == (*perm[j]).cP() )
|
||||
(biV[*perm[i]] == biV[*perm[j]]) )
|
||||
{
|
||||
VertexPointer t = perm[i];
|
||||
mp[perm[i]] = perm[j];
|
||||
|
||||
gPosV[*perm[j]].Add(gPosV[*t]);
|
||||
++i;
|
||||
gPosV[*perm[j]].BI() = biV[*perm[j]]; //store in gPosV the global border index
|
||||
vcg::tri::Allocator<MeshType>::DeleteVertex(m,*t);
|
||||
++i;
|
||||
deleted++;
|
||||
}
|
||||
else
|
||||
@ -167,7 +174,13 @@ void OCME::Extract( std::vector<Cell*> & sel_cells, MeshType & m, AttributeMap
|
||||
if(!vcg::tri::Allocator<MeshType>::IsValidHandle(m,gPosV))
|
||||
gPosV = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<GISet> (m,"ocme_gindex");
|
||||
|
||||
// create an attibute that will store if the vertex is locked or not
|
||||
// create an attibute that will store the address in ocme for the vertex
|
||||
typename MeshType::template PerVertexAttributeHandle<unsigned int> biV =
|
||||
vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<unsigned int> (m,"bi");
|
||||
if(!vcg::tri::Allocator<MeshType>::IsValidHandle(m,biV))
|
||||
biV = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<unsigned int> (m,"bi");
|
||||
|
||||
// create an attibute that will store if the vertex is locked or not
|
||||
typename MeshType::template PerVertexAttributeHandle<unsigned char> lockedV =
|
||||
vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<unsigned char> (m,"ocme_locked");
|
||||
|
||||
@ -215,47 +228,53 @@ void OCME::Extract( std::vector<Cell*> & sel_cells, MeshType & m, AttributeMap
|
||||
{
|
||||
sr.Add((*ci)->key.h);
|
||||
Chain<OVertex> * chain = (*ci)->vert;
|
||||
Chain<BorderIndex> * chain_bi = (*ci)->border;
|
||||
RAssert(chain != NULL);
|
||||
|
||||
unsigned int first_added_v = m.vert.size();
|
||||
vi = vcg::tri::Allocator<MeshType>::AddVertices(m,chain->Size());
|
||||
|
||||
locked = (*ci)->ecd->locked() ;
|
||||
|
||||
|
||||
// The vertex that was allocated to store a vertex that is not pointed by anything
|
||||
// is deleted (refer to the header of ocme_definition.h for more explanation)
|
||||
for(unsigned int i = 0; i < chain->Size(); ++i,++vi)
|
||||
{
|
||||
gPosV[*vi].Clear();
|
||||
int ind = gPosV[*vi].Index((*ci)->key);
|
||||
assert(ind == -1);
|
||||
{
|
||||
gPosV[*vi].Clear();
|
||||
int ind = gPosV[*vi].Index((*ci)->key);
|
||||
assert(ind == -1);
|
||||
|
||||
/* add this cells to the cells storing this vertices */
|
||||
gPosV[*vi].Add(GIndex((*ci)->key,i));
|
||||
/* add this cells to the cells storing this vertices */
|
||||
gPosV[*vi].Add(GIndex((*ci)->key,i));
|
||||
|
||||
/* Here there should be the importer from OVertex to vcgVertex */
|
||||
(*vi).P() = (*chain)[i].P();
|
||||
/* Here there should be the importer from OVertex to vcgVertex */
|
||||
(*vi).P() = (*chain)[i].P();
|
||||
|
||||
/* export all the attributes specified */
|
||||
attr_map.ExportVertex(*ci,*vi,i);
|
||||
/* export all the attributes specified */
|
||||
attr_map.ExportVertex(*ci,*vi,i);
|
||||
|
||||
/* mark with the "editable" flag */
|
||||
lockedV[*vi] = locked? 1 : 0 ; /* TODO: just to avoid the not-so-tested class for vector of bool in simple_temporary_data.h*/
|
||||
}
|
||||
/* mark with the "editable" flag */
|
||||
lockedV[*vi] = locked? 1 : 0 ; /* TODO: just to avoid the not-so-tested class for vector of bool in simple_temporary_data.h*/
|
||||
|
||||
/* initialize the external counter to 0 [maybe unnecessary]*/
|
||||
biV[*vi] = 0;
|
||||
}
|
||||
|
||||
Chain<OFace> * face_chain = (*ci)->face; // get the face chain
|
||||
RAssert(face_chain!=NULL);
|
||||
/* assign the border index to the border vertices */
|
||||
for(unsigned int i = 0; i < chain_bi->Size(); ++i)
|
||||
biV[m.vert[first_added_v+ (*chain_bi)[i].vi] ] = (*chain_bi)[i].bi;
|
||||
|
||||
typename MeshType::FaceIterator fi = vcg::tri::Allocator<MeshType>::AddFaces(m,face_chain->Size());
|
||||
for(unsigned int ff = 0; ff < face_chain->Size();++ff,++fi){
|
||||
gPosF[*fi] = GIndex((*ci)->key,ff);
|
||||
for(unsigned int i = 0; i < 3; ++i){
|
||||
int iii = ((*face_chain)[ff][i]);
|
||||
assert(iii+offset < m.vert.size());
|
||||
(*fi).V(i) = &m.vert[iii+offset];
|
||||
}
|
||||
}
|
||||
offset = m.vert.size();
|
||||
Chain<OFace> * face_chain = (*ci)->face; // get the face chain
|
||||
RAssert(face_chain!=NULL);
|
||||
|
||||
typename MeshType::FaceIterator fi = vcg::tri::Allocator<MeshType>::AddFaces(m,face_chain->Size());
|
||||
for(unsigned int ff = 0; ff < face_chain->Size();++ff,++fi){
|
||||
gPosF[*fi] = GIndex((*ci)->key,ff);
|
||||
for(unsigned int i = 0; i < 3; ++i){
|
||||
int iii = ((*face_chain)[ff][i]);
|
||||
assert(iii+offset < m.vert.size());
|
||||
(*fi).V(i) = &m.vert[iii+offset];
|
||||
}
|
||||
}
|
||||
offset = m.vert.size();
|
||||
}
|
||||
|
||||
range() = sr;
|
||||
@ -265,15 +284,16 @@ void OCME::Extract( std::vector<Cell*> & sel_cells, MeshType & m, AttributeMap
|
||||
(*ci)->face->FreeAll();
|
||||
}
|
||||
|
||||
///CHECK
|
||||
/// JUST CHECKING___________
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
for( GISet::iterator gi = gPosV[*vi].begin(); gi != gPosV[*vi].end();++gi){
|
||||
Cell *c = GetCell((*gi).first,false);
|
||||
assert(c);
|
||||
assert(c->vert->Size() > (*gi).second);
|
||||
}
|
||||
///--------------------------
|
||||
|
||||
Joiner<MeshType>::JoinDuplicateVertex(m,gPosV);
|
||||
Joiner<MeshType>::JoinBorderVertices(m,gPosV,biV);
|
||||
|
||||
{
|
||||
|
||||
@ -298,14 +318,16 @@ void OCME::Extract( std::vector<Cell*> & sel_cells, MeshType & m, AttributeMap
|
||||
|
||||
}
|
||||
|
||||
///CHECK
|
||||
/// JUST CHECKING___________
|
||||
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
for( GISet::iterator gi = gPosV[*vi].begin(); gi != gPosV[*vi].end();++gi){
|
||||
Cell *c = GetCell((*gi).first,false);
|
||||
assert(c);
|
||||
assert(c->vert->Size() > (*gi).second);
|
||||
}
|
||||
///--------------------------
|
||||
|
||||
vcg::tri::Allocator<MeshType>::template DeletePerVertexAttribute (m,biV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -12,12 +12,21 @@ void OCME::RemoveDeletedFaces( std::vector<Cell*> & cells){
|
||||
}
|
||||
}
|
||||
|
||||
void OCME::RemoveDeletedBorder(std::vector<Cell*> & cells){
|
||||
std::vector<Cell*>::iterator ci;
|
||||
for(ci = cells.begin(); ci != cells.end(); ++ci){
|
||||
(*ci) ->ecd->deleted_border.SetAsVectorOfMarked();
|
||||
(*ci)->border->Compact( (*ci)->ecd->deleted_border.marked_elements);
|
||||
(*ci) ->ecd->deleted_border.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void OCME::RemoveDeletedVertices( std::vector<Cell*> cs){
|
||||
std::vector<Cell*>::const_iterator ci;
|
||||
//
|
||||
for(ci = cs.begin(); ci != cs.end(); ++ci){
|
||||
std::vector<unsigned int> remap;
|
||||
Chain<BorderIndex> * bchain = (*ci)->border;
|
||||
Chain<OVertex> * vchain = (*ci)->vert;
|
||||
Chain<OFace> * fchain = (*ci)->face;
|
||||
|
||||
@ -30,9 +39,10 @@ void OCME::RemoveDeletedVertices( std::vector<Cell*> cs){
|
||||
int ind = (*fchain)[fi][i];
|
||||
assert(remap[ind] < vchain->Size());
|
||||
(*fchain)[fi][i] = remap[(*fchain)[fi][i]];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for(unsigned int ii = 0; ii < bchain->Size(); ++ii)
|
||||
(*bchain)[ii].vi = remap[(*bchain)[ii].vi];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -76,7 +76,6 @@ void OCME::ClearImpostors(std::vector<CellKey> & fromCells){
|
||||
if(level == 32) return; // if the database is empty return
|
||||
|
||||
// phase 2., bottom up clearing of the impostors
|
||||
bool to_insert = false;
|
||||
for( ; level < 31;++level ){
|
||||
::RemoveDuplicates(cells_by_level[level]);
|
||||
for(unsigned int i = 0; i <cells_by_level[level].size();++i){
|
||||
@ -106,14 +105,14 @@ void OCME::FillSamples(std::vector<CellKey> & cs){
|
||||
/* clear the data that will be recomputed */
|
||||
c->impostor->ClearDataCumulate();
|
||||
|
||||
bool hasColor = vcg::tri::HasPerVertexColor(tmp);
|
||||
|
||||
for(vcgMesh::FaceIterator fi = tmp.face.begin(); fi != tmp.face.end(); ++fi){
|
||||
vcg::Point3f bary = vcg::Barycenter(*fi);
|
||||
vcg::Point3f pp[3];
|
||||
vcg::Point3f n = vcg::Normal(*fi).Normalize();
|
||||
//for(int i = 0; i < 3; ++i) pp[i] = ((*fi).V(i))->P();
|
||||
c->impostor->AddSample(bary,n,(*fi).V(0)->cC()); // collect a sample for the impostor
|
||||
//for(int i = 0; i < 3; ++i) c->impostor->AddSample(bary*0.5+pp[i]*0.5,n,vcg::Color4b::Gray); // collect a sample for the impostor
|
||||
vcg::Color4b color = (hasColor)? (*fi).V(0)->cC() : vcg::Color4b::Gray;
|
||||
c->impostor->AddSample(bary,n,color); // collect a sample for the impostor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@ void ToPolar(vcg::Point3f n, float & alpha, float & beta){
|
||||
if( n[1]*n[1] > 0.99)
|
||||
alpha = 0.f;
|
||||
else
|
||||
alpha = ((n[2]>0)?1.0:-1.0) * acos( n[0] / sqrt(1.f-( n[1]*n[1] ) ));
|
||||
alpha = ((n[2]>0.f)?1.f:-1.f) * acos( n[0] / sqrt(1.f-( n[1]*n[1] ) ));
|
||||
}
|
||||
|
||||
vcg::Point3f FromPolar(float alpha, float beta){
|
||||
|
||||
@ -222,7 +222,6 @@ SimpleDb::Index SimpleDb::Get(std::string key, void * buf, unsigned long siz){
|
||||
|
||||
|
||||
void SimpleDb::Del(std::string name){
|
||||
FILE * f;
|
||||
std::vector<Index> all_segs;
|
||||
Index_ite ii = index.find(name);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user