Skip to content

Commit 4ef1e31

Browse files
committed
Refactor
1 parent b5ecaab commit 4ef1e31

File tree

5 files changed

+234
-62
lines changed

5 files changed

+234
-62
lines changed

src/Core/Python/PythonDatatypeConverter.cc

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,60 @@
3535
#endif
3636

3737
#include <Core/Python/PythonDatatypeConverter.h>
38+
#include <Core/Datatypes/SparseRowMatrix.h>
39+
#include <Core/Datatypes/DenseMatrix.h>
40+
#include <Core/Datatypes/String.h>
3841
#include <Core/Matlab/matlabarray.h>
3942
#include <Core/Matlab/matlabconverter.h>
4043

4144
using namespace SCIRun;
4245
using namespace SCIRun::Core::Python;
46+
using namespace SCIRun::Core::Datatypes;
4347
using namespace SCIRun::MatlabIO;
4448

45-
boost::python::object SCIRun::Core::Python::convertField(FieldHandle field)
49+
namespace
50+
{
51+
template <class T>
52+
boost::python::list toPythonList(const DenseMatrixGeneric<T>& dense)
53+
{
54+
boost::python::list list;
55+
for (int i = 0; i < dense.nrows(); ++i)
56+
{
57+
boost::python::list row;
58+
for (int j = 0; j < dense.ncols(); ++j)
59+
row.append(dense(i, j));
60+
list.append(row);
61+
}
62+
return list;
63+
}
64+
65+
template <class T>
66+
boost::python::list toPythonList(const SparseRowMatrixGeneric<T>& sparse)
67+
{
68+
boost::python::list rows, columns, values;
69+
70+
for (int i = 0; i < sparse.nonZeros(); ++i)
71+
{
72+
values.append(sparse.valuePtr()[i]);
73+
}
74+
for (int i = 0; i < sparse.nonZeros(); ++i)
75+
{
76+
columns.append(sparse.innerIndexPtr()[i]);
77+
}
78+
for (int i = 0; i < sparse.outerSize(); ++i)
79+
{
80+
rows.append(sparse.outerIndexPtr()[i]);
81+
}
82+
83+
boost::python::list list;
84+
list.append(rows);
85+
list.append(columns);
86+
list.append(values);
87+
return list;
88+
}
89+
}
90+
91+
boost::python::object SCIRun::Core::Python::convertFieldToPython(FieldHandle field)
4692
{
4793
matlabarray ma;
4894
matlabconverter mc(nullptr);
@@ -79,7 +125,29 @@ boost::python::object SCIRun::Core::Python::convertField(FieldHandle field)
79125
return matlabStructure;
80126
}
81127

128+
boost::python::object SCIRun::Core::Python::convertMatrixToPython(DenseMatrixHandle matrix)
129+
{
130+
if (matrix)
131+
return ::toPythonList(*matrix);
132+
return {};
133+
}
82134

135+
boost::python::object SCIRun::Core::Python::convertMatrixToPython(SparseRowMatrixHandle matrix)
136+
{
137+
if (matrix)
138+
return ::toPythonList(*matrix);
139+
return {};
140+
}
141+
142+
boost::python::object SCIRun::Core::Python::convertStringToPython(StringHandle str)
143+
{
144+
if (str)
145+
{
146+
boost::python::object obj(std::string(str->value()));
147+
return obj;
148+
}
149+
return {};
150+
}
83151

84152

85153

src/Core/Python/PythonDatatypeConverter.h

Lines changed: 12 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
#define CORE_PYTHON_PYTHONDATATYPECONVERTER_H
3232

3333
#include <boost/python.hpp>
34+
#include <boost/python/stl_iterator.hpp>
3435
#include <boost/shared_ptr.hpp>
35-
#include <Core/Datatypes/DenseMatrix.h>
36-
#include <Core/Datatypes/SparseRowMatrix.h>
36+
#include <vector>
37+
#include <Core/Datatypes/DatatypeFwd.h>
38+
3739

3840
#include <Core/Python/share.h>
3941

@@ -69,46 +71,18 @@ namespace SCIRun
6971
return list;
7072
}
7173

72-
template <class T>
73-
boost::python::list toPythonList(const Datatypes::DenseMatrixGeneric<T>& dense)
74+
template< typename T >
75+
std::vector< T > to_std_vector(const boost::python::object& iterable)
7476
{
75-
boost::python::list list;
76-
for (int i = 0; i < dense.nrows(); ++i)
77-
{
78-
boost::python::list row;
79-
for (int j = 0; j < dense.ncols(); ++j)
80-
row.append(dense(i, j));
81-
list.append(row);
82-
}
83-
return list;
77+
return std::vector< T >(boost::python::stl_input_iterator< T >(iterable),
78+
boost::python::stl_input_iterator< T >());
8479
}
8580

86-
template <class T>
87-
boost::python::list toPythonList(const Datatypes::SparseRowMatrixGeneric<T>& sparse)
88-
{
89-
boost::python::list rows, columns, values;
90-
91-
for (int i = 0; i < sparse.nonZeros(); ++i)
92-
{
93-
values.append(sparse.valuePtr()[i]);
94-
}
95-
for (int i = 0; i < sparse.nonZeros(); ++i)
96-
{
97-
columns.append(sparse.innerIndexPtr()[i]);
98-
}
99-
for (int i = 0; i < sparse.outerSize(); ++i)
100-
{
101-
rows.append(sparse.outerIndexPtr()[i]);
102-
}
103-
104-
boost::python::list list;
105-
list.append(rows);
106-
list.append(columns);
107-
list.append(values);
108-
return list;
109-
}
11081

111-
SCISHARE boost::python::object convertField(FieldHandle field);
82+
SCISHARE boost::python::object convertFieldToPython(FieldHandle field);
83+
SCISHARE boost::python::object convertMatrixToPython(Datatypes::DenseMatrixHandle matrix);
84+
SCISHARE boost::python::object convertMatrixToPython(Datatypes::SparseRowMatrixHandle matrix);
85+
SCISHARE boost::python::object convertStringToPython(Datatypes::StringHandle str);
11286
}
11387
}
11488
}

src/Dataflow/Engine/Controller/PythonImpl.cc

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ namespace
6565
class PyDatatypeString : public PyDatatype
6666
{
6767
public:
68-
explicit PyDatatypeString(StringHandle underlying) : underlying_(underlying)
68+
explicit PyDatatypeString(StringHandle underlying) : underlying_(underlying), str_(convertStringToPython(underlying))
6969
{
7070
}
7171

@@ -76,18 +76,18 @@ namespace
7676

7777
virtual boost::python::object value() const override
7878
{
79-
boost::python::object str(std::string(underlying_->value()));
80-
return str;
79+
return str_;
8180
}
8281

8382
private:
8483
StringHandle underlying_;
84+
boost::python::object str_;
8585
};
8686

8787
class PyDatatypeDenseMatrix : public PyDatatype
8888
{
8989
public:
90-
explicit PyDatatypeDenseMatrix(DenseMatrixHandle underlying) : underlying_(underlying)
90+
explicit PyDatatypeDenseMatrix(DenseMatrixHandle underlying) : underlying_(underlying), pyMat_(convertMatrixToPython(underlying))
9191
{
9292
}
9393

@@ -98,17 +98,18 @@ namespace
9898

9999
virtual boost::python::object value() const override
100100
{
101-
return toPythonList(*underlying_);
101+
return pyMat_;
102102
}
103103

104104
private:
105105
DenseMatrixHandle underlying_;
106+
boost::python::list pyMat_;
106107
};
107108

108109
class PyDatatypeSparseRowMatrix : public PyDatatype
109110
{
110111
public:
111-
explicit PyDatatypeSparseRowMatrix(SparseRowMatrixHandle underlying) : underlying_(underlying)
112+
explicit PyDatatypeSparseRowMatrix(SparseRowMatrixHandle underlying) : underlying_(underlying), pyMat_(convertMatrixToPython(underlying))
112113
{
113114
}
114115

@@ -119,17 +120,18 @@ namespace
119120

120121
virtual boost::python::object value() const override
121122
{
122-
return toPythonList(*underlying_);
123+
return pyMat_;
123124
}
124125

125126
private:
126127
SparseRowMatrixHandle underlying_;
128+
boost::python::list pyMat_;
127129
};
128130

129131
class PyDatatypeField : public PyDatatype
130132
{
131133
public:
132-
explicit PyDatatypeField(FieldHandle underlying) : underlying_(underlying), matlabStructure_(convertField(underlying))
134+
explicit PyDatatypeField(FieldHandle underlying) : underlying_(underlying), matlabStructure_(convertFieldToPython(underlying))
133135
{
134136
}
135137

@@ -422,11 +424,11 @@ namespace
422424
{
423425
throw std::invalid_argument("Module state key " + name + " not defined.");
424426
}
425-
state->setValue(apn, convert(object));
427+
state->setValue(apn, convert<AlgorithmParameter::Value>(object));
426428
}
427429
else
428430
{
429-
state->setTransientValue(apn, convert(object), false);
431+
state->setTransientValue(apn, convert<boost::any>(object), false);
430432
}
431433
}
432434
}
@@ -474,44 +476,47 @@ namespace
474476
boost::shared_ptr<PyPortsImpl> input_, output_;
475477

476478
//TODO: extract and use for state get/set
477-
AlgorithmParameter::Value convert(const boost::python::object& object) const
479+
template <class ReturnType>
480+
ReturnType convert(const boost::python::object& object) const
478481
{
479-
AlgorithmParameter::Value value;
480-
481482
/// @todo: yucky
482483
{
483484
boost::python::extract<int> e(object);
484485
if (e.check())
485486
{
486-
value = e();
487-
return value;
487+
return e();
488488
}
489489
}
490490
{
491491
boost::python::extract<double> e(object);
492492
if (e.check())
493493
{
494-
value = e();
495-
return value;
494+
return e();
496495
}
497496
}
498497
{
499498
boost::python::extract<std::string> e(object);
500499
if (e.check())
501500
{
502-
value = e();
503-
return value;
501+
return e();
504502
}
505503
}
506504
{
507505
boost::python::extract<bool> e(object);
508506
if (e.check())
509507
{
510-
value = e();
511-
return value;
508+
return e();
512509
}
513510
}
514-
return value;
511+
//{
512+
// auto vec = to_std_vector<double>(object);
513+
// if (!vec.empty())
514+
// {
515+
// return vec;
516+
// }
517+
//}
518+
std::cerr << "No known conversion from python object to C++ object" << std::endl;
519+
return ReturnType();
515520
}
516521
};
517522
}

0 commit comments

Comments
 (0)