I want to use Hoops for picking. When the mouse selects a line/face, they should be highlighted. When clicked again, the highlight should be canceled. I tried using the following code:
class SandboxHighlightOperator : public HPS::SelectOperator {
public:
SandboxHighlightOperator(HPSWidget* widget);
virtual ~SandboxHighlightOperator();
virtual HPS::UTF8 GetName() const { return "Qt_SandboxHighlightOperator"; }
bool OnMouseDown(HPS::MouseState const& in_state) override;
bool OnMouseUp(HPS::MouseState const& in_state) override;
bool OnMouseMove(const HPS::MouseState& in_state) override;
static ::HPS::Selection::Level SelectionLevel;
void Unhighlight();
private:
void HighlightCommon();
private:
HPSWidget* mainWidget;
bool m_isMove = false;
HPS::MouseState m_mouseUpState;
std::vector<HPS::SelectionItem> m_selectItems; // edge face
};
#include "SandboxHighlightOp.h"
#include "HPSWidget.h"
#include <hps.h>
#include <QDebug>
SandboxHighlightOperator::SandboxHighlightOperator(HPSWidget* widget)
: HPS::SelectOperator(HPS::MouseButtons::ButtonLeft(), HPS::ModifierKeys())
, mainWidget(widget)
{
}
SandboxHighlightOperator::~SandboxHighlightOperator() { }
bool SandboxHighlightOperator::OnMouseDown(HPS::MouseState const& in_state)
{
m_isMove = false;
m_mouseUpState = in_state;
return false;
}
bool SandboxHighlightOperator::OnMouseMove(const HPS::MouseState& in_state)
{
m_isMove = true;
// setHoverHighLight(in_state);
return Operator::OnMouseMove(in_state);
}
bool SandboxHighlightOperator::OnMouseUp(const HPS::MouseState& in_state)
{
if (!m_isMove) {
if (IsMouseTriggered(m_mouseUpState) && HPS::SelectOperator::OnMouseDown(m_mouseUpState)) {
HighlightCommon();
m_mouseUpState = HPS::MouseState();
m_isMove = false;
return true;
}
}
m_mouseUpState = HPS::MouseState();
m_isMove = false;
return Operator::OnMouseUp(in_state);
}
void SandboxHighlightOperator::HighlightCommon()
{
HPS::SelectionResults selection_results = GetActiveSelection();
size_t selected_count = selection_results.GetCount();
if (selected_count > 0) {
HPS::CADModel cad_model = mainWidget->getCADModel();
HPS::HighlightOptionsKit highlight_options(HPS::HighlightOptionsKit::GetDefault());
highlight_options.SetStyleName("highlight_style");
highlight_options.SetSubentityHighlighting(false);
highlight_options.SetOverlay(HPS::Drawing::Overlay::InPlace);
if (!cad_model.Empty()) {
HPS::SelectionResultsIterator it = selection_results.GetIterator();
HPS::SelectionItem item = it.GetItem();
HPS::Canvas canvas = *mainWidget->getCanvas();
HPS::ComponentPath component_path = cad_model.GetComponentPath(item);
int index = -1;
for (int i = 0; i < m_selectItems.size(); ++i) {
HPS::SelectionItem newItem = m_selectItems[i];
if (newItem.GetClassID() == item.GetClassID()) {
index = i;
}
qDebug() << i << index << newItem.GetInstanceID() << newItem.GetClassID() << item.GetClassID();
}
// auto iter = std::find_if(m_selectItems.begin(), m_selectItems.end(),
// [&item](const HPS::SelectionItem& si) { return si.GetClassID() == item.GetClassID(); });
if (index != -1) {
auto iter1 = m_selectItems.begin() + index;
component_path.Unhighlight(canvas, highlight_options);
qDebug() << "remove" << iter1->GetInstanceID() << iter1->GetClassID();
m_selectItems.erase(iter1);
} else {
component_path.Highlight(canvas, highlight_options);
const HPS::SelectionItem& newItem = item;
m_selectItems.push_back(newItem);
qDebug() << "add2" << item.GetInstanceID() << item.GetClassID();
}
qDebug() << "===============================================2";
}
}
mainWidget->getCanvas()->Update();
}
void SandboxHighlightOperator::Unhighlight()
{
HPS::HighlightOptionsKit highlightOptions;
highlightOptions.SetStyleName("highlight_style").SetNotification(true);
mainWidget->getCanvas()->GetWindowKey().GetHighlightControl().Unhighlight(highlightOptions);
HPS::EventDispatcher dispatcher = HPS::Database::GetEventDispatcher();
dispatcher.InjectEvent(HPS::HighlightEvent(HPS::HighlightEvent::Action::Unhighlight, HPS::SelectionResults(), highlightOptions));
dispatcher.InjectEvent(HPS::ComponentHighlightEvent(HPS::ComponentHighlightEvent::Action::Unhighlight, *mainWidget->getCanvas(), 0, HPS::ComponentPath(), highlightOptions));
}
When testing, I encountered the following issues:
-
Highlighting and unhighlighting sometimes work and sometimes don’t. I don’t understand why.
-
I use the following code for highlighting and unhighlighting operations:
int index = -1;
for (int i = 0; i < m_selectItems.size(); ++i) {
HPS::SelectionItem newItem = m_selectItems[i];
if (newItem.GetClassID() == item.GetClassID()) {
index = i;
}
qDebug() << i << index << newItem.GetInstanceID() << newItem.GetClassID() << item.GetClassID();
}
if (index != -1) {
auto iter1 = m_selectItems.begin() + index;
component_path.Unhighlight(canvas, highlight_options);
qDebug() << "remove" << iter1->GetInstanceID() << iter1->GetClassID();
m_selectItems.erase(iter1);
} else {
component_path.Highlight(canvas, highlight_options);
const HPS::SelectionItem& newItem = item;
m_selectItems.push_back(newItem);
qDebug() << "add2" << item.GetInstanceID() << item.GetClassID();
}
I can only determine if this SelectionItem is already saved in std::vectorHPS::SelectionItem based on GetClassID, while GetInstanceID changes every time, and I don’t know why.
In the for loop, I can find the corresponding index, but in the subsequent if (index != -1), the GetClassID of iter1 is different from the GetClassID in the for loop, which I also fail to understand.
I’m not sure if my approach is correct, or if there are other ways to implement this.