Skip to content

Commit

Permalink
working filters.matlab
Browse files Browse the repository at this point in the history
  • Loading branch information
hobu committed Jun 27, 2017
1 parent f72bdb1 commit 95b81b3
Show file tree
Hide file tree
Showing 9 changed files with 554 additions and 93 deletions.
30 changes: 23 additions & 7 deletions plugins/matlab/CMakeLists.txt
Expand Up @@ -7,24 +7,37 @@ set(MLANG ./filters/Environment.cpp

PDAL_ADD_PLUGIN(libname writer matlab
FILES
${MLANG}
./filters/Script.cpp
io/MatlabWriter.cpp
LINK_WITH
${MATLAB_ENG_LIBRARY} ${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY}
${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY}
)
target_include_directories(${libname} PRIVATE
${MATLAB_INCLUDE_DIR})

target_compile_definitions(${libname} PRIVATE -DHAVE_MATLAB=1)
target_include_directories(${libname} PRIVATE ${MATLAB_INCLUDE_DIR})

PDAL_ADD_PLUGIN(libname_reader reader matlab
FILES
./filters/Script.cpp
io/MatlabReader.cpp
LINK_WITH
${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY}
)
target_include_directories(${libname_reader} PRIVATE
${MATLAB_INCLUDE_DIR})

target_compile_definitions(${libname_reader} PRIVATE -DHAVE_MATLAB=1)
target_include_directories(${libname_reader} PRIVATE ${MATLAB_INCLUDE_DIR})




PDAL_ADD_PLUGIN(matlab_libname filter matlab
FILES
${MLANG}
./filters/Environment.cpp
./filters/Script.cpp
./filters/MatlabFilter.cpp
LINK_WITH
${MATLAB_ENG_LIBRARY} ${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY}
Expand All @@ -37,18 +50,21 @@ if (WITH_TESTS)
FILES
test/MatlabWriterTest.cpp
LINK_WITH
${MATLAB_ENG_LIBRARY} ${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY} ${libname}
${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY} ${libname}
)
target_include_directories(matlabtest PRIVATE
${PDAL_IO_DIR}
${MATLAB_INCLUDE_DIR})


PDAL_ADD_TEST(mlangtest
FILES ${MLANG} ./test/MLangTest.cpp
PDAL_ADD_TEST(pdal_filters_matlab_test
FILES
./filters/Script.cpp
./filters/Environment.cpp
./test/MatlabFilterTest.cpp
LINK_WITH ${MATLAB_ENG_LIBRARY} ${MATLAB_MX_LIBRARY} ${MATLAB_MAT_LIBRARY}
)
target_include_directories(mlangtest PRIVATE
target_include_directories(pdal_filters_matlab_test PRIVATE
${ROOT_DIR} ${MATLAB_INCLUDE_DIR})
endif()

54 changes: 36 additions & 18 deletions plugins/matlab/filters/MatlabFilter.cpp
Expand Up @@ -100,7 +100,8 @@ PointViewSet MatlabFilter::run(PointViewPtr view)
engOutputBuffer(engine, m_MatlabOutputBuffer.get(), logBufferSize);

Dimension::IdList dims;
mxArray* matlabData = mlang::Script::setMatlabStruct(view, dims);

mxArray* matlabData = mlang::Script::setMatlabStruct(view, dims, log());
if (engPutVariable(engine, "PDAL", matlabData))
{
throwError("Could not push PDAL struct to Matlab");
Expand All @@ -111,27 +112,44 @@ PointViewSet MatlabFilter::run(PointViewPtr view)
std::string noise(m_MatlabOutputBuffer.get(), strlen(m_MatlabOutputBuffer.get()));
log()->get(LogLevel::Debug) << "filters.matlab " << noise << std::endl;

matlabData = engGetVariable(engine, "PDAL");
if (!matlabData)
throwError("No 'PDAL' variable is available in Matlab scope!");

PointViewSet viewSet;

// if (m_pythonMethod->hasOutputVariable("Mask"))
// {
// PointViewPtr outview = view->makeNew();
//
// void *pydata =
// m_pythonMethod->extractResult("Mask", Dimension::Type::Unsigned8);
// char *ok = (char *)pydata;
// for (PointId idx = 0; idx < view->size(); ++idx)
// if (*ok++)
// outview->appendPoint(*view, idx);
//
// viewSet.insert(outview);
// }
// else
// {
// m_pythonMethod->end(*view, getMetadata());
std::string logicalDimensionName = m_script.getLogicalMask(matlabData, log());
if (logicalDimensionName.size())
{
PointViewPtr outview = view->makeNew();

mxArray* f = mxGetField(matlabData, 0, logicalDimensionName.c_str());
if (!f)
{
std::ostringstream oss;
oss << "Unable to fetch mask dimension '" << logicalDimensionName << "'";
throwError(oss.str());
}

mxLogical* logical = mxGetLogicals(f);
if (!logical)
{
std::ostringstream oss;
oss << "Unable to fetch logical mask for dimension '" << logicalDimensionName << "'";
throwError(oss.str());
}

char *ok = (char *)logical;
for (PointId idx = 0; idx < view->size(); ++idx)
if (*ok++)
outview->appendPoint(*view, idx);
viewSet.insert(outview);
}
else
{
mlang::Script::getMatlabStruct(matlabData, view, dims, log());
viewSet.insert(view);
// }
}

return viewSet;

Expand Down
65 changes: 59 additions & 6 deletions plugins/matlab/filters/Script.cpp
Expand Up @@ -49,15 +49,36 @@ std::ostream& operator << (std::ostream& os, Script const& script)
return os;
}

void Script::getMatlabStruct(mxArray* array, PointViewPtr view, const Dimension::IdList& indims)
std::string Script::getLogicalMask(mxArray* array, LogPtr log)
{

std::string output("");
mxClassID ml_id = mxGetClassID(array);
if (ml_id != mxSTRUCT_CLASS)
throw pdal::pdal_error("Selected array must be a Matlab struct array!");

for (int n = 0; n < mxGetNumberOfFields(array); ++n)
{

mxArray* f = mxGetFieldByNumber(array, 0, n);

if (mxIsLogical(f))
{
const char* name = mxGetFieldNameByNumber(array, n);
output = std::string(name);
}
}
return output;
}

void Script::getMatlabStruct(mxArray* array, PointViewPtr view, const Dimension::IdList& indims, LogPtr log)
{
std::vector<mxArray*> arrays;
std::vector<std::string> dimNames;

mxClassID ml_id = mxGetClassID(array);
if (ml_id != mxSTRUCT_CLASS)
throw pdal::pdal_error("input array was not a matlab 'PDAL' struct!");
throw pdal::pdal_error("Selected array must be a Matlab struct array!");

Dimension::IdList dims;
if (!indims.size())
Expand All @@ -67,14 +88,46 @@ void Script::getMatlabStruct(mxArray* array, PointViewPtr view, const Dimension:

for (auto d: dims)
{
std::string dimName = Dimension::name(d);
// int fieldNumber = mxGetFieldNumber(array, dimName.c_str());
std::string dimName = view->dimName(d);

mxArray* f = mxGetField(array, 0, dimName.c_str());
}
if (!f)
{
std::ostringstream oss;
oss << "No dimension named '" << dimName << "' exists on struct array.";
throw pdal::pdal_error(oss.str());
}

mwSize numElements = mxGetNumberOfElements(f);
if (numElements != view->size())
{
std::ostringstream oss;
oss << "Array shape is not the same as the PDAL PointView. ";
oss << "Matlab array is has '" << numElements << "' elements. ";
oss << "PointView has '" << view->size() << "' elements.";
throw pdal::pdal_error(oss.str());
}

mxClassID mt = mxGetClassID(f);
Dimension::Type pt = Script::getPDALDataType(mt);

char* p = (char*)mxGetData(f);
if (!p)
{
std::ostringstream oss;
oss << "Unable to fetch Matlab pointer to array for dimension '" << dimName << "'";
throw pdal::pdal_error(oss.str());
}

for (PointId i = 0; i < view->size(); ++i)
{
view->setField(d, pt, i, p);
p += view->dimSize(d);
}
}
}

mxArray* Script::setMatlabStruct(PointViewPtr view, const Dimension::IdList& indims)
mxArray* Script::setMatlabStruct(PointViewPtr view, const Dimension::IdList& indims, LogPtr log)
{

std::vector<mxArray*> arrays;
Expand Down
6 changes: 4 additions & 2 deletions plugins/matlab/filters/Script.hpp
Expand Up @@ -40,6 +40,7 @@

#include <pdal/Options.hpp>
#include <pdal/PointView.hpp>
#include <pdal/Log.hpp>

namespace pdal
{
Expand All @@ -54,9 +55,10 @@ class PDAL_DLL Script
static int getMatlabDataType(Dimension::Type t);
static Dimension::Type getPDALDataType(mxClassID t);

static mxArray* setMatlabStruct(PointViewPtr view, const Dimension::IdList& dims);
static mxArray* setMatlabStruct(PointViewPtr view, const Dimension::IdList& dims, LogPtr log);

static void getMatlabStruct(mxArray* array, PointViewPtr view, const Dimension::IdList& dims);
static void getMatlabStruct(mxArray* array, PointViewPtr view, const Dimension::IdList& dims, LogPtr log);
static std::string getLogicalMask(mxArray* array, LogPtr log);

std::string m_source;
std::string m_scriptFilename;
Expand Down

0 comments on commit 95b81b3

Please sign in to comment.