565 lines
21 KiB
C++
565 lines
21 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2016 Viktor Titov (DeepSOIC) <vv.titov@gmail.com> *
|
|
* *
|
|
* This file is part of the FreeCAD CAx development system. *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Library General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU Library General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Library General Public *
|
|
* License along with this library; see the file COPYING.LIB. If not, *
|
|
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
|
* Suite 330, Boston, MA 02111-1307, USA *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include "PreCompiled.h"
|
|
#ifndef _PreComp_
|
|
# include <Standard_Failure.hxx>
|
|
#endif
|
|
|
|
#include <App/DocumentObjectPy.h>
|
|
#include <Base/PlacementPy.h>
|
|
|
|
#include "AttachEnginePy.h"
|
|
#include "AttachEnginePy.cpp"
|
|
#include "AttachExtensionPy.h"
|
|
#include "OCCError.h"
|
|
#include "TopoShapePy.h"
|
|
|
|
|
|
using namespace Attacher;
|
|
|
|
// returns a string which represents the object e.g. when printed in python
|
|
std::string AttachEnginePy::representation() const
|
|
{
|
|
return std::string("<Attacher::AttachEngine>");
|
|
}
|
|
|
|
PyObject* AttachEnginePy::PyMake(struct _typeobject *, PyObject *, PyObject *)
|
|
{
|
|
// create a new instance of AttachEngine3D
|
|
return new AttachEnginePy(new AttachEngine3D);
|
|
}
|
|
|
|
// constructor method
|
|
int AttachEnginePy::PyInit(PyObject* args, PyObject* /*kwd*/)
|
|
{
|
|
PyObject* o;
|
|
if (PyArg_ParseTuple(args, "")) {
|
|
return 0;
|
|
}
|
|
|
|
PyErr_Clear();
|
|
if (PyArg_ParseTuple(args, "O!", &(AttachEnginePy::Type), &o)) {
|
|
AttachEngine* attacher = static_cast<AttachEnginePy*>(o)->getAttachEnginePtr();
|
|
AttachEngine* oldAttacher = this->getAttachEnginePtr();
|
|
this->_pcTwinPointer = attacher->copy();
|
|
delete oldAttacher;
|
|
return 0;
|
|
}
|
|
|
|
PyErr_Clear();
|
|
char* typeName;
|
|
if (PyArg_ParseTuple(args, "s", &typeName)) {
|
|
Base::Type t = Base::Type::fromName(typeName);
|
|
AttachEngine* pNewAttacher = nullptr;
|
|
if (t.isDerivedFrom(AttachEngine::getClassTypeId())){
|
|
pNewAttacher = static_cast<Attacher::AttachEngine*>(Base::Type::createInstanceByName(typeName));
|
|
}
|
|
if (!pNewAttacher) {
|
|
std::stringstream errMsg;
|
|
errMsg << "Object if this type is not derived from AttachEngine: " << typeName;
|
|
PyErr_SetString(Base::PyExc_FC_GeneralError, errMsg.str().c_str());
|
|
return -1;
|
|
}
|
|
AttachEngine* oldAttacher = this->getAttachEnginePtr();
|
|
this->_pcTwinPointer = pNewAttacher;
|
|
delete oldAttacher;
|
|
return 0;
|
|
}
|
|
|
|
PyErr_SetString(PyExc_TypeError, "Wrong set of constructor arguments. Can be: (), ('Attacher::AttachEngine3D'), ('Attacher::AttachEnginePlane'), ('Attacher::AttachEngineLine'), ('Attacher::AttachEnginePoint'), (other_attacher_instance).");
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
Py::String AttachEnginePy::getAttacherType() const
|
|
{
|
|
return Py::String(std::string(this->getAttachEnginePtr()->getTypeId().getName()));
|
|
}
|
|
|
|
/**
|
|
* @brief macro ATTACHERPY_STDCATCH_ATTR: catch for exceptions in attribute
|
|
* code (re-throws the exception converted to Py::Exception). It is a helper
|
|
* to avoid repeating the same error handling code over and over again.
|
|
*/
|
|
#define ATTACHERPY_STDCATCH_ATTR \
|
|
catch (Standard_Failure& e) {\
|
|
throw Py::Exception(Part::PartExceptionOCCError, e.GetMessageString());\
|
|
} catch (Base::Exception &e) {\
|
|
e.setPyException();\
|
|
throw Py::Exception();\
|
|
}
|
|
|
|
Py::String AttachEnginePy::getMode() const
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
return Py::String(attacher.getModeName(attacher.mapMode));
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
void AttachEnginePy::setMode(Py::String arg)
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
std::string modeName = static_cast<std::string>(arg);
|
|
attacher.mapMode = attacher.getModeByName(modeName);
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::Object AttachEnginePy::getReferences() const
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
AttachEngine::verifyReferencesAreSafe(attacher.references);
|
|
return Py::Object(attacher.references.getPyObject(),true);
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
void AttachEnginePy::setReferences(Py::Object arg)
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
attacher.references.setPyObject(arg.ptr());
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::Object AttachEnginePy::getAttachmentOffset() const
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
return Py::Object(new Base::PlacementPy(new Base::Placement(attacher.attachmentOffset)),true);
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
void AttachEnginePy::setAttachmentOffset(Py::Object arg)
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
if (PyObject_TypeCheck(arg.ptr(), &(Base::PlacementPy::Type))) {
|
|
const Base::PlacementPy* plmPy = static_cast<const Base::PlacementPy*>(arg.ptr());
|
|
attacher.attachmentOffset = *(plmPy->getPlacementPtr());
|
|
} else {
|
|
std::string error = std::string("type must be 'Placement', not ");
|
|
error += arg.type().as_string();
|
|
throw Py::TypeError(error);
|
|
}
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::Boolean AttachEnginePy::getReverse() const
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
return Py::Boolean(attacher.mapReverse);
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
void AttachEnginePy::setReverse(Py::Boolean arg)
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
attacher.mapReverse = arg.isTrue();
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::Float AttachEnginePy::getParameter() const
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
return Py::Float(attacher.attachParameter);
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
void AttachEnginePy::setParameter(Py::Float arg)
|
|
{
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
attacher.attachParameter = (double)arg;
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
|
|
Py::List AttachEnginePy::getCompleteModeList() const
|
|
{
|
|
try {
|
|
Py::List ret;
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
for(int imode = 0 ; imode < mmDummy_NumberOfModes ; imode++){
|
|
ret.append(Py::String(attacher.getModeName(eMapMode(imode))));
|
|
}
|
|
return ret;
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::List AttachEnginePy::getCompleteRefTypeList() const
|
|
{
|
|
try {
|
|
Py::List ret;
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
for(int irt = 0 ; irt < rtDummy_numberOfShapeTypes ; irt++){
|
|
ret.append(Py::String(attacher.getRefTypeName(eRefType(irt))));
|
|
}
|
|
return ret;
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
Py::List AttachEnginePy::getImplementedModes() const
|
|
{
|
|
try {
|
|
Py::List ret;
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
for(int imode = 0 ; imode < mmDummy_NumberOfModes ; imode++){
|
|
if(!attacher.modeRefTypes[imode].empty()){
|
|
ret.append(Py::String(attacher.getModeName(eMapMode(imode))));
|
|
}
|
|
}
|
|
return ret;
|
|
} ATTACHERPY_STDCATCH_ATTR;
|
|
}
|
|
|
|
/**
|
|
* @brief macro ATTACHERPY_STDCATCH_METH: catch for exceptions in method code
|
|
* (returns NULL if an exception is caught). It is a helper to avoid repeating
|
|
* the same error handling code over and over again.
|
|
*/
|
|
#define ATTACHERPY_STDCATCH_METH \
|
|
catch (Standard_Failure& e) {\
|
|
PyErr_SetString(Part::PartExceptionOCCError, e.GetMessageString());\
|
|
return NULL;\
|
|
} catch (Base::Exception &e) {\
|
|
PyErr_SetString(Base::PyExc_FC_GeneralError, e.what());\
|
|
return NULL;\
|
|
} catch (const Py::Exception &){\
|
|
return NULL;\
|
|
}
|
|
|
|
|
|
PyObject* AttachEnginePy::getModeInfo(PyObject* args)
|
|
{
|
|
char* modeName;
|
|
if (!PyArg_ParseTuple(args, "s", &modeName))
|
|
return nullptr;
|
|
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
eMapMode mmode = attacher.getModeByName(modeName);
|
|
Py::List pyListOfCombinations;
|
|
Py::List pyCombination;
|
|
refTypeStringList &listOfCombinations = attacher.modeRefTypes.at(mmode);
|
|
for(const refTypeString &combination: listOfCombinations){
|
|
pyCombination = Py::List(combination.size());
|
|
for(std::size_t iref = 0; iref < combination.size(); iref++) {
|
|
pyCombination[iref] = Py::String(AttachEngine::getRefTypeName(combination[iref]));
|
|
}
|
|
pyListOfCombinations.append(pyCombination);
|
|
}
|
|
Py::Dict ret;
|
|
ret["ReferenceCombinations"] = pyListOfCombinations;
|
|
ret["ModeIndex"] = Py::Long(mmode);
|
|
try {
|
|
Py::Module module(PyImport_ImportModule("PartGui"),true);
|
|
if (module.isNull() || !module.hasAttr("AttachEngineResources")) {
|
|
// in v0.14+, the GUI module can be loaded in console mode (but doesn't have all its document methods)
|
|
throw Py::RuntimeError("Gui is not up");//DeepSOIC: wanted to throw ImportError here, but it's not defined, so I don't know...
|
|
}
|
|
Py::Object submod(module.getAttr("AttachEngineResources"));
|
|
Py::Callable method(submod.getAttr("getModeStrings"));
|
|
Py::Tuple arg(2);
|
|
arg.setItem(0, Py::String(this->getAttachEnginePtr()->getTypeId().getName()));
|
|
arg.setItem(1, Py::Long(mmode));
|
|
Py::List strs = method.apply(arg);
|
|
assert(strs.size() == 2);
|
|
ret["UserFriendlyName"] = strs[0];
|
|
ret["BriefDocu"] = strs[1];
|
|
} catch (Py::Exception& e) {
|
|
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
|
|
// the GUI is not up.
|
|
Base::Console().Warning("AttachEngine: Gui not up, so no gui-related entries in getModeInfo.\n");
|
|
e.clear();
|
|
} else {
|
|
Base::Console().Warning("AttachEngine.getModeInfo: error obtaining GUI strings\n");
|
|
e.clear();
|
|
}
|
|
} catch (Base::Exception &e){
|
|
Base::Console().Warning("AttachEngine.getModeInfo: error obtaining GUI strings:");
|
|
Base::Console().Warning(e.what());
|
|
Base::Console().Warning("\n");
|
|
}
|
|
|
|
return Py::new_reference_to(ret);
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::getRefTypeOfShape(PyObject* args)
|
|
{
|
|
PyObject *pcObj;
|
|
if (!PyArg_ParseTuple(args, "O!", &(Part::TopoShapePy::Type), &pcObj))
|
|
return nullptr;
|
|
|
|
try{
|
|
TopoDS_Shape shape = static_cast<Part::TopoShapePy*>(pcObj)->getTopoShapePtr()->getShape();
|
|
eRefType rt = AttachEngine::getShapeType(shape);
|
|
return Py::new_reference_to(Py::String(AttachEngine::getRefTypeName(rt)));
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::isFittingRefType(PyObject* args)
|
|
{
|
|
char* type_shape_str;
|
|
char* type_need_str;
|
|
if (!PyArg_ParseTuple(args, "ss", &type_shape_str, &type_need_str))
|
|
return nullptr;
|
|
try {
|
|
eRefType type_shape = AttachEngine::getRefTypeByName(std::string(type_shape_str));
|
|
eRefType type_need = AttachEngine::getRefTypeByName(std::string(type_need_str));
|
|
bool result = AttachEngine::isShapeOfType(type_shape, type_need) > -1;
|
|
return Py::new_reference_to(Py::Boolean(result));
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::downgradeRefType(PyObject* args)
|
|
{
|
|
char* type_shape_str;
|
|
if (!PyArg_ParseTuple(args, "s", &type_shape_str))
|
|
return nullptr;
|
|
try {
|
|
eRefType type_shape = AttachEngine::getRefTypeByName(std::string(type_shape_str));
|
|
eRefType result = AttachEngine::downgradeType(type_shape);
|
|
return Py::new_reference_to(Py::String(AttachEngine::getRefTypeName(result)));
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::getRefTypeInfo(PyObject* args)
|
|
{
|
|
char* typeName;
|
|
if (!PyArg_ParseTuple(args, "s", &typeName))
|
|
return nullptr;
|
|
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
eRefType rt = attacher.getRefTypeByName(typeName);
|
|
Py::Dict ret;
|
|
ret["TypeIndex"] = Py::Long(rt);
|
|
ret["Rank"] = Py::Long(AttachEngine::getTypeRank(rt));
|
|
|
|
try {
|
|
Py::Module module(PyImport_ImportModule("PartGui"),true);
|
|
if (module.isNull() || !module.hasAttr("AttachEngineResources")) {
|
|
// in v0.14+, the GUI module can be loaded in console mode (but doesn't have all its document methods)
|
|
throw Py::RuntimeError("Gui is not up");//DeepSOIC: wanted to throw ImportError here, but it's not defined, so I don't know...
|
|
}
|
|
Py::Object submod(module.getAttr("AttachEngineResources"));
|
|
Py::Callable method(submod.getAttr("getRefTypeUserFriendlyName"));
|
|
Py::Tuple arg(1);
|
|
arg.setItem(0, Py::Long(rt));
|
|
Py::String st = method.apply(arg);
|
|
ret["UserFriendlyName"] = st;
|
|
} catch (Py::Exception& e) {
|
|
if (PyErr_ExceptionMatches(PyExc_ImportError)) {
|
|
// the GUI is not up.
|
|
Base::Console().Warning("AttachEngine: Gui not up, so no gui-related entries in getModeInfo.\n");
|
|
e.clear();
|
|
} else {
|
|
Base::Console().Warning("AttachEngine.getRefTypeInfo: error obtaining GUI strings\n");
|
|
e.clear();
|
|
}
|
|
} catch (Base::Exception &e){
|
|
Base::Console().Warning("AttachEngine.getRefTypeInfo: error obtaining GUI strings:");
|
|
Base::Console().Warning(e.what());
|
|
Base::Console().Warning("\n");
|
|
}
|
|
|
|
return Py::new_reference_to(ret);
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::copy(PyObject* args)
|
|
{
|
|
if (!PyArg_ParseTuple(args, ""))
|
|
return nullptr;
|
|
|
|
return new AttachEnginePy(this->getAttachEnginePtr()->copy());
|
|
}
|
|
|
|
PyObject* AttachEnginePy::calculateAttachedPlacement(PyObject* args)
|
|
{
|
|
PyObject *pcObj;
|
|
if (!PyArg_ParseTuple(args, "O!", &(Base::PlacementPy::Type), &pcObj))
|
|
return nullptr;
|
|
try{
|
|
const Base::Placement& plm = *(static_cast<const Base::PlacementPy*>(pcObj)->getPlacementPtr());
|
|
Base::Placement result;
|
|
try{
|
|
result = this->getAttachEnginePtr()->calculateAttachedPlacement(plm);
|
|
} catch (ExceptionCancel&) {
|
|
Py_IncRef(Py_None);
|
|
return Py_None;
|
|
}
|
|
return new Base::PlacementPy(new Base::Placement(result));
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::suggestModes(PyObject* args)
|
|
{
|
|
if (!PyArg_ParseTuple(args, ""))
|
|
return nullptr;
|
|
|
|
try {
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
SuggestResult sugr;
|
|
attacher.suggestMapModes(sugr);
|
|
Py::Dict result;
|
|
{ //sugr.allApplicableModes
|
|
Py::List pyList;
|
|
for(eMapMode mmode: sugr.allApplicableModes){
|
|
pyList.append(Py::String(AttachEngine::getModeName(mmode)));
|
|
}
|
|
result["allApplicableModes"] = pyList;
|
|
}
|
|
{ //sugr.bestFitMode
|
|
result["bestFitMode"] = Py::String(AttachEngine::getModeName(sugr.bestFitMode));
|
|
}
|
|
{//sugr.error
|
|
bool isError = sugr.message == SuggestResult::srUnexpectedError
|
|
|| sugr.message == SuggestResult::srLinkBroken;
|
|
result["error"] = Py::String(isError ? sugr.error.what() : "");
|
|
}
|
|
{//sugr.message
|
|
std::string msg;
|
|
switch(sugr.message){
|
|
case SuggestResult::srIncompatibleGeometry:
|
|
msg = "IncompatibleGeometry";
|
|
break;
|
|
case SuggestResult::srLinkBroken:
|
|
msg = "LinkBroken";
|
|
break;
|
|
case SuggestResult::srNoModesFit:
|
|
msg = "NoModesFit";
|
|
break;
|
|
case SuggestResult::srOK:
|
|
msg = "OK";
|
|
break;
|
|
case SuggestResult::srUnexpectedError:
|
|
msg = "UnexpectedError";
|
|
break;
|
|
default:
|
|
msg = "<message index out of range>";
|
|
}
|
|
result["message"] = Py::String(msg);
|
|
}
|
|
{//sugr.nextRefTypeHint
|
|
Py::List pyList;
|
|
for(eRefType rt : sugr.nextRefTypeHint){
|
|
pyList.append(Py::String(AttachEngine::getRefTypeName(rt)));
|
|
}
|
|
result["nextRefTypeHint"] = pyList;
|
|
}
|
|
{//sugr.reachableModes
|
|
Py::Dict pyRM;
|
|
for(std::pair<const eMapMode, refTypeStringList> &rm: sugr.reachableModes){
|
|
Py::List pyListOfCombinations;
|
|
for(refTypeString &rts : rm.second){
|
|
Py::List pyCombination;
|
|
for(eRefType rt : rts){
|
|
pyCombination.append(Py::String(AttachEngine::getRefTypeName(rt)));
|
|
}
|
|
pyListOfCombinations.append(pyCombination);
|
|
}
|
|
pyRM[AttachEngine::getModeName(rm.first)] = pyListOfCombinations;
|
|
}
|
|
result["reachableModes"] = pyRM;
|
|
}
|
|
{//sugr.references_Types
|
|
Py::List pyList;
|
|
for(eRefType rt : sugr.references_Types){
|
|
pyList.append(Py::String(AttachEngine::getRefTypeName(rt)));
|
|
}
|
|
result["references_Types"] = pyList;
|
|
}
|
|
|
|
return Py::new_reference_to(result);
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::readParametersFromFeature(PyObject* args)
|
|
{
|
|
PyObject* obj;
|
|
if (!PyArg_ParseTuple(args, "O!",&(App::DocumentObjectPy::Type),&obj))
|
|
return nullptr;
|
|
|
|
try{
|
|
App::DocumentObjectPy* dobjpy = static_cast<App::DocumentObjectPy*>(obj);
|
|
App::DocumentObject* dobj = dobjpy->getDocumentObjectPtr();
|
|
if (! dobj->hasExtension(Part::AttachExtension::getExtensionClassTypeId())){
|
|
throw Py::TypeError("Supplied object has no Part::AttachExtension");
|
|
}
|
|
Part::AttachExtension* feat = dobj->getExtensionByType<Part::AttachExtension>();
|
|
AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
attacher.setUp(feat->Support,
|
|
eMapMode(feat->MapMode.getValue()),
|
|
feat->MapReversed.getValue(),
|
|
feat->MapPathParameter.getValue(),
|
|
0.0,0.0,
|
|
feat->AttachmentOffset.getValue());
|
|
return Py::new_reference_to(Py::None());
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::writeParametersToFeature(PyObject* args)
|
|
{
|
|
PyObject* obj;
|
|
if (!PyArg_ParseTuple(args, "O!",&(App::DocumentObjectPy::Type),&obj))
|
|
return nullptr;
|
|
|
|
try{
|
|
App::DocumentObjectPy* dobjpy = static_cast<App::DocumentObjectPy*>(obj);
|
|
App::DocumentObject* dobj = dobjpy->getDocumentObjectPtr();
|
|
if (! dobj->hasExtension(Part::AttachExtension::getExtensionClassTypeId())){
|
|
throw Py::TypeError("Supplied object has no Part::AttachExtension");
|
|
}
|
|
Part::AttachExtension* feat = dobj->getExtensionByType<Part::AttachExtension>();
|
|
const AttachEngine &attacher = *(this->getAttachEnginePtr());
|
|
AttachEngine::verifyReferencesAreSafe(attacher.references);
|
|
feat->Support.Paste(attacher.references);
|
|
feat->MapMode.setValue(attacher.mapMode);
|
|
feat->MapReversed.setValue(attacher.mapReverse);
|
|
feat->MapPathParameter.setValue(attacher.attachParameter);
|
|
feat->AttachmentOffset.setValue(attacher.attachmentOffset);
|
|
return Py::new_reference_to(Py::None());
|
|
} ATTACHERPY_STDCATCH_METH;
|
|
}
|
|
|
|
PyObject* AttachEnginePy::getCustomAttributes(const char*) const
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
int AttachEnginePy::setCustomAttributes(const char*,PyObject*)
|
|
{
|
|
return 0;
|
|
}
|
|
|