make subproduct solving work

This commit is contained in:
Stefan Tröger
2013-08-04 08:51:38 +00:00
parent a29634b1e1
commit 680ff57ccf
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) {