Skip to content

Commit

Permalink
Attacher: change suggestion routine interface
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
DeepSOIC authored and wwmayer committed May 7, 2016
1 parent 9d19bf0 commit 505ec6a
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 117 deletions.
51 changes: 17 additions & 34 deletions src/Mod/Part/App/Attacher.cpp
Expand Up @@ -258,47 +258,40 @@ 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;
std::vector<TopoDS_Shape> shapeStorage;
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;
Expand Down Expand Up @@ -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){
Expand All @@ -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()
Expand Down
107 changes: 64 additions & 43 deletions src/Mod/Part/App/Attacher.h
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -214,43 +263,15 @@ class PartExport AttachEngine : public Base::BaseClass
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)
*/
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.
* @param result (output). Returns results of suggestion, such as best fit
* mode, list of all modes that apply, hints, etc.
*/
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.
Expand Down
4 changes: 2 additions & 2 deletions src/Mod/Part/Gui/AttacherTexts.cpp
Expand Up @@ -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));
Expand Down
8 changes: 4 additions & 4 deletions src/Mod/PartDesign/Gui/Command.cpp
Expand Up @@ -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."));
}
Expand Down
35 changes: 17 additions & 18 deletions src/Mod/PartDesign/Gui/TaskDatumParameters.cpp
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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]){
Expand All @@ -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();
Expand All @@ -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;
};
Expand Down

0 comments on commit 505ec6a

Please sign in to comment.