diff --git a/src/Mod/Assembly/App/Constraint.cpp b/src/Mod/Assembly/App/Constraint.cpp index ad8f3cb86f..5727e99009 100644 --- a/src/Mod/Assembly/App/Constraint.cpp +++ b/src/Mod/Assembly/App/Constraint.cpp @@ -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 vec3; vec3.push_back("Bidirectional"); vec3.push_back("Positiv directional"); @@ -131,6 +136,7 @@ boost::shared_ptr Constraint::initLink(App::PropertyLinkSub& link) { }; Assembly::ItemPart* part = static_cast(link.getValue()); + if(!part) return boost::shared_ptr(); @@ -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); } diff --git a/src/Mod/Assembly/App/ItemAssembly.cpp b/src/Mod/Assembly/App/ItemAssembly.cpp index a0f1306aa1..86cf7d24cf 100644 --- a/src/Mod/Assembly/App/ItemAssembly.cpp +++ b/src/Mod/Assembly/App/ItemAssembly.cpp @@ -70,14 +70,15 @@ App::DocumentObjectExecReturn* ItemAssembly::execute(void) { m_downstream_placement = Base::Placement(Base::Vector3(0,0,0), Base::Rotation()); Base::Placement dummy; initSolver(boost::shared_ptr(), dummy, false); - + #ifdef ASSEMBLY_DEBUG_FACILITIES - if(ApplyAtFailure.getValue()) - m_solver->setOption(dcm::ApplyResults); - else - m_solver->setOption(dcm::IgnoreResults); - - m_solver->setOption(Precision.getValue()); + + if(ApplyAtFailure.getValue()) + m_solver->setOption(dcm::ApplyResults); + else + m_solver->setOption(dcm::IgnoreResults); + + m_solver->setOption(Precision.getValue()); #endif initConstraints(boost::shared_ptr()); @@ -198,7 +199,7 @@ ItemAssembly* ItemAssembly::getParentAssembly(ItemPart* part) { -std::pair ItemAssembly::getContainingPart(App::DocumentObject* obj) { +std::pair ItemAssembly::getContainingPart(App::DocumentObject* obj, bool isTop) { typedef std::vector::const_iterator iter; @@ -212,10 +213,15 @@ std::pair ItemAssembly::getContainingPart(App::Documen } else if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { - std::pair part = static_cast(*it)->getContainingPart(obj); + std::pair part = static_cast(*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 parent, Base::Placement& typedef std::vector::const_iterator iter; const std::vector& vector = Items.getValues(); + for(iter it=vector.begin(); it != vector.end(); it++) { if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { diff --git a/src/Mod/Assembly/App/ItemAssembly.h b/src/Mod/Assembly/App/ItemAssembly.h index 653a264ff8..fb08ef2630 100644 --- a/src/Mod/Assembly/App/ItemAssembly.h +++ b/src/Mod/Assembly/App/ItemAssembly.h @@ -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 diff --git a/src/Mod/Assembly/App/opendcm/core/imp/kernel_imp.hpp b/src/Mod/Assembly/App/opendcm/core/imp/kernel_imp.hpp index 1bddcede15..9e9f8085d9 100644 --- a/src/Mod/Assembly/App/opendcm/core/imp/kernel_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/core/imp/kernel_imp.hpp @@ -188,7 +188,7 @@ int Dogleg::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::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 "<::solve(typename Kernel::MappedEquationSystem& sys, Functor& r nu = 2*nu; } -#ifdef USE_LOGGING - BOOST_LOG(log)<<"Result of step dF: "< 0 && dL > 0) { diff --git a/src/Mod/Assembly/App/opendcm/module3d/imp/solver_imp.hpp b/src/Mod/Assembly/App/opendcm/module3d/imp/solver_imp.hpp index ab4036c06e..b4b843c43d 100644 --- a/src/Mod/Assembly/App/opendcm/module3d/imp/solver_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/module3d/imp/solver_imp.hpp @@ -355,7 +355,7 @@ void SystemSolver::solveCluster(boost::shared_ptr 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::solveCluster(boost::shared_ptr cluster, Sys& sy done = false; } } - }; + //}; //not done already? try it the hard way! if(!done) { diff --git a/src/Mod/Assembly/Gui/CommandConstraints.cpp b/src/Mod/Assembly/Gui/CommandConstraints.cpp index cba2be8745..852d262267 100644 --- a/src/Mod/Assembly/Gui/CommandConstraints.cpp +++ b/src/Mod/Assembly/Gui/CommandConstraints.cpp @@ -168,7 +168,7 @@ void CmdAssemblyConstraint::activated(int iMsg) //check if this is the right place for the constraint if(part1.first && part2.first && (part1.second == part2.second) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } @@ -238,7 +238,7 @@ void CmdAssemblyConstraintDistance::activated(int iMsg) //check if this is the right place for the constraint if((part1.second == part2.second) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } @@ -370,7 +370,7 @@ void CmdAssemblyConstraintAngle::activated(int iMsg) //check if this is the right place for the constraint if(((part1.second == part2.second) && part1.second != Asm) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } @@ -439,7 +439,7 @@ void CmdAssemblyConstraintOrientation::activated(int iMsg) //check if this is the right place for the constraint if((part1.second == part2.second) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } @@ -507,7 +507,7 @@ void CmdAssemblyConstraintCoincidence::activated(int iMsg) //check if this is the right place for the constraint if((part1.second == part2.second) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } @@ -575,7 +575,7 @@ void CmdAssemblyConstraintAlignment::activated(int iMsg) //check if this is the right place for the constraint if((part1.second == part2.second) && part1.second != Asm) { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"), - QObject::tr("The selected parts belong both to the same subproduct, please add constraints there")); + QObject::tr("The selected parts belong both to the same subassembly, please add constraints there")); return; } diff --git a/src/Mod/Assembly/Gui/TaskAssemblyConstraints.cpp b/src/Mod/Assembly/Gui/TaskAssemblyConstraints.cpp index e02feb512b..001dc5afd0 100644 --- a/src/Mod/Assembly/Gui/TaskAssemblyConstraints.cpp +++ b/src/Mod/Assembly/Gui/TaskAssemblyConstraints.cpp @@ -65,16 +65,19 @@ TaskAssemblyConstraints::TaskAssemblyConstraints(ViewProviderConstraint* vp) //set all basic values Assembly::ItemAssembly* ass = NULL; Assembly::Constraint* obj = dynamic_cast(vp->getObject()); + if(obj->First.getValue()) { QString str; str = QString::fromAscii(obj->First.getValue()->getNameInDocument()) + QString::fromAscii(".") + QString::fromStdString(obj->First.getSubValues().front()); ui->first_geom->setText(str); ass = dynamic_cast(obj->First.getValue())->getParentAssembly(); }; + if(obj->Second.getValue()) { QString str; str = QString::fromAscii(obj->Second.getValue()->getNameInDocument()) + QString::fromAscii(".") + QString::fromStdString(obj->Second.getSubValues().front()); ui->second_geom->setText(str); + if(!ass) ass = dynamic_cast(obj->Second.getValue())->getParentAssembly(); }; @@ -88,6 +91,7 @@ TaskAssemblyConstraints::TaskAssemblyConstraints(ViewProviderConstraint* vp) setSolutionSpace(dcm::SolutionSpace(obj->SolutionSpace.getValue())); int v = obj->Type.getValue(); + if(v==0) ui->fix->setChecked(true); @@ -169,8 +173,10 @@ dcm::Direction TaskAssemblyConstraints::getOrientation() { if(ui->parallel->isChecked()) return dcm::parallel; + if(ui->equal->isChecked()) return dcm::equal; + if(ui->opposite->isChecked()) return dcm::opposite; @@ -183,12 +189,15 @@ void TaskAssemblyConstraints::setOrientation(dcm::Direction d) case dcm::perpendicular: ui->perpendicular->setChecked(true); break; + case dcm::equal: ui->equal->setChecked(true); break; + case dcm::opposite: ui->opposite->setChecked(true); break; + default : ui->parallel->setChecked(true); @@ -199,6 +208,7 @@ dcm::SolutionSpace TaskAssemblyConstraints::getSolutionSpace() { if(ui->bidirectional->isChecked()) return dcm::bidirectional; + if(ui->pos_direction->isChecked()) return dcm::positiv_directional; @@ -211,9 +221,11 @@ void TaskAssemblyConstraints::setSolutionSpace(dcm::SolutionSpace 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); @@ -305,6 +317,7 @@ void TaskAssemblyConstraints::on_constraint_selection(bool clicked) App::GetApplication().getActiveDocument()->recompute(); view->draw(); } + setPossibleOptions(); } @@ -377,9 +390,11 @@ void TaskAssemblyConstraints::setPossibleOptions() { //this only works if both objects are set Assembly::Constraint* obj = dynamic_cast(view->getObject()); + if(obj->First.getValue()) { Assembly::ItemPart* p1 = dynamic_cast(obj->First.getValue()); + if(!p1) return; @@ -387,13 +402,22 @@ void TaskAssemblyConstraints::setPossibleOptions() { //extract the geometries to use for comparison boost::shared_ptr g1 = ass->m_solver->getGeometry3D(obj->First.getSubValues()[0].c_str()); + + if(!g1) + return; + if(obj->Second.getValue()) { Assembly::ItemPart* p2 = dynamic_cast(obj->Second.getValue()); + if(!p2) return; + boost::shared_ptr g2 = ass->m_solver->getGeometry3D(obj->Second.getSubValues()[0].c_str()); + if(!g2) + return; + //distance if(obj->Type.getValue() == 1) { @@ -404,6 +428,7 @@ void TaskAssemblyConstraints::setPossibleOptions() { ui->neg_direction->setEnabled(true); }; }; + //align & coincident if(obj->Type.getValue() == 4 || obj->Type.getValue() == 5) { @@ -468,6 +493,7 @@ void TaskAssemblyConstraints::setPossibleConstraints() ui->coincident->setEnabled(false); Assembly::Constraint* obj = dynamic_cast(view->getObject()); + if(obj->First.getValue()) { Assembly::ItemPart* p1 = dynamic_cast(obj->First.getValue()); @@ -479,30 +505,63 @@ void TaskAssemblyConstraints::setPossibleConstraints() //extract the geometries to use for comparison boost::shared_ptr g1 = ass->m_solver->getGeometry3D(obj->First.getSubValues()[0].c_str()); + + //let's see if we have a part, if not give feedback to the user by color + if(!g1) { + QPalette palette = ui->widget->palette(); + palette.setColor(ui->first_geom->backgroundRole(), QColor(255, 0, 0, 127)); + ui->first_geom->setPalette(palette); + } + else { + //set normal color as we ma need to revert the red background + ui->first_geom->setPalette(ui->widget->palette()); + } + if(obj->Second.getValue()) { + Assembly::ItemPart* p2 = dynamic_cast(obj->Second.getValue()); + if(!p2) return; boost::shared_ptr g2 = ass->m_solver->getGeometry3D(obj->Second.getSubValues()[0].c_str()); + //let's see if we have a part, if not give feedback to the user by color + if(!g2) { + QPalette palette = ui->widget->palette(); + palette.setColor(ui->second_geom->backgroundRole(), QColor(255, 0, 0, 127)); + ui->second_geom->setPalette(palette); + } + else { + //set normal color as we ma need to revert the red background + ui->second_geom->setPalette(ui->widget->palette()); + } + + //return only here to allow coloring both line edits red if needed + if(!g1 || !g2) + return; + //check all valid combinaions if(isCombination(g1,g2, dcm::geometry::point, dcm::geometry::point)) { ui->distance->setEnabled(true); ui->coincident->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::point, dcm::geometry::line)) { ui->distance->setEnabled(true); ui->coincident->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::point, dcm::geometry::plane)) { ui->distance->setEnabled(true); ui->coincident->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::point, dcm::geometry::cylinder)) { ui->distance->setEnabled(true); ui->coincident->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::line, dcm::geometry::line)) { ui->distance->setEnabled(true); ui->orientation->setEnabled(true); @@ -510,12 +569,14 @@ void TaskAssemblyConstraints::setPossibleConstraints() ui->coincident->setEnabled(true); ui->align->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::line, dcm::geometry::plane)) { ui->orientation->setEnabled(true); ui->angle->setEnabled(true); ui->coincident->setEnabled(true); ui->align->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::line, dcm::geometry::cylinder)) { ui->distance->setEnabled(true); ui->orientation->setEnabled(true); @@ -523,17 +584,20 @@ void TaskAssemblyConstraints::setPossibleConstraints() ui->coincident->setEnabled(true); ui->align->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::plane, dcm::geometry::plane)) { ui->orientation->setEnabled(true); ui->angle->setEnabled(true); ui->coincident->setEnabled(true); ui->align->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::plane, dcm::geometry::cylinder)) { ui->orientation->setEnabled(true); ui->angle->setEnabled(true); ui->align->setEnabled(true); }; + if(isCombination(g1,g2, dcm::geometry::cylinder, dcm::geometry::cylinder)) { ui->coincident->setEnabled(true); ui->orientation->setEnabled(true); @@ -541,6 +605,10 @@ void TaskAssemblyConstraints::setPossibleConstraints() }; } else { + //return here to allow check for second geometry and color both red if needed + if(!g1) + return; + //only fix works ui->fix->setEnabled(true); }; diff --git a/src/Mod/Assembly/Gui/TaskAssemblyConstraints.ui b/src/Mod/Assembly/Gui/TaskAssemblyConstraints.ui index 053cfa7b61..e2ecf434d6 100644 --- a/src/Mod/Assembly/Gui/TaskAssemblyConstraints.ui +++ b/src/Mod/Assembly/Gui/TaskAssemblyConstraints.ui @@ -6,7 +6,7 @@ 0 0 - 297 + 303 541 @@ -38,8 +38,8 @@ ... - - :/icons/delete.png:/icons/delete.png + + :/icons/delete.svg:/icons/delete.svg true @@ -72,8 +72,8 @@ ... - - :/icons/delete.png:/icons/delete.png + + :/icons/delete.svg:/icons/delete.svg true @@ -99,257 +99,256 @@ - - - QLayout::SetNoConstraint - - - - - - 0 - 0 - - - - <html><head/><body><p>Setthe distance between first and second geometrie. Note that in many cases the shortes distance is used (e.g. line - line)</p></body></html> - - - Distance - - - - :/icons/Assembly_ConstraintDistance.svg:/icons/Assembly_ConstraintDistance.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Special constraint which is in general used to let the geometries be on each other. Therefore it's often the same as align, with the difference that it is also defined for points, as a point can lie on a plane. Note that this constraint has a special behaviour for cylinders. For example, a cylindrical surface can't be on a plane, only touch it. Therefore this is not valid. Furthermore point and line coincident with cylinders don't work on the cylinder surface, but on its center line. The reason for that it is, that this centerline would not be accessible with other constraints, but the surface coincident can be also achieved with the align constraint and value 0. At last specialty the cylinder cylinder constraint shall be mentioned: It works also on the cylinder centerlines and therefore makes them concentric. </p></body></html> - - - Coincident - - - - :/icons/Assembly_ConstraintCoincidence.svg:/icons/Assembly_ConstraintCoincidence.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Fixes the first geometry in its rotation and translation. Note that fix only works its the direct parrent assembly. If you stack assemblys, the parent assembly will not be fixed inside the other ones.</p></body></html> - - - Fix - - - - :/icons/Assembly_ConstraintLock.svg:/icons/Assembly_ConstraintLock.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Allows to set the orientation of the geometries normals in relation to each other. Possible values are parallel (means equal or opposite normals), equal normals, opposite normals or perpendicular ones. Note that for cylinders the base circles normal is used.</p></body></html> - - - Orientation - - - - :/icons/Assembly_ConstraintOrientation.svg:/icons/Assembly_ConstraintOrientation.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Adds a orientation and a distance constraint. Therefore this constraint is only valid where both of the individual constraints are, e.g. you can't align a point and a plane as point-plane orientation is invalid. Furthermore it can happen that this constraint is only valid for a certain orientation, e.g. plane - line has only a defined distance, when the orientation is perpendicular. The reason behind this is, that a non-perpendicular line would always cut the plane and therefore the shortest distance would always be 0. </p></body></html> - - - Align - - - - :/icons/Assembly_ConstraintAlignment.svg:/icons/Assembly_ConstraintAlignment.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - - - - - 0 - 0 - - - - <html><head/><body><p>Set the angle between the geometries normals</p></body></html> - - - Angle - - - - :/icons/Assembly_ConstraintAngle.svg:/icons/Assembly_ConstraintAngle.svg - - - - 20 - 20 - - - - true - - - false - - - true - - - Qt::ToolButtonTextBesideIcon - - - true - - - - + + + + + + + 0 + 0 + + + + <html><head/><body><p>Set the angle between the geometries normals</p></body></html> + + + Angle + + + + :/icons/Assembly_ConstraintAngle.svg:/icons/Assembly_ConstraintAngle.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Special constraint which is in general used to let the geometries be on each other. Therefore it's often the same as align, with the difference that it is also defined for points, as a point can lie on a plane. Note that this constraint has a special behaviour for cylinders. For example, a cylindrical surface can't be on a plane, only touch it. Therefore this is not valid. Furthermore point and line coincident with cylinders don't work on the cylinder surface, but on its center line. The reason for that it is, that this centerline would not be accessible with other constraints, but the surface coincident can be also achieved with the align constraint and value 0. At last specialty the cylinder cylinder constraint shall be mentioned: It works also on the cylinder centerlines and therefore makes them concentric. </p></body></html> + + + Coincident + + + + :/icons/Assembly_ConstraintCoincidence.svg:/icons/Assembly_ConstraintCoincidence.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Fixes the first geometry in its rotation and translation. Note that fix only works its the direct parrent assembly. If you stack assemblys, the parent assembly will not be fixed inside the other ones.</p></body></html> + + + Fix + + + + :/icons/Assembly_ConstraintLock.svg:/icons/Assembly_ConstraintLock.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Setthe distance between first and second geometrie. Note that in many cases the shortes distance is used (e.g. line - line)</p></body></html> + + + Distance + + + + :/icons/Assembly_ConstraintDistance.svg:/icons/Assembly_ConstraintDistance.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Allows to set the orientation of the geometries normals in relation to each other. Possible values are parallel (means equal or opposite normals), equal normals, opposite normals or perpendicular ones. Note that for cylinders the base circles normal is used.</p></body></html> + + + Orientation + + + + :/icons/Assembly_ConstraintOrientation.svg:/icons/Assembly_ConstraintOrientation.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Adds a orientation and a distance constraint. Therefore this constraint is only valid where both of the individual constraints are, e.g. you can't align a point and a plane as point-plane orientation is invalid. Furthermore it can happen that this constraint is only valid for a certain orientation, e.g. plane - line has only a defined distance, when the orientation is perpendicular. The reason behind this is, that a non-perpendicular line would always cut the plane and therefore the shortest distance would always be 0. </p></body></html> + + + Align + + + + :/icons/Assembly_ConstraintAlignment.svg:/icons/Assembly_ConstraintAlignment.svg + + + + 20 + 20 + + + + true + + + false + + + true + + + Qt::ToolButtonTextBesideIcon + + + true + + + + + @@ -728,7 +727,9 @@ - + + + distance @@ -746,6 +747,54 @@ + + align + toggled(bool) + orientation_widget + setVisible(bool) + + + 170 + 126 + + + 172 + 246 + + + + + angle + toggled(bool) + orientation_widget + setHidden(bool) + + + 58 + 126 + + + 172 + 246 + + + + + angle + toggled(bool) + value_widget + setVisible(bool) + + + 58 + 126 + + + 172 + 209 + + + distance toggled(bool) @@ -762,6 +811,38 @@ + + fix + toggled(bool) + orientation_widget + setHidden(bool) + + + 58 + 94 + + + 209 + 247 + + + + + orientation + toggled(bool) + orientation_widget + setVisible(bool) + + + 284 + 94 + + + 209 + 247 + + + fix toggled(bool) @@ -778,22 +859,6 @@ - - fix - toggled(bool) - orientation_widget - setHidden(bool) - - - 58 - 94 - - - 209 - 247 - - - orientation toggled(bool) @@ -810,54 +875,6 @@ - - orientation - toggled(bool) - orientation_widget - setVisible(bool) - - - 284 - 94 - - - 209 - 247 - - - - - angle - toggled(bool) - value_widget - setVisible(bool) - - - 58 - 126 - - - 172 - 209 - - - - - angle - toggled(bool) - orientation_widget - setHidden(bool) - - - 58 - 126 - - - 172 - 246 - - - align toggled(bool) @@ -874,22 +891,6 @@ - - align - toggled(bool) - orientation_widget - setVisible(bool) - - - 170 - 126 - - - 172 - 246 - - - coincident toggled(bool) @@ -906,6 +907,86 @@ + + align + toggled(bool) + value + selectAll() + + + 170 + 126 + + + 147 + 203 + + + + + align + toggled(bool) + value + setFocus() + + + 170 + 126 + + + 147 + 203 + + + + + angle + toggled(bool) + value + setFocus() + + + 58 + 126 + + + 147 + 203 + + + + + angle + toggled(bool) + value + selectAll() + + + 58 + 126 + + + 147 + 203 + + + + + distance + toggled(bool) + value + setFocus() + + + 170 + 94 + + + 147 + 203 + + + coincident toggled(bool) @@ -922,22 +1003,6 @@ - - distance - toggled(bool) - value - setFocus() - - - 170 - 94 - - - 147 - 203 - - - distance toggled(bool) @@ -954,69 +1019,5 @@ - - angle - toggled(bool) - value - setFocus() - - - 58 - 126 - - - 147 - 203 - - - - - angle - toggled(bool) - value - selectAll() - - - 58 - 126 - - - 147 - 203 - - - - - align - toggled(bool) - value - setFocus() - - - 170 - 126 - - - 147 - 203 - - - - - align - toggled(bool) - value - selectAll() - - - 170 - 126 - - - 147 - 203 - - -