Skip to content

Commit

Permalink
Attacher: Py: add interface for changing attacher type
Browse files Browse the repository at this point in the history
Plus a mechanism to remember attacher type of AttachableObject through
save-restore cycle.
  • Loading branch information
DeepSOIC committed May 13, 2016
1 parent fe295b7 commit d4f1ef2
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 2 deletions.
46 changes: 45 additions & 1 deletion src/Mod/Part/App/AttachableObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -138,6 +178,10 @@ void AttachableObject::onChanged(const App::Property* prop)

}

if(prop == &(this->AttacherType)){
this->changeAttacherType(this->AttacherType.getValue());
}

Part::Feature::onChanged(prop);
}

Expand Down
13 changes: 12 additions & 1 deletion src/Mod/Part/App/AttachableObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,20 @@ class PartExport AttachableObject : public Part::Feature
* @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
Expand Down
10 changes: 10 additions & 0 deletions src/Mod/Part/App/AttachableObjectPy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
19 changes: 19 additions & 0 deletions src/Mod/Part/App/AttachableObjectPyImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down

0 comments on commit d4f1ef2

Please sign in to comment.