fix unsupported geometry crashs, add visual feedback for unsupported geometry and fix crash on both parts in subassemblys

This commit is contained in:
Stefan Tröger
2013-12-22 10:40:03 +01:00
parent 61a47d7c22
commit 66f9afbef3
8 changed files with 549 additions and 456 deletions

View File

@@ -63,6 +63,11 @@ struct ConstraintInitException : std::exception {
return "Constraint cout not be initialised: unsoported geometry";
}
};
struct ConstraintPartException : std::exception {
const char* what() const throw() {
return "Constraint cout not be initialised: parts are invalid";
}
};
struct ConstraintLinkException : std::exception {
const char* what() const throw() {
return "Constraint cout not be initialised: unsoported link type";
@@ -96,7 +101,7 @@ 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");
@@ -131,6 +136,7 @@ boost::shared_ptr<Geometry3D> Constraint::initLink(App::PropertyLinkSub& link) {
};
Assembly::ItemPart* part = static_cast<Assembly::ItemPart*>(link.getValue());
if(!part)
return boost::shared_ptr<Geometry3D>();
@@ -159,52 +165,58 @@ void Constraint::init(Assembly::ItemAssembly* ass)
if(Type.getValue() == 0) {
if(part1)
part1->m_part->fix(true);
else if(part2)
part2->m_part->fix(true);
else
if(part2)
part2->m_part->fix(true);
throw ConstraintPartException();
};
//all other constraints need poth parts
if(!part1 || !part2) {
Base::Console().Message("Geometry initialisation error: invalid parts\n");
return;
throw ConstraintPartException();
};
//and both geometries
if(!m_first_geom || !m_second_geom) {
Base::Console().Message("Geometry initialisation error: invalid geometries\n");
return;
throw ConstraintInitException();
};
//we may need the orientation
dcm::Direction dir;
switch(Orientation.getValue()) {
case 0:
dir = dcm::parallel;
break;
case 1:
dir = dcm::equal;
break;
case 2:
dir = dcm::opposite;
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()) = sspace);
@@ -232,6 +244,7 @@ PyObject* Constraint::getPyObject(void)
// ref counter is set to 1
PythonObject = Py::Object(new ConstraintPy(this),true);
}
return Py::new_reference_to(PythonObject);
}

View File

@@ -70,14 +70,15 @@ App::DocumentObjectExecReturn* ItemAssembly::execute(void) {
m_downstream_placement = Base::Placement(Base::Vector3<double>(0,0,0), Base::Rotation());
Base::Placement dummy;
initSolver(boost::shared_ptr<Solver>(), dummy, false);
#ifdef ASSEMBLY_DEBUG_FACILITIES
if(ApplyAtFailure.getValue())
m_solver->setOption<dcm::solverfailure>(dcm::ApplyResults);
else
m_solver->setOption<dcm::solverfailure>(dcm::IgnoreResults);
m_solver->setOption<dcm::precision>(Precision.getValue());
if(ApplyAtFailure.getValue())
m_solver->setOption<dcm::solverfailure>(dcm::ApplyResults);
else
m_solver->setOption<dcm::solverfailure>(dcm::IgnoreResults);
m_solver->setOption<dcm::precision>(Precision.getValue());
#endif
initConstraints(boost::shared_ptr<Solver>());
@@ -198,7 +199,7 @@ ItemAssembly* ItemAssembly::getParentAssembly(ItemPart* part) {
std::pair<ItemPart*, ItemAssembly*> ItemAssembly::getContainingPart(App::DocumentObject* obj) {
std::pair<ItemPart*, ItemAssembly*> ItemAssembly::getContainingPart(App::DocumentObject* obj, bool isTop) {
typedef std::vector<App::DocumentObject*>::const_iterator iter;
@@ -212,10 +213,15 @@ std::pair<ItemPart*, ItemAssembly*> ItemAssembly::getContainingPart(App::Documen
}
else if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) {
std::pair<ItemPart*, ItemAssembly*> part = static_cast<Assembly::ItemAssembly*>(*it)->getContainingPart(obj);
std::pair<ItemPart*, ItemAssembly*> part = static_cast<Assembly::ItemAssembly*>(*it)->getContainingPart(obj, false);
if(part.first && part.second)
return part;
if(part.first && part.second) {
if(isTop)
return part;
else
return std::make_pair(part.first, this);
}
}
};
@@ -242,6 +248,7 @@ void ItemAssembly::initSolver(boost::shared_ptr<Solver> parent, Base::Placement&
typedef std::vector<App::DocumentObject*>::const_iterator iter;
const std::vector<App::DocumentObject*>& vector = Items.getValues();
for(iter it=vector.begin(); it != vector.end(); it++) {
if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) {

View File

@@ -62,7 +62,11 @@ public:
bool isParentAssembly(ItemPart* part);
ItemAssembly* getParentAssembly(ItemPart* part);
std::pair< ItemPart*, ItemAssembly* > getContainingPart(App::DocumentObject* obj);
//returns the ItemPart which holds the given document object and the ItemAssembly, which holds
//the this part and is a direct children of this ItemAssembly. The returned ItemAssembly is therefore
//the "TopLevel" Assembly holding the part of all children of this assembly. If this assembly holds
//the children directly, without any subassembly, the returned ItemAssembly is this.
std::pair< ItemPart*, ItemAssembly* > getContainingPart(App::DocumentObject* obj, bool isTop=true);
//create a new solver for this assembly and initalise all downstream itemassemblys either with a
//subsystem (if they are rigid) or with this solver plus the downstream placement

View File

@@ -188,7 +188,7 @@ int Dogleg<Kernel>::solve(typename Kernel::MappedEquationSystem& sys, Functor& r
unused=0;
counter=0;
int maxIterNumber = 5000;//MaxIterations * xsize;
int maxIterNumber = 10000;//MaxIterations * xsize;
number_type diverging_lim = 1e6*err + 1e12;
do {
@@ -219,11 +219,11 @@ int Dogleg<Kernel>::solve(typename Kernel::MappedEquationSystem& sys, Functor& r
//get the update step
calculateStep(g, sys.Jacobi, sys.Residual, h_dl, delta);
#ifdef USE_LOGGING
BOOST_LOG(log)<< "Step in iter "<<iter<<std::endl
<< "Step: "<<h_dl.transpose()<<std::endl
<< "Jacobi: "<<sys.Jacobi<<std::endl;
#endif
// #ifdef USE_LOGGING
// BOOST_LOG(log)<< "Step in iter "<<iter<<std::endl
// << "Step: "<<h_dl.transpose()<<std::endl
// << "Jacobi: "<<sys.Jacobi<<std::endl;
// #endif
// calculate the linear model
dL = sys.Residual.norm() - (sys.Residual + sys.Jacobi*h_dl).norm();
@@ -262,10 +262,10 @@ int Dogleg<Kernel>::solve(typename Kernel::MappedEquationSystem& sys, Functor& r
nu = 2*nu;
}
#ifdef USE_LOGGING
BOOST_LOG(log)<<"Result of step dF: "<<dF<<", dL: "<<dL<<std::endl
<< "New Residual: "<< sys.Residual.transpose()<<std::endl;
#endif
// #ifdef USE_LOGGING
// BOOST_LOG(log)<<"Result of step dF: "<<dF<<", dL: "<<dL<<std::endl
// << "New Residual: "<< sys.Residual.transpose()<<std::endl;
// #endif
if(dF > 0 && dL > 0) {

View File

@@ -355,7 +355,7 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
bool done = false;
if(!has_cycle) {
//if(!has_cycle) {
#ifdef USE_LOGGING
BOOST_LOG(log)<< "non-cyclic system dedected: solve rotation only";
#endif
@@ -392,7 +392,7 @@ void SystemSolver<Sys>::solveCluster(boost::shared_ptr<Cluster> cluster, Sys& sy
done = false;
}
}
};
//};
//not done already? try it the hard way!
if(!done) {