diff --git a/doc/src/dump_image.rst b/doc/src/dump_image.rst index 27d8279a2db..f922e761cc5 100644 --- a/doc/src/dump_image.rst +++ b/doc/src/dump_image.rst @@ -44,14 +44,14 @@ Syntax f_ID = per-grid vector calculated by a fix with ID f_ID[I] = Ith column of per-grid array calculated by a fix with ID *line* = color width - color = *type* + color = *type* or *index* or *atom* width = numeric value for line width (distance units) *tri* = color tflag width - color = *type* + color = *type* or *index* or *atom* tflag = 1 for just triangle, 2 for just tri edges, 3 for both width = numeric value for triangle edge width (distance units) *ellipsoid* = color eflag level width - color = *type* + color = *type* or *index* or *atom* eflag = 1 for triangles, 2 for wireframe, 3 for both level = mesh refinement level, value between 1 (low resolution) and 6 (ultra high resolution) width = diameter of wireframe edges (distance units) (ignored for triangles) @@ -494,10 +494,21 @@ as described below. The *line* keyword can be used when :doc:`atom_style line ` is used to define particles as line segments, and will draw them as lines. If this keyword is not used, such particles will be drawn as -spheres, the same as if they were regular atoms. The only setting -currently allowed for the *color* value is *type*, which will color -the lines according to the atom type of the particle. By default the -mapping of types to colors is as follows: +spheres, the same as if they were regular atoms. + +.. versionchanged:: TBD + + added *index* and *atom* color styles + +The there are currently three supported settings for the *color* value: +*type*, *index*, or *atom*. With the *type* setting the line particles +will be colored according to the atom type of the particle. With the +*index* setting the coloring follows the line index instead. With the +*atom* setting, the color follows the coloring selected for coloring +atoms (including using color maps). For *type* and *index* settings, +the value is mapped to the colors of atom types thus the coloring style +for atoms **must** be set to *type*. The list of colors is by default +the list of atom type colors as follows: * type 1 = red * type 2 = green @@ -506,8 +517,11 @@ mapping of types to colors is as follows: * type 5 = cyan * type 6 = magenta -and repeats itself for types > 6. There is not yet an option to -change this via the dump_modify command. +and repeats itself for types > 6. This list can by changed with the +:doc:`dump_modify acolor ` command. If more different +colors than atom types are desired, the *number of atom types* must be +*increased* correspondingly when using either the :doc:`create_box +` or the :doc:`read_data ` command. The line *width* can only be a numeric value, which specifies that all lines will be drawn as cylinders with that diameter, e.g. 1.0, which @@ -521,10 +535,21 @@ used to define particles as triangles, and will draw them as triangles or edges (3 lines) or both, depending on the setting for *tflag*\ . If edges are drawn, the *width* setting determines the diameters of the line segments. If this keyword is not used, triangle particles will -be drawn as spheres, the same as if they were regular atoms. The only -setting currently allowed for the *color* value is *type*, which will -color the triangles according to the atom type of the particle. By -default the mapping of types to colors is as follows: +be drawn as spheres, the same as if they were regular atoms. + +.. versionchanged:: TBD + + added *index* and *atom* color styles + +The there are currently three supported settings for the *color* value: +*type*, *index*, or *atom*. With the *type* setting the triangles +will be colored according to the atom type of the particle. With the +*index* setting the coloring follows the triangle index instead. With the +*atom* setting, the color follows the coloring selected for coloring +atoms (including using color maps). For *type* and *index* settings, +the value is mapped to the colors of atom types thus the coloring style +for atoms **must** be set to *type*. The list of colors is by default +the list of atom type colors as follows: * type 1 = red * type 2 = green @@ -533,7 +558,11 @@ default the mapping of types to colors is as follows: * type 5 = cyan * type 6 = magenta -and repeats itself for types > 6. +and repeats itself for types > 6. This list can by changed with the +:doc:`dump_modify acolor ` command. If more different +colors than atom types are desired, the *number of atom types* must be +*increased* correspondingly when using either the :doc:`create_box +` or the :doc:`read_data ` command. ---------- @@ -545,9 +574,21 @@ them as a mesh of triangles or edges or both, depending on the setting for *eflag*\ . If edges are drawn, the *width* setting determines the diameters of the line segments. If this keyword is not used, ellipsoid particles will be drawn as spheres, the same as if they were regular -atoms. The only setting currently allowed for the *color* value is -*type*, which will color the triangles according to the atom type of the -particle. By default the mapping of types to colors is as follows: +atoms. + +.. versionchanged:: TBD + + added *index* and *atom* color styles + +The there are currently three supported settings for the *color* value: +*type*, *index*, or *atom*. With the *type* setting the ellipsoids will +be colored according to the atom type of the particle. With the *index* +setting the coloring follows the ellipsoid index instead. With the +*atom* setting, the color follows the coloring selected for coloring +atoms (including using color maps). For *type* and *index* settings, +the value is mapped to the colors of atom types thus the coloring style +for atoms **must** be set to *type*. The list of colors is by default +the list of atom type colors as follows: * type 1 = red * type 2 = green @@ -556,7 +597,11 @@ particle. By default the mapping of types to colors is as follows: * type 5 = cyan * type 6 = magenta -and repeats itself for types > 6. +and repeats itself for types > 6. This list can by changed with the +:doc:`dump_modify acolor ` command. If more different +colors than atom types are desired, the *number of atom types* must be +*increased* correspondingly when using either the :doc:`create_box +` or the :doc:`read_data ` command. The *level* setting determines the number of triangles in the mesh of triangles and thus the resolution of the representation of the @@ -611,10 +656,10 @@ The there are currently three supported settings for the *color* value: the coloring selected for coloring atoms (including using color maps). With the *type* setting the body particles will be colored according to the atom type of the particle. With the *index* setting the coloring -follows the body index instead. For both settings, the value (type or -index) is mapped to the colors of atom types thus the coloring style for -atoms **must** be set to *type*. The list of colors is by default as -follows: +follows the body index instead. For the *type* and *index* settings, +the value (type or index) is mapped to the colors of atom types thus +the coloring style for atoms **must** be set to *type*. The list of +colors is by default as follows: * type 1 = red * type 2 = green diff --git a/src/GRAPHICS/dump_image.cpp b/src/GRAPHICS/dump_image.cpp index e1c0b560399..671e78dd0d0 100644 --- a/src/GRAPHICS/dump_image.cpp +++ b/src/GRAPHICS/dump_image.cpp @@ -261,7 +261,13 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : if (iarg+3 > narg) utils::missing_cmd_args(FLERR,"dump image line", error); lineflag = YES; if (strcmp(arg[iarg+1],"type") == 0) lcolor = TYPE; - else error->all(FLERR, iarg+1, "Dump image line only supports color by type"); + else if (strcmp(arg[iarg+1],"atom") == 0) lcolor = ATOM; + else if (strcmp(arg[iarg+1],"index") == 0) lcolor = INDEX; + else + error->all(FLERR, iarg+1, "Dump image line only supports color by type, atom, or index"); + if ((lcolor != ATOM) && (acolor != TYPE)) + error->all(FLERR, iarg+1, + "Must color atoms by type with line particles colored by type or index"); ldiam = NUMERIC; ldiamvalue = utils::numeric(FLERR,arg[iarg+2],false,lmp); iarg += 3; @@ -270,7 +276,13 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : if (iarg+4 > narg) utils::missing_cmd_args(FLERR,"dump image tri", error); triflag = YES; if (strcmp(arg[iarg+1],"type") == 0) tcolor = TYPE; - else error->all(FLERR, iarg+1, "Dump image tri only supports color by type"); + else if (strcmp(arg[iarg+1],"atom") == 0) tcolor = ATOM; + else if (strcmp(arg[iarg+1],"index") == 0) tcolor = INDEX; + else + error->all(FLERR, iarg+1, "Dump image tri only supports color by type, atom, or index"); + if ((tcolor != ATOM) && (acolor != TYPE)) + error->all(FLERR, iarg+1, + "Must color atoms by type with tri particles colored by type or index"); tstyle = utils::inumeric(FLERR,arg[iarg+2],false,lmp); tdiamvalue = utils::numeric(FLERR,arg[iarg+3],false,lmp); iarg += 4; @@ -279,14 +291,20 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : if (iarg+5 > narg) utils::missing_cmd_args(FLERR,"dump image ellipsoid", error); ellipsoidflag = YES; if (strcmp(arg[iarg+1],"type") == 0) ecolor = TYPE; - else error->all(FLERR, iarg+1, "Dump image ellipsoid only supports color by type"); + else if (strcmp(arg[iarg+1],"atom") == 0) ecolor = ATOM; + else if (strcmp(arg[iarg+1],"index") == 0) ecolor = INDEX; + else + error->all(FLERR, iarg+1, "Dump image ellipsoid only supports color by type, atom, or index"); + if ((ecolor != ATOM) && (acolor != TYPE)) + error->all(FLERR, iarg+1, + "Must color atoms by type with ellipsoid particles colored by type or index"); estyle = utils::inumeric(FLERR,arg[iarg+2],false,lmp); if ((estyle < 0) || (estyle > 3)) error->all(FLERR, iarg+2, "Dump image ellipsoid only supports style setting 1, 2, or 3"); elevel = utils::inumeric(FLERR,arg[iarg+3],false,lmp); if (elevel == 0) elevel = 4; // default setting if (elevel > 6) - error->all(FLERR, iarg+3, "Dump image ellipsoid mesh refinement level is too large"); + error->all(FLERR, iarg+3, "Dump image ellipsoid mesh refinement level {} is too large", elevel); ediamvalue = utils::numeric(FLERR,arg[iarg+4],false,lmp); iarg += 5; @@ -1230,12 +1248,30 @@ void DumpImage::create_image() int *line = atom->line; int *type = atom->type; + m = 0; for (i = 0; i < nchoose; i++) { j = clist[i]; if (line[j] < 0) continue; + itype = type[j]; + double opacity = aopacity[itype]; if (lcolor == TYPE) { - color = colortype[type[j]]; + color = colortype[itype]; + } else if (lcolor == INDEX) { + itype = (line[j] % atom->ntypes) + 1; + color = colortype[itype]; + } else if (lcolor == ATOM) { + if (acolor == TYPE) { + color = colortype[itype]; + } else if (acolor == ELEMENT) { + color = colorelement[itype]; + } else if (acolor == ATTRIBUTE) { + color = image->map_value2color(0,buf[m]); + } else { + color = image->color2rgb("white"); + } + } else { + color = image->color2rgb("white"); } if (ldiam == NUMERIC) { @@ -1255,6 +1291,8 @@ void DumpImage::create_image() pt2[2] = 0.0; image->draw_cylinder(pt1,pt2,color,ldiamvalue,3,aopacity[atom->type[j]]); + + m += size_one; } } @@ -1271,14 +1309,31 @@ void DumpImage::create_image() int *tri = atom->tri; int *type = atom->type; + m = 0; for (i = 0; i < nchoose; i++) { j = clist[i]; if (tri[j] < 0) continue; + itype = type[j]; + double opacity = aopacity[itype]; if (tcolor == TYPE) { - color = colortype[type[j]]; + color = colortype[itype]; + } else if (tcolor == INDEX) { + itype = (tri[j] % atom->ntypes) + 1; + color = colortype[itype]; + } else if (tcolor == ATOM) { + if (acolor == TYPE) { + color = colortype[itype]; + } else if (acolor == ELEMENT) { + color = colorelement[itype]; + } else if (acolor == ATTRIBUTE) { + color = image->map_value2color(0,buf[m]); + } else { + color = image->color2rgb("white"); + } + } else { + color = image->color2rgb("white"); } - double opacity = aopacity[atom->type[j]]; MathExtra::quat_to_mat(avec_tri->bonus[tri[j]].quat,mat); MathExtra::matvec(mat,avec_tri->bonus[tri[j]].c1,pt1); @@ -1288,12 +1343,27 @@ void DumpImage::create_image() MathExtra::add3(pt2,x[j],pt2); MathExtra::add3(pt3,x[j],pt3); - if (tridraw) image->draw_triangle(pt1,pt2,pt3,color,opacity); + if (tridraw) { + // brighten flat surfaces a little bit + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.3; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.8; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.8; + + image->draw_triangle(pt1,pt2,pt3,color,opacity); + + // restore previous settings + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.0; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.9; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.9; + } if (edgedraw) { image->draw_cylinder(pt1,pt2,color,tdiamvalue,3,opacity); image->draw_cylinder(pt2,pt3,color,tdiamvalue,3,opacity); image->draw_cylinder(pt3,pt1,color,tdiamvalue,3,opacity); } + m += size_one; } } @@ -1304,16 +1374,50 @@ void DumpImage::create_image() double **x = atom->x; int *ellipsoid = atom->ellipsoid; int *type = atom->type; + m = 0; + for (i = 0; i < nchoose; i++) { j = clist[i]; if (ellipsoid[j] < 0) continue; + itype = type[j]; + double opacity = aopacity[itype]; if (ecolor == TYPE) { - color = colortype[type[j]]; + color = colortype[itype]; + } else if (ecolor == INDEX) { + itype = (ellipsoid[j] % atom->ntypes) + 1; + color = colortype[itype]; + } else if (ecolor == ATOM) { + if (acolor == TYPE) { + color = colortype[itype]; + } else if (acolor == ELEMENT) { + color = colorelement[itype]; + } else if (acolor == ATTRIBUTE) { + color = image->map_value2color(0,buf[m]); + } else { + color = image->color2rgb("white"); + } + } else { + color = image->color2rgb("white"); + } + if (estyle & 1) { + // brighten flat surfaces a little bit + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.3; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.8; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.8; } EllipsoidObj e(elevel); e.draw(image, estyle, color, x[j], avec_ellipsoid->bonus[ellipsoid[j]].shape, - avec_ellipsoid->bonus[ellipsoid[j]].quat, ediamvalue, aopacity[type[j]]); + avec_ellipsoid->bonus[ellipsoid[j]].quat, ediamvalue, opacity); + if (estyle & 1) { + // restore previous settings + image->ambientColor[0] = image->ambientColor[1] = image->ambientColor[2] = 0.0; + image->keyLightColor[0] = image->keyLightColor[1] = image->keyLightColor[2] = 0.9; + image->fillLightColor[0] = image->fillLightColor[1] = image->fillLightColor[2] = 0.45; + image->backLightColor[0] = image->backLightColor[1] = image->backLightColor[2] = 0.9; + } + m += size_one; } } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index a19303168f9..c5abdfdc600 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -108,9 +108,8 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : ioptional = parse_fields(nfield,earg); - if (ioptional < nfield && - strcmp(style,"image") != 0 && strcmp(style,"movie") != 0) - error->all(FLERR,"Invalid attribute {} in dump {} command",earg[ioptional],style); + if ((ioptional < nfield) && (strcmp(style,"image") != 0) && (strcmp(style,"movie") != 0)) + error->all(FLERR, "Invalid attribute {} in dump {} command", earg[ioptional], style); // noptional = # of optional args // reset nfield to subtract off optional args @@ -1455,6 +1454,10 @@ int DumpCustom::parse_fields(int narg, char **arg) for (int iarg = 0; iarg < narg; iarg++) { int errptr = iarg + argoff; + + // only attempt to parse first two fields for dump image/movie + if ((iarg == 2) && ((strcmp(style,"image") == 0) || (strcmp(style,"movie") == 0))) return 2; + if (strcmp(arg[iarg],"id") == 0) { pack_choice[iarg] = &DumpCustom::pack_id; if (sizeof(tagint) == sizeof(smallint)) vtype[iarg] = Dump::INT;