make solution spaces accessible from GUI and fix some solver implementation errors
This commit is contained in:
parent
3abda4dd67
commit
45a3f149c3
|
@ -78,6 +78,7 @@ Constraint::Constraint()
|
|||
ADD_PROPERTY(Value,(0));
|
||||
ADD_PROPERTY(Orientation, (long(0)));
|
||||
ADD_PROPERTY(Type, (long(6)));
|
||||
ADD_PROPERTY(SolutionSpace, (long(0)));
|
||||
|
||||
std::vector<std::string> vec;
|
||||
vec.push_back("Parallel");
|
||||
|
@ -95,6 +96,12 @@ Constraint::Constraint()
|
|||
vec2.push_back("Coincident");
|
||||
vec2.push_back("None");
|
||||
Type.setEnumVector(vec2);
|
||||
|
||||
std::vector<std::string> vec3;
|
||||
vec3.push_back("Bidirectional");
|
||||
vec3.push_back("Positiv directional");
|
||||
vec3.push_back("Negative directional");
|
||||
SolutionSpace.setEnumVector(vec3);
|
||||
}
|
||||
|
||||
short Constraint::mustExecute() const
|
||||
|
@ -175,12 +182,24 @@ void Constraint::init(Assembly::ItemAssembly* ass)
|
|||
break;
|
||||
default:
|
||||
dir = dcm::perpendicular;
|
||||
|
||||
};
|
||||
|
||||
//we may need the SolutionSpace
|
||||
dcm::SolutionSpace sspace;
|
||||
switch(SolutionSpace.getValue()) {
|
||||
case 0:
|
||||
sspace = dcm::bidirectional;
|
||||
break;
|
||||
case 1:
|
||||
sspace = dcm::positiv_directional;
|
||||
break;
|
||||
default:
|
||||
sspace = dcm::negative_directional;
|
||||
};
|
||||
|
||||
//distance constraint
|
||||
if(Type.getValue() == 1)
|
||||
m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, dcm::distance = Value.getValue());
|
||||
m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, (dcm::distance = Value.getValue()) & (dcm::distance=sspace));
|
||||
|
||||
//orientation constraint
|
||||
if(Type.getValue() == 2)
|
||||
|
@ -192,7 +211,7 @@ void Constraint::init(Assembly::ItemAssembly* ass)
|
|||
|
||||
//alignemnt constraint
|
||||
if(Type.getValue() == 4)
|
||||
m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, dcm::alignment(dir, Value.getValue()));
|
||||
m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, (dcm::alignment=dir) & (dcm::alignment=Value.getValue()) & (dcm::alignment=sspace));
|
||||
|
||||
//coincident constraint
|
||||
if(Type.getValue() == 5)
|
||||
|
|
|
@ -54,6 +54,7 @@ public:
|
|||
App::PropertyLinkSub Second;
|
||||
App::PropertyFloat Value;
|
||||
App::PropertyEnumeration Orientation;
|
||||
App::PropertyEnumeration SolutionSpace;
|
||||
App::PropertyEnumeration Type;
|
||||
|
||||
/** @name methods override feature */
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <boost/fusion/include/for_each.hpp>
|
||||
#include <boost/fusion/include/map.hpp>
|
||||
#include <boost/fusion/include/as_map.hpp>
|
||||
#include <boost/fusion/include/filter_view.hpp>
|
||||
|
||||
#include <boost/exception/exception.hpp>
|
||||
|
||||
|
@ -52,7 +53,7 @@ namespace dcm {
|
|||
enum Direction { parallel, equal, opposite, perpendicular };
|
||||
|
||||
//the possible solution spaces
|
||||
enum SolutionSpace {unidirectional, positiv_directional, negative_directional};
|
||||
enum SolutionSpace {bidirectional, positiv_directional, negative_directional};
|
||||
|
||||
struct no_option {};
|
||||
|
||||
|
@ -84,12 +85,36 @@ struct EQ {};
|
|||
template<typename Seq, typename T>
|
||||
struct pushed_seq;
|
||||
|
||||
//metafunctions to retrieve the options of an equation
|
||||
template<typename T>
|
||||
struct options {
|
||||
typedef typename T::options type;
|
||||
};
|
||||
template<>
|
||||
struct options< mpl::arg<-1> > {
|
||||
typedef fusion::map<> type;
|
||||
};
|
||||
template<typename Eq, typename Opt>
|
||||
struct has_option : public mpl::if_<mpl::has_key<typename options<Eq>::type, Opt>, boost::true_type, boost::false_type>::type {
|
||||
typedef typename mpl::has_key<typename options<Eq>::type, Opt>::type type;
|
||||
};
|
||||
template<typename cs, typename T>
|
||||
struct seq_has_option {
|
||||
typedef typename mpl::transform<cs, has_option<mpl::_1, T> >::type bool_seq;
|
||||
typedef typename mpl::not_<boost::is_same<typename mpl::find<bool_seq, mpl::true_>::type, mpl::end<bool_seq> > >::type type;
|
||||
};
|
||||
|
||||
template<typename seq>
|
||||
struct constraint_sequence : public seq {
|
||||
|
||||
//an equation gets added to this equation
|
||||
template<typename T>
|
||||
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<seq, T>::type >::type operator &(T val) {
|
||||
void pretty(T type) {
|
||||
std::cout<<"pretty: "<<__PRETTY_FUNCTION__<<std::endl;
|
||||
};
|
||||
|
||||
//an equation gets added to this sequence
|
||||
template<typename T>
|
||||
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<seq, T>::type >::type operator &(T& val) {
|
||||
|
||||
typedef typename pushed_seq<seq, T>::type Sequence;
|
||||
typedef typename fusion::result_of::begin<Sequence>::type Begin;
|
||||
|
@ -113,20 +138,14 @@ struct constraint_sequence : public seq {
|
|||
return vec;
|
||||
};
|
||||
|
||||
//an sequence gets added to this sequence (happens only if sequenced equations like coincident are used)
|
||||
template<typename T>
|
||||
void pretty(T type) {
|
||||
std::cout<<"pretty: "<<__PRETTY_FUNCTION__<<std::endl;
|
||||
};
|
||||
|
||||
//an sequence gets added to this equation (happens only if sequenced equations like coincident are used)
|
||||
template<typename T>
|
||||
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, seq>::type >::type operator &(T val) {
|
||||
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, seq>::type >::type operator &(T& val) {
|
||||
|
||||
typedef typename pushed_seq<T, seq>::type Sequence;
|
||||
typedef typename fusion::result_of::begin<Sequence>::type Begin;
|
||||
typedef typename fusion::result_of::find<Sequence, typename fusion::result_of::back<typename pushed_seq<T, seq>::S1>::type >::type EndF;
|
||||
|
||||
|
||||
//create the new sequence
|
||||
Sequence vec;
|
||||
|
||||
|
@ -136,7 +155,6 @@ struct constraint_sequence : public seq {
|
|||
fusion::iterator_range<Begin, EndF> range(b, ef);
|
||||
fusion::copy(val, range);
|
||||
|
||||
|
||||
//to copy the types of the second sequence is not as easy as before. If types were already present in
|
||||
//the original sequence they are not added again. therefore we need to find all types of the second sequence
|
||||
//in the new one and assign the objects to this positions.
|
||||
|
@ -153,6 +171,17 @@ struct constraint_sequence : public seq {
|
|||
//and return our new extendet sequence
|
||||
return vec;
|
||||
};
|
||||
|
||||
//we also allow to set values directly into the equation, as this makes it more compftable for multi constraints
|
||||
//as align. Note that this only works if all option types of all equations in this sequence are distinguishable
|
||||
template<typename T>
|
||||
typename boost::enable_if<typename seq_has_option<seq, T>::type, constraint_sequence<seq>&>::type
|
||||
operator=(const T& val) {
|
||||
|
||||
fusion::filter_view<constraint_sequence, has_option<mpl::_, T > > view(*this);
|
||||
fusion::front(view) = val;
|
||||
return *this;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Seq, typename T>
|
||||
|
@ -204,23 +233,27 @@ struct Equation : public EQ {
|
|||
return operator()(val);
|
||||
};
|
||||
//assign complete equation
|
||||
template<typename T>
|
||||
typename boost::enable_if<boost::is_base_of<EQ, T>, Derived& >::type
|
||||
operator=(T& eq) {
|
||||
Derived& operator=(const Derived& eq) {
|
||||
|
||||
//we only copy the values which were set and are therefore valid
|
||||
option_copy oc(values);
|
||||
fusion::for_each(eq.values, oc);
|
||||
|
||||
//the assigned eqution can be set back to default for convinience in further usage
|
||||
eq.setDefault();
|
||||
const_cast<Derived*>(&eq)->setDefault();
|
||||
|
||||
return *static_cast<Derived*>(this);
|
||||
};
|
||||
/*
|
||||
Derived& operator=(const Derived& eq) {
|
||||
option_copy oc(values);
|
||||
fusion::for_each(eq.values, oc);
|
||||
return *static_cast<Derived*>(this);
|
||||
};*/
|
||||
|
||||
//an equation gets added to this equation
|
||||
template<typename T>
|
||||
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<T, Derived>::type >::type operator &(const T& val) {
|
||||
typename boost::enable_if< boost::is_base_of< dcm::EQ, T>, typename pushed_seq<T, Derived>::type >::type operator &(T& val) {
|
||||
|
||||
typename pushed_seq<T, Derived>::type vec;
|
||||
*fusion::find<T>(vec) = val;
|
||||
|
@ -230,7 +263,7 @@ struct Equation : public EQ {
|
|||
|
||||
//an sequence gets added to this equation (happens only if sequenced equations like coincident are used)
|
||||
template<typename T>
|
||||
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, Derived>::type >::type operator &(const T& val) {
|
||||
typename boost::enable_if< mpl::is_sequence<T>, typename pushed_seq<T, Derived>::type >::type operator &(T& val) {
|
||||
|
||||
typedef typename pushed_seq<T, Derived>::type Sequence;
|
||||
typedef typename fusion::result_of::begin<Sequence>::type Begin;
|
||||
|
@ -257,6 +290,28 @@ struct Equation : public EQ {
|
|||
virtual void setDefault() = 0;
|
||||
};
|
||||
|
||||
//convinience stream functions for debugging
|
||||
template <typename charT, typename traits>
|
||||
struct print_pair {
|
||||
std::basic_ostream<charT,traits>* stream;
|
||||
|
||||
template<typename T>
|
||||
void operator()(const T& t) const {
|
||||
*stream << "("<<t.second.first << ", "<<t.second.second<<") ";
|
||||
};
|
||||
};
|
||||
|
||||
template <typename charT, typename traits, typename Eq>
|
||||
typename boost::enable_if<boost::is_base_of<EQ, Eq>, std::basic_ostream<charT,traits>&>::type
|
||||
operator << (std::basic_ostream<charT,traits> & stream, const Eq& equation)
|
||||
{
|
||||
print_pair<charT, traits> pr;
|
||||
pr.stream = &stream;
|
||||
stream << typeid(equation).name() << ": ";
|
||||
fusion::for_each(equation.values, pr);
|
||||
return stream;
|
||||
}
|
||||
|
||||
struct Distance : public Equation<Distance, mpl::vector2<double, SolutionSpace> > {
|
||||
|
||||
using Equation::operator=;
|
||||
|
@ -265,9 +320,15 @@ struct Distance : public Equation<Distance, mpl::vector2<double, SolutionSpace>
|
|||
setDefault();
|
||||
};
|
||||
|
||||
//override needed ass assignmend operator is always created by the compiler
|
||||
//and we need to ensure that our custom one is used
|
||||
Distance& operator=(const Distance& d) {
|
||||
return Equation::operator=(d);
|
||||
};
|
||||
|
||||
void setDefault() {
|
||||
fusion::at_key<double>(values) = std::make_pair(false, 0.);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, unidirectional);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
|
||||
};
|
||||
|
||||
template< typename Kernel, typename Tag1, typename Tag2 >
|
||||
|
@ -333,6 +394,12 @@ struct Orientation : public Equation<Orientation, Direction, true> {
|
|||
setDefault();
|
||||
};
|
||||
|
||||
//override needed ass assignmend operator is always created by the compiler
|
||||
//and we need to ensure that our custom one is used
|
||||
Orientation& operator=(const Orientation& d) {
|
||||
return Equation::operator=(d);
|
||||
};
|
||||
|
||||
void setDefault() {
|
||||
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
|
||||
};
|
||||
|
@ -392,9 +459,15 @@ struct Angle : public Equation<Angle, mpl::vector2<double, SolutionSpace>, true>
|
|||
setDefault();
|
||||
};
|
||||
|
||||
//override needed ass assignmend operator is always created by the compiler
|
||||
//and we need to ensure that our custom one is used
|
||||
Angle& operator=(const Angle& d) {
|
||||
return Equation::operator=(d);
|
||||
};
|
||||
|
||||
void setDefault() {
|
||||
fusion::at_key<double>(values) = std::make_pair(false, 0.);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, unidirectional);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
|
||||
};
|
||||
|
||||
template< typename Kernel, typename Tag1, typename Tag2 >
|
||||
|
@ -456,3 +529,4 @@ static Angle angle;
|
|||
|
||||
#endif //GCM_EQUATIONS_H
|
||||
|
||||
|
||||
|
|
|
@ -25,34 +25,9 @@
|
|||
|
||||
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;
|
||||
};
|
||||
struct Alignment : public constraint_sequence< fusion::vector2< Distance, Orientation > > {
|
||||
|
||||
using constraint_sequence::operator=;
|
||||
};
|
||||
|
||||
static Alignment alignment;
|
||||
|
|
|
@ -35,6 +35,10 @@ struct ci_orientation : public Equation<ci_orientation, Direction, true> {
|
|||
ci_orientation() : Equation() {
|
||||
setDefault();
|
||||
};
|
||||
|
||||
ci_orientation& operator=(const ci_orientation& d) {
|
||||
return Equation::operator=(d);
|
||||
};
|
||||
|
||||
void setDefault() {
|
||||
fusion::at_key<Direction>(values) = std::make_pair(false, parallel);
|
||||
|
@ -158,10 +162,14 @@ struct ci_distance : public Equation<ci_distance, mpl::vector2<double, SolutionS
|
|||
ci_distance() : Equation() {
|
||||
setDefault();
|
||||
};
|
||||
|
||||
ci_distance& operator=(const ci_distance& d) {
|
||||
return Equation::operator=(d);
|
||||
};
|
||||
|
||||
void setDefault() {
|
||||
fusion::at_key<double>(values) = std::make_pair(false, 0.);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, unidirectional);
|
||||
fusion::at_key<SolutionSpace>(values) = std::make_pair(false, bidirectional);
|
||||
};
|
||||
|
||||
template< typename Kernel, typename Tag1, typename Tag2 >
|
||||
|
|
|
@ -227,13 +227,13 @@ struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
|
|||
//(p1-p2)°n / |n| - distance
|
||||
result = (param1.head(3)-param2.head(3)).dot(param2.tail(3)) / param2.tail(3).norm();
|
||||
|
||||
if(sspace == unidirectional)
|
||||
if(sspace == bidirectional)
|
||||
return std::abs(result) - sc_value;
|
||||
|
||||
if(sspace==positiv_directional)
|
||||
if(sspace == positiv_directional)
|
||||
return result - sc_value;
|
||||
|
||||
if(sspace ==negative_directional)
|
||||
if(sspace == negative_directional)
|
||||
return result + sc_value;
|
||||
#ifdef USE_LOGGING
|
||||
if(!boost::math::isfinite(res))
|
||||
|
@ -257,7 +257,7 @@ struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
|
|||
//r' = 1/2(x^2)^(-1/2) * (x^2)'
|
||||
//r' = 1/sqrt(x^2) * x * x'
|
||||
//r' = sign(x)*x'
|
||||
if(sspace == unidirectional && result<0.)
|
||||
if(sspace == bidirectional && result<0.)
|
||||
return -res;
|
||||
|
||||
return res;
|
||||
|
@ -279,7 +279,7 @@ struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
|
|||
if(!boost::math::isfinite(res))
|
||||
BOOST_LOG(log) << "Unnormal second cluster gradient detected: "<<res;
|
||||
#endif
|
||||
if(sspace == unidirectional && result<0.)
|
||||
if(sspace == bidirectional && result<0.)
|
||||
return -res;
|
||||
|
||||
return res;
|
||||
|
@ -291,7 +291,7 @@ struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
|
|||
E::MatrixBase<DerivedC>& gradient) {
|
||||
gradient = param2.tail(3) / param2.tail(3).norm();
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
if(sspace == bidirectional && result<0.)
|
||||
gradient *= -1.;
|
||||
};
|
||||
|
||||
|
@ -305,7 +305,7 @@ struct Distance::type< Kernel, tag::point3D, tag::plane3D > {
|
|||
gradient.head(3) = -n / n.norm();
|
||||
gradient.tail(3) = (p1m2)/n.norm() - (p1m2).dot(n)*n/std::pow(n.norm(),3);
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
if(sspace == bidirectional && result<0.)
|
||||
gradient *= -1.;
|
||||
};
|
||||
};
|
||||
|
@ -318,6 +318,7 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
|
||||
Scalar result;
|
||||
SolutionSpace sspace;
|
||||
using Distance::template type<Kernel, tag::point3D, tag::line3D>::sc_value;
|
||||
using Distance::template type<Kernel, tag::point3D, tag::line3D>::values;
|
||||
#ifdef USE_LOGGING
|
||||
type() {
|
||||
|
@ -333,15 +334,12 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
template <typename DerivedA,typename DerivedB>
|
||||
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
|
||||
//(p1-p2)°n / |n| - distance
|
||||
result = Distance::type< Kernel, tag::point3D, tag::line3D >::calculate(param1, param2);
|
||||
result = Distance::type< Kernel, tag::point3D, tag::line3D >::calculate(param1, param2) - param2(6);
|
||||
|
||||
if(sspace == unidirectional)
|
||||
return std::abs(result) - param2(6);
|
||||
if(sspace==negative_directional || (sspace == bidirectional && (result+sc_value)<0.))
|
||||
return result+2*sc_value;
|
||||
|
||||
if(sspace==positiv_directional)
|
||||
return result - param2(6);
|
||||
|
||||
return result + param2(6);
|
||||
return result;
|
||||
};
|
||||
|
||||
template <typename DerivedA,typename DerivedB, typename DerivedC>
|
||||
|
@ -349,12 +347,7 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
const E::MatrixBase<DerivedB>& param2,
|
||||
const E::MatrixBase<DerivedC>& dparam1) {
|
||||
|
||||
const Scalar res = Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientFirst(param1,param2,dparam1);
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
return -res;
|
||||
|
||||
return res;
|
||||
return Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientFirst(param1,param2,dparam1);
|
||||
};
|
||||
|
||||
template <typename DerivedA,typename DerivedB, typename DerivedC>
|
||||
|
@ -362,12 +355,7 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
const E::MatrixBase<DerivedB>& param2,
|
||||
const E::MatrixBase<DerivedC>& dparam2) {
|
||||
|
||||
const Scalar res = Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientSecond(param1,param2,dparam2);
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
return -res;
|
||||
|
||||
return res;
|
||||
return Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientSecond(param1,param2,dparam2) - dparam2(6);
|
||||
};
|
||||
|
||||
template <typename DerivedA,typename DerivedB, typename DerivedC>
|
||||
|
@ -375,9 +363,6 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
const E::MatrixBase<DerivedB>& param2,
|
||||
E::MatrixBase<DerivedC>& gradient) {
|
||||
Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientFirstComplete(param1,param2,gradient);
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
gradient *= -1;
|
||||
};
|
||||
|
||||
template <typename DerivedA,typename DerivedB, typename DerivedC>
|
||||
|
@ -385,13 +370,8 @@ struct Distance::type< Kernel, tag::point3D, tag::cylinder3D > : public Distance
|
|||
const E::MatrixBase<DerivedB>& p2,
|
||||
E::MatrixBase<DerivedC>& g) {
|
||||
Distance::type< Kernel, tag::point3D, tag::line3D >::calculateGradientSecondComplete(p1,p2,g);
|
||||
if(sspace == negative_directional)
|
||||
g(6) = 1;
|
||||
else
|
||||
g(6) = -1;
|
||||
g(6) = -1;
|
||||
|
||||
if(sspace == unidirectional && result<0.)
|
||||
g *= -1;
|
||||
};
|
||||
};
|
||||
//TODO: this won't work for parallel lines. switch to point-line distance when lines are parallel
|
||||
|
@ -652,6 +632,10 @@ struct Distance::type< Kernel, tag::plane3D, tag::cylinder3D > : public Distance
|
|||
Scalar calculate(const E::MatrixBase<DerivedA>& param1, const E::MatrixBase<DerivedB>& param2) {
|
||||
//(p1-p2)°n / |n| - distance
|
||||
const Scalar res = Distance::type< Kernel, tag::point3D, tag::plane3D >::calculate(param2, param1);
|
||||
|
||||
if(Distance::type< Kernel, tag::point3D, tag::plane3D >::sspace == negative_directional)
|
||||
return res + param2(6);
|
||||
|
||||
return res - param2(6);
|
||||
};
|
||||
|
||||
|
@ -683,7 +667,11 @@ struct Distance::type< Kernel, tag::plane3D, tag::cylinder3D > : public Distance
|
|||
typename Kernel::VectorMap grad(&g(0), 3, typename Kernel::DynStride(1,1));
|
||||
Distance::type< Kernel, tag::point3D, tag::plane3D >::calculateGradientFirstComplete(p2,p1,grad);
|
||||
g.segment(3,3).setZero();
|
||||
g(6) = -1;
|
||||
|
||||
if(Distance::type< Kernel, tag::point3D, tag::plane3D >::sspace == negative_directional)
|
||||
g(6) = 1;
|
||||
else
|
||||
g(6) = -1;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ TaskAssemblyConstraints::TaskAssemblyConstraints(ViewProviderConstraint* vp)
|
|||
//get the individual constraint settings
|
||||
ui->value->setValue(obj->Value.getValue());
|
||||
setOrientation(dcm::Direction(obj->Orientation.getValue()));
|
||||
setSolutionSpace(dcm::SolutionSpace(obj->SolutionSpace.getValue()));
|
||||
|
||||
int v = obj->Type.getValue();
|
||||
if(v==0)
|
||||
|
@ -139,6 +140,18 @@ TaskAssemblyConstraints::TaskAssemblyConstraints(ViewProviderConstraint* vp)
|
|||
QObject::connect(
|
||||
ui->perpendicular, SIGNAL(toggled(bool)),
|
||||
this, SLOT(on_orientation_selection(bool)));
|
||||
QObject::connect(
|
||||
ui->bidirectional, SIGNAL(toggled(bool)),
|
||||
this, SLOT(on_solutionspace_selection(bool)));
|
||||
QObject::connect(
|
||||
ui->pos_direction, SIGNAL(toggled(bool)),
|
||||
this, SLOT(on_solutionspace_selection(bool)));
|
||||
QObject::connect(
|
||||
ui->neg_direction, SIGNAL(toggled(bool)),
|
||||
this, SLOT(on_solutionspace_selection(bool)));
|
||||
QObject::connect(
|
||||
ui->perpendicular, SIGNAL(toggled(bool)),
|
||||
this, SLOT(on_orientation_selection(bool)));
|
||||
QObject::connect(
|
||||
ui->value, SIGNAL(valueChanged(double)),
|
||||
this, SLOT(on_value_change(double)));
|
||||
|
@ -180,6 +193,30 @@ void TaskAssemblyConstraints::setOrientation(dcm::Direction d)
|
|||
}
|
||||
}
|
||||
|
||||
dcm::SolutionSpace TaskAssemblyConstraints::getSolutionSpace()
|
||||
{
|
||||
if(ui->bidirectional->isChecked())
|
||||
return dcm::bidirectional;
|
||||
if(ui->pos_direction->isChecked())
|
||||
return dcm::positiv_directional;
|
||||
|
||||
return dcm::negative_directional;
|
||||
}
|
||||
|
||||
void TaskAssemblyConstraints::setSolutionSpace(dcm::SolutionSpace d)
|
||||
{
|
||||
switch(d) {
|
||||
case dcm::bidirectional:
|
||||
ui->bidirectional->setChecked(true);
|
||||
break;
|
||||
case dcm::positiv_directional:
|
||||
ui->pos_direction->setChecked(true);
|
||||
break;
|
||||
default:
|
||||
ui->neg_direction->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TaskAssemblyConstraints::~TaskAssemblyConstraints()
|
||||
{
|
||||
|
@ -216,8 +253,8 @@ void TaskAssemblyConstraints::onSelectionChanged(const Gui::SelectionChanges& ms
|
|||
if(ui->second_geom->text().isEmpty()) {
|
||||
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
|
||||
Assembly::Constraint* con = dynamic_cast<Assembly::Constraint*>(view->getObject());
|
||||
|
||||
if(!ActiveAsmObject || !ActiveAsmObject->getTypeId().isDerivedFrom(Assembly::ItemAssembly::getClassTypeId())) {
|
||||
|
||||
if(!ActiveAsmObject || !ActiveAsmObject->getTypeId().isDerivedFrom(Assembly::ItemAssembly::getClassTypeId())) {
|
||||
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("No active Assembly"),
|
||||
QObject::tr("You need a active (blue) Assembly to insert a Constraint. Please create a new one or make one active (double click)."));
|
||||
return;
|
||||
|
@ -277,6 +314,17 @@ void TaskAssemblyConstraints::on_orientation_selection(bool clicked)
|
|||
}
|
||||
}
|
||||
|
||||
void TaskAssemblyConstraints::on_solutionspace_selection(bool clicked)
|
||||
{
|
||||
if(clicked) {
|
||||
Assembly::Constraint* obj = dynamic_cast<Assembly::Constraint*>(view->getObject());
|
||||
obj->SolutionSpace.setValue(getSolutionSpace());
|
||||
|
||||
App::GetApplication().getActiveDocument()->recompute();
|
||||
view->draw();
|
||||
}
|
||||
}
|
||||
|
||||
void TaskAssemblyConstraints::on_value_change(double val)
|
||||
{
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ public Q_SLOTS:
|
|||
void on_constraint_selection(bool clicked);
|
||||
void on_value_change(double val);
|
||||
void on_orientation_selection(bool clicked);
|
||||
void on_solutionspace_selection(bool clicked);
|
||||
void on_clear_first();
|
||||
void on_clear_second();
|
||||
|
||||
|
@ -63,6 +64,8 @@ private:
|
|||
|
||||
void setOrientation(dcm::Direction);
|
||||
dcm::Direction getOrientation();
|
||||
void setSolutionSpace(dcm::SolutionSpace d);
|
||||
dcm::SolutionSpace getSolutionSpace();
|
||||
void setPossibleConstraints();
|
||||
bool isCombination(boost::shared_ptr<Geometry3D> g1, boost::shared_ptr<Geometry3D> g2, dcm::geometry::types t1, dcm::geometry::types t2);
|
||||
};
|
||||
|
|
|
@ -402,7 +402,7 @@
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="two_directional">
|
||||
<widget class="QToolButton" name="bidirectional">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
|
|
Loading…
Reference in New Issue
Block a user