diff --git a/src/Mod/Assembly/App/Constraint.cpp b/src/Mod/Assembly/App/Constraint.cpp index f492c7394..fa5fc368d 100644 --- a/src/Mod/Assembly/App/Constraint.cpp +++ b/src/Mod/Assembly/App/Constraint.cpp @@ -199,7 +199,7 @@ void Constraint::init(Assembly::ItemAssembly* ass) //distance constraint if(Type.getValue() == 1) - m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, (dcm::distance = Value.getValue()) & (dcm::distance=sspace)); + m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, (dcm::distance = Value.getValue()) = sspace); //orientation constraint if(Type.getValue() == 2) @@ -211,7 +211,7 @@ void Constraint::init(Assembly::ItemAssembly* ass) //alignemnt constraint if(Type.getValue() == 4) - m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, (dcm::alignment=dir) & (dcm::alignment=Value.getValue()) & (dcm::alignment=sspace)); + m_constraint = ass->m_solver->createConstraint3D(getNameInDocument(), m_first_geom, m_second_geom, ((dcm::alignment = dir) = Value.getValue()) = sspace); //coincident constraint if(Type.getValue() == 5) diff --git a/src/Mod/Assembly/App/ItemAssembly.cpp b/src/Mod/Assembly/App/ItemAssembly.cpp index 79067e1cd..d342aa55f 100644 --- a/src/Mod/Assembly/App/ItemAssembly.cpp +++ b/src/Mod/Assembly/App/ItemAssembly.cpp @@ -57,7 +57,8 @@ short ItemAssembly::mustExecute() const { App::DocumentObjectExecReturn* ItemAssembly::execute(void) { - Base::Console().Message("Execute\n"); + Base::Console().Message("Execute\n"); + try { //create a solver and init all child assemblys with subsolvers @@ -69,11 +70,6 @@ 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()); - } catch (boost::exception& e) { @@ -81,23 +77,25 @@ App::DocumentObjectExecReturn* ItemAssembly::execute(void) { message << "Solver exception " << *boost::get_error_info(e) << "raised: " << boost::get_error_info(e)->c_str() << std::endl; //throw Base::Exception(message.str().c_str()); - Base::Console().Error(message.str().c_str()); + Base::Console().Error(message.str().c_str()); } catch (std::exception& e) { message.clear(); message << "Exception raised in assembly solver: " << e.what() << std::endl; //throw Base::Exception(message.str().c_str()); - Base::Console().Error(message.str().c_str()); + Base::Console().Error(message.str().c_str()); } catch (...) { message.clear(); message << "Unknown Exception raised in assembly solver during execution" << std::endl; //throw Base::Exception(message.str().c_str()); - Base::Console().Error(message.str().c_str()); + Base::Console().Error(message.str().c_str()); }; + this->touch(); + return App::DocumentObject::StdReturn; } @@ -106,9 +104,11 @@ TopoDS_Shape ItemAssembly::getShape(void) const { std::vector obj = Items.getValues(); std::vector::iterator it; + for(it = obj.begin(); it != obj.end(); ++it) { if((*it)->getTypeId().isDerivedFrom(Assembly::Item::getClassTypeId())) { TopoDS_Shape aShape = static_cast(*it)->getShape(); + if(!aShape.IsNull()) s.push_back(aShape); } @@ -123,10 +123,12 @@ TopoDS_Shape ItemAssembly::getShape(void) const { aBuilder.Add(aRes, *it); } + //if (aRes.IsNull()) // throw Base::Exception("Resulting shape is invalid"); return aRes; } + // set empty shape return TopoDS_Compound(); @@ -137,6 +139,7 @@ PyObject* ItemAssembly::getPyObject(void) { // ref counter is set to 1 PythonObject = Py::Object(new ItemAssemblyPy(this),true); } + return Py::new_reference_to(PythonObject); } @@ -145,6 +148,7 @@ bool ItemAssembly::isParentAssembly(ItemPart* part) { 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::ItemPart::getClassTypeId()) @@ -160,19 +164,20 @@ ItemAssembly* ItemAssembly::getParentAssembly(ItemPart* part) { 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::ItemPart::getClassTypeId()) { if(*it == part) return this; } - else - if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { + else if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { - Assembly::ItemAssembly* assembly = static_cast(*it)->getParentAssembly(part); - if(assembly) - return assembly; - } + Assembly::ItemAssembly* assembly = static_cast(*it)->getParentAssembly(part); + + if(assembly) + return assembly; + } }; return (ItemAssembly*)NULL; @@ -185,19 +190,20 @@ std::pair ItemAssembly::getContainingPart(App::Documen 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::ItemPart::getClassTypeId()) { if(static_cast(*it)->holdsObject(obj)) return std::make_pair(static_cast(*it), this); } - else - if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { + else if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) { - std::pair part = static_cast(*it)->getContainingPart(obj); - if(part.first && part.second) - return part; - } + std::pair part = static_cast(*it)->getContainingPart(obj); + + if(part.first && part.second) + return part; + } }; return std::pair(NULL, NULL); @@ -217,10 +223,14 @@ void ItemAssembly::initSolver(boost::shared_ptr parent, Base::Placement& m_downstream_placement = PL_downstream; } } + + //connect the recalculated signal in case we need to update the placement + m_solver->connectSignal(boost::bind(&ItemAssembly::finish, this, _1)); 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()) { @@ -238,6 +248,7 @@ void ItemAssembly::initConstraints(boost::shared_ptr parent) { typedef std::vector::const_iterator iter; const std::vector& vector = Annotations.getValues(); + for(iter it=vector.begin(); it != vector.end(); it++) { if((*it)->getTypeId() == Assembly::ConstraintGroup::getClassTypeId()) @@ -246,6 +257,7 @@ void ItemAssembly::initConstraints(boost::shared_ptr parent) { // iterate down as long as a non-rigid subsystem exists const std::vector& vector2 = Items.getValues(); + for(iter it=vector2.begin(); it != vector2.end(); it++) { if((*it)->getTypeId() == Assembly::ItemAssembly::getClassTypeId()) @@ -253,29 +265,14 @@ void ItemAssembly::initConstraints(boost::shared_ptr parent) { }; } -} +}; -//no signals for subsystems, we need to extract the placement by hand -void ItemAssembly::finish(boost::shared_ptr parent) { +//the callback for the recalculated signal +void ItemAssembly::finish(boost::shared_ptr subsystem) { - if(parent && Rigid.getValue()) { - Base::Placement p = m_solver->getTransformation(); - this->Placement.setValue(p); - } + //assert(subsystem == m_solver); + Base::Placement p = m_solver->getTransformation(); + this->Placement.setValue(p); +}; - - 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()) { - - static_cast(*it)->finish(m_solver); - } - }; - -} - - -} +} //assembly diff --git a/src/Mod/Assembly/App/ItemAssembly.h b/src/Mod/Assembly/App/ItemAssembly.h index d0b6e9f3f..058d09f74 100644 --- a/src/Mod/Assembly/App/ItemAssembly.h +++ b/src/Mod/Assembly/App/ItemAssembly.h @@ -73,7 +73,7 @@ public: void initConstraints(boost::shared_ptr parent); //read the downstream itemassemblys and set their placement to the propertyplacement - void finish(boost::shared_ptr parent); + void finish(boost::shared_ptr subsystem); boost::shared_ptr m_solver; Base::Placement m_downstream_placement; diff --git a/src/Mod/Assembly/App/opendcm/core/equations.hpp b/src/Mod/Assembly/App/opendcm/core/equations.hpp index 6ef1b8be2..0b1004937 100644 --- a/src/Mod/Assembly/App/opendcm/core/equations.hpp +++ b/src/Mod/Assembly/App/opendcm/core/equations.hpp @@ -17,8 +17,8 @@ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#ifndef GCM_EQUATIONS_H -#define GCM_EQUATIONS_H +#ifndef DCM_EQUATIONS_H +#define DCM_EQUATIONS_H #include @@ -204,13 +204,17 @@ struct Distance : public Equation, using Equation::operator=; using Equation::options; - Distance(); + Distance() { + setDefault(); + }; //override needed ass assignmend operator is always created by the compiler //and we need to ensure that our custom one is used - Distance& operator=(const Distance& d); + Distance& operator=(const Distance& d) { + return Equation::assign(d); + }; - void setDefault(); + void setDefault() {}; template< typename Kernel, typename Tag1, typename Tag2 > struct type { @@ -271,13 +275,19 @@ struct Orientation : public Equation { using Equation::operator=; using Equation::options; - Orientation(); + Orientation() { + setDefault(); + }; //override needed ass assignmend operator is always created by the compiler //and we need to ensure that our custom one is used - Orientation& operator=(const Orientation& d); + Orientation& operator=(const Orientation& d) { + return Equation::assign(d); + }; - void setDefault(); + void setDefault() { + fusion::at_key(values) = std::make_pair(false, parallel); + }; template< typename Kernel, typename Tag1, typename Tag2 > struct type : public PseudoScale { @@ -331,13 +341,20 @@ struct Angle : public Equation, 3, tr using Equation::operator=; - Angle(); + Angle() { + setDefault(); + }; //override needed ass assignmend operator is always created by the compiler //and we need to ensure that our custom one is used - Angle& operator=(const Angle& d); + Angle& operator=(const Angle& d) { + return Equation::assign(d); + }; - void setDefault(); + void setDefault() { + fusion::at_key(values) = std::make_pair(false, 0.); + fusion::at_key(values) = std::make_pair(false, bidirectional); + }; template< typename Kernel, typename Tag1, typename Tag2 > struct type : public PseudoScale { diff --git a/src/Mod/Assembly/App/opendcm/core/imp/equations_imp.hpp b/src/Mod/Assembly/App/opendcm/core/imp/equations_imp.hpp index 2090ac413..b0f072565 100644 --- a/src/Mod/Assembly/App/opendcm/core/imp/equations_imp.hpp +++ b/src/Mod/Assembly/App/opendcm/core/imp/equations_imp.hpp @@ -210,6 +210,7 @@ operator << (std::basic_ostream& stream, const Eq& equation) return stream; } +/* Distance::Distance() : Equation() { setDefault(); }; @@ -246,7 +247,7 @@ void Angle::setDefault() { fusion::at_key(values) = std::make_pair(false, 0.); fusion::at_key(values) = std::make_pair(false, bidirectional); }; - +*/ }; diff --git a/src/Mod/Assembly/CMakeLists.txt b/src/Mod/Assembly/CMakeLists.txt index aa8e18d55..fcded4781 100644 --- a/src/Mod/Assembly/CMakeLists.txt +++ b/src/Mod/Assembly/CMakeLists.txt @@ -1,10 +1,11 @@ -option(FREECAD_ASSEMBLY_SOLVER_LOGS "Generate extensive logs of the assembly solving process" OFF) +option(FREECAD_ASSEMBLY_DEBUG_FACILITIES "Tune solver settings manual and generate extensive logs of the assembly solving process" OFF) -if(FREECAD_ASSEMBLY_SOLVER_LOGS) +if(FREECAD_ASSEMBLY_DEBUG_FACILITIES) find_package(Boost COMPONENTS log REQUIRED) add_definitions(-DUSE_LOGGING) -endif(FREECAD_ASSEMBLY_SOLVER_LOGS) + add_definitions(-DASSEMBLY_DEBUG_FACILITIES) +endif(FREECAD_ASSEMBLY_DEBUG_FACILITIES) if(MSVC) add_definitions(/wd4503)