Skip to content

Commit

Permalink
ReverseEngineering: implement mesh segmentation workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer authored and berndhahnebach committed Mar 3, 2020
1 parent 432ae7c commit 8b3c311
Show file tree
Hide file tree
Showing 8 changed files with 603 additions and 8 deletions.
38 changes: 38 additions & 0 deletions src/Mod/Mesh/App/Core/Segmentation.cpp
Expand Up @@ -171,6 +171,21 @@ float PlaneSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
return fitter->GetDistanceToPlane(pnt);
}

Base::Vector3f PlaneSurfaceFit::Project(const Base::Vector3f& pt) const
{
Base::Vector3f prj(pt);
if (!fitter) {
prj.ProjectToPlane(basepoint, normal);
}
else {
Base::Vector3f base = fitter->GetBase();
Base::Vector3f norm = fitter->GetNormal();
prj.ProjectToPlane(base, norm);
}

return prj;
}

// --------------------------------------------------------

CylinderSurfaceFit::CylinderSurfaceFit()
Expand Down Expand Up @@ -257,6 +272,12 @@ float CylinderSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
return (dist - radius);
}

Base::Vector3f CylinderSurfaceFit::Project(const Base::Vector3f& pt) const
{
//TODO
return pt;
}

// --------------------------------------------------------

SphereSurfaceFit::SphereSurfaceFit()
Expand Down Expand Up @@ -332,6 +353,12 @@ float SphereSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
return (dist - radius);
}

Base::Vector3f SphereSurfaceFit::Project(const Base::Vector3f& pt) const
{
//TODO
return pt;
}

// --------------------------------------------------------

MeshDistanceGenericSurfaceFitSegment::MeshDistanceGenericSurfaceFitSegment(AbstractSurfaceFit* fit,
Expand Down Expand Up @@ -383,6 +410,17 @@ void MeshDistanceGenericSurfaceFitSegment::AddFacet(const MeshFacet& face)
fitter->AddTriangle(triangle);
}

std::vector<Base::Vector3f> MeshDistanceGenericSurfaceFitSegment::Project(const std::vector<Base::Vector3f>& pts) const
{
std::vector<Base::Vector3f> prj;
prj.reserve(pts.size());
for (const auto it : pts) {
prj.push_back(fitter->Project(it));
}

return prj;
}

// --------------------------------------------------------

bool MeshCurvaturePlanarSegment::TestFacet (const MeshFacet &rclFacet) const
Expand Down
5 changes: 5 additions & 0 deletions src/Mod/Mesh/App/Core/Segmentation.h
Expand Up @@ -99,6 +99,7 @@ class MeshExport AbstractSurfaceFit
virtual bool Done() const = 0;
virtual float Fit() = 0;
virtual float GetDistanceToSurface(const Base::Vector3f&) const = 0;
virtual Base::Vector3f Project(const Base::Vector3f&) const = 0;
};

class MeshExport PlaneSurfaceFit : public AbstractSurfaceFit
Expand All @@ -114,6 +115,7 @@ class MeshExport PlaneSurfaceFit : public AbstractSurfaceFit
bool Done() const;
float Fit();
float GetDistanceToSurface(const Base::Vector3f&) const;
Base::Vector3f Project(const Base::Vector3f&) const;

private:
Base::Vector3f basepoint;
Expand All @@ -134,6 +136,7 @@ class MeshExport CylinderSurfaceFit : public AbstractSurfaceFit
bool Done() const;
float Fit();
float GetDistanceToSurface(const Base::Vector3f&) const;
Base::Vector3f Project(const Base::Vector3f&) const;

private:
Base::Vector3f basepoint;
Expand All @@ -155,6 +158,7 @@ class MeshExport SphereSurfaceFit : public AbstractSurfaceFit
bool Done() const;
float Fit();
float GetDistanceToSurface(const Base::Vector3f&) const;
Base::Vector3f Project(const Base::Vector3f&) const;

private:
Base::Vector3f center;
Expand All @@ -173,6 +177,7 @@ class MeshExport MeshDistanceGenericSurfaceFitSegment : public MeshDistanceSurfa
void Initialize(unsigned long);
bool TestInitialFacet(unsigned long) const;
void AddFacet(const MeshFacet& rclFacet);
std::vector<Base::Vector3f> Project(const std::vector<Base::Vector3f>&) const;

protected:
AbstractSurfaceFit* fitter;
Expand Down
4 changes: 4 additions & 0 deletions src/Mod/ReverseEngineering/Gui/CMakeLists.txt
Expand Up @@ -31,13 +31,15 @@ endif()
set(ReenGui_MOC_HDRS
FitBSplineSurface.h
Poisson.h
Segmentation.h
)
fc_wrap_cpp(ReenGui_MOC_SRCS ${ReenGui_MOC_HDRS})
SOURCE_GROUP("Moc" FILES ${ReenGui_MOC_SRCS})

set(Dialogs_UIC_SRCS
FitBSplineSurface.ui
Poisson.ui
Segmentation.ui
)

if(BUILD_QT5)
Expand All @@ -53,6 +55,8 @@ SET(Dialogs_SRCS
FitBSplineSurface.h
Poisson.cpp
Poisson.h
Segmentation.cpp
Segmentation.h
)
SOURCE_GROUP("Dialogs" FILES ${Dialogs_SRCS})

Expand Down
91 changes: 91 additions & 0 deletions src/Mod/ReverseEngineering/Gui/Command.cpp
Expand Up @@ -25,6 +25,9 @@
#ifndef _PreComp_
# include <QApplication>
# include <QMessageBox>
# include <BRep_Builder.hxx>
# include <BRepBuilderAPI_MakePolygon.hxx>
# include <TopoDS_Compound.hxx>
#endif

#include <sstream>
Expand All @@ -34,7 +37,9 @@
#include <Mod/Points/App/Structured.h>
#include <Mod/Mesh/App/MeshFeature.h>
#include <Mod/Mesh/App/Core/Approximation.h>
#include <Mod/Mesh/App/Core/Algorithm.h>

#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
Expand All @@ -47,6 +52,7 @@
#include "../App/ApproxSurface.h"
#include "FitBSplineSurface.h"
#include "Poisson.h"
#include "Segmentation.h"

using namespace std;

Expand Down Expand Up @@ -186,6 +192,89 @@ bool CmdApproxPlane::isActive(void)
return false;
}

DEF_STD_CMD_A(CmdSegmentation)

CmdSegmentation::CmdSegmentation()
: Command("Reen_Segmentation")
{
sAppModule = "Reen";
sGroup = QT_TR_NOOP("Reverse Engineering");
sMenuText = QT_TR_NOOP("Create mesh segments...");
sToolTipText = QT_TR_NOOP("Create mesh segments");
sWhatsThis = "Reen_Segmentation";
sStatusTip = sToolTipText;
}

void CmdSegmentation::activated(int)
{
std::vector<Mesh::Feature*> objs = Gui::Selection().getObjectsOfType<Mesh::Feature>();
Mesh::Feature* mesh = static_cast<Mesh::Feature*>(objs.front());
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
if (!dlg) {
dlg = new ReverseEngineeringGui::TaskSegmentation(mesh);
}
Gui::Control().showDialog(dlg);
}

bool CmdSegmentation::isActive(void)
{
if (Gui::Control().activeDialog())
return false;
return Gui::Selection().countObjectsOfType
(Mesh::Feature::getClassTypeId()) == 1;
}

DEF_STD_CMD_A(CmdMeshBoundary)

CmdMeshBoundary::CmdMeshBoundary()
: Command("Reen_MeshBoundary")
{
sAppModule = "Reen";
sGroup = QT_TR_NOOP("Reverse Engineering");
sMenuText = QT_TR_NOOP("Wire from mesh...");
sToolTipText = QT_TR_NOOP("Create wire from mesh");
sWhatsThis = "Reen_Segmentation";
sStatusTip = sToolTipText;
}

void CmdMeshBoundary::activated(int)
{
std::vector<Mesh::Feature*> objs = Gui::Selection().getObjectsOfType<Mesh::Feature>();
App::Document* document = App::GetApplication().getActiveDocument();
document->openTransaction("Wire from mesh");
for (auto it : objs) {
const Mesh::MeshObject& mesh = it->Mesh.getValue();
std::list<std::vector<Base::Vector3f> > bounds;
MeshCore::MeshAlgorithm algo(mesh.getKernel());
algo.GetMeshBorders(bounds);

BRep_Builder builder;
TopoDS_Compound compound;
builder.MakeCompound(compound);

for (auto bt = bounds.begin(); bt != bounds.end(); ++bt) {
BRepBuilderAPI_MakePolygon mkPoly;
for (std::vector<Base::Vector3f>::reverse_iterator it = bt->rbegin(); it != bt->rend(); ++it) {
mkPoly.Add(gp_Pnt(it->x,it->y,it->z));
}
if (mkPoly.IsDone()) {
builder.Add(compound, mkPoly.Wire());
}
}

Part::Feature* shapeFea = static_cast<Part::Feature*>(document->addObject("Part::Feature", "Wires from mesh"));
shapeFea->Shape.setValue(compound);

}
document->commitTransaction();
}

bool CmdMeshBoundary::isActive(void)
{
return Gui::Selection().countObjectsOfType
(Mesh::Feature::getClassTypeId()) > 0;
}

DEF_STD_CMD_A(CmdPoissonReconstruction)

CmdPoissonReconstruction::CmdPoissonReconstruction()
Expand Down Expand Up @@ -277,6 +366,8 @@ void CreateReverseEngineeringCommands(void)
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
rcCmdMgr.addCommand(new CmdApproxSurface());
rcCmdMgr.addCommand(new CmdApproxPlane());
rcCmdMgr.addCommand(new CmdSegmentation());
rcCmdMgr.addCommand(new CmdMeshBoundary());
rcCmdMgr.addCommand(new CmdPoissonReconstruction());
rcCmdMgr.addCommand(new CmdViewTriangulation());
}

0 comments on commit 8b3c311

Please sign in to comment.