summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManoj Rajagopalan <manoj@nanorex.com>2008-04-23 22:02:26 +0000
committerManoj Rajagopalan <manoj@nanorex.com>2008-04-23 22:02:26 +0000
commitb9c1699510519ee541b8a93481002d51a778c12d (patch)
treec6f89067e3e3a079f44d7d41445f111d3b5df949
parent13d5aeb9ec1d2404e3384b1f05fff1120af901ec (diff)
downloadnanoengineer-theirix-b9c1699510519ee541b8a93481002d51a778c12d.tar.gz
nanoengineer-theirix-b9c1699510519ee541b8a93481002d51a778c12d.zip
Adding files to repo to correct breakage of revision 12636
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Interface/NXNamedView.h74
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Utility/NXMatrix.h170
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Utility/NXQuaternion.h407
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Utility/NXTrackball.h90
-rw-r--r--cad/plugins/NanoVision-1/include/Nanorex/Utility/NXVector.h583
-rw-r--r--cad/plugins/NanoVision-1/src/KDevelop/nv1.kdevelop25
-rw-r--r--cad/plugins/NanoVision-1/src/Utility/NXVectorTest.cpp262
-rw-r--r--cad/plugins/NanoVision-1/src/Utility/NXVectorTest.h51
8 files changed, 1656 insertions, 6 deletions
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXNamedView.h b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXNamedView.h
new file mode 100644
index 000000000..1983f575b
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Interface/NXNamedView.h
@@ -0,0 +1,74 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_NAMEDVIEW_H
+#define NX_NAMEDVIEW_H
+
+#include <Nanorex/Utility/NXVector.h>
+#include <Nanorex/Utility/NXQuaternion.h>
+
+#include <iostream>
+#include <string>
+
+namespace Nanorex {
+
+/* CLASS: NXNamedView */
+class NXNamedView {
+public:
+ NXNamedView() {}
+ NXNamedView(std::string const& theName,
+ NXQuaternion<double> const& theRotationQuat,
+ double const& theScale,
+ NXVector3d const& thePOV,
+ double const& theZoomFactor)
+ : name(theName), rotationQuat(theRotationQuat), scale(theScale),
+ POV(thePOV), zoomFactor(theZoomFactor), vdist(6.0*scale)
+ {
+ }
+ ~NXNamedView() {}
+
+ std::string const& getName(void) const { return name; }
+ void setName(std::string const& theName) { name = theName; }
+
+ NXQuaternion<double> const& getQuat(void) const { return rotationQuat; }
+ void setQuat(NXQuaternion<double> const& quat) { rotationQuat = quat; }
+
+ double const& getScale(void) const { return scale; }
+ void setScale(double const& theScale) { scale = theScale; vdist = 6.0*scale; }
+
+ NXVectorRef3d getPOV(void) { return NXVectorRef3d(POV); }
+ void setPOV(NXVector3d const& thePOV) { POV = thePOV; }
+
+ double const& getZoomFactor(void) const { return zoomFactor; }
+ void setZoomFactor(double const& theZoomFactor) {zoomFactor = theZoomFactor;}
+
+ static double GetNear(void) { return 0.25; }
+ static double GetFar(void) { return 12.0; }
+
+ double const& getPOVDistanceFromEye(void) const { return vdist; }
+ double getNearPlaneDistanceFromEye(void) const { return GetNear() * vdist; }
+ double getFarPlaneDistanceFromEye(void) const { return GetFar() * vdist; }
+
+private:
+ std::string name;
+ NXQuaternion<double> rotationQuat;
+ double scale;
+ NXVector3d POV;
+ double zoomFactor;
+
+ double vdist;
+};
+
+
+inline
+std::ostream& operator << (std::ostream& o, Nanorex::NXNamedView& view)
+{
+ o << "csys (" << view.getName() << ") " << view.getQuat()
+ << " (" << view.getScale() << ") " << view.getPOV()
+ << " (" << view.getZoomFactor() << ')';
+ return o;
+}
+
+
+} // namespace Nanorex
+
+#endif // NX_NAMEDVIEW_H
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXMatrix.h b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXMatrix.h
new file mode 100644
index 000000000..f37104482
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXMatrix.h
@@ -0,0 +1,170 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_MATRIX_H
+#define NX_MATRIX_H
+
+#include <Nanorex/Utility/NXVector.h>
+
+namespace Nanorex {
+
+/* CLASS: NXMatrix */
+/**
+ * Column-major matrix of dimensions M x N
+ *
+ */
+template<typename T, int M, int N>
+ class NXMatrix {
+ public:
+ NXMatrix() throw() {}
+ ~NXMatrix() throw() {}
+
+ T const *const data(void) const throw() { return elems; }
+ T *const data(void) throw() { return elems; }
+
+ /// Access value at m-th row, n-th column
+ T const& operator () (int const& m, int const& n) const throw();
+
+ /// Access value at m-th row, n-th column
+ T& operator () (int const& m, int const& n) throw();
+
+ /// Access n-th column
+ NXVectorRef<T,N> col(int const& n) throw();
+
+ template<typename T1>
+ NXMatrix<T,M,N>& operator += (NXMatrix<T1,M,N> const& A) throw();
+
+ template<typename T1>
+ NXMatrix<T,M,N>& operator -= (NXMatrix<T1,M,N> const& A) throw();
+
+ template<typename T1>
+ NXMatrix<T,M,N>& operator *= (T1 const& c) throw();
+
+ template<typename T1>
+ NXMatrix<T,M,N>& operator /= (T1 const& c) throw();
+
+
+ private:
+ T elems[M*N];
+ };
+
+
+typedef NXMatrix<double,3,3> NXMatrix33d;
+typedef NXMatrix<float,3,3> NXMatrix33f;
+typedef NXMatrix<double,4,4> NXMatrix44d;
+typedef NXMatrix<float,4,4> NXMatrix44f;
+
+// Access value at m-th row, n-th column
+template<typename T, int M, int N>
+ inline
+ T const& NXMatrix<T,M,N>::operator () (int const& m, int const& n) const throw()
+{
+ return elems[n*M + m];
+}
+
+// Access value at m-th row, n-th column
+template<typename T, int M, int N>
+ inline
+ T& NXMatrix<T,M,N>::operator () (int const& m, int const& n) throw()
+{
+ return elems[n*M + m];
+}
+
+// Access n-th column
+template<typename T, int M, int N>
+ inline
+ NXVectorRef<T,N> NXMatrix<T,M,N>::col(int const& n) throw()
+{
+ return NXVectorRef<T,N>(elems + n*M);
+}
+
+
+template<typename T, int M, int N>
+ template<typename T1>
+ inline
+ NXMatrix<T,M,N>&
+ NXMatrix<T,M,N>::operator += (NXMatrix<T1,M,N> const& A) throw()
+{
+ // Exploit isomorphism with M*N-dimensional vectors
+ NXVectorRef<T,M*N> selfRef(elems);
+ NXVectorRef<T1,M*N> ARef(A.data());
+ selfRef += ARef;
+ return *this;
+}
+
+
+template<typename T, int M, int N>
+ template<typename T1>
+ inline
+ NXMatrix<T,M,N>&
+ NXMatrix<T,M,N>::operator -= (NXMatrix<T1,M,N> const& A) throw()
+{
+ // Exploit isomorphism with M*N-dimensional vectors
+ NXVectorRef<T,M*N> selfRef(elems);
+ NXVectorRef<T1,M*N> ARef(A.data());
+ selfRef -= ARef;
+ return *this;
+}
+
+
+template<typename T, int M, int N>
+ template<typename T1>
+ inline
+ NXMatrix<T,M,N>& NXMatrix<T,M,N>::operator *= (T1 const& c) throw()
+{
+ // Exploit isomorphism with M*N-dimensional vectors
+ NXVectorRef<T,M*N> selfRef(elems);
+ selfRef *= c;
+ return *this;
+}
+
+
+template<typename T, int M, int N>
+ template<typename T1>
+ inline
+ NXMatrix<T,M,N>& NXMatrix<T,M,N>::operator /= (T1 const& c) throw()
+{
+ // Exploit isomorphism with M*N-dimensional vectors
+ NXVectorRef<T,M*N> selfRef(elems);
+ T const one_by_c = T(1) / c;
+ selfRef *= one_by_c;
+ return *this;
+}
+
+
+
+/// Matrix-matrix multiplication (inefficient)
+template<typename T, int M, int N, int K>
+ NXMatrix<T,M,N> operator * (NXMatrix<T,M,K> const& A,
+ NXMatrix<T,K,N> const& B)
+{
+ NXMatrix<T,M,N> C; // result
+ for(int m=0; m<M; ++m) {
+ for(int n=0; n<N; ++n) {
+ T sum_mn(0);
+ for(int k=0; k<K; ++k) {
+ sum_mn += A(m,k) * B(k,n);
+ }
+ C(m,n) = sum_mn;
+ }
+ }
+}
+
+
+/// Matrix-vector multiplication (inefficient)
+template<typename T, int M, int N>
+ NXVector<T,M> operator * (NXMatrix<T,M,N> const& A,
+ NXVector<T,N> const& x)
+{
+ NXVector<T,M> y; // result
+ y.zero();
+ for(int n=0; n<N; ++n) {
+ for(int m=0; m<M; ++m) {
+ y[m] += A(m,n) * x[n];
+ }
+ }
+}
+
+
+} // namespace Nanorex
+
+#endif // NX_MATRIX_H
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXQuaternion.h b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXQuaternion.h
new file mode 100644
index 000000000..781476f00
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXQuaternion.h
@@ -0,0 +1,407 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_QUATERNION_H
+#define NX_QUATERNION_H
+
+#include <Nanorex/Utility/NXVector.h>
+#include <Nanorex/Utility/NXMatrix.h>
+
+#include <cmath>
+
+
+#ifdef _GNU_SOURCE
+inline void sincos(float x, float *sinx, float *cosx) {sincosf(x, sinx, cosx);}
+inline void sincos(long double x, long double *sinx, long double *cosx) {
+ sincosl(x, sinx, cosx);
+}
+#endif
+
+
+namespace Nanorex {
+
+/// Quaternion class stored as cos(theta/2) + sin(theta/2)*(x,y,z)
+template<typename T>
+class NXQuaternion {
+public:
+
+ NXQuaternion();
+
+ /// w = cos(theta)/2 where theta is rotation angle, (x,y,z) specify axis vector
+ /// NXQuaternion(1,0,0,0) => no rotation
+ NXQuaternion(T const& _w, // cos(theta)/2
+ T const& _x, T const& _y, T const& _z);
+
+ /// Quaternion that rotates the standard axes into the right-handed coordinate
+ /// frame described by orthonormal vectors _x, _y and _z
+ NXQuaternion(NXVectorRef<T,3> x, NXVectorRef<T,3> y, NXVectorRef<T,3> z);
+
+ /// Rotation quaternion
+ NXQuaternion(NXVectorRef<T,3> rotAxis, T const& theta);
+
+ /// Quaternion that rotates from vec1 to vec2
+ NXQuaternion(NXVectorRef<T,3> vec1, NXVectorRef<T,3> vec2);
+
+ ~NXQuaternion() {}
+
+ /// Vector along the rotation axis
+ NXVector<T,3> getAxisDirection(void);
+
+ /// Rotation angle in radians
+ T getAngle(void) const;
+ void setAngle(T const& theta);
+
+ /// Set to (*this + q) which is the result of applying *this followed by q
+ NXQuaternion<T>& operator += (NXQuaternion<T> const& q);
+
+ /// Result of (*this + q2)
+ NXQuaternion<T> operator + (NXQuaternion<T> const& q2) const;
+
+ /// Unary minus
+ NXQuaternion<T> operator - (void) const;
+
+ NXQuaternion<T>& operator *= (T const& n);
+
+ /// Build rotation matrix.
+ void buildMatrix(NXMatrix<T,4,4>& R);
+
+ NXVector<T,3> rot(NXVectorRef<T,3> v);
+ NXVector<T,3> unrot(NXVectorRef<T,3> v);
+
+ NXQuaternion<T>& normalizeSelf(void);
+
+private:
+ T w; ///< cos(theta/2)
+ NXVector<T,3> axis; ///< sin(theta/2) * rotation-axis-vector
+
+ int incrementCounter;
+
+ template<typename S>
+ friend std::ostream& operator << (std::ostream& o, NXQuaternion<S> const& q);
+};
+
+
+template<typename T>
+ inline
+ NXQuaternion<T>::NXQuaternion()
+ : w(1.0), axis(0.0, 0.0, 1.0)
+{
+}
+
+
+template<typename T>
+ inline
+ NXQuaternion<T>::NXQuaternion(T const& _w,
+ T const& _x, T const& _y, T const& _z)
+ : w(_w), axis(), incrementCounter(0)
+{
+ /// @fixme check domain of _w
+ T const sin_half_theta = sqrt(1.0 - _w*_w);
+ axis[0] = sin_half_theta * _x;
+ axis[1] = sin_half_theta * _y;
+ axis[2] = sin_half_theta * _z;
+ normalizeSelf();
+}
+
+
+// Rotation quaternion
+template<typename T>
+ inline
+ NXQuaternion<T>::NXQuaternion(NXVectorRef<T,3> rotAxis, T const& theta)
+ : w(0), axis(rotAxis), incrementCounter(0)
+{
+ setAngle(theta);
+}
+
+
+// Quaternion that rotates from vec1 to vec2
+template<typename T>
+ inline
+ NXQuaternion<T>::NXQuaternion(NXVectorRef<T,3> vec1, NXVectorRef<T,3> vec2)
+ : w(0), axis(), incrementCounter(0)
+{
+ NXVector<T,3> x = vec1;
+ NXVector<T,3> y = vec2;
+ x.normalizeSelf();
+ y.normalizeSelf();
+ T const dotxy = dot(x,y);
+ NXVector<T,3> v = cross(x,y);
+ T const vLen = length(v);
+
+ if(vLen < 0.000001) {
+ // x, y are very close, or very close to opposite, or one of them is zero
+ if(dotxy < 0.0) {
+ // close to opposite; treat as actually opposite
+ w = 0.0;
+ NXVector<T,3> X_AXIS(1,0,0), Y_AXIS(0,1,0);
+ NXVector<T,3> ax1 = cross(x, X_AXIS);
+ NXVector<T,3> ax2 = cross(x, Y_AXIS);
+ if(length(ax1) > length(ax2))
+ axis = ax1;
+ else
+ axis = ax2;
+ }
+ else {
+ // very close, or one is zero -- we could pretend they're equal, but let's be a little
+ // more accurate than that -- vl is sin of desired theta, so vl/2 is approximately sin(theta/2)
+ // (##e could improve this further by using a better formula to relate sin(theta/2) to sin(theta)),
+ // so formula for xyz part is v/vl * vl/2 == v/2 [bruce 050730]
+ NXVector<T,3> const xyz = v / 2.0;
+ double const sin_half_theta = vLen / 2.0;
+ double const cos_half_theta = sqrt(1 - sin_half_theta * sin_half_theta);
+ w = cos_half_theta;
+ axis = xyz;
+ }
+ }
+
+ else {
+ /// @todo check for possible instability when dotxy ~ 1
+ T const maxval = T(-1.0) > dotxy ? T(-1.0) : dotxy;
+ T const minval = T(1.0) < maxval ? T(1.0) : maxval;
+ T theta = acos(minval);
+ NXVector<T,3> crossxv = cross(x,v);
+ T const doty_crossxv = dot(y, crossxv);
+ if (doty_crossxv > 0.0)
+ theta = 2.0 * M_PI - theta;
+ w = cos(theta * 0.5);
+ double const s = sqrt(1 - w*w) / vLen;
+ axis = s * v;
+ }
+}
+
+template<typename T>
+ NXVector<T,3> NXQuaternion<T>::getAxisDirection(void)
+{
+ if(axis[0] == 0.0 && axis[1] == 0.0 && axis[2] == 0.0)
+ // no rotation => return arbitrary axis
+ return NXVector<T,3>(0.0, 0.0, 1.0);
+ else
+ return axis;
+}
+
+
+template<typename T>
+ inline
+ T twistor_angle(NXVectorRef<T,3> axis,
+ NXVectorRef<T,3> pt1,
+ NXVectorRef<T,3> pt2)
+{
+ NXQuaternion<T> q(axis, NXVector<T,3>(0,0,1));
+ pt1 = q.rot(pt1);
+ pt2 = q.rot(pt2);
+ T const a1 = atan2(pt1[1], pt1[0]);
+ T const a2 = atan2(pt2[1], pt2[0]);
+ T const theta = a2 - a1;
+ return theta;
+}
+
+
+template<typename T>
+ inline
+ NXQuaternion<T> twistor(NXVectorRef<T,3> axis,
+ NXVectorRef<T,3> pt1,
+ NXVectorRef<T,3> pt2)
+{
+ T const theta = twistor_angle(axis, pt1, pt2);
+ return NXQuaternion<T>(axis, theta);
+}
+
+
+/* CONSTRUCTOR */
+// Placed here because of dependence on twistor() which in turn depends on other constructors
+// Quaternion that rotates the standard axes into the right-handed coordinate
+// frame described by orthonormal vectors _x, _y and _z
+template<typename T>
+ inline
+ NXQuaternion<T>::NXQuaternion(NXVectorRef<T,3> x,
+ NXVectorRef<T,3> y,
+ NXVectorRef<T,3> z)
+ : w(0), axis(), incrementCounter(0)
+{
+ NXVector<T,3> const X_AXIS(1.0, 0.0, 0.0);
+ NXVector<T,3> const Y_AXIS(1.0, 0.0, 0.0);
+
+ NXQuaternion<T> xfixer(X_AXIS, x);
+ NXVector<T,3> yAxis2 = xfixer.rot(Y_AXIS);
+ NXQuaternion<T> yfixer = twistor(x, yAxis2, y); /// @todo implement twistor
+ NXQuaternion<T> res = xfixer + yfixer;
+
+ *this = res;
+}
+
+
+
+
+template<typename T>
+inline T NXQuaternion<T>::getAngle(void) const
+{
+ if(w > -1.0 && w < 1.0) {
+ T const retval = 2.0 * acos(w);
+ return retval;
+ }
+ else
+ return 0.0;
+}
+
+
+template<typename T>
+inline void NXQuaternion<T>::setAngle(T const& theta)
+{
+ T const half_theta = 0.5 * theta;
+#ifdef _GNU_SOURCE
+ T sin_half_theta = 0.0, cos_half_theta = 0.0;
+ sincos(half_theta, &sin_half_theta, &cos_half_theta);
+#else
+ T const sin_half_theta = sin(half_theta);
+ T const cos_half_theta = cos(half_theta);
+#endif
+ w = cos_half_theta;
+ axis *= sin_half_theta;
+ normalizeSelf();
+}
+
+
+template<typename T>
+ inline
+ NXQuaternion<T> NXQuaternion<T>::operator + (NXQuaternion<T> const& q2) const
+{
+ NXQuaternion<T> q;
+ q.w = q2.w*w - q2.axis[0]*axis[0] - q2.axis[1]*axis[1] - q2.axis[2]*axis[2];
+ q.axis[0] = q2.w*axis[0] + q2.axis[0]*w + q2.axis[1]*axis[2] - q2.axis[2]*axis[1];
+ q.axis[1] = q2.w*axis[1] - q2.axis[0]*axis[2] + q2.axis[1]*w + q2.axis[2]*axis[0];
+ q.axis[2] = q2.w*axis[2] + q2.axis[0]*axis[1] - q2.axis[1]*axis[0] + q2.axis[2]*w;
+ return q;
+}
+
+
+template<typename T>
+ inline NXQuaternion<T>& NXQuaternion<T>::operator += (NXQuaternion<T> const& q)
+{
+ *this = *this + q;
+ ++incrementCounter;
+ if(incrementCounter == 50)
+ normalizeSelf();
+ return *this;
+}
+
+/// multiplication by a scalar, i.e. Q1 * 1.3, defined so that
+/// e.g. Q1 * 2 == Q1 + Q1, or Q1 = Q1 * 0.5 + Q1 * 0.5
+template<typename T>
+ inline NXQuaternion<T> operator * (NXQuaternion<T> const& q, T const& n)
+{
+ NXQuaternion<T> qResult(q);
+ qResult.setAngle(n * q.getAngle());
+ return qResult;
+}
+
+template<typename T>
+ inline NXQuaternion<T>& NXQuaternion<T>::operator *= (T const& n)
+{
+ *this = *this * n;
+ return *this;
+}
+
+
+template<typename T>
+ inline NXQuaternion<T> NXQuaternion<T>::operator - (void) const
+{
+ NXQuaternion<T> q;
+ q.w = w; // cos is even
+ q.axis = -axis;
+ return q;
+}
+
+
+template<typename T>
+ inline NXQuaternion<T> conj(NXQuaternion<T> const& q)
+{
+ return -q;
+}
+
+
+template<typename T>
+ inline NXQuaternion<T>& NXQuaternion<T>::normalizeSelf(void)
+{
+ T const len = length(axis);
+ if(len != 0.0) {
+ T const s = sqrt(1.0 - w*w) / len;
+ axis *= s;
+ }
+ else {
+ w = 1.0;
+ axis.zero();
+ }
+ return *this;
+}
+
+
+/// Build rotation matrix
+template<typename T>
+ inline void NXQuaternion<T>::buildMatrix(NXMatrix<T,4,4>& R)
+{
+ normalizeSelf();
+ R(0,0) = T(1.0) - T(2.0) * (axis[1] * axis[1] + axis[2] * axis[2]);
+ R(0,1) = T(2.0) * (axis[0] * axis[1] - axis[2] * w);
+ R(0,2) = T(2.0) * (axis[2] * axis[0] + axis[1] * w);
+ R(0,3) = T(0.0);
+
+ R(1,0) = T(2.0) * (axis[0] * axis[1] + axis[2] * w);
+ R(1,1) = T(1.0) - T(2.0) * (axis[2] * axis[2] + axis[0] * axis[0]);
+ R(1,2) = T(2.0) * (axis[1] * axis[2] - axis[0] * w);
+ R(1,3) = T(0.0);
+
+ R(2,0) = T(2.0) * (axis[2] * axis[0] - axis[1] * w);
+ R(2,1) = T(2.0) * (axis[1] * axis[2] + axis[0] * w);
+ R(2,2) = T(1.0) - T(2.0) * (axis[1] * axis[1] + axis[0] * axis[0]);
+ R(2,3) = T(0.0);
+
+ R(3,0) = T(0.0);
+ R(3,1) = T(0.0);
+ R(3,2) = T(0.0);
+ R(3,3) = T(1.0);
+
+}
+
+
+template<typename T>
+ inline
+ NXVector<T,3> NXQuaternion<T>::rot(NXVectorRef<T,3> v)
+{
+ NXMatrix<T,4,4> R;
+ buildMatrix(R);
+ NXVector<T,4> v4;
+ NXVectorRef<T,3>(v4.data()).copy(v);
+ v4[3] = T(0);
+ NXVector<T,4> result4 = R * v4;
+ NXVector<T,3> result;
+ result.copy(NXVectorRef<T,3>(result4.data()));
+ return result;
+}
+
+
+template<typename T>
+ inline
+ NXVector<T,3> unrot(NXVectorRef<T,3> v)
+{
+ NXMatrix<T,4,4> R;
+ NXVector<T,3> result;
+
+ // compute R^T v
+ buildMatrix(R);
+ for(int m=0; m<3; ++m)
+ result[m] = dot(R.col(m), v);
+
+ return result;
+}
+
+
+template<typename T>
+ std::ostream& operator << (std::ostream& o, NXQuaternion<T> const& q)
+{
+ o << '(' << q.w << ',' << q.axis[0] << ',' << q.axis[1] << ',' << q.axis[2] << ')';
+ return o;
+}
+
+
+} // namespace Nanorex
+
+#endif // NX_QUATERNION_H
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXTrackball.h b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXTrackball.h
new file mode 100644
index 000000000..d05b658c3
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXTrackball.h
@@ -0,0 +1,90 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_TRACKBALL_H
+#define NX_TRACKBALL_H
+
+#include <Nanorex/Utility/NXQuaternion.h>
+#include <cmath>
+
+namespace Nanorex {
+
+class NXTrackball {
+public:
+ NXTrackball()
+ : w2(0.0), h2(0.0), scale(0.0), mouseSpeedDuringRotation(1.0) {}
+
+ NXTrackball(int const& w, int const& h) {
+ resize(w, h);
+ mouseSpeedDuringRotation = 1.0;
+ }
+
+ ~NXTrackball() {}
+
+ // accessors
+ double getWidth(void) const { return (w2+w2); }
+
+ double getHeight(void) const { return (h2+h2); }
+
+ void resize(int const& w, int const& h) {
+ w2 = 0.5*((double)w);
+ h2 = 0.5*((double)h);
+ scale = 1.1 / ((w2 < h2) ? w2 : h2);
+ }
+
+ // double const *const getOldMouse(void) const { return oldMouse; }
+ // double const *const getNewMouse(void) const { return newMouse; }
+
+ double const& getMouseSpeedDuringRotation(void) const {
+ return mouseSpeedDuringRotation;
+ }
+ void setMouseSpeedDuringRotation(double const& speed) {
+ mouseSpeedDuringRotation = speed;
+ }
+
+ void start(int const& x, int const& y) {
+ proj2sphere( oldMouse,
+ (double(x) - w2) * scale * mouseSpeedDuringRotation,
+ (h2 - double(y)) * scale * mouseSpeedDuringRotation );
+ }
+
+ void update(int const& x, int const& y) {
+ proj2sphere( newMouse,
+ (double(x) - w2) * scale * mouseSpeedDuringRotation,
+ (h2 - double(y)) * scale * mouseSpeedDuringRotation );
+ }
+
+ NXQuaternion<double> getRotationQuat(void) {
+ return NXQuaternion<double>(NXVectorRef<double,3>(oldMouse),
+ NXVectorRef<double,3>(newMouse));
+ }
+
+private:
+ double w2; // half-screen-width
+ double h2; // half-screen-height
+ double scale;
+ double mouseSpeedDuringRotation;
+ double oldMouse[3];
+ double newMouse[3];
+
+ /// Project screen coords (x,y) in [-1,1]^2 to unit-sphere and store in wpt
+ static void proj2sphere(double *wpt, double const& x, double const& y) {
+ double const d = sqrt(x*x+y*y);
+ double const theta = M_PI * 0.5 * d;
+ if(d > 0.0001) {
+#ifdef _GNU_SOURCE
+ double sinTheta = 0.0, cosTheta = 0.0;
+ sincos(theta, &sinTheta, &cosTheta);
+#else
+ double const sinTheta = sin(theta);
+ double const cosTheta = cos(theta);
+#endif
+ wpt[0] = sinTheta * x / d;
+ wpt[1] = sinTheta * y / d;
+ wpt[2] = cosTheta;
+ }
+ }
+};
+
+} // Nanorex
+
+#endif // NX_TRACKBALL_H
diff --git a/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXVector.h b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXVector.h
new file mode 100644
index 000000000..e66881e66
--- /dev/null
+++ b/cad/plugins/NanoVision-1/include/Nanorex/Utility/NXVector.h
@@ -0,0 +1,583 @@
+
+/** \file NXVector.h
+ * \brief Implements point-vector classes using expression templates
+ */
+#ifndef NX_VECTOR_H
+#define NX_VECTOR_H
+
+#include "Nanorex/Utility/NXUtility.h"
+#include <cmath>
+#include <cstring>
+#include <iostream>
+
+namespace Nanorex {
+
+
+// forward declarations for usable types
+template<typename T, int N> class NXVectorRef;
+template<typename T, int N> class NXVector;
+
+static double const NX_DEFAULTTOL = 1.0e-6;
+
+template<typename T1, typename T2>
+ struct promotion_traits;
+
+template<typename T> struct promotion_traits<T,T> { typedef T type; };
+template<> struct promotion_traits<float,double> { typedef double type; };
+template<> struct promotion_traits<double,float> { typedef double type; };
+template<> struct promotion_traits<double,long double> { typedef long double type; };
+template<> struct promotion_traits<long double,double> { typedef long double type; };
+template<> struct promotion_traits<float,long double> { typedef long double type; };
+template<> struct promotion_traits<long double,float> { typedef long double type; };
+
+
+/* CLASS: NXVectorBase */
+template <typename T, int N, template <typename,int> class NXVectorDerived>
+ class NXVectorBase {
+ public:
+ typedef T value_type;
+ typedef NXVectorBase<T,N,NXVectorDerived> baseclass_type;
+ typedef NXVectorDerived<T,N> subclass_type;
+
+ private:
+ typedef NXVectorBase<T,N,NXVectorDerived> self_type;
+
+
+ public:
+ NXVectorBase() {}
+ ~NXVectorBase() {}
+
+ // shallow or deep copy as per the implementation
+ template<template <typename, int> class NXVectorDerived2>
+ self_type&
+ operator = (NXVectorBase<T,N,NXVectorDerived2> const& v) throw()
+ {
+ asLeaf() = v.asLeaf();
+ return *this;
+ }
+
+ // force deep copy between identical value_types
+ template<template <typename, int> class NXVectorDerived2>
+ self_type& copy(NXVectorBase<T,N,NXVectorDerived2> const& v) throw()
+ {
+ NXVectorBase<T,N,NXVectorDerived2>& v_non_const =
+ const_cast<NXVectorBase<T,N,NXVectorDerived2>&>(v);
+ memcpy((void*) data(),
+ (void*) v_non_const.data(),
+ N * sizeof(T));
+ return *this;
+ }
+
+ // force deep copy between static_cast-able value_types
+ template<typename T1, template <typename, int> class NXVectorDerived2>
+ self_type& copy(NXVectorBase<T1,N,NXVectorDerived2> const& v) throw()
+ {
+ for(int n=0; n<N; ++n)
+ data()[n] = static_cast<T const>(v.data()[n]);
+ return *this;
+ }
+
+ subclass_type& asLeaf(void) throw() {
+ return static_cast<subclass_type&>(*this);
+ }
+
+ subclass_type const& asLeaf(void) const throw() {
+ return static_cast<subclass_type const&>(*this);
+ }
+
+ // derived classes must implement the data array m_coords
+ T *const data(void) throw() { return asLeaf().data(); }
+ T const *const data(void) const throw() { return asLeaf().data(); }
+
+ T const& operator [] (int const& n) const throw() { return data()[n]; }
+ T& operator [] (int const& n) throw() { return data()[n]; }
+
+ int size(void) const throw() { return N; }
+
+ self_type& zero(void) throw();
+
+ /// Unary minus
+ NXVector<T,N> operator - (void) const throw();
+
+ /// self-increment
+ template<typename T1, template <typename, int> class NXVectorDerived2>
+ self_type& operator += (NXVectorBase<T1,N,NXVectorDerived2> const& b)
+ throw();
+
+ /// self-decrement
+ template<typename T1, template <typename, int> class NXVectorDerived2>
+ self_type& operator -= (NXVectorBase<T1,N,NXVectorDerived2> const& b)
+ throw();
+
+ /// self-scaling
+ template<typename T1>
+ self_type& operator *= (T1 const& c) throw();
+
+ /// self-scaling
+ template<typename T1>
+ self_type& operator /= (T1 const& c) throw();
+
+ self_type& normalizeSelf(double const& TOL=NX_DEFAULTTOL) throw();
+
+ /// normalized copy of self
+ NXVector<T,N> normalized(double const& TOL=NX_DEFAULTTOL) const throw();
+
+ protected:
+ static inline T s_sqr(T const& x) throw() { return x*x; }
+ static inline T s_div(T const& a, T const& b) throw()
+ { return static_cast<T>(static_cast<double>(a)/static_cast<double>(b)); }
+
+ };
+
+
+/* CLASS: NXVectorRef */
+/**
+ * N-dimensional vector view of an array with shallow copy semantics
+ */
+template<typename T, int N>
+ class NXVectorRef : public NXVectorBase<T,N,NXVectorRef> {
+ public:
+
+ NXVectorRef() : m_coords(NULL) {}
+ NXVectorRef(T *const v) : m_coords(v) {}
+ NXVectorRef(NXVector<T,N>& v) : m_coords(v.data()) {}
+
+ // shallow copy constructor
+ template<template <typename, int> class NXVectorDerived>
+ NXVectorRef<T,N>& operator = (NXVectorBase<T,N,NXVectorDerived>& v) {
+ m_coords = v.data();
+ return *this;
+ }
+ ~NXVectorRef() {}
+
+ T *const data(void) throw() { return m_coords; }
+ T const *const data(void) const throw() { return m_coords; }
+
+ protected:
+ T *m_coords;
+ };
+
+// typedefs for common instantiations
+typedef NXVectorRef<float, 2> NXVectorRef2f;
+typedef NXVectorRef<double,2> NXVectorRef2d;
+typedef NXVectorRef<float, 3> NXVectorRef3f;
+typedef NXVectorRef<double,3> NXVectorRef3d;
+typedef NXVectorRef<float, 4> NXVectorRef4f;
+typedef NXVectorRef<double,4> NXVectorRef4d;
+
+
+// -----------------------------------------------------------------------------
+/* CLASS: NXVector */
+/**
+ * N-dimensional point
+ * Allocates private data store and inherits functionality from NXVectorBase
+ */
+template<typename T, int N>
+ class NXVector : public NXVectorBase<T,N,NXVector> {
+ public:
+ NXVector() throw () {}
+ NXVector(T const& x) throw (NXException);
+ NXVector(T const& y, T const& y) throw (NXException);
+ NXVector(T const& x, T const& y, T const& z) throw (NXException);
+ NXVector(T const v[]) throw (); ///< initialize from array
+
+ // copy assignment with deep copy semantics
+ template<typename T1, template <typename, int> class NXVectorDerived>
+ NXVector<T,N>&
+ operator = (NXVectorBase<T1,N,NXVectorDerived> const& v) throw();
+
+ // copy constructor with deep copy semantics
+ template<typename T1, template <typename, int> class NXVectorDerived>
+ NXVector(NXVectorBase<T1,N,NXVectorDerived> const& v) throw ();
+
+ ~NXVector() {}
+
+ T *const data(void) throw() { return m_coords; }
+ T const *const data(void) const throw() { return m_coords; }
+
+ private:
+ T m_coords[N];
+ };
+
+// typedefs for common instantiations
+typedef NXVector<float, 2> NXVector2f;
+typedef NXVector<double,2> NXVector2d;
+typedef NXVector<float, 3> NXVector3f;
+typedef NXVector<double,3> NXVector3d;
+typedef NXVector<float, 4> NXVector4f;
+typedef NXVector<double,4> NXVector4d;
+
+
+/* CONSTRUCTOR */
+template<typename T, int N>
+ inline
+ NXVector<T,N>::NXVector(T const& x) throw (NXException)
+ : NXVector<T,N>::baseclass_type()
+ // : NXVectorRef<T,N>(m_coord_data)
+{
+ if(N != 1)
+ throw NXException("Initialization with different dimensionality");
+ m_coords[0] = x;
+}
+
+/* CONSTRUCTOR */
+template<typename T, int N>
+ inline
+ NXVector<T,N>::NXVector(T const& x, T const& y) throw (NXException)
+ : NXVector<T,N>::baseclass_type()
+ // : NXVectorRef<T,N>(m_coord_data)
+{
+ if(N != 2)
+ throw NXException("Initialization with different dimensionality");
+ m_coords[0] = x;
+ m_coords[1] = y;
+}
+
+/* CONSTRUCTOR */
+template<typename T, int N>
+ inline
+ NXVector<T,N>::NXVector(T const& x, T const& y, T const& z) throw (NXException)
+ : NXVector<T,N>::baseclass_type()
+ // : NXVectorRef<T,N>(m_coord_data)
+{
+ if(N != 3)
+ throw NXException("Initialization with different dimensionality");
+ m_coords[0] = x;
+ m_coords[1] = y;
+ m_coords[2] = z;
+}
+
+/* CONSTRUCTOR */
+template<typename T, int N>
+ inline
+ NXVector<T,N>::NXVector(T const v[]) throw ()
+ : NXVector<T,N>::baseclass_type()
+ // : NXVectorRef<T,N>(m_coord_data)
+{
+ // for(int n=0; n<N; ++n) m_coords[n] = v[n];
+ std::memcpy((void*) m_coords,
+ (void*) const_cast<T*>(v),
+ N * sizeof(T));
+}
+
+/* COPY-ASSIGNMENT */
+/// Deep copy semantics
+template<typename T, int N>
+ template<typename T1, template <typename, int> class NXVectorDerived>
+ inline
+ NXVector<T,N>&
+ NXVector<T,N>::operator = (NXVectorBase<T1,N,NXVectorDerived> const& v) throw()
+{
+ for(int n=0; n<N; ++n) m_coords[n] = static_cast<T const>(v[n]);
+ return *this;
+}
+
+/* CONSTRUCTOR */
+// copy constructor with deep copy semantics
+template<typename T, int N>
+ template<typename T1, template <typename, int> class NXVectorDerived>
+ inline
+ NXVector<T,N>::NXVector(NXVectorBase<T1,N,NXVectorDerived> const& v) throw ()
+ : NXVector<T,N>::baseclass_type()
+{
+ (void) (*this = v); // use copy assignment
+}
+
+
+// ------------------------------------------------------------------------
+/* Global functions */
+
+template<typename T, template<typename,int> class NXVectorDerived>
+ inline
+ T dot(NXVectorBase<T,1,NXVectorDerived>& a,
+ NXVectorBase<T,1,NXVectorDerived>& b)
+{
+ return a[0]*b[0];
+}
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ T dot(NXVectorBase<T,N,NXVectorDerived>& a,
+ NXVectorBase<T,N,NXVectorDerived>& b)
+{
+ NXVectorRef<T,N-1> a1(a.data()), b1(b.data());
+ T const s = dot(a1, b1);
+ T const result = s + a[N-1]*b[N-1];
+ return result;
+}
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ T squared_norm(NXVectorBase<T,N,NXVectorDerived>& v) { return dot(v,v); }
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ T norm(NXVectorBase<T,N,NXVectorDerived>& v)
+{
+ double const sqr_nrm = static_cast<double>(squared_norm(v));
+ double const nrm = sqrt(sqr_nrm);
+ return static_cast<T>(nrm);
+}
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ T length(NXVectorBase<T,N,NXVectorDerived>& v)
+{
+ return norm(v);
+}
+
+template<typename T,
+ template<typename,int> class NXVectorDerived1,
+ template<typename,int> class NXVectorDerived2
+ >
+ inline
+ NXVector<T,3> cross(NXVectorBase<T,3,NXVectorDerived1>& a,
+ NXVectorBase<T,3,NXVectorDerived2>& b)
+{
+ NXVector<T,3> c;
+ c[0] = a[1] * b[2] - a[2] * b[1];
+ c[1] = a[2] * b[0] - a[0] * b[2];
+ c[2] = a[0] * b[1] - a[1] * b[0];
+ return c;
+}
+
+// ------------------------------------------------------------------------
+/* NXVectorBase member functions - common operations */
+
+// template<typename T>
+// inline
+// NXVectorRef<T,1>& NXVectorRef<T,1>::zero(void)
+// { m_coords[0] = T(0); return *this; }
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVectorBase<T,N, NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::zero(void) throw()
+{
+ for(int n=0; n<N; ++n) data()[n] = T(0);
+/* if(N==1) m_coords[0] = T(0);
+ else {
+ NXVectorRef<T,N-1>(m_coords).zero();
+ m_coords[N-1]=T(0);
+ }*/
+ return *this;
+}
+
+// increment base-case
+// template<typename T>
+// inline
+// NXVectorRef<T,1>& NXVectorRef<T,1>::operator += (NXVectorRef<T,1> const& v)
+// { m_coords[0] += v.m_coords[0]; return *this; }
+
+// increment common-case
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ template<typename T1, template<typename, int> class NXVectorDerived2>
+ inline
+ NXVectorBase<T,N,NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::
+ operator += (NXVectorBase<T1,N,NXVectorDerived2> const& v)
+ throw()
+{
+ for(int n=0; n<N; ++n) data()[n] += static_cast<T const>(v.data()[n]);
+/* NXVectorRef<T,N-1>(m_coords) += NXVectorRef<T,N-1>(v.m_coords);
+ m_coords[N-1] += v.m_coords[N-1];*/
+ return *this;
+}
+
+// decrement base-case
+// template<typename T>
+// inline
+// NXVectorRef<T,1>& NXVectorRef<T,1>::operator -= (NXVectorRef<T,1> const& v)
+// { m_coords[0] -= v.m_coords[0]; return *this; }
+
+// decrement common-case
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ template<typename T1, template<typename, int> class NXVectorDerived2>
+ inline
+ NXVectorBase<T,N,NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::
+ operator -= (NXVectorBase<T1,N,NXVectorDerived2> const& v)
+ throw()
+{
+ for(int n=0; n<N; ++n) data()[n] -= static_cast<T const>(v.data()[n]);
+/* NXVectorRef<T,N-1>(m_coords) -= NXVectorRef<T,N-1>(v.m_coords);
+ m_coords[N-1] -= v.m_coords[N-1];*/
+ return *this;
+}
+
+// scaling base-case
+// template<typename T>
+// inline
+// NXVectorRef<T,1>& NXVectorRef<T,1>::operator *= (T const& c)
+// {
+// m_coords[0] *= c;
+// return *this;
+// }
+
+// scaling common-case
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ template<typename T1>
+ inline
+ NXVectorBase<T,N,NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::operator *= (T1 const& c) throw()
+{
+ for(int n=0; n<N; ++n) data()[n] *= static_cast<T const>(c);
+/* NXVectorRef<T,N-1>(m_coords) *= c;
+ m_coords[N-1] *= c;*/
+ return *this;
+}
+
+// scaling base-case
+// template<typename T>
+// inline
+// NXVectorRef<T,1>& NXVectorRef<T,1>::operator /= (T const& c)
+// {
+// m_coords[0] /= c;
+// return *this;
+// }
+
+// scaling common-case
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ template<typename T1>
+ inline
+ NXVectorBase<T,N,NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::operator /= (T1 const& c) throw()
+{
+ for(int n=0; n<N; ++n) data()[n] /= static_cast<T1 const>(c);
+/* NXVectorRef<T,N-1>(m_coords) /= c;
+ m_coords[N-1] /= c;*/
+ return *this;
+}
+
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVectorBase<T,N,NXVectorDerived>&
+ NXVectorBase<T,N,NXVectorDerived>::normalizeSelf(double const& TOL) throw()
+{
+ /// @fixme possible loss of precision through repeated interconversion
+ T const len = norm(*this);
+ if(double(len) < TOL) zero();
+ else this->operator /= (len);
+ return *this;
+}
+
+/// Return normalized copy without modifying self
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVector<T,N>
+ NXVectorBase<T,N,NXVectorDerived>::normalized(double const& TOL) const throw()
+{
+ NXVector<T,N> v(data());
+ v.normalizeSelf(TOL);
+ return v;
+}
+
+/// Unary minus
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVector<T,N>
+ NXVectorBase<T,N,NXVectorDerived>::operator - (void) const throw()
+{
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = -data()[n];
+ return result;
+}
+
+// Binary operators
+
+/// Addition
+template<typename T1, typename T2, int N,
+ template<typename,int> class NXVectorDerived1,
+ template<typename,int> class NXVectorDerived2
+ >
+ inline
+ NXVector<typename promotion_traits<T1,T2>::type, N>
+ operator + (NXVectorBase<T1,N,NXVectorDerived1>& v1,
+ NXVectorBase<T2,N,NXVectorDerived2>& v2)
+{
+ typedef typename promotion_traits<T1,T2>::type T;
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = v1[n] + v2[n];
+ return result;
+}
+
+
+/// Subtraction
+template<typename T1, typename T2, int N,
+ template<typename,int> class NXVectorDerived1,
+ template<typename,int> class NXVectorDerived2
+ >
+ inline
+ NXVector<typename promotion_traits<T1,T2>::type, N>
+ operator - (NXVectorBase<T1,N,NXVectorDerived1>& v1,
+ NXVectorBase<T2,N,NXVectorDerived2>& v2)
+{
+ typedef typename promotion_traits<T1,T2>::type T;
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = v1[n] - v2[n];
+ return result;
+}
+
+
+/// Scaling
+template<typename T1, typename T2, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVector<typename promotion_traits<T1,T2>::type, N>
+ operator * (T1 const& c, NXVectorBase<T2,N,NXVectorDerived>& v)
+{
+ typedef typename promotion_traits<T1,T2>::type T;
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = static_cast<T>(c) * static_cast<T>(v[n]);
+ return result;
+}
+
+
+/// Scaling - post-multiplication by scalar
+template<typename T1, typename T2, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVector<typename promotion_traits<T1,T2>::type, N>
+ operator * (NXVectorBase<T2,N,NXVectorDerived>& v, T1 const& c)
+{
+ typedef typename promotion_traits<T1,T2>::type T;
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = static_cast<T>(c) * static_cast<T>(v[n]);
+ return result;
+}
+
+
+/// Scaling - division by
+template<typename T1, typename T2, int N, template<typename,int> class NXVectorDerived>
+ inline
+ NXVector<typename promotion_traits<T1,T2>::type, N>
+ operator / (NXVectorBase<T2,N,NXVectorDerived>& v, T1 const& c)
+{
+ typedef typename promotion_traits<T1,T2>::type T;
+ NXVector<T,N> result;
+ for(int n=0; n<N; ++n)
+ result[n] = static_cast<T>(v[n]) / static_cast<T>(c);
+ return result;
+}
+
+
+template <typename T, int N, template <typename,int> class NXVectorDerived>
+ inline
+ std::ostream& operator << (std::ostream& o,
+ NXVectorBase<T,N,NXVectorDerived> const& v)
+{
+ o << '(';
+ for(int n=0; n<N-1; ++n)
+ o << v[n] << ',';
+ o << v[N-1] << ')';
+ return o;
+}
+
+} // Nanorex
+
+#endif // NX_VECTOR_H
+
diff --git a/cad/plugins/NanoVision-1/src/KDevelop/nv1.kdevelop b/cad/plugins/NanoVision-1/src/KDevelop/nv1.kdevelop
index 2feb5387d..148201ebc 100644
--- a/cad/plugins/NanoVision-1/src/KDevelop/nv1.kdevelop
+++ b/cad/plugins/NanoVision-1/src/KDevelop/nv1.kdevelop
@@ -142,39 +142,46 @@
</kdevdebugger>
<kdevtrollproject>
<run>
- <mainprogram>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/bin/nv1</mainprogram>
+ <mainprogram>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</mainprogram>
<programargs/>
<directoryradio>executable</directoryradio>
<globaldebugarguments/>
<globalcwd>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/bin/</globalcwd>
- <useglobalprogram>true</useglobalprogram>
+ <useglobalprogram>false</useglobalprogram>
<terminal>false</terminal>
<autocompile>false</autocompile>
<autoinstall>false</autoinstall>
<autokdesu>false</autokdesu>
<envvars>
<envvar value="/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/lib:/usr/local/lib" name="LD_LIBRARY_PATH" />
- <envvar value="/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop/count1" name="QMAKEFEATURES" />
</envvars>
<runarguments>
<HDF5_SimResultsImportExport/>
<GLT/>
- <CppUnit/>
+ <CppUnit>NXSceneGraphTestSuite</CppUnit>
<NXOpenGLRenderingEngineTest/>
<HDF5_Consumer/>
<nv1/>
<NXBallAndStickOpenGLRendererTest/>
<count1/>
+ <QTestLib/>
+ <QtTests/>
+ <MMPOpenGLRendererTest/>
+ <TrajectoryGraphicsWindowTest/>
</runarguments>
<cwd>
<HDF5_SimResultsImportExport>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</HDF5_SimResultsImportExport>
<GLT>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</GLT>
- <CppUnit>/home/bh/11Nano/SVN-D/cad/plugins/NanoVision-1/src/KDevelop/../../../..</CppUnit>
+ <CppUnit>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop/../../../../</CppUnit>
<HDF5_Consumer>/home/bh/11Nano/SVN-D/cad/plugins/NanoVision-1/src/KDevelop</HDF5_Consumer>
<nv1>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</nv1>
<NXBallAndStickOpenGLRendererTest>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</NXBallAndStickOpenGLRendererTest>
<count1>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</count1>
<NXOpenGLRenderingEngineTest>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop</NXOpenGLRenderingEngineTest>
+ <QTestLib>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/bin/</QTestLib>
+ <QtTests>/home/rmanoj/Nanorex/SVN/trunk/cad/plugins/NanoVision-1/src/KDevelop/../../../..</QtTests>
+ <MMPOpenGLRendererTest>../../../../../bin/</MMPOpenGLRendererTest>
+ <TrajectoryGraphicsWindowTest>../../../../../../../bin/</TrajectoryGraphicsWindowTest>
</cwd>
<debugarguments>
<HDF5_SimResultsImportExport/>
@@ -185,10 +192,14 @@
<nv1/>
<NXBallAndStickOpenGLRendererTest/>
<count1/>
+ <QTestLib/>
+ <QtTests/>
+ <MMPOpenGLRendererTest/>
+ <TrajectoryGraphicsWindowTest/>
</debugarguments>
</run>
<general>
- <activedir>nv1</activedir>
+ <activedir>Testing/Plugins/RenderingEngines/OpenGL/TrajectoryGraphicsWindowTest</activedir>
</general>
<make>
<abortonerror>false</abortonerror>
@@ -204,6 +215,8 @@
<replacePaths>false</replacePaths>
<disableDefaultOpts>true</disableDefaultOpts>
<enableFilenamesOnly>false</enableFilenamesOnly>
+ <showVariablesInTree>true</showVariablesInTree>
+ <showParseErrors>true</showParseErrors>
</qmake>
<subclassing/>
</kdevtrollproject>
diff --git a/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.cpp b/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.cpp
new file mode 100644
index 000000000..96abcc1d8
--- /dev/null
+++ b/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.cpp
@@ -0,0 +1,262 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#include "NXVectorTest.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(NXVectorTest);
+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(NXVectorTest,
+ "NXVectorTestSuite");
+
+// ---------------------------------------------------------------------
+/* Helper comparison functions */
+
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+void cppunit_assert_vectors_equal(NXVectorBase<T,N,NXVectorDerived> const& pRef,
+ T answer[N],
+ T const& delta = 1.0e-8)
+{
+ for(int n=0; n<N; ++n) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(double(pRef[n]),
+ double(answer[n]),
+ double(delta));
+ }
+}
+
+template<typename T, int N, template<typename,int> class NXVectorDerived>
+void cppunit_assert_points_unequal(NXVectorBase<T,N,NXVectorDerived> const& pRef,
+ T answer[N],
+ T const& delta = 1.0e-8)
+{
+ for(int n=0; n<N; ++n) {
+ CPPUNIT_ASSERT(fabs(double(pRef[n])-double(answer[n])) > double(delta));
+ }
+}
+
+template<typename T, int N,
+template<typename,int> class NXVectorDerived,
+template<typename,int> class NXVectorDerived2
+>
+void cppunit_assert_vectors_equal(NXVectorBase<T,N,NXVectorDerived> const& p1Ref,
+ NXVectorBase<T,N,NXVectorDerived2> const& p2Ref,
+ T const& delta = 1.0e-8)
+{
+ for(int n=0; n<N; ++n) {
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(double(p1Ref[n]),
+ double(p2Ref[n]),
+ double(delta));
+ }
+}
+
+
+// ---------------------------------------------------------------------
+/* Test-suite */
+
+void NXVectorTest::accessTest(void)
+{
+ NXVector4d p;
+ double answer[4] = { 0.0, 1.0, 2.0, 3.0 };
+ p[0] = answer[0]; p[1] = answer[1]; p[2] = answer[2]; p[3] = answer[3];
+ double const *const ptr = p.data();
+ CPPUNIT_ASSERT(ptr[0] == 0.0);
+ CPPUNIT_ASSERT(ptr[1] == 1.0);
+ CPPUNIT_ASSERT(ptr[2] == 2.0);
+ CPPUNIT_ASSERT(ptr[3] == 3.0);
+ cppunit_assert_vectors_equal(p, answer, 0.0);
+}
+
+void NXVectorTest::dataTest(void)
+{
+ NXVector4d p;
+ NXVectorRef4d pRef;
+ pRef = p;
+ CPPUNIT_ASSERT(p.data() == pRef.data());
+
+ // test copy constructor for deep-copy semantics
+ double init[4] = { 2.0, 3.0, -1.0, 6.0 };
+ NXVectorRef4d initRef(init);
+ NXVector4d initCopy(initRef);
+ CPPUNIT_ASSERT(initRef.data() != initCopy.data());
+ cppunit_assert_vectors_equal(initRef, initCopy);
+ // test copy assignment for deep-copy
+ initCopy.zero();
+ initCopy = initRef;
+ CPPUNIT_ASSERT(initRef.data() != initCopy.data());
+ cppunit_assert_vectors_equal(initRef, initCopy);
+}
+
+void NXVectorTest::sizeTest(void)
+{
+ NXVector4d p;
+ CPPUNIT_ASSERT(p.size() == 4);
+ NXVectorRef3f pRef;
+ CPPUNIT_ASSERT(pRef.size() == 3);
+}
+
+void NXVectorTest::zeroTest(void)
+{
+ NXVector4d p;
+ p.zero();
+ CPPUNIT_ASSERT(p[0] == 0.0);
+ CPPUNIT_ASSERT(p[1] == 0.0);
+ CPPUNIT_ASSERT(p[2] == 0.0);
+ CPPUNIT_ASSERT(p[3] == 0.0);
+
+ NXVector<char,2> cp;
+ cp.zero();
+ CPPUNIT_ASSERT(cp[0] == '\0');
+ CPPUNIT_ASSERT(cp[1] == '\0');
+}
+
+void NXVectorTest::incrementTest(void)
+{
+ NXVector4d p;
+ double init[4] = { 0.0, 1.0, 2.0, 3.0 };
+ p[0] = init[0]; p[1] = init[1]; p[2] = init[2]; p[3] = init[3];
+ NXVector4d p2;
+ p2.zero();
+ p2 += p;
+ cppunit_assert_vectors_equal(p2, init);
+ double twice[4] = { 0.0, 2.0, 4.0, 6.0 };
+ p2 += p2;
+ cppunit_assert_vectors_equal(p2, twice, 0.0);
+
+}
+
+void NXVectorTest::decrementTest(void)
+{
+ double zeros[4] = { 0.0, 0.0, 0.0, 0.0 };
+ NXVector4d p1;
+ p1.zero();
+ NXVector4d p2;
+ p2.zero();
+ p1 -= p2;
+ cppunit_assert_vectors_equal(p1, zeros, 0.0);
+
+ double init[4] = { 1.0, -2.0, 13.0, -27.0 };
+ double answer[4] = { -1.0, 2.0, -13.0, 27.0 };
+ NXVectorRef4d initRef(init);
+ NXVector4d initCopy = initRef;
+ cppunit_assert_vectors_equal(initRef, initCopy);
+ initCopy -= initRef;
+ cppunit_assert_vectors_equal(initCopy, zeros, 0.0);
+ initCopy -= initRef;
+ cppunit_assert_vectors_equal(initCopy, answer, 0.0);
+}
+
+void NXVectorTest::scalingTest(void)
+{
+ double init[4] = { 5.0, 8.0, -2.0, 3.0 };
+ double const factor = -2.0;
+ double answer[4] = { -10.0, -16.0, 4.0, -6.0 };
+ NXVectorRef4d p(init);
+ p *= factor;
+ cppunit_assert_vectors_equal(p, answer, 0.0);
+ // check to see if the reference updated the actual array
+ for(int n=0; n<4; ++n)
+ CPPUNIT_ASSERT(init[n] == answer[n]);
+}
+
+void NXVectorTest::invScalingTest(void)
+{
+ double init[4] = { -10.0, -16.0, 4.0, -6.0 };
+ double answer[4] = { 5.0, 8.0, -2.0, 3.0 };
+ double const factor = -2.0;
+ NXVectorRef4d p(init);
+ p /= factor;
+ cppunit_assert_vectors_equal(p, answer, 0.0);
+ // check to see if the reference updated the actual array
+ for(int n=0; n<4; ++n)
+ CPPUNIT_ASSERT(init[n] == answer[n]);
+}
+
+void NXVectorTest::dotTest(void)
+{
+ double p1Data[4] = { 5.0, 6.0, 7.0, 8.0 };
+ double p2Data[4] = { 8.0, 7.0, 6.0, 5.0 };
+ NXVectorRef4d p1(p1Data);
+ NXVectorRef4d p2(p2Data);
+ double const p1_dot_p2 = dot(p1, p2);
+ double const answer = (p1Data[0] * p2Data[0] +
+ p1Data[1] * p2Data[1] +
+ p1Data[2] * p2Data[2] +
+ p1Data[3] * p2Data[3]);
+ CPPUNIT_ASSERT(p1_dot_p2 == answer);
+}
+
+void NXVectorTest::squared_normTest(void)
+{
+ double pData[4] = { 5.0, 6.0, 7.0, 8.0 };
+ NXVectorRef4d p(pData);
+ double const pSquaredNorm = squared_norm(p);
+ double const answer = (pData[0] * pData[0] +
+ pData[1] * pData[1] +
+ pData[2] * pData[2] +
+ pData[3] * pData[3]);
+ CPPUNIT_ASSERT(pSquaredNorm == answer);
+}
+
+void NXVectorTest::normTest(void)
+{
+ double pData[5] = { 3.0, 4.0, 5.0, 5.0, 5.0 };
+ NXVectorRef<double,5> p(pData);
+ double const pNorm = norm(p);
+ double const answer = 10.0;
+ CPPUNIT_ASSERT_DOUBLES_EQUAL(pNorm, answer, 1.0e-8);
+}
+
+void NXVectorTest::normalizeSelfTest(void)
+{
+ double init[4] = { 1.0, 1.0, 1.0, 1.0 };
+ NXVector4d initCopy(init);
+ initCopy.normalizeSelf();
+ double answer[4] = { 0.5, 0.5, 0.5, 0.5 };
+ cppunit_assert_vectors_equal(initCopy, answer, 1.0e-8);
+
+ NXVector<float,2> pythagoreanPair;
+ pythagoreanPair[0] = 3.0f;
+ pythagoreanPair[1] = 4.0f;
+ pythagoreanPair.normalizeSelf();
+ float pythagoreanPairNormalizedValues[2] = { 0.6f, 0.8f };
+ NXVectorRef2f pythagoreanPairNormalized(pythagoreanPairNormalizedValues);
+ cppunit_assert_vectors_equal(pythagoreanPair,
+ pythagoreanPairNormalized,
+ 1.0e-8f);
+}
+
+void NXVectorTest::normalizedTest(void)
+{
+ double init[4] = { 1.0, 1.0, 1.0, 1.0 };
+ NXVector4d initCopy(init);
+ NXVector4d initNormalized = initCopy.normalized();
+ double answer[4] = { 0.5, 0.5, 0.5, 0.5 };
+ cppunit_assert_vectors_equal(initNormalized, answer, 1.0e-8);
+ cppunit_assert_points_unequal(initNormalized, init, 1.0e-8);
+}
+
+void NXVectorTest::crossTest(void)
+{
+ double iData[3] = { 1.0, 0.0, 0.0 };
+ double jData[3] = { 0.0, 1.0, 0.0 };
+ double kData[3] = { 0.0, 0.0, 1.0 };
+ NXVectorRef3d iUnit(iData), jUnit(jData), kUnit(kData);
+ NXVector3d iCross = cross(jUnit, kUnit);
+ cppunit_assert_vectors_equal(iCross, iUnit);
+ NXVector3d jCross = cross(kUnit, iUnit);
+ cppunit_assert_vectors_equal(jCross, jUnit);
+ NXVector3d kCross = cross(iUnit, jUnit);
+ cppunit_assert_vectors_equal(kCross, kUnit);
+
+ double pData[3] = { 2.0, 1.0, -1.0 };
+ double qData[3] = { -3.0, 4.0, 1.0 };
+ double pcrossqData [3] = { 5.0, 1.0, 11.0 };
+ NXVectorRef3d p(pData), q(qData);
+ NXVector3d r = cross(p,q);
+ cppunit_assert_vectors_equal(NXVectorRef3d(pcrossqData), r.data());
+
+ int lData[3] = { 0, 1, 1 };
+ int mData[3] = { 1, -1, 3 };
+ int minus_lcrossm_data[3] = { -4, -1, 1 };
+ NXVectorRef<int,3> l(lData), m(mData);
+ NXVector<int,3> n = cross(m,l);
+ cppunit_assert_vectors_equal(n, minus_lcrossm_data, 0);
+}
diff --git a/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.h b/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.h
new file mode 100644
index 000000000..10a5298b1
--- /dev/null
+++ b/cad/plugins/NanoVision-1/src/Utility/NXVectorTest.h
@@ -0,0 +1,51 @@
+// Copyright 2008 Nanorex, Inc. See LICENSE file for details.
+
+#ifndef NX_POINTTEST_H
+#define NX_POINTTEST_H
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "Nanorex/Utility/NXVector.h"
+
+using namespace Nanorex;
+
+class NXVectorTest : public CPPUNIT_NS::TestFixture {
+
+ CPPUNIT_TEST_SUITE(NXVectorTest);
+ CPPUNIT_TEST(accessTest);
+ CPPUNIT_TEST(dataTest);
+ CPPUNIT_TEST(sizeTest);
+ CPPUNIT_TEST(zeroTest);
+ CPPUNIT_TEST(incrementTest);
+ CPPUNIT_TEST(decrementTest);
+ CPPUNIT_TEST(scalingTest);
+ CPPUNIT_TEST(invScalingTest);
+ CPPUNIT_TEST(dotTest);
+ CPPUNIT_TEST(squared_normTest);
+ CPPUNIT_TEST(normTest);
+ CPPUNIT_TEST(normalizeSelfTest);
+ CPPUNIT_TEST(normalizedTest);
+ CPPUNIT_TEST(crossTest);
+ CPPUNIT_TEST_SUITE_END();
+
+public:
+ void setUp(void) {}
+ void tearDown(void) {}
+
+ void accessTest(void);
+ void dataTest(void);
+ void sizeTest(void);
+ void zeroTest(void);
+ void incrementTest(void);
+ void decrementTest(void);
+ void scalingTest(void);
+ void invScalingTest(void);
+ void dotTest(void);
+ void squared_normTest(void);
+ void normTest(void);
+ void normalizeSelfTest(void);
+ void normalizedTest(void);
+ void crossTest(void);
+};
+
+#endif // NX_POINTTEST_H