netgen/libsrc/visualization/vsfieldlines.cpp

353 lines
8.6 KiB
C++
Raw Normal View History

2009-01-13 04:40:13 +05:00
#ifndef NOTCL
#include <mystdlib.h>
2014-10-08 18:46:25 +06:00
#include <incopengl.hpp>
2009-01-13 04:40:13 +05:00
#include <myadt.hpp>
#include <meshing.hpp>
#include <csg.hpp>
#include <stlgeom.hpp>
#include <visual.hpp>
#include <meshing/fieldlines.hpp>
2009-01-13 04:40:13 +05:00
namespace netgen
{
2014-10-06 15:57:44 +06:00
// extern shared_ptr<Mesh> mesh;
2009-01-13 04:40:13 +05:00
2022-04-11 20:27:47 +05:00
void VisualSceneSolution :: BuildFieldLinesFromBox(Array<Point<3>> & startpoints)
2009-01-13 04:40:13 +05:00
{
2015-01-09 02:18:33 +05:00
shared_ptr<Mesh> mesh = GetMesh();
2014-10-06 15:57:44 +06:00
if (!mesh) return;
2009-01-13 04:40:13 +05:00
if(fieldlines_startarea_parameter[0] > fieldlines_startarea_parameter[3] ||
fieldlines_startarea_parameter[1] > fieldlines_startarea_parameter[4] ||
fieldlines_startarea_parameter[2] > fieldlines_startarea_parameter[5])
{
Point3d pmin, pmax;
mesh->GetBox (pmin, pmax);
fieldlines_startarea_parameter[0] = pmin.X();
fieldlines_startarea_parameter[1] = pmin.Y();
fieldlines_startarea_parameter[2] = pmin.Z();
fieldlines_startarea_parameter[3] = pmax.X();
fieldlines_startarea_parameter[4] = pmax.Y();
fieldlines_startarea_parameter[5] = pmax.Z();
}
for (int i = 1; i <= startpoints.Size(); i++)
{
2022-04-11 20:27:47 +05:00
Point<3> p (fieldlines_startarea_parameter[0] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]),
2009-01-13 04:40:13 +05:00
fieldlines_startarea_parameter[1] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]),
fieldlines_startarea_parameter[2] + double (rand()) / RAND_MAX * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2]));
startpoints[i-1] = p;
}
}
2022-04-11 20:27:47 +05:00
void VisualSceneSolution :: BuildFieldLinesFromLine(Array<Point<3>> & startpoints)
2009-01-13 04:40:13 +05:00
{
2015-01-09 02:18:33 +05:00
shared_ptr<Mesh> mesh = GetMesh();
2014-10-06 15:57:44 +06:00
if (!mesh) return;
2009-01-13 04:40:13 +05:00
for (int i = 1; i <= startpoints.Size(); i++)
{
double s = double (rand()) / RAND_MAX;
2022-04-11 20:27:47 +05:00
Point<3> p (fieldlines_startarea_parameter[0] + s * (fieldlines_startarea_parameter[3]-fieldlines_startarea_parameter[0]),
2009-01-13 04:40:13 +05:00
fieldlines_startarea_parameter[1] + s * (fieldlines_startarea_parameter[4]-fieldlines_startarea_parameter[1]),
fieldlines_startarea_parameter[2] + s * (fieldlines_startarea_parameter[5]-fieldlines_startarea_parameter[2]));
startpoints[i-1] = p;
}
}
2022-04-11 20:27:47 +05:00
void VisualSceneSolution :: BuildFieldLinesFromFile(Array<Point<3>> & startpoints)
2009-01-13 04:40:13 +05:00
{
2015-01-09 02:18:33 +05:00
shared_ptr<Mesh> mesh = GetMesh();
2014-10-06 15:57:44 +06:00
if (!mesh) return;
2009-01-13 04:40:13 +05:00
ifstream * infile;
infile = new ifstream(fieldlines_filename.c_str());
//cout << "reading from file " << fieldlines_filename << endl;
int numpoints = 0;
string keyword;
double dparam;
int iparam;
while(infile->good())
{
(*infile) >> keyword;
if(keyword == "point") numpoints++;
else if(keyword == "line" || keyword == "box")
{
for(int i=0; i<6; i++) (*infile) >> dparam;
(*infile) >> iparam;
numpoints += iparam;
}
}
delete infile;
//cout << numpoints << " startpoints" << endl;
startpoints.SetSize(numpoints);
infile = new ifstream(fieldlines_filename.c_str());
numpoints = 0;
while(infile->good())
{
(*infile) >> keyword;
if (keyword == "point")
{
2022-04-11 20:27:47 +05:00
(*infile) >> startpoints[numpoints][0];
(*infile) >> startpoints[numpoints][1];
(*infile) >> startpoints[numpoints][2];
2009-01-13 04:40:13 +05:00
numpoints++;
}
else if (keyword == "line" || keyword == "box")
{
for(int i=0; i<6; i++) (*infile) >> fieldlines_startarea_parameter[i];
(*infile) >> iparam;
2022-04-11 20:27:47 +05:00
Array<Point<3>> auxpoints(iparam);
2009-01-13 04:40:13 +05:00
if (keyword == "box")
BuildFieldLinesFromBox(auxpoints);
else if (keyword == "line")
BuildFieldLinesFromLine(auxpoints);
for(int i=0; i<iparam; i++)
{
startpoints[numpoints] = auxpoints[i];
numpoints++;
}
}
//cout << "startpoints " << startpoints << endl;
}
delete infile;
}
2022-04-11 20:27:47 +05:00
void VisualSceneSolution :: BuildFieldLinesFromFace(Array<Point<3>> & startpoints)
2009-01-13 04:40:13 +05:00
{
2015-01-09 02:18:33 +05:00
shared_ptr<Mesh> mesh = GetMesh();
2014-10-06 15:57:44 +06:00
if (!mesh) return;
Array<SurfaceElementIndex> elements_2d;
2009-01-13 04:40:13 +05:00
//cout << "fieldlines_startface " << fieldlines_startface << endl;
mesh->GetSurfaceElementsOfFace(fieldlines_startface,elements_2d);
if(elements_2d.Size() == 0)
{
cerr << "No Elements on selected face (?)" << endl;
return;
}
Vec3d v1,v2,cross;
double area = 0;
int i;
for(i=0; i<elements_2d.Size(); i++)
{
const Element2d & elem = (*mesh)[elements_2d[i]];
2009-01-13 04:40:13 +05:00
v1 = mesh->Point(elem[1]) - mesh->Point(elem[0]);
v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]);
cross = Cross(v1,v2);
area += cross.Length();
if(elem.GetNV() == 4)
{
v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]);
v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]);
cross = Cross(v1,v2);
area += cross.Length();
}
}
int startpointsp = 0;
i = 0;
while(startpointsp < startpoints.Size())
{
const Element2d & elem = (*mesh)[elements_2d[i]];
2009-01-13 04:40:13 +05:00
int numtri = (elem.GetNV() == 3) ? 1 : 2;
for(int tri = 0; startpointsp < startpoints.Size() && tri<numtri; tri++)
{
if(tri == 0)
{
v1 = mesh->Point(elem[1]) - mesh->Point(elem[0]);
v2 = mesh->Point(elem[2]) - mesh->Point(elem[0]);
cross = Cross(v1,v2);
}
else if(tri == 1)
{
v1 = mesh->Point(elem[2]) - mesh->Point(elem[0]);
v2 = mesh->Point(elem[3]) - mesh->Point(elem[0]);
cross = Cross(v1,v2);
}
double thisarea = cross.Length();
int numloc = int(startpoints.Size()*thisarea/area);
if(double (rand()) / RAND_MAX < startpoints.Size()*thisarea/area - numloc)
numloc++;
for(int j=0; startpointsp < startpoints.Size() && j<numloc; j++)
{
double s = double (rand()) / RAND_MAX;
double t = double (rand()) / RAND_MAX;
if(s+t > 1)
{
s = 1.-s; t = 1.-t;
}
startpoints[startpointsp] = mesh->Point(elem[0]) + s*v1 +t*v2;
startpointsp++;
}
}
i++;
if(i == elements_2d.Size()) i = 0;
}
}
void VisualSceneSolution :: BuildFieldLinesPlot ()
{
2015-01-09 02:18:33 +05:00
shared_ptr<Mesh> mesh = GetMesh();
2014-10-06 15:57:44 +06:00
if (!mesh) return;
2009-01-13 04:40:13 +05:00
if (fieldlinestimestamp >= solutiontimestamp)
return;
fieldlinestimestamp = solutiontimestamp;
if (fieldlineslist)
glDeleteLists (fieldlineslist, num_fieldlineslists);
if (vecfunction == -1)
return;
const SolData * vsol = soldata[fieldlines_vecfunction];
num_fieldlineslists = (vsol -> iscomplex && !fieldlines_fixedphase) ? 100 : 1;
2022-04-11 20:27:47 +05:00
double phaser=1.0;
double phasei=0.0;
std::function<bool(int, const double *, Vec<3> &)> eval_func = [&](int elnr, const double * lami, Vec<3> & vec)
2022-04-11 20:27:47 +05:00
{
double values[6] = {0., 0., 0., 0., 0., 0.};
bool drawelem;
auto mesh = GetMesh();
if (mesh->GetDimension()==3)
drawelem = GetValues (vsol, elnr, lami[0], lami[1], lami[2], values);
else
drawelem = GetSurfValues (vsol, elnr, -1, lami[0], lami[1], values);
Vec3d v;
RealVec3d (values, v, vsol->iscomplex, phaser, phasei);
vec = v;
return drawelem;
};
FieldLineCalc linecalc(*mesh, eval_func,
2009-01-13 04:40:13 +05:00
fieldlines_rellength,fieldlines_maxpoints,fieldlines_relthickness,fieldlines_reltolerance,fieldlines_rktype);
if(fieldlines_randomstart)
linecalc.Randomized();
fieldlineslist = glGenLists (num_fieldlineslists);
int num_startpoints = num_fieldlines / num_fieldlineslists;
if (num_fieldlines % num_fieldlineslists != 0) num_startpoints++;
if(fieldlines_randomstart)
num_startpoints *= 10;
2022-04-11 20:27:47 +05:00
Array<Point<3>> startpoints(num_startpoints);
2009-01-13 04:40:13 +05:00
for (int ln = 0; ln < num_fieldlineslists; ln++)
{
if(fieldlines_startarea == 0)
BuildFieldLinesFromBox(startpoints);
else if(fieldlines_startarea == 1)
BuildFieldLinesFromFile(startpoints);
else if(fieldlines_startarea == 2)
BuildFieldLinesFromFace(startpoints);
double phi;
if(vsol -> iscomplex)
{
if(fieldlines_fixedphase)
phi = fieldlines_phase;
else
phi = 2*M_PI*ln / num_fieldlineslists;
}
else
phi = 0;
cout << "phi = " << phi << endl;
2022-04-11 20:27:47 +05:00
phaser = cos(phi);
phasei = sin(phi);
2009-01-13 04:40:13 +05:00
2022-04-11 20:27:47 +05:00
linecalc.GenerateFieldLines(startpoints,num_fieldlines / num_fieldlineslists+1);
auto & pstart = linecalc.GetPStart();
auto & pend = linecalc.GetPEnd();
auto & values = linecalc.GetValues();
auto nlines = values.Size();
2009-08-05 20:20:30 +06:00
glNewList(fieldlineslist+ln, GL_COMPILE);
SetTextureMode (usetexture);
2022-04-11 20:27:47 +05:00
for(auto i : Range(nlines))
{
SetOpenGlColor (values[i]);
DrawCylinder (pstart[i], pend[i], fieldlines_relthickness);
}
2009-08-05 20:20:30 +06:00
2022-04-11 20:27:47 +05:00
glEndList ();
2009-01-13 04:40:13 +05:00
}
}
}
#endif // NOTCL