Commit f1d3f96c authored by Christophe Geuzaine's avatar Christophe Geuzaine

Merge branch 'master' of http://gitlab.onelab.info/gmsh/gmsh

parents e4bbcd36 30cc1751
Pipeline #3032 passed with stage
in 58 minutes and 59 seconds
4.0.5 (November 17, 2018): automatic hybrid mesh generation (pyramid layer) when
3D Delaunay algorithm is applied to a volume with quadrangles on boundary;
4.0.6 (November 25, 2018): moved private API wrappers to utils/wrappers;
improved Gmsh 3 compatibility for high-order periodic meshes; fixed '-v 0' not
being completely silent; fixed rendering of image textures on some OSes; small
compilation fixes.
4.0.5 (November 17, 2018): new automatic hybrid mesh generation (pyramid layer)
when 3D Delaunay algorithm is applied to a volume with quadrangles on boundary;
improved robustness of 2D MeshAdapt algorithm; bug fixes.
4.0.4 (October 19, 2018): fix physical names regression in 4.0.3.
4.0.4 (October 19, 2018): fixed physical names regression in 4.0.3.
4.0.3 (October 18, 2018): bug fixes.
......@@ -33,7 +38,7 @@ export; small improvements and bug fixes.
3.0.5 (September 6, 2017): bug fixes.
3.0.4 (July 28, 2017): moved vorometal code to plugin; openmp improvements; bug
3.0.4 (July 28, 2017): moved vorometal code to plugin; OpenMP improvements; bug
fixes.
3.0.3 (June 27, 2017): new element quality measures; Block->Box; minor fixes.
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
# See the LICENSE.txt file for license information. Please report all
# issues on https://gitlab.onelab.info/gmsh/gmsh/issues
set(SRC
set(SRC
GmshGlobal.cpp
GmshMessage.cpp
gmshPopplerWrapper.cpp
......@@ -15,7 +15,7 @@ set(SRC
CreateFile.cpp
VertexArray.cpp
SmoothData.cpp
Octree.cpp
Octree.cpp
OctreeInternals.cpp
StringUtils.cpp
ListUtils.cpp
......@@ -24,14 +24,9 @@ set(SRC
onelabUtils.cpp
GamePad.cpp
GmshRemote.cpp
gmshLocalNetworkClient.cpp
gmsh.cpp
)
if(ENABLE_ONELAB AND NOT ENABLE_ONELAB2)
set(SRC
${SRC}
gmshLocalNetworkClient.cpp)
endif(ENABLE_ONELAB AND NOT ENABLE_ONELAB2)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h)
append_gmsh_src(Common "${SRC};${HDR}")
......@@ -30,7 +30,7 @@ struct contextMeshOptions {
int recombine3DConformity, flexibleTransfinite;
int order, secondOrderLinear, secondOrderIncomplete, secondOrderExperimental;
int meshOnlyVisible, minCircPoints, minCurvPoints;
int hoOptimize, hoNLayers, hoOptPrimSurfMesh;
int hoOptimize, hoPeriodic, hoNLayers, hoOptPrimSurfMesh;
double hoThresholdMin, hoThresholdMax, hoPoissonRatio;
std::map<int, int> algo2dPerFace;
std::map<int, int> curvatureControlPerFace;
......
......@@ -146,8 +146,8 @@ StringXString GeometryOptions_String[] = {
{ F|O, "OCCTargetUnit" , opt_geometry_occ_target_unit , "M" ,
"Length unit to which coordinates from STEP and IGES files are converted to when "
"imported by OpenCASCADE (leave empty to keep the unit defined in the STEP and "
"IGES file)"},
"imported by OpenCASCADE, e.g. 'M' for meters (leave empty to keep the unit defined "
"in the STEP and IGES file)"},
{ 0, 0 , 0 , "" , 0 }
} ;
......@@ -1054,6 +1054,8 @@ StringXNumber MeshOptions_Number[] = {
"Number of high order mesh elements to consider for optimization"},
{ F|O, "HighOrderOptimize" , opt_mesh_ho_optimize , 0.,
"Optimize high order meshes?" },
{ F|O, "HighOrderPeriodic" , opt_mesh_ho_periodic , 0.,
"Correct high order optimization for periodic connections?" },
{ F|0, "HighOrderPoissonRatio", opt_mesh_ho_poisson, 0.33,
"Poisson ratio of the material used in the elastic smoother for high order meshes"
"Must be between -1.0 and 0.5, excluded"},
......
......@@ -21,6 +21,7 @@
#cmakedefine HAVE_GMM
#cmakedefine HAVE_GMP
#cmakedefine HAVE_HXT
#cmakedefine HAVE_HXT3D
#cmakedefine HAVE_KBIPACK
#cmakedefine HAVE_LAPACK
#cmakedefine HAVE_LIBCGNS
......
......@@ -296,7 +296,8 @@ static int defineSolver(const std::string &name)
#endif
int MergeFile(const std::string &fileName, bool warnIfMissing,
bool setBoundingBox, bool importPhysicalsInOnelab)
bool setBoundingBox, bool importPhysicalsInOnelab,
int partitionToRead)
{
// added 'b' for pure Windows programs, since some of these files
// contain binary data
......@@ -520,7 +521,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing,
}
mesh = true;
#if defined(HAVE_POST)
if(status > 1) status = PView::readMSH(fileName);
if(status > 1) status = PView::readMSH(fileName, -1, partitionToRead);
#endif
}
#if defined(HAVE_POST)
......
......@@ -14,7 +14,8 @@ void ParseString(const std::string &str, bool inCurrentModelDir = false);
void OpenProject(const std::string &filename);
void OpenProjectMacFinder(const char *fileName);
int MergeFile(const std::string &fileName, bool warnIfMissing = false,
bool setBoundingBox = true, bool importPhysicalsInOnelab = true);
bool setBoundingBox = true, bool importPhysicalsInOnelab = true,
int partitionToRead = -1);
int MergePostProcessingFile(const std::string &fileName, int showViews = 2,
bool showLastStep = false,
bool warnIfMissing = false);
......
......@@ -6178,6 +6178,13 @@ double opt_mesh_ho_optimize(OPT_ARGS_NUM)
return CTX::instance()->mesh.hoOptimize;
}
double opt_mesh_ho_periodic(OPT_ARGS_NUM)
{
if(action & GMSH_SET)
CTX::instance()->mesh.hoPeriodic = (int)val;
return CTX::instance()->mesh.hoPeriodic;
}
double opt_mesh_ho_nlayers(OPT_ARGS_NUM)
{
if(action & GMSH_SET)
......
......@@ -516,6 +516,7 @@ double opt_mesh_allow_swap_edge_angle(OPT_ARGS_NUM);
double opt_mesh_min_curv_points(OPT_ARGS_NUM);
double opt_mesh_order(OPT_ARGS_NUM);
double opt_mesh_ho_optimize(OPT_ARGS_NUM);
double opt_mesh_ho_periodic(OPT_ARGS_NUM);
double opt_mesh_ho_nlayers(OPT_ARGS_NUM);
double opt_mesh_ho_threshold_min(OPT_ARGS_NUM);
double opt_mesh_ho_threshold_max(OPT_ARGS_NUM);
......
......@@ -109,7 +109,7 @@ void smooth_data::add_scale(double x, double y, double z, double scale_val)
}
}
bool smooth_data::get(double x, double y, double z, int n, double *vals)
bool smooth_data::get(double x, double y, double z, int n, double *vals) const
{
std::set<xyzv, lessthanxyzv>::const_iterator it = c.find(xyzv(x, y, z));
if(it == c.end()) return false;
......@@ -118,7 +118,7 @@ bool smooth_data::get(double x, double y, double z, int n, double *vals)
}
// added by Trevor Strickler
bool smooth_data::get_scale(double x, double y, double z, double *scale_val)
bool smooth_data::get_scale(double x, double y, double z, double *scale_val) const
{
std::set<xyzv, lessthanxyzv>::const_iterator it = c.find(xyzv(x, y, z));
if(it == c.end()) return false;
......@@ -135,12 +135,12 @@ void smooth_data::normalize()
}
}
bool smooth_data::exportview(const std::string &filename)
bool smooth_data::exportview(const std::string &filename) const
{
FILE *fp = Fopen(filename.c_str(), "w");
if(!fp) return false;
fprintf(fp, "View \"data\" {\n");
std::set<xyzv, lessthanxyzv>::iterator it = c.begin();
std::set<xyzv, lessthanxyzv>::const_iterator it = c.begin();
while(it != c.end()) {
switch(it->nbvals) {
case 1:
......@@ -232,7 +232,7 @@ void smooth_normals::add(double x, double y, double z, double nx, double ny,
}
bool smooth_normals::get(double x, double y, double z, double &nx, double &ny,
double &nz)
double &nz) const
{
std::set<xyzn, lessthanxyzn>::const_iterator it =
c.find(xyzn((float)x, (float)y, (float)z));
......
......@@ -60,13 +60,11 @@ public:
iter end() { return c.end(); }
smooth_data() {}
void add(double x, double y, double z, int n, double *vals);
bool get(double x, double y, double z, int n, double *vals);
void add_scale(double x, double y, double z,
double scale_val); // Trevor Strickler
bool get_scale(double x, double y, double z,
double *scale_val); // Trevor Strickler
bool get(double x, double y, double z, int n, double *vals) const;
void add_scale(double x, double y, double z, double scale_val);
bool get_scale(double x, double y, double z, double *scale_val) const;
void normalize();
bool exportview(const std::string &filename);
bool exportview(const std::string &filename) const;
};
// Normal smoother with threshold (saves memory by storing normals as
......@@ -107,7 +105,7 @@ private:
public:
smooth_normals(double angle) : tol((float)angle) {}
void add(double x, double y, double z, double nx, double ny, double nz);
bool get(double x, double y, double z, double &nx, double &ny, double &nz);
bool get(double x, double y, double z, double &nx, double &ny, double &nz) const;
};
#endif
......@@ -9,6 +9,7 @@
#include "VertexArray.h"
#include "Context.h"
#include "Numeric.h"
#include "OS.h"
template<int N> float ElementDataLessThan<N>::tolerance = 0.0F;
float BarycenterLessThan::tolerance = 0.0F;
......@@ -17,11 +18,27 @@ VertexArray::VertexArray(int numVerticesPerElement, int numElements)
: _numVerticesPerElement(numVerticesPerElement)
{
int nb = (numElements ? numElements : 1) * _numVerticesPerElement;
double memv = (nb * 3. * sizeof(float)) / 1024. / 1024.;
double memmax = TotalRam() / 3.;
if(memv > memmax){
int old = nb;
nb = memmax / (3. * sizeof(float)) * 1024 * 1024;
Msg::Debug("Reduce preallocation of vertex array (%d -> %d)", old, nb);
}
_vertices.reserve(nb * 3);
_normals.reserve(nb * 3);
_colors.reserve(nb * 4);
}
double VertexArray::getMemoryInMb()
{
int bytes = _vertices.size() * sizeof(float) +
_normals.size() * sizeof(normal_type) +
_colors.size() * sizeof(unsigned char);
return (double)bytes / 1024. / 1024.;
}
void VertexArray::_addVertex(float x, float y, float z)
{
_vertices.push_back(x);
......@@ -214,14 +231,6 @@ void VertexArray::sort(double x, double y, double z)
_colors = sortedColors;
}
double VertexArray::getMemoryInMb()
{
int bytes = _vertices.size() * sizeof(float) +
_normals.size() * sizeof(normal_type) +
_colors.size() * sizeof(unsigned char);
return (double)bytes / 1024. / 1024.;
}
char *VertexArray::toChar(int num, const std::string &name, int type,
double min, double max, int numsteps, double time,
const SBoundingBox3d &bbox, int &len)
......
......@@ -81,6 +81,7 @@ GLuint gmshPopplerWrapper::getTextureForPage(double xres, double yres)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->w(), img->h(), 0,
(img->d() == 4) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
img->array);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
_w = img->w();
_h = img->h();
......
......@@ -147,9 +147,9 @@ public:
void drawString(const char *str) { gl_draw(str); }
void resetFontTextures()
{
#if defined(__APPLE__)
gl_texture_pile_height(
gl_texture_pile_height()); // force font texture recomputation
#if ((FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION >= 4)) || defined(__APPLE__)
// force font texture recomputation
gl_texture_pile_height(gl_texture_pile_height());
#endif
}
std::string getName() { return "Fltk"; }
......
......@@ -190,6 +190,9 @@ template <class T>
static void addElementsInArrays(GEntity *e, std::vector<T *> &elements,
bool edges, bool faces)
{
#if defined(_OPENMP)
#pragma omp parallel for schedule(dynamic)
#endif
for(unsigned int i = 0; i < elements.size(); i++) {
MElement *ele = elements[i];
......@@ -222,7 +225,12 @@ static void addElementsInArrays(GEntity *e, std::vector<T *> &elements,
for(int k = 0; k < 2; k++)
e->model()->normals->get(x[k], y[k], z[k], n[k][0], n[k][1],
n[k][2]);
e->va_lines->add(x, y, z, n, col, ele, unique);
#if defined(_OPENMP)
#pragma omp critical
#endif
{
e->va_lines->add(x, y, z, n, col, ele, unique);
}
}
}
......@@ -244,7 +252,12 @@ static void addElementsInArrays(GEntity *e, std::vector<T *> &elements,
for(int k = 0; k < 3; k++)
e->model()->normals->get(x[k], y[k], z[k], n[k][0], n[k][1],
n[k][2]);
e->va_triangles->add(x, y, z, n, col, ele, unique, skin);
#if defined(_OPENMP)
#pragma omp critical
#endif
{
e->va_triangles->add(x, y, z, n, col, ele, unique, skin);
}
}
}
}
......@@ -329,8 +342,8 @@ public:
if(edg || fac) {
_curved = (areSomeElementsCurved(f->triangles) ||
areSomeElementsCurved(f->quadrangles));
f->va_lines = new VertexArray(2, _estimateNumLines(f));
f->va_triangles = new VertexArray(3, _estimateNumTriangles(f));
f->va_lines = new VertexArray(2, edg ? _estimateNumLines(f) : 100);
f->va_triangles = new VertexArray(3, fac ? _estimateNumTriangles(f) : 100);
if(CTX::instance()->mesh.triangles)
addElementsInArrays(f, f->triangles, edg, fac);
if(CTX::instance()->mesh.quadrangles)
......@@ -347,11 +360,18 @@ private:
bool _curved;
int _estimateIfClipped(int num)
{
if(CTX::instance()->clipWholeElements &&
CTX::instance()->clipOnlyDrawIntersectingVolume) {
if(CTX::instance()->clipWholeElements) {
for(int clip = 0; clip < 6; clip++) {
if(CTX::instance()->mesh.clip & (1 << clip))
return (int)sqrt((double)num);
if(CTX::instance()->mesh.clip & (1 << clip)){
if(CTX::instance()->clipOnlyDrawIntersectingVolume){
// let be more aggressive than num^{2/3}
return (int)sqrt((double)num);
}
else{
// why not :-)
return num / 4;
}
}
}
}
return num;
......@@ -413,8 +433,8 @@ public:
areSomeElementsCurved(r->prisms) ||
areSomeElementsCurved(r->pyramids) ||
areSomeElementsCurved(r->trihedra));
r->va_lines = new VertexArray(2, _estimateNumLines(r));
r->va_triangles = new VertexArray(3, _estimateNumTriangles(r));
r->va_lines = new VertexArray(2, edg ? _estimateNumLines(r) : 100);
r->va_triangles = new VertexArray(3, fac ? _estimateNumTriangles(r) : 100);
if(CTX::instance()->mesh.tetrahedra)
addElementsInArrays(r, r->tetrahedra, edg, fac);
if(CTX::instance()->mesh.hexahedra)
......
......@@ -445,6 +445,7 @@ bool drawContext::generateTextureForImage(const std::string &name, int page,
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img2->w(), img2->h(), 0,
(img2->d() == 4) ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE,
img2->array);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
imageW = img->w();
imageH = img->h();
delete img;
......
......@@ -111,6 +111,12 @@ public:
virtual std::string getName() { return "None"; }
};
class imgtex {
public:
GLuint tex, w, h;
imgtex() : tex(0), w(0), h(0) {}
};
class drawContext {
private:
static drawContextGlobal *_global;
......@@ -121,9 +127,6 @@ private:
std::set<PView *> _hiddenViews;
GLuint _bgImageTexture, _bgImageW, _bgImageH;
openglWindow *_openglWindow;
struct imgtex {
GLuint tex, w, h;
};
std::map<std::string, imgtex> _imageTextures;
public:
......
......@@ -323,7 +323,8 @@ public:
CTX::instance()->geom.surfaceType > 0)
f->fillVertexArray(f->geomType() == GEntity::ProjectionFace);
if(CTX::instance()->geom.surfaces || f->getSelection() > 1 ||
if(((CTX::instance()->geom.surfaces || f->getSelection() > 1) &&
CTX::instance()->geom.surfaceType == 0) ||
CTX::instance()->geom.surfacesNum || CTX::instance()->geom.normals)
f->buildRepresentationCross();
......
......@@ -23,14 +23,14 @@
#include "fullMatrix.h"
#include "BasisFactory.h"
#include "InnerVertexPlacement.h"
#include "Context.h"
#if defined(HAVE_OPTHOM)
#include "OptHomFastCurving.h"
#include "OptHomPeriodicity.h"
#endif
// --------- Functions that help optimizing placement of points on geometry
// -----------
// Functions that help optimizing placement of points on geometry
// The aim here is to build a polynomial representation that consist
// in polynomial segments of equal length
......@@ -247,7 +247,7 @@ void createMatLob2LagP6()
Vandermonde.mult(coefficient, (*lob2lagP6));
}
// --------- Creation of high-order edge vertices -----------
// Creation of high-order edge vertices
static bool getEdgeVerticesOnGeo(GEdge *ge, MVertex *v0, MVertex *v1,
std::vector<MVertex *> &ve, int nPts = 1)
......@@ -433,7 +433,8 @@ static void getEdgeVertices(GEdge *ge, MElement *ele,
}
else if(p.first != p.second) { // Vertices already exist and edge is not a
// degenerated edge
Msg::Error("Edges from different entities share vertices: create a finer mesh");
Msg::Error(
"Edges from different entities share vertices: create a finer mesh");
}
ve.insert(ve.end(), veEdge.begin(), veEdge.end());
}
......@@ -525,7 +526,7 @@ static void getEdgeVertices(GRegion *gr, MElement *ele,
}
}
// --------- Creation of high-order face vertices -----------
// Creation of high-order face vertices
static void reorientTrianglePoints(std::vector<MVertex *> &vtcs,
int orientation, bool swap)
......@@ -924,7 +925,7 @@ static void getVolumeVertices(GRegion *gr, MElement *ele,
}
}
// --------- Creation of high-order elements -----------
// Creation of high-order elements
static void setHighOrder(GEdge *ge, std::vector<MVertex *> &newHOVert,
edgeContainer &edgeVertices, bool linear,
......@@ -1201,7 +1202,7 @@ static void setHighOrder(GRegion *gr, std::vector<MVertex *> &newHOVert,
gr->deleteVertexArrays();
}
// --------- High-level functions -----------
// High-level functions
template <class T>
static void setFirstOrder(GEntity *e, std::vector<T *> &elements,
......@@ -1254,14 +1255,14 @@ static void updatePeriodicEdgesAndFaces(GModel *m)
Msg::Info(
"Constructing high order periodicity for edge connection %d - %d",
tgt->tag(), src->tag());
tgt->tag(), src->tag());
std::map<MEdge, MLine *, Less_Edge> srcEdges;
for(unsigned int i = 0; i < src->getNumMeshElements(); i++) {
MLine *srcLine = dynamic_cast<MLine *>(src->getMeshElement(i));
if(!srcLine) {
Msg::Error("Master element %d is not an edge",
src->getMeshElement(i)->getNum());
src->getMeshElement(i)->getNum());
return;
}
srcEdges[MEdge(srcLine->getVertex(0), srcLine->getVertex(1))] = srcLine;
......@@ -1308,13 +1309,16 @@ static void updatePeriodicEdgesAndFaces(GModel *m)
}
}
if(CTX::instance()->mesh.hoPeriodic) {
#if defined(HAVE_OPTHOM)
std::vector<GEntity *> modelEdges(m->firstEdge(), m->lastEdge());
OptHomPeriodicity edgePeriodicity(modelEdges);
edgePeriodicity.fixPeriodicity();
edgePeriodicity.fixPeriodicity(); // apply twice for operation order effects
std::vector<GEntity *> modelEdges(m->firstEdge(), m->lastEdge());
OptHomPeriodicity edgePeriodicity(modelEdges);
edgePeriodicity.fixPeriodicity();
edgePeriodicity.fixPeriodicity(); // apply twice for operation order effects
#else
Msg::Error("High-order mesh optimization requires the OPTHOM module");
#endif
}
for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it) {
GFace *tgt = *it;
......@@ -1384,12 +1388,16 @@ static void updatePeriodicEdgesAndFaces(GModel *m)
}
}
if(CTX::instance()->mesh.hoPeriodic) {
#if defined(HAVE_OPTHOM)
std::vector<GEntity *> modelFaces;
modelFaces.insert(modelFaces.end(), m->firstFace(), m->lastFace());
OptHomPeriodicity facePeriodicity(modelFaces);
facePeriodicity.fixPeriodicity();
std::vector<GEntity *> modelFaces;
modelFaces.insert(modelFaces.end(), m->firstFace(), m->lastFace());
OptHomPeriodicity facePeriodicity(modelFaces);
facePeriodicity.fixPeriodicity();
#else
Msg::Error("High-order mesh optimization requires the OPTHOM module");
#endif
}
Msg::Debug("Finalized high order topology of periodic connections");
}
......@@ -1613,27 +1621,30 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete,
for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
updateHighOrderVertices(*it, newHOVert[*it], onlyVisible);
if(CTX::instance()->mesh.hoOptimize) {
#if defined(HAVE_OPTHOM)
// Determine mesh dimension and curve BL elements
FastCurvingParameters p;
p.dim = 0;
p.curveOuterBL = FastCurvingParameters::OUTER_CURVE;
p.thickness = false;
// p.optimizeGeometry = true;
for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
if((*it)->getNumMeshElements() > 0) {
p.dim = 3;
break;
}
if(p.dim == 0)
for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
// Determine mesh dimension and curve BL elements
FastCurvingParameters p;
p.dim = 0;
p.curveOuterBL = FastCurvingParameters::OUTER_CURVE;
p.thickness = false;
// p.optimizeGeometry = true;
for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); ++it)
if((*it)->getNumMeshElements() > 0) {
p.dim = 2;
p.dim = 3;
break;
}
// if (p.dim == 2)
// HighOrderMeshFastCurving(GModel::current(), p, true);
if(p.dim == 0)
for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
if((*it)->getNumMeshElements() > 0) {
p.dim = 2;
break;
}
if(p.dim == 2) HighOrderMeshFastCurving(GModel::current(), p, true);
#else
// Msg::Error("High-order mesh optimization requires the OPTHOM module");
#endif
}
updatePeriodicEdgesAndFaces(m);
......
......@@ -677,12 +677,12 @@ void meshGEdge::operator()(GEdge *ge)
if((ge->meshAttributes.method != MESH_TRANSFINITE ||
CTX::instance()->mesh.flexibleTransfinite) &&
CTX::instance()->mesh.algoRecombine != 0) {
if(CTX::instance()->mesh.recombineAll) {
std::vector<GFace *> const &faces = ge->faces();
if(CTX::instance()->mesh.recombineAll && faces.size()) {
if(N % 2 == 0) N++;
if(CTX::instance()->mesh.algoRecombine == 2) N = increaseN(N);
}
else {
std::vector<GFace *> const &faces = ge->faces();
for(std::vector<GFace *>::const_iterator it = faces.begin();
it != faces.end(); it++) {
if((*it)->meshAttributes.recombine) {
......
This diff is collapsed.
......@@ -121,7 +121,7 @@ void GMSH_DistancePlugin::printView(std::vector<GEntity *> _entities,
if(_entities[ii]->dim() == _maxDim) {
for(unsigned int i = 0; i < _entities[ii]->getNumMeshElements(); i++) {
MElement *e = _entities[ii]->getMeshElement(i);
int numNodes = e->getNumVertices();
int numNodes = e->getNumPrimaryVertices();
if(e->getNumChildren())
numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
std::vector<double> x(numNodes), y(numNodes), z(numNodes);
......@@ -525,7 +525,7 @@ PView *GMSH_DistancePlugin::execute(PView *v)
it != allElems.end(); it++) {
MElement *e = *it;
int numNodes = e->getNumVertices();
int numNodes = e->getNumPrimaryVertices();
if(e->getType() == TYPE_POLYG)
numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices();
std::vector<double> x(numNodes), y(numNodes), z(numNodes);
......
......@@ -128,7 +128,8 @@ public:
// IO read routines (these are global: they can create multiple
// views)
static bool readPOS(const std::string &fileName, int fileIndex = -1);
static bool readMSH(const std::string &fileName, int fileIndex = -1);
static bool readMSH(const std::string &fileName, int fileIndex = -1,
int partitionToRead = -1);
static bool readMED(const std::string &fileName, int fileIndex = -1);
static bool writeX3D(const std::string &fileName);
// IO write routine
......
......@@ -81,7 +81,7 @@ bool PView::readPOS(const std::string &fileName, int fileIndex)
return true;
}
bool PView::readMSH(const std::string &fileName, int fileIndex)
bool PView::readMSH(const std::string &fileName, int fileIndex, int partitionToRead)
{
FILE *fp = Fopen(fileName.c_str(), "rb");
if(!fp) {
......@@ -230,6 +230,7 @@ bool PView::readMSH(const std::string &fileName, int fileIndex)
}
// integer tags
int timeStep = 0, numComp = 0, numEnt = 0, partition = 0;
long int blocksize = 0;
if(!fgets(str, sizeof(str), fp)) {
fclose(fp);
return false;
......@@ -267,29 +268,44 @@ bool PView::readMSH(const std::string &fileName, int fileIndex)
return false;
}
}
}
if(numEnt > 0) {
// either get existing viewData, or create new one
PView *p = getViewByName(viewName, timeStep, partition);
PViewDataGModel *d = 0;
if(p) d = dynamic_cast<PViewDataGModel *>(p->getData());
bool create = d ? false : true;
if(create) d = new PViewDataGModel(type);
if(!d->readMSH(viewName, fileName, fileIndex, fp, binary, swap,
timeStep, time, partition, numComp, numEnt,
interpolationScheme)) {
Msg::Error("Could not read data in msh file");
if(create) delete d;
fclose(fp);
return false;
else if(i == 4) {
if(sscanf(str, "%ld", &blocksize) != 1) {
fclose(fp);
return false;
}
}
else {
d->setName(viewName);
d->setFileName(fileName);
d->setFileIndex(index);
if(create) new PView(d);
}
if(partitionToRead == -1 || partitionToRead == partition) {
// if default (no particular partition requested from MergeFile -> -1) or
// if current partition corresponds to the requested partition, read the data
if(numEnt > 0) {
// either get existing viewData, or create new one
PView *p = getViewByName(viewName, timeStep, partition);
PViewDataGModel *d = 0;
if(p) d = dynamic_cast<PViewDataGModel *>(p->getData());
bool create = d ? false : true;
if(create) d = new PViewDataGModel(type);
if(!d->readMSH(viewName, fileName, fileIndex, fp, binary, swap,
timeStep, time, partition, numComp, numEnt,
interpolationScheme)) {
Msg::Error("Could not read data in msh file");
if(create) delete d;
fclose(fp);
return false;
}
else {
d