mirror of
https://github.com/NGSolve/netgen.git
synced 2025-01-24 03:40:34 +05:00
Rewrite double-click selection in GUI
This commit is contained in:
parent
a12e9bec61
commit
832c17c834
@ -77,9 +77,11 @@ namespace netgen
|
||||
int VisualScene :: locpi;
|
||||
int VisualScene :: seledge;
|
||||
|
||||
int VisualScene :: selecttimestamp;
|
||||
optional<Point<3>> VisualScene :: marker = nullopt;
|
||||
|
||||
int VisualScene :: subdivision_timestamp = -1;
|
||||
int VisualScene :: subdivisions = 2;
|
||||
|
||||
int VisualScene :: viewport[4];
|
||||
|
||||
VisualizationParameters :: VisualizationParameters()
|
||||
|
@ -31,9 +31,10 @@ namespace netgen
|
||||
static int locpi;
|
||||
static int NGGUI_API seledge;
|
||||
|
||||
static int selecttimestamp;
|
||||
static optional<Point<3>> marker;
|
||||
|
||||
static int subdivision_timestamp;
|
||||
static int subdivisions;
|
||||
public:
|
||||
static int viewport[4];
|
||||
static GLuint coltexname;
|
||||
@ -126,35 +127,47 @@ namespace netgen
|
||||
|
||||
class VisualSceneMesh : public VisualScene
|
||||
{
|
||||
int filledlist;
|
||||
int linelist;
|
||||
int edgelist;
|
||||
int pointnumberlist;
|
||||
int filledlist = 0;
|
||||
int linelist = 0;
|
||||
int edgelist = 0;
|
||||
int pointnumberlist = 0;
|
||||
|
||||
int tetlist;
|
||||
int prismlist;
|
||||
int pyramidlist;
|
||||
int hexlist;
|
||||
int tetlist = 0;
|
||||
int prismlist = 0;
|
||||
int pyramidlist = 0;
|
||||
int hexlist = 0;
|
||||
|
||||
int badellist;
|
||||
int identifiedlist;
|
||||
int domainsurflist;
|
||||
int badellist = 0;
|
||||
int identifiedlist = 0;
|
||||
int domainsurflist = 0;
|
||||
|
||||
int vstimestamp;//, selecttimestamp;
|
||||
int filledtimestamp;
|
||||
int linetimestamp;
|
||||
int edgetimestamp;
|
||||
int pointnumbertimestamp;
|
||||
int vstimestamp = -1;
|
||||
int filledtimestamp = -1;
|
||||
int linetimestamp = -1;
|
||||
int edgetimestamp = -1;
|
||||
int pointnumbertimestamp = -1;
|
||||
|
||||
int tettimestamp;
|
||||
int prismtimestamp;
|
||||
int pyramidtimestamp;
|
||||
int hextimestamp;
|
||||
int tettimestamp = -1;
|
||||
int prismtimestamp = -1;
|
||||
int pyramidtimestamp = -1;
|
||||
int hextimestamp = -1;
|
||||
|
||||
int badeltimestamp;
|
||||
int identifiedtimestamp;
|
||||
int domainsurftimestamp;
|
||||
int badeltimestamp = -1;
|
||||
int identifiedtimestamp = -1;
|
||||
int domainsurftimestamp = -1;
|
||||
|
||||
struct {
|
||||
unsigned framebuffer = 0;
|
||||
unsigned render_buffers[2];
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
unsigned x = 0;
|
||||
unsigned y = 0;
|
||||
int list = 0;
|
||||
int list_timestamp = -1;
|
||||
double projmat[16];
|
||||
int viewport[4];
|
||||
} select;
|
||||
|
||||
#ifdef PARALLELGL
|
||||
NgArray<int> par_linelists;
|
||||
@ -200,7 +213,7 @@ namespace netgen
|
||||
{ return selelement; }
|
||||
NGGUI_API int SelectedPoint () const
|
||||
{ return selpoint; }
|
||||
void BuildFilledList (bool names);
|
||||
void BuildFilledList (bool select);
|
||||
// private:
|
||||
void BuildLineList();
|
||||
void BuildEdgeList();
|
||||
@ -215,7 +228,9 @@ namespace netgen
|
||||
void BuildIdentifiedList();
|
||||
void BuildDomainSurfList();
|
||||
|
||||
bool Unproject (int px, int py, Point<3> &p);
|
||||
bool SelectSurfaceElement (int px, int py, Point<3> &p, bool select_on_clipping_plane);
|
||||
bool Unproject(int px, int py, Point<3> &p);
|
||||
ngcore::INT<2> Project(Point<3> p);
|
||||
};
|
||||
|
||||
NGGUI_API extern VisualSceneMesh vsmesh;
|
||||
|
@ -23,38 +23,9 @@ namespace netgen
|
||||
VisualSceneMesh :: VisualSceneMesh ()
|
||||
: VisualScene()
|
||||
{
|
||||
filledlist = 0;
|
||||
linelist = 0;
|
||||
edgelist = 0;
|
||||
badellist = 0;
|
||||
tetlist = 0;
|
||||
prismlist = 0;
|
||||
hexlist = 0;
|
||||
pyramidlist = 0;
|
||||
identifiedlist = 0;
|
||||
pointnumberlist = 0;
|
||||
domainsurflist = 0;
|
||||
|
||||
vstimestamp = -1; // GetTimeStamp();
|
||||
selecttimestamp = -1; // GetTimeStamp();
|
||||
filledtimestamp = -1; // GetTimeStamp();
|
||||
linetimestamp = -1; // GetTimeStamp();
|
||||
edgetimestamp = -1; // GetTimeStamp();
|
||||
pointnumbertimestamp = -1; // GetTimeStamp();
|
||||
|
||||
tettimestamp = -1; // GetTimeStamp();
|
||||
prismtimestamp = -1; // GetTimeStamp();
|
||||
hextimestamp = -1; // GetTimeStamp();
|
||||
pyramidtimestamp = -1; // GetTimeStamp();
|
||||
|
||||
badeltimestamp = -1; // GetTimeStamp();
|
||||
identifiedtimestamp = -1; // GetTimeStamp();
|
||||
domainsurftimestamp = -1; // GetTimeStamp();
|
||||
|
||||
|
||||
selface = -1;
|
||||
selelement = -1;
|
||||
locpi = 1;
|
||||
locpi = -2;
|
||||
selpoint = PointIndex::INVALID;
|
||||
selpoint2 = PointIndex::INVALID;
|
||||
seledge = -1;
|
||||
@ -62,7 +33,6 @@ namespace netgen
|
||||
minh = 0.0;
|
||||
maxh = 0.0;
|
||||
user_me_handler = NULL;
|
||||
|
||||
}
|
||||
|
||||
VisualSceneMesh :: ~VisualSceneMesh ()
|
||||
@ -150,11 +120,7 @@ namespace netgen
|
||||
|
||||
if (vispar.drawfilledtrigs)
|
||||
{
|
||||
if (filledtimestamp < mesh->GetTimeStamp () ||
|
||||
filledtimestamp < selecttimestamp)
|
||||
{
|
||||
BuildFilledList (false);
|
||||
}
|
||||
BuildFilledList (false);
|
||||
|
||||
|
||||
#ifdef PARALLELGL
|
||||
@ -883,12 +849,17 @@ namespace netgen
|
||||
|
||||
|
||||
|
||||
void VisualSceneMesh :: BuildFilledList (bool names)
|
||||
void VisualSceneMesh :: BuildFilledList (bool build_select)
|
||||
{
|
||||
shared_ptr<Mesh> mesh = GetMesh();
|
||||
|
||||
static int timer = NgProfiler::CreateTimer ("Mesh::BuildFilledList");
|
||||
NgProfiler::RegionTimer reg (timer);
|
||||
auto & list = build_select ? select.list : filledlist;
|
||||
auto & timestamp = build_select ? select.list_timestamp : filledtimestamp;
|
||||
if (list && timestamp > max(mesh->GetTimeStamp(), subdivision_timestamp))
|
||||
return;
|
||||
|
||||
|
||||
#ifdef PARALLELGL
|
||||
if (id == 0 && ntasks > 1)
|
||||
@ -901,18 +872,18 @@ namespace netgen
|
||||
for ( int dest = 1; dest < ntasks; dest++ )
|
||||
MyMPI_Recv (par_filledlists[dest], dest, MPI_TAG_VIS);
|
||||
|
||||
if (filledlist)
|
||||
glDeleteLists (filledlist, 1);
|
||||
if (list)
|
||||
glDeleteLists (list, 1);
|
||||
|
||||
filledlist = glGenLists (1);
|
||||
glNewList (filledlist, GL_COMPILE);
|
||||
list = glGenLists (1);
|
||||
glNewList (list, GL_COMPILE);
|
||||
|
||||
for ( int dest = 1; dest < ntasks; dest++ )
|
||||
glCallList (par_filledlists[dest]);
|
||||
|
||||
glEndList();
|
||||
|
||||
filledtimestamp = NextTimeStamp();
|
||||
timestamp = NextTimeStamp();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -925,13 +896,13 @@ namespace netgen
|
||||
lock -> Lock();
|
||||
}
|
||||
|
||||
filledtimestamp = NextTimeStamp();
|
||||
timestamp = NextTimeStamp();
|
||||
|
||||
if (filledlist)
|
||||
glDeleteLists (filledlist, 1);
|
||||
if (list)
|
||||
glDeleteLists (list, 1);
|
||||
|
||||
filledlist = glGenLists (1);
|
||||
glNewList (filledlist, GL_COMPILE);
|
||||
list = glGenLists (1);
|
||||
glNewList (list, GL_COMPILE);
|
||||
|
||||
|
||||
#ifdef STLGEOM
|
||||
@ -967,6 +938,14 @@ namespace netgen
|
||||
else
|
||||
glDisable (GL_COLOR_MATERIAL);
|
||||
|
||||
if(build_select)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_FOG);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable (GL_COLOR_MATERIAL);
|
||||
}
|
||||
|
||||
|
||||
GLfloat matcol[] = { 0, 1, 0, 1 };
|
||||
GLfloat matcolsel[] = { 1, 0, 0, 1 };
|
||||
@ -976,7 +955,7 @@ namespace netgen
|
||||
|
||||
CurvedElements & curv = mesh->GetCurvedElements();
|
||||
|
||||
int hoplotn = 1 << vispar.subdivisions;
|
||||
int hoplotn = 1 << subdivisions;
|
||||
|
||||
Array<SurfaceElementIndex> seia;
|
||||
|
||||
@ -993,10 +972,13 @@ namespace netgen
|
||||
for (auto i : Range(4))
|
||||
matcol[i] = mesh->GetFaceDescriptor(faceindex).SurfColour()[i];
|
||||
|
||||
if (faceindex == selface)
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolsel);
|
||||
else
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol);
|
||||
if(!build_select)
|
||||
{
|
||||
if (faceindex == selface)
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcolsel);
|
||||
else
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matcol);
|
||||
}
|
||||
|
||||
static Point<3> xa[129];
|
||||
static Vec<3> na[129];
|
||||
@ -1020,8 +1002,14 @@ namespace netgen
|
||||
if (!drawel)
|
||||
continue;
|
||||
|
||||
if (names)
|
||||
glLoadName (sei+1);
|
||||
if (build_select)
|
||||
{
|
||||
GLushort r,g,b;
|
||||
r = (sei+1) % (1<<16);
|
||||
g = (sei+1) >> 16;
|
||||
b = 0;
|
||||
glColor3us(r,g,b);
|
||||
}
|
||||
|
||||
switch (el.GetType())
|
||||
{
|
||||
@ -1267,7 +1255,7 @@ namespace netgen
|
||||
#ifdef PARALLELGL
|
||||
glFinish();
|
||||
if (id > 0)
|
||||
MyMPI_Send (filledlist, 0, MPI_TAG_VIS);
|
||||
MyMPI_Send (list, 0, MPI_TAG_VIS);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -1335,7 +1323,7 @@ namespace netgen
|
||||
glLineWidth (1.0f);
|
||||
|
||||
|
||||
int hoplotn = 1 << vispar.subdivisions;
|
||||
int hoplotn = 1 << subdivisions;
|
||||
|
||||
// PrintMessage (3, "nse = ", mesh->GetNSE());
|
||||
for (SurfaceElementIndex sei = 0; sei < mesh->GetNSE(); sei++)
|
||||
@ -1621,7 +1609,7 @@ namespace netgen
|
||||
|
||||
if (mesh->GetCurvedElements().IsHighOrder())
|
||||
{
|
||||
int hoplotn = 1 << vispar.subdivisions;
|
||||
int hoplotn = 1 << subdivisions;
|
||||
// mesh->GetCurvedElements().GetNVisualSubsecs();
|
||||
|
||||
Point<3> x;
|
||||
@ -1832,7 +1820,7 @@ namespace netgen
|
||||
else
|
||||
glShadeModel (GL_SMOOTH);
|
||||
|
||||
int hoplotn = max (2, 1 << vispar.subdivisions);
|
||||
int hoplotn = max (2, 1 << subdivisions);
|
||||
|
||||
|
||||
|
||||
@ -2134,7 +2122,7 @@ namespace netgen
|
||||
|
||||
Point<3> grid[11][11];
|
||||
Point<3> fpts[4];
|
||||
int order = vispar.subdivisions+1;
|
||||
int order = subdivisions+1;
|
||||
|
||||
for (int trig = 0; trig < 2; trig++)
|
||||
{
|
||||
@ -2233,7 +2221,7 @@ namespace netgen
|
||||
|
||||
|
||||
/*
|
||||
int hoplotn = 1 << vispar.subdivisions;
|
||||
int hoplotn = 1 << subdivisions;
|
||||
// int hoplotn = curv.GetNVisualSubsecs();
|
||||
|
||||
const Point3d * facepoint = MeshTopology :: GetVertices (TRIG);
|
||||
@ -2521,7 +2509,7 @@ namespace netgen
|
||||
|
||||
Point<3> grid[11][11];
|
||||
Point<3> fpts[4];
|
||||
int order = vispar.subdivisions+1;
|
||||
int order = subdivisions+1;
|
||||
|
||||
for (int quad = 0; quad<6; quad++)
|
||||
{
|
||||
@ -2672,7 +2660,7 @@ namespace netgen
|
||||
|
||||
Point<3> grid[11][11];
|
||||
Point<3> fpts[4];
|
||||
int order = vispar.subdivisions+1;
|
||||
int order = subdivisions+1;
|
||||
|
||||
for (int trig = 0; trig < 4; trig++)
|
||||
{
|
||||
@ -3097,28 +3085,105 @@ namespace netgen
|
||||
|
||||
|
||||
|
||||
|
||||
bool VisualSceneMesh :: Unproject (int px, int py, Point<3> &p)
|
||||
bool VisualSceneMesh :: SelectSurfaceElement (int px, int py, Point<3> &p, bool select_on_clipping_plane)
|
||||
{
|
||||
shared_ptr<Mesh> mesh = GetMesh();
|
||||
|
||||
BuildFilledList (true);
|
||||
|
||||
selelement = -1;
|
||||
marker = nullopt;
|
||||
MouseDblClickSelect(px,py,clipplane,backcolor,transformationmat,center,rad,
|
||||
filledlist,selelement,selface,seledge,selpoint,selpoint2,locpi);
|
||||
shared_ptr<Mesh> mesh = GetMesh();
|
||||
if(px != select.x || py != select.y)
|
||||
{
|
||||
select.x = px;
|
||||
select.y = py;
|
||||
locpi = -2;
|
||||
}
|
||||
|
||||
glGetIntegerv (GL_VIEWPORT, select.viewport);
|
||||
GLenum err;
|
||||
if(select.framebuffer == 0 || select.viewport[2] != select.width || select.viewport[3] != select.height)
|
||||
{
|
||||
select.width = select.viewport[2];
|
||||
select.height = select.viewport[3];
|
||||
if(select.framebuffer != 0)
|
||||
{
|
||||
glDeleteRenderbuffers(2, select.render_buffers);
|
||||
glDeleteFramebuffers(1, &select.framebuffer);
|
||||
}
|
||||
|
||||
GLdouble /* modelview[16], */ projection[16];
|
||||
GLint viewport[4];
|
||||
GLdouble result[3];
|
||||
glGenFramebuffers(1, &select.framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, select.framebuffer);
|
||||
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]);
|
||||
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
|
||||
// create, reserve and attach color and depth renderbuffer
|
||||
glGenRenderbuffers(2, select.render_buffers);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, select.render_buffers[0]);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB16, select.width, select.height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, select.render_buffers[0]);
|
||||
|
||||
int hy = viewport[3]-py;
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, select.render_buffers[1]);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, select.width, select.height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, select.render_buffers[1]);
|
||||
|
||||
GLfloat pz;
|
||||
// check if framebuffer status is complete
|
||||
if(int fbstatus; (fbstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE)
|
||||
cerr << "no frame buffer " << fbstatus << endl;
|
||||
|
||||
}
|
||||
glFlush();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, select.framebuffer);
|
||||
BuildFilledList (true);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClearColor(0, 0, 0, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glMultMatrixd (transformationmat);
|
||||
|
||||
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
|
||||
auto hy = select.viewport[3] - py;
|
||||
|
||||
SetClippingPlane();
|
||||
if (vispar.clipping.enable)
|
||||
{
|
||||
Vec<3> n(clipplane[0], clipplane[1], clipplane[2]);
|
||||
double len = Abs(n);
|
||||
double mu = -clipplane[3] / (len*len);
|
||||
Point<3> p (mu * n);
|
||||
n /= len;
|
||||
Vec<3> t1 = n.GetNormal ();
|
||||
Vec<3> t2 = Cross (n, t1);
|
||||
|
||||
double xi1mid = (center - p) * t1;
|
||||
double xi2mid = (center - p) * t2;
|
||||
|
||||
if(select_on_clipping_plane)
|
||||
{
|
||||
glColor3us(0,0,0);
|
||||
glBegin (GL_QUADS);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
glCallList (select.list);
|
||||
glFinish();
|
||||
|
||||
glGetDoublev (GL_PROJECTION_MATRIX, select.projmat);
|
||||
auto found = Unproject(px, py, p);
|
||||
if(found)
|
||||
{
|
||||
marker = p;
|
||||
GLushort numbers[3];
|
||||
glReadPixels (px, hy, 1, 1, GL_RGB, GL_UNSIGNED_SHORT, numbers);
|
||||
selelement = numbers[0] + numbers[1]*(1<<16);
|
||||
locpi++;
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glPopMatrix();
|
||||
|
||||
if(lock)
|
||||
{
|
||||
@ -3127,48 +3192,79 @@ namespace netgen
|
||||
lock = NULL;
|
||||
}
|
||||
|
||||
// cout << "x, y = " << px << ", " << hy << endl;
|
||||
return found;
|
||||
}
|
||||
|
||||
bool VisualSceneMesh :: Unproject(int px, int py, Point<3> &p)
|
||||
{
|
||||
auto hy = select.viewport[3] - py;
|
||||
float pz;
|
||||
glReadPixels (px, hy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &pz);
|
||||
if(pz<1 && pz>0)
|
||||
gluUnProject(px, hy, pz, transformationmat, select.projmat, select.viewport,
|
||||
&p[0], &p[1], &p[2]);
|
||||
return pz<1 && pz>0;
|
||||
}
|
||||
|
||||
if(pz>=1.0)
|
||||
return false;
|
||||
if(pz<=0.0)
|
||||
return false;
|
||||
ngcore::INT<2> VisualSceneMesh :: Project(Point<3> p)
|
||||
{
|
||||
Point<3> pwin;
|
||||
gluProject(p[0], p[1], p[2], transformationmat, select.projmat, select.viewport,
|
||||
&pwin[0], &pwin[1], &pwin[2]);
|
||||
|
||||
// cout << "pz = " << pz << endl;
|
||||
gluUnProject(px, hy, pz, transformationmat, projection, viewport,
|
||||
&result[0], &result[1], &result[2]);
|
||||
|
||||
p = Point<3>{result[0], result[1], result[2]};
|
||||
marker = p;
|
||||
return true;
|
||||
return ngcore::INT<2>(pwin[0]+0.5, select.viewport[3]-pwin[1]+0.5);
|
||||
}
|
||||
|
||||
|
||||
void VisualSceneMesh :: MouseDblClick (int px, int py)
|
||||
{
|
||||
Point<3> p;
|
||||
bool found_point = Unproject(px, py, p);
|
||||
bool found_point = SelectSurfaceElement(px, py, p, false);
|
||||
int sel_face = 0;
|
||||
|
||||
if(selelement!=-1)
|
||||
if(selelement>0)
|
||||
{
|
||||
const Element2d & sel = GetMesh()->SurfaceElement(selelement);
|
||||
|
||||
cout << "select element " << selelement
|
||||
<< " on face " << sel.GetIndex() << endl;
|
||||
cout << "Nodes: ";
|
||||
for (int i = 1; i <= sel.GetNP(); i++)
|
||||
cout << sel.PNum(i) << " ";
|
||||
cout << endl;
|
||||
|
||||
cout << "selected point " << selpoint
|
||||
<< ", pos = " << GetMesh()->Point (selpoint)
|
||||
<< endl;
|
||||
|
||||
cout << "seledge = " << seledge << endl;
|
||||
|
||||
auto pi_nearest = sel[0];
|
||||
double min_dist = 1e99;
|
||||
for(auto pi : sel.PNums())
|
||||
if(Dist2(GetMesh()->Point(pi), p) < min_dist)
|
||||
{
|
||||
min_dist = Dist2(GetMesh()->Point(pi), p);
|
||||
pi_nearest = pi;
|
||||
}
|
||||
auto p_win = Project(GetMesh()->Point(pi_nearest));
|
||||
cout << endl;
|
||||
if(abs(p_win[0]-px) < 5 && abs(p_win[1]-py) < 5)
|
||||
{
|
||||
cout << "select point " << pi_nearest << endl;
|
||||
marker = GetMesh()->Point(pi_nearest);
|
||||
sel_face = sel.GetIndex();
|
||||
locpi = -2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(locpi < 0)
|
||||
{
|
||||
cout << "select element " << selelement
|
||||
<< " on face " << sel.GetIndex() << endl;
|
||||
cout << "Nodes: ";
|
||||
for (int i = 1; i <= sel.GetNP(); i++)
|
||||
cout << sel.PNum(i) << " ";
|
||||
cout << endl;
|
||||
}
|
||||
else {
|
||||
auto pi = sel[locpi%sel.GetNP()];
|
||||
auto p = GetMesh()->Points()[pi];
|
||||
marker = p;
|
||||
cout << "selected point " << pi << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetSelectedFace(sel_face);
|
||||
|
||||
if(found_point)
|
||||
{
|
||||
cout << "point : " << p << endl;
|
||||
@ -3179,353 +3275,21 @@ namespace netgen
|
||||
}
|
||||
}
|
||||
|
||||
selecttimestamp = NextTimeStamp();
|
||||
|
||||
if(lock)
|
||||
{
|
||||
lock->UnLock();
|
||||
delete lock;
|
||||
lock = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
int i, hits;
|
||||
|
||||
// select surface triangle by mouse click
|
||||
|
||||
GLuint selbuf[10000];
|
||||
glSelectBuffer (10000, selbuf);
|
||||
|
||||
|
||||
glRenderMode (GL_SELECT);
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
GLdouble projmat[16];
|
||||
glGetDoublev (GL_PROJECTION_MATRIX, projmat);
|
||||
|
||||
glLoadIdentity();
|
||||
gluPickMatrix (px, viewport[3] - py, 1, 1, viewport);
|
||||
glMultMatrixd (projmat);
|
||||
|
||||
|
||||
|
||||
glClearColor(backcolor, backcolor, backcolor, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixf (transformationmat);
|
||||
|
||||
|
||||
// SetClippingPlane();
|
||||
|
||||
glInitNames();
|
||||
glPushName (1);
|
||||
|
||||
glPolygonOffset (1, 1);
|
||||
glEnable (GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
|
||||
if (vispar.clipenable)
|
||||
{
|
||||
Vec<3> n(clipplane[0], clipplane[1], clipplane[2]);
|
||||
double len = Abs(n);
|
||||
double mu = -clipplane[3] / (len*len);
|
||||
Point<3> p (mu * n);
|
||||
n /= len;
|
||||
Vec<3> t1 = n.GetNormal ();
|
||||
Vec<3> t2 = Cross (n, t1);
|
||||
|
||||
double xi1mid = (center - p) * t1;
|
||||
double xi2mid = (center - p) * t2;
|
||||
|
||||
glLoadName (0);
|
||||
glBegin (GL_QUADS);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2);
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
// SetClippingPlane();
|
||||
|
||||
glCallList (filledlist);
|
||||
|
||||
glDisable (GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glPopName();
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glFlush();
|
||||
|
||||
|
||||
hits = glRenderMode (GL_RENDER);
|
||||
|
||||
// cout << "hits = " << hits << endl;
|
||||
|
||||
int minname = 0;
|
||||
GLuint mindepth = 0;
|
||||
|
||||
// find clippingplane
|
||||
GLuint clipdepth = 0; // GLuint(-1);
|
||||
|
||||
for (i = 0; i < hits; i++)
|
||||
{
|
||||
int curname = selbuf[4*i+3];
|
||||
if (!curname) clipdepth = selbuf[4*i+1];
|
||||
}
|
||||
|
||||
for (i = 0; i < hits; i++)
|
||||
{
|
||||
int curname = selbuf[4*i+3];
|
||||
GLuint curdepth = selbuf[4*i+1];
|
||||
|
||||
if (curname && (curdepth > clipdepth) &&
|
||||
(curdepth < mindepth || !minname))
|
||||
{
|
||||
mindepth = curdepth;
|
||||
minname = curname;
|
||||
}
|
||||
}
|
||||
|
||||
seledge = -1;
|
||||
if (minname)
|
||||
{
|
||||
const Element2d & sel = mesh->SurfaceElement(minname);
|
||||
|
||||
|
||||
cout << "select element " << minname
|
||||
<< " on face " << sel.GetIndex() << endl;
|
||||
cout << "Nodes: ";
|
||||
for (i = 1; i <= sel.GetNP(); i++)
|
||||
cout << sel.PNum(i) << " ";
|
||||
cout << endl;
|
||||
|
||||
selelement = minname;
|
||||
selface = mesh->SurfaceElement(minname).GetIndex();
|
||||
|
||||
locpi = (locpi % sel.GetNP()) + 1;
|
||||
selpoint2 = selpoint;
|
||||
selpoint = sel.PNum(locpi);
|
||||
cout << "selected point " << selpoint
|
||||
<< ", pos = " << mesh->Point (selpoint)
|
||||
<< endl;
|
||||
|
||||
for (i = 1; i <= mesh->GetNSeg(); i++)
|
||||
{
|
||||
const Segment & seg = mesh->LineSegment(i);
|
||||
if (seg[0] == selpoint && seg[1] == selpoint2 ||
|
||||
seg[1] == selpoint && seg[0] == selpoint2)
|
||||
{
|
||||
seledge = seg.edgenr;
|
||||
cout << "seledge = " << seledge << endl;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
selface = -1;
|
||||
selelement = -1;
|
||||
selpoint = -1;
|
||||
selpoint2 = -1;
|
||||
}
|
||||
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
|
||||
selecttimestamp = NextTimeStamp();
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void MouseDblClickSelect (const int px, const int py,
|
||||
const GLdouble * clipplane, const GLdouble backcolor,
|
||||
const double * transformationmat,
|
||||
const Point3d & center,
|
||||
const double rad,
|
||||
const int displaylist,
|
||||
int & selelement, int & selface, int & seledge, PointIndex & selpoint,
|
||||
PointIndex & selpoint2, int & locpi)
|
||||
{
|
||||
auto mesh = vsmesh.GetMesh();
|
||||
|
||||
int i, hits;
|
||||
|
||||
// select surface triangle by mouse click
|
||||
|
||||
GLuint selbuf[10000];
|
||||
glSelectBuffer (10000, selbuf);
|
||||
|
||||
|
||||
glRenderMode (GL_SELECT);
|
||||
|
||||
GLint viewport[4];
|
||||
glGetIntegerv (GL_VIEWPORT, viewport);
|
||||
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
|
||||
GLdouble projmat[16];
|
||||
glGetDoublev (GL_PROJECTION_MATRIX, projmat);
|
||||
|
||||
glLoadIdentity();
|
||||
gluPickMatrix (px, viewport[3] - py, 1, 1, viewport);
|
||||
glMultMatrixd (projmat);
|
||||
|
||||
|
||||
|
||||
glClearColor(backcolor, backcolor, backcolor, 1.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
glPushMatrix();
|
||||
glMultMatrixd (transformationmat);
|
||||
|
||||
|
||||
// SetClippingPlane();
|
||||
|
||||
glInitNames();
|
||||
glPushName (1);
|
||||
|
||||
glPolygonOffset (1, 1);
|
||||
glEnable (GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
|
||||
if (vispar.clipping.enable)
|
||||
{
|
||||
glEnable(GL_CLIP_PLANE0);
|
||||
Vec<3> n(clipplane[0], clipplane[1], clipplane[2]);
|
||||
double len = Abs(n);
|
||||
double mu = -clipplane[3] / (len*len);
|
||||
Point<3> p (mu * n);
|
||||
n /= len;
|
||||
Vec<3> t1 = n.GetNormal ();
|
||||
Vec<3> t2 = Cross (n, t1);
|
||||
|
||||
double xi1mid = (center - p) * t1;
|
||||
double xi2mid = (center - p) * t2;
|
||||
|
||||
glLoadName (0);
|
||||
glBegin (GL_QUADS);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid-rad) * t2);
|
||||
glVertex3dv (p + (xi1mid+rad) * t1 + (xi2mid+rad) * t2);
|
||||
glVertex3dv (p + (xi1mid-rad) * t1 + (xi2mid+rad) * t2);
|
||||
glEnd ();
|
||||
}
|
||||
|
||||
// SetClippingPlane();
|
||||
glCallList (displaylist);
|
||||
|
||||
glDisable (GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
glPopName();
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
|
||||
glFlush();
|
||||
|
||||
|
||||
hits = glRenderMode (GL_RENDER);
|
||||
//cout << "hits = " << hits << endl;
|
||||
|
||||
int minname = 0;
|
||||
GLuint mindepth = 0;
|
||||
|
||||
// find clippingplane
|
||||
GLuint clipdepth = 0; // GLuint(-1);
|
||||
|
||||
for (i = 0; i < hits; i++)
|
||||
{
|
||||
int curname = selbuf[4*i+3];
|
||||
if (!curname) clipdepth = selbuf[4*i+1];
|
||||
}
|
||||
|
||||
for (i = 0; i < hits; i++)
|
||||
{
|
||||
int curname = selbuf[4*i+3];
|
||||
GLuint curdepth = selbuf[4*i+1];
|
||||
/*
|
||||
cout << selbuf[4*i] << " " << selbuf[4*i+1] << " "
|
||||
<< selbuf[4*i+2] << " " << selbuf[4*i+3] << endl;
|
||||
*/
|
||||
if (curname && (curdepth > clipdepth) &&
|
||||
(curdepth < mindepth || !minname))
|
||||
{
|
||||
mindepth = curdepth;
|
||||
minname = curname;
|
||||
}
|
||||
}
|
||||
|
||||
seledge = -1;
|
||||
if (minname)
|
||||
{
|
||||
const Element2d & sel = mesh->SurfaceElement(minname);
|
||||
|
||||
selelement = minname;
|
||||
selface = mesh->SurfaceElement(minname).GetIndex();
|
||||
|
||||
locpi = (locpi % sel.GetNP()) + 1;
|
||||
selpoint2 = selpoint;
|
||||
selpoint = sel.PNum(locpi);
|
||||
|
||||
for (i = 1; i <= mesh->GetNSeg(); i++)
|
||||
{
|
||||
const Segment & seg = mesh->LineSegment(i);
|
||||
if ( (seg[0] == selpoint && seg[1] == selpoint2) ||
|
||||
(seg[1] == selpoint && seg[0] == selpoint2) )
|
||||
{
|
||||
seledge = seg.edgenr;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
selface = -1;
|
||||
selelement = -1;
|
||||
selpoint = -1;
|
||||
selpoint2 = -1;
|
||||
}
|
||||
|
||||
glDisable(GL_CLIP_PLANE0);
|
||||
|
||||
|
||||
|
||||
#ifdef PARALLELGL
|
||||
vsmesh.Broadcast ();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void VisualSceneMesh :: SetSelectedFace (int asf)
|
||||
{
|
||||
if(selface != asf)
|
||||
filledlist = 0;
|
||||
selface = asf;
|
||||
selecttimestamp = NextTimeStamp();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4806,91 +4806,79 @@ namespace netgen
|
||||
}
|
||||
};
|
||||
|
||||
// Check if clipping plane is drawn at current mouse cursor position
|
||||
if(dim==3 && clipsolution && vispar.clipping.enable)
|
||||
{
|
||||
GLint viewport[4];
|
||||
GLdouble projection[16];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]);
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
|
||||
|
||||
int hy = viewport[3]-py;
|
||||
|
||||
// manually intersect the view vector with the clipping plane (also working if clipping vectors are shown)
|
||||
Point<3> p_clipping_plane;
|
||||
gluUnProject(px, hy, 1.0, transformationmat, projection, viewport,
|
||||
&p_clipping_plane[0], &p_clipping_plane[1], &p_clipping_plane[2]);
|
||||
|
||||
Point<3> eye;
|
||||
gluUnProject( (viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2,
|
||||
0.0, transformationmat, projection, viewport, &eye[0], &eye[1], &eye[2]);
|
||||
|
||||
Vec<3> n{vispar.clipping.normal};
|
||||
n.Normalize();
|
||||
Vec<3> view = p_clipping_plane-eye;
|
||||
|
||||
// check if we look at the clipping plane from the right direction
|
||||
if(n*view > 1e-8)
|
||||
{
|
||||
double lam = vispar.clipping.dist - Vec<3>{eye}*n;
|
||||
lam /= n*view;
|
||||
p_clipping_plane = eye + lam*view;
|
||||
|
||||
double lami[3];
|
||||
if(auto el3d = mesh->GetElementOfPoint( p_clipping_plane, lami ))
|
||||
{
|
||||
cout << endl << "Selected point " << p_clipping_plane << " on clipping plane" << endl;
|
||||
marker = p_clipping_plane;
|
||||
|
||||
bool have_scal_func = scalfunction!=-1 && soldata[scalfunction]->draw_volume;
|
||||
bool have_vec_func = vecfunction!=-1 && soldata[vecfunction]->draw_volume;
|
||||
|
||||
if(have_scal_func)
|
||||
{
|
||||
auto & sol = *soldata[scalfunction];
|
||||
double val;
|
||||
double imag = 0;
|
||||
int rcomponent = scalcomp;
|
||||
int comp = scalcomp;
|
||||
if(sol.iscomplex && rcomponent != 0)
|
||||
{
|
||||
rcomponent = 2 * ((rcomponent-1)/2) + 1;
|
||||
GetValue(&sol, el3d-1, lami[0], lami[1], lami[2], rcomponent+1,
|
||||
imag);
|
||||
comp = (scalcomp-1)/2 + 1;
|
||||
}
|
||||
GetValue(&sol, el3d-1, lami[0], lami[1], lami[2], rcomponent, val);
|
||||
printScalValue(sol, comp, val, imag, sol.iscomplex && comp > 0);
|
||||
}
|
||||
if(vecfunction!=-1 && soldata[vecfunction]->draw_volume)
|
||||
{
|
||||
auto & sol = *soldata[vecfunction];
|
||||
ArrayMem<double, 10> values(sol.components);
|
||||
GetValues(&sol, el3d-1, lami[0], lami[1], lami[2], &values[0]);
|
||||
printVecValue(sol, values);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no point on clipping plane found -> continue searching for surface element
|
||||
|
||||
Point<3> p;
|
||||
bool found_point = vsmesh.Unproject(px, py, p);
|
||||
bool found_point = vsmesh.SelectSurfaceElement(px, py, p, showclipsolution && clipsolution);
|
||||
if(!found_point)
|
||||
return;
|
||||
|
||||
marker = p;
|
||||
// marker = p;
|
||||
|
||||
if(selelement<=0)
|
||||
return;
|
||||
// found point on clipping plane
|
||||
if(selelement==0)
|
||||
{
|
||||
GLint viewport[4];
|
||||
GLdouble projection[16];
|
||||
glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]);
|
||||
|
||||
glGetIntegerv(GL_VIEWPORT, &viewport[0]);
|
||||
|
||||
Point<3> eye;
|
||||
gluUnProject( (viewport[2]-viewport[0])/2 , (viewport[3]-viewport[1])/2,
|
||||
0.0, transformationmat, projection, viewport, &eye[0], &eye[1], &eye[2]);
|
||||
|
||||
Vec<3> n{vispar.clipping.normal};
|
||||
n.Normalize();
|
||||
Vec<3> view = p-eye;
|
||||
|
||||
// check if we look at the clipping plane from the right direction
|
||||
if(n*view > 1e-8)
|
||||
{
|
||||
double lam = vispar.clipping.dist - Vec<3>{eye}*n;
|
||||
lam /= n*view;
|
||||
p = eye + lam*view;
|
||||
|
||||
double lami[3];
|
||||
if(auto el3d = mesh->GetElementOfPoint( p, lami ))
|
||||
{
|
||||
cout << endl << "Selected point " << p << " on clipping plane" << endl;
|
||||
// marker = p;
|
||||
|
||||
bool have_scal_func = scalfunction!=-1 && soldata[scalfunction]->draw_volume;
|
||||
bool have_vec_func = vecfunction!=-1 && soldata[vecfunction]->draw_volume;
|
||||
|
||||
if(have_scal_func)
|
||||
{
|
||||
auto & sol = *soldata[scalfunction];
|
||||
double val;
|
||||
double imag = 0;
|
||||
int rcomponent = scalcomp;
|
||||
int comp = scalcomp;
|
||||
if(sol.iscomplex && rcomponent != 0)
|
||||
{
|
||||
rcomponent = 2 * ((rcomponent-1)/2) + 1;
|
||||
GetValue(&sol, el3d-1, lami[0], lami[1], lami[2], rcomponent+1,
|
||||
imag);
|
||||
comp = (scalcomp-1)/2 + 1;
|
||||
}
|
||||
GetValue(&sol, el3d-1, lami[0], lami[1], lami[2], rcomponent, val);
|
||||
printScalValue(sol, comp, val, imag, sol.iscomplex && comp > 0);
|
||||
}
|
||||
if(vecfunction!=-1 && soldata[vecfunction]->draw_volume)
|
||||
{
|
||||
auto & sol = *soldata[vecfunction];
|
||||
ArrayMem<double, 10> values(sol.components);
|
||||
GetValues(&sol, el3d-1, lami[0], lami[1], lami[2], &values[0]);
|
||||
printVecValue(sol, values);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double lami[3] = {0.0, 0.0, 0.0};
|
||||
// Check if unprojected Point is close to surface element (eps of 1e-3 due to z-Buffer accuracy)
|
||||
bool found_2del = false;
|
||||
if(mesh->PointContainedIn2DElement(p, lami, selelement, false && fabs(lami[2])<1e-3))
|
||||
if(selelement>0 && mesh->PointContainedIn2DElement(p, lami, selelement, false && fabs(lami[2])<1e-3))
|
||||
{
|
||||
// Found it, use coordinates of point projected to surface element
|
||||
mesh->GetCurvedElements().CalcSurfaceTransformation({1.0-lami[0]-lami[1], lami[0]}, selelement-1, p);
|
||||
|
@ -94,7 +94,6 @@ class NGGUI_API VisualSceneSolution : public VisualScene
|
||||
int fieldlinestimestamp, surface_vector_timestamp;
|
||||
int pointcurve_timestamp;
|
||||
int isosurface_timestamp;
|
||||
int subdivision_timestamp;
|
||||
int timetimestamp;
|
||||
double minval, maxval;
|
||||
|
||||
@ -174,7 +173,6 @@ public:
|
||||
int autoscale, logscale;
|
||||
double mminval, mmaxval;
|
||||
int numisolines;
|
||||
int subdivisions;
|
||||
|
||||
bool showclipsolution;
|
||||
bool showsurfacesolution;
|
||||
|
Loading…
Reference in New Issue
Block a user