Commit 893c52f1 authored by Christophe Geuzaine's avatar Christophe Geuzaine

nicer multiline messages

parent 23572fb0
Pipeline #1489 passed with stage
in 36 minutes and 22 seconds
......@@ -178,3 +178,35 @@ bool SplitOptionName(const std::string &fullName, std::string &category,
name.c_str(), index);
return true;
}
static std::string getNextTokenInString(const std::string &msg,
std::string::size_type &first,
char separator)
{
if(first == std::string::npos) return "";
std::string::size_type last = msg.find_first_of(separator, first);
std::string next("");
if(last == std::string::npos){
next = msg.substr(first);
first = last;
}
else if(first == last){
next = "";
first = last + 1;
}
else{
next = msg.substr(first, last - first);
first = last + 1;
}
return next;
}
std::vector<std::string> SplitString(const std::string &msg,
char separator)
{
std::vector<std::string> out;
std::string::size_type first = 0;
while(first != std::string::npos)
out.push_back(getNextTokenInString(msg, first, separator));
return out;
}
......@@ -25,5 +25,6 @@ std::string ReplaceSubString(const std::string &olds, const std::string &news,
void ConvertToHTML(std::string &in);
bool SplitOptionName(const std::string &fullName, std::string &category,
std::string &name, int &index);
std::vector<std::string> SplitString(const std::string &msg, char separator);
#endif
......@@ -2050,81 +2050,6 @@ static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
Msg::StatusGl("");
}
static std::vector<std::string> getInfoStrings(MElement *ele)
{
std::vector<std::string> info;
{
std::ostringstream sstream;
sstream << "Element " << ele->getNum() << ":";
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
const char *name;
MElement::getInfoMSH(ele->getTypeForMSH(), &name);
sstream << " " << name
<< " (MSH type " << ele->getTypeForMSH()
<< ", dimension "<< ele->getDim()
<< ", order "<< ele->getPolynomialOrder()
<< ", partition " << ele->getPartition()
<< ")";
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream << " Nodes:";
for(int i = 0; i < ele->getNumVertices(); i++)
sstream << " " << ele->getVertex(i)->getNum();
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
SPoint3 pt = ele->barycenter();
sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")";
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
sstream << " Edge length: "
<< "min = " << ele->minEdge() << " "
<< "max = " << ele->maxEdge();
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
sstream << " Quality: "
<< "gamma = " << ele->gammaShapeMeasure();
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
double sICNMin, sICNMax;
ele->signedInvCondNumRange(sICNMin, sICNMax);
sstream << " SICN range: " << sICNMin << " " << sICNMax;
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
double sIGEMin, sIGEMax;
ele->signedInvGradErrorRange(sIGEMin, sIGEMax);
sstream << " SIGE range: " << sIGEMin << " " << sIGEMax;
info.push_back(sstream.str());
}
{
std::ostringstream sstream;
sstream.precision(12);
sstream << " Inner / outer radius: "
<< ele->getInnerRadius() << " / " << ele->getOuterRadius();
info.push_back(sstream.str());
}
return info;
}
static void mesh_inspect_cb(Fl_Widget *w, void *data)
{
CTX::instance()->pickElements = 1;
......@@ -2141,7 +2066,7 @@ static void mesh_inspect_cb(Fl_Widget *w, void *data)
ele->setVisibility(2);
CTX::instance()->mesh.changed = ENT_ALL;
drawContext::global()->draw();
std::vector<std::string> info = getInfoStrings(ele);
std::vector<std::string> info = SplitString(ele->getInfoString(true), '\n');
for(unsigned int i = 0; i < info.size(); i++)
Msg::Direct("%s", info[i].c_str());
if(CTX::instance()->tooltips){
......
......@@ -665,24 +665,25 @@ int openglWindow::handle(int event)
else
cursor(FL_CURSOR_DEFAULT, FL_BLACK, FL_WHITE);
std::string text, cmd;
bool multiline = CTX::instance()->tooltips;
if(vertices.size()){
text = vertices[0]->getInfoString();
text = vertices[0]->getInfoString(true, multiline);
cmd = CTX::instance()->geom.doubleClickedPointCommand;
}
else if(edges.size()){
text = edges[0]->getInfoString();
text = edges[0]->getInfoString(true, multiline);
cmd = CTX::instance()->geom.doubleClickedCurveCommand;
}
else if(faces.size()){
text = faces[0]->getInfoString();
text = faces[0]->getInfoString(true, multiline);
cmd = CTX::instance()->geom.doubleClickedSurfaceCommand;
}
else if(regions.size()){
text = regions[0]->getInfoString();
text = regions[0]->getInfoString(true, multiline);
cmd = CTX::instance()->geom.doubleClickedVolumeCommand;
}
else if(elements.size()){
text = elements[0]->getInfoString();
text = elements[0]->getInfoString(multiline);
}
else if(points.size()){
char tmp[256];
......
......@@ -272,27 +272,35 @@ void GEdge::setColor(unsigned int val, bool recursive)
}
}
std::string GEdge::getAdditionalInfoString()
std::string GEdge::getAdditionalInfoString(bool multline)
{
std::ostringstream sstream;
sstream.precision(12);
if(v0 && v1) sstream << "{" << v0->tag() << " " << v1->tag() << "}";
if(meshAttributes.method == MESH_TRANSFINITE){
sstream << " transfinite (" << meshAttributes.nbPointsTransfinite;
int type = meshAttributes.typeTransfinite;
if(std::abs(type) == 1)
sstream << ", progression " << gmsh_sign(type) * meshAttributes.coeffTransfinite;
else if(std::abs(type) == 2)
sstream << ", bump " << meshAttributes.coeffTransfinite;
sstream << ")";
if(v0 && v1){
sstream << "Boundary points: " << v0->tag() << ", " << v1->tag();
}
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reversed";
if(meshAttributes.method == MESH_TRANSFINITE || meshAttributes.extrude ||
meshAttributes.reverseMesh){
if(v0 && v1){
if(multline) sstream << "\n";
else sstream << " ";
}
sstream << "Mesh attributes:";
if(meshAttributes.method == MESH_TRANSFINITE){
sstream << " transfinite " << meshAttributes.nbPointsTransfinite;
int type = meshAttributes.typeTransfinite;
if(std::abs(type) == 1)
sstream << ", progression " << gmsh_sign(type) * meshAttributes.coeffTransfinite;
else if(std::abs(type) == 2)
sstream << ", bump " << meshAttributes.coeffTransfinite;
}
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reversed";
}
return sstream.str();
}
......
......@@ -75,10 +75,10 @@ class GEdge : public GEntity {
virtual GEdge* getParentEntity() { return 0; }
// set the visibility flag
virtual void setVisibility(char val, bool recursive=false);
virtual void setVisibility(char val, bool recursive = false);
// set color
virtual void setColor(unsigned int val, bool recursive=false);
virtual void setColor(unsigned int val, bool recursive = false);
// true if the edge is a seam for the given face.
virtual bool isSeam(const GFace *face) const { return false; }
......@@ -128,7 +128,7 @@ class GEdge : public GEntity {
virtual int minimumDrawSegments() const { return 1; }
// return a type-specific additional information string
virtual std::string getAdditionalInfoString();
virtual std::string getAdditionalInfoString(bool multline = false);
// export in GEO format
virtual void writeGEO(FILE *fp);
......
......@@ -47,18 +47,24 @@ bool GEntity::useColor()
return true;
}
std::string GEntity::getInfoString(bool additional)
std::string GEntity::getInfoString(bool additional, bool multiline)
{
std::ostringstream sstream;
sstream << getTypeString() << " " << tag();
if(additional){
std::string info = getAdditionalInfoString();
if(info.size()) sstream << " " << info;
std::string info = getAdditionalInfoString(multiline);
if(info.size()){
if(multiline) sstream << "\n";
else sstream << " ";
sstream << info;
}
}
if(physicals.size()){
sstream << ": Physical ";
if(multiline) sstream << "\n";
else sstream << ": ";
sstream << "Physical ";
switch(dim()){
case 0: sstream << "Point"; break;
case 1: sstream << "Curve"; break;
......
......@@ -314,10 +314,10 @@ class GEntity {
virtual bool useColor();
// return an information string for the entity
virtual std::string getInfoString(bool additional=true);
virtual std::string getInfoString(bool additional = true, bool multiline = false);
// return a type-specific additional information string
virtual std::string getAdditionalInfoString() { return std::string(""); }
virtual std::string getAdditionalInfoString(bool multline = false){ return ""; }
// reset the mesh attributes to default values
virtual void resetMeshAttributes() { return; }
......
......@@ -337,30 +337,35 @@ void GFace::setColor(unsigned int val, bool recursive)
}
}
std::string GFace::getAdditionalInfoString()
std::string GFace::getAdditionalInfoString(bool multline)
{
std::ostringstream sstream;
if(l_edges.size() > 20){
sstream << "{" << l_edges.front()->tag() << ",...," << l_edges.back()->tag() << "}";
sstream << "Boundary curves: " << l_edges.front()->tag() << ", ...," << l_edges.back()->tag();
}
else if(l_edges.size()){
sstream << "{";
sstream << "Boundary curves: ";
for(std::list<GEdge*>::iterator it = l_edges.begin(); it != l_edges.end(); ++it){
if(it != l_edges.begin()) sstream << " ";
if(it != l_edges.begin()) sstream << ", ";
sstream << (*it)->tag();
}
sstream << "}";
}
if(meshAttributes.recombine)
sstream << " recombined";
if(meshAttributes.method == MESH_TRANSFINITE)
sstream << " transfinite";
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reverse";
if(meshAttributes.recombine || meshAttributes.method == MESH_TRANSFINITE ||
meshAttributes.extrude || meshAttributes.reverseMesh){
if(l_edges.size()){
if(multline) sstream << "\n";
else sstream << " ";
}
sstream << "Mesh attributes: ";
if(meshAttributes.recombine)
sstream << " recombined";
if(meshAttributes.method == MESH_TRANSFINITE)
sstream << " transfinite";
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reverse";
}
return sstream.str();
}
......
......@@ -203,7 +203,7 @@ class GFace : public GEntity {
double *curvMax, double *curvMin) const;
// return a type-specific additional information string
virtual std::string getAdditionalInfoString();
virtual std::string getAdditionalInfoString(bool multline = false);
// export in GEO format
virtual void writeGEO(FILE *fp);
......@@ -259,8 +259,8 @@ class GFace : public GEntity {
// points are at most maxDist apart
bool fillPointCloud(double maxDist,
std::vector<SPoint3> *points,
std::vector<SPoint2> *uvpoints=0,
std::vector<SVector3> *normals=0);
std::vector<SPoint2> *uvpoints = 0,
std::vector<SVector3> *normals = 0);
// apply Lloyd's algorithm to the mesh
void lloyd(int nIter, int infNorm = 0);
......
......@@ -244,7 +244,7 @@ int GRegion::delFace(GFace* face)
pos++;
}
l_faces.erase(it);
std::list<int>::iterator itOri;
int posOri = 0;
int orientation = 0;
......@@ -256,27 +256,32 @@ int GRegion::delFace(GFace* face)
posOri++;
}
l_dirs.erase(itOri);
return orientation;
}
std::string GRegion::getAdditionalInfoString()
std::string GRegion::getAdditionalInfoString(bool multline)
{
std::ostringstream sstream;
if(l_faces.size()){
sstream << "{";
sstream << "Boundary surfaces: ";
for(std::list<GFace*>::iterator it = l_faces.begin(); it != l_faces.end(); ++it){
if(it != l_faces.begin()) sstream << " ";
if(it != l_faces.begin()) sstream << ", ";
sstream << (*it)->tag();
}
sstream << "}";
}
if(meshAttributes.method == MESH_TRANSFINITE)
sstream << " transfinite";
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.method == MESH_TRANSFINITE || meshAttributes.extrude){
if(l_faces.size()){
if(multline) sstream << "\n";
else sstream << " ";
}
sstream << "Mesh attributes:";
if(meshAttributes.method == MESH_TRANSFINITE)
sstream << " transfinite";
if(meshAttributes.extrude)
sstream << " extruded";
}
return sstream.str();
}
......
......@@ -97,7 +97,7 @@ class GRegion : public GEntity {
std::vector<double> inertia);
// return a type-specific additional information string
virtual std::string getAdditionalInfoString();
virtual std::string getAdditionalInfoString(bool multline = false);
// export in GEO format
virtual void writeGEO(FILE *fp);
......
......@@ -59,13 +59,17 @@ SPoint2 GVertex::reparamOnFace(const GFace *gf, int) const
return gf->parFromPoint(SPoint3(x(), y(), z()));
}
std::string GVertex::getAdditionalInfoString()
std::string GVertex::getAdditionalInfoString(bool multline)
{
std::ostringstream sstream;
sstream.precision(12);
sstream << "{" << x() << "," << y() << "," << z() << "}";
sstream << "Position (" << x() << ", " << y() << ", " << z() << ")";
double lc = prescribedMeshSizeAtVertex();
if(lc < MAX_LC) sstream << " (mesh size: " << lc << ")";
if(lc < MAX_LC){
if(multline) sstream << "\n";
else sstream << " ";
sstream << "Mesh attributes: size " << lc;
}
return sstream.str();
}
......
......@@ -25,7 +25,7 @@ class GVertex : public GEntity
std::list<GEdge*> l_edges;
double meshSize;
public:
GVertex(GModel *m, int tag, double ms=MAX_LC);
GVertex(GModel *m, int tag, double ms = MAX_LC);
virtual ~GVertex();
// delete mesh data
......@@ -75,10 +75,10 @@ class GVertex : public GEntity
virtual SPoint2 reparamOnFace(const GFace *gf, int) const;
// return a type-specific additional information string
virtual std::string getAdditionalInfoString();
virtual std::string getAdditionalInfoString(bool multline = false);
// export in GEO format
virtual void writeGEO(FILE *fp, const std::string &meshSizeParameter="");
virtual void writeGEO(FILE *fp, const std::string &meshSizeParameter = "");
// get number of elements in the mesh
unsigned int getNumMeshElements() const;
......
......@@ -490,11 +490,55 @@ int MElement::getValidity()
#endif
}
std::string MElement::getInfoString()
std::string MElement::getInfoString(bool multline)
{
char tmp[256];
sprintf(tmp, "Element %d", getNum());
return std::string(tmp);
std::ostringstream sstream;
sstream.precision(12);
sstream << "Element " << getNum() << ":";
if(multline) sstream << "\n";
const char *name;
MElement::getInfoMSH(getTypeForMSH(), &name);
sstream << " " << name
<< " (MSH type " << getTypeForMSH()
<< ", dimension "<< getDim()
<< ", order "<< getPolynomialOrder()
<< ", partition " << getPartition()
<< ")";
if(multline) sstream << "\n";
sstream << " Nodes:";
for(int i = 0; i < getNumVertices(); i++)
sstream << " " << getVertex(i)->getNum();
if(multline) sstream << "\n";
SPoint3 pt = barycenter();
sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")";
if(multline) sstream << "\n";
sstream << " Edge length: "
<< "min = " << minEdge() << " "
<< "max = " << maxEdge();
if(multline) sstream << "\n";
sstream << " Quality: "
<< "gamma = " << gammaShapeMeasure();
if(multline) sstream << "\n";
double sICNMin, sICNMax;
signedInvCondNumRange(sICNMin, sICNMax);
sstream << " SICN range: " << sICNMin << " " << sICNMax;
if(multline) sstream << "\n";
double sIGEMin, sIGEMax;
signedInvGradErrorRange(sIGEMin, sIGEMax);
sstream << " SIGE range: " << sIGEMin << " " << sIGEMax;
if(multline) sstream << "\n";
sstream << " Inner / outer radius: "
<< getInnerRadius() << " / " << getOuterRadius();
return sstream.str();
}
const nodalBasis* MElement::getFunctionSpace(int order, bool serendip) const
......@@ -1354,7 +1398,7 @@ void MElement::writeMATLAB(FILE *fp, int filetype, int elementary, int physical,
for(int i = 0; i < getNumVertices(); i++)
fprintf(fp, " %d", getVertex(i)->getIndex());
fprintf(fp, " %d\n", physical ? abs(physical) : elementary);
if(physical < 0) reverse();
}
}
......
......@@ -274,7 +274,7 @@ class MElement
int getValidity();
// return an information string for the element
virtual std::string getInfoString();
virtual std::string getInfoString(bool multline);
// get the function space for the element
virtual const nodalBasis* getFunctionSpace(int order=-1, bool serendip=false) const;
......
......@@ -89,33 +89,37 @@ GEntity::GeomType gmshEdge::geomType() const
}
}
std::string gmshEdge::getAdditionalInfoString()
std::string gmshEdge::getAdditionalInfoString(bool multline)
{
if(List_Nbr(c->Control_Points) > 0){
std::ostringstream sstream;
sstream << "{";
sstream << "Control points: ";
for(int i = 0; i < List_Nbr(c->Control_Points); i++){
if(i) sstream << " ";
if(i) sstream << ", ";
Vertex *v;
List_Read(c->Control_Points, i, &v);
sstream << v->Num;
}
sstream << "}";
if(meshAttributes.method == MESH_TRANSFINITE){
sstream << " transfinite (" << meshAttributes.nbPointsTransfinite;
int type = meshAttributes.typeTransfinite;
if(std::abs(type) == 1)
sstream << ", progression " << gmsh_sign(type) * meshAttributes.coeffTransfinite;
else if(std::abs(type) == 2)
sstream << ", bump " << meshAttributes.coeffTransfinite;
sstream << ")";
if(meshAttributes.method == MESH_TRANSFINITE ||
meshAttributes.extrude || meshAttributes.reverseMesh){
if(multline) sstream << "\n";
else sstream << " ";
sstream << "Mesh attributes:";
if(meshAttributes.method == MESH_TRANSFINITE){
sstream << " transfinite (" << meshAttributes.nbPointsTransfinite;
int type = meshAttributes.typeTransfinite;
if(std::abs(type) == 1)
sstream << ", progression " << gmsh_sign(type) * meshAttributes.coeffTransfinite;
else if(std::abs(type) == 2)
sstream << ", bump " << meshAttributes.coeffTransfinite;
sstream << ")";
}
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reversed";
}
if(meshAttributes.extrude)
sstream << " extruded";
if(meshAttributes.reverseMesh)
sstream << " reversed";
return sstream.str();
}
else
......
......@@ -24,7 +24,7 @@ class gmshEdge : public GEdge {
virtual SVector3 secondDer(double par) const;
ModelType getNativeType() const { return GmshModel; }
void *getNativePtr() const { return c; }
virtual std::string getAdditionalInfoString();
virtual std::string getAdditionalInfoString(bool multline = false);
virtual int minimumMeshSegments() const;
virtual int minimumDrawSegments() const;
virtual void resetMeshAttributes();
......
......@@ -235,12 +235,16 @@ class drawContext {
void drawScales();
void drawString(const std::string &s, double x, double y, double z,
const std::string &font_name, int font_enum,
int font_size, int align);
void drawString(const std::string &s, double x, double y, double z);
void drawStringCenter(const std::string &s, double x, double y, double z);
void drawStringRight(const std::string &s, double x, double y, double z);
void drawString(const std::string &s, double x, double y, double z, double style);
void drawImage(const std::string &s, double x, double y, double z, int align=0);
int font_size, int align, int line_num = 0);
void drawString(const std::string &s, double x, double y, double z,
int line_num = 0);
void drawStringCenter(const std::string &s, double x, double y, double z,
int line_num = 0);
void drawStringRight(const std::string &s, double x, double y, double z,
int line_num = 0);
void drawString(const std::string &s, double x, double y, double z, double style,
int line_num = 0);
void drawImage(const std::string &s, double x, double y, double z, int align = 0);
void drawSphere(double R, double x, double y, double z, int n1, int n2, int light);
void drawEllipsoid(double x, double y, double z, float v0[3], float v1[3],
float v2[3], int light);
......
......@@ -11,15 +11,24 @@
#include "GModel.h"
#include "SBoundingBox3d.h"
#include "GmshMessage.h"
#include "StringUtils.h"
static void drawEntityLabel(drawContext *ctx, GEntity *e,
double x, double y, double z, double offset)
{
char str[1024];
double xx = x + offset / ctx->s[0];
double yy = y + offset / ctx->s[1];
double zz = z + offset / ctx->s[2];
if(CTX::instance()->geom.labelType == 0){
strcpy(str, e->getInfoString(false).c_str());
std::vector<std::string> info = SplitString(e->getInfoString(false, true), '\n');
for(int line = 0; line < (int)info.size(); line++)
ctx->drawString(info[line].c_str(), xx, yy, zz, line);
return;
}
else if(CTX::instance()->geom.labelType == 1){
char str[1024];
if(CTX::instance()->geom.labelType == 1){
sprintf(str, "%d", e->tag());
}
else{
......@@ -31,10 +40,7 @@ static void drawEntityLabel(drawContext *ctx, GEntity *e,
strcat(str, tmp);
}
}
ctx->drawString(str,
x + offset / ctx->s[0],
y + offset / ctx->s[1],
z + offset / ctx->s[2]);
ctx->drawString(str, xx, yy, zz);
}
class drawGVertex {
......
......@@ -15,7 +15,7 @@
void drawContext::drawString(const std::string &s, double x, double y, double z,
const std::string &font_name, int font_enum,
int font_size, int align)
int font_size, int align, int line_num)
{
if(s.empty()) return;
if(CTX::instance()->printing && !CTX::instance()->print.text) return;
......@@ -30,9 +30,7 @@ void drawContext::drawString(const std::string &s, double x, double y, double z,
glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &valid);
if(valid == GL_FALSE) return; // the primitive is culled
// change the raster position only if not creating TeX files
if(align > 0 && (!CTX::instance()->printing ||
CTX::instance()->print.fileFormat != FORMAT_TEX)){
if(align > 0 || line_num){
GLdouble pos[4];
glGetDoublev(GL_CURRENT_RASTER_POSITION, pos);
double x[3], w[3] = {pos[0], pos[1], pos[2]};
......@@ -45,17 +43,23 @@ void drawContext::drawString(const std::string &s, double x, double y, double z,
width *= 2;
height *= 2;
}
switch(align){
case 1: w[0] -= width/2.; break; // bottom center
case 2: w[0] -= width; break; // bottom right