From 3f5e4b145c22d2dd512d584cd71bd4ae60c08a49 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Tue, 24 Feb 2015 14:54:11 +0100
Subject: added get_geometry for 3d volume objects

---
 matlab/mex/astra_mex_data3d_c.cpp | 82 +++++++++++++++++++--------------------
 matlab/mex/mexHelpFunctions.cpp   | 41 ++++++++++++++------
 matlab/mex/mexHelpFunctions.h     |  6 +++
 3 files changed, 76 insertions(+), 53 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 35a7512..47316f5 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -266,48 +266,46 @@ void astra_mex_data3d_dimensions(int nlhs, mxArray* plhs[], int nrhs, const mxAr
 }
 
 //-----------------------------------------------------------------------------------------
-/**
- * [geom] = astra_mex_data3d('geometry', id);
+/** geom = astra_mex_data3d('get_geometry', id);
+ * 
+ * Fetch the geometry of a 3d data object stored in the astra-library.
+ * id: identifier of the 3d data object as stored in the astra-library.
+ * geom: MATLAB-struct containing information about the used geometry.
  */
-void astra_mex_data3d_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+void astra_mex_data3d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
 { 
-	//// Get input
-	//if (nrhs < 2) {
-	//	mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
-	//	return;
-	//}
-	//int iDid = (int)(mxGetScalar(prhs[1]));
-
-	//// Get data object
-	//CFloat32Data3D* pData = CData3DManager::getSingleton().get(iDid);
-	//if (!pData) {
-	//	mexErrMsgTxt("DataObject not valid. \n");
-	//	return;
-	//}
-
-	//// Projection Data
-	//if (pData->getType() == CFloat32Data3D::PROJECTION) {
-	//	CFloat32ProjectionData3D* pData2 = dynamic_cast<CFloat32ProjectionData3D*>(pData);
-	//	CProjectionGeometry3D* pProjGeom = pData2->getGeometry();
-	//	XMLDocument* config = pProjGeom->toXML();
-
-	//	if (1 <= nlhs) {
-	//		plhs[0] = XML2struct(config);
-	//	}
-	//} 
-	//// Volume Data
-	//else if (pData->getType() == CFloat32Data3D::VOLUME) {
-	////	CFloat32VolumeData3D* pData2 = dynamic_cast<CFloat32VolumeData3D*>(pData);
-	////	CVolumeGeometry2D* pVolGeom = pData2->getGeometry2D(iSliceNr);
-	////	if (1 <= nlhs) {
-	////		plhs[0] = createVolumeGeometryStruct(pVolGeom);
-	////	}
-	//} 
-	//// Error
-	//else {
-	//	mexErrMsgTxt("Type not valid. \n");
-	//	return;	
-	//}
+	// parse input
+	if (nrhs < 2) {
+		mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
+		return;
+	}
+	if (!mxIsDouble(prhs[1])) {
+		mexErrMsgTxt("Identifier should be a scalar value. \n");
+		return;
+	}
+	int iDataID = (int)(mxGetScalar(prhs[1]));
+
+	// fetch data object
+	CFloat32Data3D* pDataObject = astra::CData3DManager::getSingleton().get(iDataID);
+	if (!pDataObject || !pDataObject->isInitialized()) {
+		mexErrMsgTxt("Data object not found or not initialized properly.\n");
+		return;
+	}
+
+	// create output
+	if (1 <= nlhs) {
+		if (pDataObject->getType() == CFloat32Data3D::PROJECTION) {
+			// CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
+			// plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
+			mexErrMsgTxt("Not implemented yet. \n");
+		}
+		else if (pDataObject->getType() == CFloat32Data3D::VOLUME) {
+			CFloat32VolumeData3DMemory* pDataObject2 = dynamic_cast<CFloat32VolumeData3DMemory*>(pDataObject);
+			plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+		}
+	}
+
+
 }
 
 //-----------------------------------------------------------------------------------------
@@ -395,8 +393,8 @@ void mexFunction(int nlhs, mxArray* plhs[],
 		astra_mex_data3d_info(nlhs, plhs, nrhs, prhs);
 	} else if (sMode ==  std::string("dimensions")) { 
 		astra_mex_data3d_dimensions(nlhs, plhs, nrhs, prhs); 
-	} else if (sMode == std::string("geometry")) {
-		astra_mex_data3d_geometry(nlhs, plhs, nrhs, prhs);
+	} else if (sMode == std::string("get_geometry")) {
+		astra_mex_data3d_get_geometry(nlhs, plhs, nrhs, prhs);
 	} else {
 		printHelp();
 	}
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index e919dd9..9b65e77 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -331,28 +331,47 @@ astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
 }
 
 //-----------------------------------------------------------------------------------------
-// create reconstruction geometry data
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom)
+// create 2D volume geometry struct
+mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pVolGeom)
 {
-	// temporary map to store the data for the MATLAB struct
 	std::map<std::string, mxArray*> mGeometryInfo;
 
-	// fill up map
-	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pReconGeom->getGridColCount());
-	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pReconGeom->getGridRowCount());
+	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
+	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
 
 	std::map<std::string, mxArray*> mGeometryOptions;
-	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinX());
-	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxX());
-	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMinY());
-	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pReconGeom->getWindowMaxY());
+	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
+	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
+	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
+	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
 
 	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
 
-	// build and return the MATLAB struct
 	return buildStruct(mGeometryInfo);
 }
 
+//-----------------------------------------------------------------------------------------
+// create 3D volume geometry struct
+mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pVolGeom)
+{
+	std::map<std::string, mxArray*> mGeometryInfo;
+
+	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
+	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
+	mGeometryInfo["GridSliceCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
+
+	std::map<std::string, mxArray*> mGeometryOptions;
+	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
+	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
+	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
+	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
+	mGeometryOptions["WindowMinZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinZ());
+	mGeometryOptions["WindowMaxZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxZ());
+
+	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
+
+	return buildStruct(mGeometryInfo);
+}
 
 //-----------------------------------------------------------------------------------------
 string matlab2string(const mxArray* pField)
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index 84372ba..ae8acac 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -47,6 +47,9 @@ $Id$
 #include "astra/FanFlatProjectionGeometry2D.h"
 #include "astra/VolumeGeometry2D.h"
 
+#include "astra/VolumeGeometry3D.h"
+
+
 #include "astra/XMLDocument.h"
 #include "astra/XMLNode.h"
 
@@ -63,8 +66,11 @@ mxArray* anyToMxArray(boost::any _any);
 
 astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
 mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
+
 astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
+
 mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
+mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pReconGeom);
 
 astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
 
-- 
cgit v1.2.3


From 9e48494ecc1e4655bd6c25b34bb5c53c80c30d7a Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Tue, 24 Feb 2015 15:17:38 +0100
Subject: fixed get_geometry for fanflat_vec

---
 matlab/mex/astra_mex_data2d_c.cpp |  4 +--
 matlab/mex/mexHelpFunctions.cpp   | 72 +++++++++++++++++++++------------------
 2 files changed, 41 insertions(+), 35 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index b219179..bd70e1b 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -373,7 +373,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
  */
 void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
 { 
-	// step1: input
+	// parse input
 	if (nrhs < 2) {
 		mexErrMsgTxt("Not enough arguments.  See the help document for a detailed argument list. \n");
 		return;
@@ -384,7 +384,7 @@ void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 	}
 	int iDataID = (int)(mxGetScalar(prhs[1]));
 
-	// step2: get data object
+	// fetch data object
 	CFloat32Data2D* pDataObject = astra::CData2DManager::getSingleton().get(iDataID);
 	if (!pDataObject || !pDataObject->isInitialized()) {
 		mexErrMsgTxt("Data object not found or not initialized properly.\n");
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index 9b65e77..63d2003 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -213,61 +213,67 @@ mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom
 	// temporary map to store the data for the MATLAB struct
 	std::map<std::string, mxArray*> mGeometryInfo;
 
-	// detectorCount
-	mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
-	
-	if (!_pProjGeom->isOfType("fanflat_vec")) {
-		// detectorWidth
+	// parallel beam
+	if (_pProjGeom->isOfType("parallel")) {
+		mGeometryInfo["type"] = mxCreateString("parallel");
+		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
 		mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
 
-		// pfProjectionAngles
 		mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionAngleCount(), mxREAL);
 		double* out = mxGetPr(pAngles);
 		for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) {
 			out[i] = _pProjGeom->getProjectionAngle(i);
 		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;
+		mGeometryInfo["ProjectionAngles"] = pAngles;	
 	}
-	else {
+
+	// fanflat
+	else if (_pProjGeom->isOfType("fanflat")) {
+		astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom);
+
+		mGeometryInfo["type"] = mxCreateString("fanflat");
+		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
+		mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
+		mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance());
+		mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance());		
+
+		mxArray* pAngles = mxCreateDoubleMatrix(1, pFanFlatGeom->getProjectionAngleCount(), mxREAL);
+		double* out = mxGetPr(pAngles);
+		for (int i = 0; i < pFanFlatGeom->getProjectionAngleCount(); i++) {
+			out[i] = pFanFlatGeom->getProjectionAngle(i);
+		}
+		mGeometryInfo["ProjectionAngles"] = pAngles;	
+	}
+
+	// fanflat_vec
+	else if (_pProjGeom->isOfType("fanflat_vec")) {
 		astra::CFanFlatVecProjectionGeometry2D* pVecGeom = dynamic_cast<astra::CFanFlatVecProjectionGeometry2D*>(_pProjGeom);
-		mxArray* pVectors = mxCreateDoubleMatrix(1, pVecGeom->getProjectionAngleCount()*6, mxREAL);
+
+		mGeometryInfo["type"] = mxCreateString("fanflat_vec");
+		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorCount());
+
+		mxArray* pVectors = mxCreateDoubleMatrix(pVecGeom->getProjectionAngleCount(), 6, mxREAL);
 		double* out = mxGetPr(pVectors);
 		int iDetCount = pVecGeom->getDetectorCount();
+		int iAngleCount = pVecGeom->getProjectionAngleCount();
 		for (int i = 0; i < pVecGeom->getProjectionAngleCount(); i++) {
 			const SFanProjection* p = &pVecGeom->getProjectionVectors()[i];
-			out[6*i + 0] = p->fSrcX;
-			out[6*i + 1] = p->fSrcY;
-			out[6*i + 2] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
-			out[6*i + 3] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
-			out[6*i + 4] = p->fDetUX;
-			out[6*i + 5] = p->fDetUY;
+			out[0*iAngleCount + i] = p->fSrcX;
+			out[1*iAngleCount + i] = p->fSrcY;
+			out[2*iAngleCount + i] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
+			out[3*iAngleCount + i] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
+			out[4*iAngleCount + i] = p->fDetUX;
+			out[5*iAngleCount + i] = p->fDetUY;			
 		}
 		mGeometryInfo["Vectors"] = pVectors;
 	}
 
-	// parallel specific options
-	if (_pProjGeom->isOfType("parallel")) {
-		// type
-		mGeometryInfo["type"] = mxCreateString("parallel");
-	}
-	// fanflat specific options
-	else if (_pProjGeom->isOfType("fanflat")) {
-		astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom);
-		// detectorCount
-		mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance());
-		// detectorWidth
-		mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance());
-		// type
-		mGeometryInfo["type"] = mxCreateString("fanflat");
-	}
+	// sparse_matrix
 	else if (_pProjGeom->isOfType("sparse_matrix")) {
 		astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom = dynamic_cast<astra::CSparseMatrixProjectionGeometry2D*>(_pProjGeom);
 		mGeometryInfo["type"] = mxCreateString("sparse_matrix");
 		mGeometryInfo["MatrixID"] = mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix()));
 	}
-	else if(_pProjGeom->isOfType("fanflat_vec")) {
-		mGeometryInfo["type"] = mxCreateString("fanflat_vec");
-	}
 
 	// build and return the MATLAB struct
 	return buildStruct(mGeometryInfo);
-- 
cgit v1.2.3


From 569515f3e20ef3b3c2c4a777f38f45dc67e6f9b6 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Tue, 24 Feb 2015 16:46:39 +0100
Subject: added get_geometry for 3d projection data objects

---
 matlab/mex/astra_mex_data3d_c.cpp |   5 +-
 matlab/mex/mexHelpFunctions.cpp   | 117 ++++++++++++++++++++++++++++++++++++--
 matlab/mex/mexHelpFunctions.h     |  11 +++-
 3 files changed, 123 insertions(+), 10 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 47316f5..84bc0a4 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -295,9 +295,8 @@ void astra_mex_data3d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 	// create output
 	if (1 <= nlhs) {
 		if (pDataObject->getType() == CFloat32Data3D::PROJECTION) {
-			// CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
-			// plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
-			mexErrMsgTxt("Not implemented yet. \n");
+			CFloat32ProjectionData3DMemory* pDataObject2 = dynamic_cast<CFloat32ProjectionData3DMemory*>(pDataObject);
+			plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
 		}
 		else if (pDataObject->getType() == CFloat32Data3D::VOLUME) {
 			CFloat32VolumeData3DMemory* pDataObject2 = dynamic_cast<CFloat32VolumeData3DMemory*>(pDataObject);
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index 63d2003..654f5c6 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -207,7 +207,7 @@ astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs)
 }
 
 //-----------------------------------------------------------------------------------------
-// create projection geometry data
+// create 2D projection geometry struct
 mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom)
 {
 	// temporary map to store the data for the MATLAB struct
@@ -224,7 +224,7 @@ mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom
 		for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) {
 			out[i] = _pProjGeom->getProjectionAngle(i);
 		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;	
+		mGeometryInfo["ProjectionAngles"] = pAngles;
 	}
 
 	// fanflat
@@ -242,7 +242,7 @@ mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom
 		for (int i = 0; i < pFanFlatGeom->getProjectionAngleCount(); i++) {
 			out[i] = pFanFlatGeom->getProjectionAngle(i);
 		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;	
+		mGeometryInfo["ProjectionAngles"] = pAngles;
 	}
 
 	// fanflat_vec
@@ -263,7 +263,7 @@ mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom
 			out[2*iAngleCount + i] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
 			out[3*iAngleCount + i] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
 			out[4*iAngleCount + i] = p->fDetUX;
-			out[5*iAngleCount + i] = p->fDetUY;			
+			out[5*iAngleCount + i] = p->fDetUY;
 		}
 		mGeometryInfo["Vectors"] = pVectors;
 	}
@@ -279,6 +279,115 @@ mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom
 	return buildStruct(mGeometryInfo);
 }
 
+//-----------------------------------------------------------------------------------------
+// create 3D projection geometry struct
+mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry3D* _pProjGeom)
+{
+	// temporary map to store the data for the MATLAB struct
+	std::map<std::string, mxArray*> mGeometryInfo;
+
+	// parallel beam
+	if (_pProjGeom->isOfType("parallel3d")) {
+		mGeometryInfo["type"] = mxCreateString("parallel3d");
+		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorRowCount());
+		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorColCount());
+		mGeometryInfo["DetectorSpacingX"] = mxCreateDoubleScalar(_pProjGeom->getDetectorSpacingX());
+		mGeometryInfo["DetectorSpacingY"] = mxCreateDoubleScalar(_pProjGeom->getDetectorSpacingY());
+
+		mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionCount(), mxREAL);
+		double* out = mxGetPr(pAngles);
+		for (int i = 0; i < _pProjGeom->getProjectionCount(); i++) {
+			out[i] = _pProjGeom->getProjectionAngle(i);
+		}
+		mGeometryInfo["ProjectionAngles"] = pAngles;
+	}
+
+	// parallel beam vector
+	if (_pProjGeom->isOfType("parallel3d_vec")) {
+		astra::CParallelVecProjectionGeometry3D* pVecGeom = dynamic_cast<astra::CParallelVecProjectionGeometry3D*>(_pProjGeom);
+
+		mGeometryInfo["type"] = mxCreateString("parallel3d_vec");
+		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorRowCount());
+		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorColCount());
+
+		mxArray* pVectors = mxCreateDoubleMatrix(pVecGeom->getProjectionCount(), 12, mxREAL);
+		double* out = mxGetPr(pVectors);
+		int iDetRowCount = pVecGeom->getDetectorRowCount();
+		int iDetColCount = pVecGeom->getDetectorColCount();
+		int iAngleCount = pVecGeom->getProjectionCount();
+		for (int i = 0; i < pVecGeom->getProjectionCount(); i++) {
+			const SPar3DProjection* p = &pVecGeom->getProjectionVectors()[i];
+			out[ 0*iAngleCount + i] = p->fRayX;
+			out[ 1*iAngleCount + i] = p->fRayY;
+			out[ 2*iAngleCount + i] = p->fRayZ;
+			out[ 3*iAngleCount + i] = p->fDetSX + 0.5f*iDetRowCount*p->fDetUX + 0.5f*iDetColCount*p->fDetVX;
+			out[ 4*iAngleCount + i] = p->fDetSY + 0.5f*iDetRowCount*p->fDetUY + 0.5f*iDetColCount*p->fDetVY;
+			out[ 5*iAngleCount + i] = p->fDetSZ + 0.5f*iDetRowCount*p->fDetUZ + 0.5f*iDetColCount*p->fDetVZ;
+			out[ 6*iAngleCount + i] = p->fDetUX;
+			out[ 7*iAngleCount + i] = p->fDetUY;
+			out[ 8*iAngleCount + i] = p->fDetUZ;
+			out[ 9*iAngleCount + i] = p->fDetVX;
+			out[10*iAngleCount + i] = p->fDetVY;
+			out[11*iAngleCount + i] = p->fDetVZ;
+		}
+		mGeometryInfo["Vectors"] = pVectors;
+	}
+
+	// cone beam
+	else if (_pProjGeom->isOfType("cone")) {
+		astra::CConeProjectionGeometry3D* pConeGeom = dynamic_cast<astra::CConeProjectionGeometry3D*>(_pProjGeom);
+
+		mGeometryInfo["type"] = mxCreateString("cone");
+		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pConeGeom->getDetectorRowCount());
+		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pConeGeom->getDetectorColCount());
+		mGeometryInfo["DetectorSpacingX"] = mxCreateDoubleScalar(pConeGeom->getDetectorSpacingX());
+		mGeometryInfo["DetectorSpacingY"] = mxCreateDoubleScalar(pConeGeom->getDetectorSpacingY());
+		mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pConeGeom->getOriginSourceDistance());
+		mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pConeGeom->getOriginDetectorDistance());	
+
+		mxArray* pAngles = mxCreateDoubleMatrix(1, pConeGeom->getProjectionCount(), mxREAL);
+		double* out = mxGetPr(pAngles);
+		for (int i = 0; i < pConeGeom->getProjectionCount(); i++) {
+			out[i] = pConeGeom->getProjectionAngle(i);
+		}
+		mGeometryInfo["ProjectionAngles"] = pAngles;
+	}
+
+	// cone beam vector
+	else if (_pProjGeom->isOfType("cone_vec")) {
+		astra::CConeVecProjectionGeometry3D* pConeVecGeom = dynamic_cast<astra::CConeVecProjectionGeometry3D*>(_pProjGeom);
+
+		mGeometryInfo["type"] = mxCreateString("cone_vec");
+		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pConeVecGeom->getDetectorRowCount());
+		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pConeVecGeom->getDetectorColCount());
+
+		mxArray* pVectors = mxCreateDoubleMatrix(pConeVecGeom->getProjectionCount(), 12, mxREAL);
+		double* out = mxGetPr(pVectors);
+		int iDetRowCount = pConeVecGeom->getDetectorRowCount();
+		int iDetColCount = pConeVecGeom->getDetectorColCount();
+		int iAngleCount = pConeVecGeom->getProjectionCount();
+		for (int i = 0; i < pConeVecGeom->getProjectionCount(); i++) {
+			const SConeProjection* p = &pConeVecGeom->getProjectionVectors()[i];
+			out[ 0*iAngleCount + i] = p->fSrcX;
+			out[ 1*iAngleCount + i] = p->fSrcY;
+			out[ 2*iAngleCount + i] = p->fSrcZ;
+			out[ 3*iAngleCount + i] = p->fDetSX + 0.5f*iDetRowCount*p->fDetUX + 0.5f*iDetColCount*p->fDetVX;
+			out[ 4*iAngleCount + i] = p->fDetSY + 0.5f*iDetRowCount*p->fDetUY + 0.5f*iDetColCount*p->fDetVY;
+			out[ 5*iAngleCount + i] = p->fDetSZ + 0.5f*iDetRowCount*p->fDetUZ + 0.5f*iDetColCount*p->fDetVZ;
+			out[ 6*iAngleCount + i] = p->fDetUX;
+			out[ 7*iAngleCount + i] = p->fDetUY;
+			out[ 8*iAngleCount + i] = p->fDetUZ;
+			out[ 9*iAngleCount + i] = p->fDetVX;
+			out[10*iAngleCount + i] = p->fDetVY;
+			out[11*iAngleCount + i] = p->fDetVZ;
+		}
+		mGeometryInfo["Vectors"] = pVectors;
+	}
+
+	// build and return the MATLAB struct
+	return buildStruct(mGeometryInfo);
+}
+
 //-----------------------------------------------------------------------------------------
 // parse reconstruction geometry data
 astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index ae8acac..8b65a04 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -45,8 +45,12 @@ $Id$
 
 #include "astra/ParallelProjectionGeometry2D.h"
 #include "astra/FanFlatProjectionGeometry2D.h"
-#include "astra/VolumeGeometry2D.h"
+#include "astra/ParallelProjectionGeometry3D.h"
+#include "astra/ParallelVecProjectionGeometry3D.h"
+#include "astra/ConeProjectionGeometry3D.h"
+#include "astra/ConeVecProjectionGeometry3D.h"
 
+#include "astra/VolumeGeometry2D.h"
 #include "astra/VolumeGeometry3D.h"
 
 
@@ -65,10 +69,11 @@ mxArray* vectorToMxArray(std::vector<astra::float32> mInput);
 mxArray* anyToMxArray(boost::any _any);
 
 astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
-
 astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
 
+mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
+mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry3D*);
+
 mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
 mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pReconGeom);
 
-- 
cgit v1.2.3


From 85f397c64461499a27b13e84fbc0348b19feb248 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Tue, 24 Feb 2015 16:58:50 +0100
Subject: re-enabled get_geometry for 3d projectors

---
 matlab/mex/astra_mex_projector3d_c.cpp | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
index 25980f9..95b3e0f 100644
--- a/matlab/mex/astra_mex_projector3d_c.cpp
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -135,16 +135,16 @@ void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], in
 	}
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
-	//if (1 <= nlhs) {
-	//	plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
-	//}
+	if (1 <= nlhs) {
+		plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+	}
 }
 
 //-----------------------------------------------------------------------------------------
 /**
 * [recon_geom] = astra_mex_projector3d('get_volume_geometry', pid);
 */
-void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
+void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[])
 {
 	// step1: read input
 	if (nrhs < 2) {
@@ -161,9 +161,9 @@ void astra_mex_projector3d_get_reconstruction_geometry(int nlhs, mxArray* plhs[]
 	}
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
-	//if (1 <= nlhs) {
-	//	plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
-	//}
+	if (1 <= nlhs) {
+		plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+	}
 }
 
 //-----------------------------------------------------------------------------------------
@@ -413,7 +413,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	} else if (sMode == "get_projection_geometry") {
 		astra_mex_projector3d_get_projection_geometry(nlhs, plhs, nrhs, prhs);
 	} else if (sMode == "get_volume_geometry") {
-		astra_mex_projector3d_get_reconstruction_geometry(nlhs, plhs, nrhs, prhs);
+		astra_mex_projector3d_get_volume_geometry(nlhs, plhs, nrhs, prhs);
 	} else if (sMode == "weights_single_ray") {
 		astra_mex_projector_weights_single_ray(nlhs, plhs, nrhs, prhs);
 	//} else if (sMode == "weights_projection") {
-- 
cgit v1.2.3


From 065d9c6a18f2b8eececc608ce850a9a308ca6356 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Wed, 25 Feb 2015 16:46:09 +0100
Subject: get_geometry now uses XML config object (for volumes)

---
 matlab/mex/astra_mex_data2d_c.cpp |   4 +-
 matlab/mex/astra_mex_data3d_c.cpp |   2 +-
 matlab/mex/mexHelpFunctions.cpp   | 107 ++++++++++++++++++++++++++------------
 matlab/mex/mexHelpFunctions.h     |   5 +-
 4 files changed, 80 insertions(+), 38 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index bd70e1b..d07a13a 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -399,7 +399,9 @@ void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 		}
 		else if (pDataObject->getType() == CFloat32Data2D::VOLUME) {
 			CFloat32VolumeData2D* pDataObject2 = dynamic_cast<CFloat32VolumeData2D*>(pDataObject);
-			plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+			plhs[0] = config2struct(pDataObject2->getGeometry()->getConfiguration());
+			// mexErrMsgTxt(pDataObject2->getGeometry()->getConfiguration()->self->toString().c_str());
+			// plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
 		}
 	}
 }
diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 84bc0a4..5abdf50 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -300,7 +300,7 @@ void astra_mex_data3d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 		}
 		else if (pDataObject->getType() == CFloat32Data3D::VOLUME) {
 			CFloat32VolumeData3DMemory* pDataObject2 = dynamic_cast<CFloat32VolumeData3DMemory*>(pDataObject);
-			plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+			plhs[0] = config2struct(pDataObject2->getGeometry()->getConfiguration());
 		}
 	}
 
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index 654f5c6..b57f27f 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -447,46 +447,46 @@ astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
 
 //-----------------------------------------------------------------------------------------
 // create 2D volume geometry struct
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pVolGeom)
-{
-	std::map<std::string, mxArray*> mGeometryInfo;
+// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pVolGeom)
+// {
+// 	std::map<std::string, mxArray*> mGeometryInfo;
 
-	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
-	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
+// 	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
+// 	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
 
-	std::map<std::string, mxArray*> mGeometryOptions;
-	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
-	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
-	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
-	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
+// 	std::map<std::string, mxArray*> mGeometryOptions;
+// 	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
+// 	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
+// 	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
+// 	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
 
-	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
+// 	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
 
-	return buildStruct(mGeometryInfo);
-}
+// 	return buildStruct(mGeometryInfo);
+// }
 
 //-----------------------------------------------------------------------------------------
 // create 3D volume geometry struct
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pVolGeom)
-{
-	std::map<std::string, mxArray*> mGeometryInfo;
+// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pVolGeom)
+// {
+// 	std::map<std::string, mxArray*> mGeometryInfo;
 
-	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
-	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
-	mGeometryInfo["GridSliceCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
+// 	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
+// 	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
+// 	mGeometryInfo["GridSliceCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
 
-	std::map<std::string, mxArray*> mGeometryOptions;
-	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
-	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
-	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
-	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
-	mGeometryOptions["WindowMinZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinZ());
-	mGeometryOptions["WindowMaxZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxZ());
+// 	std::map<std::string, mxArray*> mGeometryOptions;
+// 	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
+// 	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
+// 	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
+// 	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
+// 	mGeometryOptions["WindowMinZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinZ());
+// 	mGeometryOptions["WindowMaxZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxZ());
 
-	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
+// 	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
 
-	return buildStruct(mGeometryInfo);
-}
+// 	return buildStruct(mGeometryInfo);
+// }
 
 //-----------------------------------------------------------------------------------------
 string matlab2string(const mxArray* pField)
@@ -714,6 +714,12 @@ bool mex_is_scalar(const mxArray* pInput)
 	return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
 }
 
+//-----------------------------------------------------------------------------------------
+mxArray* config2struct(astra::Config* cfg)
+{
+	return XMLNode2struct(cfg->self);
+}
+
 //-----------------------------------------------------------------------------------------
 mxArray* XML2struct(astra::XMLDocument* xml)
 {
@@ -724,9 +730,26 @@ mxArray* XML2struct(astra::XMLDocument* xml)
 }
 
 //-----------------------------------------------------------------------------------------
+mxArray* XMLNode2option(astra::XMLNode* node)
+{
+	char* end;
+	double content = ::strtod(node->getAttribute("value").c_str(), &end);
+	bool isnumber = !*end;
+
+	// float
+	if (isnumber) {
+		return mxCreateDoubleScalar(content);
+	}
+	// string
+	else {
+		return mxCreateString(node->getAttribute("value").c_str());
+	}
+}
+
 mxArray* XMLNode2struct(astra::XMLNode* node)
 {
-	std::map<std::string, mxArray*> mList; 
+	std::map<std::string, mxArray*> mList;
+	std::map<std::string, mxArray*> mOptions;
 
 	// type_attribute
 	if (node->hasAttribute("type")) {
@@ -736,11 +759,22 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
 	list<XMLNode*> nodes = node->getNodes();
 	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
 		XMLNode* subnode = (*it);
+
+		char* end;
+		double content = ::strtod(subnode->getContent().c_str(), &end);
+		bool isnumber = !*end;
+
+		// option
+		if (subnode->getName() == "Option") {
+			mOptions[subnode->getAttribute("key")] = XMLNode2option(subnode);
+		}
 		// list
-		if (subnode->hasAttribute("listsize")) {
-			cout << "lkmdsqldqsjkl" << endl;
-			cout << " " << node->getContentNumericalArray().size() << endl;
-			mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray());
+		// else if (subnode->hasAttribute("listsize")) {
+		// 	mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray());
+		// }
+		// float
+		else if (isnumber) {
+			mList[subnode->getName()] =  mxCreateDoubleScalar(content);
 		}
 		// string
 		else {
@@ -749,9 +783,14 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
 		delete subnode;
 	}
 
+	mList["options"] = buildStruct(mOptions);
 	return buildStruct(mList);
 }
 
+
+
+
+
 void get3DMatrixDims(const mxArray* x, mwSize *dims)
 {
 	const mwSize* mdims = mxGetDimensions(x);
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index 8b65a04..f8a7d48 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -74,11 +74,12 @@ astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
 mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
 mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry3D*);
 
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
-mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pReconGeom);
+// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
+// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pReconGeom);
 
 astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
 
+mxArray* config2struct(astra::Config* cfg);
 mxArray* XML2struct(astra::XMLDocument* xml);
 mxArray* XMLNode2struct(astra::XMLNode* xml);
 
-- 
cgit v1.2.3


From cca150841cd1de4f3b4d24c1188263b9623bc511 Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Thu, 26 Feb 2015 13:47:59 +0100
Subject: get_geometry now uses XML config object (for projections)

---
 matlab/mex/astra_mex_data2d_c.cpp      |   6 +-
 matlab/mex/astra_mex_data3d_c.cpp      |   5 +-
 matlab/mex/astra_mex_projector3d_c.cpp |   4 +-
 matlab/mex/astra_mex_projector_c.cpp   |   5 +-
 matlab/mex/mexHelpFunctions.cpp        | 332 +++++++++------------------------
 matlab/mex/mexHelpFunctions.h          |  10 +-
 6 files changed, 96 insertions(+), 266 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index d07a13a..03d3807 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -395,13 +395,11 @@ void astra_mex_data2d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 	if (1 <= nlhs) {
 		if (pDataObject->getType() == CFloat32Data2D::PROJECTION) {
 			CFloat32ProjectionData2D* pDataObject2 = dynamic_cast<CFloat32ProjectionData2D*>(pDataObject);
-			plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
+			plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
 		}
 		else if (pDataObject->getType() == CFloat32Data2D::VOLUME) {
 			CFloat32VolumeData2D* pDataObject2 = dynamic_cast<CFloat32VolumeData2D*>(pDataObject);
-			plhs[0] = config2struct(pDataObject2->getGeometry()->getConfiguration());
-			// mexErrMsgTxt(pDataObject2->getGeometry()->getConfiguration()->self->toString().c_str());
-			// plhs[0] = createVolumeGeometryStruct(pDataObject2->getGeometry());
+			plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
 		}
 	}
 }
diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 5abdf50..64c013d 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -296,11 +296,12 @@ void astra_mex_data3d_get_geometry(int nlhs, mxArray* plhs[], int nrhs, const mx
 	if (1 <= nlhs) {
 		if (pDataObject->getType() == CFloat32Data3D::PROJECTION) {
 			CFloat32ProjectionData3DMemory* pDataObject2 = dynamic_cast<CFloat32ProjectionData3DMemory*>(pDataObject);
-			plhs[0] = createProjectionGeometryStruct(pDataObject2->getGeometry());
+			plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
+			
 		}
 		else if (pDataObject->getType() == CFloat32Data3D::VOLUME) {
 			CFloat32VolumeData3DMemory* pDataObject2 = dynamic_cast<CFloat32VolumeData3DMemory*>(pDataObject);
-			plhs[0] = config2struct(pDataObject2->getGeometry()->getConfiguration());
+			plhs[0] = configToStruct(pDataObject2->getGeometry()->getConfiguration());
 		}
 	}
 
diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
index 95b3e0f..b2f6b02 100644
--- a/matlab/mex/astra_mex_projector3d_c.cpp
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -136,7 +136,7 @@ void astra_mex_projector3d_get_projection_geometry(int nlhs, mxArray* plhs[], in
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
 	}
 }
 
@@ -162,7 +162,7 @@ void astra_mex_projector3d_get_volume_geometry(int nlhs, mxArray* plhs[], int nr
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
 	}
 }
 
diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp
index de73f07..4793020 100644
--- a/matlab/mex/astra_mex_projector_c.cpp
+++ b/matlab/mex/astra_mex_projector_c.cpp
@@ -162,7 +162,7 @@ void astra_mex_projector_projection_geometry(int nlhs, mxArray* plhs[], int nrhs
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = createProjectionGeometryStruct(pProjector->getProjectionGeometry());
+		plhs[0] = configToStruct(pProjector->getProjectionGeometry()->getConfiguration());
 	}
 }
 
@@ -191,7 +191,8 @@ void astra_mex_projector_volume_geometry(int nlhs, mxArray* plhs[], int nrhs, co
 
 	// step3: get projection_geometry and turn it into a MATLAB struct
 	if (1 <= nlhs) {
-		plhs[0] = createVolumeGeometryStruct(pProjector->getVolumeGeometry());
+		plhs[0] = configToStruct(pProjector->getVolumeGeometry()->getConfiguration());
+
 	}
 }
 
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index b57f27f..c25123a 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -32,6 +32,12 @@ $Id$
  */
 #include "mexHelpFunctions.h"
 
+#include <algorithm>
+#include <boost/lexical_cast.hpp>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
 #include "astra/SparseMatrixProjectionGeometry2D.h"
 #include "astra/FanFlatVecProjectionGeometry2D.h"
 #include "astra/AstraObjectManager.h"
@@ -206,188 +212,6 @@ astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs)
 	}
 }
 
-//-----------------------------------------------------------------------------------------
-// create 2D projection geometry struct
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D* _pProjGeom)
-{
-	// temporary map to store the data for the MATLAB struct
-	std::map<std::string, mxArray*> mGeometryInfo;
-
-	// parallel beam
-	if (_pProjGeom->isOfType("parallel")) {
-		mGeometryInfo["type"] = mxCreateString("parallel");
-		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
-		mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
-
-		mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionAngleCount(), mxREAL);
-		double* out = mxGetPr(pAngles);
-		for (int i = 0; i < _pProjGeom->getProjectionAngleCount(); i++) {
-			out[i] = _pProjGeom->getProjectionAngle(i);
-		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;
-	}
-
-	// fanflat
-	else if (_pProjGeom->isOfType("fanflat")) {
-		astra::CFanFlatProjectionGeometry2D* pFanFlatGeom = dynamic_cast<astra::CFanFlatProjectionGeometry2D*>(_pProjGeom);
-
-		mGeometryInfo["type"] = mxCreateString("fanflat");
-		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorCount());
-		mGeometryInfo["DetectorWidth"] = mxCreateDoubleScalar(_pProjGeom->getDetectorWidth());
-		mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginSourceDistance());
-		mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pFanFlatGeom->getOriginDetectorDistance());		
-
-		mxArray* pAngles = mxCreateDoubleMatrix(1, pFanFlatGeom->getProjectionAngleCount(), mxREAL);
-		double* out = mxGetPr(pAngles);
-		for (int i = 0; i < pFanFlatGeom->getProjectionAngleCount(); i++) {
-			out[i] = pFanFlatGeom->getProjectionAngle(i);
-		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;
-	}
-
-	// fanflat_vec
-	else if (_pProjGeom->isOfType("fanflat_vec")) {
-		astra::CFanFlatVecProjectionGeometry2D* pVecGeom = dynamic_cast<astra::CFanFlatVecProjectionGeometry2D*>(_pProjGeom);
-
-		mGeometryInfo["type"] = mxCreateString("fanflat_vec");
-		mGeometryInfo["DetectorCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorCount());
-
-		mxArray* pVectors = mxCreateDoubleMatrix(pVecGeom->getProjectionAngleCount(), 6, mxREAL);
-		double* out = mxGetPr(pVectors);
-		int iDetCount = pVecGeom->getDetectorCount();
-		int iAngleCount = pVecGeom->getProjectionAngleCount();
-		for (int i = 0; i < pVecGeom->getProjectionAngleCount(); i++) {
-			const SFanProjection* p = &pVecGeom->getProjectionVectors()[i];
-			out[0*iAngleCount + i] = p->fSrcX;
-			out[1*iAngleCount + i] = p->fSrcY;
-			out[2*iAngleCount + i] = p->fDetSX + 0.5f*iDetCount*p->fDetUX;
-			out[3*iAngleCount + i] = p->fDetSY + 0.5f*iDetCount*p->fDetUY;
-			out[4*iAngleCount + i] = p->fDetUX;
-			out[5*iAngleCount + i] = p->fDetUY;
-		}
-		mGeometryInfo["Vectors"] = pVectors;
-	}
-
-	// sparse_matrix
-	else if (_pProjGeom->isOfType("sparse_matrix")) {
-		astra::CSparseMatrixProjectionGeometry2D* pSparseMatrixGeom = dynamic_cast<astra::CSparseMatrixProjectionGeometry2D*>(_pProjGeom);
-		mGeometryInfo["type"] = mxCreateString("sparse_matrix");
-		mGeometryInfo["MatrixID"] = mxCreateDoubleScalar(CMatrixManager::getSingleton().getIndex(pSparseMatrixGeom->getMatrix()));
-	}
-
-	// build and return the MATLAB struct
-	return buildStruct(mGeometryInfo);
-}
-
-//-----------------------------------------------------------------------------------------
-// create 3D projection geometry struct
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry3D* _pProjGeom)
-{
-	// temporary map to store the data for the MATLAB struct
-	std::map<std::string, mxArray*> mGeometryInfo;
-
-	// parallel beam
-	if (_pProjGeom->isOfType("parallel3d")) {
-		mGeometryInfo["type"] = mxCreateString("parallel3d");
-		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorRowCount());
-		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(_pProjGeom->getDetectorColCount());
-		mGeometryInfo["DetectorSpacingX"] = mxCreateDoubleScalar(_pProjGeom->getDetectorSpacingX());
-		mGeometryInfo["DetectorSpacingY"] = mxCreateDoubleScalar(_pProjGeom->getDetectorSpacingY());
-
-		mxArray* pAngles = mxCreateDoubleMatrix(1, _pProjGeom->getProjectionCount(), mxREAL);
-		double* out = mxGetPr(pAngles);
-		for (int i = 0; i < _pProjGeom->getProjectionCount(); i++) {
-			out[i] = _pProjGeom->getProjectionAngle(i);
-		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;
-	}
-
-	// parallel beam vector
-	if (_pProjGeom->isOfType("parallel3d_vec")) {
-		astra::CParallelVecProjectionGeometry3D* pVecGeom = dynamic_cast<astra::CParallelVecProjectionGeometry3D*>(_pProjGeom);
-
-		mGeometryInfo["type"] = mxCreateString("parallel3d_vec");
-		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorRowCount());
-		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pVecGeom->getDetectorColCount());
-
-		mxArray* pVectors = mxCreateDoubleMatrix(pVecGeom->getProjectionCount(), 12, mxREAL);
-		double* out = mxGetPr(pVectors);
-		int iDetRowCount = pVecGeom->getDetectorRowCount();
-		int iDetColCount = pVecGeom->getDetectorColCount();
-		int iAngleCount = pVecGeom->getProjectionCount();
-		for (int i = 0; i < pVecGeom->getProjectionCount(); i++) {
-			const SPar3DProjection* p = &pVecGeom->getProjectionVectors()[i];
-			out[ 0*iAngleCount + i] = p->fRayX;
-			out[ 1*iAngleCount + i] = p->fRayY;
-			out[ 2*iAngleCount + i] = p->fRayZ;
-			out[ 3*iAngleCount + i] = p->fDetSX + 0.5f*iDetRowCount*p->fDetUX + 0.5f*iDetColCount*p->fDetVX;
-			out[ 4*iAngleCount + i] = p->fDetSY + 0.5f*iDetRowCount*p->fDetUY + 0.5f*iDetColCount*p->fDetVY;
-			out[ 5*iAngleCount + i] = p->fDetSZ + 0.5f*iDetRowCount*p->fDetUZ + 0.5f*iDetColCount*p->fDetVZ;
-			out[ 6*iAngleCount + i] = p->fDetUX;
-			out[ 7*iAngleCount + i] = p->fDetUY;
-			out[ 8*iAngleCount + i] = p->fDetUZ;
-			out[ 9*iAngleCount + i] = p->fDetVX;
-			out[10*iAngleCount + i] = p->fDetVY;
-			out[11*iAngleCount + i] = p->fDetVZ;
-		}
-		mGeometryInfo["Vectors"] = pVectors;
-	}
-
-	// cone beam
-	else if (_pProjGeom->isOfType("cone")) {
-		astra::CConeProjectionGeometry3D* pConeGeom = dynamic_cast<astra::CConeProjectionGeometry3D*>(_pProjGeom);
-
-		mGeometryInfo["type"] = mxCreateString("cone");
-		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pConeGeom->getDetectorRowCount());
-		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pConeGeom->getDetectorColCount());
-		mGeometryInfo["DetectorSpacingX"] = mxCreateDoubleScalar(pConeGeom->getDetectorSpacingX());
-		mGeometryInfo["DetectorSpacingY"] = mxCreateDoubleScalar(pConeGeom->getDetectorSpacingY());
-		mGeometryInfo["DistanceOriginSource"] = mxCreateDoubleScalar(pConeGeom->getOriginSourceDistance());
-		mGeometryInfo["DistanceOriginDetector"] = mxCreateDoubleScalar(pConeGeom->getOriginDetectorDistance());	
-
-		mxArray* pAngles = mxCreateDoubleMatrix(1, pConeGeom->getProjectionCount(), mxREAL);
-		double* out = mxGetPr(pAngles);
-		for (int i = 0; i < pConeGeom->getProjectionCount(); i++) {
-			out[i] = pConeGeom->getProjectionAngle(i);
-		}
-		mGeometryInfo["ProjectionAngles"] = pAngles;
-	}
-
-	// cone beam vector
-	else if (_pProjGeom->isOfType("cone_vec")) {
-		astra::CConeVecProjectionGeometry3D* pConeVecGeom = dynamic_cast<astra::CConeVecProjectionGeometry3D*>(_pProjGeom);
-
-		mGeometryInfo["type"] = mxCreateString("cone_vec");
-		mGeometryInfo["DetectorRowCount"] = mxCreateDoubleScalar(pConeVecGeom->getDetectorRowCount());
-		mGeometryInfo["DetectorColCount"] = mxCreateDoubleScalar(pConeVecGeom->getDetectorColCount());
-
-		mxArray* pVectors = mxCreateDoubleMatrix(pConeVecGeom->getProjectionCount(), 12, mxREAL);
-		double* out = mxGetPr(pVectors);
-		int iDetRowCount = pConeVecGeom->getDetectorRowCount();
-		int iDetColCount = pConeVecGeom->getDetectorColCount();
-		int iAngleCount = pConeVecGeom->getProjectionCount();
-		for (int i = 0; i < pConeVecGeom->getProjectionCount(); i++) {
-			const SConeProjection* p = &pConeVecGeom->getProjectionVectors()[i];
-			out[ 0*iAngleCount + i] = p->fSrcX;
-			out[ 1*iAngleCount + i] = p->fSrcY;
-			out[ 2*iAngleCount + i] = p->fSrcZ;
-			out[ 3*iAngleCount + i] = p->fDetSX + 0.5f*iDetRowCount*p->fDetUX + 0.5f*iDetColCount*p->fDetVX;
-			out[ 4*iAngleCount + i] = p->fDetSY + 0.5f*iDetRowCount*p->fDetUY + 0.5f*iDetColCount*p->fDetVY;
-			out[ 5*iAngleCount + i] = p->fDetSZ + 0.5f*iDetRowCount*p->fDetUZ + 0.5f*iDetColCount*p->fDetVZ;
-			out[ 6*iAngleCount + i] = p->fDetUX;
-			out[ 7*iAngleCount + i] = p->fDetUY;
-			out[ 8*iAngleCount + i] = p->fDetUZ;
-			out[ 9*iAngleCount + i] = p->fDetVX;
-			out[10*iAngleCount + i] = p->fDetVY;
-			out[11*iAngleCount + i] = p->fDetVZ;
-		}
-		mGeometryInfo["Vectors"] = pVectors;
-	}
-
-	// build and return the MATLAB struct
-	return buildStruct(mGeometryInfo);
-}
-
 //-----------------------------------------------------------------------------------------
 // parse reconstruction geometry data
 astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
@@ -445,48 +269,6 @@ astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
 										fWindowMaxX, fWindowMaxY);
 }
 
-//-----------------------------------------------------------------------------------------
-// create 2D volume geometry struct
-// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pVolGeom)
-// {
-// 	std::map<std::string, mxArray*> mGeometryInfo;
-
-// 	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
-// 	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
-
-// 	std::map<std::string, mxArray*> mGeometryOptions;
-// 	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
-// 	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
-// 	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
-// 	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
-
-// 	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
-
-// 	return buildStruct(mGeometryInfo);
-// }
-
-//-----------------------------------------------------------------------------------------
-// create 3D volume geometry struct
-// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pVolGeom)
-// {
-// 	std::map<std::string, mxArray*> mGeometryInfo;
-
-// 	mGeometryInfo["GridColCount"] = mxCreateDoubleScalar(_pVolGeom->getGridColCount());
-// 	mGeometryInfo["GridRowCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
-// 	mGeometryInfo["GridSliceCount"] = mxCreateDoubleScalar(_pVolGeom->getGridRowCount());
-
-// 	std::map<std::string, mxArray*> mGeometryOptions;
-// 	mGeometryOptions["WindowMinX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinX());
-// 	mGeometryOptions["WindowMaxX"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxX());
-// 	mGeometryOptions["WindowMinY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinY());
-// 	mGeometryOptions["WindowMaxY"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxY());
-// 	mGeometryOptions["WindowMinZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMinZ());
-// 	mGeometryOptions["WindowMaxZ"] = mxCreateDoubleScalar(_pVolGeom->getWindowMaxZ());
-
-// 	mGeometryInfo["option"] = buildStruct(mGeometryOptions);
-
-// 	return buildStruct(mGeometryInfo);
-// }
 
 //-----------------------------------------------------------------------------------------
 string matlab2string(const mxArray* pField)
@@ -640,7 +422,6 @@ XMLDocument* struct2XML(string rootname, const mxArray* pStruct)
 
 	// read the struct
 	bool ret = readStruct(rootnode, pStruct);
-	//doc->getRootNode()->print();
 	delete rootnode;
 
 	if (!ret) {
@@ -714,8 +495,21 @@ bool mex_is_scalar(const mxArray* pInput)
 	return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
 }
 
+
+
+
+
+
+
+
+
+
+
+
+
+
 //-----------------------------------------------------------------------------------------
-mxArray* config2struct(astra::Config* cfg)
+mxArray* configToStruct(astra::Config* cfg)
 {
 	return XMLNode2struct(cfg->self);
 }
@@ -730,22 +524,67 @@ mxArray* XML2struct(astra::XMLDocument* xml)
 }
 
 //-----------------------------------------------------------------------------------------
-mxArray* XMLNode2option(astra::XMLNode* node)
+mxArray* stringToMxArray(std::string input) 
 {
+	// matrix
+	if (input.find(';') != std::string::npos) {
+
+		// split rows
+		std::vector<std::string> row_strings;
+		std::vector<std::string> col_strings;
+		boost::split(row_strings, input, boost::is_any_of(";"));
+		boost::split(col_strings, row_strings[0], boost::is_any_of(","));
+
+		// get dimensions
+		int rows = row_strings.size();
+		int cols = col_strings.size();
+
+		// init matrix
+		mxArray* pMatrix = mxCreateDoubleMatrix(rows, cols, mxREAL);
+		double* out = mxGetPr(pMatrix);
+
+		// loop elements
+		for (unsigned int row = 0; row < rows; row++) {
+			boost::split(col_strings, row_strings[row], boost::is_any_of(","));
+			// check size
+			for (unsigned int col = 0; col < col_strings.size(); col++) {
+				out[col*rows + row] = boost::lexical_cast<float32>(col_strings[col]);
+			}
+		}
+		return pMatrix;
+	}
+	
+	// vector
+	if (input.find(',') != std::string::npos) {
+
+		// split
+		std::vector<std::string> items;
+		boost::split(items, input, boost::is_any_of(","));
+
+		// init matrix
+		mxArray* pVector = mxCreateDoubleMatrix(1, items.size(), mxREAL);
+		double* out = mxGetPr(pVector);
+
+		// loop elements
+		for (unsigned int i = 0; i < items.size(); i++) {
+			out[i] = boost::lexical_cast<float32>(items[i]);
+		}
+		return pVector;
+	}
+	
+	// number
 	char* end;
-	double content = ::strtod(node->getAttribute("value").c_str(), &end);
+	double content = ::strtod(input.c_str(), &end);
 	bool isnumber = !*end;
-
-	// float
 	if (isnumber) {
 		return mxCreateDoubleScalar(content);
 	}
+	
 	// string
-	else {
-		return mxCreateString(node->getAttribute("value").c_str());
-	}
+	return mxCreateString(input.c_str());
 }
 
+//-----------------------------------------------------------------------------------------
 mxArray* XMLNode2struct(astra::XMLNode* node)
 {
 	std::map<std::string, mxArray*> mList;
@@ -760,30 +599,19 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
 	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
 		XMLNode* subnode = (*it);
 
-		char* end;
-		double content = ::strtod(subnode->getContent().c_str(), &end);
-		bool isnumber = !*end;
-
 		// option
 		if (subnode->getName() == "Option") {
-			mOptions[subnode->getAttribute("key")] = XMLNode2option(subnode);
-		}
-		// list
-		// else if (subnode->hasAttribute("listsize")) {
-		// 	mList[subnode->getName()] = vectorToMxArray(node->getContentNumericalArray());
-		// }
-		// float
-		else if (isnumber) {
-			mList[subnode->getName()] =  mxCreateDoubleScalar(content);
+			mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value"));
 		}
-		// string
+
+		// regular content
 		else {
-			mList[subnode->getName()] =  mxCreateString(subnode->getContent().c_str());
+			mList[subnode->getName()] = stringToMxArray(subnode->getContent());
 		}
 		delete subnode;
 	}
 
-	mList["options"] = buildStruct(mOptions);
+	if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions);
 	return buildStruct(mList);
 }
 
@@ -791,6 +619,12 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
 
 
 
+
+
+
+
+
+//-----------------------------------------------------------------------------------------
 void get3DMatrixDims(const mxArray* x, mwSize *dims)
 {
 	const mwSize* mdims = mxGetDimensions(x);
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index f8a7d48..6c80f8c 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -71,17 +71,13 @@ mxArray* anyToMxArray(boost::any _any);
 astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
 astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
 
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry2D*);
-mxArray* createProjectionGeometryStruct(astra::CProjectionGeometry3D*);
-
-// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry2D* _pReconGeom);
-// mxArray* createVolumeGeometryStruct(astra::CVolumeGeometry3D* _pReconGeom);
-
 astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
 
-mxArray* config2struct(astra::Config* cfg);
+mxArray* configToStruct(astra::Config* cfg);
 mxArray* XML2struct(astra::XMLDocument* xml);
 mxArray* XMLNode2struct(astra::XMLNode* xml);
+mxArray* stringToMxArray(std::string input);
+
 
 void get3DMatrixDims(const mxArray* x, mwSize *dims);
 
-- 
cgit v1.2.3


From 169e912d2633cda7ffc234e78afba1b096e122ea Mon Sep 17 00:00:00 2001
From: Wim van Aarle <wimvanaarle@gmail.com>
Date: Thu, 26 Feb 2015 16:11:38 +0100
Subject: code cleanup

---
 matlab/mex/astra_mex_algorithm_c.cpp       |  17 +-
 matlab/mex/astra_mex_c.cpp                 |   2 +-
 matlab/mex/astra_mex_data2d_c.cpp          |  74 ++--
 matlab/mex/astra_mex_data3d_c.cpp          |   6 +-
 matlab/mex/astra_mex_matrix_c.cpp          |   2 +-
 matlab/mex/astra_mex_projector3d_c.cpp     |  10 +-
 matlab/mex/astra_mex_projector_c.cpp       |  13 +-
 matlab/mex/mexCopyDataHelpFunctions.cpp    |   2 +-
 matlab/mex/mexDataManagerHelpFunctions.cpp |  40 +-
 matlab/mex/mexHelpFunctions.cpp            | 601 ++++++++++-------------------
 matlab/mex/mexHelpFunctions.h              |  39 +-
 11 files changed, 288 insertions(+), 518 deletions(-)

(limited to 'matlab')

diff --git a/matlab/mex/astra_mex_algorithm_c.cpp b/matlab/mex/astra_mex_algorithm_c.cpp
index f719a6b..98cf8a4 100644
--- a/matlab/mex/astra_mex_algorithm_c.cpp
+++ b/matlab/mex/astra_mex_algorithm_c.cpp
@@ -78,26 +78,23 @@ void astra_mex_algorithm_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr
 	}
 
 	// turn MATLAB struct to an XML-based Config object
-	XMLDocument* xml = struct2XML("Algorithm", prhs[1]);
-	Config cfg;
-	cfg.self = xml->getRootNode();
+	Config* cfg = structToConfig("Algorithm", prhs[1]);
 
-	CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg.self->getAttribute("type"));
+	CAlgorithm* pAlg = CAlgorithmFactory::getSingleton().create(cfg->self->getAttribute("type"));
 	if (!pAlg) {
-		delete xml;
+		delete cfg;
 		mexErrMsgTxt("Unknown algorithm. \n");
 		return;
 	}
 
 	// create algorithm
-	if (!pAlg->initialize(cfg)) {
-		delete xml;
+	if (!pAlg->initialize(*cfg)) {
+		delete cfg;
 		delete pAlg;
 		mexErrMsgTxt("Algorithm not initialized. \n");
 		return;
 	}
-
-	delete xml;
+	delete cfg;
 
 	// store algorithm
 	int iIndex = CAlgorithmManager::getSingleton().store(pAlg);
@@ -322,7 +319,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_c.cpp b/matlab/mex/astra_mex_c.cpp
index 2989b7a..760bd51 100644
--- a/matlab/mex/astra_mex_c.cpp
+++ b/matlab/mex/astra_mex_c.cpp
@@ -122,7 +122,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT0: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_data2d_c.cpp b/matlab/mex/astra_mex_data2d_c.cpp
index 03d3807..5f79e98 100644
--- a/matlab/mex/astra_mex_data2d_c.cpp
+++ b/matlab/mex/astra_mex_data2d_c.cpp
@@ -98,10 +98,10 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 		return;
 	}
 
-	string sDataType = mex_util_get_string(prhs[1]);	
+	string sDataType = mexToString(prhs[1]);	
 	CFloat32Data2D* pDataObject2D = NULL;
 
-	if (nrhs >= 4 && !(mex_is_scalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) {
+	if (nrhs >= 4 && !(mexIsScalar(prhs[3])|| mxIsDouble(prhs[3]) || mxIsLogical(prhs[3]) || mxIsSingle(prhs[3]) )) {
 		mexErrMsgTxt("Data must be single, double or logical.");
 		return;
 	}
@@ -116,23 +116,20 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 		if (!mxIsStruct(prhs[2])) {
 			mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
 		}
-		XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
-		if (!xml)
-			return;
-		Config cfg;
-		cfg.self = xml->getRootNode();
+		
+		Config* cfg = structToConfig("VolumeGeometry", prhs[2]);
 		CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
-		if (!pGeometry->initialize(cfg)) {
+		if (!pGeometry->initialize(*cfg)) {
 			mexErrMsgTxt("Geometry class not initialized. \n");
-			delete xml;
+			delete cfg;
 			delete pGeometry;
 			return;
 		}
 		// If data is specified, check dimensions
-		if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+		if (nrhs >= 4 && !mexIsScalar(prhs[3])) {
 			if (pGeometry->getGridColCount() != mxGetN(prhs[3]) || pGeometry->getGridRowCount() != mxGetM(prhs[3])) {
 				mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
-				delete xml;
+				delete cfg;
 				delete pGeometry;
 				return;
 			}
@@ -140,21 +137,18 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 		// Initialize data object
 		pDataObject2D = new CFloat32VolumeData2D(pGeometry);		
 		delete pGeometry;
-		delete xml;
+		delete cfg;
 	}
 	else if (sDataType == "-sino") {
 		// Read geometry
 		if (!mxIsStruct(prhs[2])) {
 			mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
 		}
-		XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
-		if (!xml)
-			return;
-		Config cfg;
-		cfg.self = xml->getRootNode();
+		
+		Config* cfg = structToConfig("ProjectionGeometry", prhs[2]);
 		// FIXME: Change how the base class is created. (This is duplicated
 		// in 'change_geometry' and Projector2D.cpp.)
-		std::string type = cfg.self->getAttribute("type");
+		std::string type = cfg->self->getAttribute("type");
 		CProjectionGeometry2D* pGeometry;
 		if (type == "sparse_matrix") {
 			pGeometry = new CSparseMatrixProjectionGeometry2D();
@@ -168,25 +162,25 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 		} else {
 			pGeometry = new CParallelProjectionGeometry2D();	
 		}
-		if (!pGeometry->initialize(cfg)) {
+		if (!pGeometry->initialize(*cfg)) {
 			mexErrMsgTxt("Geometry class not initialized. \n");
 			delete pGeometry;
-			delete xml;
+			delete cfg;
 			return;
 		}
 		// If data is specified, check dimensions
-		if (nrhs >= 4 && !mex_is_scalar(prhs[3])) {
+		if (nrhs >= 4 && !mexIsScalar(prhs[3])) {
 			if (pGeometry->getDetectorCount() != mxGetN(prhs[3]) || pGeometry->getProjectionAngleCount() != mxGetM(prhs[3])) {
 				mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
 				delete pGeometry;
-				delete xml;
+				delete cfg;
 				return;
 			}
 		}
 		// Initialize data object
 		pDataObject2D = new CFloat32ProjectionData2D(pGeometry);
 		delete pGeometry;
-		delete xml;
+		delete cfg;
 	}
 	else {
 		mexErrMsgTxt("Invalid datatype.  Please specify '-vol' or '-sino'. \n");
@@ -210,7 +204,7 @@ void astra_mex_data2d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 	// Store data
 	if (nrhs >= 4) {
 		// fill with scalar value
-		if (mex_is_scalar(prhs[3])) {
+		if (mexIsScalar(prhs[3])) {
 			float32 fValue = (float32)mxGetScalar(prhs[3]);
 			for (int i = 0; i < pDataObject2D->getSize(); ++i) {
 				pDataObject2D->getData()[i] = fValue;
@@ -294,7 +288,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
 	}
 	int iDataID = (int)(mxGetScalar(prhs[1]));
 
-	if (!(mex_is_scalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) {
+	if (!(mexIsScalar(prhs[2]) || mxIsDouble(prhs[2]) || mxIsLogical(prhs[2]) || mxIsSingle(prhs[2]))) {
 		mexErrMsgTxt("Data must be single, double or logical.");
 		return;
 	}
@@ -312,7 +306,7 @@ void astra_mex_data2d_store(int nlhs, mxArray* plhs[], int nrhs, const mxArray*
 	
 	// step3: insert data
 	// fill with scalar value
-	if (mex_is_scalar(prhs[2])) {
+	if (mexIsScalar(prhs[2])) {
 		float32 fValue = (float32)mxGetScalar(prhs[2]);
 		for (int i = 0; i < pDataObject->getSize(); ++i) {
 			pDataObject->getData()[i] = fValue;
@@ -440,12 +434,10 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
 		if (!mxIsStruct(prhs[2])) {
 			mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
 		}
-		XMLDocument* xml = struct2XML("ProjectionGeometry", prhs[2]);
-		Config cfg;
-		cfg.self = xml->getRootNode();
+		Config* cfg = structToConfig("ProjectionGeometry2D", prhs[2]);
 		// FIXME: Change how the base class is created. (This is duplicated
 		// in 'create' and Projector2D.cpp.)
-		std::string type = cfg.self->getAttribute("type");
+		std::string type = cfg->self->getAttribute("type");
 		CProjectionGeometry2D* pGeometry;
 		if (type == "sparse_matrix") {
 			pGeometry = new CSparseMatrixProjectionGeometry2D();
@@ -459,24 +451,24 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
 		} else {
 			pGeometry = new CParallelProjectionGeometry2D();	
 		}
-		if (!pGeometry->initialize(cfg)) {
+		if (!pGeometry->initialize(*cfg)) {
 			mexErrMsgTxt("Geometry class not initialized. \n");
 			delete pGeometry;
-			delete xml;
+			delete cfg;
 			return;
 		}
 		// If data is specified, check dimensions
 		if (pGeometry->getDetectorCount() != pSinogram->getDetectorCount() || pGeometry->getProjectionAngleCount() != pSinogram->getAngleCount()) {
 			mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
 			delete pGeometry;
-			delete xml;
+			delete cfg;
 			return;
 		}
 
 		// If ok, change geometry
 		pSinogram->changeGeometry(pGeometry);
 		delete pGeometry;
-		delete xml;
+		delete cfg;
 
 		return;
 	}
@@ -490,27 +482,25 @@ void astra_mex_data2d_change_geometry(int nlhs, mxArray* plhs[], int nrhs, const
 		if (!mxIsStruct(prhs[2])) {
 			mexErrMsgTxt("Argument 3 is not a valid MATLAB struct.\n");
 		}
-		XMLDocument* xml = struct2XML(string("VolumeGeometry"), prhs[2]);
-		Config cfg;
-		cfg.self = xml->getRootNode();
+		Config* cfg = structToConfig("VolumeGeometry2D", prhs[2]);
 		CVolumeGeometry2D* pGeometry = new CVolumeGeometry2D();
-		if (!pGeometry->initialize(cfg)) {
+		if (!pGeometry->initialize(*cfg)) {
 			mexErrMsgTxt("Geometry class not initialized. \n");
-			delete xml;
+			delete cfg;
 			delete pGeometry;
 			return;
 		}
 		// If data is specified, check dimensions
 		if (pGeometry->getGridColCount() != pVolume->getWidth() || pGeometry->getGridRowCount() != pVolume->getHeight()) {
 			mexErrMsgTxt("The dimensions of the data do not match those specified in the geometry. \n");
-			delete xml;
+			delete cfg;
 			delete pGeometry;
 			return;
 		}
 
 		// If ok, change geometry
 		pVolume->changeGeometry(pGeometry);
-		delete xml;
+		delete cfg;
 		delete pGeometry;
 
 	}
@@ -639,7 +629,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT0: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_data3d_c.cpp b/matlab/mex/astra_mex_data3d_c.cpp
index 64c013d..0a3f85d 100644
--- a/matlab/mex/astra_mex_data3d_c.cpp
+++ b/matlab/mex/astra_mex_data3d_c.cpp
@@ -83,7 +83,7 @@ void astra_mex_data3d_create(int& nlhs, mxArray* plhs[], int& nrhs, const mxArra
 		return;
 	}
 
-	const string sDataType = mex_util_get_string(prhs[1]);
+	const string sDataType = mexToString(prhs[1]);
 
 	// step2: Allocate data
 	CFloat32Data3DMemory* pDataObject3D =
@@ -152,7 +152,7 @@ void astra_mex_data3d_link(int& nlhs, mxArray* plhs[], int& nrhs, const mxArray*
 		return;
 	}
 
-	string sDataType = mex_util_get_string(prhs[1]);
+	string sDataType = mexToString(prhs[1]);
 
 	// step2: Allocate data
 	CFloat32Data3DMemory* pDataObject3D =
@@ -365,7 +365,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_matrix_c.cpp b/matlab/mex/astra_mex_matrix_c.cpp
index 016566a..01ad08b 100644
--- a/matlab/mex/astra_mex_matrix_c.cpp
+++ b/matlab/mex/astra_mex_matrix_c.cpp
@@ -406,7 +406,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT0: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_projector3d_c.cpp b/matlab/mex/astra_mex_projector3d_c.cpp
index b2f6b02..5381cf6 100644
--- a/matlab/mex/astra_mex_projector3d_c.cpp
+++ b/matlab/mex/astra_mex_projector3d_c.cpp
@@ -65,16 +65,16 @@ void astra_mex_projector3d_create(int nlhs, mxArray* plhs[], int nrhs, const mxA
 	}
 
 	// turn MATLAB struct to an XML-based Config object
-	XMLDocument* xml = struct2XML("Projector3D", prhs[1]);
-	Config cfg;
-	cfg.self = xml->getRootNode();
+	Config* cfg = structToConfig("Projector3D", prhs[1]);
 
 	// create algorithm
-	CProjector3D* pProj = CProjector3DFactory::getSingleton().create(cfg);
+	CProjector3D* pProj = CProjector3DFactory::getSingleton().create(*cfg);
 	if (pProj == NULL) {
+		delete cfg;
 		mexErrMsgTxt("Error creating Projector3D. \n");
 		return;
 	}
+	delete cfg;
 
 	// store projector
 	int iIndex = CProjector3DManager::getSingleton().store(pProj);
@@ -397,7 +397,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/astra_mex_projector_c.cpp b/matlab/mex/astra_mex_projector_c.cpp
index 4793020..58cd953 100644
--- a/matlab/mex/astra_mex_projector_c.cpp
+++ b/matlab/mex/astra_mex_projector_c.cpp
@@ -74,19 +74,16 @@ void astra_mex_projector_create(int nlhs, mxArray* plhs[], int nrhs, const mxArr
 
 
 	// turn MATLAB struct to an XML-based Config object
-	XMLDocument* xml = struct2XML("Projector2D", prhs[1]);
-	Config cfg;
-	cfg.self = xml->getRootNode();
+	Config* cfg = structToConfig("Projector2D", prhs[1]);
 
 	// create algorithm
-	CProjector2D* pProj = CProjector2DFactory::getSingleton().create(cfg);
+	CProjector2D* pProj = CProjector2DFactory::getSingleton().create(*cfg);
 	if (pProj == NULL) {
-		delete xml;
+		delete cfg;
 		mexErrMsgTxt("Error creating projector. \n");
 		return;
 	}
-
-	delete xml;
+	delete cfg;
 
 	// store projector
 	iIndex = CProjector2DManager::getSingleton().store(pProj);
@@ -473,7 +470,7 @@ void mexFunction(int nlhs, mxArray* plhs[],
 	// INPUT: Mode
 	string sMode = "";
 	if (1 <= nrhs) {
-		sMode = mex_util_get_string(prhs[0]);	
+		sMode = mexToString(prhs[0]);	
 	} else {
 		printHelp();
 		return;
diff --git a/matlab/mex/mexCopyDataHelpFunctions.cpp b/matlab/mex/mexCopyDataHelpFunctions.cpp
index 6dfd4a6..80fb834 100644
--- a/matlab/mex/mexCopyDataHelpFunctions.cpp
+++ b/matlab/mex/mexCopyDataHelpFunctions.cpp
@@ -263,7 +263,7 @@ copyMexToCFloat32Array(const mxArray * const in,
 #pragma omp parallel
 	{
 		// fill with scalar value
-		if (mex_is_scalar(in)) {
+		if (mexIsScalar(in)) {
 			astra::float32 fValue = 0.f;
 			if (!mxIsEmpty(in)) {
 				fValue = (astra::float32)mxGetScalar(in);
diff --git a/matlab/mex/mexDataManagerHelpFunctions.cpp b/matlab/mex/mexDataManagerHelpFunctions.cpp
index f9d971c..d482428 100644
--- a/matlab/mex/mexDataManagerHelpFunctions.cpp
+++ b/matlab/mex/mexDataManagerHelpFunctions.cpp
@@ -105,7 +105,7 @@ checkID(const astra::int32 & id, astra::CFloat32Data3DMemory *& pDataObj)
 bool
 checkDataType(const mxArray * const in)
 {
-	return (mex_is_scalar(in) || mxIsDouble(in) || mxIsSingle(in) || mxIsLogical(in));
+	return (mexIsScalar(in) || mxIsDouble(in) || mxIsSingle(in) || mxIsLogical(in));
 }
 
 //-----------------------------------------------------------------------------------------
@@ -213,7 +213,7 @@ allocateDataObject(const std::string & sDataType,
 	bool bUnshare = true;
 	if (unshare)
 	{
-		if (!mex_is_scalar(unshare))
+		if (!mexIsScalar(unshare))
 		{
 			mexErrMsgTxt("Argument 5 (read-only) must be scalar");
 			return NULL;
@@ -225,7 +225,7 @@ allocateDataObject(const std::string & sDataType,
 	mwIndex iZ = 0;
 	if (zIndex)
 	{
-		if (!mex_is_scalar(zIndex))
+		if (!mexIsScalar(zIndex))
 		{
 			mexErrMsgTxt("Argument 6 (Z) must be scalar");
 			return NULL;
@@ -237,25 +237,19 @@ allocateDataObject(const std::string & sDataType,
 	if (sDataType == "-vol")
 	{
 		// Read geometry
-		astra::XMLDocument* xml = struct2XML("VolumeGeometry", geometry);
-		if (!xml) {
-			return NULL;
-		}
-		astra::Config cfg;
-		cfg.self = xml->getRootNode();
-
+		astra::Config* cfg = structToConfig("VolumeGeometry3D", geometry);
 		astra::CVolumeGeometry3D* pGeometry = new astra::CVolumeGeometry3D();
-		if (!pGeometry->initialize(cfg))
+		if (!pGeometry->initialize(*cfg))
 		{
 			mexErrMsgTxt("Geometry class not initialized. \n");
 			delete pGeometry;
-			delete xml;
+			delete cfg;
 			return NULL;
 		}
-		delete xml;
+		delete cfg;
 
 		// If data is specified, check dimensions
-		if (data && !mex_is_scalar(data))
+		if (data && !mexIsScalar(data))
 		{
 			if (! (zIndex
 					? checkDataSize(data, pGeometry, iZ)
@@ -288,16 +282,10 @@ allocateDataObject(const std::string & sDataType,
 	else if (sDataType == "-sino" || sDataType == "-proj3d" || sDataType == "-sinocone")
 	{
 		// Read geometry
-		astra::XMLDocument* xml = struct2XML("ProjectionGeometry", geometry);
-		if (!xml) {
-			return NULL;
-		}
-		astra::Config cfg;
-		cfg.self = xml->getRootNode();
-
+		astra::Config* cfg = structToConfig("ProjectionGeometry3D", geometry);
 		// FIXME: Change how the base class is created. (This is duplicated
 		// in Projector3D.cpp.)
-		std::string type = cfg.self->getAttribute("type");
+		std::string type = cfg->self->getAttribute("type");
 		astra::CProjectionGeometry3D* pGeometry = 0;
 		if (type == "parallel3d") {
 			pGeometry = new astra::CParallelProjectionGeometry3D();
@@ -312,16 +300,16 @@ allocateDataObject(const std::string & sDataType,
 			return NULL;
 		}
 
-		if (!pGeometry->initialize(cfg)) {
+		if (!pGeometry->initialize(*cfg)) {
 			mexErrMsgTxt("Geometry class not initialized. \n");
 			delete pGeometry;
-			delete xml;
+			delete cfg;
 			return NULL;
 		}
-		delete xml;
+		delete cfg;
 
 		// If data is specified, check dimensions
-		if (data && !mex_is_scalar(data))
+		if (data && !mexIsScalar(data))
 		{
 			if (! (zIndex
 					? checkDataSize(data, pGeometry, iZ)
diff --git a/matlab/mex/mexHelpFunctions.cpp b/matlab/mex/mexHelpFunctions.cpp
index c25123a..c0ac711 100644
--- a/matlab/mex/mexHelpFunctions.cpp
+++ b/matlab/mex/mexHelpFunctions.cpp
@@ -38,307 +38,154 @@ $Id$
 #include <boost/algorithm/string/split.hpp>
 #include <boost/algorithm/string/classification.hpp>
 
-#include "astra/SparseMatrixProjectionGeometry2D.h"
-#include "astra/FanFlatVecProjectionGeometry2D.h"
-#include "astra/AstraObjectManager.h"
-
 using namespace std;
 using namespace astra;
 
 
 //-----------------------------------------------------------------------------------------
 // get string from matlab 
-std::string mex_util_get_string(const mxArray* pInput)
+string mexToString(const mxArray* pInput)
 {
-	if (!mxIsChar(pInput)) {
-		return "";
+	// is string?
+	if (mxIsChar(pInput)) {
+		mwSize iLength = mxGetNumberOfElements(pInput) + 1;
+		char* buf = new char[iLength]; 
+		mxGetString(pInput, buf, iLength);
+		std::string res = std::string(buf);
+		delete[] buf;
+		return res;
 	}
-	mwSize iLength = mxGetNumberOfElements(pInput) + 1;
-	char* buf = new char[iLength]; 
-	mxGetString(pInput, buf, iLength);
-	std::string res = std::string(buf);
-	delete[] buf;
-	return res;
+
+	// is scalar?
+	if (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1) {
+		return boost::lexical_cast<string>(mxGetScalar(pInput));
+	}
+
+	return "";
 }
 
 //-----------------------------------------------------------------------------------------
-// is option
-bool isOption(std::list<std::string> lOptions, std::string sOption) 
+// return true if the argument is a scalar
+bool mexIsScalar(const mxArray* pInput)
 {
-	return std::find(lOptions.begin(), lOptions.end(), sOption) != lOptions.end();
+	return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
 }
 
 //-----------------------------------------------------------------------------------------
-// turn a matlab struct into a c++ map
-std::map<std::string, mxArray*> parseStruct(const mxArray* pInput) 
+void get3DMatrixDims(const mxArray* x, mwSize *dims)
 {
-	std::map<std::string, mxArray*> res;
-
-	// check type
-	if (!mxIsStruct(pInput)) {
-      mexErrMsgTxt("Input must be a struct.");
-	  return res;
+	const mwSize* mdims = mxGetDimensions(x);
+	mwSize dimCount = mxGetNumberOfDimensions(x);
+	if (dimCount == 1) {
+		dims[0] = mdims[0];
+		dims[1] = 1;
+		dims[2] = 1;
+	} else if (dimCount == 2) {
+		dims[0] = mdims[0];
+		dims[1] = mdims[1];
+		dims[2] = 1;
+	} else if (dimCount == 3) {
+		dims[0] = mdims[0];
+		dims[1] = mdims[1];
+		dims[2] = mdims[2];
+	} else {
+		dims[0] = 0;
+		dims[1] = 0;
+		dims[2] = 0;
 	}
+} 
+
+
+
+
 
-	// get field names
-	int nfields = mxGetNumberOfFields(pInput);
-	for (int i = 0; i < nfields; i++) {
-		std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i));
-		res[sFieldName] = mxGetFieldByNumber(pInput,0,i);
-	}
-	return res;
-}
 
 //-----------------------------------------------------------------------------------------
-// turn a c++ map into a matlab struct
-mxArray* buildStruct(std::map<std::string, mxArray*> mInput) 
+// turn an std vector<float32> object to an mxArray
+mxArray* vectorToMxArray(std::vector<astra::float32> mInput)
 {
-	mwSize dims[2] = {1, 1};
-	mxArray* res = mxCreateStructArray(2,dims,0,0);
-	
-	for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) {
-		mxAddField(res, (*it).first.c_str());
-		mxSetField(res, 0, (*it).first.c_str(), (*it).second);
+	mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL);
+	double* pdData = mxGetPr(res);
+	for (unsigned int i = 0; i < mInput.size(); i++) {
+		pdData[i] = mInput[i];
 	}
 	return res;
 }
 
 //-----------------------------------------------------------------------------------------
-// parse projection geometry data
-astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray* prhs)
+// turn a vector<vector<float32>> object to an mxArray
+mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput)
 {
-	// parse struct	
-	std::map<string, mxArray*> mStruct = parseStruct(prhs);
-
-	// create projection geometry object
-	string type = mex_util_get_string(mStruct["type"]);
-	if (type == "parallel") {
-
-		// detector_width
-		float32 fDetWidth = 1.0f;
-		mxArray* tmp = mStruct["detector_width"];
-		if (tmp != NULL) {
-			fDetWidth = (float32)(mxGetScalar(tmp));
-		}
-
-		// detector_count
-		int iDetCount = 100;
-		tmp = mStruct["detector_count"];
-		if (tmp != NULL) {
-			iDetCount = (int)(mxGetScalar(tmp));
-		}
-
-		// angles
-		float32* pfAngles;
-		int iAngleCount;
-		tmp = mStruct["projection_angles"];
-		if (tmp != NULL) {
-			double* angleValues = mxGetPr(tmp);
-			iAngleCount = mxGetN(tmp) * mxGetM(tmp);
-			pfAngles = new float32[iAngleCount];
-			for (int i = 0; i < iAngleCount; i++) {
-				pfAngles[i] = angleValues[i];
-			}
-		} else {
-			mexErrMsgTxt("'angles' not specified, error.");
-			return NULL;
-		}
-
-		// create projection geometry
-		return new astra::CParallelProjectionGeometry2D(iAngleCount,	// number of projections
-														iDetCount,		// number of detectors
-														fDetWidth,		// width of the detectors
-														pfAngles);		// angles array
-	} 
-	
-	else if (type == "fanflat") {
-
-		// detector_width
-		float32 fDetWidth = 1.0f;
-		mxArray* tmp = mStruct["detector_width"];
-		if (tmp != NULL) {
-			fDetWidth = (float32)(mxGetScalar(tmp));
-		}
-
-		// detector_count
-		int iDetCount = 100;
-		tmp = mStruct["detector_count"];
-		if (tmp != NULL) {
-			iDetCount = (int)(mxGetScalar(tmp));
-		}
-
-		// angles
-		float32* pfAngles;
-		int iAngleCount;
-		tmp = mStruct["projection_angles"];
-		if (tmp != NULL) {
-			double* angleValues = mxGetPr(tmp);
-			iAngleCount = mxGetN(tmp) * mxGetM(tmp);
-			pfAngles = new float32[iAngleCount];
-			for (int i = 0; i < iAngleCount; i++) {
-				pfAngles[i] = angleValues[i];
-			}
-		} else {
-			mexErrMsgTxt("'angles' not specified, error.");
-			return NULL;
-		}
-
-		// origin_source_dist
-		int iDistOriginSource = 100;
-		tmp = mStruct["origin_source_dist"];
-		if (tmp != NULL) {
-			iDistOriginSource = (int)(mxGetScalar(tmp));
-		}
+	unsigned int sizex = mInput.size();
+	if (sizex == 0) return mxCreateString("empty");
+	unsigned int sizey = mInput[0].size();
 
-		// origin_det_dist
-		int iDistOriginDet = 100;
-		tmp = mStruct["origin_det_dist"];
-		if (tmp != NULL) {
-			iDistOriginDet = (int)(mxGetScalar(tmp));
+	mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL);
+	double* pdData = mxGetPr(res);
+	for (unsigned int i = 0; i < sizex; i++) {
+		for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) {
+			pdData[j*sizex+i] = mInput[i][j];
 		}
-
-		// create projection geometry
-		return new astra::CFanFlatProjectionGeometry2D(iAngleCount,			// number of projections
-													   iDetCount,			// number of detectors
-													   fDetWidth,			// width of the detectors
-													   pfAngles,			// angles array
-													   iDistOriginSource,	// distance origin source
-													   iDistOriginDet);		// distance origin detector
-	}
-
-	else {
-		mexPrintf("Only parallel and fanflat projection geometry implemented.");
-		return NULL;
 	}
+	return res;
 }
 
 //-----------------------------------------------------------------------------------------
-// parse reconstruction geometry data
-astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray* prhs)
+// turn a boost::any object to an mxArray
+mxArray* anyToMxArray(boost::any _any) 
 {
-	// parse struct	
-	std::map<string, mxArray*> mStruct = parseStruct(prhs);
-
-	std::map<string, mxArray*> mOptions = parseStruct(mStruct["option"]);
-
-	// GridColCount
-	int iWindowColCount = 128;
-	mxArray* tmp = mStruct["GridColCount"];
-	if (tmp != NULL) {
-		iWindowColCount = (int)(mxGetScalar(tmp));
-	} 
-
-	// GridRowCount
-	int iWindowRowCount = 128;
-	tmp = mStruct["GridRowCount"];
-	if (tmp != NULL) {
-		iWindowRowCount = (int)(mxGetScalar(tmp));
+	if (_any.type() == typeid(std::string)) {
+		std::string str = boost::any_cast<std::string>(_any);
+		return mxCreateString(str.c_str());     
 	}
-
-	// WindowMinX
-	float32 fWindowMinX = - iWindowColCount / 2;
-	tmp = mOptions["WindowMinX"];
-	if (tmp != NULL) {
-		fWindowMinX = (float32)(mxGetScalar(tmp));
-	} 
-
-	// WindowMaxX
-	float32 fWindowMaxX = iWindowColCount / 2;
-	tmp = mOptions["WindowMaxX"];
-	if (tmp != NULL) {
-		fWindowMaxX = (float32)(mxGetScalar(tmp));
-	} 
-
-	// WindowMinY
-	float32 fWindowMinY = - iWindowRowCount / 2;
-	tmp = mOptions["WindowMinY"];
-	if (tmp != NULL) {
-		fWindowMinY = (float32)(mxGetScalar(tmp));
-	} 
-
-	// WindowMaxX
-	float32 fWindowMaxY = iWindowRowCount / 2;
-	tmp = mOptions["WindowMaxY"];
-	if (tmp != NULL) {
-		fWindowMaxY = (float32)(mxGetScalar(tmp));
-	} 
-	
-	// create and return reconstruction geometry
-	return new astra::CVolumeGeometry2D(iWindowColCount, iWindowRowCount, 
-										fWindowMinX, fWindowMinY, 
-										fWindowMaxX, fWindowMaxY);
+	if (_any.type() == typeid(int)) {
+		return mxCreateDoubleScalar(boost::any_cast<int>(_any));
+	}
+	if (_any.type() == typeid(float32)) {
+		return mxCreateDoubleScalar(boost::any_cast<float32>(_any));
+	}
+	if (_any.type() == typeid(std::vector<astra::float32>)) {
+		return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any));
+	}
+	if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) {
+		return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any));
+	}
+	return NULL;
 }
 
 
-//-----------------------------------------------------------------------------------------
-string matlab2string(const mxArray* pField)
-{
-	// is string?
-	if (mxIsChar(pField)) {
-		return mex_util_get_string(pField);
-	}
 
-	// is scalar?
-	if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {
-		return boost::lexical_cast<string>(mxGetScalar(pField));
-	}
 
-	return "";
-}
+
+
+
+
 
 //-----------------------------------------------------------------------------------------
-// Options struct to xml node
-bool readOptions(XMLNode* node, const mxArray* pOptionStruct)
+// turn a MATLAB struct into a Config object
+Config* structToConfig(string rootname, const mxArray* pStruct)
 {
-	// loop all fields
-	int nfields = mxGetNumberOfFields(pOptionStruct);
-	for (int i = 0; i < nfields; i++) {
-		std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));
-		const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i);
+	if (!mxIsStruct(pStruct)) {
+		mexErrMsgTxt("Input must be a struct.");
+		return NULL;
+	}
 
-		if (node->hasOption(sFieldName)) {
-			mexErrMsgTxt("Duplicate option");
-			return false;
-		}
-	
-		// string or scalar
-		if (mxIsChar(pField) || mex_is_scalar(pField)) {
-			string sValue = matlab2string(pField);
-			node->addOption(sFieldName, sValue);
-		} else
-		// numerical array
-		if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
-			if (!mxIsDouble(pField)) {
-				mexErrMsgTxt("Numeric input must be double.");
-				return false;
-			}
+	// create the document
+	Config* cfg = new Config();
+	cfg->initialize(rootname);
 
-			XMLNode* listbase = node->addChildNode("Option");
-			listbase->addAttribute("key", sFieldName);
-			listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
-			double* pdValues = mxGetPr(pField);
-			int index = 0;
-			for (unsigned int row = 0; row < mxGetM(pField); row++) {
-				for (unsigned int col = 0; col < mxGetN(pField); col++) {
-					XMLNode* item = listbase->addChildNode("ListItem");
-					item->addAttribute("index", index);
-					item->addAttribute("value", pdValues[col*mxGetM(pField)+row]);
-					index++;
-					delete item;
-				}
-			}
-			delete listbase;
-		} else {
-			mexErrMsgTxt("Unsupported option type");
-			return false;
-		}
+	// read the struct
+	bool ret = structToXMLNode(cfg->self, pStruct);
+	if (!ret) {
+		delete cfg;
+		mexErrMsgTxt("Error parsing struct.");
+		return NULL;		
 	}
-	return true;
+	return cfg;
 }
 
 //-----------------------------------------------------------------------------------------
-// struct to xml node
-bool readStruct(XMLNode* root, const mxArray* pStruct)
+bool structToXMLNode(XMLNode* node, const mxArray* pStruct) 
 {
 	// loop all fields
 	int nfields = mxGetNumberOfFields(pStruct);
@@ -350,27 +197,27 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
 
 		// string
 		if (mxIsChar(pField)) {
-			string sValue = matlab2string(pField);
+			string sValue = mexToString(pField);
 			if (sFieldName == "type") {
-				root->addAttribute("type", sValue);
+				node->addAttribute("type", sValue);
 			} else {
-				delete root->addChildNode(sFieldName, sValue);
+				delete node->addChildNode(sFieldName, sValue);
 			}
 		}
 
 		// scalar
-		if (mex_is_scalar(pField)) {
-			string sValue = matlab2string(pField);
-			delete root->addChildNode(sFieldName, sValue);
+		else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) == 1) {
+			string sValue = mexToString(pField);
+			delete node->addChildNode(sFieldName, sValue);
 		}
 
 		// numerical array
-		if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+		else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
 			if (!mxIsDouble(pField)) {
 				mexErrMsgTxt("Numeric input must be double.");
 				return false;
 			}
-			XMLNode* listbase = root->addChildNode(sFieldName);
+			XMLNode* listbase = node->addChildNode(sFieldName);
 			listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
 			double* pdValues = mxGetPr(pField);
 			int index = 0;
@@ -386,16 +233,15 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
 			delete listbase;
 		}
 
-
 		// not castable to a single string
-		if (mxIsStruct(pField)) {
+		else if (mxIsStruct(pField)) {
 			if (sFieldName == "options" || sFieldName == "option" || sFieldName == "Options" || sFieldName == "Option") {
-				bool ret = readOptions(root, pField);
+				bool ret = optionsToXMLNode(node, pField);
 				if (!ret)
 					return false;
 			} else {
-				XMLNode* newNode = root->addChildNode(sFieldName);
-				bool ret = readStruct(newNode, pField);
+				XMLNode* newNode = node->addChildNode(sFieldName);
+				bool ret = structToXMLNode(newNode, pField);
 				delete newNode;
 				if (!ret)
 					return false;
@@ -406,93 +252,74 @@ bool readStruct(XMLNode* root, const mxArray* pStruct)
 
 	return true;
 }
-
 //-----------------------------------------------------------------------------------------
-// turn a MATLAB struct into an XML Document
-XMLDocument* struct2XML(string rootname, const mxArray* pStruct)
+// Options struct to xml node
+bool optionsToXMLNode(XMLNode* node, const mxArray* pOptionStruct)
 {
-	if (!mxIsStruct(pStruct)) {
-      mexErrMsgTxt("Input must be a struct.");
-	  return NULL;
-	}
-
-	// create the document
-	XMLDocument* doc = XMLDocument::createDocument(rootname);
-	XMLNode* rootnode = doc->getRootNode();
-
-	// read the struct
-	bool ret = readStruct(rootnode, pStruct);
-	delete rootnode;
-
-	if (!ret) {
-		delete doc;
-		doc = 0;
-	}
-
-	return doc;
-}
-
-
-
+	// loop all fields
+	int nfields = mxGetNumberOfFields(pOptionStruct);
+	for (int i = 0; i < nfields; i++) {
+		std::string sFieldName = std::string(mxGetFieldNameByNumber(pOptionStruct, i));
+		const mxArray* pField = mxGetFieldByNumber(pOptionStruct, 0, i);
 
+		if (node->hasOption(sFieldName)) {
+			mexErrMsgTxt("Duplicate option");
+			return false;
+		}
+	
+		// string or scalar
+		if (mxIsChar(pField) || mexIsScalar(pField)) {
+			string sValue = mexToString(pField);
+			node->addOption(sFieldName, sValue);
+		}
+		// numerical array
+		else if (mxIsNumeric(pField) && mxGetM(pField)*mxGetN(pField) > 1) {
+			if (!mxIsDouble(pField)) {
+				mexErrMsgTxt("Numeric input must be double.");
+				return false;
+			}
 
-//-----------------------------------------------------------------------------------------
-// turn an std vector<float32> object to an mxArray
-mxArray* vectorToMxArray(std::vector<astra::float32> mInput)
-{
-	mxArray* res = mxCreateDoubleMatrix(1, mInput.size(), mxREAL);
-	double* pdData = mxGetPr(res);
-	for (unsigned int i = 0; i < mInput.size(); i++) {
-		pdData[i] = mInput[i];
+			XMLNode* listbase = node->addChildNode("Option");
+			listbase->addAttribute("key", sFieldName);
+			listbase->addAttribute("listsize", mxGetM(pField)*mxGetN(pField));
+			double* pdValues = mxGetPr(pField);
+			int index = 0;
+			for (unsigned int row = 0; row < mxGetM(pField); row++) {
+				for (unsigned int col = 0; col < mxGetN(pField); col++) {
+					XMLNode* item = listbase->addChildNode("ListItem");
+					item->addAttribute("index", index);
+					item->addAttribute("value", pdValues[col*mxGetM(pField)+row]);
+					index++;
+					delete item;
+				}
+			}
+			delete listbase;
+		} else {
+			mexErrMsgTxt("Unsupported option type");
+			return false;
+		}
 	}
-	return res;
+	return true;
 }
-
 //-----------------------------------------------------------------------------------------
-// turn a vector<vector<float32>> object to an mxArray
-mxArray* vector2DToMxArray(std::vector<std::vector<astra::float32> > mInput)
+// turn a matlab struct into a c++ map
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput) 
 {
-	unsigned int sizex = mInput.size();
-	if (sizex == 0) return mxCreateString("empty");
-	unsigned int sizey = mInput[0].size();
+	std::map<std::string, mxArray*> res;
 
-	mxArray* res = mxCreateDoubleMatrix(sizex, sizey, mxREAL);
-	double* pdData = mxGetPr(res);
-	for (unsigned int i = 0; i < sizex; i++) {
-		for (unsigned int j = 0; j < sizey && j < mInput[i].size(); j++) {
-			pdData[j*sizex+i] = mInput[i][j];
-		}
+	// check type
+	if (!mxIsStruct(pInput)) {
+      mexErrMsgTxt("Input must be a struct.");
+	  return res;
 	}
-	return res;
-}
 
-//-----------------------------------------------------------------------------------------
-// turn a boost::any object to an mxArray
-mxArray* anyToMxArray(boost::any _any) 
-{
-	if (_any.type() == typeid(std::string)) {
-		std::string str = boost::any_cast<std::string>(_any);
-		return mxCreateString(str.c_str());     
-	}
-	if (_any.type() == typeid(int)) {
-		return mxCreateDoubleScalar(boost::any_cast<int>(_any));
-	}
-	if (_any.type() == typeid(float32)) {
-		return mxCreateDoubleScalar(boost::any_cast<float32>(_any));
-	}
-	if (_any.type() == typeid(std::vector<astra::float32>)) {
-		return vectorToMxArray(boost::any_cast<std::vector<float32> >(_any));
-	}
-	if (_any.type() == typeid(std::vector<std::vector<astra::float32> >)) {
-		return vector2DToMxArray(boost::any_cast<std::vector<std::vector<float32> > >(_any));
+	// get field names
+	int nfields = mxGetNumberOfFields(pInput);
+	for (int i = 0; i < nfields; i++) {
+		std::string sFieldName = std::string(mxGetFieldNameByNumber(pInput, i));
+		res[sFieldName] = mxGetFieldByNumber(pInput,0,i);
 	}
-	return NULL;
-}
-//-----------------------------------------------------------------------------------------
-// return true ig the argument is a scalar
-bool mex_is_scalar(const mxArray* pInput)
-{
-	return (mxIsNumeric(pInput) && mxGetM(pInput)*mxGetN(pInput) == 1);
+	return res;
 }
 
 
@@ -509,18 +336,41 @@ bool mex_is_scalar(const mxArray* pInput)
 
 
 //-----------------------------------------------------------------------------------------
+// turn a Config object into a MATLAB struct
 mxArray* configToStruct(astra::Config* cfg)
 {
-	return XMLNode2struct(cfg->self);
+	return XMLNodeToStruct(cfg->self);
 }
 
 //-----------------------------------------------------------------------------------------
-mxArray* XML2struct(astra::XMLDocument* xml)
+mxArray* XMLNodeToStruct(astra::XMLNode* node)
 {
-	XMLNode* node = xml->getRootNode();
-	mxArray* str = XMLNode2struct(xml->getRootNode());
-	delete node;
-	return str;
+	std::map<std::string, mxArray*> mList;
+	std::map<std::string, mxArray*> mOptions;
+
+	// type_attribute
+	if (node->hasAttribute("type")) {
+		mList["type"] = mxCreateString(node->getAttribute("type").c_str());
+	}
+
+	list<XMLNode*> nodes = node->getNodes();
+	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
+		XMLNode* subnode = (*it);
+
+		// option
+		if (subnode->getName() == "Option") {
+			mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value"));
+		}
+
+		// regular content
+		else {
+			mList[subnode->getName()] = stringToMxArray(subnode->getContent());
+		}
+		delete subnode;
+	}
+
+	if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions);
+	return buildStruct(mList);
 }
 
 //-----------------------------------------------------------------------------------------
@@ -583,36 +433,18 @@ mxArray* stringToMxArray(std::string input)
 	// string
 	return mxCreateString(input.c_str());
 }
-
 //-----------------------------------------------------------------------------------------
-mxArray* XMLNode2struct(astra::XMLNode* node)
+// turn a c++ map into a matlab struct
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput) 
 {
-	std::map<std::string, mxArray*> mList;
-	std::map<std::string, mxArray*> mOptions;
-
-	// type_attribute
-	if (node->hasAttribute("type")) {
-		mList["type"] = mxCreateString(node->getAttribute("type").c_str());
-	}
-
-	list<XMLNode*> nodes = node->getNodes();
-	for (list<XMLNode*>::iterator it = nodes.begin(); it != nodes.end(); it++) {
-		XMLNode* subnode = (*it);
-
-		// option
-		if (subnode->getName() == "Option") {
-			mOptions[subnode->getAttribute("key")] = stringToMxArray(subnode->getAttribute("value"));
-		}
-
-		// regular content
-		else {
-			mList[subnode->getName()] = stringToMxArray(subnode->getContent());
-		}
-		delete subnode;
+	mwSize dims[2] = {1, 1};
+	mxArray* res = mxCreateStructArray(2,dims,0,0);
+	
+	for (std::map<std::string, mxArray*>::iterator it = mInput.begin(); it != mInput.end(); it++) {
+		mxAddField(res, (*it).first.c_str());
+		mxSetField(res, 0, (*it).first.c_str(), (*it).second);
 	}
-
-	if (mOptions.size() > 0) mList["options"] = buildStruct(mOptions);
-	return buildStruct(mList);
+	return res;
 }
 
 
@@ -624,26 +456,3 @@ mxArray* XMLNode2struct(astra::XMLNode* node)
 
 
 
-//-----------------------------------------------------------------------------------------
-void get3DMatrixDims(const mxArray* x, mwSize *dims)
-{
-	const mwSize* mdims = mxGetDimensions(x);
-	mwSize dimCount = mxGetNumberOfDimensions(x);
-	if (dimCount == 1) {
-		dims[0] = mdims[0];
-		dims[1] = 1;
-		dims[2] = 1;
-	} else if (dimCount == 2) {
-		dims[0] = mdims[0];
-		dims[1] = mdims[1];
-		dims[2] = 1;
-	} else if (dimCount == 3) {
-		dims[0] = mdims[0];
-		dims[1] = mdims[1];
-		dims[2] = mdims[2];
-	} else {
-		dims[0] = 0;
-		dims[1] = 0;
-		dims[2] = 0;
-	}
-} 
diff --git a/matlab/mex/mexHelpFunctions.h b/matlab/mex/mexHelpFunctions.h
index 6c80f8c..f9ffcf2 100644
--- a/matlab/mex/mexHelpFunctions.h
+++ b/matlab/mex/mexHelpFunctions.h
@@ -43,42 +43,31 @@ $Id$
 #include "astra/Globals.h"
 #include "astra/Utilities.h"
 
-#include "astra/ParallelProjectionGeometry2D.h"
-#include "astra/FanFlatProjectionGeometry2D.h"
-#include "astra/ParallelProjectionGeometry3D.h"
-#include "astra/ParallelVecProjectionGeometry3D.h"
-#include "astra/ConeProjectionGeometry3D.h"
-#include "astra/ConeVecProjectionGeometry3D.h"
-
-#include "astra/VolumeGeometry2D.h"
-#include "astra/VolumeGeometry3D.h"
-
-
+#include "astra/Config.h"
 #include "astra/XMLDocument.h"
 #include "astra/XMLNode.h"
 
-std::string mex_util_get_string(const mxArray* pInput);
-bool isOption(std::list<std::string> lOptions, std::string sOption);
-
-bool mex_is_scalar(const mxArray* pInput);
+// utility functions
+string mexToString(const mxArray* pInput);
+bool mexIsScalar(const mxArray* pInput);
+void get3DMatrixDims(const mxArray* x, mwSize *dims);
 
-std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);
-mxArray* buildStruct(std::map<std::string, mxArray*> mInput);
+// convert boost::any into a MALTAB object
 mxArray* vectorToMxArray(std::vector<astra::float32> mInput);
-
 mxArray* anyToMxArray(boost::any _any);
 
-astra::CProjectionGeometry2D* parseProjectionGeometryStruct(const mxArray*);
-astra::CVolumeGeometry2D* parseVolumeGeometryStruct(const mxArray*);
-
-astra::XMLDocument* struct2XML(string rootname, const mxArray* pStruct);
+// turn a MATLAB struct into a Config object
+astra::Config* structToConfig(string rootname, const mxArray* pStruct);
+bool structToXMLNode(astra::XMLNode* node, const mxArray* pStruct);
+bool optionsToXMLNode(astra::XMLNode* node, const mxArray* pOptionStruct);
+std::map<std::string, mxArray*> parseStruct(const mxArray* pInput);
 
+// turn a Config object into a MATLAB struct
 mxArray* configToStruct(astra::Config* cfg);
-mxArray* XML2struct(astra::XMLDocument* xml);
-mxArray* XMLNode2struct(astra::XMLNode* xml);
+mxArray* XMLNodeToStruct(astra::XMLNode* xml);
 mxArray* stringToMxArray(std::string input);
+mxArray* buildStruct(std::map<std::string, mxArray*> mInput);
 
 
-void get3DMatrixDims(const mxArray* x, mwSize *dims);
 
 #endif
-- 
cgit v1.2.3