It is currently Sat Aug 22, 2020 5:26 am


All times are UTC




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: using LowPassFilter
PostPosted: Tue Oct 30, 2012 2:54 pm 

Joined: Mon Oct 15, 2012 4:33 pm
Posts: 52
i found here http://www.volumesoffun.com/new-polyvox ... available/ that it is possible to smooth the volume data with LowPassFilter. Simply i modified the TestLowPassFilter example to see what happens:

Quote:
#include "testApp.h"
#include "ofxPolyvox.h"
#include "PolyVoxCore/MarchingCubesSurfaceExtractor.h"
#include "PolyVoxCore/RawVolume.h"
#include "PolyVoxCore/MaterialDensityPair.h"
#include "PolyVoxCore/Density.h"
#include "PolyVoxCore/PolyVoxForwardDeclarations.h"
#include "PolyVoxCore/LowPassFilter.h"
//Use the PolyVox namespace
using namespace PolyVox;

void testExecute(RawVolume<Density8>& volData)
{
const int32_t g_uVolumeSideLength = 8;



//Create two solid walls at opposite sides of the volume
for (int32_t z = 0; z < g_uVolumeSideLength; z++)
{
for (int32_t y = 0; y < g_uVolumeSideLength; y++)
{
for (int32_t x = 0; x < g_uVolumeSideLength; x++)
{
if(x % 2 == 0)
{
Density8 voxel(32);
volData.setVoxelAt(x, y, z, voxel);
}
}
}
}
}
//--------------------------------------------------------------
void testApp::setup(){
//We'll be rendering with index/vertex arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

const int32_t g_uVolumeSideLength = 12;

PolyVox::Region reg(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1));

//Create empty volume
RawVolume<Density8> volData(reg);
testExecute(volData);

RawVolume<Density8> resultVolume(reg);

LowPassFilter< RawVolume<Density8>, RawVolume<Density8> > pass1(&volData, reg, &resultVolume, reg, 5);

pass1.execute();

std::cout << "Input volume:" << std::endl;
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(0,0,0).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(1,1,1).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(2,2,2).getDensity()) << std::endl; // 3
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(3,3,3).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(4,4,4).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(5,5,5).getDensity()) << std::endl; // 0
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(6,6,6).getDensity()) << std::endl; // 32
std::cout << "Voxel = " << static_cast<int>(volData.getVoxelAt(7,7,7).getDensity()) << std::endl; // 0

std::cout << std::endl << "Output volume:" << std::endl;
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(0,0,0).getDensity()) << std::endl; // 4
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(1,1,1).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(2,2,2).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(3,3,3).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(4,4,4).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(5,5,5).getDensity()) << std::endl; // 21
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(6,6,6).getDensity()) << std::endl; // 10
std::cout << "Voxel = " << static_cast<int>(resultVolume.getVoxelAt(7,7,7).getDensity()) << std::endl; // 4

SurfaceMesh<PositionMaterialNormal> mesh;

CubicSurfaceExtractorWithNormals< RawVolume<Density8> > surfaceExtractor(&resultVolume, resultVolume.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();

polyvox.setSurfaceMeshToRender(mesh);

}

//--------------------------------------------------------------
void testApp::update(){
}

//--------------------------------------------------------------
void testApp::draw(){

cam.begin();
//Anable smooth lighting

ofEnableLighting();
//glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

polyvox.draw();
cam.end();

}


but i got this error:
Quote:
-------------- Build: Debug in LowPassFilter ---------------

Using makefile: Makefile
compiling x86_64 object for: src/testApp.cpp
In file included from ../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.h:27:0,
from ../../../addons/ofxPolyvox/src/ofxPolyvox.h:3,
from src/testApp.h:4,
from src/testApp.cpp:1:
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/DefaultIsQuadNeeded.h: In member function ‘bool PolyVox::DefaultIsQuadNeeded<VoxelType>::operator()(VoxelType, VoxelType, float&) [with VoxelType = PolyVox::Density<unsigned char>]’:
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/CubicSurfaceExtractorWithNormals.inl:54:6: instantiated from ‘void PolyVox::CubicSurfaceExtractorWithNormals<VolumeType, IsQuadNeeded>::execute() [with VolumeType = PolyVox::RawVolume<PolyVox::Density<unsigned char> >, IsQuadNeeded = PolyVox::DefaultIsQuadNeeded<PolyVox::Density<unsigned char> >]’
src/testApp.cpp:77:27: instantiated from here
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/DefaultIsQuadNeeded.h:35:4: error: no match for ‘operator>’ in ‘back > 0’
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/DefaultIsQuadNeeded.h:35:4: note: candidates are:
/usr/include/c++/4.6/bits/stl_pair.h:220:5: note: template<class _T1, class _T2> constexpr bool std::operator>(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
/usr/include/c++/4.6/bits/stl_iterator.h:303:5: note: template<class _Iterator> bool std::operator>(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/stl_iterator.h:353:5: note: template<class _IteratorL, class _IteratorR> bool std::operator>(const std::reverse_iterator<_IteratorL>&, const std::reverse_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/stl_iterator.h:1073:5: note: template<class _IteratorL, class _IteratorR> bool std::operator>(const std::move_iterator<_IteratorL>&, const std::move_iterator<_IteratorR>&)
/usr/include/c++/4.6/bits/stl_iterator.h:1079:5: note: template<class _Iterator> bool std::operator>(const std::move_iterator<_Iterator>&, const std::move_iterator<_Iterator>&)
/usr/include/c++/4.6/bits/basic_string.h:2547:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator>(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/basic_string.h:2559:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator>(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
/usr/include/c++/4.6/bits/basic_string.h:2571:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator>(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/include/c++/4.6/bits/stl_vector.h:1303:5: note: template<class _Tp, class _Alloc> bool std::operator>(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&)
/usr/include/c++/4.6/tuple:603:5: note: template<class ... _TElements, class ... _UElements> bool std::operator>(const std::tuple<_TElements ...>&, const std::tuple<_Elements ...>&)
/usr/include/c++/4.6/bits/unique_ptr.h:482:5: note: template<class _Tp, class _Dp, class _Up, class _Ep> bool std::operator>(const std::unique_ptr<_Tp, _Dp>&, const std::unique_ptr<_Up, _Ep>&)
/usr/include/c++/4.6/bits/stl_deque.h:287:5: note: template<class _Tp, class _Ref, class _Ptr> bool std::operator>(const std::_Deque_iterator<_Tp, _Ref, _Ptr>&, const std::_Deque_iterator<_Tp, _Ref, _Ptr>&)
/usr/include/c++/4.6/bits/stl_deque.h:294:5: note: template<class _Tp, class _RefL, class _PtrL, class _RefR, class _PtrR> bool std::operator>(const std::_Deque_iterator<_Tp, _RefL, _PtrL>&, const std::_Deque_iterator<_Tp, _RefR, _PtrR>&)
/usr/include/c++/4.6/bits/stl_deque.h:1950:5: note: template<class _Tp, class _Alloc> bool std::operator>(const std::deque<_Tp, _Alloc>&, const std::deque<_Tp, _Alloc>&)
/usr/include/c++/4.6/bits/stl_queue.h:296:5: note: template<class _Tp, class _Seq> bool std::operator>(const std::queue<_Tp, _Seq>&, const std::queue<_Tp, _Seq>&)
/usr/include/c++/4.6/bits/stl_list.h:1606:5: note: template<class _Tp, class _Alloc> bool std::operator>(const std::list<_Tp, _Alloc>&, const std::list<_Tp, _Alloc>&)
/usr/include/c++/4.6/bits/stl_stack.h:271:5: note: template<class _Tp, class _Seq> bool std::operator>(const std::stack<_Tp, _Seq>&, const std::stack<_Tp, _Seq>&)
/usr/include/c++/4.6/bits/stl_tree.h:883:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator>(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_map.h:913:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator>(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_multimap.h:831:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator>(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_set.h:727:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator>(const std::set<_Key, _Compare, _Alloc>&, const std::set<_Key, _Compare, _Alloc>&)
/usr/include/c++/4.6/bits/stl_multiset.h:710:5: note: template<class _Key, class _Compare, class _Alloc> bool std::operator>(const std::multiset<_Key, _Compare, _Alloc>&, const std::multiset<_Key, _Compare, _Alloc>&)
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/DefaultIsQuadNeeded.h:37:5: error: invalid static_cast from type ‘PolyVox::Density<unsigned char>’ to type ‘float’
../../../addons/ofxPolyvox/src/PolyVoxCore/include/PolyVoxCore/DefaultIsQuadNeeded.h:44:3: warning: control reaches end of non-void function [-Wreturn-type]
make: *** [obj/x86_64Debug/src/testApp.o] Errore 1
Process terminated with status 2 (0 minutes, 1 seconds)
25 errors, 1 warnings




if i exclude these lines of code:

Quote:
CubicSurfaceExtractorWithNormals< RawVolume<Density8> > surfaceExtractor(&resultVolume, resultVolume.getEnclosingRegion(), &mesh);
surfaceExtractor.execute();


the code compile fine but of course without a mesh.

Is this the correct way to use the LowPassFilter and the error is related?
Because i'm interested to smooth my mesh it's better to use another approach to smooth volume data like other c++ lib ( for example OpenMesh http://openmesh.org/ or trimesh2 http://gfx.cs.princeton.edu/proj/trimesh2/) ?
Thanks
Walter


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 9:40 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
The problem here is not the LowPassFilter but it's the CubicSurfaceExtractorWithNormals. The CubicSurfaceExtractorWithNormals will always give you a cubic-style mesh so there's no real point in trying to smooth the volume data. The volume is holding voxels of type 'Density' but the CubicSurfaceExtractorWithNormals doesn't know how to deal with this. It expects each voxel to be either just solid or empty so it can decide whether to generate a cube at that location.

Now, it's quite easy to fix this... we could just use a threshold value and say that all voxels over a given value are solid. While this would be possible it doesn't conceptually make sense because the result is still going to be a cubic-style volume which can't be smooth.

From your other comments regarding smoothing I think you don't really want a cubic surface (you were just experimenting?) but you actually want a smooth marching cubes surface (I notice you actually included MarchingCubesSurfaceExtractor.h). I'm going to guess that you tried the MarchingCubesSurfaceExtractor already and it compiled ok, but you didn't get any output mesh? If so, the reason is that I'm writting values of '32' into the volume which is below the threshold.

Try switching back the the marching cubes extractor and replacing this:
Code:
if(x % 2 == 0)
{
   Density8 voxel(32);
   volData.setVoxelAt(x, y, z, voxel);
}


with:

Code:
if(x % 2 == 0)
{
   Density8 voxel(255); // <-- Note this value has changed
   volData.setVoxelAt(x, y, z, voxel);
}


You should find the marching cubes extractor then generates a valid mesh.

kalwalt wrote:
Because i'm interested to smooth my mesh it's better to use another approach to smooth volume data like other c++ lib ( for example OpenMesh http://openmesh.org/ or trimesh2 http://gfx.cs.princeton.edu/proj/trimesh2/) ?


If your aiming for smooth terrain and using the marching cubes surface extractor, then I'd recommend you smooth the volume data rather than trying to smooth the mesh with those libraries. Using such libraries is possible but there are some catches which make it tricky.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 10:36 am 

Joined: Mon Oct 15, 2012 4:33 pm
Posts: 52
Hi David, I actually own a mesh smooth, not a cubic, and think about it does not make much sense, the code I wrote. and you're right, I'm doing several experiments to understand polyvox.
I will try again with MarchingCubesSurfaceExtractor and the fix suggested... Also i found other functions:
Quote:
computeCentralDifferenceGradient() : PolyVox
computeDecimatedCentralDifferenceGradient() : PolyVox
computeSmoothCentralDifferenceGradient() : PolyVox
computeSmoothedVoxel() : PolyVox
computeSmoothSobelGradient() : PolyVox
computeSobelGradient() : PolyVox

are they also used to smooth the mesh?
may i find some example somewhere?

Quote:
kalwalt wrote:
Because i'm interested to smooth my mesh it's better to use another approach to smooth volume data like other c++ lib ( for example OpenMesh http://openmesh.org/ or trimesh2 http://gfx.cs.princeton.edu/proj/trimesh2/) ?


If your aiming for smooth terrain and using the marching cubes surface extractor, then I'd recommend you smooth the volume data rather than trying to smooth the mesh with those libraries. Using such libraries is possible but there are some catches which make it tricky.


ok i understand,very useful advice ! and i agree with you these lib are sometimes very tricky...


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 12:28 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
kalwalt wrote:
Also i found other functions:
Quote:
computeCentralDifferenceGradient() : PolyVox
computeDecimatedCentralDifferenceGradient() : PolyVox
computeSmoothCentralDifferenceGradient() : PolyVox
computeSmoothedVoxel() : PolyVox
computeSmoothSobelGradient() : PolyVox
computeSobelGradient() : PolyVox

are they also used to smooth the mesh?


No, they are used to compute normals for the mesh. This doesn't affect how smooth the mesh actually is, but it can affect how smooth it looks. But actually I think the MarchingCubesSurfaceExtractor contains some copies of this code so the functions you list might not actually be called anywhere. I need to tidy up some of this code duplication in the future.

Basically you can just ignore those functions - the MarchingcubesSurfaceExtractor takes care of computing the normals for you.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 1:30 pm 

Joined: Mon Oct 15, 2012 4:33 pm
Posts: 52
Dear David,

I made ​​changes to the code that you suggested me, trying on a simple sphere. Now it compiles without errors but I get no mesh. From the console, I get 0 vertices. I tried different combinations of density, region size and radius of the sphere but still getting the same result ... there is still something wrong with the code or what else?
Sorry for these embarrassing questions from beginner ...!

here my code:

Quote:
#include "testApp.h"
#include "ofxPolyvox.h"
#include "PolyVoxCore/MarchingCubesSurfaceExtractor.h"
#include "PolyVoxCore/RawVolume.h"
#include "PolyVoxCore/MaterialDensityPair.h"
#include "PolyVoxCore/Density.h"
#include "PolyVoxCore/PolyVoxForwardDeclarations.h"
#include "PolyVoxCore/LowPassFilter.h"
//Use the PolyVox namespace
using namespace PolyVox;


void createSphereInVolume(RawVolume<Density8>& volData, float fRadius)

{
//This vector hold the position of the center of the volume
Vector3DFloat v3dVolCenter(volData.getWidth() / 2, volData.getHeight() / 2, volData.getDepth() / 2);

//This three-level for loop iterates over every voxel in the volume
for (int z = 0; z < volData.getWidth(); z++)
{
for (int y = 0; y < volData.getHeight(); y++)
{
for (int x = 0; x < volData.getDepth(); x++)
{
//Store our current position as a vector...
Vector3DFloat v3dCurrentPos(x,y,z);
//And compute how far the current position is from the center of the volume
float fDistToCenter = (v3dCurrentPos - v3dVolCenter).length();



//If the current voxel is less than 'radius' units from the center then we make it solid.
if(fDistToCenter <= fRadius)
{
uint8_t uDensity = std::numeric_limits<uint8_t>::max();
//Our new density value

Density8 voxel(210);
//volData.setVoxelAt(x, y, z, uDensity);
volData.setVoxelAt(x, y, z, voxel);
}



}
}
}
}
//--------------------------------------------------------------
void testApp::setup(){
//We'll be rendering with index/vertex arrays
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);

const int32_t g_uVolumeSideLength = 255;

PolyVox::Region reg(Vector3DInt32(0,0,0), Vector3DInt32(g_uVolumeSideLength-1, g_uVolumeSideLength-1, g_uVolumeSideLength-1));

//Create empty volume
RawVolume<Density8> volData(reg);

createSphereInVolume(volData,80);

RawVolume<Density8> resultVolume(reg);


LowPassFilter< RawVolume<Density8>, RawVolume<Density8> > pass1(&volData, reg, &resultVolume, reg, 5);

pass1.execute();

SurfaceMesh<PositionMaterialNormal> mesh;


MarchingCubesSurfaceExtractor< RawVolume<Density8> > surfaceExtractor(&resultVolume, resultVolume.getEnclosingRegion(), &mesh);

surfaceExtractor.execute();

cout << "No. vertices=" << mesh.getNoOfVertices() << endl;

polyvox.setSurfaceMeshToRender(mesh);

}

//--------------------------------------------------------------
void testApp::update(){
}

//--------------------------------------------------------------
void testApp::draw(){

cam.begin();

//Enable smooth lighting

ofEnableLighting();

glEnable(GL_LIGHT0);

ofScale(200,200,200);
polyvox.draw();

cam.end();

}


thanks also for the clarification in the previous post!


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 1:56 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
Does it work if you run the surface extractor on 'volData' instead of 'resultVolume'? i.e. are you sure it's the LowPassFilter which is causing the problem here?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 2:07 pm 

Joined: Mon Oct 15, 2012 4:33 pm
Posts: 52
[
Quote:
Does it work if you run the surface extractor on 'volData' instead of 'resultVolume'? i.e. are you sure it's the LowPassFilter which is causing the problem here?


No, it doesn't work . so the problem reside not in the LowPassFilter but in somewhere in the code....


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 2:35 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
But it was working for you at some point, or did you never see it working? I guess you based the code on the BasicExample and that was working for you? I don't see anything obviously wrong, so maybe you can compare to the BasicExample?


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Wed Oct 31, 2012 3:23 pm 

Joined: Mon Oct 15, 2012 4:33 pm
Posts: 52
David, i solved the problem! :D

just used:

Quote:
pass1.executeSAT();


instead of:

Quote:
pass1.execute();


what is the difference between the two?

I plan to create a repo in my github page for the OpenFrameworks addon and i will upload the addon and some examples, I think in a few days, a week.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: using LowPassFilter
PostPosted: Thu Nov 01, 2012 9:09 am 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
I don't think that was the problem, we'd already found that it still didn't work if you removed the LowPassFilter entirely. Or at least, it's not the whole problem. But I'm glad you got it working at least.

kalwalt wrote:
what is the difference between the two?


It's supposed to just be an implementation difference and the results should be the same (I think) but in practice they are not. I need to look into this, there may be a bug. But basically the SAT version runs in constant time whereas for the other version the time depends on the size of the kernel. This makes the SAT version slower for small kernels and faster for big kernels.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net