Commit 4c945fcf authored by bonnell's avatar bonnell
Browse files

Add ability for Picks to be called with keyword arguments. Fix Pick and Query logging.

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@16108 18c085ea-50e0-402c-830e-de6fd14e8384
parent 37423f01
......@@ -2583,14 +2583,14 @@ Variant::Read(Connection &conn)
// Kathleen Biagas, Thu Sep 1 11:19:23 PDT 2011
// Fix typo (two FLOAT_VECTOR_TYPES if statements).
//
// Kathleen Biagas, Tue Sep 6 14:06:24 PDT 2011
// Fix formatting of vectors, strings should be surrounded by quotes.
//
// ****************************************************************************
string &
Variant::ConvertToString()
{
if(dataType == STRING_TYPE)
return *((string *)dataValue);
tmp.clear();
char retval[5000];
if (dataType == BOOL_TYPE)
......@@ -2600,7 +2600,7 @@ Variant::ConvertToString()
}
else if (dataType == CHAR_TYPE)
{
sprintf(retval, "%c", AsChar());
sprintf(retval, "\'%c\'", AsChar());
tmp = string(retval);
}
else if (dataType == UNSIGNED_CHAR_TYPE)
......@@ -2628,13 +2628,20 @@ Variant::ConvertToString()
sprintf(retval, "%g", AsDouble());
tmp = string(retval);
}
else if (dataType == STRING_TYPE)
{
sprintf(retval, "\"%s\"", AsString().c_str());
tmp = string(retval);
}
else if (dataType == BOOL_VECTOR_TYPE)
{
tmp = "(";
const boolVector &vec = AsBoolVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%s ",vec[i] ? "true" : "false");
if (i != 0)
tmp += ", ";
sprintf(retval,"%s",vec[i] ? "true" : "false");
tmp += retval;
}
tmp += ")";
......@@ -2645,7 +2652,9 @@ Variant::ConvertToString()
const charVector &vec = AsCharVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%c ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"\'%c\'",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2656,7 +2665,9 @@ Variant::ConvertToString()
const unsignedCharVector &vec = AsUnsignedCharVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%d ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"%d",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2667,7 +2678,9 @@ Variant::ConvertToString()
const intVector &vec = AsIntVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%d ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"%d",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2678,7 +2691,9 @@ Variant::ConvertToString()
const longVector &vec = AsLongVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%ld ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"%ld",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2689,7 +2704,9 @@ Variant::ConvertToString()
const floatVector &vec = AsFloatVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%g ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"%g",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2700,7 +2717,9 @@ Variant::ConvertToString()
const doubleVector &vec = AsDoubleVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%g ",vec[i]);
if (i != 0)
tmp += ", ";
sprintf(retval,"%g",vec[i]);
tmp += retval;
}
tmp += ")";
......@@ -2711,7 +2730,9 @@ Variant::ConvertToString()
const stringVector &vec = AsStringVector();
for(size_t i=0;i<vec.size();i++)
{
sprintf(retval,"%s ",vec[i].c_str());
if (i != 0)
tmp += ", ";
sprintf(retval,"\"%s\"",vec[i].c_str());
tmp += retval;
}
tmp += ")";
......
......@@ -450,7 +450,7 @@ QvisPickQueryWidget::GetQueryParameters(MapNode &params)
doubleVector p(3);
bool noerrors = true;
int curvePlotType = GetPlotType();
bool preserveCoord = GetTimePreservesCoord();
int preserveCoord = (int) GetTimePreservesCoord();
int dom = 0, el = 0;
switch (pickType->currentIndex())
{
......
......@@ -287,7 +287,9 @@ QvisXRayImageQueryWidget::GetIntValues(int whichWidget, int *pt)
// Creation: June 17, 2011
//
// Modifications:
//
// Kathleen Biagas, Wed Sep 7 08:40:22 PDT 2011
// Return output_type as string instead of int.
//
// ****************************************************************************
bool
QvisXRayImageQueryWidget::GetQueryParameters(MapNode &params)
......@@ -318,7 +320,7 @@ QvisXRayImageQueryWidget::GetQueryParameters(MapNode &params)
if (noerrors)
{
params["output_type"] = imageFormat->currentIndex();
params["output_type"] = imageFormat->currentText().toStdString();
params["divide_emis_by_absorb"] = (int)divideFlag->isChecked();
params["origin"] = origin;
params["theta"] = t;
......
......@@ -3185,6 +3185,9 @@ ViewerQueryManager::HandlePickCache()
// Modifications notes to last couple of years. Move test for non-hidden
// active plot and running engine to generic 'Query' method.
//
// Kathleen Biagas, Wed Sep 7 11:11:19 PDT 2011
// coord argument may be an intVector or a doubleVector.
//
// ****************************************************************************
void
......@@ -3252,13 +3255,25 @@ ViewerQueryManager::PointQuery(const MapNode &queryParams)
Error(tr("%1 requires a 'coord' parameter.\n").arg(qName.c_str()));
return;
}
doubleVector pt = queryParams.GetEntry("coord")->AsDoubleVector();
PICK_POINT_INFO ppi;
ppi.callbackData = win;
ppi.rayPt1[0] = ppi.rayPt2[0] = pt[0];
ppi.rayPt1[1] = ppi.rayPt2[1] = pt[1];
ppi.rayPt1[2] = ppi.rayPt2[2] = pt[2];
ppi.validPick = true;
if (queryParams.GetEntry("coord")->TypeName() == "doubleVector")
{
doubleVector pt = queryParams.GetEntry("coord")->AsDoubleVector();
ppi.rayPt1[0] = ppi.rayPt2[0] = pt[0];
ppi.rayPt1[1] = ppi.rayPt2[1] = pt[1];
ppi.rayPt1[2] = ppi.rayPt2[2] = pt[2];
ppi.validPick = true;
}
else if (queryParams.GetEntry("coord")->TypeName() == "intVector")
{
intVector pt = queryParams.GetEntry("coord")->AsIntVector();
ppi.rayPt1[0] = ppi.rayPt2[0] = (double)pt[0];
ppi.rayPt1[1] = ppi.rayPt2[1] = (double)pt[1];
ppi.rayPt1[2] = ppi.rayPt2[2] = (double)pt[2];
ppi.validPick = true;
}
if (!timeCurve)
{
Pick(&ppi);
......
......@@ -1263,6 +1263,14 @@ static std::string log_SetRenderingAttributesRPC(ViewerRPC *rpc)
return s;
}
//*****************************************************************************
// Modifications:
// Kathleen Biagas, Wed Sep 7 12:53:16 PDT 2011
// Fix pick logging, vars logging.
//
//*****************************************************************************
static std::string log_QueryRPC(ViewerRPC *rpc)
{
std::vector<std::string> paramNames;
......@@ -1280,14 +1288,15 @@ static std::string log_QueryRPC(ViewerRPC *rpc)
{
std::string pt;
std::string qn;
bool timePick = false;
if (queryParams.HasEntry("do_time"))
timePick = (bool)queryParams.GetEntry("do_time")->AsInt();
if (queryParams.HasEntry("pick_type"))
pt = queryParams.GetEntry("pick_type")->AsString();
if (pt == "ScreenZone" || pt == "Zone")
qn = "ZonePick";
else if (pt == "ScreenNode" || pt == "Node")
qn = "NodePick";
else if (pt == "DomainZone")
qn = "PickByZone";
else if (pt == "DomainZone")
{
int global = 0;
......@@ -1311,31 +1320,37 @@ static std::string log_QueryRPC(ViewerRPC *rpc)
else
return MESSAGE_COMMENT("Pick with no type", MSG_UNSUPPORTED);
s = qn + "(";
int numPrinted = 0;
for (size_t i = 0; i < paramNames.size(); ++i)
{
if ((paramNames[i] == "curve_plot_type" ||
paramNames[i] == "preserve_coord") &&
!timePick)
continue;
if (paramNames[i] != "query_name" &&
paramNames[i] != "query_type" &&
paramNames[i] != "pick_type" &&
paramNames[i] != "use_global_id" &&
paramNames[i] != "vars")
{
s += ", ";
if (numPrinted > 0)
s += ", ";
s += paramNames[i];
s += "=";
s += queryParams.GetEntry(paramNames[i])->ConvertToString();
numPrinted++;
}
}
std::vector<std::string> vars;
if (queryParams.HasEntry("vars"))
queryParams.GetEntry("vars")->AsStringVector();
vars = queryParams.GetEntry("vars")->AsStringVector();
if (!vars.empty() && !(vars.size() == 1 && vars[0] == "default"))
{
s += "\"vars=(";
for (size_t i = 0; i < vars.size(); ++i)
{
s += vars[i];
s += ",";
}
s += ")";
if (numPrinted > 0)
s += ", ";
s += "vars=";
s += queryParams.GetEntry("vars")->ConvertToString();
}
s += ")\n";
}
......@@ -1372,16 +1387,11 @@ static std::string log_QueryRPC(ViewerRPC *rpc)
}
std::vector<std::string> vars;
if (queryParams.HasEntry("vars"))
queryParams.GetEntry("vars")->AsStringVector();
vars = queryParams.GetEntry("vars")->AsStringVector();
if (!vars.empty() && !(vars.size() == 1 && vars[0] == "default"))
{
s += "\"vars=(";
for (size_t i = 0; i < vars.size(); ++i)
{
s += vars[i];
s += ",";
}
s += ")";
s += ", vars=";
s += queryParams.GetEntry("vars")->ConvertToString();
}
s += ")\n";
......
......@@ -113,6 +113,10 @@ PyMapNode_Wrap(const MapNode &node)
// Programmer: Kathleen Bonnell
// Creation: July 13, 2011
//
// Modifications:
// Kathleen Biagas, Wed Sep 7 11:56:23 PDT 2011
// Allow ints and doubles in same sequence.
//
// ****************************************************************************
bool
......@@ -162,20 +166,49 @@ PyDict_To_MapNode(PyObject *obj, MapNode &mn)
}
else if (PyInt_Check(item))
{
intVector mval;
mval.push_back(PyInt_AS_LONG(item));
int ni = 1, nd = 0, no = 0;
for (Py_ssize_t i = 1; i < PySequence_Size(value); ++i)
{
item = PySequence_GetItem(value, i);
if (!PyInt_Check(item))
if (PyFloat_Check(item))
nd++;
else if (PyInt_Check(item))
ni++;
else
no++;
}
if (no != 0)
{
debug3 << "PyDict_To_MapNode: tuples/lists must "
<< "contain same type." << endl;
return false;
}
else if (nd != 0)
{
// process as doubleVector
doubleVector mval;
mval.push_back((double)PyInt_AS_LONG(item));
for (Py_ssize_t i = 1; i < PySequence_Size(value); ++i)
{
debug3 << "PyDict_To_MapNode: tuples/lists must "
<< "contain same type." << endl;
return false;
item = PySequence_GetItem(value, i);
if (PyFloat_Check(item))
mval.push_back(PyFloat_AS_DOUBLE(item));
else if (PyInt_Check(item))
mval.push_back((double)PyInt_AS_LONG(item));
}
mval.push_back(PyInt_AS_LONG(item));
mn[mkey] = mval;
}
mn[mkey] = mval;
else
{
intVector mval;
mval.push_back(PyInt_AS_LONG(item));
for (Py_ssize_t i = 1; i < PySequence_Size(value); ++i)
{
item = PySequence_GetItem(value, i);
mval.push_back(PyInt_AS_LONG(item));
}
mn[mkey] = mval;
}
}
else if (PyString_Check(item))
{
......
......@@ -10867,7 +10867,6 @@ visit_Query_deprecated(PyObject *self, PyObject *args)
}
}
if(!parse_success)
{
PyErr_Clear();
......@@ -10964,6 +10963,10 @@ visit_Query_deprecated(PyObject *self, PyObject *args)
// Programmer: Kathleen Bonnell
// Creation: July 15, 2011
//
// Modifications:
// Kathleen Biagas, Wed Sep 7 12:46:24 PDT 2011
// Use VisItErrorFunc instead of cerr.
//
// ****************************************************************************
STATIC PyObject *
......@@ -10978,13 +10981,13 @@ visit_Query(PyObject *self, PyObject *args, PyObject *kwargs)
if (args == NULL)
{
cerr << "Query requires at least one argument: the query name." << endl;
VisItErrorFunc("Query requires at least one argument: the query name.");
return NULL;
}
if (!(PyString_Check(PyTuple_GetItem(args, 0))))
{
cerr << "Query requires first argument to be the query name." << endl;
VisItErrorFunc("Query requires first argument to be the query name.");
return NULL;
}
queryName = PyString_AS_STRING(PyTuple_GetItem(args, 0));
......@@ -11004,7 +11007,7 @@ visit_Query(PyObject *self, PyObject *args, PyObject *kwargs)
parse_success = PyDict_To_MapNode(PyTuple_GetItem(args,1), queryParams);
if (!parse_success)
{
debug3 << "Query, dictionary second argument not parseable " << endl;
VisItErrorFunc("Query: could not parse dictionary argument.");
return NULL;
}
}
......@@ -11013,7 +11016,7 @@ visit_Query(PyObject *self, PyObject *args, PyObject *kwargs)
parse_success = PyDict_To_MapNode(kwargs, queryParams);
if (!parse_success)
{
debug3 << "Query, keyword args present, but un parseable." << endl;
VisItErrorFunc(" Query: could not parse keyword args.");
return NULL;
}
}
......@@ -11047,8 +11050,6 @@ visit_Query(PyObject *self, PyObject *args, PyObject *kwargs)
}
// ****************************************************************************
// Function: visit_PythonQuery
//
......@@ -11523,13 +11524,13 @@ visit_QueryOverTime(PyObject *self, PyObject *args, PyObject *kwargs)
if (args == NULL)
{
cerr << mn << "requires at least one argument: the query name." << endl;
VisItErrorFunc("QueryOverTime: requires at least one argument, the query name.");
return NULL;
}
if (!(PyString_Check(PyTuple_GetItem(args, 0))))
{
cerr << mn << "requires first argument to be the query name." << endl;
VisItErrorFunc("QueryOverTime: requires first argument to be the query name.");
return NULL;
}
queryName = PyString_AS_STRING(PyTuple_GetItem(args, 0));
......@@ -11549,8 +11550,8 @@ visit_QueryOverTime(PyObject *self, PyObject *args, PyObject *kwargs)
parse_success = PyDict_To_MapNode(PyTuple_GetItem(args,1), queryParams);
if (!parse_success)
{
debug3 << mn << "dictionary second argument not parseable " << endl;
return NULL;
VisItErrorFunc("QueryOverTime: could not parse dictionary argument.");
return NULL;
}
}
else if (kwargs != NULL)
......@@ -11558,8 +11559,8 @@ visit_QueryOverTime(PyObject *self, PyObject *args, PyObject *kwargs)
parse_success = PyDict_To_MapNode(kwargs, queryParams);
if (!parse_success)
{
debug3 << mn << ", keyword args present, but unparseable." << endl;
return NULL;
VisItErrorFunc("QueryOverTime: could not parse keyword arguments.");
return NULL;
}
}
......@@ -11577,7 +11578,7 @@ visit_QueryOverTime(PyObject *self, PyObject *args, PyObject *kwargs)
// ****************************************************************************
// Function: visit_ZonePick
// Function: visit_ZonePick_deprecated
//
// Purpose:
// Tells the viewer to do pick.
......@@ -11615,10 +11616,14 @@ visit_QueryOverTime(PyObject *self, PyObject *args, PyObject *kwargs)
// Kathleen Biagas, Tue Jul 19 12:00:04 PDT 2011
// Send args as MapNode to new ViewerMethod 'Query'.
//
// Kathleen Biagas, Wed Sep 7 07:39:35 PDT 2011
// Made this a deprecated method, in favor of one that uses
// python dictionary and/or named arguments.
//
// ****************************************************************************
STATIC PyObject *
visit_ZonePick(PyObject *self, PyObject *args)
visit_ZonePick_deprecated(PyObject *self, PyObject *args)
{
ENSURE_VIEWER_EXISTS();
......@@ -11689,7 +11694,79 @@ visit_ZonePick(PyObject *self, PyObject *args)
// ****************************************************************************
// Function: visit_NodePick
// Function: visit_ZonePick
//
// Purpose:
// Tells the viewer to do ZonePick.
//
// Notes:
//
// Programmer: Kathleen Biagas
// Creation: September 7, 2011
//
// ****************************************************************************
STATIC PyObject *
visit_ZonePick(PyObject *self, PyObject *args, PyObject *kwargs)
{
ENSURE_VIEWER_EXISTS();
bool parse_success = true;
MapNode pickParams;
// parse arguments. First check if first arg (if present) is
// a python dictionary object
// If not, check for named args (kwargs).
if (PyTuple_Size(args) > 0)
{
if (!(PyDict_Check(PyTuple_GetItem(args, 0))))
{
debug3 << "Pick first argument not a Python dictionary." << endl;
debug3 << " attempting old parsing methodology." << endl;
return visit_ZonePick_deprecated(self, args);
}
parse_success = PyDict_To_MapNode(PyTuple_GetItem(args,0), pickParams);
if (!parse_success)
{
VisItErrorFunc("ZonePick: could not parse dictionary argument.");
return NULL;
}
}
else if (kwargs != NULL)
{
parse_success = PyDict_To_MapNode(kwargs, pickParams);
if (!parse_success)
{
VisItErrorFunc("ZonePick: could not parse keyword arguments.");
return NULL;
}
}
if (pickParams.HasEntry("coord"))
{
pickParams["pick_type"] = std::string("Zone");
}
else if (pickParams.HasEntry("x") && pickParams.HasEntry("y"))
{
pickParams["pick_type"] = std::string("ScreenZone");
}
else
{
VisItErrorFunc("ZonePick: requires \"coord\" argument.");
return NULL;
}
pickParams["query_name"] = std::string("Pick");
MUTEX_LOCK();
GetViewerMethods()->Query(pickParams);
MUTEX_UNLOCK();
// Return the success value.
return IntReturnValue(Synchronize());
}
// ****************************************************************************
// Function: visit_NodePick_deprecated
//
// Purpose:
// Tells the viewer to do NodePick.
......@@ -11718,10 +11795,14 @@ visit_ZonePick(PyObject *self, PyObject *args)
// Kathleen Biagas, Tue Jul 19 12:00:04 PDT 2011
// Send args as MapNode to new ViewerMethod 'Query'.
//
// Kathleen Biagas, Wed Sep 7 07:39:35 PDT 2011
// Made this a deprecated method, in favor of one that uses
// python dictionary and/or named arguments.
//
// ****************************************************************************
STATIC PyObject *
visit_NodePick(PyObject *self, PyObject *args)
visit_NodePick_deprecated(PyObject *self, PyObject *args)
{
ENSURE_VIEWER_EXISTS();
......@@ -11788,6 +11869,77 @@ visit_NodePick(PyObject *self, PyObject *args)
return IntReturnValue(Synchronize());
}
// ****************************************************************************
// Function: visit_NodePick
//
// Purpose:
// Tells the viewer to do NodePick.
//
// Notes:
//
// Programmer: Kathleen Biagas
// Creation: September 7, 2011
//
// ****************************************************************************
STATIC PyObject *
visit_NodePick(PyObject *self, PyObject *args, PyObject *kwargs)
{
ENSURE_VIEWER_EXISTS();
bool parse_success = true;
MapNode pickParams;
// parse arguments. First check if first arg (if present) is
// a python dictionary object
// If not, check for named args (kwargs).
if (PyTuple_Size(args) > 0)
{
if (!(PyDict_Check(PyTuple_GetItem(args, 0))))
{
debug3 << "Pick first argument not a Python dictionary." << endl;
debug3 << " attempting old parsing methodology." << endl;
return visit_NodePick_deprecated(self, args);
}
parse_success = PyDict_To_MapNode(PyTuple_GetItem(args,0), pickParams);
if (!parse_success)
{
VisItErrorFunc("NodePick: could not parse dictionary argument.");
return NULL;
}
}
else if (kwargs != NULL)
{
parse_success = PyDict_To_MapNode(kwargs, pickParams);
if (!parse_success)
{
VisItErrorFunc("NodePick: could not parse keyword arguments.");