make subproduct solving work
This commit is contained in:
@@ -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);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user