Newer
Older
#if defined(HAVE_FOURIER_MODEL)
#include "model.h"
void debugVertices(std::vector<MVertex*> &vertices, std::string file,
bool parametric, int num=0)
{
char name[256];
sprintf(name, "%s_%d.pos", file.c_str(), num);
FILE *fp = fopen(name, "w");
fprintf(fp, "View \"debug\"{\n");
for(unsigned int i = 0; i < vertices.size(); i++){
double x, y, z;
if(parametric){
vertices[i]->getParameter(0, x);
vertices[i]->getParameter(1, y);
z = 0;
}
else{
x = vertices[i]->x();
y = vertices[i]->y();
z = vertices[i]->z();
}
fprintf(fp, "SP(%g,%g,%g){%d};\n", x, y, z, i);
}
fprintf(fp, "};\n");
fclose(fp);
}
template<class T>
void debugElements(std::vector<T*> &elements, std::string file,
bool parametric, int num=0)
{
char name[256];
sprintf(name, "%s_%d.pos", file.c_str(), num);
FILE *fp = fopen(name, "w");
fprintf(fp, "View \"debug\"{\n");
for(unsigned int i = 0; i < elements.size(); i++){
fprintf(fp, "%s(", elements[i]->getStringForPOS());
for(int j = 0; j < elements[i]->getNumVertices(); j++){
MVertex *v = elements[i]->getVertex(j);
if(j) fprintf(fp, ",");
double x, y, z;
if(parametric){
v->getParameter(0, x);
v->getParameter(1, y);
z = 0;
}
else{
x = v->x(); y = v->y(); z = v->z();
}
fprintf(fp, "%g,%g,%g", x, y, z);
}
fprintf(fp, "){");
for(int j = 0; j < elements[i]->getNumVertices(); j++){
MVertex *v = elements[i]->getVertex(j);
if(j) fprintf(fp, ",");
if(v->getData()){
double pou = *(double*)v->getData();
fprintf(fp, "%g", pou);
}
else{
fprintf(fp, "%d", v->onWhat()->tag());
}
}
fprintf(fp, "};\n");
}
fprintf(fp, "};\n");
int M = (int)(30. / CTX.mesh.lc_factor), N = (int)(30. / CTX.mesh.lc_factor);
for(int i = 0; i < M; i++){
for(int j = 0; j < N; j++){
double u = i/(double)(M - 1);
double v = j/(double)(N - 1);
//if(gf->tag() == 2){
// hack for sttr report 2 (ship model, top right patch)
// XYZ_values_ship_Top(u,v=0) =
// XYZ_values_ship_Med(u*matching_const1_+matching_const2_,v=1)
// where 0=<u=<1,
// matching_const1_=0.523540136032613,
// matching_const2_=0.475747890863610.
//u = u * 0.5268 + 0.475;
//}
gf->mesh_vertices.push_back
(new MDataFaceVertex<double>(p.x(), p.y(), p.z(), gf, u, v, pou));
}
}
for(int i = 0; i < M - 1; i++){
for(int j = 0; j < N - 1; j++){
MQuadrangle *q = new MQuadrangle(gf->mesh_vertices[i * N + j],
gf->mesh_vertices[(i + 1) * N + j],
gf->mesh_vertices[(i + 1) * N + (j + 1)],
gf->mesh_vertices[i * N + (j + 1)]);
class meshGmsh{
public:
void operator() (GFace *gf)
{
fourierFace *ff = dynamic_cast<fourierFace*>(gf);
if(!ff) {
Msg(GERROR, "face %d is not Fourier", gf->tag());
return;
}
ff->meshBoundary();
meshGFace mesh;
mesh(ff);
}
};
class computePartitionOfUnity{
public:
void operator() (GFace *gf)
{
// we only normalize the partition of unity amongst patches that
// overlap; we don't normalize across hard edges
std::vector<int> overlaps;
FM->GetNeighbor(gf->tag(), overlaps);
for(unsigned int i = 0; i < gf->mesh_vertices.size(); i++){
MVertex *v = gf->mesh_vertices[i];
std::vector<std::pair<GFace*, SPoint2> > param;
for(unsigned int j = 0; j < overlaps.size(); j++){
GFace *gf2 = gf->model()->faceByTag(overlaps[j]);
SPoint2 uv2 = gf2->parFromPoint(SPoint3(v->x(), v->y(), v->z()));
if(gf2->containsParam(uv2)){
GPoint xyz2 = gf2->point(uv2);
const double tol = 1.e-2; // Warning: tolerance
if(fabs(xyz2.x() - v->x()) < tol &&
fabs(xyz2.y() - v->y()) < tol &&
fabs(xyz2.z() - v->z()) < tol)
param.push_back(std::pair<GFace*, SPoint2>(gf2, uv2));
}
}
Msg(GERROR, "Vertex %d does not belong to any patch", v->getNum());
}
else{
double allPou = 0.;
for(unsigned int i = 0; i < param.size(); i++){
double u2 = param[i].second[0], v2 = param[i].second[1];
double pou2=1;
//FM->GetPou(param[i].first->tag(), u2, v2, pou2);
if(v->getData()){
double *pou = (double*)v->getData();
*pou = *pou / allPou;
}
else{
Msg(GERROR, "Vertex %d has no POU data", v->getNum());
}
}
}
public:
void operator() (GFace *gf)
{
// mark elements in the groove with '-1' visibility tag
for(unsigned int i = 0; i < gf->quadrangles.size(); i++){
MElement *e = gf->quadrangles[i];
for(int j = 0; j < e->getNumVertices(); j++){
void *data = e->getVertex(j)->getData();
if(data){
double pou = *(double*)data;
// remove elements in the groove
std::vector<MQuadrangle*> newq;
for(unsigned int i = 0; i < gf->quadrangles.size(); i++)
if(gf->quadrangles[i]->getVisibility() < 0)
else
newq.push_back(gf->quadrangles[i]);
gf->quadrangles = newq;
std::vector<MVertex*> newv;
for(unsigned int i = 0; i < gf->mesh_vertices.size(); i++)
gf->mesh_vertices[i]->setVisibility(-1);
for(unsigned int i = 0; i < gf->quadrangles.size(); i++)
for(int j = 0; j < gf->quadrangles[i]->getNumVertices(); j++)
gf->quadrangles[i]->getVertex(j)->setVisibility(1);
for(unsigned int i = 0; i < gf->mesh_vertices.size(); i++)
if(gf->mesh_vertices[i]->getVisibility() < 0)
else
newv.push_back(gf->mesh_vertices[i]);
gf->mesh_vertices = newv;
void getOrderedBoundaryLoops(std::vector<MElement*> &elements,
std::vector<std::vector<MVertex*> > &loops)
{
typedef std::pair<MVertex*, MVertex*> vpair;
std::map<vpair, vpair> edges;
for(unsigned int i = 0; i < elements.size(); i++){
for(int j = 0; j < elements[i]->getNumEdges(); j++){
MEdge e = elements[i]->getEdge(j);
vpair p(e.getMinVertex(), e.getMaxVertex());
if(edges.count(p)) edges.erase(p);
else edges[p] = vpair(e.getVertex(0), e.getVertex(1));
std::map<MVertex*, MVertex*> connect;
for(std::map<vpair, vpair>::iterator it = edges.begin(); it != edges.end(); it++)
connect[it->second.first] = it->second.second;
loops.resize(1);
while(connect.size()){
if(loops[loops.size() - 1].empty())
loops[loops.size() - 1].push_back(connect.begin()->first);
MVertex *prev = loops[loops.size() - 1][loops[loops.size() - 1].size() - 1];
MVertex *next = connect[prev];
connect.erase(prev);
loops[loops.size() - 1].push_back(next);
if(next == loops[loops.size() - 1][0])
loops.resize(loops.size() + 1);
}
if(loops[loops.size() - 1].empty())
loops.pop_back();
Msg(INFO, "Found %d loop(s) in boundary", loops.size());
void classifyFaces(GFace *gf, std::set<GFace*> &connected, std::set<GFace*> &other)
connected.insert(gf);
std::set<MVertex*> verts;
for(unsigned int i = 0; i < gf->mesh_vertices.size(); i++)
verts.insert(gf->mesh_vertices[i]);
for(int i = 0; i < gf->model()->numFace() - 1; i++){ // worst case
for(GModel::fiter it = gf->model()->firstFace(); it != gf->model()->lastFace(); it++){
if(connected.find(*it) == connected.end()){
for(unsigned int j = 0; j < (*it)->mesh_vertices.size(); j++){
if(std::find(verts.begin(), verts.end(), (*it)->mesh_vertices[j]) != verts.end()){
connected.insert(*it);
for(unsigned int k = 0; k < (*it)->mesh_vertices.size(); k++)
verts.insert((*it)->mesh_vertices[k]);
break;
}
}
}
}
for(GModel::fiter it = gf->model()->firstFace(); it != gf->model()->lastFace(); it++)
if(connected.find(*it) == connected.end())
other.insert(*it);
Msg(INFO, "Found %d face(s) connected to face %d", (int)connected.size(), gf->tag());
for(std::set<GFace*>::iterator it = connected.begin(); it != connected.end(); it++)
Msg(INFO, " %d", (*it)->tag());
void getIntersectingBoundaryParts(GFace *gf, std::vector<MElement*> &elements,
std::vector<std::vector<std::vector<MVertex*> > > &parts)
std::vector<std::vector<MVertex*> > loops;
getOrderedBoundaryLoops(elements, loops);
parts.resize(loops.size());
for(unsigned int i = 0; i < loops.size(); i++){
bool newpart = true;
for(unsigned int j = 0; j < loops[i].size() - 1; j++){
MVertex *v = loops[i][j];
SPoint2 uv = gf->parFromPoint(SPoint3(v->x(), v->y(), v->z()));
if(gf->containsParam(uv)){
GPoint xyz = gf->point(uv);
const double tol = 1.e-2; // Warning: tolerance
if(fabs(xyz.x() - v->x()) < tol &&
fabs(xyz.y() - v->y()) < tol &&
fabs(xyz.z() - v->z()) < tol){
if(newpart){
parts[i].resize(parts[i].size() + 1);
newpart = false;
}
v->setParameter(0, uv[0]);
v->setParameter(1, uv[1]);
parts[i][parts[i].size() - 1].push_back(v);
}
else{
newpart = true;
}
}
else{
newpart = true;
}
}
}
#if 0
static int nn = 0;
debugElements(elements, "elements", false, nn++);
for(unsigned int i = 0; i < loops.size(); i++)
debugVertices(loops[i], "loops", false, nn++);
for(unsigned int i = 0; i < parts.size(); i++)
for(unsigned int j = 0; j < parts[i].size(); j++)
debugVertices(parts[i][j], "parts", false, nn++);
#endif
void meshGrout(GFace *gf, std::vector<MVertex*> &loop, std::vector<MVertex*> &hole)
{
debugVertices(hole, "hole", true, gf->tag());
debugVertices(loop, "loop", true, gf->tag());
fourierFace *grout = new fourierFace(gf, loop, hole);
meshGFace mesh;
mesh(grout);
//debugElements(grout->triangles, "grout", true);
for(unsigned int i = 0; i < grout->triangles.size(); i++)
gf->triangles.push_back(grout->triangles[i]);
for(unsigned int i = 0; i < loop.size(); i++)
gf->mesh_vertices.push_back(loop[i]);
for(unsigned int i = 0; i < hole.size(); i++)
gf->mesh_vertices.push_back(hole[i]);
for(unsigned int i = 0; i < grout->mesh_vertices.size(); i++)
gf->mesh_vertices.push_back(grout->mesh_vertices[i]);
delete grout;
}
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
void meshGroutWithHole(GFace *gf,
std::vector<std::vector<std::vector<MVertex*> > > &inside,
std::vector<std::vector<std::vector<MVertex*> > > &outside)
{
std::vector<MVertex*> hole, loop;
// create hole
SPoint2 ic(0., 0.);
for(unsigned int i = 0; i < inside[0][0].size(); i++){
hole.push_back(inside[0][0][i]);
double u, v;
inside[0][0][i]->getParameter(0, u);
inside[0][0][i]->getParameter(1, v);
ic += SPoint2(u, v);
}
ic *= 1. / (double)inside[0][0].size();
hole.push_back(hole[0]);
// order exterior parts and create exterior loop
std::vector<std::pair<double, int> > angle;
std::map<int, std::vector<MVertex*> > outside_flat;
int part = 0;
for(unsigned int i = 0; i < outside.size(); i++){
for(unsigned int j = 0; j < outside[i].size(); j++){
for(unsigned int k = 0; k < outside[i][j].size(); k++){
outside_flat[part].push_back(outside[i][j][k]);
}
part++;
}
}
std::map<int, std::vector<MVertex*> >::iterator it = outside_flat.begin();
for(; it != outside_flat.end(); it++){
SPoint2 oc(0., 0.);
for(unsigned int i = 0; i < it->second.size(); i++){
double u, v;
it->second[i]->getParameter(0, u);
it->second[i]->getParameter(1, v);
oc += SPoint2(u, v);
}
oc *= 1. / (double)it->second.size();
double a = atan2(oc[1] - ic[1], oc[0] - ic[0]);
angle.push_back(std::make_pair(a, it->first));
}
std::sort(angle.begin(), angle.end());
for(unsigned int i = 0; i < angle.size(); i++){
for(unsigned int j = 0; j < outside_flat[angle[i].second].size(); j++)
loop.push_back(outside_flat[angle[i].second][j]);
}
loop.push_back(hole[0]);
// mesh the grout
meshGrout(gf, loop, hole);
}
bool onHardEdge(GFace *gf, MVertex *vertex)
{
std::vector<int> edges;
FM->GetEdge(gf->tag(), edges);
if(edges.empty()) return false;
double u, v;
vertex->getParameter(0, u);
vertex->getParameter(1, v);
for(unsigned int i = 0; i < edges.size(); i++){
switch(edges[i]){
case 0: if(u == 0.) return true;
case 1: if(u == 1.) return true;
case 2: if(v == 0.) return true;
case 3: if(v == 1.) return true;
}
}
return false;
}
bool removeHardEdges(GFace *gf, std::vector<MVertex*> &loop,
std::vector<std::vector<MVertex*> > &subloops)
{
for(unsigned int i = 1; i < loop.size() - 1; i++){
if(onHardEdge(gf, loop[i - 1]) &&
onHardEdge(gf, loop[i]) &&
onHardEdge(gf, loop[i + 1])){
// skip + create new path
if(subloops.size() > 1){
for(unsigned int i = 0; i < subloops.size(); i++){
//if(subloops[i].size()) debugVertices(subloops[i], "x", false, i);
}
Msg(INFO, "HAVE SUBLOOPS!");
return true;
}
return false;
}
void meshGroutWithoutHole(GFace *gf,
std::vector<std::vector<MVertex*> > &inside)
{
std::vector<MVertex*> hole, tmp;
std::vector<std::vector<MVertex*> > loops;
for(unsigned int i = 0; i < inside.size(); i++)
for(unsigned int j = 0; j < inside[i].size(); j++)
tmp.push_back(inside[i][j]);
tmp.push_back(tmp[0]);
if(removeHardEdges(gf, tmp, loops)){
//for(unsigned int i = 0; i < loops.size(); i++)
//meshGrout(gf, loops[i], hole);
class createGrout{
public:
void operator() (GFace *gf)
{
Msg(INFO, "Processing grout for face %d", gf->tag());
std::set<GFace*> connected, other;
classifyFaces(gf, connected, other);
std::vector<MElement*> connectedElements;
for(std::set<GFace*>::iterator it = connected.begin(); it != connected.end(); it++){
for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
connectedElements.push_back((*it)->triangles[i]);
for(unsigned int i = 0; i < (*it)->quadrangles.size(); i++)
connectedElements.push_back((*it)->quadrangles[i]);
}
std::vector<MElement*> otherElements;
for(std::set<GFace*>::iterator it = other.begin(); it != other.end(); it++){
for(unsigned int i = 0; i < (*it)->triangles.size(); i++)
otherElements.push_back((*it)->triangles[i]);
for(unsigned int i = 0; i < (*it)->quadrangles.size(); i++)
otherElements.push_back((*it)->quadrangles[i]);
}
std::vector<std::vector<std::vector<MVertex*> > > inside;
getIntersectingBoundaryParts(gf, connectedElements, inside);
Msg(INFO, "%d inside loop(s)", (int)inside.size());
for(unsigned int i = 0; i < inside.size(); i++)
Msg(INFO, " inside loop %d intersect has %d part(s)", i, (int)inside[i].size());
std::vector<std::vector<std::vector<MVertex*> > > outside;
getIntersectingBoundaryParts(gf, otherElements, outside);
Msg(INFO, "%d outside loop(s)", (int)outside.size());
for(unsigned int i = 0; i < outside.size(); i++)
Msg(INFO, " outside loop %d intersect has %d part(s)", i, (int)outside[i].size());
if(inside.size() == 1 && inside[0].size() == 1){
Msg(INFO, "*** CASE 1: grout has a single hole in one part ***");
meshGroutWithHole(gf, inside, outside);
Msg(INFO, "*** CASE 2: grout has no outside contributions ***");
for(unsigned int i = 0; i < inside.size(); i++)
meshGroutWithoutHole(gf, inside[i]);
fourierEdge::fourierEdge(GModel *model, int num, GVertex *v1, GVertex *v2)
: GEdge(model, num, v1, v2)
{
}
fourierFace::fourierFace(GModel *m, int num)
: GFace(m, num)
}
fourierFace::fourierFace(GFace *f, std::vector<MVertex*> &loop, std::vector<MVertex*> &hole)
: GFace(f->model(), f->tag())
{
if(!loop.size()){
Msg(GERROR, "No vertices in exterior loop");
return;
}
_v[0] = new fourierVertex(f->model(), loop[0]);
_v[1] = new fourierVertex(f->model(), loop[loop.size() - 2]);
_e[0] = new fourierEdge(f->model(), 1, _v[0], _v[1]);
_e[0]->addFace(this);
_e[1] = new fourierEdge(f->model(), 2, _v[1], _v[0]);
_e[1]->addFace(this);
l_edges.push_back(_e[0]); l_dirs.push_back(-1);
l_edges.push_back(_e[1]); l_dirs.push_back(-1);
_v[2] = new fourierVertex(f->model(), hole[0]);
_v[3] = new fourierVertex(f->model(), hole[hole.size() - 2]);
_e[2] = new fourierEdge(f->model(), 3, _v[2], _v[3]);
_e[2]->addFace(this);
_e[3] = new fourierEdge(f->model(), 4, _v[3], _v[2]);
_e[3]->addFace(this);
l_edges.push_back(_e[2]); l_dirs.push_back(1);
l_edges.push_back(_e[3]); l_dirs.push_back(1);
if(!_discrete){
// this face was just used temporarily for meshing, so don't
// delete the mesh vertices or the mesh elements: they have been
// transferred elsewhere
for(int i = 0; i < 4; i++){
if(_e[i]){
_e[i]->mesh_vertices.clear();
delete _e[i];
}
}
for(int i = 0; i < 4; i++){
if(_v[i]){
_v[i]->mesh_vertices.clear();
delete _v[i];
}
}
triangles.clear();
quadrangles.clear();
mesh_vertices.clear();
l_edges.clear();
}
_discrete = 0;
int nu=0, nv=0;
FM->GetNum(tag(), nu, nv);
std::vector<double> u, v;
FM->GetBoundary_Points(tag(), u, v);
if(2*nu+2*nv != u.size()){
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
Msg(INFO, "Special planar patch from YoungAe: %d", tag());
#if 1 // transfinite, by hand -- WARNING
_plane = 1; // to enable smoothing of transfinite meshes
nu = 14;
nv = 9;
// remove duplicates
std::vector<MVertex*> verts;
for(unsigned int i = 0; i < u.size() - 1; i++){
if(!i || fabs(u[i]-u[i-1]) > tol || fabs(v[i]-v[i-1]) > tol){
GPoint p = point(u[i], v[i]);
verts.push_back(new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]));
}
}
int corners[4] = {0, nu - 1, nu + nv - 2, 2 * nu + nv - 3};
for(int i = 0; i < 4; i++)
_v[i] = new fourierVertex(model(), verts[corners[i]]);
meshAttributes.Method = TRANSFINI;
meshAttributes.recombine = 1;
meshAttributes.transfiniteArrangement = 1;
meshAttributes.corners.clear();
for(int i = 0; i < 4; i++)
meshAttributes.corners.push_back(_v[i]);
_e[0] = new fourierEdge(model(), 1, _v[0], _v[1]);
_e[0]->addFace(this);
_e[1] = new fourierEdge(model(), 2, _v[1], _v[2]);
_e[1]->addFace(this);
_e[2] = new fourierEdge(model(), 3, _v[2], _v[3]);
_e[2]->addFace(this);
_e[3] = new fourierEdge(model(), 4, _v[3], _v[0]);
_e[3]->addFace(this);
for(unsigned int i = corners[0] + 1; i < corners[1]; i++)
_e[0]->mesh_vertices.push_back(verts[i]);
for(unsigned int i = corners[1] + 1; i < corners[2]; i++)
_e[1]->mesh_vertices.push_back(verts[i]);
for(unsigned int i = corners[2] + 1; i < corners[3]; i++)
_e[2]->mesh_vertices.push_back(verts[i]);
for(unsigned int i = corners[3] + 1; i < verts.size(); i++)
_e[3]->mesh_vertices.push_back(verts[i]);
l_edges.push_back(_e[0]); l_dirs.push_back(1);
l_edges.push_back(_e[1]); l_dirs.push_back(1);
l_edges.push_back(_e[2]); l_dirs.push_back(1);
l_edges.push_back(_e[3]); l_dirs.push_back(1);
#else // unstructured
GPoint p0 = point(u[0], v[0]);
GPoint p1 = point(u[1], v[1]);
MVertex *v0 = new MFaceVertex(p0.x(), p0.y(), p0.z(), this, u[0], v[0]);
MVertex *v1 = new MFaceVertex(p1.x(), p1.y(), p1.z(), this, u[1], v[1]);
_v[0] = new fourierVertex(model(), v0);
_v[1] = new fourierVertex(model(), v1);
_e[0] = new fourierEdge(model(), 1, _v[0], _v[1]);
_e[0]->addFace(this);
_e[1] = new fourierEdge(model(), 2, _v[1], _v[0]);
_e[1]->addFace(this);
for(unsigned int i = 2; i < u.size() - 1; i++){
if(fabs(u[i]-u[i-1]) > tol || fabs(v[i]-v[i-1]) > tol){
GPoint p = point(u[i], v[i]);
MVertex *vv = new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]);
_e[1]->mesh_vertices.push_back(vv);
}
}
l_edges.push_back(_e[0]); l_dirs.push_back(1);
l_edges.push_back(_e[1]); l_dirs.push_back(1);
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
return;
}
int corners[4] = {0, nu, nu + nv, 2 * nu + nv};
for(int i = 0; i < 4; i++){
double uu = u[corners[i]], vv = v[corners[i]];
GPoint p = point(uu, vv);
MVertex *newv = new MFaceVertex(p.x(), p.y(), p.z(), this, uu, vv);
_v[i] = new fourierVertex(model(), newv);
}
meshAttributes.Method = TRANSFINI;
meshAttributes.recombine = 1;
meshAttributes.transfiniteArrangement = 1;
meshAttributes.corners.clear();
for(int i = 0; i < 4; i++)
meshAttributes.corners.push_back(_v[i]);
_e[0] = new fourierEdge(model(), 1, _v[0], _v[1]);
_e[0]->addFace(this);
_e[1] = new fourierEdge(model(), 2, _v[1], _v[2]);
_e[1]->addFace(this);
_e[2] = new fourierEdge(model(), 3, _v[2], _v[3]);
_e[2]->addFace(this);
_e[3] = new fourierEdge(model(), 4, _v[3], _v[0]);
_e[3]->addFace(this);
for(unsigned int i = corners[0] + 1; i < corners[1] - 1; i++){
GPoint p = point(u[i], v[i]);
_e[0]->mesh_vertices.push_back(new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]));
}
for(unsigned int i = corners[1] + 1; i < corners[2] - 1; i++){
GPoint p = point(u[i], v[i]);
_e[1]->mesh_vertices.push_back(new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]));
}
for(unsigned int i = corners[2] + 1; i < corners[3] - 1; i++){
GPoint p = point(u[i], v[i]);
_e[2]->mesh_vertices.push_back(new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]));
}
for(unsigned int i = corners[3] + 1; i < u.size() - 1; i++){
GPoint p = point(u[i], v[i]);
_e[3]->mesh_vertices.push_back(new MFaceVertex(p.x(), p.y(), p.z(), this, u[i], v[i]));
}
l_edges.push_back(_e[0]); l_dirs.push_back(1);
l_edges.push_back(_e[1]); l_dirs.push_back(1);
l_edges.push_back(_e[2]); l_dirs.push_back(1);
l_edges.push_back(_e[3]); l_dirs.push_back(1);
}
Range<double> fourierFace::parBounds(int i) const
{
double min, max;
FM->GetParamBounds(tag(), i, min, max);
return Range<double>(min, max);
}
GPoint fourierFace::point(double par1, double par2) const
{
double x, y, z;
FM->GetPoint(tag(), par1, par2, x, y, z);
return GPoint(x, y, z);
}
GPoint fourierFace::point(const SPoint2 &pt) const
{
GPoint fourierFace::closestPoint(const SPoint3 & queryPoint) const
{
throw;
}
int fourierFace::containsPoint(const SPoint3 &pt) const
{
throw;
}
int fourierFace::containsParam(const SPoint2 &pt) const
{
double umin, umax, vmin, vmax;
FM->GetParamBounds(tag(), 0, umin, umax);
FM->GetParamBounds(tag(), 1, vmin, vmax);
const double tol = 1.e-6;
if(pt[0] < umin - tol || pt[0] > umax + tol) return 0;
if(pt[1] < vmin - tol || pt[1] > vmax + tol) return 0;
return 1;
}
SVector3 fourierFace::normal(const SPoint2 ¶m) const
{
throw;
}
GEntity::GeomType fourierFace::geomType() const
{
if(_discrete)
return GEntity::DiscreteSurface;
else if(_plane)
return GEntity::Plane;
else
return GEntity::Unknown;
double u, v;
FM->GetParamFromPoint(tag(), p.x(), p.y(), p.z(), u, v);
return SPoint2(u, v);
int GModel::readFourier(const std::string &name)
{
FM = new model(name);
CTX.terminal = 1;
Msg(INFO, "Fourier model created: %d patches", FM->GetNumPatches());
// create one face per patch
for(int i = 0; i < FM->GetNumPatches(); i++)
add(new fourierFace(this, i));
// mesh each face with quads
//std::for_each(firstFace(), lastFace(), meshCartesian());
//return 1;
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
return 1;
// compute partition of unity
std::for_each(firstFace(), lastFace(), computePartitionOfUnity());
// create grooves
std::for_each(firstFace(), lastFace(), createGroove());
// create grout
std::for_each(firstFace(), lastFace(), createGrout());
// remove any duplicate vertices on hard edges
// Here's an alternative approach that might be worth investigating:
// - compute and store the pou of each overlapping patch in the nodes of
// all the patches
// - for each pair of overlapping patches, find the line pou1=pou2 by
// interpolation on the overlapping grids
// - compute the intersections of these lines
// This should define a non-overlapping partitioning of the grid, which
// could be used as the boundary constrain for the unstructured algo
CTX.terminal = 0;
CTX.mesh.changed = ENT_ALL;
return 1;
}
#else
int GModel::readFourier(const std::string &name)
{
Msg(GERROR, "Fourier model is not compiled in this version of Gmsh");
return 1;
}