From b83d8fce5ef9672a4fd13665b50043cb1cb9a51c Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 8 May 2020 19:19:29 +0200 Subject: [PATCH] ReverseEngineering: improve manual segmentation --- .../Gui/SegmentationManual.cpp | 120 ++++++++++++ .../Gui/SegmentationManual.h | 6 + .../Gui/SegmentationManual.ui | 181 +++++++++++++++++- 3 files changed, 304 insertions(+), 3 deletions(-) diff --git a/src/Mod/ReverseEngineering/Gui/SegmentationManual.cpp b/src/Mod/ReverseEngineering/Gui/SegmentationManual.cpp index 6b9f93db44..1e15bb51c5 100644 --- a/src/Mod/ReverseEngineering/Gui/SegmentationManual.cpp +++ b/src/Mod/ReverseEngineering/Gui/SegmentationManual.cpp @@ -41,6 +41,7 @@ #include #include #include +#include using namespace ReverseEngineeringGui; @@ -110,6 +111,119 @@ void SegmentationManual::on_cbSelectComp_toggled(bool on) meshSel.setAddComponentOnClick(on); } +class SegmentationManual::Private { +public: +static void findGeometry(int minFaces, double tolerance, + std::function&, + const std::vector&)> fitFunc) +{ + Gui::Document* gdoc = Gui::Application::Instance->activeDocument(); + if (!gdoc) + return; + + App::Document* adoc = gdoc->getDocument(); + std::vector meshes = adoc->getObjectsOfType(); + for (auto it : meshes) { + MeshGui::ViewProviderMesh* vpm = static_cast(gdoc->getViewProvider(it)); + const Mesh::MeshObject& mesh = it->Mesh.getValue(); + + if (mesh.hasSelectedFacets()) { + const MeshCore::MeshKernel& kernel = mesh.getKernel(); + + std::vector facets, vertexes; + mesh.getFacetsFromSelection(facets); + vertexes = mesh.getPointsFromFacets(facets); + MeshCore::MeshPointArray coords = kernel.GetPoints(vertexes); + + std::vector 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 segm; + segm.emplace_back(new MeshCore::MeshDistanceGenericSurfaceFitSegment + (surfFit, kernel, minFaces, tolerance)); + finder.FindSegments(segm); + + for (auto segmIt : segm) { + const std::vector& data = segmIt->GetSegments(); + for (const auto dataIt : data) { + vpm->addSelection(dataIt); + } + } + } + } + } +} +}; + +void SegmentationManual::on_planeDetect_clicked() +{ + auto func = [=](const std::vector& points, + const std::vector& normal) -> MeshCore::AbstractSurfaceFit* { + Q_UNUSED(normal) + + MeshCore::PlaneFit fit; + fit.AddPoints(points); + if (fit.Fit() < 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::on_cylinderDetect_clicked() +{ + auto func = [=](const std::vector& points, + const std::vector& 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() < 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::on_sphereDetect_clicked() +{ + auto func = [=](const std::vector& points, + const std::vector& normal) -> MeshCore::AbstractSurfaceFit* { + Q_UNUSED(normal) + + MeshCore::SphereFit fit; + fit.AddPoints(points); + if (fit.Fit() < 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(); @@ -138,6 +252,12 @@ void SegmentationManual::createSegment() Mesh::MeshObject* feaMesh = feaSegm->Mesh.startEditing(); feaMesh->swap(*segment); feaSegm->Mesh.finishEditing(); + + if (ui->checkBoxCutSegm->isChecked()) { + Mesh::MeshObject* editmesh = it->Mesh.startEditing(); + editmesh->deleteFacets(facets); + it->Mesh.finishEditing(); + } } } diff --git a/src/Mod/ReverseEngineering/Gui/SegmentationManual.h b/src/Mod/ReverseEngineering/Gui/SegmentationManual.h index b1acda693d..2105459615 100644 --- a/src/Mod/ReverseEngineering/Gui/SegmentationManual.h +++ b/src/Mod/ReverseEngineering/Gui/SegmentationManual.h @@ -57,10 +57,16 @@ public Q_SLOTS: void on_visibleTriangles_toggled(bool); void on_screenTriangles_toggled(bool); void on_cbSelectComp_toggled(bool); + void on_planeDetect_clicked(); + void on_cylinderDetect_clicked(); + void on_sphereDetect_clicked(); protected: void changeEvent(QEvent *e); +private: + class Private; + private: std::unique_ptr ui; MeshGui::MeshSelection meshSel; diff --git a/src/Mod/ReverseEngineering/Gui/SegmentationManual.ui b/src/Mod/ReverseEngineering/Gui/SegmentationManual.ui index 0300c15936..7759a5709f 100644 --- a/src/Mod/ReverseEngineering/Gui/SegmentationManual.ui +++ b/src/Mod/ReverseEngineering/Gui/SegmentationManual.ui @@ -7,13 +7,13 @@ 0 0 346 - 314 + 804 Manual segmentation - + @@ -117,11 +117,170 @@ + + + Plane + + + + + + Tolerance + + + + + + + 3 + + + 0.010000000000000 + + + 0.010000000000000 + + + + + + + Minimum number of faces + + + + + + + 100000 + + + 100 + + + + + + + Detect + + + + + + + + + + Cylinder + + + + + + Tolerance + + + + + + + 3 + + + 0.010000000000000 + + + 0.010000000000000 + + + + + + + Minimum number of faces + + + + + + + 100000 + + + 100 + + + + + + + Detect + + + + + + + + + + Sphere + + + + + + Tolerance + + + + + + + 3 + + + 0.010000000000000 + + + 0.010000000000000 + + + + + + + Minimum number of faces + + + + + + + 100000 + + + 100 + + + + + + + Detect + + + + + + + Region options - + @@ -145,6 +304,22 @@ + + + + Segmentation + + + + + + Cut segment from mesh + + + + + +