mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-20 03:16:10 +00:00
improved movement of particles on the Surface
more realistic generation of dust mesh implemented in dirt_utils.h deleted dustsampler.h
This commit is contained in:
parent
26fb620ec0
commit
d959e7f63a
@ -24,8 +24,8 @@
|
||||
#define DIRT_UTILS_H
|
||||
|
||||
//Include Files
|
||||
#include <vcg/complex/trimesh/point_sampling.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <common/meshmodel.h>
|
||||
#include <common/interfaces.h>
|
||||
#include<vector>
|
||||
@ -34,25 +34,33 @@
|
||||
#include<vcg/complex/trimesh/base.h>
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/space/intersection2.h>
|
||||
|
||||
|
||||
#include "dustparticle.h"
|
||||
|
||||
|
||||
/*
|
||||
@description Simulate the movement of a point, affected by a force "dir" on a face.
|
||||
|
||||
@parameter CMeshO::CoordType p - coordinates of the point
|
||||
@parameter CMeshO::FaceType face - pointer to the face
|
||||
@parameter CmeshO;;CoordType dir
|
||||
@param CoordType p - coordinates of the point
|
||||
@param CoordType v - velocity of the particle
|
||||
@param float m - mass of the particle
|
||||
@param FaceType face - pointer to the face
|
||||
@param CoordType dir - direction of the force
|
||||
@param float t - time step
|
||||
|
||||
@return new coordinates of the point
|
||||
*/
|
||||
|
||||
CMeshO::CoordType StepForward(CMeshO::CoordType p, CMeshO::FacePointer &face, CMeshO::CoordType dir,float t=1){
|
||||
CMeshO::CoordType StepForward(CMeshO::CoordType p,
|
||||
CMeshO::CoordType v,
|
||||
float m,
|
||||
CMeshO::FacePointer &face,
|
||||
CMeshO::CoordType dir,
|
||||
float t=1){
|
||||
//int t=1;
|
||||
Point3<float> new_pos;
|
||||
Point3<float> n= face->N();
|
||||
Point3<float> n= face->cN();
|
||||
float a=n[0]*dir[0]+n[1]*dir[1]+n[2]*dir[2];
|
||||
//if(a<0.01 && a>-0.01 ) return p;
|
||||
|
||||
|
||||
Point3<float> f;
|
||||
//Calcolo le componenti della forza lungo il piano
|
||||
@ -62,51 +70,72 @@ CMeshO::CoordType StepForward(CMeshO::CoordType p, CMeshO::FacePointer &face, CM
|
||||
|
||||
|
||||
|
||||
new_pos[0]=p[0]+0.5*f[0]*t*t;
|
||||
new_pos[1]=p[1]+0.5*f[1]*t*t;
|
||||
new_pos[2]=p[2]+0.5*f[2]*t*t;
|
||||
new_pos[0]=p[0]+v[0]*t+0.5*(f[0]/m)*pow(t,2);
|
||||
new_pos[1]=p[1]+v[1]*t+0.5*(f[1]/m)*pow(t,2);
|
||||
new_pos[2]=p[2]+v[2]*t+0.5*(f[2]/m)*pow(t,2);
|
||||
|
||||
return new_pos;
|
||||
};
|
||||
|
||||
void DrawDirt(MeshDocument &md,std::vector<Point3f> &dp){
|
||||
//TODO
|
||||
void DrawDirt(MeshModel &m/*,std::vector<Point3f> &dp*/){
|
||||
|
||||
float base_color=255;
|
||||
float s_color;
|
||||
std::pair<float,float> minmax = tri::Stat<CMeshO>::ComputePerFaceQualityMinMax(m.cm);
|
||||
CMeshO::FaceIterator fi;
|
||||
|
||||
for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)
|
||||
{
|
||||
if(fi->Q()>0.5){
|
||||
|
||||
s_color=(1-(*fi).Q())*base_color;
|
||||
(*fi).C()=Color4b(s_color, s_color, s_color, 0);
|
||||
}else{
|
||||
(*fi).C()=Color4b(255,255,255,255);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// (*fi).C().ColorRamp(minmax.first,minmax.second,(*fi).Q());
|
||||
|
||||
};
|
||||
|
||||
|
||||
bool ComputeIntersection(CMeshO::CoordType p1,
|
||||
CMeshO::CoordType p2,
|
||||
CMeshO::FacePointer &f,
|
||||
CMeshO::CoordType &int_point,
|
||||
CMeshO::FacePointer &new_f){
|
||||
/*
|
||||
@description Compute the intersection of the segment from p1 to p2 and the face f
|
||||
|
||||
@param CoordType p1 - position of the first point
|
||||
@param Coordtype p2 - position of the second poin
|
||||
@param Facepointer f - pointer to the face
|
||||
@param CoordType int_point - intersection point this is a return parameter for the function.
|
||||
@param FacePointer face - pointer to the new face
|
||||
@return true if there is an intersection
|
||||
|
||||
*/
|
||||
|
||||
|
||||
bool ComputeIntersection(CMeshO::CoordType p1,CMeshO::CoordType p2,CMeshO::FacePointer &f,CMeshO::CoordType &int_point,CMeshO::FacePointer &new_f)
|
||||
{
|
||||
|
||||
CMeshO::CoordType n=f->N();
|
||||
|
||||
//(*f).C()=Color4b::Blue;
|
||||
int max_c;
|
||||
float n0=math::Abs(n[0]);
|
||||
/*float n0=math::Abs(n[0]);
|
||||
float n1=math::Abs(n[1]);
|
||||
float n2=math::Abs(n[2]);
|
||||
|
||||
|
||||
if(n0>n1){
|
||||
if(n0>n2) max_c=0;
|
||||
else max_c=2;
|
||||
}else{
|
||||
if(n1>n2) max_c=1;
|
||||
else max_c=2;
|
||||
}
|
||||
|
||||
/*
|
||||
if(n0>n1){
|
||||
if(n0>n2) max_c=0;
|
||||
else max_c=2;
|
||||
}else{
|
||||
if(n1>n2) max_c=1;
|
||||
else max_c=2;
|
||||
}
|
||||
*/
|
||||
// CMeshO::CoordType int_point;
|
||||
float n0=n[0];
|
||||
float n1=n[1];
|
||||
float n2=n[2];
|
||||
|
||||
if(n0>n1){
|
||||
if(n0>n2) max_c=0;
|
||||
else max_c=2;
|
||||
}else{
|
||||
if(n1>n2) max_c=1;
|
||||
else max_c=2;
|
||||
}
|
||||
Point2f int_p;
|
||||
|
||||
Segment2f seg;
|
||||
@ -195,53 +224,25 @@ bool ComputeIntersection(CMeshO::CoordType p1,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if(SegmentSegmentIntersection(line0,seg,int_p)){
|
||||
int_found=true;
|
||||
edge=0;
|
||||
}else{
|
||||
if(SegmentSegmentIntersection(line1,seg,int_p)){
|
||||
int_found=true;
|
||||
edge=1;
|
||||
}else{
|
||||
if(SegmentSegmentIntersection(line2,seg,int_p)){
|
||||
int_found=true;
|
||||
edge=2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
if(int_found){
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
f->C()=Color4b::Red;//Debug
|
||||
new_f=f->FFp(edge);
|
||||
|
||||
|
||||
//f->C()=Color4b::Blue; //Debugging
|
||||
new_f=f->FFp(edge);
|
||||
//new_f->C()=Color4b::Green;//Debugging
|
||||
switch(max_c){
|
||||
|
||||
case 0:{
|
||||
case 0:{
|
||||
int_point[0]=(n[0]*fv0[0]-n[1]*(int_p[0]-fv0[1])-n[2]*(int_p[1]-fv0[2]))/n[0];
|
||||
int_point[1]=int_p[0];
|
||||
int_point[2]=int_p[1];
|
||||
break;
|
||||
}
|
||||
case 1:{
|
||||
}
|
||||
case 1:{
|
||||
int_point[0]=int_p[0];
|
||||
int_point[1]=(n[1]*fv0[1]-n[0]*(int_p[0]-fv0[0])-n[2]*(int_p[1]-fv0[2]))/n[1];
|
||||
int_point[2]=int_p[1];
|
||||
break;
|
||||
}
|
||||
case 2:{
|
||||
}
|
||||
case 2:{
|
||||
int_point[0]=int_p[0];
|
||||
int_point[1]=int_p[1];
|
||||
int_point[2]=(n[2]*fv0[2]-n[0]*(int_p[0]-fv0[0])-n[1]*(int_p[1]-fv0[1]))/n[2];
|
||||
@ -253,39 +254,139 @@ bool ComputeIntersection(CMeshO::CoordType p1,
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
return int_found;
|
||||
|
||||
|
||||
};
|
||||
|
||||
bool IsOnFace(CMeshO::CoordType &p, CMeshO::FacePointer &f){
|
||||
|
||||
|
||||
CMeshO::CoordType RandomBaricentric(){
|
||||
CMeshO::CoordType interp;
|
||||
|
||||
static math::MarsenneTwisterRNG rnd;
|
||||
interp[1] = rnd.generate01();
|
||||
interp[2] = rnd.generate01();
|
||||
if(interp[1] + interp[2] > 1.0)
|
||||
{
|
||||
interp[1] = 1.0 - interp[1];
|
||||
interp[2] = 1.0 - interp[2];
|
||||
}
|
||||
|
||||
assert(interp[1] + interp[2] <= 1.0);
|
||||
interp[0]=1.0-(interp[1] + interp[2]);
|
||||
return interp;
|
||||
};
|
||||
|
||||
/*
|
||||
@description Compute the Normal Dust Amount Function per face of a Mesh m
|
||||
|
||||
@param m MeshModel
|
||||
@param u CoordType dust direction
|
||||
@param k float
|
||||
@param s float
|
||||
*/
|
||||
bool ComputeNormalDustAmount(MeshModel* m,CMeshO::CoordType u,float k,float s){
|
||||
|
||||
//Verify if FaceQualty is enabled
|
||||
CMeshO::FaceIterator fi;
|
||||
float d;
|
||||
for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){
|
||||
d=k/s+(1+k/s)*pow(fi->N().dot(u),s);
|
||||
fi->Q()=d;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
@description This function compute the Surface Exposure per face of a Mesh m
|
||||
|
||||
|
||||
*/
|
||||
float ComputeSurfaceExposure(MeshModel* m){
|
||||
return 0.0f;
|
||||
};
|
||||
|
||||
void CreateDustTexture(MeshModel* m){
|
||||
QString textName="dust_texture";
|
||||
QString fileName(m->fullName());
|
||||
fileName = fileName.left(std::max<int>(fileName.lastIndexOf('\\'),fileName.lastIndexOf('/'))+1).append(textName);
|
||||
QFile textFile(fileName);
|
||||
QImage img(640, 640, QImage::Format_RGB32);
|
||||
img.fill(qRgb(0,0,0)); // black
|
||||
img.save(fileName,"jpg");
|
||||
m->cm.textures.clear();
|
||||
m->cm.textures.push_back(textName.toStdString());
|
||||
|
||||
}
|
||||
|
||||
bool GenerateDustParticles(MeshModel* m,std::vector<CMeshO::CoordType> &cpv,std::vector<DustParticle <CMeshO> > &dpv,int d,float threshold){
|
||||
|
||||
CMeshO::FaceIterator fi;
|
||||
CMeshO::CoordType p;
|
||||
cpv.clear();
|
||||
dpv.clear();
|
||||
//bool added=false; //debugging
|
||||
|
||||
for(fi=m->cm.face.begin();fi!=m->cm.face.end();++fi){
|
||||
if(fi->Q()>threshold){
|
||||
for(int i=0;i<(int)d*fi->Q()/* && !added*/;i++){
|
||||
//added=true;
|
||||
p=RandomBaricentric();
|
||||
CMeshO::CoordType n_p;
|
||||
n_p[0]=fi->P(0)[0]*p[0]+fi->P(1)[0]*p[1]+fi->P(2)[0]*p[2];
|
||||
n_p[1]=fi->P(0)[1]*p[0]+fi->P(1)[1]*p[1]+fi->P(2)[1]*p[2];
|
||||
n_p[2]=fi->P(0)[2]*p[0]+fi->P(1)[2]*p[1]+fi->P(2)[2]*p[2];
|
||||
//cpv.push_back(fi->P(0)*p[0]+fi->P(1)*p[1]+fi->P(2)*p[2]);
|
||||
cpv.push_back(n_p);
|
||||
DustParticle<CMeshO> part;
|
||||
part.face=&(*fi);
|
||||
part.bar_coord=p;
|
||||
dpv.push_back(part);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/*
|
||||
@description
|
||||
|
||||
@param
|
||||
@param
|
||||
*/
|
||||
bool IsOnFace(CMeshO::CoordType &p, CMeshO::FacePointer f){
|
||||
|
||||
CMeshO::CoordType b;
|
||||
CMeshO::CoordType p0=f->P(0);
|
||||
CMeshO::CoordType p1=f->P(1);
|
||||
CMeshO::CoordType p2=f->P(2);
|
||||
|
||||
//x
|
||||
float A=p0[0]-p2[0];
|
||||
float B=p1[0]-p2[0];
|
||||
float C=p2[0]-p[0];
|
||||
double A=p0[0]-p2[0];
|
||||
double B=p1[0]-p2[0];
|
||||
double C=p2[0]-p[0];
|
||||
//y
|
||||
float D=p0[1]-p2[1];
|
||||
float E=p1[1]-p2[1];
|
||||
float F=p2[1]-p[1];
|
||||
double D=p0[1]-p2[1];
|
||||
double E=p1[1]-p2[1];
|
||||
double F=p2[1]-p[1];
|
||||
//z
|
||||
float G=p0[1]-p2[1];
|
||||
float H=p1[1]-p2[1];
|
||||
float I=p2[1]-p[1];
|
||||
double G=p0[2]-p2[2];
|
||||
double H=p1[2]-p2[2];
|
||||
double I=p2[2]-p[2];
|
||||
|
||||
b[0]=( B*(F+I)-C*(E+H))/( A*(E+H)-B*(D+G) );
|
||||
b[1]=( A*(F+I)-C*(D+G))/( B*(D+G)- A*(E+H) );
|
||||
b[2]=1.0-b[0]-b[1];
|
||||
|
||||
if(b[0]<0 || b[1]<0 || b[2]<0) return false;
|
||||
if(b[0]<0 || b[1]<0 || b[2]<0) return false;
|
||||
|
||||
return true;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // DIRT_UTILS_H
|
||||
|
||||
@ -28,7 +28,6 @@
|
||||
#include<vcg/simplex/vertex/base.h>
|
||||
#include<vcg/simplex/face/base.h>
|
||||
#include<vcg/complex/trimesh/base.h>
|
||||
#include "dirt_utils.h"
|
||||
|
||||
template <class MeshType>
|
||||
|
||||
@ -39,17 +38,24 @@ class DustParticle{
|
||||
typedef typename MeshType::FacePointer FacePointer;
|
||||
public:
|
||||
DustParticle(){
|
||||
mass=1;
|
||||
mass=1.0f;
|
||||
speed[0]=0.0f;
|
||||
speed[1]=0.0f;
|
||||
speed[2]=0.0f;
|
||||
};
|
||||
|
||||
DustParticle(float m,CoordType v){
|
||||
mass=m;
|
||||
speed=v;
|
||||
};
|
||||
~DustParticle(){};
|
||||
|
||||
|
||||
public:
|
||||
FacePointer face;
|
||||
CoordType bar_coord;
|
||||
CoordType bar_coord;/*To delete?*/
|
||||
float mass;
|
||||
float speed;/*to delete?*/
|
||||
CoordType speed;
|
||||
|
||||
float ad_coeff;/*Adhesion Coefficient*/
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
#include <QtGui>
|
||||
#include "filter_dirt.h"
|
||||
#include "dustparticle.h"
|
||||
#include "dustsampler.h"
|
||||
//#include "dustsampler.h"
|
||||
#include "dirt_utils.h"
|
||||
|
||||
|
||||
@ -78,6 +78,7 @@ QString FilterDirt::filterName(FilterIDType filterId) const
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString FilterDirt::filterInfo(FilterIDType filterId) const
|
||||
{
|
||||
switch (filterId) {
|
||||
@ -91,9 +92,18 @@ QString FilterDirt::filterInfo(FilterIDType filterId) const
|
||||
}
|
||||
|
||||
void FilterDirt::initParameterSet(QAction* filter,MeshDocument &md, RichParameterSet &par){
|
||||
par.addParam(new RichInt("nparticles",1000,"Number of Dust Particles","Number of Dust Particles to Generate"));
|
||||
//par.addParam(new RichDynamicFloat("step",0,0,10,"Steps","Steps of simulation"));
|
||||
|
||||
|
||||
|
||||
par.addParam(new RichFloat("dir_x",0.0,"x","x direction of dust source"));
|
||||
par.addParam(new RichFloat("dir_y",0.0,"y","y direction of dust source"));
|
||||
par.addParam(new RichFloat("dir_z",0.0,"z","z direction of dust source"));
|
||||
par.addParam(new RichInt("nparticles",10,"particles","Max Number of Dust Particles to Generate Per Face"));
|
||||
par.addParam(new RichFloat("slippiness",1,"s","The surface slippines"));
|
||||
par.addParam(new RichFloat("adhesion",0.2,"k","Factor to model the general adhesion"));
|
||||
par.addParam(new RichBool("mtc",false,"Map To Colors",""));
|
||||
par.addParam(new RichBool("gt",false,"Generate Texture",""));
|
||||
//par.addParam(new RichDynamicFloat("step",0,0,10,"Steps","Steps of simulation"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -106,53 +116,48 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet
|
||||
{
|
||||
|
||||
|
||||
if(md.size()>=2){//This is temporary just to try new steps of simulation
|
||||
if(md.size()>=2){//This is temporary, just to try new steps of simulation
|
||||
|
||||
|
||||
MeshModel* dmesh=md.getMesh("Dust Mesh");
|
||||
Point3f dir;
|
||||
Point3f new_bar_coords;
|
||||
dir[0]=0;
|
||||
dir[1]=0;
|
||||
dir[2]=0.5;
|
||||
dir[1]=-1;
|
||||
dir[2]=0;
|
||||
if(dmesh!=0){
|
||||
CMeshO::VertexIterator vi;//= dmesh->cm.vert.begin();
|
||||
CMeshO::PerVertexAttributeHandle<DustParticle<CMeshO> > pi = tri::Allocator<CMeshO>::GetPerVertexAttribute<DustParticle<CMeshO> >(dmesh->cm,"ParticleInfo");
|
||||
CMeshO::CoordType new_pos;
|
||||
CMeshO::CoordType int_p;
|
||||
CMeshO::FacePointer pre_face;
|
||||
CMeshO::FacePointer new_f;
|
||||
bool stop_movement=false;
|
||||
for(vi=dmesh->cm.vert.begin();vi!=dmesh->cm.vert.end();++vi){
|
||||
stop_movement=false;
|
||||
new_pos=StepForward((*vi).P(),pi[vi].face,dir);
|
||||
pre_face=pi[vi].face;
|
||||
new_pos=StepForward((*vi).P(),pi[vi].speed,pi[vi].mass,pi[vi].face,dir);
|
||||
while(!stop_movement){
|
||||
|
||||
if(!IsOnFace(new_pos,pi[vi].face)){
|
||||
|
||||
|
||||
//if(ComputeIntersection((*vi).P(),new_pos,pi[vi].face,int_p,new_f)){
|
||||
//if(ComputeIntersection((*vi).P(),new_pos,pi[vi].face,int_p,new_f))
|
||||
ComputeIntersection((*vi).P(),new_pos,pi[vi].face,int_p,new_f);
|
||||
|
||||
pi[vi].face=new_f;
|
||||
Segment3f s1=Segment3f((*vi).P(),new_pos);
|
||||
Segment3f s2=Segment3f((*vi).P(),int_p);
|
||||
float t=s2.Length()/s1.Length();
|
||||
new_pos=int_p;
|
||||
(*vi).P()=new_pos;
|
||||
(*pi[vi].face).C()=Color4b::Blue;//Debugging
|
||||
new_pos=StepForward((*vi).P(),pi[vi].face,dir,t);
|
||||
|
||||
/*if(!IsOnFace(new_pos,pi[vi].face))
|
||||
{ {
|
||||
(*pi[vi].face).C()=Color4b::Green;//Debugging
|
||||
stop_movement=true;
|
||||
(*vi).P()=new_pos;
|
||||
}*/
|
||||
// }
|
||||
if(pre_face!=new_f)
|
||||
{
|
||||
float t=s2.Length()/s1.Length();
|
||||
pre_face=new_f;
|
||||
new_pos=StepForward((*vi).P(),pi[vi].speed,pi[vi].mass,pi[vi].face,dir,t);
|
||||
}
|
||||
else stop_movement=true;
|
||||
}else{
|
||||
//The new position is on the same face
|
||||
(*pi[vi].face).C()=Color4b::Green;//Debugging
|
||||
stop_movement=true;
|
||||
stop_movement=true;
|
||||
(*vi).P()=new_pos;
|
||||
}
|
||||
|
||||
@ -162,28 +167,31 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet
|
||||
}
|
||||
}
|
||||
}else{
|
||||
|
||||
//First Application
|
||||
Point3f dir;
|
||||
dir[0]=par.getFloat("dir_x");
|
||||
dir[1]=par.getFloat("dir_y");
|
||||
dir[2]=par.getFloat("dir_z");
|
||||
|
||||
vector<Point3f> dustVertexVec;
|
||||
vector<DustParticle<CMeshO> > dustParticleVec;
|
||||
|
||||
DustSampler<CMeshO> ts(dustVertexVec,dustParticleVec);
|
||||
MeshModel* currMM=md.mm();
|
||||
|
||||
if (currMM->cm.fn==0) {
|
||||
errorMessage = "This filter requires a mesh with some faces,<br> it does not work on PointSet";
|
||||
return false;
|
||||
}
|
||||
std::string func_d = "ny";
|
||||
|
||||
|
||||
currMM->updateDataMask(MeshModel::MM_FACEFACETOPO);
|
||||
currMM->updateDataMask(MeshModel::MM_FACEMARK);
|
||||
currMM->updateDataMask(MeshModel::MM_FACECOLOR);
|
||||
currMM->updateDataMask(MeshModel::MM_VERTQUALITY);
|
||||
currMM->updateDataMask(MeshModel::MM_FACEQUALITY);
|
||||
//currMM->updateDataMask(MeshModel::MM_WEDGTEXCOORD);
|
||||
tri::UnMarkAll(currMM->cm);
|
||||
|
||||
//clean Mesh
|
||||
|
||||
tri::Allocator<CMeshO>::CompactFaceVector(currMM->cm);
|
||||
tri::Clean<CMeshO>::RemoveUnreferencedVertex(currMM->cm);
|
||||
tri::Clean<CMeshO>::RemoveDuplicateVertex(currMM->cm);
|
||||
@ -197,28 +205,15 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet
|
||||
tri::UpdateNormals<CMeshO>::PerFaceNormalized(currMM->cm);
|
||||
tri::UpdateFlags<CMeshO>::FaceProjection(currMM->cm);
|
||||
|
||||
Parser p;
|
||||
|
||||
|
||||
setPerVertexVariables(p);
|
||||
p.SetExpr(func_d);
|
||||
|
||||
CMeshO::VertexIterator vi;
|
||||
|
||||
for(vi=currMM->cm.vert.begin();vi!=currMM->cm.vert.end();++vi)
|
||||
{
|
||||
setAttributes(vi,currMM->cm);
|
||||
try {
|
||||
(*vi).Q() = p.Eval();
|
||||
} catch(Parser::exception_type &e) {
|
||||
errorMessage = e.GetMsg().c_str();
|
||||
return false;
|
||||
}
|
||||
//Initialize quality for face
|
||||
CMeshO::FaceIterator fIter;
|
||||
for(fIter=currMM->cm.face.begin();fIter!=currMM->cm.face.end();++fIter){
|
||||
fIter->Q()=0;
|
||||
}
|
||||
|
||||
tri::SurfaceSampling<CMeshO,DustSampler<CMeshO> >::Montecarlo(currMM->cm,ts,par.getInt("nparticles"));
|
||||
|
||||
//dmm -> Dust Mesh Model
|
||||
ComputeNormalDustAmount(currMM,dir,par.getFloat("adhesion"),par.getFloat("slippiness"));
|
||||
GenerateDustParticles(currMM,dustVertexVec,dustParticleVec,par.getInt("nparticles"),0.6);
|
||||
//dmm-> Dust Mesh Model
|
||||
MeshModel* dmm=md.addNewMesh("Dust Mesh");
|
||||
|
||||
dmm->cm.Clear();
|
||||
@ -226,20 +221,17 @@ bool FilterDirt::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet
|
||||
|
||||
CMeshO::PerVertexAttributeHandle<DustParticle<CMeshO> > ph= tri::Allocator<CMeshO>::AddPerVertexAttribute<DustParticle<CMeshO> > (dmm->cm,std::string("ParticleInfo"));
|
||||
|
||||
|
||||
CMeshO::VertexIterator vIter=dmm->cm.vert.begin();
|
||||
vector<Point3f>::iterator dvIter;
|
||||
std::vector< DustParticle<CMeshO> >::iterator dpIter=dustParticleVec.begin();
|
||||
|
||||
for(dvIter=dustVertexVec.begin();dvIter!=dustVertexVec.end();++dvIter){
|
||||
(*vIter).P()=CMeshO::CoordType ((*dvIter)[0],(*dvIter)[1],(*dvIter)[2]);
|
||||
|
||||
ph[vIter]=(*dpIter);
|
||||
++dpIter;
|
||||
++vIter;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -248,52 +240,7 @@ MeshFilterInterface::FilterClass FilterDirt::getClass(QAction *)
|
||||
return MeshFilterInterface::VertexColoring;
|
||||
}
|
||||
|
||||
void FilterDirt::setPerVertexVariables(Parser &p)
|
||||
{
|
||||
p.DefineVar("x", &x);
|
||||
p.DefineVar("y", &y);
|
||||
p.DefineVar("z", &z);
|
||||
p.DefineVar("nx", &nx);
|
||||
p.DefineVar("ny", &ny);
|
||||
p.DefineVar("nz", &nz);
|
||||
p.DefineVar("r", &r);
|
||||
p.DefineVar("g", &g);
|
||||
p.DefineVar("b", &b);
|
||||
p.DefineVar("q", &q);
|
||||
p.DefineVar("vi",&v);
|
||||
p.DefineVar("rad",&rad);
|
||||
|
||||
// define var for user-defined attributes (if any exists)
|
||||
// if vector is empty, code won't be executed
|
||||
for(int i = 0; i < (int) v_attrNames.size(); i++)
|
||||
p.DefineVar(v_attrNames[i],&v_attrValue[i]);
|
||||
}
|
||||
|
||||
void FilterDirt::setAttributes(CMeshO::VertexIterator &vi, CMeshO &m)
|
||||
{
|
||||
x = (*vi).P()[0]; // coord x
|
||||
y = (*vi).P()[1]; // coord y
|
||||
z = (*vi).P()[2]; // coord z
|
||||
|
||||
nx = (*vi).N()[0]; // normal coord x
|
||||
ny = (*vi).N()[1]; // normal coord y
|
||||
nz = (*vi).N()[2]; // normal coord z
|
||||
|
||||
r = (*vi).C()[0]; // color R
|
||||
g = (*vi).C()[1]; // color G
|
||||
b = (*vi).C()[2]; // color B
|
||||
|
||||
q = (*vi).Q(); // quality
|
||||
|
||||
if(tri::HasPerVertexRadius(m)) rad = (*vi).R();
|
||||
else rad=0;
|
||||
|
||||
v = vi - m.vert.begin(); // zero based index of current vertex
|
||||
|
||||
// if user-defined attributes exist (vector is not empty)
|
||||
// set variables to explicit value obtained through attribute's handler
|
||||
for(int i = 0; i < (int) v_attrValue.size(); i++)
|
||||
v_attrValue[i] = vhandlers[i][vi];
|
||||
}
|
||||
|
||||
Q_EXPORT_PLUGIN(FilterDirt)
|
||||
|
||||
@ -50,7 +50,7 @@ class FilterDirt : public QObject, public MeshFilterInterface
|
||||
std::vector<std::string> v_attrNames;
|
||||
std::vector<double> v_attrValue;
|
||||
//std::vector<std::string> f_attrNames;
|
||||
//std::vector<double> f_attrValue;
|
||||
//std:: vector<double> f_attrValue;
|
||||
std::vector<CMeshO::PerVertexAttributeHandle<float> > vhandlers;
|
||||
//std::vector<CMeshO::PerFaceAttributeHandle<float> > fhandlers;
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
include (../../shared.pri)
|
||||
HEADERS = filter_dirt.h \
|
||||
dirt_utils.h \
|
||||
dustparticle.h \
|
||||
dustsampler.h \
|
||||
dirt_utils.h \
|
||||
# dustsampler.h \
|
||||
$$VCGDIR/vcg/complex/trimesh/point_sampling.h
|
||||
|
||||
SOURCES = filter_dirt.cpp
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user