/*************************************************************************** * Copyright (c) 2013 Jürgen Riegel * * * * 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 #include #include #include #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "FemSelectionGate.h" #include "TaskCreateNodeSet.h" #include "ViewProviderFemMesh.h" #include "ui_TaskCreateNodeSet.h" using namespace FemGui; using namespace Gui; TaskCreateNodeSet::TaskCreateNodeSet(Fem::FemSetNodesObject* pcObject, QWidget* parent) : TaskBox(Gui::BitmapFactory().pixmap("FEM_CreateNodesSet"), tr("Nodes set"), true, parent) , pcObject(pcObject) , selectionMode(none) , ui(new Ui_TaskCreateNodeSet) { // we need a separate container widget to add all controls to proxy = new QWidget(this); ui->setupUi(proxy); QMetaObject::connectSlotsByName(this); this->groupLayout()->addWidget(proxy); QObject::connect(ui->toolButton_Poly, &QToolButton::clicked, this, &TaskCreateNodeSet::Poly); QObject::connect(ui->toolButton_Pick, &QToolButton::clicked, this, &TaskCreateNodeSet::Pick); QObject::connect(ui->comboBox, qOverload(&QComboBox::activated), this, &TaskCreateNodeSet::SwitchMethod); // check if the Link to the FemMesh is defined assert(pcObject->FemMesh.getValue()); MeshViewProvider = dynamic_cast(Gui::Application::Instance->getViewProvider( pcObject->FemMesh.getValue())); assert(MeshViewProvider); tempSet = pcObject->Nodes.getValues(); MeshViewProvider->setHighlightNodes(tempSet); ui->groupBox_AngleSearch->setEnabled(false); } void TaskCreateNodeSet::Poly() { Gui::Document* doc = Gui::Application::Instance->activeDocument(); Gui::MDIView* view = doc->getActiveView(); if (view->isDerivedFrom()) { Gui::View3DInventorViewer* viewer = ((Gui::View3DInventor*)view)->getViewer(); viewer->setEditing(true); viewer->startSelection(Gui::View3DInventorViewer::Clip); viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback, this); } } void TaskCreateNodeSet::Pick() { if (selectionMode == none) { selectionMode = PickElement; Gui::Selection().clearSelection(); Gui::Selection().addSelectionGate(new FemSelectionGate(FemSelectionGate::Element)); } } void TaskCreateNodeSet::SwitchMethod(int Value) { if (Value == 1) { ui->groupBox_AngleSearch->setEnabled(true); ui->toolButton_Pick->setEnabled(true); ui->toolButton_Poly->setEnabled(false); } else { ui->groupBox_AngleSearch->setEnabled(false); ui->toolButton_Pick->setEnabled(false); ui->toolButton_Poly->setEnabled(true); } } void TaskCreateNodeSet::DefineNodesCallback(void* ud, SoEventCallback* n) { // show the wait cursor because this could take quite some time Gui::WaitCursor wc; TaskCreateNodeSet* taskBox = static_cast(ud); // When this callback function is invoked we must in either case leave the edit mode Gui::View3DInventorViewer* view = static_cast(n->getUserData()); view->setEditing(false); view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineNodesCallback, ud); n->setHandled(); Gui::SelectionRole role; std::vector clPoly = view->getGLPolygon(&role); if (clPoly.size() < 3) { return; } if (clPoly.front() != clPoly.back()) { clPoly.push_back(clPoly.front()); } SoCamera* cam = view->getSoRenderManager()->getCamera(); SbViewVolume vv = cam->getViewVolume(); Gui::ViewVolumeProjection proj(vv); Base::Polygon2d polygon; for (auto it : clPoly) { polygon.Add(Base::Vector2d(it[0], it[1])); } taskBox->DefineNodes(polygon, proj, role == Gui::SelectionRole::Inner ? true : false); } void TaskCreateNodeSet::DefineNodes(const Base::Polygon2d& polygon, const Gui::ViewVolumeProjection& proj, bool inner) { const SMESHDS_Mesh* data = pcObject->FemMesh.getValue() ->FemMesh.getValue() .getSMesh() ->GetMeshDS(); SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator(); Base::Vector3f pt2d; if (!ui->checkBox_Add->isChecked()) { tempSet.clear(); } while (aNodeIter->more()) { const SMDS_MeshNode* aNode = aNodeIter->next(); Base::Vector3f vec(aNode->X(), aNode->Y(), aNode->Z()); pt2d = proj(vec); if (polygon.Contains(Base::Vector2d(pt2d.x, pt2d.y)) == inner) { tempSet.insert(aNode->GetID()); } } MeshViewProvider->setHighlightNodes(tempSet); } void TaskCreateNodeSet::onSelectionChanged(const Gui::SelectionChanges& msg) { if (selectionMode == none) { return; } if (msg.Type == Gui::SelectionChanges::AddSelection) { std::string subName(msg.pSubName); unsigned int i = 0; for (; i < subName.size(); i++) { if (msg.pSubName[i] == 'F') { break; } } int elem = atoi(subName.substr(4).c_str()); int face = atoi(subName.substr(i + 1).c_str()); tempSet.clear(); Base::Console().Message("Picked Element:%i Face:%i\n", elem, face); if (!ui->checkBox_Add->isChecked()) { std::set tmp = pcObject->FemMesh.getValue() ->FemMesh.getValue() .getSurfaceNodes(elem, face); tempSet.insert(tmp.begin(), tmp.end()); } else { tempSet = pcObject->FemMesh.getValue() ->FemMesh.getValue() .getSurfaceNodes(elem, face); } selectionMode = none; Gui::Selection().rmvSelectionGate(); MeshViewProvider->setHighlightNodes(tempSet); } } TaskCreateNodeSet::~TaskCreateNodeSet() { Gui::Selection().rmvSelectionGate(); } #include "moc_TaskCreateNodeSet.cpp"