multiple files added

This commit is contained in:
Stefan Tröger 2013-10-03 12:27:15 +00:00
parent e8dda0b25a
commit 5dea42c995
9 changed files with 1625 additions and 0 deletions

View File

@ -0,0 +1,404 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_CORE_MULTIMAP_H
#define DCM_CORE_MULTIMAP_H
#include <Eigen/Dense>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/make_vector.hpp>
#include <boost/fusion/include/at.hpp>
#include <boost/fusion/include/at_c.hpp>
namespace dcm {
namespace details {
template<typename Derived>
class MultiMap;
}
}
namespace Eigen {
namespace internal {
template<typename PlainObjectType>
struct traits<dcm::details::MultiMap<PlainObjectType> >
: public traits<PlainObjectType> {
typedef traits<PlainObjectType> TraitsBase;
typedef typename PlainObjectType::Index Index;
typedef typename PlainObjectType::Scalar Scalar;
enum {
InnerStrideAtCompileTime = int(PlainObjectType::InnerStrideAtCompileTime),
OuterStrideAtCompileTime = int(PlainObjectType::OuterStrideAtCompileTime),
HasNoInnerStride = InnerStrideAtCompileTime == 1,
HasNoOuterStride = OuterStrideAtCompileTime == 1,
HasNoStride = HasNoInnerStride && HasNoOuterStride,
IsAligned = false,//bool(EIGEN_ALIGN),
IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,
KeepsPacketAccess = bool(HasNoInnerStride)
&& (bool(IsDynamicSize)
|| HasNoOuterStride
|| (OuterStrideAtCompileTime != Dynamic
&& ((static_cast<int>(sizeof(Scalar)) * OuterStrideAtCompileTime) % 16) == 0)),
Flags0 = TraitsBase::Flags & (~NestByRefBit),
Flags1 = IsAligned ? (int(Flags0) | AlignedBit) : (int(Flags0) & ~AlignedBit),
Flags2 = (bool(HasNoStride) || bool(PlainObjectType::IsVectorAtCompileTime))
? int(Flags1) : int(Flags1 & ~LinearAccessBit),
Flags3 = is_lvalue<PlainObjectType>::value ? int(Flags2) : (int(Flags2) & ~LvalueBit),
Flags = KeepsPacketAccess ? int(Flags3) : (int(Flags3) & ~PacketAccessBit)
};
private:
enum { Options }; // Expressions don't have Options
};
} //internal
} //Eigen
namespace dcm {
namespace details {
using namespace Eigen; //needed for macros
namespace fusion = boost::fusion;
template<typename Derived>
class MultiMapBase : public internal::dense_xpr_base<Derived>::type {
public:
typedef typename internal::dense_xpr_base<Derived>::type Base;
enum {
RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
SizeAtCompileTime = Base::SizeAtCompileTime
};
typedef typename internal::traits<Derived>::StorageKind StorageKind;
typedef typename internal::traits<Derived>::Index Index;
typedef typename internal::traits<Derived>::Scalar Scalar;
typedef typename internal::packet_traits<Scalar>::type PacketScalar;
typedef typename NumTraits<Scalar>::Real RealScalar;
typedef typename internal::conditional <
bool(internal::is_lvalue<Derived>::value),
Scalar*,
const Scalar* >::type
PointerType;
using Base::derived;
using Base::MaxRowsAtCompileTime;
using Base::MaxColsAtCompileTime;
using Base::MaxSizeAtCompileTime;
using Base::IsVectorAtCompileTime;
using Base::Flags;
using Base::IsRowMajor;
using Base::size;
using Base::coeff;
using Base::coeffRef;
using Base::lazyAssign;
using Base::eval;
// bug 217 - compile error on ICC 11.1
using Base::operator=;
typedef typename Base::CoeffReturnType CoeffReturnType;
typedef Stride<Dynamic, Dynamic> DynStride;
typedef fusion::vector6<PointerType, int, int, int, int, DynStride> MapData;
inline Index rows() const {
return m_rows.value();
}
inline Index cols() const {
return m_cols.value();
}
inline const Scalar* data() const {
assert(false);
return m_data;
}
inline const Scalar& coeff(Index row, Index col) const {
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > row && fusion::at_c<1>(data) <= row
&& (fusion::at_c<2>(data) + fusion::at_c<4>(data)) > col && fusion::at_c<2>(data) <= col)
return fusion::at_c<0>(data)[(col - fusion::at_c<2>(data)) * fusion::at_c<5>(data).outer() + (row - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner()];
};
return default_value;
}
inline const Scalar& coeff(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > index)
return fusion::at_c<0>(data)[(index - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner()];
};
return default_value;
}
inline const Scalar& coeffRef(Index row, Index col) const {
return coeff(row, col);
}
inline const Scalar& coeffRef(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
return coeff(index);
}
template<int LoadMode>
inline PacketScalar packet(Index row, Index col) const {
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > row && fusion::at_c<1>(data) <= row
&& (fusion::at_c<2>(data) + fusion::at_c<4>(data)) > col && fusion::at_c<2>(data) <= col)
return internal::ploadt<PacketScalar, LoadMode>
(fusion::at_c<0>(data) + (col - fusion::at_c<2>(data)) * fusion::at_c<5>(data).outer() + (row - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner());
};
return internal::ploadt<PacketScalar, LoadMode>(&default_value);
}
template<int LoadMode>
inline PacketScalar packet(Index index) const {
EIGEN_STATIC_ASSERT_INDEX_BASED_ACCESS(Derived)
typedef typename std::vector<MapData>::const_iterator iter;
for(iter i = m_data.begin(); i != m_data.end(); i++) {
const MapData& data = *i;
if((fusion::at_c<1>(data) + fusion::at_c<3>(data)) > index)
return internal::ploadt<PacketScalar, LoadMode>(fusion::at_c<0>(data) + (index - fusion::at_c<1>(data)) * fusion::at_c<5>(data).inner());
};
return internal::ploadt<PacketScalar, LoadMode>(&default_value);
}
// constructor for datapointer which resembles the fixed size derived type
// this works only if this is the only maped data!
inline MultiMapBase(PointerType data)
: default_value(0), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
// constructor for datapointer which resembles the derived dynamic size vector
inline MultiMapBase(PointerType data, Index size)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? 1 : Index(ColsAtCompileTime)) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, 0, 0, size, 1, DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
// constructor for datapointer which resembles the derived dynamic size matrix
// this works only if this matrix is the only mapped data!
inline MultiMapBase(PointerType data, Index rows, Index cols)
: default_value(0), m_rows(rows), m_cols(cols) {
eigen_assert((data == 0)
|| (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//the fixed size derived type. This only works if this is the only data
template<typename Stride>
inline MultiMapBase(PointerType data, const Stride& stride)
: default_value(0), m_rows(RowsAtCompileTime), m_cols(ColsAtCompileTime) {
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(stride.outer(), stride.inner())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//a part or all of the derived vector type.
template<typename Stride>
inline MultiMapBase(PointerType data, Index size, const Stride& stride)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? size : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? size : Index(ColsAtCompileTime)) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(stride.outer(), stride.inner())));
checkSanity();
}
//constructor for a data pointer with stride. Data in combination with stride needs to resemble
//a part or all of the derived matrix type
template<typename Stride>
inline MultiMapBase(PointerType data, Index rows, Index cols, const Stride& stride)
: default_value(0), m_rows(rows), m_cols(cols) {
eigen_assert((data == 0)
|| (rows >= 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols >= 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
m_data.push_back(fusion::make_vector(data, 0, 0, m_rows.value(), m_cols.value(), DynStride(Base::outerStride(), Base::innerStride())));
checkSanity();
}
//constructor for arbitrary dense matrix types. The matrix must resemble a part or all of the
//derived type.
template<typename DerivedType>
inline MultiMapBase(MatrixBase<DerivedType>& matrix)
: default_value(0),
m_rows(RowsAtCompileTime == Dynamic ? matrix.rows() : Index(RowsAtCompileTime)),
m_cols(ColsAtCompileTime == Dynamic ? matrix.cols() : Index(ColsAtCompileTime)) {
m_data.push_back(fusion::make_vector(&matrix(0, 0), 0, 0, matrix.rows(), matrix.cols(), DynStride(matrix.outerStride(), matrix.innerStride())));
checkSanity();
};
//map extensions
//**************
//extend with data vector in derived type form
inline void extend(PointerType data, Index size) {
extend(data, size, DynStride(Base::outerStride(), Base::innerStride()));
};
//extend with data vector in arbitrary form
template<typename Stride>
inline void extend(PointerType data, Index size, const Stride& stride) {
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(size >= 0);
eigen_assert(data == 0 || SizeAtCompileTime == Dynamic || SizeAtCompileTime == size);
m_data.push_back(fusion::make_vector(data, m_rows.value(), 0, size, 1, DynStride(stride.outer(), stride.inner())));
m_rows.setValue(m_rows.value() + size);
checkSanity();
};
//extend with eigen vector
template<typename DerivedType>
inline void extend(MatrixBase<DerivedType>& matrix) {
//this only works for vectors, as we would not know where to add a matrix
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
eigen_assert(matrix.cols() == 1);
extend(matrix.derived().data(), matrix.rows(), DynStride(matrix.outerStride(), matrix.innerStride()));
};
//extend with general pointer data
template<typename Stride>
inline void extend(PointerType matrix, Index row, Index col, Index rows, Index cols, const Stride& stride) {
m_data.push_back(fusion::make_vector(matrix, row, col, rows, cols, DynStride(stride.outer(), stride.inner())));
if((row + rows) > m_rows.value())
m_rows.setValue(row + rows);
if((col + cols) > m_cols.value())
m_cols.setValue(col + cols);
checkSanity();
};
//extend with pointer data in derived type form
inline void extend(PointerType matrix, Index row, Index col, Index rows, Index cols) {
extend(matrix.derived().data(), row, col, rows, cols, DynStride(Base::outerStride(), Base::innerStride()));
};
//extend with eigen matrix
template<typename DerivedType>
inline void extend(MatrixBase<DerivedType>& matrix, Index row, Index col) {
extend(matrix.derived().data(), row, col, matrix.rows(), matrix.cols(), DynStride(matrix.outerStride(), matrix.innerStride()));
};
protected:
void checkSanity() const {
EIGEN_STATIC_ASSERT(EIGEN_IMPLIES(internal::traits<Derived>::Flags & PacketAccessBit,
internal::inner_stride_at_compile_time<Derived>::ret == 1),
PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags & AlignedBit, (size_t(fusion::at_c<0>(m_data.back())) % 16) == 0)
&& "data is not aligned");
}
std::vector<MapData> m_data;
Scalar default_value;
internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
};
//this indirection is needed so that the map base coeff functions are called
template<typename Derived>
class MultiMap : public MultiMapBase< MultiMap<Derived> > {
public:
typedef MultiMapBase< MultiMap<Derived> > Base;
EIGEN_DENSE_PUBLIC_INTERFACE(MultiMap)
inline Index innerStride() const {
return 1;
}
inline Index outerStride() const {
if(Flags & RowMajorBit)
return Base::m_cols.value();
else // column-major
return Base::m_rows.value();
}
inline MultiMap(typename Base::PointerType matrix) : Base(matrix) {};
inline MultiMap(typename Base::PointerType matrix, typename Base::Index size) : Base(matrix, size) {};
inline MultiMap(typename Base::PointerType matrix,
typename Base::Index row,
typename Base::Index col) : Base(matrix, row, col) {};
template<typename DerivedType>
inline MultiMap(MatrixBase<DerivedType>& matrix) : Base(matrix) {};
};
} // details
} // dcm
#endif // EIGEN_MAPBASE_H

View File

@ -0,0 +1,63 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more detemplate tails.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_ALIGNMENT_HPP
#define DCM_ALIGNMENT_HPP
#include <opendcm/core/equations.hpp>
#include "distance.hpp"
namespace dcm {
struct Alignment : public dcm::constraint_sequence< fusion::vector2< Distance, Orientation > > {
//allow to set the distance
Alignment& operator()(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
Alignment& operator()(double val) {
fusion::at_c<0>(*this) = val;
return *this;
};
Alignment& operator()(double val1, Direction val2) {
fusion::at_c<0>(*this) = val1;
fusion::at_c<1>(*this) = val2;
return *this;
};
Alignment& operator()(Direction val1, double val2) {
fusion::at_c<0>(*this) = val2;
fusion::at_c<1>(*this) = val1;
return *this;
};
Alignment& operator=(Direction val) {
fusion::at_c<1>(*this) = val;
return *this;
};
Alignment& operator=(double val) {
fusion::at_c<0>(*this) = val;
return *this;
};
};
static Alignment alignment;
}//dcm
#endif //DCM_ALIGNMENT_HPP

View File

@ -0,0 +1,40 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2012 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DEFINES_SHAPE3D_H
#define GCM_DEFINES_SHAPE3D_H
namespace dcm {
enum purpose {
startpoint = 1,
midpoint,
endpoint,
line,
circle
};
namespace details {
struct mshape3d {}; //base of modulehlg3d::type to allow other modules check for it
} //details
} //dcm
#endif

View File

@ -0,0 +1,137 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_DISTANCE_SHAPE3D_H
#define GCM_DISTANCE_SHAPE3D_H
#include <opendcm/core/constraint.hpp>
#include <opendcm/moduleShape3d/geometry.hpp>
#include <math.h>
#include <Eigen/Dense>
#include <Eigen/Geometry>
namespace dcm {
template<typename Kernel>
struct Distance::type< Kernel, tag::point3D, tag::segment3D > {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
typedef typename Kernel::Vector3 Vector3;
typedef std::vector<typename Kernel::Vector3, Eigen::aligned_allocator<typename Kernel::Vector3> > Vec;
Scalar value, sc_value, cross_n, cross_v12_n, v12_n;
Vector3 v01, v02, v12, cross;
#ifdef USE_LOGGING
src::logger log;
attrs::mutable_constant< std::string > tag;
type() : tag("Distance point3D segment3D") {
log.add_attribute("Tag", tag);
};
#endif
//template definition
void calculatePseudo(typename Kernel::Vector& point, Vec& v1, typename Kernel::Vector& segment, Vec& v2) {
Vector3 dir = (segment.template head<3>() - segment.template tail<3>()).normalized();
Vector3 pp = segment.head(3) + (segment.head(3)-point.head(3)).norm()*dir;
#ifdef USE_LOGGING
if(!boost::math::isnormal(pp.norm()))
BOOST_LOG(log) << "Unnormal pseudopoint detected";
#endif
v2.push_back(pp);
};
void setScale(Scalar scale) {
sc_value = value*scale;
};
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& point, const E::MatrixBase<DerivedB>& segment) {
//diff = point1 - point2
v01 = point-segment.template head<3>();
v02 = point-segment.template tail<3>();
v12 = segment.template head<3>() - segment.template tail<3>();
cross = v01.cross(v02);
v12_n = v12.norm();
cross_n = cross.norm();
cross_v12_n = cross_n/std::pow(v12_n,3);
const Scalar res = cross.norm()/v12_n - sc_value;
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG(log) << "Unnormal residual detected: "<<res;
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
const E::MatrixBase<DerivedC>& dpoint) {
const Vector3 d_point = dpoint; //eigen only acceppts vector3 for cross product
const Vector3 d_cross = d_point.cross(v02) + v01.cross(d_point);
const Scalar res = cross.dot(d_cross)/(cross_n*v12_n);
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG(log) << "Unnormal first cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", segment: "<<segment.transpose()
<<" and dpoint: "<<dpoint.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
const E::MatrixBase<DerivedC>& dsegment) {
const Vector3 d_cross = - (dsegment.template head<3>().cross(v02) + v01.cross(dsegment.template tail<3>()));
const Vector3 d_v12 = dsegment.template head<3>() - dsegment.template tail<3>();
const Scalar res = cross.dot(d_cross)/(cross_n*v12_n) - v12.dot(d_v12)*cross_v12_n;
#ifdef USE_LOGGING
if(!boost::math::isfinite(res))
BOOST_LOG(log) << "Unnormal second cluster gradient detected: "<<res
<<" with point: "<<point.transpose()<<", segment: "<<segment.transpose()
<< "and dsegment: "<<dsegment.transpose();
#endif
return res;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
E::MatrixBase<DerivedC>& gradient) {
//gradient = (v02.cross(cross)+cross.cross(v01))/(cross.norm()*v12_n);
gradient = (v02-v01).cross(cross)/(cross_n*v12_n);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& point,
const E::MatrixBase<DerivedB>& segment,
E::MatrixBase<DerivedC>& gradient) {
gradient.template head<3>() = cross.cross(v02)/(cross_n*v12_n) - v12*cross_v12_n;
gradient.template tail<3>() = v01.cross(cross)/(cross_n*v12_n) + v12*cross_v12_n;
};
};
}
#endif //GCM_DISTANCE_SHAPE3D_H

View File

@ -0,0 +1,87 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_FIXED_SHAPE3D_H
#define GCM_FIXED_SHAPE3D_H
//we need constraints to identifie connections between geometries in our shapes, however, if the
//geometries are linked to each other a calculation is not necessary. Therfore a no-equation constraint
//is needed
#include <opendcm/core/equations.hpp>
namespace dcm {
namespace details {
//this equation is for internal use only. one needs to ensure the constraint is disabled after adding
//this fixed equation
struct Fixed : public Equation<Orientation, Direction, true> {
using Equation::operator=;
Fixed() : Equation(parallel) {};
template< typename Kernel, typename Tag1, typename Tag2 >
struct type : public PseudoScale<Kernel> {
typedef typename Kernel::number_type Scalar;
typedef typename Kernel::VectorMap Vector;
option_type value;
//we shall not use this equation, warn the user about wrong usage
template <typename DerivedA,typename DerivedB>
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientFirst(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam1) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
Scalar calculateGradientSecond(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
const E::MatrixBase<DerivedC>& dparam2) {
assert(false);
return 0;
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientFirstComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
template <typename DerivedA,typename DerivedB, typename DerivedC>
void calculateGradientSecondComplete(const E::MatrixBase<DerivedA>& param1,
const E::MatrixBase<DerivedB>& param2,
E::MatrixBase<DerivedC>& gradient) {
assert(false);
};
};
};
static Fixed fixed;
}//details
} //dcm
#endif

View File

@ -0,0 +1,223 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GENERATOR_SHAPE3D_H
#define GCM_GENERATOR_SHAPE3D_H
#include <opendcm/core/defines.hpp>
#include <opendcm/core/geometry.hpp>
#include <opendcm/module3d/defines.hpp>
#include "geometry.hpp"
#include "fixed.hpp"
#include "defines.hpp"
#include <boost/exception/errinfo_errno.hpp>
#include <boost/bind.hpp>
namespace dcm {
namespace details {
template<typename Sys>
struct ShapeGeneratorBase {
BOOST_MPL_ASSERT((typename system_traits<Sys>::template getModule<details::m3d>::has_module));
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef typename module3d::Constraint3D Constraint3D;
typedef typename system_traits<Sys>::template getModule<details::mshape3d>::type moduleShape3d;
typedef typename moduleShape3d::Shape3D Shape3D;
typedef typename moduleShape3d::shape_purpose_prop shape_purpose_prop;
typedef typename moduleShape3d::shape_geometry_prop shape_geometry_prop;
typedef typename moduleShape3d::shape_constraint_prop shape_constraint_prop;
Sys* m_system;
boost::shared_ptr<Shape3D> m_shape;
std::vector<boost::shared_ptr<Geometry3D> >* m_geometries;
std::vector<boost::shared_ptr<Shape3D> >* m_shapes;
std::vector<boost::shared_ptr<Constraint3D> >* m_constraints;
ShapeGeneratorBase(Sys* system) : m_system(system) {};
virtual ~ShapeGeneratorBase() {};
void set(boost::shared_ptr<Shape3D> shape,
std::vector<boost::shared_ptr<Geometry3D> >* geometries,
std::vector<boost::shared_ptr<Shape3D> >* shapes,
std::vector<boost::shared_ptr<Constraint3D> >* constraints) {
m_shape = shape;
m_geometries = geometries;
m_shapes = shapes;
m_constraints = constraints;
};
//check if all needed parts are supplied
virtual bool check() = 0;
//initialise all relations between the geometries
virtual void init() = 0;
//get geometry3d for optional types (e.g. midpoints)
virtual boost::shared_ptr<Geometry3D> getOrCreateG3d(int type) = 0;
//get hlgeometry3d for optional types
virtual boost::shared_ptr<Shape3D> getOrCreateHLG3d(int type) = 0;
};
} //details
struct dummy_generator {
template<typename Sys>
struct type : public details::ShapeGeneratorBase<Sys> {
type(Sys* system) : details::ShapeGeneratorBase<Sys>(system) {};
//check if all needed parts are supplied
virtual bool check() {
throw creation_error() << boost::errinfo_errno(210) << error_message("not all needd types for high level geometry present");
};
//initialise all relations between the geometries, throw on error
virtual void init() {
throw creation_error() << boost::errinfo_errno(211) << error_message("dummy generator can't create high level geometry");
};
//get geometry3d for optional types (e.g. midpoints)
virtual boost::shared_ptr<typename details::ShapeGeneratorBase<Sys>::Geometry3D> getOrCreateG3d(int type) {
throw creation_error() << boost::errinfo_errno(212) << error_message("dummy generator has no geometry to access");
};
//get hlgeometry3d for optional types
virtual boost::shared_ptr<typename details::ShapeGeneratorBase<Sys>::Shape3D> getOrCreateHLG3d(int type) {
throw creation_error() << boost::errinfo_errno(213) << error_message("dummy generator has no high level geometry to access");
};
};
};
//test generator
struct segment3D {
template<typename Sys>
struct type : public dcm::details::ShapeGeneratorBase<Sys> {
typedef dcm::details::ShapeGeneratorBase<Sys> base;
typedef typename Sys::Kernel Kernel;
using typename base::Geometry3D;
using typename base::Constraint3D;
using typename base::Shape3D;
type(Sys* system) : details::ShapeGeneratorBase<Sys>(system) {};
//check if all needed parts are supplied, a segment needs 2 points
virtual bool check() {
//even we have a real geometry segment
if(base::m_shape->getGeneralType() == tag::weight::segment::value)
return true;
//or two point geometries
if(base::m_geometries->size() == 2)
return true;
return false;
};
//initialise all relations between the geometries
virtual void init() {
if(base::m_shape->getGeneralType() == dcm::tag::weight::segment::value) {
//link the line geometrie to our shape
boost::shared_ptr<Geometry3D> g1 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g1);
g1->template linkTo<tag::segment3D>(base::m_shape,0);
g1->template setProperty<typename base::shape_purpose_prop>(line);
g1->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
//we have a segment, lets link the two points to it
boost::shared_ptr<Geometry3D> g2 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g2);
g2->template setProperty<typename base::shape_purpose_prop>(startpoint);
boost::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g3);
g3->template setProperty<typename base::shape_purpose_prop>(endpoint);
//link the points to our new segment
g2->template linkTo<tag::point3D>(base::m_shape, 0);
g3->template linkTo<tag::point3D>(base::m_shape, 3);
//add the fix constraints
boost::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g2, details::fixed);
boost::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
c2->disable(); //requiered by fixed constraint
}
else
if(base::m_geometries->size() == 2) {
//we have two points, lets get them
boost::shared_ptr<Geometry3D> g1 = base::m_geometries->operator[](0);
boost::shared_ptr<Geometry3D> g2 = base::m_geometries->operator[](1);
//possibility 1: two points. we add a segment line an link the point in
if(g1->getGeneralType() == tag::weight::point::value || g2->getGeneralType() == tag::weight::point::value) {
g1->template setProperty<typename base::shape_purpose_prop>(startpoint);
g2->template setProperty<typename base::shape_purpose_prop>(endpoint);
//construct our segment value
typename Kernel::Vector val(6);
val.head(3) = g1->getValue();
val.tail(3) = g2->getValue();
//the shape is a segment
base::m_shape->template setValue<tag::segment3D>(val);
//and create a segment geometry we use as line
boost::shared_ptr<Geometry3D> g3 = base::m_system->createGeometry3D();
base::m_geometries->push_back(g3);
g3->template linkTo<tag::segment3D>(base::m_shape,0);
g3->template setProperty<typename base::shape_purpose_prop>(line);
g3->template connectSignal<recalculated>(boost::bind(&base::Shape3D::recalc, base::m_shape, _1));
//link the points to our new segment
g1->template linkTo<tag::point3D>(base::m_shape, 0);
g2->template linkTo<tag::point3D>(base::m_shape, 3);
//add the fix constraints to show our relation
boost::shared_ptr<Constraint3D> c1 = base::m_system->createConstraint3D(g1,g3, details::fixed);
boost::shared_ptr<Constraint3D> c2 = base::m_system->createConstraint3D(g1,g3, details::fixed);
c1->disable(); //required by fixed constraint
c2->disable(); //requiered by fixed constraint
}
else
throw creation_error() << boost::errinfo_errno(501) << error_message("Wrong geometries for segment construction");
};
};
//get geometry3d for optional types (e.g. midpoints)
virtual boost::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Geometry3D> getOrCreateG3d(int type) {
return boost::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Geometry3D>();
};
//get hlgeometry3d for optional types
virtual boost::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Shape3D> getOrCreateHLG3d(int type) {
return boost::shared_ptr<typename dcm::details::ShapeGeneratorBase<Sys>::Shape3D>();
};
};
};
} //dcm
#endif //GCM_GENERATOR_SHAPE3D_H

View File

@ -0,0 +1,45 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_GEOMETRY_HL3D_H
#define GCM_GEOMETRY_HL3D_H
#include "opendcm/core/geometry.hpp"
#include "opendcm/module3d/geometry.hpp"
namespace dcm {
namespace details {
template<typename T>
struct tag_traits {
typedef void return_type;
typedef void value_type;
BOOST_MPL_ASSERT_MSG(false, NO_TAG_TRAITS_SPECIFIED_FOR_TYPE, (T));
};
} //details
namespace tag {
struct segment3D : details::stacked2_geometry<weight::segment, point3D, point3D> {};
} //tag
} //dcm
#endif

View File

@ -0,0 +1,591 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef GCM_MODULE_SHAPE3D_H
#define GCM_MODULE_SHAPE3D_H
#include <opendcm/core.hpp>
#include <opendcm/core/geometry.hpp>
#include <opendcm/module3d.hpp>
#include "defines.hpp"
#include "geometry.hpp"
#include "generator.hpp"
#include <boost/mpl/if.hpp>
#include <boost/mpl/map.hpp>
#include <boost/type_traits.hpp>
#include <boost/preprocessor.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#define APPEND_SINGLE(z, n, data) \
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::geometry_types gtypes; \
g_ptr = details::converter_g<BOOST_PP_CAT(Arg,n), Geometry3D>::template apply<gtypes, Sys>(BOOST_PP_CAT(arg,n), m_this); \
if(!g_ptr) { \
hlg_ptr = details::converter_hlg<BOOST_PP_CAT(Arg,n), Shape3D>::template apply<Sys>(BOOST_PP_CAT(arg,n), data); \
if(!hlg_ptr) \
throw creation_error() << boost::errinfo_errno(216) << error_message("could not handle input"); \
else \
data->append(hlg_ptr);\
} \
else { \
data->append(g_ptr); \
} \
#define CREATE_DEF(z, n, data) \
template < \
typename Generator \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg) \
> \
boost::shared_ptr<Shape3D> createShape3D( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
);
#define CREATE_DEC(z, n, data) \
template<typename TypeList, typename ID> \
template<typename Sys> \
template <\
typename Generator \
BOOST_PP_ENUM_TRAILING_PARAMS(n, typename Arg)\
> \
boost::shared_ptr<typename ModuleShape3D<TypeList, ID>::template type<Sys>::Shape3D> \
ModuleShape3D<TypeList, ID>::type<Sys>::inheriter_base::createShape3D( \
BOOST_PP_ENUM_BINARY_PARAMS(n, Arg, const& arg) \
) \
{ \
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d; \
typedef typename module3d::Geometry3D Geometry3D; \
boost::shared_ptr<Geometry3D> g_ptr; \
boost::shared_ptr<Shape3D> hlg_ptr; \
boost::shared_ptr<Shape3D> ptr = boost::shared_ptr<Shape3D>(new Shape3D(*m_this)); \
BOOST_PP_REPEAT(n, APPEND_SINGLE, ptr) \
ptr->template initShape<Generator>();\
m_this->push_back(ptr);\
return ptr;\
};
namespace mpl = boost::mpl;
namespace dcm {
namespace details {
//return always a geometry3d pointer struct, no matter whats the supplied type
template<typename T, typename R>
struct converter_g {
//check if the type T is usable from within module3d, as it could also be a shape type
template<typename gtypes, typename Sys>
static typename boost::enable_if<
mpl::not_< boost::is_same<
typename mpl::find<gtypes, T>::type,typename mpl::end<gtypes>::type> >,
boost::shared_ptr<R> >::type apply(T const& t, Sys* sys) {
return sys->createGeometry3D(t);
};
//seems to be a shape type, return an empty geometry
template<typename gtypes, typename Sys>
static typename boost::enable_if<
boost::is_same<
typename mpl::find<gtypes, T>::type, typename mpl::end<gtypes>::type>,
boost::shared_ptr<R> >::type apply(T const& t, Sys* sys) {
return boost::shared_ptr<R>();
};
};
template<typename R>
struct converter_g< boost::shared_ptr<R>, R> {
template<typename gtypes, typename Sys>
static boost::shared_ptr<R> apply(boost::shared_ptr<R> t, Sys* sys) {
return t;
};
};
template<typename T, typename R>
struct converter_hlg {
template<typename Sys>
static typename boost::enable_if<
boost::is_same<
typename mpl::find<typename system_traits<Sys>::template getModule<details::mshape3d>::type::geometry_types, T>::type,
typename mpl::end<typename system_traits<Sys>::template getModule<details::mshape3d>::type::geometry_types>::type>,
boost::shared_ptr<R> >::type apply(T const& t, boost::shared_ptr<R> self) {
return boost::shared_ptr<R>();
};
template<typename Sys>
static typename boost::enable_if<
mpl::not_< boost::is_same<
typename mpl::find<typename system_traits<Sys>::template getModule<details::mshape3d>::type::geometry_types, T>::type,
typename mpl::end<typename system_traits<Sys>::template getModule<details::mshape3d>::type::geometry_types>::type> >,
boost::shared_ptr<R> >::type apply(T const& t, boost::shared_ptr<R> self) {
self->set(t);
return self;
};
};
template<typename R>
struct converter_hlg<boost::shared_ptr<R>, R> {
template<typename Sys>
static boost::shared_ptr<R> apply(boost::shared_ptr<R> t, boost::shared_ptr<R> self) {
return t;
};
};
}//details
template<typename TypeList, typename ID = No_Identifier>
struct ModuleShape3D {
template<typename Sys>
struct type : details::mshape3d {
typedef TypeList geometry_types;
//forward declare
struct inheriter_base;
struct Shape3D;
typedef mpl::map0<> ShapeSig;
template<typename Derived>
struct Shape3D_base : public details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries>, public Object<Sys, Derived, ShapeSig > {
typedef typename Sys::Kernel Kernel;
typedef typename Kernel::number_type Scalar;
//traits are only accessible in subclass scope
BOOST_MPL_ASSERT((typename system_traits<Sys>::template getModule<details::m3d>::has_module));
typedef typename system_traits<Sys>::template getModule<details::m3d>::type module3d;
typedef typename module3d::Geometry3D Geometry3D;
typedef typename module3d::Constraint3D Constraint3D;
Shape3D_base(Sys& system);
template<typename T>
Shape3D_base(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry);
bool holdsType() {
return m_geometry.which()!=0;
};
int whichType() {
return m_geometry.which()-1;
};
template<typename Visitor>
typename Visitor::result_type apply(Visitor& vis) {
return boost::apply_visitor(vis, m_geometry);
};
template<typename T>
T convertTo() {
T t;
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, Base::m_global);
return t;
};
virtual boost::shared_ptr<Derived> clone(Sys& newSys);
/*shape access functions*/
typedef typename std::vector<boost::shared_ptr<Geometry3D> >::const_iterator geometry3d_iterator;
typedef typename std::vector<boost::shared_ptr<Shape3D> >::const_iterator shape3d_iterator;
shape3d_iterator beginShape3D() {
return m_shapes.begin();
};
shape3d_iterator endShape3D() {
return m_shapes.end();
};
geometry3d_iterator beginGeometry3D() {
return m_geometries.begin();
};
geometry3d_iterator endGeometry3D() {
return m_geometries.end();
};
boost::shared_ptr<Geometry3D> geometry(purpose f);
template<typename T>
boost::shared_ptr<Shape3D> subshape();
void recalc(boost::shared_ptr<Geometry3D> g);
protected:
typedef details::Geometry<typename Sys::Kernel, 3, typename Sys::geometries> Base;
typedef Object<Sys, Derived, ShapeSig > ObjBase;
typedef typename mpl::push_front<TypeList, boost::blank>::type ExtTypeList;
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
struct cloner : boost::static_visitor<void> {
typedef typename boost::make_variant_over< ExtTypeList >::type Variant;
Variant variant;
cloner(Variant& v) : variant(v) {};
template<typename T>
void operator()(T& t) {
variant = geometry_clone_traits<T>()(t);
};
};
//visitor to write the calculated value into the variant
struct apply_visitor : public boost::static_visitor<void> {
apply_visitor(typename Kernel::Vector& v) : value(v) {};
template <typename T>
void operator()(T& t) const {
(typename geometry_traits<T>::modell()).template inject<typename Kernel::number_type,
typename geometry_traits<T>::accessor >(t, value);
}
typename Kernel::Vector& value;
};
Variant m_geometry; //Variant holding the real geometry type
boost::shared_ptr< details::ShapeGeneratorBase<Sys> > m_generator;
using Object<Sys, Derived, mpl::map0<> >::m_system;
std::vector<boost::shared_ptr<Geometry3D> > m_geometries;
std::vector<boost::shared_ptr<Derived> > m_shapes;
std::vector<boost::shared_ptr<Constraint3D> > m_constraints;
template<typename generator>
void initShape() {
m_generator = boost::shared_ptr<details::ShapeGeneratorBase<Sys> >(new typename generator::template type<Sys>(m_system));
m_generator->set(ObjBase::shared_from_this(), &m_geometries, &m_shapes, &m_constraints);
if(!m_generator->check())
throw creation_error() << boost::errinfo_errno(210) << error_message("not all needd geometry for shape present");
m_generator->init();
};
boost::shared_ptr<Derived> append(boost::shared_ptr<Geometry3D> g);
boost::shared_ptr<Derived> append(boost::shared_ptr<Derived> g);
//override protected event functions to emit signals
void reset() {};
void recalculated() {};
void removed() {};
friend struct inheriter_base;
friend struct Object<Sys, Derived, mpl::map0<> >;
};
template<typename Derived>
class Shape3D_id : public Shape3D_base<Derived> {
typedef Shape3D_base<Derived> Base;
#ifdef USE_LOGGING
attrs::mutable_constant< std::string > log_id;
#endif
public:
Shape3D_id(Sys& system);
template<typename T>
Shape3D_id(const T& geometry, Sys& system);
template<typename T>
void set(const T& geometry, ID id);
//somehow the base class set funtion is not found
template<typename T>
void set(const T& geometry);
ID& getIdentifier();
void setIdentifier(ID id);
};
struct Shape3D : public mpl::if_<boost::is_same<ID, No_Identifier>,
Shape3D_base<Shape3D>, Shape3D_id<Shape3D> >::type {
Shape3D(Sys& system);
template<typename T>
Shape3D(const T& geometry, Sys& system);
//allow accessing the internals by module3d classes but not by users
friend struct details::ClusterMath<Sys>;
friend struct details::ClusterMath<Sys>::map_downstream;
friend struct details::SystemSolver<Sys>;
friend struct details::SystemSolver<Sys>::Rescaler;
friend struct inheriter_base;
public:
//the geometry class itself does not hold an aligned eigen object, but maybe the variant
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};
//inheriter for own functions
struct inheriter_base {
inheriter_base(){
m_this = (Sys*)this;
};
private:
Sys* m_this;
public:
//with no vararg templates before c++11 we need preprocessor to create the overloads of create we need
BOOST_PP_REPEAT(5, CREATE_DEF, ~)
};
struct inheriter_id : public inheriter_base {};
struct inheriter : public mpl::if_<boost::is_same<ID, No_Identifier>, inheriter_base, inheriter_id>::type {};
//add properties to geometry and constraint to evaluate their shape partipance
struct shape_purpose_prop {
typedef purpose type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D kind;
};
struct shape_geometry_prop {
typedef bool type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D kind;
};
struct shape_constraint_prop {
typedef bool type;
typedef typename system_traits<Sys>::template getModule<details::m3d>::type::Constraint3D kind;
};
//needed typedefs
typedef ID Identifier;
typedef mpl::vector3<shape_purpose_prop, shape_constraint_prop, shape_geometry_prop> properties;
typedef mpl::vector1<Shape3D> objects;
typedef mpl::vector1<tag::segment3D> geometries;
//needed static functions
static void system_init(Sys& sys) {};
static void system_copy(const Sys& from, Sys& into) {};
};
};
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
/*****************************************************************************************************************/
BOOST_PP_REPEAT(5, CREATE_DEC, ~)
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::Shape3D_base(Sys& system)
: Object<Sys, Derived, ShapeSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::Shape3D_base(const T& geometry, Sys& system)
: Object<Sys, Derived, ShapeSig>(system) {
#ifdef USE_LOGGING
log.add_attribute("Tag", attrs::constant< std::string >("Geometry3D"));
#endif
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
Base::template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, Base::getValue());
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::set(const T& geometry) {
m_geometry = geometry;
//first init, so that the geometry internal vector has the right size
this->template init< typename geometry_traits<T>::tag >();
//now write the value;
(typename geometry_traits<T>::modell()).template extract<Scalar,
typename geometry_traits<T>::accessor >(geometry, this->getValue());
reset();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived> ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::clone(Sys& newSys) {
//copy the standart stuff
boost::shared_ptr<Derived> np = boost::shared_ptr<Derived>(new Derived(*static_cast<Derived*>(this)));
np->m_system = &newSys;
//it's possible that the variant contains pointers, so we need to clone them
cloner clone_fnc(np->m_geometry);
boost::apply_visitor(clone_fnc, m_geometry);
return np;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<typename system_traits<Sys>::template getModule<details::m3d>::type::Geometry3D>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::geometry(purpose f) {
for(geometry3d_iterator it = m_geometries.begin(); it != m_geometries.end(); it++) {
if((*it)->template getProperty<shape_purpose_prop>() == f)
return *it;
};
return boost::shared_ptr<Geometry3D>();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(boost::shared_ptr<Geometry3D> g) {
m_geometries.push_back(g);
g->template setProperty<shape_geometry_prop>(true);
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
boost::shared_ptr<Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::append(boost::shared_ptr<Derived> g) {
m_shapes.push_back(g);
return ObjBase::shared_from_this();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_base<Derived>::recalc(boost::shared_ptr<Geometry3D> g) {
//we recalculated thebase line, that means we have our new value. use it.
Base::finishCalculation();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::Shape3D_id(Sys& system)
: ModuleShape3D<Typelist, ID>::template type<Sys>::template Shape3D_base<Derived>(system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::Shape3D_id(const T& geometry, Sys& system)
: ModuleShape3D<Typelist, ID>::template type<Sys>::template Shape3D_base<Derived>(geometry, system)
#ifdef USE_LOGGING
, log_id("No ID")
#endif
{
#ifdef USE_LOGGING
Base::log.add_attribute("ID", log_id);
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::set(const T& geometry, Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
template<typename T>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::set(const T& geometry) {
Base::set(geometry);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
typename ModuleShape3D<Typelist, ID>::template type<Sys>::Identifier&
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::getIdentifier() {
return this->template getProperty<id_prop<Identifier> >();
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename Derived>
void ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D_id<Derived>::setIdentifier(Identifier id) {
this->template setProperty<id_prop<Identifier> >(id);
#ifdef USE_LOGGING
std::stringstream str;
str<<this->template getProperty<id_prop<Identifier> >();
log_id.set(str.str());
BOOST_LOG(Base::log)<<"Identifyer set: "<<id;
#endif
};
template<typename Typelist, typename ID>
template<typename Sys>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D::Shape3D(Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Shape3D_base<Shape3D>,
Shape3D_id<Shape3D> >::type(system) {
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
ModuleShape3D<Typelist, ID>::type<Sys>::Shape3D::Shape3D(const T& geometry, Sys& system)
: mpl::if_<boost::is_same<Identifier, No_Identifier>,
Shape3D_base<Shape3D>,
Shape3D_id<Shape3D> >::type(geometry, system) {
};
}//dcm
#endif //GCM_MODULE_SHAPE3D_H

View File

@ -0,0 +1,35 @@
/*
openDCM, dimensional constraint manager
Copyright (C) 2013 Stefan Troeger <stefantroeger@gmx.net>
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef DCM_MODULEHL3D_H
#define DCM_MODULEHL3D_H
#define DCM_USE_MODULEHL3D
#ifdef _WIN32
//warning about to long decoraded names, won't affect the code correctness
#pragma warning( disable : 4503 )
#endif
#include "moduleShape3d/defines.hpp"
#include "moduleShape3d/module.hpp"
#include "moduleShape3d/geometry.hpp"
#include "moduleShape3d/distance.hpp"
#endif //DCM_MODULEHL3D_H