added support for unreferenced vertices (not fully tested yet)

This commit is contained in:
Fabio Ganovelli ganovelli 2010-10-25 17:20:27 +00:00
parent 6c9f7b7838
commit 403b8cad7e
18 changed files with 251 additions and 195 deletions

View File

@ -40,7 +40,7 @@ using namespace std;
using namespace vcg;
#define _RELEASED_
//#define _RELEASED_
OcmeEditPlugin::OcmeEditPlugin() {
showTouched = false;
@ -262,13 +262,17 @@ void OcmeEditPlugin::drawFace(CMeshO::FacePointer , MeshModel &, GLArea * )
void OcmeEditPlugin::updateButtonsState(){
odw->commitPushButton->setEnabled( ocme_loaded && (!ocme->edited_faces.empty() || !ocme->edited_vertices.empty()));
odw->dropSelectionPushButton->setEnabled(ocme_loaded && (!ocme->edited_faces.empty() || !ocme->edited_vertices.empty()));
odw->markEditablePushButton->setEnabled(ocme_loaded && (!ocme->edited_faces.empty() || !ocme->edited_vertices.empty()));
bool is_editing = ocme_loaded && (!ocme->edited_faces.empty() || !ocme->edited_vertices.empty());
odw->commitPushButton->setEnabled( is_editing);
odw->dropSelectionPushButton->setEnabled(is_editing);
odw->markEditablePushButton->setEnabled(is_editing);
odw->closeOcmPushButton->setEnabled(ocme_loaded);
odw->addPushButton->setEnabled(ocme_loaded);
odw->editPushButton->setEnabled(!this->cells_to_edit.empty());
odw->ocm2triPushButton->setEnabled( (odw->ocmeAttrListWidget->count()>0) && !is_editing);
odw->loadOcmPushButton->setEnabled(!ocme_loaded);
odw->createOcmPushButton->setEnabled(!ocme_loaded);
//odw->markEditablePushButton->setEnabled(!mm->cm.face.empty());
@ -415,7 +419,8 @@ void OcmeEditPlugin::tri2ocmAttribute(){
}
void OcmeEditPlugin::ocm2triAttribute(){
odw->meshAttrListWidget->addItem(odw->ocmeAttrListWidget->currentItem()->text());
if(odw->ocmeAttrListWidget->selectedItems ().size() > 0)
odw->meshAttrListWidget->addItem(odw->ocmeAttrListWidget->currentItem()->text());
}
@ -431,7 +436,7 @@ void OcmeEditPlugin::loadOcm(){
ocme = new OCME();
ocme->params.side_factor = 50; // READ IT FROM THE FILEEEEEEEEE
ocme->InitRender();
ocme->renderParams.only_impostors = false;
ocme->renderParams.only_impostors = true;
// ocme->renderParams.memory_limit_in_core = 100;
ocme->Open ( ocm_name.toAscii() );
@ -516,10 +521,13 @@ void OcmeEditPlugin::drop(){
ocme->renderCache.controller.pause();
mm->cm.Clear();
cells_to_edit.clear();
ocme->edited_faces.clear();
ocme->edited_vertices.clear();
ocme->DropEdited();
ocme->renderCache.controller.resume();
clearOcmAttribute();
clearMeshAttribute();
updateButtonsState();
gla->update();
}
@ -620,22 +628,12 @@ void OcmeEditPlugin::edit(){
mm->cm.face[i].C() = c;
}
// for(unsigned int fi = 0; fi < 3; ++ fi ){
// lockedV[mm->cm.face[i].V(fi)] = 1;
// mm->cm.face[i].V(fi)->SetS();
// }
// mm->cm.face[i].SetS();
// }
//
// for(unsigned int i = 0; i < mm->cm.vert.size();++i)
// if( lockedV[i] ) mm->cm.vert[i].SetS();
vcg::tri::UpdateBounding<CMeshO>::Box(mm->cm);
ocme->renderCache.controller.resume();
clearOcmAttribute();
updateButtonsState();
gla->update();
}
void OcmeEditPlugin::commit(){

View File

@ -105,13 +105,13 @@ public slots:
void loadOcm(); // load an ocm database
void closeOcm(); // close an ocm database
void createOcm(); // create an ocm database
void edit(); // edit current selection
void markEditable(); // mark as selected (flag S) the editable element on the editing mesh
void drop(); // drop current selection
void edit(); // edit current selection
void markEditable(); // mark as selected (flag S) the editable element on the editing mesh
void drop(); // drop current selection
void commit(); // commit
void add(); // add new mesh
void addFromDisk(); // add from disk
void refreshImpostors(); // refresh impostor (debug)
void add(); // add new mesh
void addFromDisk(); // add from disk
void refreshImpostors(); // refresh impostor (debug)
void toggleExtraction();
void toggleShowTouched();
void updateButtonsState();

View File

@ -1,20 +1,20 @@
#include "../ooc_vector/ooc_chains.h"
#include "gindex_chunk.h"
#include "BorderIndex_chunk.h"
#define _COMPRESS_GINDEX_
#ifdef _COMPRESS_GINDEX_
#define _COMPRESS_BorderIndex_
#ifdef _COMPRESS_BorderIndex_
#include <bcl/src/bcl.h>
template <> unsigned int Chain<GIndex>::Chunk::
SizeOfMem(){ return sizeof(GIndex)*this->capacity;}
template <> unsigned int Chain<BorderIndex>::Chunk::
SizeOfMem(){ return sizeof(BorderIndex)*this->capacity;}
template <> unsigned int Chain<GIndex>::Chunk::
template <> unsigned int Chain<BorderIndex>::Chunk::
SizeOfDisk(){ return size_of_disk;}
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
Written(unsigned char * & buf){ delete [] buf; buf = 0;}
template < > unsigned int Chain<GIndex>::Chunk::
template < > unsigned int Chain<BorderIndex>::Chunk::
Write(unsigned char * & buf ){
const unsigned int insize = this->SizeOfMem();
unsigned int worstcase_outsize = ceil(257.f/256.f * (insize+1));
@ -25,58 +25,58 @@ Write(unsigned char * & buf ){
}
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
Read(unsigned char *buf, unsigned char * here ){
if(!here) this->buffer = new GIndex[this->capacity];
if(!here) this->buffer = new BorderIndex[this->capacity];
unsigned int outsize = RLE_Uncompress((unsigned char*)&buf [0],this->size_of_disk,(here)?here:(unsigned char*)this->buffer,this->SizeOfMem());
assert(outsize == this->SizeOfMem());
delete [] buf;
}
template <> float Chain<GIndex>::Chunk::
template <> float Chain<BorderIndex>::Chunk::
CompressionRatio(){
return 0.5;// crappy estimation of rle over GIndex
return 0.5;// crappy estimation of rle over BorderIndex
}
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
AllocMem(unsigned char * & buf,unsigned char * here ){
// ignore "here"
buf = (unsigned char*) new unsigned char [this->size_of_disk];
};
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
DeAllocMem(){delete [] this->buffer;this->buffer=0;}
#else
template <> unsigned int Chain<GIndex>::Chunk::
SizeOfMem(){ return sizeof(GIndex)*this->capacity;}
template <> unsigned int Chain<BorderIndex>::Chunk::
SizeOfMem(){ return sizeof(BorderIndex)*this->capacity;}
template <> unsigned int Chain<GIndex>::Chunk::
template <> unsigned int Chain<BorderIndex>::Chunk::
SizeOfDisk(){ return size_of_disk;}
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
Written(unsigned char * & buffer){}
template < > unsigned int Chain<GIndex>::Chunk::
template < > unsigned int Chain<BorderIndex>::Chunk::
Write(unsigned char * & buffer ){
unsigned char *ptr = buffer;
buffer = (unsigned char*) this->buffer;
return this->size*sizeof(GIndex);
return this->size*sizeof(BorderIndex);
}
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
Read(unsigned char *buffer ){
unsigned char *ptr = buffer;
this->buffer = (GIndex*)buffer;
this->buffer = (BorderIndex*)buffer;
}
template < > void Chain<GIndex>::Chunk::
AllocMem(unsigned char * & buf ){this->buffer = new GIndex[this->capacity];buf = (unsigned char*) this->buffer;};
template < > void Chain<BorderIndex>::Chunk::
AllocMem(unsigned char * & buf ){this->buffer = new BorderIndex[this->capacity];buf = (unsigned char*) this->buffer;};
template < > void Chain<GIndex>::Chunk::
template < > void Chain<BorderIndex>::Chunk::
DeAllocMem(){delete [] this->buffer;this->buffer=0;}
#endif

View File

@ -0,0 +1,27 @@
#ifndef _OCME_GINDEX_CHUNK_
#define _OCME_GINDEX_CHUNK_
#include "cell.h"
template <> unsigned int Chain<BorderIndex>::Chunk::SizeOfMem();
template <> unsigned int Chain<BorderIndex>::Chunk::SizeOfDisk();
template <> void Chain<GIndex>::Chunk::
Written(unsigned char * & buffer);
template <> unsigned int Chain<BorderIndex>::Chunk::
Write(unsigned char * & buffer );
template <> void Chain<BorderIndex>::Chunk::
Read(unsigned char *buffer,unsigned char *here );
template <> float Chain<BorderIndex>::Chunk::
CompressionRatio();
template <> void Chain<BorderIndex>::Chunk::
AllocMem(unsigned char * & buf,unsigned char * here);
template <> void Chain<BorderIndex>::Chunk::
DeAllocMem();
#endif

View File

@ -76,8 +76,6 @@ struct GISet{
return giset<o.giset;
}
void sub(GISet & o){
for(iterator i = o.begin(); i!=o.end(); ++i)
giset.erase((*i).first);
@ -128,6 +126,7 @@ struct Box4{
Box4(){bbox3.SetNull();};
Box4(vcg::Box3f _bbox3, ScaleRange _sr):bbox3(_bbox3),sr(_sr){}
Box4 Add(vcg::Box3f b3, ScaleRange _sr ){ bbox3.Add(b3); sr.Add(_sr); return (*this);}
Box4 Add(vcg::Point3f p, int h ){ bbox3.Add(p); sr.Add(h); return (*this);}
vcg::Box3f bbox3;
ScaleRange sr;
bool operator ==(const Box4 & b) const {return (bbox3==b.bbox3) && (sr==b.sr);}

View File

@ -1,27 +0,0 @@
#ifndef _OCME_GINDEX_CHUNK_
#define _OCME_GINDEX_CHUNK_
#include "cell.h"
template <> unsigned int Chain<GIndex>::Chunk::SizeOfMem();
template <> unsigned int Chain<GIndex>::Chunk::SizeOfDisk();
template <> void Chain<GIndex>::Chunk::
Written(unsigned char * & buffer);
template <> unsigned int Chain<GIndex>::Chunk::
Write(unsigned char * & buffer );
template <> void Chain<GIndex>::Chunk::
Read(unsigned char *buffer,unsigned char *here );
template <> float Chain<GIndex>::Chunk::
CompressionRatio();
template <> void Chain<GIndex>::Chunk::
AllocMem(unsigned char * & buf,unsigned char * here);
template <> void Chain<GIndex>::Chunk::
DeAllocMem();
#endif

View File

@ -97,9 +97,9 @@ struct Impostor{
void GetPointNormalColor( PointCell pn, vcg::Point3f & p, vcg::Point3f & n,vcg::Point3<unsigned char> & c){
unsigned char i,j,k;
stdMatrix3Sparse<vcg::Point3<char>,8>::Index(pn.first,i,j,k);
vcg::Point3<char> & a = pn.second.p;
vcg::Point3<char> & a = pn.second.p;
p = vcg::Point3f(C2F (a[0],i,0),C2F (a[1],j,1),C2F (a[2],k,2));
vcg::Point3<char> & b = pn.second.n;
vcg::Point3<char> & b = pn.second.n;
n = vcg::Point3f(C2F_01(b[0]),C2F_01(b[1]),C2F_01(b[2])).Normalize();
c = pn.second.c;

View File

@ -36,7 +36,7 @@
vcg::Point3f p,n;
vcg::Point3<unsigned char> c;
glPointSize(5);
glPointSize(8);
glBegin(GL_POINTS);
for( PointCellIterator pi = this->proxies.begin(); pi != this->proxies .end(); ++pi ){

View File

@ -1,15 +1,19 @@
#include <sys/stat.h>
#include "ocme.h"
#include "impostor_definition.h"
#include "../utils/memory_debug.h"
#include "../utils/timing.h"
#include "../utils/logging.h"
#include "../ooc_vector/ooc_chains.h"
//#include "gindex_chunk.h"
#include "ocme.h"
#include "impostor_definition.h"
#include "import_ocm_ply.h"
#include "../ooc_vector/berkeleydb/ooc_chains_berkeleydb.hpp"
@ -143,12 +147,13 @@ void AddImpostors(char * ocmFile){
}
void UsageExit(){
printf("Usage ocm_build.exe [options] [*.aln | *.ply]...\
-f : database name\n \
-c : add per vertex color if present \
-o : owerwrite if already exists \
-m : RAM cache \
-p : DB page size (bytes) \n");
printf("Usage ocm_build.exe [options] [*.aln | *.ply]...\n\
-f : database name [default: out]\n\
-v : verbose [default: no]\n\
-s : skip faces (just insert vertices) [default: no]\n\
-o : owerwrite if already exists [default: no]\n\
-m : RAM cache (MB) [default: 200]\n\
-p : database page size (B) [default: 1024]\n");
exit(0);
}
@ -262,23 +267,25 @@ bool Interrupt(){
int
main (int argc,char **argv )
{
#ifdef _DEBUG
printf("SIZE OF CELL: %d\n",sizeof(Cell));
printf("SIZE OF EdiTCOmmitData: %d\n",sizeof(EditCommitAuxData));
printf("SIZE OF RenderAuxData: %d\n",sizeof(RenderAuxData));
printf("SIZE OF FBOOL: %d\n",sizeof(FBool));
printf("SIZE OF BoolVector: %d\n",sizeof(BoolVector));
printf("SIZE OF Chain<GIndex>: %d\n",sizeof(Chain<GIndex>));
printf("SIZE OF std::map<unsigned int,unsigned int>: %d\n",sizeof(std::map<unsigned int,unsigned int>));
printf("waste: %d\n",sizeof(FBool)*5+sizeof(BoolVector)*3+sizeof(Chain<GIndex>)+sizeof(std::map<unsigned int,unsigned int>));
// printf("SIZE OF CELL: %d\n",sizeof(Cell));
// printf("SIZE OF FBOOL: %d\n",sizeof(FBool));
// printf("SIZE OF BoolVector: %d\n",sizeof(BoolVector));
// printf("SIZE OF Chain<GIndex>: %d\n",sizeof(Chain<GIndex>));
// printf("SIZE OF std::map<unsigned int,unsigned int>: %d\n",sizeof(std::map<unsigned int,unsigned int>));
// printf("waste: %d\n",sizeof(FBool)*5+sizeof(BoolVector)*3+sizeof(Chain<GIndex>)+sizeof(std::map<unsigned int,unsigned int>));
//
// printf("SIZE OF Chain<GIndex>: %d\n",sizeof(Chain<GIndex>));
// printf("SIZE OF Chain<OFace>: %d\n",sizeof(Chain<OFace>));
// printf("SIZE OF Chain<OVertex>: %d\n",sizeof(Chain<OVertex>));
// printf("SIZE OF Chain<OVertex>::Chunk: %d\n",sizeof(Chain<OVertex>::Chunk));
// printf("SIZE OF CachePolicy: %d\n",sizeof(CachePolicy));
// printf("SIZE OF std::string: %d\n",sizeof(std::string));
// printf("SIZE OF vcgMesh: %d\n",sizeof(vcgMesh));
// printf("SIZE OF Impostor: %d\n",sizeof(Impostor));
printf("SIZE OF Chain<GIndex>: %d\n",sizeof(Chain<GIndex>));
printf("SIZE OF Chain<OFace>: %d\n",sizeof(Chain<OFace>));
printf("SIZE OF Chain<OVertex>: %d\n",sizeof(Chain<OVertex>));
printf("SIZE OF Chain<OVertex>::Chunk: %d\n",sizeof(Chain<OVertex>::Chunk));
printf("SIZE OF CachePolicy: %d\n",sizeof(CachePolicy));
printf("SIZE OF std::string: %d\n",sizeof(std::string));
printf("SIZE OF vcgMesh: %d\n",sizeof(vcgMesh));
printf("SIZE OF Impostor: %d\n",sizeof(Impostor));
#endif
// _CrtSetBreakAlloc(1281429);
struct stat buf;
@ -301,9 +308,9 @@ main (int argc,char **argv )
bool logging = false;
bool compute_impostors = false;
bool overwrite_database = false;
bool add_per_vertex_color = false;
bool transform = false;
bool verify = false;
bool only_vertices = false;
vcg::Matrix44f tra_ma;tra_ma.SetIdentity();
@ -311,12 +318,14 @@ main (int argc,char **argv )
printf("ocme builder DEBUG MODE\n");
#endif
std::string stat_file = std::string("");
std::string stat_file = std::string("");
if(argc==1)
UsageExit();
while (1)
{
int this_option_optind = optind ? optind : 1;
c = getopt (argc, argv, "qciosvp:t:m:l:f:L:a:A:k:");
c = getopt (argc, argv, "sqciosvp:t:m:l:f:L:a:A:k:");
if (c == EOF)
break;
@ -329,23 +338,23 @@ main (int argc,char **argv )
compute_impostors = true;
break;
case 's':
only_vertices = true;
break;
case 't':
transform = true;
printf("filename %s\n",optarg );tra_ma_file = std::string(optarg);
LoadTraMa(tra_ma_file.c_str(),tra_ma);
break;
case 's':
case 'S':
printf("filename %s\n",optarg );stat_file = std::string(optarg);
break;
case 'o':
overwrite_database = true;
break;
case 'c':
add_per_vertex_color = true;
break;
case 'f':
printf("filename %s\n",optarg );ocmename = std::string(optarg);
break;
@ -463,6 +472,7 @@ main (int argc,char **argv )
vcg::tri::UpdatePosition<vcgMesh>::Matrix(m,aln[idm].second);
unsigned int newstart = clock();
if(!m.face.empty()){
if(only_vertices) m.fn = 0;
meshona->AddMesh(m);
++meshadded;
}
@ -510,7 +520,7 @@ main (int argc,char **argv )
lgn->Push();
vcg::tri::UpdatePosition<vcgMesh>::Matrix(m,tra_ma);
vcg::tri::io::ExporterPLY<vcgMesh>::Save(m,std::string(argv[i]).append("T.ply").c_str());
// vcg::tri::io::ExporterPLY<vcgMesh>::Save(m,std::string(argv[i]).append("T.ply").c_str());
}
TIM::End(0);
@ -521,11 +531,11 @@ main (int argc,char **argv )
assert( MemDbg::CheckHeap(0));
++meshona->stat.n_files;
if(!m.face.empty()) {
meshona->AddMesh(m,am);
++meshadded;
}
if(only_vertices) m.fn = 0;
meshona->AddMesh(m,am);
++meshadded;
sprintf(lgn->Buf(),"#cells: %d \n", meshona->cells.size());
lgn->Push();
}
@ -533,7 +543,7 @@ main (int argc,char **argv )
{
TIM::Begin(2);
// if the file is more that 50 MB build directly from file
n_faces = vcg::tri::io::ImporterOCMPLY<vcgMesh>::Open(m,meshona,argv[i],tra_ma,cb);
// n_faces = vcg::tri::io::ImporterOCMPLY<vcgMesh>::Open(m,meshona,argv[i],tra_ma,cb);
TIM::End(2);
}
@ -624,7 +634,6 @@ else
}
delete meshona;
delete lgn;
}
samples.clear();

View File

@ -31,14 +31,30 @@ ScaleRange OCME::ScaleRangeOfTris( std::vector<vcg::Point3<vcg::Point3<S> > > &
template <class MeshType>
ScaleRange OCME::ScaleRangeOfMesh( MeshType & m){
typename MeshType::ScalarType minScale,maxScale;
vcg::Histogramf mHist;
vcg::tri::Stat<MeshType>::ComputeEdgeHistogram(m,mHist);
minScale = mHist.Percentile(0.5f);
maxScale = mHist.Percentile(0.95f);
ScaleRange sr;
sr.min = ComputeLevel(minScale);
sr.max = ComputeLevel(maxScale);
if(m.fn * 3> m.vn){ // use the faces
vcg::tri::Stat<MeshType>::ComputeEdgeHistogram(m,mHist);
minScale = mHist.Percentile(0.5f);
maxScale = mHist.Percentile(0.95f);
sr.min = ComputeLevel(minScale);
sr.max = ComputeLevel(maxScale);
}
else{// use the vertices
mHist.Clear();
mHist.SetRange( 0, m.bbox.Diag(), 10000);
MeshType::VertexIterator vi = m.vert.begin();
MeshType::VertexIterator vi1 = vi; vi++;
for( ; vi != m.vert.end(); ++vi,++vi1)
mHist.Add(vcg::Distance((*vi).P(),(*vi1).P()));
minScale = mHist.Percentile(0.15f);
maxScale = mHist.Percentile(0.70f);
sr.min = ComputeLevel(minScale);
sr.max = ComputeLevel(maxScale);
}
return sr;
}
@ -64,7 +80,6 @@ inline int OCME::ComputeLevel( typename MeshType::FaceType & f, ScaleRange & sr
template <class MeshType>
void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
sprintf(lgn->Buf(),"Adding Mesh\n");
lgn->Push();
@ -74,7 +89,7 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
typename MeshType::VertexIterator vi;
static unsigned int n_duplicate_removal = 0;
int n_box_updates = 0;
int n_box_updates = 0,added_vert = 0;
int h;
Cell * c = NULL; // current cell. Cache the last used cell because very often this is coherent from face to face
@ -93,7 +108,7 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
Since it is not really of much use to have multiple scales for a single mesh
here we put al the mesh at the same scale
*/
sr.min = sr.max;
//sr.min = sr.max;
sprintf(lgn->Buf(),"MeshSize face %d vert%d\n",m.fn,m.vn);
lgn->Push();
@ -104,9 +119,10 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
RecordCellsSetModification();
bool hasColor = vcg::tri::HasPerVertexColor(m);
bool hasColor = vcg::tri::HasPerVertexColor(m);
/* Here the main cycle. for each face of the mesh put it in the hashed multigrid */
if(m.fn)
for(fi = m.face.begin(); fi != m.face.end(); ++fi) if(!(*fi).IsD()){
TIM::Begin(20);
if(added_cells.size() > (n_duplicate_removal+1)*1000){
@ -141,6 +157,7 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
for(int i = 0; i < 3 ; ++i){
vIndex[i] = gPos[(*fi).V(i)].Index(ck); // get the index of the vertx in this cell (or -1)
if(vIndex[i]==-1){
added_vert++;
vIndex[i] = c-> AddVertex(OVertex(*(*fi).V(i)) ); // no: add the vertex to it
gPos[(*fi).V(i)].Add(GIndex(ck,vIndex[i])); // record to index
}
@ -157,9 +174,9 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
// rough roughroughourhg adding of samples
vcg::Point3f bary = vcg::Barycenter(*fi);
vcg::Color4b color = (hasColor)? (*fi).V(0)->cC() : vcg::Color4b::Gray;
vcg::Color4b color = (hasColor)? (*fi).V(0)->cC() : vcg::Color4b::Gray;
c->impostor->AddSample(bary,vcg::Normal(*fi).Normalize(),color); // collect a sample for the impostor
c->impostor->AddSample(bary,vcg::Normal(*fi).Normalize(),color); // collect a sample for the impostor
TIM::End(23);
@ -206,7 +223,32 @@ void OCME::AddMesh( MeshType & m, AttributeMapper attr_map){
TIM::End(21);
TIM::End(20);
}
{
// adding unreferenced vertices (the referenced vertices have already been added in the face cycle
if(added_vert<m.vn) // is there are no deleted and no unreferenced vertices,
// this avoids to run over the vertices just to check
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)if(!(*vi).IsD()){
if(gPos[*vi].giset.empty()){// if it was not assigned it means is unreferenced
CellKey ck = ComputeCellKey((*vi).cP(),sr.max);
if( (c==NULL) || !(c->key == ck)) {
c = GetCellC(ck);
if(!c->generic_bool()) { // if it is the first occurrence of the cell
UpdateCellsAttributes(c,attr_map); // make sure it contains all the attributes
c->generic_bool = FBool(&generic_bool);
c->generic_bool = true;
}
}
int pos = c-> AddVertex(OVertex(*vi) );
attr_map.ImportVertex(c,*vi,pos);
gPos[ *vi].Add(GIndex(ck,pos));
vcg::Color4b color = (hasColor)? (*vi).cC() : vcg::Color4b::Gray;
c->impostor->AddSample((*vi).cP(),(*vi).cN(),color); // collect a sample for the impostor
c->bbox.Add((*vi).cP(),sr.max);
}
}
}
StopRecordCellsSetModification();
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)

View File

@ -160,13 +160,14 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
}
}
}
vcg::Box3<ScalarType> facebox;
/* Here the main cycle. for each face of the mesh put it in the hashed multigrid */
for(fi = m.face.begin(); fi != m.face.end(); ++fi)
if( lockedF[*fi]==0) // skip if not editable
{
CellKey ck;
GIndex gposf = gPosF[*fi]; // note: gPosF[] will not be updated because it is won't be used again
vcg::Box3<ScalarType> facebox;
CellKey ck;
GIndex gposf = gPosF[*fi]; // note: gPosF[] will not be updated because it is won't be used again
// before it is destroyed
//if( ((&(*fi) - &(*m.face.begin()))%1000) == 0){
@ -189,7 +190,7 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
}
// compute the cell where to put this face
{
{
// find in which level the face should be
h = ComputeLevel<MeshType>(*fi,srM);
@ -206,7 +207,7 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
if( (!c) || !(c->key == ck)) // check if the current cell is the right one
c = GetCell(ck); // if not update it
}
}
@ -244,33 +245,14 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
}
// import all the attributes specified
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)if( lockedV[*vi]==0)
for(GISet::CopiesIterator ci = gPosV[*vi].giset.begin();ci != gPosV[*vi].giset.end();++ci){
if(!(c->key == (*ci).first)) c = GetCell((*ci).first,false);
if( (c==NULL) || !(c->key == (*ci).first)) c = GetCell((*ci).first,false);
RAssert(c);
(*c->vert)[(*ci).second].P() = (*vi).cP();
attr_map.ImportVertex(c,*vi,(*ci).second);
}
/* mark unreferenced vertices for deletion in cells included in the selection at edit time */
{
std::vector<bool> todel;
for(unsigned int i = 0; i < sel_cells_attr().size(); ++i){
Cell * c = GetCell(sel_cells_attr()[i],false);
RAssert(c);
todel.resize(c->vert->Size(),true);
for(unsigned int fi = 0; fi < c->face->Size(); ++fi){
for(unsigned int vi = 0; vi < 3; ++vi)
todel[(*c->face)[fi][vi]] = false;
}
c->ecd->deleted_vertex.SetAsVectorOfMarked();
for(unsigned int ii = 0; ii < c->vert->Size(); ++ii)
if(todel[ii])
c->ecd->deleted_vertex.SetMarked(ii,true);
}
}
/* update gPosV by removing deleted vertices */
{
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi){
@ -347,33 +329,54 @@ void OCME::Commit(MeshType & m, AttributeMapper attr_map){
}
}
/* mark unreferenced vertices for deletion in cells included in the selection at edit time */
{
std::vector<bool> todel;
std::vector<bool> border;
for(unsigned int i = 0; i < sel_cells_attr().size(); ++i){
Cell * c = GetCell(sel_cells_attr()[i],false);
RAssert(c);
todel.resize(c->vert->Size(),true);
border.resize(c->vert->Size(),false);
for(unsigned int ii = 0; ii < c->border->Size(); ++ii)
border[(*c->border)[ii].vi] = true;
for(unsigned int fi = 0; fi < c->face->Size(); ++fi){
for(unsigned int vi = 0; vi < 3; ++vi)
todel[(*c->face)[fi][vi]] = false;
}
c->ecd->deleted_vertex.SetAsVectorOfMarked();
for(unsigned int ii = 0; ii < c->vert->Size(); ++ii)
if(todel[ii] && border[ii])
c->ecd->deleted_vertex.SetMarked(ii,true);
}
}
lgn->Append("cleaning up");
if(!toCleanUpCells.empty()){
RemoveDuplicates (toCleanUpCells);
std::vector<Cell*>::iterator ci;
for(ci = toCleanUpCells.begin(); ci != toCleanUpCells.end(); ++ci){
RAssert((*ci));
if(*ci){
if(!(*ci)->ecd){
sprintf(lgn->Buf(),"%d %d %d %d",(*ci)->key.x,(*ci)->key.y,(*ci)->key.z,(*ci)->key.h);lgn->Push();
sprintf(lgn->Buf(),"vert: %d face: %d ",(*ci)->vert->Size(),(*ci)->face->Size());lgn->Push();
}
RAssert((*ci)->rd);
}
}
lgn->Append("RemoveDeletedFaces");
RemoveDeletedFaces (toCleanUpCells);
lgn->Append("RemoveDeletedBorder");
RemoveDeletedBorder (toCleanUpCells);
lgn->Append("RemoveDeletedVertices");
RemoveDeletedVertices (toCleanUpCells);
}
{
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi)
if(!(*vi).IsD() && gPosV[*vi].IsUnassigned() && gPosVNew[*vi].IsUnassigned() ){
CellKey ck = ComputeCellKey((*vi).cP(),srM.max);
if( (c==NULL) || !(c->key == ck)) {
c = GetCellC(ck);
if(!c->generic_bool()) { // if it is the first occurrence of the cell
UpdateCellsAttributes(c,attr_map); // make sure it contains all the attributes
c->generic_bool = FBool(&generic_bool);
c->generic_bool = true;
}
}
int pos = c-> AddVertex(OVertex(*vi) );
attr_map.ImportVertex(c,*vi,pos);
}
}
#ifdef _DEBUG
// DEBUG - check

View File

@ -262,8 +262,8 @@ void OCME::Extract( std::vector<Cell*> & sel_cells, MeshType & m, AttributeMap
/* export all the attributes specified */
attr_map.ExportVertex(*ci,*vi,i);
(*vi).C() = (*vi).C().Scatter(32, (*ci)->key.h+16 ); //TMP DEBUG
/* mark with the "editable" flag */
/* 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]*/

View File

@ -4,21 +4,18 @@
void OCME::RemoveDeletedFaces( std::vector<Cell*> & cucells){
std::vector<Cell*>::iterator ci;
for(ci = cucells.begin(); ci != cucells.end(); ++ci){
RAssert((*ci));
if(*ci){
if(!(*ci)->ecd){
sprintf(lgn->Buf(),"%d %d %d %d",(*ci)->key.x,(*ci)->key.y,(*ci)->key.z,(*ci)->key.h);lgn->Push();
sprintf(lgn->Buf(),"vert: %d face: %d ",(*ci)->vert->Size(),(*ci)->face->Size());lgn->Push();
}
RAssert((*ci)->rd);
}
}
for(ci = cucells.begin(); ci != cucells.end(); ++ci){
MarkTouched((*ci)->key);
(*ci) ->ecd->deleted_face.SetAsVectorOfMarked();
/* remove the faces (indices) */
(*ci)->face->Compact( (*ci)->ecd->deleted_face.marked_elements);
/* remove corresponding per face attribute (color, normal, whatever... */
Cell::StringChainMap::iterator fai;
for(fai = (*ci)->perFace_attributes.begin(); fai != (*ci)->perFace_attributes.end(); ++fai)
(*fai).second->Compact((*ci)->ecd->deleted_face.marked_elements);
(*ci) ->ecd->deleted_face.Clear();
}
}
@ -52,6 +49,12 @@ void OCME::RemoveDeletedVertices( std::vector<Cell*> cs){
(*ci)->ecd->deleted_vertex.SetAsVectorOfMarked();
vchain->BuildRemap( (*ci)->ecd->deleted_vertex.marked_elements, remap);
vchain->Compact((*ci)->ecd->deleted_vertex.marked_elements);
/* remove corresponding per vertex attribute (color, normal, whatever... */
Cell::StringChainMap::iterator vai;
for( vai = (*ci)->perVertex_attributes.begin(); vai != (*ci)->perVertex_attributes.end(); ++vai)
(*vai).second->Compact((*ci)->ecd->deleted_vertex.marked_elements);
(*ci)->ecd->deleted_vertex.Clear();
for(unsigned int fi = 0; fi < fchain->Size(); ++fi)

View File

@ -1,6 +1,7 @@
#include "ooc_chains.h"
#include "./berkeleydb/ooc_chains_berkeleydb.hpp"
/* -------------------------------------------------------------------------- */
/* ------------------------- OOCEnv implementation ----------------------------- */
/* -------------------------------------------------------------------------- */

View File

@ -197,7 +197,7 @@ SimpleDb::Index SimpleDb::Get(std::string key, void *& buf){
ptr+= segment_size;
}
return res;
}else{
}else{
buf = new char[segment_size];
return Get((*ii).second,buf,segment_size);
}

View File

@ -38,7 +38,7 @@ struct SimpleDb{
Index GetSingle(std::string ,void *, unsigned long siz);
Index Get(std::string key ,void *, unsigned long siz);
Index Get(std::string key, void *& buf);
Index Get(const Index & id, void * buf, const unsigned int &);
Index Get(const Index & id, void * buf, const unsigned int &);
void Del(std::string);
void Open(const std::string & _name);

View File

@ -22,7 +22,8 @@ public:
}
}
~Logging(){
delete [] Buf();
if( Buf())
{delete [] Buf(); Buf()=0;}
if(off) return;
J().clear();
}

View File

@ -16,7 +16,7 @@ struct TIM{
}
static void End(unsigned int p){T()[p]+=(clock()-ST()[p]);}
static unsigned int Total(unsigned int p){return T()[p];}
static unsigned int Total(unsigned int p){return (p<T().size())?T()[p]:0;}
};