git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@10865 f3b2605a-c512-4ea7-a41b-209d697bcdaa

This commit is contained in:
sjplimp 2013-10-14 23:22:02 +00:00
parent 60d086bf65
commit 7ec38094e1
3 changed files with 285 additions and 222 deletions

View File

@ -76,10 +76,10 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) :
if (strcmp(arg[6],"type") == 0) adiam = TYPE;
else if (strcmp(arg[6],"element") == 0) adiam = ELEMENT;
// create Image class
// create Image class with single colormap for atoms
// change defaults for 2d
image = new Image(lmp);
image = new Image(lmp,1);
if (domain->dimension == 2) {
image->theta = 0.0;
@ -493,7 +493,7 @@ void DumpImage::write()
// nme = # of atoms this proc will contribute to dump
// pack buf with x,y,z,color,diameter
// set minmax color range if using color map
// set minmax color range if using atom color map
// create my portion of image for my particles
nme = count();
@ -505,7 +505,7 @@ void DumpImage::write()
}
pack(NULL);
if (acolor == ATTRIBUTE) image->color_minmax(nchoose,buf,size_one);
if (acolor == ATTRIBUTE) image->map_minmax(0,nchoose,buf,size_one);
// create image on each proc, then merge them
@ -635,7 +635,7 @@ void DumpImage::create_image()
itype = static_cast<int> (buf[m]);
color = colorelement[itype];
} else if (acolor == ATTRIBUTE) {
color = image->value2color(buf[m]);
color = image->map_value2color(0,buf[m]);
}
if (adiam == NUMERIC) {
@ -717,8 +717,8 @@ void DumpImage::create_image()
color1 = colorelement[type[atom1]];
color2 = colorelement[type[atom2]];
} else if (acolor == ATTRIBUTE) {
color1 = image->value2color(bufcopy[atom1][0]);
color2 = image->value2color(bufcopy[atom2][0]);
color1 = image->map_value2color(0,bufcopy[atom1][0]);
color2 = image->map_value2color(0,bufcopy[atom2][0]);
}
} else if (bcolor == TYPE) {
itype = bond_type[atom1][m];
@ -957,7 +957,7 @@ int DumpImage::modify_param(int narg, char **arg)
if (nentry < 1) error->all(FLERR,"Illegal dump_modify command");
int n = 6 + factor*nentry;
if (narg < n) error->all(FLERR,"Illegal dump_modify command");
int flag = image->colormap(n-1,&arg[1]);
int flag = image->map_reset(0,n-1,&arg[1]);
if (flag) error->all(FLERR,"Illegal dump_modify command");
return n;
}

View File

@ -47,7 +47,7 @@ enum{NO,YES};
/* ---------------------------------------------------------------------- */
Image::Image(LAMMPS *lmp) : Pointers(lmp)
Image::Image(LAMMPS *lmp, int nmap_caller) : Pointers(lmp)
{
MPI_Comm_rank(world,&me);
MPI_Comm_size(world,&nprocs);
@ -75,19 +75,12 @@ Image::Image(LAMMPS *lmp) : Pointers(lmp)
boxcolor = color2rgb("yellow");
background[0] = background[1] = background[2] = 0;
// default color map
// define nmap colormaps, all with default settings
mlo = MINVALUE;
mhi = MAXVALUE;
mstyle = CONTINUOUS;
mrange = FRACTIONAL;
nentry = 2;
mentry = new MapEntry[nentry];
mentry[0].svalue = 0.0;
mentry[0].color = color2rgb("blue");
mentry[1].svalue = 1.0;
mentry[1].color = color2rgb("red");
nmap = nmap_caller;
maps = new ColorMap*[nmap];
for (int i = 0; i < nmap; i++)
maps[i] = new ColorMap(lmp,this);
// static parameters
@ -124,7 +117,6 @@ Image::~Image()
for (int i = 0; i < ncolors; i++) delete [] username[i];
memory->sfree(username);
memory->destroy(userrgb);
delete [] mentry;
memory->destroy(depthBuffer);
memory->destroy(surfaceBuffer);
@ -263,55 +255,6 @@ void Image::view_params(double boxxlo, double boxxhi, double boxylo,
tanPerPixel = -(maxdel / (double) height);
}
/* ----------------------------------------------------------------------
set explicit values for all min/max settings in color map
lo/hi current and lvalue/hvalue settings for lo/hi = MIN/MAX VALUE in entries
if mlo/mhi = MIN/MAX VALUE, compute bounds on just the atoms being visualized
------------------------------------------------------------------------- */
void Image::color_minmax(int n, double *buf, int stride)
{
double two[2],twoall[2];
if (mlo == MINVALUE || mhi == MAXVALUE) {
double lo = BIG;
double hi = -BIG;
int m = 0;
for (int i = 0; i < n; i++) {
lo = MIN(lo,buf[m]);
hi = MAX(hi,buf[m]);
m += stride;
}
two[0] = -lo;
two[1] = hi;
MPI_Allreduce(two,twoall,2,MPI_DOUBLE,MPI_MAX,world);
}
if (mlo == MINVALUE) locurrent = -twoall[0];
else locurrent = mlovalue;
if (mhi == MAXVALUE) hicurrent = twoall[1];
else hicurrent = mhivalue;
if (locurrent > hicurrent) error->all(FLERR,"Invalid image color range");
if (mstyle == CONTINUOUS) {
if (mrange == ABSOLUTE) mentry[0].svalue = locurrent;
else mentry[0].svalue = 0.0;
if (mrange == ABSOLUTE) mentry[nentry-1].svalue = hicurrent;
else mentry[nentry-1].svalue = 1.0;
} else if (mstyle == DISCRETE) {
for (int i = 0; i < nentry; i++) {
if (mentry[i].lo == MINVALUE) {
if (mrange == ABSOLUTE) mentry[i].lvalue = locurrent;
else mentry[i].lvalue = 0.0;
}
if (mentry[i].hi == MAXVALUE) {
if (mrange == ABSOLUTE) mentry[i].hvalue = hicurrent;
else mentry[i].hvalue = 1.0;
}
}
}
}
/* ----------------------------------------------------------------------
initialize image to background color and depth buffer
no need to init surfaceBuffer, since will be based on depth
@ -1090,97 +1033,31 @@ void Image::write_PPM(FILE *fp)
}
/* ----------------------------------------------------------------------
define a color map
args = lo hi style delta N entry1 entry2 ... entryN as defined by caller
redefine properties of the color map index
return 1 if any error in args, else return 0
------------------------------------------------------------------------- */
int Image::colormap(int narg, char **arg)
int Image::map_reset(int index, int narg, char **arg)
{
if (!islower(arg[0][0])) {
mlo = NUMERIC;
mlovalue = force->numeric(FLERR,arg[0]);
} else if (strcmp(arg[0],"min") == 0) mlo = MINVALUE;
else return 1;
return maps[index]->reset(narg,arg);
}
if (!islower(arg[1][0])) {
mhi = NUMERIC;
mhivalue = force->numeric(FLERR,arg[1]);
} else if (strcmp(arg[1],"max") == 0) mhi = MAXVALUE;
else return 1;
/* ----------------------------------------------------------------------
set min/max bounds of color map index
------------------------------------------------------------------------- */
if (mlo == NUMERIC && mhi == NUMERIC && mlovalue >= mhivalue) return 1;
void Image::map_minmax(int index, int n, double *buf, int stride)
{
maps[index]->minmax(n,buf,stride);
}
if (strlen(arg[2]) != 2) return 1;
if (arg[2][0] == 'c') mstyle = CONTINUOUS;
else if (arg[2][0] == 'd') mstyle = DISCRETE;
else if (arg[2][0] == 's') mstyle = SEQUENTIAL;
else return 1;
if (arg[2][1] == 'a') mrange = ABSOLUTE;
else if (arg[2][1] == 'f') mrange = FRACTIONAL;
else return 1;
/* ----------------------------------------------------------------------
return 3-vector color corresponding to value from color map index
------------------------------------------------------------------------- */
if (mstyle == SEQUENTIAL) {
mbinsize = force->numeric(FLERR,arg[3]);
if (mbinsize <= 0.0) return 1;
mbinsizeinv = 1.0/mbinsize;
}
nentry = force->inumeric(FLERR,arg[4]);
if (nentry < 1) return 1;
mentry = new MapEntry[nentry];
int n = 5;
for (int i = 0; i < nentry; i++) {
if (mstyle == CONTINUOUS) {
if (n+2 > narg) return 1;
if (!islower(arg[n][0])) {
mentry[i].single = NUMERIC;
mentry[i].svalue = force->numeric(FLERR,arg[n]);
} else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
mentry[i].color = color2rgb(arg[n+1]);
n += 2;
} else if (mstyle == DISCRETE) {
if (n+3 > narg) return 1;
if (!islower(arg[n][0])) {
mentry[i].lo = NUMERIC;
mentry[i].lvalue = force->numeric(FLERR,arg[n]);
} else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
if (!islower(arg[n+1][0])) {
mentry[i].hi = NUMERIC;
mentry[i].hvalue = force->numeric(FLERR,arg[n+1]);
} else if (strcmp(arg[n+1],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n+1],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
mentry[i].color = color2rgb(arg[n+2]);
n += 3;
} else if (mstyle == SEQUENTIAL) {
if (n+1 > narg) return 1;
mentry[i].color = color2rgb(arg[n]);
n += 1;
}
if (mentry[i].color == NULL) return 1;
}
if (mstyle == CONTINUOUS) {
if (nentry < 2) return 1;
if (mentry[0].single != MINVALUE || mentry[nentry-1].single != MAXVALUE)
return 1;
for (int i = 2; i < nentry-1; i++)
if (mentry[i].svalue <= mentry[i-1].svalue) return 1;
} else if (mstyle == DISCRETE) {
if (nentry < 1) return 1;
if (mentry[nentry-1].lo != MINVALUE || mentry[nentry-1].hi != MAXVALUE)
return 1;
} else if (mstyle == SEQUENTIAL) {
if (nentry < 1) return 1;
}
return 0;
double *Image::map_value2color(int index, double value)
{
return maps[index]->value2color(value);
}
/* ----------------------------------------------------------------------
@ -1216,52 +1093,6 @@ int Image::addcolor(char *name, double r, double g, double b)
return 0;
}
/* ----------------------------------------------------------------------
convert value into an RGB color via color map
------------------------------------------------------------------------- */
double *Image::value2color(double value)
{
double lo,hi;
value = MAX(value,locurrent);
value = MIN(value,hicurrent);
if (mrange == FRACTIONAL) {
if (locurrent == hicurrent) value = 0.0;
else value = (value-locurrent) / (hicurrent-locurrent);
lo = 0.0;
hi = 1.0;
} else {
lo = locurrent;
hi = hicurrent;
}
if (mstyle == CONTINUOUS) {
for (int i = 0; i < nentry-1; i++)
if (value >= mentry[i].svalue && value <= mentry[i+1].svalue) {
double fraction = (value-mentry[i].svalue) /
(mentry[i+1].svalue-mentry[i].svalue);
interpolate[0] = mentry[i].color[0] +
fraction*(mentry[i+1].color[0]-mentry[i].color[0]);
interpolate[1] = mentry[i].color[1] +
fraction*(mentry[i+1].color[1]-mentry[i].color[1]);
interpolate[2] = mentry[i].color[2] +
fraction*(mentry[i+1].color[2]-mentry[i].color[2]);
return interpolate;
}
} else if (mstyle == DISCRETE) {
for (int i = 0; i < nentry; i++)
if (value >= mentry[i].lvalue && value <= mentry[i].hvalue)
return mentry[i].color;
} else {
int ibin = static_cast<int> ((value-lo) * mbinsizeinv);
return mentry[ibin%nentry].color;
}
return NULL;
}
/* ----------------------------------------------------------------------
search the list of color names for the string color
return a pointer to the 3 floating point RGB values
@ -1753,3 +1584,220 @@ double Image::element2diam(char *element)
if (strcmp(element,name[i]) == 0) return diameter[i];
return 0.0;
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ColorMap class
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
ColorMap::ColorMap(LAMMPS *lmp, Image *caller) : Pointers(lmp)
{
image = caller;
// default color map
nentry = 2;
mentry = new MapEntry[nentry];
mentry[0].svalue = 0.0;
mentry[0].color = image->color2rgb("blue");
mentry[1].svalue = 1.0;
mentry[1].color = image->color2rgb("red");
}
/* ---------------------------------------------------------------------- */
ColorMap::~ColorMap()
{
delete [] mentry;
}
/* ----------------------------------------------------------------------
redefine color map
args = lo hi style delta N entry1 entry2 ... entryN as defined by caller
return 1 if any error in args, else return 0
------------------------------------------------------------------------- */
int ColorMap::reset(int narg, char **arg)
{
if (!islower(arg[0][0])) {
mlo = NUMERIC;
mlovalue = force->numeric(FLERR,arg[0]);
} else if (strcmp(arg[0],"min") == 0) mlo = MINVALUE;
else return 1;
if (!islower(arg[1][0])) {
mhi = NUMERIC;
mhivalue = force->numeric(FLERR,arg[1]);
} else if (strcmp(arg[1],"max") == 0) mhi = MAXVALUE;
else return 1;
if (mlo == NUMERIC && mhi == NUMERIC && mlovalue >= mhivalue) return 1;
if (strlen(arg[2]) != 2) return 1;
if (arg[2][0] == 'c') mstyle = CONTINUOUS;
else if (arg[2][0] == 'd') mstyle = DISCRETE;
else if (arg[2][0] == 's') mstyle = SEQUENTIAL;
else return 1;
if (arg[2][1] == 'a') mrange = ABSOLUTE;
else if (arg[2][1] == 'f') mrange = FRACTIONAL;
else return 1;
if (mstyle == SEQUENTIAL) {
mbinsize = force->numeric(FLERR,arg[3]);
if (mbinsize <= 0.0) return 1;
mbinsizeinv = 1.0/mbinsize;
}
nentry = force->inumeric(FLERR,arg[4]);
if (nentry < 1) return 1;
mentry = new MapEntry[nentry];
int n = 5;
for (int i = 0; i < nentry; i++) {
if (mstyle == CONTINUOUS) {
if (n+2 > narg) return 1;
if (!islower(arg[n][0])) {
mentry[i].single = NUMERIC;
mentry[i].svalue = force->numeric(FLERR,arg[n]);
} else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
mentry[i].color = image->color2rgb(arg[n+1]);
n += 2;
} else if (mstyle == DISCRETE) {
if (n+3 > narg) return 1;
if (!islower(arg[n][0])) {
mentry[i].lo = NUMERIC;
mentry[i].lvalue = force->numeric(FLERR,arg[n]);
} else if (strcmp(arg[n],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
if (!islower(arg[n+1][0])) {
mentry[i].hi = NUMERIC;
mentry[i].hvalue = force->numeric(FLERR,arg[n+1]);
} else if (strcmp(arg[n+1],"min") == 0) mentry[i].single = MINVALUE;
else if (strcmp(arg[n+1],"max") == 0) mentry[i].single = MAXVALUE;
else return 1;
mentry[i].color = image->color2rgb(arg[n+2]);
n += 3;
} else if (mstyle == SEQUENTIAL) {
if (n+1 > narg) return 1;
mentry[i].color = image->color2rgb(arg[n]);
n += 1;
}
if (mentry[i].color == NULL) return 1;
}
if (mstyle == CONTINUOUS) {
if (nentry < 2) return 1;
if (mentry[0].single != MINVALUE || mentry[nentry-1].single != MAXVALUE)
return 1;
for (int i = 2; i < nentry-1; i++)
if (mentry[i].svalue <= mentry[i-1].svalue) return 1;
} else if (mstyle == DISCRETE) {
if (nentry < 1) return 1;
if (mentry[nentry-1].lo != MINVALUE || mentry[nentry-1].hi != MAXVALUE)
return 1;
} else if (mstyle == SEQUENTIAL) {
if (nentry < 1) return 1;
}
return 0;
}
/* ----------------------------------------------------------------------
set explicit values for all min/max settings in color map
lo/hi current and lvalue/hvalue settings for lo/hi = MIN/MAX VALUE in entries
if mlo/mhi = MIN/MAX VALUE, compute bounds based on N strided values in buf
------------------------------------------------------------------------- */
void ColorMap::minmax(int n, double *buf, int stride)
{
double two[2],twoall[2];
if (mlo == MINVALUE || mhi == MAXVALUE) {
double lo = BIG;
double hi = -BIG;
int m = 0;
for (int i = 0; i < n; i++) {
lo = MIN(lo,buf[m]);
hi = MAX(hi,buf[m]);
m += stride;
}
two[0] = -lo;
two[1] = hi;
MPI_Allreduce(two,twoall,2,MPI_DOUBLE,MPI_MAX,world);
}
if (mlo == MINVALUE) locurrent = -twoall[0];
else locurrent = mlovalue;
if (mhi == MAXVALUE) hicurrent = twoall[1];
else hicurrent = mhivalue;
if (locurrent > hicurrent) error->all(FLERR,"Invalid image color range");
if (mstyle == CONTINUOUS) {
if (mrange == ABSOLUTE) mentry[0].svalue = locurrent;
else mentry[0].svalue = 0.0;
if (mrange == ABSOLUTE) mentry[nentry-1].svalue = hicurrent;
else mentry[nentry-1].svalue = 1.0;
} else if (mstyle == DISCRETE) {
for (int i = 0; i < nentry; i++) {
if (mentry[i].lo == MINVALUE) {
if (mrange == ABSOLUTE) mentry[i].lvalue = locurrent;
else mentry[i].lvalue = 0.0;
}
if (mentry[i].hi == MAXVALUE) {
if (mrange == ABSOLUTE) mentry[i].hvalue = hicurrent;
else mentry[i].hvalue = 1.0;
}
}
}
}
/* ----------------------------------------------------------------------
convert value into an RGB color via color map
return pointer to 3-vector
------------------------------------------------------------------------- */
double *ColorMap::value2color(double value)
{
double lo,hi;
value = MAX(value,locurrent);
value = MIN(value,hicurrent);
if (mrange == FRACTIONAL) {
if (locurrent == hicurrent) value = 0.0;
else value = (value-locurrent) / (hicurrent-locurrent);
lo = 0.0;
hi = 1.0;
} else {
lo = locurrent;
hi = hicurrent;
}
if (mstyle == CONTINUOUS) {
for (int i = 0; i < nentry-1; i++)
if (value >= mentry[i].svalue && value <= mentry[i+1].svalue) {
double fraction = (value-mentry[i].svalue) /
(mentry[i+1].svalue-mentry[i].svalue);
interpolate[0] = mentry[i].color[0] +
fraction*(mentry[i+1].color[0]-mentry[i].color[0]);
interpolate[1] = mentry[i].color[1] +
fraction*(mentry[i+1].color[1]-mentry[i].color[1]);
interpolate[2] = mentry[i].color[2] +
fraction*(mentry[i+1].color[2]-mentry[i].color[2]);
return interpolate;
}
} else if (mstyle == DISCRETE) {
for (int i = 0; i < nentry; i++)
if (value >= mentry[i].lvalue && value <= mentry[i].hvalue)
return mentry[i].color;
} else {
int ibin = static_cast<int> ((value-lo) * mbinsizeinv);
return mentry[ibin%nentry].color;
}
return NULL;
}

View File

@ -35,7 +35,7 @@ class Image : protected Pointers {
double *boxcolor; // color to draw box outline with
int background[3]; // RGB values of background
Image(class LAMMPS *);
Image(class LAMMPS *, int);
~Image();
void buffers();
void clear();
@ -44,7 +44,6 @@ class Image : protected Pointers {
void write_PPM(FILE *);
void view_params(double, double, double, double, double, double);
void color_minmax(int, double *, int);
void draw_sphere(double *, double *, double);
void draw_cube(double *, double *, double);
void draw_cylinder(double *, double *, double *, double, int);
@ -52,11 +51,13 @@ class Image : protected Pointers {
void draw_box(double (*)[3], double);
void draw_axes(double (*)[3], double);
int colormap(int, char **);
int map_reset(int, int, char **);
void map_minmax(int, int, double *, int);
double *map_value2color(int, double);
int addcolor(char *, double, double, double);
double *element2color(char *);
double element2diam(char *);
double *value2color(double);
double *color2rgb(const char *, int index=0);
int default_colors();
@ -64,6 +65,9 @@ class Image : protected Pointers {
int me,nprocs;
int npixels;
class ColorMap **maps;
int nmap;
double *depthBuffer,*surfaceBuffer;
double *depthcopy,*surfacecopy;
char *imageBuffer,*rgbcopy,*writeBuffer;
@ -106,24 +110,6 @@ class Image : protected Pointers {
char **username;
double **userrgb;
// color map
int mstyle,mrange; // 2-letter style/range of color map
int mlo,mhi; // bounds = NUMERIC or MINVALUE or MAXVALUE
double mlovalue,mhivalue; // user bounds if NUMERIC
double locurrent,hicurrent; // current bounds for this snapshot
double mbinsize,mbinsizeinv; // bin size for sequential color map
struct MapEntry {
int single,lo,hi; // NUMERIC or MINVALUE or MAXVALUE
double svalue,lvalue,hvalue; // actual value
double *color; // RGB values
};
MapEntry *mentry;
int nentry;
double interpolate[3];
// SSAO RNG
class RanMars *random;
@ -148,6 +134,35 @@ class Image : protected Pointers {
}
};
// ColorMap class
class ColorMap : protected Pointers {
public:
ColorMap(class LAMMPS *, class Image*);
~ColorMap();
int reset(int, char **);
void minmax(int, double *, int);
double *value2color(double);
private:
class Image *image; // caller with color2rgb() method
int mstyle,mrange; // 2-letter style/range of color map
int mlo,mhi; // bounds = NUMERIC or MINVALUE or MAXVALUE
double mlovalue,mhivalue; // user bounds if NUMERIC
double locurrent,hicurrent; // current bounds for this snapshot
double mbinsize,mbinsizeinv; // bin size for sequential color map
double interpolate[3]; // local storage for returned RGB color
struct MapEntry {
int single,lo,hi; // NUMERIC or MINVALUE or MAXVALUE
double svalue,lvalue,hvalue; // actual value
double *color; // RGB values
};
MapEntry *mentry;
int nentry;
};
}
#endif