Attacher: change suggestion routine interface
When another bit of information was needed to be extracted from mode suggestion routine, it felt like listMapModes had too many arguments. So, the arguments have been collapsed into a struct. This triggered a few namespace-related changes, which lead to massive search-and-replace changes all over FreeCAD. So the only functional change carried out is the addition of reference types readout to info returned by suggestor.
This commit is contained in:
parent
9d19bf023a
commit
505ec6a26d
|
@ -258,31 +258,21 @@ Base::Placement AttachEngine::placementFactory(const gp_Dir &ZAxis,
|
|||
|
||||
}
|
||||
|
||||
eMapMode AttachEngine::listMapModes(eSuggestResult& msg,
|
||||
std::vector<eMapMode>* allApplicableModes,
|
||||
std::set<eRefType>* nextRefTypeHint,
|
||||
std::map<eMapMode,refTypeStringList>* reachableModes) const
|
||||
void AttachEngine::suggestMapModes(SuggestResult &result) const
|
||||
{
|
||||
//replace a pointer with a valid reference, to avoid checks for zero pointer everywhere
|
||||
std::vector<eMapMode> buf;
|
||||
if (allApplicableModes == 0)
|
||||
allApplicableModes = &buf;
|
||||
std::vector<eMapMode> &mlist = *allApplicableModes;
|
||||
std::vector<eMapMode> &mlist = result.allApplicableModes;
|
||||
mlist.clear();
|
||||
mlist.reserve(mmDummy_NumberOfModes);
|
||||
|
||||
std::set<eRefType> buf2;
|
||||
if (nextRefTypeHint == 0)
|
||||
nextRefTypeHint = &buf2;
|
||||
std::set<eRefType> &hints = *nextRefTypeHint;
|
||||
std::set<eRefType> &hints = result.nextRefTypeHint;
|
||||
hints.clear();
|
||||
|
||||
std::map<eMapMode,refTypeStringList> buf3;
|
||||
if (reachableModes == 0)
|
||||
reachableModes = &buf3;
|
||||
std::map<eMapMode,refTypeStringList> &mlist_reachable = *reachableModes;
|
||||
std::map<eMapMode,refTypeStringList> &mlist_reachable = result.reachableModes;
|
||||
mlist_reachable.clear();
|
||||
|
||||
result.message = SuggestResult::srLinkBroken;
|
||||
result.bestFitMode = mmDeactivated;
|
||||
|
||||
|
||||
std::vector<App::GeoFeature*> parts;
|
||||
std::vector<const TopoDS_Shape*> shapes;
|
||||
|
@ -290,15 +280,18 @@ eMapMode AttachEngine::listMapModes(eSuggestResult& msg,
|
|||
std::vector<eRefType> typeStr;
|
||||
try{
|
||||
readLinks(this->references, parts, shapes, shapeStorage, typeStr);
|
||||
} catch (Base::Exception) {
|
||||
msg = srLinkBroken;
|
||||
return mmDeactivated;
|
||||
} catch (Base::Exception &err) {
|
||||
result.references_Types = typeStr;
|
||||
result.message = SuggestResult::srLinkBroken;
|
||||
result.error = err;
|
||||
return;
|
||||
}
|
||||
|
||||
result.references_Types = typeStr;
|
||||
|
||||
//search valid modes.
|
||||
eMapMode bestMatchType = mmDeactivated;
|
||||
int bestMatchScore = -1;
|
||||
msg = srNoModesFit;
|
||||
result.message = SuggestResult::srNoModesFit;
|
||||
for (std::size_t iMode = 0; iMode < this->modeRefTypes.size(); ++iMode) {
|
||||
if (! this->modeEnabled[iMode])
|
||||
continue;
|
||||
|
@ -352,8 +345,8 @@ eMapMode AttachEngine::listMapModes(eSuggestResult& msg,
|
|||
if (score > -1){//still output a best match, even if it is not completely compatible
|
||||
if (score > bestMatchScore){
|
||||
bestMatchScore = score;
|
||||
bestMatchType = eMapMode(iMode);
|
||||
msg = score > 0 ? srOK : srIncompatibleGeometry;
|
||||
result.bestFitMode = eMapMode(iMode);
|
||||
result.message = score > 0 ? SuggestResult::srOK : SuggestResult::srIncompatibleGeometry;
|
||||
}
|
||||
}
|
||||
if (score > 0){
|
||||
|
@ -365,16 +358,6 @@ eMapMode AttachEngine::listMapModes(eSuggestResult& msg,
|
|||
}
|
||||
}
|
||||
|
||||
return bestMatchType;
|
||||
|
||||
}
|
||||
|
||||
const std::set<eRefType> AttachEngine::getHint(bool forCurrentModeOnly) const
|
||||
{
|
||||
eSuggestResult msg;
|
||||
std::set<eRefType> ret;
|
||||
this->listMapModes(msg, 0, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AttachEngine::EnableAllSupportedModes()
|
||||
|
|
|
@ -102,13 +102,6 @@ enum eMapMode {
|
|||
mmDummy_NumberOfModes//a value useful to check the validity of mode value
|
||||
};//see also eMapModeStrings[] definition in .cpp
|
||||
|
||||
enum eSuggestResult{
|
||||
srOK,
|
||||
srLinkBroken,
|
||||
srUnexpectedError,
|
||||
srNoModesFit,//none of the avaliable mapping modes accepts the set of topological type
|
||||
srIncompatibleGeometry,//there is a mode that could fit, but geometry is wrong (e.g. a line is required, but a curve was passed).
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The eRefType enum lists the types of references. If adding one, see
|
||||
|
@ -144,6 +137,66 @@ enum eRefType {
|
|||
};
|
||||
|
||||
|
||||
typedef std::vector<eRefType> refTypeString; //a sequence of ref types, according to Support contents for example
|
||||
typedef std::vector<refTypeString> refTypeStringList; //a set of type strings, defines which selection sets are supported by a certain mode
|
||||
|
||||
|
||||
/**
|
||||
* @brief The SuggestResult struct is a container for output information of AttachEngine mode suggesting routine.
|
||||
*/
|
||||
struct SuggestResult{
|
||||
/**
|
||||
* @brief message contains overall verdict of suggestor on current reference set
|
||||
*/
|
||||
enum eSuggestResult{
|
||||
srOK, //references are valid for at least one mode
|
||||
srLinkBroken, //failed to resolve out some of current references. Exception info is stored in SuggestResult::error.
|
||||
srUnexpectedError,
|
||||
srNoModesFit,//none of the avaliable mapping modes accepts the set of topological type
|
||||
srIncompatibleGeometry,//there is a mode that could fit, but geometry is wrong (e.g. a line is required, but a curve was passed).
|
||||
};
|
||||
eSuggestResult message;
|
||||
|
||||
/**
|
||||
* @brief allApplicableModes. Vector array that will recieve the list of
|
||||
* all modes that are applicable to current set of references. It doesn't
|
||||
* guarantee that all modes will work, it only checks that subelemnts are
|
||||
* of right type.
|
||||
*/
|
||||
std::vector<eMapMode> allApplicableModes;
|
||||
|
||||
/**
|
||||
* @brief bestFitMode is the mode that is the most specific to current
|
||||
* references. Note that the mode may not be valid for current references;
|
||||
* check if it's listed in allApplicableModes, or test if message == srOK.
|
||||
*/
|
||||
eMapMode bestFitMode;
|
||||
|
||||
/**
|
||||
* @brief nextRefTypeHint: a hint of what can be added to references to
|
||||
* achieve other modes.
|
||||
*/
|
||||
std::set<eRefType> nextRefTypeHint;
|
||||
|
||||
/**
|
||||
* @brief reachableModes. List of modes that can be reached by selecing
|
||||
* more references. Is a map, where key is the mode that can be reached,
|
||||
* and value is a list of reference sequences that can be added to reach
|
||||
* the mode (stuff already linked is omitted from these lists; only extra
|
||||
* links needed are listed)
|
||||
*/
|
||||
std::map<eMapMode, refTypeStringList> reachableModes;
|
||||
|
||||
/**
|
||||
* @brief references_Types: list of types of references, as queried when
|
||||
* running suggesting routine.
|
||||
*/
|
||||
refTypeString references_Types;
|
||||
|
||||
Base::Exception error;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief The AttachEngine class is the placement calculation routine, modes,
|
||||
* hints and so on. It can be used separately, without deriving from
|
||||
|
@ -152,10 +205,6 @@ enum eRefType {
|
|||
class PartExport AttachEngine : public Base::BaseClass
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
public: //typedefs
|
||||
typedef std::vector<eRefType> refTypeString; //a sequence of ref types, according to Support contents for example
|
||||
typedef std::vector<refTypeString> refTypeStringList; //a set of type strings, defines which selection sets are supported by a certain mode
|
||||
|
||||
public: //methods
|
||||
AttachEngine();
|
||||
virtual void setUp(const App::PropertyLinkSubList &references,
|
||||
|
@ -214,43 +263,15 @@ public: //methods
|
|||
Base::Placement* placeOfRef = 0) const;
|
||||
|
||||
/**
|
||||
* @brief listMapModes is the procedure that knows everything about
|
||||
* @brief suggestMapModes is the procedure that knows everything about
|
||||
* mapping modes. It returns the most appropriate mapping mode, as well as
|
||||
* list of all modes that will accept the set of references. In case no modes apply,
|
||||
* extra information regarding reasons is returned in msg.
|
||||
*
|
||||
* @param msg (output). Returns a message from the decision logic: OK if
|
||||
* the mode was chosen, a reason if not.
|
||||
*
|
||||
* @param allApplicableModes (output). Pointer to a vector array that will recieve the
|
||||
* list of all modes that are applicable to the support. It doesn't
|
||||
* guarantee that all modes will work, it only checks that subelemnts are of
|
||||
* right type.
|
||||
*
|
||||
* @param nextRefTypeHint (output). A hint of what can be added to references.
|
||||
*
|
||||
* @param reachableModes (output). List of modes that can be reached by
|
||||
* selecing more references. Is a map, where key is the mode that can be
|
||||
* reached and value is a list of reference sequences that can be added to
|
||||
* reach the mode (stuff already linked is omitted from these lists; only
|
||||
* extra links needed are listed)
|
||||
* @param result (output). Returns results of suggestion, such as best fit
|
||||
* mode, list of all modes that apply, hints, etc.
|
||||
*/
|
||||
virtual eMapMode listMapModes(eSuggestResult &msg,
|
||||
std::vector<eMapMode>* allApplicableModes = 0,
|
||||
std::set<eRefType>* nextRefTypeHint = 0,
|
||||
std::map<eMapMode, refTypeStringList> *reachableModes = 0) const;
|
||||
|
||||
/**
|
||||
* @brief getHint function returns a set of types that user can add to
|
||||
* references to arrive to combinations valid for some modes. This function
|
||||
* is a shoutcut to listMapModes.
|
||||
*
|
||||
* @return a set of selection types that can be appended to the support.
|
||||
*
|
||||
* Subclassing: This function works out of the box via a call to
|
||||
* listMapModes, so there is no need to reimplement it.
|
||||
*/
|
||||
virtual const std::set<eRefType> getHint(bool forCurrentModeOnly) const;
|
||||
virtual void suggestMapModes(SuggestResult &result) const;
|
||||
|
||||
/**
|
||||
* @brief EnableAllModes enables all modes that have shape type lists filled. The function acts on modeEnabled array.
|
||||
|
|
|
@ -313,9 +313,9 @@ QString getShapeTypeText(eRefType type)
|
|||
|
||||
QStringList getRefListForMode(AttachEngine &attacher, eMapMode mmode)
|
||||
{
|
||||
AttachEngine::refTypeStringList list = attacher.modeRefTypes[mmode];
|
||||
refTypeStringList list = attacher.modeRefTypes[mmode];
|
||||
QStringList strlist;
|
||||
for(AttachEngine::refTypeString &rts : list){
|
||||
for(refTypeString &rts : list){
|
||||
QStringList buf;
|
||||
for(eRefType rt : rts){
|
||||
buf.append(getShapeTypeText(rt));
|
||||
|
|
|
@ -114,12 +114,12 @@ void UnifiedDatumCommand(Gui::Command &cmd, Base::Type type, std::string name)
|
|||
if (support.getSize() > 0) {
|
||||
Part::AttachableObject* pcDatum = static_cast<Part::AttachableObject*>(cmd.getDocument()->getObject(FeatName.c_str()));
|
||||
pcDatum->attacher().references.Paste(support);
|
||||
eSuggestResult msg;
|
||||
eMapMode suggMode = pcDatum->attacher().listMapModes(msg);
|
||||
if (msg == srOK) {
|
||||
SuggestResult sugr;
|
||||
pcDatum->attacher().suggestMapModes(sugr);
|
||||
if (sugr.message == Attacher::SuggestResult::srOK) {
|
||||
//fits some mode. Populate support property.
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.Support = %s",FeatName.c_str(),support.getPyReprString().c_str());
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",FeatName.c_str(),AttachEngine::eMapModeStrings[suggMode]);
|
||||
cmd.doCommand(Gui::Command::Doc,"App.activeDocument().%s.MapMode = '%s'",FeatName.c_str(),AttachEngine::getModeName(sugr.bestFitMode).c_str());
|
||||
} else {
|
||||
QMessageBox::information(Gui::getMainWindow(),QObject::tr("Invalid selection"), QObject::tr("There are no attachment modes that fit seleted objects. Select something else."));
|
||||
}
|
||||
|
|
|
@ -315,13 +315,12 @@ void TaskDatumParameters::updateUI(std::string message, bool error)
|
|||
completed = false;
|
||||
|
||||
// Get hints for further required references
|
||||
eSuggestResult msg;
|
||||
std::set<eRefType> hint;
|
||||
SuggestResult sugr;
|
||||
|
||||
pcDatum->attacher().listMapModes(msg,0,&hint);
|
||||
pcDatum->attacher().suggestMapModes(sugr);
|
||||
|
||||
if (msg != srOK) {
|
||||
if(hint.size() > 0)
|
||||
if (sugr.message != SuggestResult::srOK) {
|
||||
if(sugr.nextRefTypeHint.size() > 0)
|
||||
message = "Need more references";
|
||||
} else {
|
||||
completed = true;
|
||||
|
@ -344,10 +343,10 @@ void TaskDatumParameters::updateUI(std::string message, bool error)
|
|||
ui->labelAngle->setEnabled(true);
|
||||
ui->spinAngle->setEnabled(true);
|
||||
|
||||
QString hintText = makeHintText(hint);
|
||||
QString hintText = makeHintText(sugr.nextRefTypeHint);
|
||||
|
||||
// Check if we have all required references
|
||||
if (hint.size() == 0) {
|
||||
if (sugr.nextRefTypeHint.size() == 0) {
|
||||
ui->buttonRef2->setEnabled(numrefs >= 2);
|
||||
ui->lineRef2->setEnabled(numrefs >= 2);
|
||||
ui->buttonRef3->setEnabled(numrefs >= 3);
|
||||
|
@ -674,15 +673,15 @@ void TaskDatumParameters::updateListOfModes(eMapMode curMode)
|
|||
|
||||
//obtain list of available modes:
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
eMapMode suggMode = mmDeactivated;
|
||||
std::map<eMapMode, AttachEngine::refTypeStringList> reachableModes;
|
||||
SuggestResult sugr;
|
||||
sugr.bestFitMode = mmDeactivated;
|
||||
int lastValidModeItemIndex = mmDummy_NumberOfModes;
|
||||
if (pcDatum->Support.getSize() > 0){
|
||||
eSuggestResult msg;
|
||||
suggMode = pcDatum->attacher().listMapModes(msg, &modesInList, 0, &reachableModes);
|
||||
pcDatum->attacher().suggestMapModes(sugr);
|
||||
modesInList = sugr.allApplicableModes;
|
||||
//add reachable modes to the list, too, but gray them out (using lastValidModeItemIndex, later)
|
||||
lastValidModeItemIndex = modesInList.size()-1;
|
||||
for(std::pair<const eMapMode, AttachEngine::refTypeStringList> &rm: reachableModes){
|
||||
for(std::pair<const eMapMode, refTypeStringList> &rm: sugr.reachableModes){
|
||||
modesInList.push_back(rm.first);
|
||||
}
|
||||
} else {
|
||||
|
@ -713,7 +712,7 @@ void TaskDatumParameters::updateListOfModes(eMapMode curMode)
|
|||
//potential mode - can be reached by selecting more stuff
|
||||
item->setFlags(item->flags() & ~(Qt::ItemFlag::ItemIsEnabled | Qt::ItemFlag::ItemIsSelectable));
|
||||
|
||||
AttachEngine::refTypeStringList &extraRefs = reachableModes[mmode];
|
||||
refTypeStringList &extraRefs = sugr.reachableModes[mmode];
|
||||
if (extraRefs.size() == 1){
|
||||
QStringList buf;
|
||||
for(eRefType rt : extraRefs[0]){
|
||||
|
@ -726,7 +725,7 @@ void TaskDatumParameters::updateListOfModes(eMapMode curMode)
|
|||
} else {
|
||||
item->setText(tr("%1 (add more references)").arg(item->text()));
|
||||
}
|
||||
} else if (mmode == suggMode){
|
||||
} else if (mmode == sugr.bestFitMode){
|
||||
//suggested mode - make bold
|
||||
assert (item);
|
||||
QFont fnt = item->font();
|
||||
|
@ -750,10 +749,10 @@ Attacher::eMapMode TaskDatumParameters::getActiveMapMode()
|
|||
return modesInList[ui->listOfModes->row(sel[0])];
|
||||
else {
|
||||
Part::Datum* pcDatum = static_cast<Part::Datum*>(DatumView->getObject());
|
||||
eSuggestResult msg;
|
||||
eMapMode suggMode = pcDatum->attacher().listMapModes(msg);
|
||||
if (msg == srOK)
|
||||
return suggMode;
|
||||
SuggestResult sugr;
|
||||
pcDatum->attacher().suggestMapModes(sugr);
|
||||
if (sugr.message == SuggestResult::srOK)
|
||||
return sugr.bestFitMode;
|
||||
else
|
||||
return mmDeactivated;
|
||||
};
|
||||
|
|
|
@ -79,14 +79,14 @@ namespace SketcherGui {
|
|||
};
|
||||
|
||||
|
||||
Attacher::eMapMode SuggestAutoMapMode(Attacher::eSuggestResult* pMsgId = 0,
|
||||
Attacher::eMapMode SuggestAutoMapMode(Attacher::SuggestResult::eSuggestResult* pMsgId = 0,
|
||||
QString* message = 0,
|
||||
std::vector<Attacher::eMapMode>* allmodes = 0){
|
||||
//convert pointers into valid references, to avoid checking for null pointers everywhere
|
||||
Attacher::eSuggestResult buf;
|
||||
Attacher::SuggestResult::eSuggestResult buf;
|
||||
if (pMsgId == 0)
|
||||
pMsgId = &buf;
|
||||
Attacher::eSuggestResult &msg = *pMsgId;
|
||||
Attacher::SuggestResult::eSuggestResult &msg = *pMsgId;
|
||||
QString buf2;
|
||||
if (message == 0)
|
||||
message = &buf2;
|
||||
|
@ -95,23 +95,26 @@ namespace SketcherGui {
|
|||
App::PropertyLinkSubList tmpSupport;
|
||||
Gui::Selection().getAsPropertyLinkSubList(tmpSupport);
|
||||
|
||||
Attacher::SuggestResult sugr;
|
||||
AttachEngine3D eng;
|
||||
eng.setUp(tmpSupport);
|
||||
Attacher::eMapMode ret;
|
||||
ret = eng.listMapModes(msg, allmodes);
|
||||
eng.suggestMapModes(sugr);
|
||||
if (allmodes)
|
||||
*allmodes = sugr.allApplicableModes;
|
||||
msg = sugr.message;
|
||||
switch(msg){
|
||||
case Attacher::srOK:
|
||||
case Attacher::SuggestResult::srOK:
|
||||
break;
|
||||
case Attacher::srNoModesFit:
|
||||
case Attacher::SuggestResult::srNoModesFit:
|
||||
msg_str = QObject::tr("There are no modes that accept the selected set of subelements");
|
||||
break;
|
||||
case Attacher::srLinkBroken:
|
||||
case Attacher::SuggestResult::srLinkBroken:
|
||||
msg_str = QObject::tr("Broken link to support subelements");
|
||||
break;
|
||||
case Attacher::srUnexpectedError:
|
||||
case Attacher::SuggestResult::srUnexpectedError:
|
||||
msg_str = QObject::tr("Unexpected error");
|
||||
break;
|
||||
case Attacher::srIncompatibleGeometry:
|
||||
case Attacher::SuggestResult::srIncompatibleGeometry:
|
||||
if(tmpSupport.getSubValues()[0].substr(0,4) == std::string("Face"))
|
||||
msg_str = QObject::tr("Face is non-planar");
|
||||
else
|
||||
|
@ -122,7 +125,7 @@ namespace SketcherGui {
|
|||
assert(0/*no message for eSuggestResult enum item*/);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return sugr.bestFitMode;
|
||||
}
|
||||
} //namespace SketcherGui
|
||||
|
||||
|
@ -147,13 +150,13 @@ void CmdSketcherNewSketch::activated(int iMsg)
|
|||
Attacher::eMapMode mapmode = Attacher::mmDeactivated;
|
||||
bool bAttach = false;
|
||||
if (Gui::Selection().hasSelection()){
|
||||
Attacher::eSuggestResult msgid = Attacher::srOK;
|
||||
Attacher::SuggestResult::eSuggestResult msgid = Attacher::SuggestResult::srOK;
|
||||
QString msg_str;
|
||||
std::vector<Attacher::eMapMode> validModes;
|
||||
mapmode = SuggestAutoMapMode(&msgid, &msg_str, &validModes);
|
||||
if (msgid == Attacher::srOK)
|
||||
if (msgid == Attacher::SuggestResult::srOK)
|
||||
bAttach = true;
|
||||
if (msgid != Attacher::srOK && msgid != Attacher::srNoModesFit){
|
||||
if (msgid != Attacher::SuggestResult::srOK && msgid != Attacher::SuggestResult::srNoModesFit){
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
QObject::tr("Sketch mapping"),
|
||||
QObject::tr("Can't map the skecth to selected object. %1.").arg(msg_str));
|
||||
|
@ -166,7 +169,7 @@ void CmdSketcherNewSketch::activated(int iMsg)
|
|||
items.push_back(QObject::tr("Don't attach"));
|
||||
int iSugg = 0;//index of the auto-suggested mode in the list of valid modes
|
||||
for (size_t i = 0 ; i < validModes.size() ; ++i){
|
||||
items.push_back(QString::fromLatin1(AttachEngine::eMapModeStrings[validModes[i]]));
|
||||
items.push_back(QString::fromLatin1(AttachEngine::getModeName(validModes[i]).c_str()));
|
||||
if (validModes[i] == mapmode)
|
||||
iSugg = items.size()-1;
|
||||
}
|
||||
|
@ -447,7 +450,7 @@ void CmdSketcherMapSketch::activated(int iMsg)
|
|||
std::vector<Attacher::eMapMode> validModes;
|
||||
|
||||
//check that selection is valid for at least some mapping mode.
|
||||
Attacher::eSuggestResult msgid = Attacher::srOK;
|
||||
Attacher::SuggestResult::eSuggestResult msgid = Attacher::SuggestResult::srOK;
|
||||
suggMapMode = SuggestAutoMapMode(&msgid, &msg_str, &validModes);
|
||||
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
|
|
Loading…
Reference in New Issue
Block a user