Attacher: Py: add interface for changing attacher type

Plus a mechanism to remember attacher type of AttachableObject through
save-restore cycle.
This commit is contained in:
DeepSOIC 2016-05-06 21:52:23 +03:00
parent fe295b701b
commit d4f1ef2f7a
4 changed files with 86 additions and 2 deletions

View File

@ -42,6 +42,9 @@ PROPERTY_SOURCE(Part::AttachableObject, Part::Feature);
AttachableObject::AttachableObject()
: _attacher(0)
{
ADD_PROPERTY_TYPE(AttacherType, ("Attacher::AttachEngine3D"), "Attachment",(App::PropertyType)(App::Prop_None),"Class name of attach engine object driving the attachment.");
this->AttacherType.setStatus(App::Property::Status::Hidden, true);
ADD_PROPERTY_TYPE(Support, (0,0), "Attachment",(App::PropertyType)(App::Prop_None),"Support of the 2D geometry");
ADD_PROPERTY_TYPE(MapMode, (mmDeactivated), "Attachment", App::Prop_None, "Mode of attachment to other object");
@ -69,7 +72,44 @@ void AttachableObject::setAttacher(AttachEngine* attacher)
if (_attacher)
delete _attacher;
_attacher = attacher;
updateAttacherVals();
if (_attacher){
const char* typeName = attacher->getTypeId().getName();
if(strcmp(this->AttacherType.getValue(),typeName)!=0) //make sure we need to change, to break recursive onChange->changeAttacherType->onChange...
this->AttacherType.setValue(typeName);
updateAttacherVals();
} else {
if (strlen(AttacherType.getValue()) != 0){ //make sure we need to change, to break recursive onChange->changeAttacherType->onChange...
this->AttacherType.setValue("");
}
}
}
bool AttachableObject::changeAttacherType(const char* typeName)
{
//check if we need to actually change anything
if (_attacher){
if (strcmp(_attacher->getTypeId().getName(),typeName)==0){
return false;
}
} else if (strlen(typeName) == 0){
return false;
}
if (strlen(typeName) == 0){
setAttacher(nullptr);
return true;
}
Base::Type t = Base::Type::fromName(typeName);
if (t.isDerivedFrom(AttachEngine::getClassTypeId())){
AttachEngine* pNewAttacher = static_cast<Attacher::AttachEngine*>(Base::Type::createInstanceByName(typeName));
this->setAttacher(pNewAttacher);
return true;
} else {
std::stringstream errMsg;
errMsg << "Object if this type is not derived from AttachEngine: " << typeName;
throw Base::Exception(errMsg.str());
}
assert(false);//exec shouldn't ever get here
return false;
}
bool AttachableObject::positionBySupport()
@ -138,6 +178,10 @@ void AttachableObject::onChanged(const App::Property* prop)
}
if(prop == &(this->AttacherType)){
this->changeAttacherType(this->AttacherType.getValue());
}
Part::Feature::onChanged(prop);
}

View File

@ -68,9 +68,20 @@ public:
* @param attacher. AttachableObject takes ownership and will delete it eventually.
*/
virtual void setAttacher(Attacher::AttachEngine* attacher);
/**
* @brief changeAttacherType
* @param typeName is the typename of new attacher class. Must be derived
* from Attacher::AttachEngine.
* @return true if attacher was changed. false if attacher is already of the
* type requested. Throws if invalid type is supplied.
*/
bool changeAttacherType(const char* typeName);
Attacher::AttachEngine &attacher(void) const {return *_attacher;}
/// if the 2DObject lies on the Face of an other object this links to it
App::PropertyString AttacherType;
App::PropertyLinkSubList Support;
App::PropertyEnumeration MapMode; //see AttachEngine::eMapMode
App::PropertyBool MapReversed; //inverts Z and X internal axes

View File

@ -20,5 +20,15 @@ Returns True if attachment calculation was successful, false if object is not at
and raises an exception if attachment calculation fails.</UserDocu>
</Documentation>
</Methode>
<Methode Name = "changeAttacherType">
<Documentation>
<UserDocu>changeAttacherType(typename): Changes Attacher class of this object.
typename: string. The following are accepted so far:
'Attacher::AttachEngine3D'
'Attacher::AttachEnginePlane'
'Attacher::AttachEngineLine'
'Attacher::AttachEnginePoint'</UserDocu>
</Documentation>
</Methode>
</PythonExport>
</GenerateModel>

View File

@ -34,6 +34,25 @@ PyObject* AttachableObjectPy::positionBySupport(PyObject *args)
return Py::new_reference_to(Py::Boolean(bAttached));
}
PyObject* AttachableObjectPy::changeAttacherType(PyObject *args)
{
const char* typeName;
if (!PyArg_ParseTuple(args, "s", &typeName))
return 0;
bool ret;
try{
ret = this->getAttachableObjectPtr()->changeAttacherType(typeName);
} catch (Standard_Failure) {
Handle_Standard_Failure e = Standard_Failure::Caught();
PyErr_SetString(PartExceptionOCCError, e->GetMessageString());
return NULL;
} catch (Base::Exception &e) {
PyErr_SetString(Base::BaseExceptionFreeCADError, e.what());
return NULL;
}
return Py::new_reference_to(Py::Boolean(ret));
}
PyObject *AttachableObjectPy::getCustomAttributes(const char* /*attr*/) const
{