Merge branch 'faster_dbl_click' into 'master'

Speed up face/point selection in mesh scene

See merge request ngsolve/netgen!564
This commit is contained in:
Hochsteger, Matthias 2023-04-03 10:17:37 +02:00
commit 9180f9b972
5 changed files with 408 additions and 631 deletions

View File

@ -77,9 +77,11 @@ namespace netgen
int VisualScene :: locpi; int VisualScene :: locpi;
int VisualScene :: seledge; int VisualScene :: seledge;
int VisualScene :: selecttimestamp;
optional<Point<3>> VisualScene :: marker = nullopt; optional<Point<3>> VisualScene :: marker = nullopt;
int VisualScene :: subdivision_timestamp = -1;
int VisualScene :: subdivisions = 2;
int VisualScene :: viewport[4]; int VisualScene :: viewport[4];
VisualizationParameters :: VisualizationParameters() VisualizationParameters :: VisualizationParameters()

View File

@ -31,9 +31,10 @@ namespace netgen
static int locpi; static int locpi;
static int NGGUI_API seledge; static int NGGUI_API seledge;
static int selecttimestamp;
static optional<Point<3>> marker; static optional<Point<3>> marker;
static int subdivision_timestamp;
static int subdivisions;
public: public:
static int viewport[4]; static int viewport[4];
static GLuint coltexname; static GLuint coltexname;
@ -126,35 +127,54 @@ namespace netgen
class VisualSceneMesh : public VisualScene class VisualSceneMesh : public VisualScene
{ {
int filledlist; int filledlist = 0;
int linelist; int linelist = 0;
int edgelist; int edgelist = 0;
int pointnumberlist; int pointnumberlist = 0;
int tetlist; int tetlist = 0;
int prismlist; int prismlist = 0;
int pyramidlist; int pyramidlist = 0;
int hexlist; int hexlist = 0;
int badellist; int badellist = 0;
int identifiedlist; int identifiedlist = 0;
int domainsurflist; int domainsurflist = 0;
int vstimestamp;//, selecttimestamp; int vstimestamp = -1;
int filledtimestamp; int filledtimestamp = -1;
int linetimestamp; int linetimestamp = -1;
int edgetimestamp; int edgetimestamp = -1;
int pointnumbertimestamp; int pointnumbertimestamp = -1;
int tettimestamp; int tettimestamp = -1;
int prismtimestamp; int prismtimestamp = -1;
int pyramidtimestamp; int pyramidtimestamp = -1;
int hextimestamp; int hextimestamp = -1;
int badeltimestamp; int badeltimestamp = -1;
int identifiedtimestamp; int identifiedtimestamp = -1;
int domainsurftimestamp; int domainsurftimestamp = -1;
struct {
unsigned texture = -1;
int width = 0;
int height = 0;
int size = 0;
} colors;
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 #ifdef PARALLELGL
NgArray<int> par_linelists; NgArray<int> par_linelists;
@ -200,7 +220,9 @@ namespace netgen
{ return selelement; } { return selelement; }
NGGUI_API int SelectedPoint () const NGGUI_API int SelectedPoint () const
{ return selpoint; } { return selpoint; }
void BuildFilledList (bool names); void BuildFilledList (bool select);
void BuildColorTexture();
void SelectCenter(int zoomall);
// private: // private:
void BuildLineList(); void BuildLineList();
void BuildEdgeList(); void BuildEdgeList();
@ -215,7 +237,9 @@ namespace netgen
void BuildIdentifiedList(); void BuildIdentifiedList();
void BuildDomainSurfList(); 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; NGGUI_API extern VisualSceneMesh vsmesh;

File diff suppressed because it is too large Load Diff

View File

@ -791,35 +791,7 @@ namespace netgen
if (mesh->GetTimeStamp() > surfeltimestamp || zoomall) if (mesh->GetTimeStamp() > surfeltimestamp || zoomall)
{ {
// mesh has changed // mesh has changed
vsmesh.SelectCenter(zoomall);
Point3d pmin, pmax;
static double oldrad = 0;
mesh->GetBox (pmin, pmax, -1);
if(vispar.use_center_coords && zoomall == 2)
{
center.X() = vispar.centerx;
center.Y() = vispar.centery;
center.Z() = vispar.centerz;
}
else if(selpoint >= 1 && zoomall == 2)
center = mesh->Point(selpoint);
else if(vispar.centerpoint >= 1 && zoomall == 2)
center = mesh->Point(vispar.centerpoint);
else
center = Center (pmin, pmax);
rad = 0.5 * Dist (pmin, pmax);
if(rad == 0) rad = 1e-6;
glEnable (GL_NORMALIZE);
if (rad > 1.2 * oldrad ||
mesh->GetMajorTimeStamp() > surfeltimestamp ||
zoomall)
{
CalcTransformationMatrices();
oldrad = rad;
}
} }
DrawSurfaceElements(); DrawSurfaceElements();
@ -4775,6 +4747,7 @@ namespace netgen
auto printScalValue = [&formatComplex] auto printScalValue = [&formatComplex]
(SolData & sol, int comp, double value, double imag=0., bool iscomplex=false) (SolData & sol, int comp, double value, double imag=0., bool iscomplex=false)
{ {
cout << '\t';
if(sol.components>1) if(sol.components>1)
{ {
if(comp==0) if(comp==0)
@ -4806,91 +4779,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; Point<3> p;
bool found_point = vsmesh.Unproject(px, py, p); bool found_point = vsmesh.SelectSurfaceElement(px, py, p, showclipsolution && clipsolution);
if(!found_point) if(!found_point)
return; return;
marker = p; // marker = p;
if(selelement<=0) // found point on clipping plane
return; 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}; 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) // Check if unprojected Point is close to surface element (eps of 1e-3 due to z-Buffer accuracy)
bool found_2del = false; 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 // Found it, use coordinates of point projected to surface element
mesh->GetCurvedElements().CalcSurfaceTransformation({1.0-lami[0]-lami[1], lami[0]}, selelement-1, p); mesh->GetCurvedElements().CalcSurfaceTransformation({1.0-lami[0]-lami[1], lami[0]}, selelement-1, p);

View File

@ -94,7 +94,6 @@ class NGGUI_API VisualSceneSolution : public VisualScene
int fieldlinestimestamp, surface_vector_timestamp; int fieldlinestimestamp, surface_vector_timestamp;
int pointcurve_timestamp; int pointcurve_timestamp;
int isosurface_timestamp; int isosurface_timestamp;
int subdivision_timestamp;
int timetimestamp; int timetimestamp;
double minval, maxval; double minval, maxval;
@ -174,7 +173,6 @@ public:
int autoscale, logscale; int autoscale, logscale;
double mminval, mmaxval; double mminval, mmaxval;
int numisolines; int numisolines;
int subdivisions;
bool showclipsolution; bool showclipsolution;
bool showsurfacesolution; bool showsurfacesolution;