fix unsupported geometry crashs, add visual feedback for unsupported geometry and fix crash on both parts in subassemblys
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user