make subproduct solving work

This commit is contained in:
Stefan Tröger 2013-08-04 08:51:38 +00:00
parent 26cd6de30f
commit 98d81ed483
7 changed files with 366 additions and 163 deletions

View File

@ -73,6 +73,11 @@ App::DocumentObjectExecReturn* ItemAssembly::execute(void) {
//solve the system
m_solver->solve();
//Parts have updated automaticly, however, currently there are no signals
//for subsystems. We have to retrieve the product placements therefore by hand
finish(boost::shared_ptr<Solver>());
} catch(dcm::solving_error& e) {
Base::Console().Error("Solver failed with error %i: %s",
*boost::get_error_info<boost::errinfo_errno>(e),
@ -163,7 +168,7 @@ ItemAssembly* ItemAssembly::getParentAssembly(ItemPart* part) {
ItemPart* ItemAssembly::getContainingPart(App::DocumentObject* obj) {
std::pair<ItemPart*, ItemAssembly*> ItemAssembly::getContainingPart(App::DocumentObject* obj) {
typedef std::vector<App::DocumentObject*>::const_iterator iter;
@ -172,22 +177,24 @@ ItemPart* ItemAssembly::getContainingPart(App::DocumentObject* obj) {
if((*it)->getTypeId() == Assembly::ItemPart::getClassTypeId()) {
if(static_cast<Assembly::ItemPart*>(*it)->holdsObject(obj))
return static_cast<Assembly::ItemPart*>(*it);
return std::make_pair(static_cast<Assembly::ItemPart*>(*it), this);
} else if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) {
Assembly::ItemPart* part = static_cast<Assembly::ItemAssembly*>(*it)->getContainingPart(obj);
if(part)
std::pair<ItemPart*, ItemAssembly*> part = static_cast<Assembly::ItemAssembly*>(*it)->getContainingPart(obj);
if(part.first && part.second)
return part;
}
};
return NULL;
return std::pair<ItemPart*, ItemAssembly*>(NULL, NULL);
}
void ItemAssembly::init(boost::shared_ptr<Solver> parent) {
if(parent)
if(parent) {
m_solver = boost::shared_ptr<Solver>(parent->createSubsystem());
m_solver->setTransformation(this->Placement.getValue());
}
typedef std::vector<App::DocumentObject*>::const_iterator iter;
@ -201,5 +208,27 @@ void ItemAssembly::init(boost::shared_ptr<Solver> parent) {
};
}
//no signals for subsystems, we need to extract the placement by hand
void ItemAssembly::finish(boost::shared_ptr<Solver> parent) {
Base::Console().Message("finish\n");
if(parent) {
Base::Console().Message("set product placement\n");
Base::Placement p = m_solver->getTransformation<Base::Placement>();
this->Placement.setValue(p);
}
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()) {
static_cast<Assembly::ItemAssembly*>(*it)->finish(m_solver);
}
};
}
}

View File

@ -60,8 +60,9 @@ public:
bool isParentAssembly(ItemPart* part);
ItemAssembly* getParentAssembly(ItemPart* part);
ItemPart* getContainingPart(App::DocumentObject* obj);
std::pair< ItemPart*, ItemAssembly* > getContainingPart(App::DocumentObject* obj);
void init(boost::shared_ptr<Solver> parent);
void finish(boost::shared_ptr<Solver> parent);
boost::shared_ptr<Solver> m_solver;
};

View File

@ -418,7 +418,7 @@ std::vector<typename ClusterMath<Sys>::Geom>& ClusterMath<Sys>::getGeometry() {
template<typename Sys>
ClusterMath<Sys>::map_downstream::map_downstream(details::ClusterMath<Sys>& cm, bool fix)
: m_clusterMath(cm), m_isFixed(fix) {
m_transform = m_clusterMath.getTransform();
m_transform = m_clusterMath.getTransform().inverse();
};
template<typename Sys>
@ -431,13 +431,12 @@ void ClusterMath<Sys>::map_downstream::operator()(Geom g) {
//position and offset of the parameters must be set to the clusters values
g->setClusterMode(true, m_isFixed);
//calculate the appropriate local values
typename Kernel::Transform3D trans = m_transform.inverse();
g->transform(trans);
g->transform(m_transform);
};
template<typename Sys>
void ClusterMath<Sys>::map_downstream::operator()(boost::shared_ptr<Cluster> c) {
m_transform *= c->template getClusterProperty<math_prop>().getTransform();
m_transform *= c->template getClusterProperty<math_prop>().getTransform().inverse();
};
@ -481,7 +480,7 @@ typename ClusterMath<Sys>::Scalar ClusterMath<Sys>::calculateClusterScale() {
m_points.push_back((*it)->getPoint());
//start scale calculation
if(m_points.empty()) assert(false); //TODO: Throw
if(m_points.empty()) return 1.;
else if(m_points.size() == 1) {
const typename Kernel::Vector3 p = m_points[0];
return calcOnePoint(p);

View File

@ -98,6 +98,9 @@ struct ModulePart {
}
Transform& m_transform;
};
//collect all clustergraph upstream cluster transforms
void transform_traverse(Transform& t, boost::shared_ptr<Cluster> c);
public:
using Object<Sys, Part, PartSignal >::m_system;
@ -113,6 +116,15 @@ struct ModulePart {
template<typename T>
void set(const T& geometry);
//access the parts transformation
template<typename T>
T& get();
//get the transformation from part local to overall global. In multi layer systems
//this means the successive transformation from this part to the toplevel cluster
template<typename T>
T getGlobal();
virtual boost::shared_ptr<Part> clone(Sys& newSys);
@ -276,6 +288,9 @@ ModulePart<Typelist, ID>::type<Sys>::Part_base::Part_base(const T& geometry, Sys
cluster->template setClusterProperty<typename module3d::fix_prop>(false);
//the the clustermath transform
m_cluster->template getClusterProperty<typename module3d::math_prop>().getTransform() = m_transform;
#ifdef USE_LOGGING
BOOST_LOG(log) << "Init: "<<m_transform;
#endif
@ -294,8 +309,14 @@ template<typename T>
typename ModulePart<Typelist, ID>::template type<Sys>::Part_base::Geom
ModulePart<Typelist, ID>::type<Sys>::Part_base::addGeometry3D(const T& geom, CoordinateFrame frame) {
Geom g(new Geometry3D(geom, *m_system));
if(frame == Local)
g->transform(m_transform);
if(frame == Local) {
//we need to collect all transforms up to this part!
Transform t;
transform_traverse(t, m_cluster);
g->transform(t);
}
fusion::vector<LocalVertex, GlobalVertex> res = m_cluster->addVertex();
m_cluster->template setObject<Geometry3D> (fusion::at_c<0> (res), g);
@ -305,6 +326,19 @@ ModulePart<Typelist, ID>::type<Sys>::Part_base::addGeometry3D(const T& geom, Coo
return g;
};
template<typename Typelist, typename ID>
template<typename Sys>
void ModulePart<Typelist, ID>::type<Sys>::Part_base::transform_traverse(ModulePart<Typelist, ID>::type<Sys>::Part_base::Transform& t,
boost::shared_ptr<ModulePart<Typelist, ID>::type<Sys>::Part_base::Cluster> c) {
t *= c->template getClusterProperty<typename Part_base::module3d::math_prop>().m_transform;
if(c->isRoot())
return;
transform_traverse(t, c->parent());
}
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
@ -312,6 +346,34 @@ void ModulePart<Typelist, ID>::type<Sys>::Part_base::set(const T& geometry) {
Part_base::m_geometry = geometry;
(typename geometry_traits<T>::modell()).template extract<Kernel,
typename geometry_traits<T>::accessor >(geometry, Part_base::m_transform);
//set the clustermath transform
m_cluster->template getClusterProperty<typename module3d::math_prop>().getTransform() = m_transform;
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
T& ModulePart<Typelist, ID>::type<Sys>::Part_base::get() {
return get<T>(this);
};
template<typename Typelist, typename ID>
template<typename Sys>
template<typename T>
T ModulePart<Typelist, ID>::type<Sys>::Part_base::getGlobal() {
//get the successive transform
Transform t;
transform_traverse(t, m_cluster);
//put it into the user type
T ut;
(typename geometry_traits<T>::modell()).template inject<Kernel,
typename geometry_traits<T>::accessor >(ut, t);
return ut;
};
template<typename Typelist, typename ID>
@ -564,3 +626,5 @@ void ModulePart<Typelist, ID>::type<Sys>::EvaljuateCluster::execute(Sys& sys) {

View File

@ -40,29 +40,31 @@
using namespace std;
extern Assembly::Item *ActiveAsmObject;
extern Assembly::Item* ActiveAsmObject;
// Helper methods ===========================================================
Assembly::ConstraintGroup * getConstraintGroup(Assembly::ItemAssembly *Asm)
Assembly::ConstraintGroup* getConstraintGroup(Assembly::ItemAssembly* Asm)
{
Assembly::ConstraintGroup *ConstGrp = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
std::vector<App::DocumentObject*> Ano = Asm->Annotations.getValues();
for(std::vector<App::DocumentObject*>::const_iterator it = Ano.begin();it!=Ano.end();++it){
if((*it)->getTypeId().isDerivedFrom(Assembly::ConstraintGroup::getClassTypeId() )){
for(std::vector<App::DocumentObject*>::const_iterator it = Ano.begin(); it != Ano.end(); ++it) {
if((*it)->getTypeId().isDerivedFrom(Assembly::ConstraintGroup::getClassTypeId())) {
ConstGrp = static_cast<Assembly::ConstraintGroup*>(*it);
break;
}
}
return ConstGrp;
}
bool getConstraintPrerequisits(Assembly::ItemAssembly **Asm,Assembly::ConstraintGroup **ConstGrp)
bool getConstraintPrerequisits(Assembly::ItemAssembly** Asm, Assembly::ConstraintGroup** ConstGrp)
{
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)."));
QObject::tr("You need a active (blue) Assembly to insert a Constraint. Please create a new one or make one active (double click)."));
return true;
}
@ -70,15 +72,18 @@ bool getConstraintPrerequisits(Assembly::ItemAssembly **Asm,Assembly::Constraint
// find the Constraint group of the active Assembly
*ConstGrp = getConstraintGroup(*Asm);
// if it hasen't aleardy one, create one:
if(!*ConstGrp){
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject('Assembly::ConstraintGroup','ConstraintGroup')");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().ActiveObject.Label = 'ConstraintGroup'");
Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Annotations = App.activeDocument().%s.Annotations + [App.activeDocument().ActiveObject]",(*Asm)->getNameInDocument(),(*Asm)->getNameInDocument());
if(!*ConstGrp) {
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().addObject('Assembly::ConstraintGroup','ConstraintGroup')");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().ActiveObject.Label = 'ConstraintGroup'");
Gui::Command::doCommand(Gui::Command::Doc, "App.activeDocument().%s.Annotations = App.activeDocument().%s.Annotations + [App.activeDocument().ActiveObject]", (*Asm)->getNameInDocument(), (*Asm)->getNameInDocument());
}
// find now
*ConstGrp = getConstraintGroup(*Asm);
if(!*ConstGrp)
throw Base::Exception("Could not create Assembly::ConstraintGroup in active Assembly");
@ -87,13 +92,14 @@ bool getConstraintPrerequisits(Assembly::ItemAssembly **Asm,Assembly::Constraint
}
std::string asSubLinkString(Assembly::ItemPart* part, std::string element) {
std::string buf;
std::string asSubLinkString(Assembly::ItemPart* part, std::string element)
{
std::string buf;
buf += "(App.ActiveDocument.";
buf += part->getNameInDocument();
buf += part->getNameInDocument();
buf += ",['";
buf += element;
buf += "'])";
buf += "'])";
return buf;
}
@ -102,7 +108,7 @@ std::string asSubLinkString(Assembly::ItemPart* part, std::string element) {
DEF_STD_CMD(CmdAssemblyConstraintDistance);
CmdAssemblyConstraintDistance::CmdAssemblyConstraintDistance()
:Command("Assembly_ConstraintDistance")
: Command("Assembly_ConstraintDistance")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -116,45 +122,57 @@ CmdAssemblyConstraintDistance::CmdAssemblyConstraintDistance()
void CmdAssemblyConstraintDistance::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
return;
};
Assembly::ItemPart* part1 = Asm->getContainingPart(objs[0].getObject());
Assembly::ItemPart* part2 = Asm->getContainingPart(objs[1].getObject());
if(!part1 || !part2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part1 = Asm->getContainingPart(objs[0].getObject());
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part2 = Asm->getContainingPart(objs[1].getObject());
//checking the parts is enough, both or non!
if(!part1.first || !part2.first) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
return;
};
//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"));
return;
}
bool ok;
double d = QInputDialog::getDouble(NULL, QObject::tr("Constraint value"),
QObject::tr("Distance:"), 0., -10000., 10000., 2, &ok);
QObject::tr("Distance:"), 0., -10000., 10000., 2, &ok);
if(!ok)
return;
return;
openCommand("Insert Constraint Distance");
std::string ConstrName = getUniqueObjectName("Distance");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintDistance','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2, objs[1].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Distance = %f", d);
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintDistance','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2.first, objs[1].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Distance = %f", d);
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
/******************************************************************************************/
@ -162,7 +180,7 @@ void CmdAssemblyConstraintDistance::activated(int iMsg)
DEF_STD_CMD(CmdAssemblyConstraintFix);
CmdAssemblyConstraintFix::CmdAssemblyConstraintFix()
:Command("Assembly_ConstraintFix")
: Command("Assembly_ConstraintFix")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -176,43 +194,56 @@ CmdAssemblyConstraintFix::CmdAssemblyConstraintFix()
void CmdAssemblyConstraintFix::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 1) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select one part only"));
QObject::tr("You need to select one part only"));
return;
};
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part = Asm->getContainingPart(objs[0].getObject());
if(!part.first) {
Base::Console().Message("The selected part need to belong to the active assembly\n");
return;
};
Assembly::ItemPart* part = Asm->getContainingPart(objs[0].getObject());
if(!part) {
Base::Console().Message("The selected object need to belong to the active assembly\n");
if(part.second != Asm) {
Base::Console().Message("The selected part need belongs to an subproduct, please add constraint there\n");
return;
};
}
openCommand("Insert Constraint Fix");
std::string ConstrName = getUniqueObjectName("Fix");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintFix','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintFix','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
/******************************************************************************************/
DEF_STD_CMD(CmdAssemblyConstraintAngle);
CmdAssemblyConstraintAngle::CmdAssemblyConstraintAngle()
:Command("Assembly_ConstraintAngle")
: Command("Assembly_ConstraintAngle")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -226,45 +257,57 @@ CmdAssemblyConstraintAngle::CmdAssemblyConstraintAngle()
void CmdAssemblyConstraintAngle::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
QObject::tr("You need to select two geometries on two different parts"));
return;
};
Assembly::ItemPart* part1 = Asm->getContainingPart(objs[0].getObject());
Assembly::ItemPart* part2 = Asm->getContainingPart(objs[1].getObject());
if(!part1 || !part2) {
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part1 = Asm->getContainingPart(objs[0].getObject());
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part2 = Asm->getContainingPart(objs[1].getObject());
//checking the parts is enough, both or non!
if(!part1.first || !part2.first) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
return;
};
//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"));
return;
}
bool ok;
double d = QInputDialog::getDouble(NULL, QObject::tr("Constraint value"),
QObject::tr("Angle:"), 0., 0., 360., 2, &ok);
QObject::tr("Angle:"), 0., 0., 360., 2, &ok);
if(!ok)
return;
return;
openCommand("Insert Constraint Angle");
std::string ConstrName = getUniqueObjectName("Angle");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintAngle','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2, objs[1].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Angle = %f", d);
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintAngle','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2.first, objs[1].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Angle = %f", d);
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
@ -274,7 +317,7 @@ void CmdAssemblyConstraintAngle::activated(int iMsg)
DEF_STD_CMD(CmdAssemblyConstraintOrientation);
CmdAssemblyConstraintOrientation::CmdAssemblyConstraintOrientation()
:Command("Assembly_ConstraintOrientation")
: Command("Assembly_ConstraintOrientation")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -288,48 +331,61 @@ CmdAssemblyConstraintOrientation::CmdAssemblyConstraintOrientation()
void CmdAssemblyConstraintOrientation::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
QObject::tr("You need to select two geometries on two different parts"));
return;
};
Assembly::ItemPart* part1 = Asm->getContainingPart(objs[0].getObject());
Assembly::ItemPart* part2 = Asm->getContainingPart(objs[1].getObject());
if(!part1 || !part2) {
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part1 = Asm->getContainingPart(objs[0].getObject());
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part2 = Asm->getContainingPart(objs[1].getObject());
//checking the parts is enough, both or non!
if(!part1.first || !part2.first) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
return;
};
//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"));
return;
}
QStringList items;
items << QObject::tr("Parallel") << QObject::tr("Perpendicular") << QObject::tr("Equal") << QObject::tr("Opposite");
bool ok;
QString item = QInputDialog::getItem(NULL, QObject::tr("Constraint value"),
QObject::tr("Orientation:"), items, 0, false, &ok);
if (!ok || item.isEmpty())
QObject::tr("Orientation:"), items, 0, false, &ok);
if(!ok || item.isEmpty())
return;
openCommand("Insert Constraint Orientation");
std::string ConstrName = getUniqueObjectName("Orientation");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintOrientation','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2, objs[1].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Orientation = '%s'", item.toStdString().c_str());
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintOrientation','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2.first, objs[1].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Orientation = '%s'", item.toStdString().c_str());
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
/******************************************************************************************/
@ -338,7 +394,7 @@ void CmdAssemblyConstraintOrientation::activated(int iMsg)
DEF_STD_CMD(CmdAssemblyConstraintCoincidence);
CmdAssemblyConstraintCoincidence::CmdAssemblyConstraintCoincidence()
:Command("Assembly_ConstraintCoincidence")
: Command("Assembly_ConstraintCoincidence")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -352,48 +408,61 @@ CmdAssemblyConstraintCoincidence::CmdAssemblyConstraintCoincidence()
void CmdAssemblyConstraintCoincidence::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
QObject::tr("You need to select two geometries on two different parts"));
return;
};
Assembly::ItemPart* part1 = Asm->getContainingPart(objs[0].getObject());
Assembly::ItemPart* part2 = Asm->getContainingPart(objs[1].getObject());
if(!part1 || !part2) {
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part1 = Asm->getContainingPart(objs[0].getObject());
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part2 = Asm->getContainingPart(objs[1].getObject());
//checking the parts is enough, both or non!
if(!part1.first || !part2.first) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
return;
};
//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"));
return;
}
QStringList items;
items << QObject::tr("Parallel") << QObject::tr("Equal") << QObject::tr("Opposite");
bool ok;
QString item = QInputDialog::getItem(NULL, QObject::tr("Constraint value"),
QObject::tr("Orientation:"), items, 0, false, &ok);
if (!ok || item.isEmpty())
QObject::tr("Orientation:"), items, 0, false, &ok);
if(!ok || item.isEmpty())
return;
openCommand("Insert Constraint Coincidence");
std::string ConstrName = getUniqueObjectName("Coincidence");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintCoincidence','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2, objs[1].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Orientation = '%s'", item.toStdString().c_str());
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintCoincidence','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2.first, objs[1].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Orientation = '%s'", item.toStdString().c_str());
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
/******************************************************************************************/
@ -402,7 +471,7 @@ void CmdAssemblyConstraintCoincidence::activated(int iMsg)
DEF_STD_CMD(CmdAssemblyConstraintAlignment);
CmdAssemblyConstraintAlignment::CmdAssemblyConstraintAlignment()
:Command("Assembly_ConstraintAlignment")
: Command("Assembly_ConstraintAlignment")
{
sAppModule = "Assembly";
sGroup = QT_TR_NOOP("Assembly");
@ -416,55 +485,70 @@ CmdAssemblyConstraintAlignment::CmdAssemblyConstraintAlignment()
void CmdAssemblyConstraintAlignment::activated(int iMsg)
{
Assembly::ItemAssembly *Asm=0;
Assembly::ConstraintGroup *ConstGrp=0;
Assembly::ItemAssembly* Asm = 0;
Assembly::ConstraintGroup* ConstGrp = 0;
// retrive the standard objects needed
if(getConstraintPrerequisits(&Asm,&ConstGrp))
if(getConstraintPrerequisits(&Asm, &ConstGrp))
return;
std::vector<Gui::SelectionObject> objs = Gui::Selection().getSelectionEx();
if(objs.size() != 2) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("You need to select two geometries on two different parts"));
QObject::tr("You need to select two geometries on two different parts"));
return;
};
Assembly::ItemPart* part1 = Asm->getContainingPart(objs[0].getObject());
Assembly::ItemPart* part2 = Asm->getContainingPart(objs[1].getObject());
if(!part1 || !part2) {
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part1 = Asm->getContainingPart(objs[0].getObject());
std::pair<Assembly::ItemPart*, Assembly::ItemAssembly*> part2 = Asm->getContainingPart(objs[1].getObject());
//checking the parts is enough, both or non!
if(!part1.first || !part2.first) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
QObject::tr("The selected parts need to belong to the active assembly (active product or one of it's subproducts)"));
return;
};
//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"));
return;
}
QStringList items;
items << QObject::tr("Parallel") << QObject::tr("Equal") << QObject::tr("Opposite");
QDialog dialog;
Ui_AlignmentDialog ui;
Ui_AlignmentDialog ui;
ui.setupUi(&dialog);
ui.comboBox->addItems(items);
if( dialog.exec() != QDialog::Accepted )
return;
if(dialog.exec() != QDialog::Accepted)
return;
openCommand("Insert Constraint Alignment");
std::string ConstrName = getUniqueObjectName("Alignment");
doCommand(Doc,"App.activeDocument().addObject('Assembly::ConstraintAlignment','%s')",ConstrName.c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1, objs[0].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2, objs[1].getSubNames()[0]).c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Orientation = '%s'", ui.comboBox->currentText().toStdString().c_str());
doCommand(Doc,"App.activeDocument().ActiveObject.Offset = %f", ui.doubleSpinBox->value());
doCommand(Doc,"App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]",ConstGrp->getNameInDocument(),ConstGrp->getNameInDocument());
doCommand(Doc, "App.activeDocument().addObject('Assembly::ConstraintAlignment','%s')", ConstrName.c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.First = %s", asSubLinkString(part1.first, objs[0].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Second = %s", asSubLinkString(part2.first, objs[1].getSubNames()[0]).c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Orientation = '%s'", ui.comboBox->currentText().toStdString().c_str());
doCommand(Doc, "App.activeDocument().ActiveObject.Offset = %f", ui.doubleSpinBox->value());
doCommand(Doc, "App.activeDocument().%s.Constraints = App.activeDocument().%s.Constraints + [App.activeDocument().ActiveObject]", ConstGrp->getNameInDocument(), ConstGrp->getNameInDocument());
commitCommand();
updateActive();
}
void CreateAssemblyConstraintCommands(void)
{
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdAssemblyConstraintFix());
rcCmdMgr.addCommand(new CmdAssemblyConstraintDistance());
@ -472,4 +556,6 @@ void CreateAssemblyConstraintCommands(void)
rcCmdMgr.addCommand(new CmdAssemblyConstraintOrientation());
rcCmdMgr.addCommand(new CmdAssemblyConstraintCoincidence());
rcCmdMgr.addCommand(new CmdAssemblyConstraintAlignment());
}
}

View File

@ -232,7 +232,8 @@ void ViewProviderConstraint::draw()
TopLoc_Location l1 = s1.Location();
gp_XYZ tr1 = l1.Transformation().TranslationPart();
Base::Placement p1(Base::Vector3d(tr1.X(), tr1.Y(), tr1.Z()), Base::Rotation());
p1 = part1->Placement.getValue() * p1;
upstream_placement(p1, part1);
//p1 = part1->m_part->getGlobal<Base::Placement>() * p1;
float q0 = (float)p1.getRotation().getValue()[0];
float q1 = (float)p1.getRotation().getValue()[1];
@ -265,11 +266,32 @@ void ViewProviderConstraint::draw()
TopLoc_Location l2 = s2.Location();
gp_XYZ tr2 = l2.Transformation().TranslationPart();
Base::Placement p2(Base::Vector3d(tr2.X(), tr2.Y(), tr2.Z()), Base::Rotation());
upstream_placement(p2, part2);
p2 = p1.inverse() * (part2->Placement.getValue() * p2);
p2 = p1.inverse()*p2;
//p2 = p1.inverse() * (part2->m_part->getGlobal<Base::Placement>() * p2);
internal_vp.updatePlacement(p2);
}
void ViewProviderConstraint::upstream_placement(Base::Placement& p, Assembly::Item* item) {
//successive transformation for this item
p = item->Placement.getValue() * p;
typedef std::vector<App::DocumentObject*>::const_iterator iter;
//get all links to this item and see if we have more ItemAssemblys
const std::vector<App::DocumentObject*>& vector = item->getInList();
for(iter it=vector.begin(); it != vector.end(); it++) {
if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) {
upstream_placement(p, static_cast<Assembly::ItemAssembly*>(*it));
return;
}
};
};
void ViewProviderConstraint::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if(Gui::Selection().isSelected(pcObject) && Visibility.getValue()) {

View File

@ -28,6 +28,7 @@
#include <Base/Placement.h>
#include <Gui/Selection.h>
#include <Inventor/nodes/SoAnnotation.h>
#include "Mod/Assembly/App/Item.h"
namespace AssemblyGui {
@ -88,6 +89,7 @@ private:
//update visualisation and placements of the scenegraph
void draw();
void upstream_placement(Base::Placement& p, Assembly::Item* item);
//watch if something got selected in the tree
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);