| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include <QPushButton> |
| |
|
| |
|
| | #include <App/Document.h> |
| | #include <Gui/Application.h> |
| | #include <Gui/Document.h> |
| | #include <Gui/Selection/Selection.h> |
| | #include <Mod/Mesh/App/Core/Algorithm.h> |
| | #include <Mod/Mesh/App/Core/Approximation.h> |
| | #include <Mod/Mesh/App/Core/Segmentation.h> |
| | #include <Mod/Mesh/App/MeshFeature.h> |
| | #include <Mod/Mesh/Gui/ViewProvider.h> |
| |
|
| | #include "SegmentationManual.h" |
| | #include "ui_SegmentationManual.h" |
| |
|
| |
|
| | using namespace ReverseEngineeringGui; |
| |
|
| | SegmentationManual::SegmentationManual(QWidget* parent, Qt::WindowFlags fl) |
| | : QWidget(parent, fl) |
| | , ui(new Ui_SegmentationManual) |
| | { |
| | ui->setupUi(this); |
| | setupConnections(); |
| | ui->spSelectComp->setRange(1, std::numeric_limits<int>::max()); |
| | ui->spSelectComp->setValue(10); |
| |
|
| | Gui::Selection().clearSelection(); |
| | meshSel.setCheckOnlyVisibleTriangles(ui->visibleTriangles->isChecked()); |
| | meshSel.setCheckOnlyPointToUserTriangles(ui->screenTriangles->isChecked()); |
| | meshSel.setEnabledViewerSelection(false); |
| | } |
| |
|
| | SegmentationManual::~SegmentationManual() = default; |
| |
|
| | void SegmentationManual::setupConnections() |
| | { |
| | connect(ui->selectRegion, &QPushButton::clicked, this, &SegmentationManual::onSelectRegionClicked); |
| | connect(ui->selectAll, &QPushButton::clicked, this, &SegmentationManual::onSelectAllClicked); |
| | connect( |
| | ui->selectComponents, |
| | &QPushButton::clicked, |
| | this, |
| | &SegmentationManual::onSelectComponentsClicked |
| | ); |
| | connect(ui->selectTriangle, &QPushButton::clicked, this, &SegmentationManual::onSelectTriangleClicked); |
| | connect(ui->deselectAll, &QPushButton::clicked, this, &SegmentationManual::onDeselectAllClicked); |
| | connect(ui->visibleTriangles, &QCheckBox::toggled, this, &SegmentationManual::onVisibleTrianglesToggled); |
| | connect(ui->screenTriangles, &QCheckBox::toggled, this, &SegmentationManual::onScreenTrianglesToggled); |
| | connect(ui->cbSelectComp, &QCheckBox::toggled, this, &SegmentationManual::onSelectCompToggled); |
| | connect(ui->planeDetect, &QPushButton::clicked, this, &SegmentationManual::onPlaneDetectClicked); |
| | connect(ui->cylinderDetect, &QPushButton::clicked, this, &SegmentationManual::onCylinderDetectClicked); |
| | connect(ui->sphereDetect, &QPushButton::clicked, this, &SegmentationManual::onSphereDetectClicked); |
| | } |
| |
|
| | void SegmentationManual::changeEvent(QEvent* e) |
| | { |
| | if (e->type() == QEvent::LanguageChange) { |
| | ui->retranslateUi(this); |
| | } |
| | QWidget::changeEvent(e); |
| | } |
| |
|
| | void SegmentationManual::onSelectRegionClicked() |
| | { |
| | meshSel.startSelection(); |
| | } |
| |
|
| | void SegmentationManual::onSelectAllClicked() |
| | { |
| | |
| | meshSel.fullSelection(); |
| | } |
| |
|
| | void SegmentationManual::onDeselectAllClicked() |
| | { |
| | |
| | meshSel.clearSelection(); |
| | } |
| |
|
| | void SegmentationManual::onSelectComponentsClicked() |
| | { |
| | |
| | int size = ui->spSelectComp->value(); |
| | meshSel.selectComponent(size); |
| | } |
| |
|
| | void SegmentationManual::onVisibleTrianglesToggled(bool on) |
| | { |
| | meshSel.setCheckOnlyVisibleTriangles(on); |
| | } |
| |
|
| | void SegmentationManual::onScreenTrianglesToggled(bool on) |
| | { |
| | meshSel.setCheckOnlyPointToUserTriangles(on); |
| | } |
| |
|
| | void SegmentationManual::onSelectCompToggled(bool on) |
| | { |
| | meshSel.setAddComponentOnClick(on); |
| | } |
| |
|
| | class SegmentationManual::Private |
| | { |
| | public: |
| | static void findGeometry( |
| | int minFaces, |
| | double tolerance, |
| | std::function<MeshCore::AbstractSurfaceFit*( |
| | const std::vector<Base::Vector3f>&, |
| | const std::vector<Base::Vector3f>& |
| | )> fitFunc |
| | ) |
| | { |
| | Gui::Document* gdoc = Gui::Application::Instance->activeDocument(); |
| | if (!gdoc) { |
| | return; |
| | } |
| |
|
| | App::Document* adoc = gdoc->getDocument(); |
| | std::vector<Mesh::Feature*> meshes = adoc->getObjectsOfType<Mesh::Feature>(); |
| | for (auto it : meshes) { |
| | MeshGui::ViewProviderMesh* vpm = static_cast<MeshGui::ViewProviderMesh*>( |
| | gdoc->getViewProvider(it) |
| | ); |
| | const Mesh::MeshObject& mesh = it->Mesh.getValue(); |
| |
|
| | if (mesh.hasSelectedFacets()) { |
| | const MeshCore::MeshKernel& kernel = mesh.getKernel(); |
| |
|
| | std::vector<MeshCore::FacetIndex> facets; |
| | std::vector<MeshCore::PointIndex> vertexes; |
| | mesh.getFacetsFromSelection(facets); |
| | vertexes = mesh.getPointsFromFacets(facets); |
| | MeshCore::MeshPointArray coords = kernel.GetPoints(vertexes); |
| |
|
| | std::vector<Base::Vector3f> points, normals; |
| | normals = kernel.GetFacetNormals(facets); |
| | points.insert(points.end(), coords.begin(), coords.end()); |
| | coords.clear(); |
| |
|
| | MeshCore::AbstractSurfaceFit* surfFit = fitFunc(points, normals); |
| | if (surfFit) { |
| | MeshCore::MeshSegmentAlgorithm finder(kernel); |
| |
|
| | std::vector<MeshCore::MeshSurfaceSegmentPtr> segm; |
| | segm.emplace_back( |
| | std::make_shared<MeshCore::MeshDistanceGenericSurfaceFitSegment>( |
| | surfFit, |
| | kernel, |
| | minFaces, |
| | tolerance |
| | ) |
| | ); |
| | finder.FindSegments(segm); |
| |
|
| | for (const auto& segmIt : segm) { |
| | const std::vector<MeshCore::MeshSegment>& data = segmIt->GetSegments(); |
| | for (const auto& dataIt : data) { |
| | vpm->addSelection(dataIt); |
| | } |
| | } |
| | } |
| | } |
| | } |
| | } |
| | }; |
| |
|
| | void SegmentationManual::onPlaneDetectClicked() |
| | { |
| | auto func = [=](const std::vector<Base::Vector3f>& points, |
| | const std::vector<Base::Vector3f>& normal) -> MeshCore::AbstractSurfaceFit* { |
| | Q_UNUSED(normal) |
| |
|
| | MeshCore::PlaneFit fit; |
| | fit.AddPoints(points); |
| | if (fit.Fit() < std::numeric_limits<float>::max()) { |
| | Base::Vector3f base = fit.GetBase(); |
| | Base::Vector3f axis = fit.GetNormal(); |
| | return new MeshCore::PlaneSurfaceFit(base, axis); |
| | } |
| |
|
| | return nullptr; |
| | }; |
| | Private::findGeometry(ui->numPln->value(), ui->tolPln->value(), func); |
| | } |
| |
|
| | void SegmentationManual::onCylinderDetectClicked() |
| | { |
| | auto func = [=](const std::vector<Base::Vector3f>& points, |
| | const std::vector<Base::Vector3f>& normal) -> MeshCore::AbstractSurfaceFit* { |
| | Q_UNUSED(normal) |
| |
|
| | MeshCore::CylinderFit fit; |
| | fit.AddPoints(points); |
| | if (!normal.empty()) { |
| | Base::Vector3f base = fit.GetGravity(); |
| | Base::Vector3f axis = fit.GetInitialAxisFromNormals(normal); |
| | fit.SetInitialValues(base, axis); |
| | } |
| | if (fit.Fit() < std::numeric_limits<float>::max()) { |
| | Base::Vector3f base = fit.GetBase(); |
| | Base::Vector3f axis = fit.GetAxis(); |
| | float radius = fit.GetRadius(); |
| | return new MeshCore::CylinderSurfaceFit(base, axis, radius); |
| | } |
| |
|
| | return nullptr; |
| | }; |
| | Private::findGeometry(ui->numCyl->value(), ui->tolCyl->value(), func); |
| | } |
| |
|
| | void SegmentationManual::onSphereDetectClicked() |
| | { |
| | auto func = [=](const std::vector<Base::Vector3f>& points, |
| | const std::vector<Base::Vector3f>& normal) -> MeshCore::AbstractSurfaceFit* { |
| | Q_UNUSED(normal) |
| |
|
| | MeshCore::SphereFit fit; |
| | fit.AddPoints(points); |
| | if (fit.Fit() < std::numeric_limits<float>::max()) { |
| | Base::Vector3f base = fit.GetCenter(); |
| | float radius = fit.GetRadius(); |
| | return new MeshCore::SphereSurfaceFit(base, radius); |
| | } |
| |
|
| | return nullptr; |
| | }; |
| | Private::findGeometry(ui->numSph->value(), ui->tolSph->value(), func); |
| | } |
| |
|
| | void SegmentationManual::createSegment() |
| | { |
| | Gui::Document* gdoc = Gui::Application::Instance->activeDocument(); |
| | if (!gdoc) { |
| | return; |
| | } |
| | |
| | App::Document* adoc = gdoc->getDocument(); |
| | gdoc->openCommand(QT_TRANSLATE_NOOP("Command", "Segmentation")); |
| |
|
| | std::vector<Mesh::Feature*> meshes = adoc->getObjectsOfType<Mesh::Feature>(); |
| | bool selected = false; |
| | for (auto it : meshes) { |
| | const Mesh::MeshObject& mesh = it->Mesh.getValue(); |
| | const MeshCore::MeshKernel& kernel = mesh.getKernel(); |
| |
|
| | MeshCore::MeshAlgorithm algo(kernel); |
| | unsigned long ct = algo.CountFacetFlag(MeshCore::MeshFacet::SELECTED); |
| | if (ct > 0) { |
| | selected = true; |
| |
|
| | std::vector<MeshCore::FacetIndex> facets; |
| | algo.GetFacetsFlag(facets, MeshCore::MeshFacet::SELECTED); |
| |
|
| | std::unique_ptr<Mesh::MeshObject> segment(mesh.meshFromSegment(facets)); |
| | auto* feaSegm = adoc->addObject<Mesh::Feature>("Segment"); |
| | Mesh::MeshObject* feaMesh = feaSegm->Mesh.startEditing(); |
| | feaMesh->swap(*segment); |
| | feaMesh->clearFacetSelection(); |
| | feaSegm->Mesh.finishEditing(); |
| |
|
| | if (ui->checkBoxHideSegm->isChecked()) { |
| | feaSegm->Visibility.setValue(false); |
| | } |
| |
|
| | if (ui->checkBoxCutSegm->isChecked()) { |
| | Mesh::MeshObject* editmesh = it->Mesh.startEditing(); |
| | editmesh->deleteFacets(facets); |
| | it->Mesh.finishEditing(); |
| | } |
| | } |
| | } |
| |
|
| | if (!selected) { |
| | gdoc->abortCommand(); |
| | } |
| | else { |
| | gdoc->commitCommand(); |
| | } |
| | meshSel.clearSelection(); |
| | } |
| |
|
| | void SegmentationManual::onSelectTriangleClicked() |
| | { |
| | meshSel.selectTriangle(); |
| | meshSel.setAddComponentOnClick(ui->cbSelectComp->isChecked()); |
| | } |
| |
|
| | void SegmentationManual::reject() |
| | { |
| | |
| | meshSel.clearSelection(); |
| | meshSel.setEnabledViewerSelection(true); |
| | } |
| |
|
| | |
| |
|
| | |
| |
|
| | TaskSegmentationManual::TaskSegmentationManual() |
| | { |
| | widget = new SegmentationManual(); |
| | addTaskBox(widget, false); |
| | } |
| |
|
| | void TaskSegmentationManual::modifyStandardButtons(QDialogButtonBox* box) |
| | { |
| | QPushButton* btn = box->button(QDialogButtonBox::Ok); |
| | btn->setText(tr("Create")); |
| | } |
| |
|
| | bool TaskSegmentationManual::accept() |
| | { |
| | return false; |
| | } |
| |
|
| | void TaskSegmentationManual::clicked(int id) |
| | { |
| | if (id == QDialogButtonBox::Ok) { |
| | widget->createSegment(); |
| | } |
| | else if (id == QDialogButtonBox::Close) { |
| | widget->reject(); |
| | } |
| | } |
| |
|
| | #include "moc_SegmentationManual.cpp" |
| |
|