ReverseEngineering: improve mesh segmentation
This commit is contained in:
@@ -906,7 +906,7 @@ float CylinderFit::Fit()
|
||||
return FLOAT_MAX;
|
||||
_bIsFitted = true;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
std::vector<Wm4::Vector3d> input;
|
||||
std::transform(_vPoints.begin(), _vPoints.end(), std::back_inserter(input),
|
||||
[](const Base::Vector3f& v) { return Wm4::Vector3d(v.x, v.y, v.z); });
|
||||
|
||||
@@ -171,19 +171,23 @@ float PlaneSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
|
||||
return fitter->GetDistanceToPlane(pnt);
|
||||
}
|
||||
|
||||
Base::Vector3f PlaneSurfaceFit::Project(const Base::Vector3f& pt) const
|
||||
std::vector<float> PlaneSurfaceFit::Parameters() 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);
|
||||
Base::Vector3f base = basepoint;
|
||||
Base::Vector3f norm = normal;
|
||||
if (fitter) {
|
||||
base = fitter->GetBase();
|
||||
norm = fitter->GetNormal();
|
||||
}
|
||||
|
||||
return prj;
|
||||
std::vector<float> c;
|
||||
c.push_back(base.x);
|
||||
c.push_back(base.y);
|
||||
c.push_back(base.z);
|
||||
c.push_back(norm.x);
|
||||
c.push_back(norm.y);
|
||||
c.push_back(norm.z);
|
||||
return c;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -272,10 +276,26 @@ float CylinderSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
|
||||
return (dist - radius);
|
||||
}
|
||||
|
||||
Base::Vector3f CylinderSurfaceFit::Project(const Base::Vector3f& pt) const
|
||||
std::vector<float> CylinderSurfaceFit::Parameters() const
|
||||
{
|
||||
//TODO
|
||||
return pt;
|
||||
Base::Vector3f base = basepoint;
|
||||
Base::Vector3f norm = axis;
|
||||
float radval = radius;
|
||||
if (fitter) {
|
||||
base = fitter->GetBase();
|
||||
norm = fitter->GetAxis();
|
||||
radval = fitter->GetRadius();
|
||||
}
|
||||
|
||||
std::vector<float> c;
|
||||
c.push_back(base.x);
|
||||
c.push_back(base.y);
|
||||
c.push_back(base.z);
|
||||
c.push_back(norm.x);
|
||||
c.push_back(norm.y);
|
||||
c.push_back(norm.z);
|
||||
c.push_back(radval);
|
||||
return c;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -353,10 +373,21 @@ float SphereSurfaceFit::GetDistanceToSurface(const Base::Vector3f& pnt) const
|
||||
return (dist - radius);
|
||||
}
|
||||
|
||||
Base::Vector3f SphereSurfaceFit::Project(const Base::Vector3f& pt) const
|
||||
std::vector<float> SphereSurfaceFit::Parameters() const
|
||||
{
|
||||
//TODO
|
||||
return pt;
|
||||
Base::Vector3f base = center;
|
||||
float radval = radius;
|
||||
if (fitter) {
|
||||
base = fitter->GetCenter();
|
||||
radval = fitter->GetRadius();
|
||||
}
|
||||
|
||||
std::vector<float> c;
|
||||
c.push_back(base.x);
|
||||
c.push_back(base.y);
|
||||
c.push_back(base.z);
|
||||
c.push_back(radval);
|
||||
return c;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
@@ -410,15 +441,9 @@ void MeshDistanceGenericSurfaceFitSegment::AddFacet(const MeshFacet& face)
|
||||
fitter->AddTriangle(triangle);
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3f> MeshDistanceGenericSurfaceFitSegment::Project(const std::vector<Base::Vector3f>& pts) const
|
||||
std::vector<float> MeshDistanceGenericSurfaceFitSegment::Parameters() const
|
||||
{
|
||||
std::vector<Base::Vector3f> prj;
|
||||
prj.reserve(pts.size());
|
||||
for (const auto it : pts) {
|
||||
prj.push_back(fitter->Project(it));
|
||||
}
|
||||
|
||||
return prj;
|
||||
return fitter->Parameters();
|
||||
}
|
||||
|
||||
// --------------------------------------------------------
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
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;
|
||||
virtual std::vector<float> Parameters() const = 0;
|
||||
};
|
||||
|
||||
class MeshExport PlaneSurfaceFit : public AbstractSurfaceFit
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
bool Done() const;
|
||||
float Fit();
|
||||
float GetDistanceToSurface(const Base::Vector3f&) const;
|
||||
Base::Vector3f Project(const Base::Vector3f&) const;
|
||||
std::vector<float> Parameters() const;
|
||||
|
||||
private:
|
||||
Base::Vector3f basepoint;
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
bool Done() const;
|
||||
float Fit();
|
||||
float GetDistanceToSurface(const Base::Vector3f&) const;
|
||||
Base::Vector3f Project(const Base::Vector3f&) const;
|
||||
std::vector<float> Parameters() const;
|
||||
|
||||
private:
|
||||
Base::Vector3f basepoint;
|
||||
@@ -158,7 +158,7 @@ public:
|
||||
bool Done() const;
|
||||
float Fit();
|
||||
float GetDistanceToSurface(const Base::Vector3f&) const;
|
||||
Base::Vector3f Project(const Base::Vector3f&) const;
|
||||
std::vector<float> Parameters() const;
|
||||
|
||||
private:
|
||||
Base::Vector3f center;
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
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;
|
||||
std::vector<float> Parameters() const;
|
||||
|
||||
protected:
|
||||
AbstractSurfaceFit* fitter;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Interpreter.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Language/Translator.h>
|
||||
#include "Workbench.h"
|
||||
@@ -74,6 +75,15 @@ PyMOD_INIT_FUNC(ReverseEngineeringGui)
|
||||
PyMOD_Return(0);
|
||||
}
|
||||
|
||||
// load dependent module
|
||||
try {
|
||||
Base::Interpreter().loadModule("MeshGui");
|
||||
}
|
||||
catch(const Base::Exception& e) {
|
||||
PyErr_SetString(PyExc_ImportError, e.what());
|
||||
PyMOD_Return(0);
|
||||
}
|
||||
|
||||
PyObject* mod = ReverseEngineeringGui::initModule();
|
||||
Base::Console().Log("Loading GUI of ReverseEngineering module... done\n");
|
||||
|
||||
|
||||
@@ -34,11 +34,13 @@
|
||||
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/FaceMakerCheese.h>
|
||||
#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/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
@@ -98,7 +100,7 @@ CmdApproxPlane::CmdApproxPlane()
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Approximate plane...");
|
||||
sMenuText = QT_TR_NOOP("Plane...");
|
||||
sToolTipText = QT_TR_NOOP("Approximate a plane");
|
||||
sWhatsThis = "Reen_ApproxPlane";
|
||||
sStatusTip = sToolTipText;
|
||||
@@ -192,6 +194,104 @@ bool CmdApproxPlane::isActive(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdApproxCylinder)
|
||||
|
||||
CmdApproxCylinder::CmdApproxCylinder()
|
||||
: Command("Reen_ApproxCylinder")
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Cylinder");
|
||||
sToolTipText = QT_TR_NOOP("Approximate a cylinder");
|
||||
sWhatsThis = "Reen_ApproxCylinder";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
|
||||
void CmdApproxCylinder::activated(int)
|
||||
{
|
||||
std::vector<Mesh::Feature*> sel = getSelection().getObjectsOfType<Mesh::Feature>();
|
||||
openCommand("Fit cylinder");
|
||||
for (auto it : sel) {
|
||||
const Mesh::MeshObject& mesh = it->Mesh.getValue();
|
||||
const MeshCore::MeshKernel& kernel = mesh.getKernel();
|
||||
MeshCore::CylinderFit fit;
|
||||
fit.AddPoints(kernel.GetPoints());
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Rotation rot;
|
||||
rot.setValue(Base::Vector3d(0,0,1), Base::convertTo<Base::Vector3d>(fit.GetAxis()));
|
||||
double q0, q1, q2, q3;
|
||||
rot.getValue(q0, q1, q2, q3);
|
||||
|
||||
std::stringstream str;
|
||||
str << "from FreeCAD import Base" << std::endl;
|
||||
str << "App.ActiveDocument.addObject('Part::Cylinder','Cylinder_fit')" << std::endl;
|
||||
str << "App.ActiveDocument.ActiveObject.Radius = " << fit.GetRadius() << std::endl;
|
||||
str << "App.ActiveDocument.ActiveObject.Placement = Base.Placement("
|
||||
<< "Base.Vector(" << base.x << "," << base.y << "," << base.z << "),"
|
||||
<< "Base.Rotation(" << q0 << "," << q1 << "," << q2 << "," << q3 << "))" << std::endl;
|
||||
|
||||
runCommand(Gui::Command::Doc, str.str().c_str());
|
||||
}
|
||||
}
|
||||
commitCommand();
|
||||
updateActive();
|
||||
}
|
||||
|
||||
bool CmdApproxCylinder::isActive(void)
|
||||
{
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdApproxSphere)
|
||||
|
||||
CmdApproxSphere::CmdApproxSphere()
|
||||
: Command("Reen_ApproxSphere")
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Sphere");
|
||||
sToolTipText = QT_TR_NOOP("Approximate a sphere");
|
||||
sWhatsThis = "Reen_ApproxSphere";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
|
||||
void CmdApproxSphere::activated(int)
|
||||
{
|
||||
std::vector<Mesh::Feature*> sel = getSelection().getObjectsOfType<Mesh::Feature>();
|
||||
openCommand("Fit sphere");
|
||||
for (auto it : sel) {
|
||||
const Mesh::MeshObject& mesh = it->Mesh.getValue();
|
||||
const MeshCore::MeshKernel& kernel = mesh.getKernel();
|
||||
MeshCore::SphereFit fit;
|
||||
fit.AddPoints(kernel.GetPoints());
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetCenter();
|
||||
|
||||
std::stringstream str;
|
||||
str << "from FreeCAD import Base" << std::endl;
|
||||
str << "App.ActiveDocument.addObject('Part::Sphere','Sphere_fit')" << std::endl;
|
||||
str << "App.ActiveDocument.ActiveObject.Radius = " << fit.GetRadius() << std::endl;
|
||||
str << "App.ActiveDocument.ActiveObject.Placement = Base.Placement("
|
||||
<< "Base.Vector(" << base.x << "," << base.y << "," << base.z << "),"
|
||||
<< "Base.Rotation(" << 1 << "," << 0 << "," << 0 << "," << 0 << "))" << std::endl;
|
||||
|
||||
runCommand(Gui::Command::Doc, str.str().c_str());
|
||||
}
|
||||
}
|
||||
commitCommand();
|
||||
updateActive();
|
||||
}
|
||||
|
||||
bool CmdApproxSphere::isActive(void)
|
||||
{
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdSegmentation)
|
||||
|
||||
CmdSegmentation::CmdSegmentation()
|
||||
@@ -199,7 +299,7 @@ CmdSegmentation::CmdSegmentation()
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Create mesh segments...");
|
||||
sMenuText = QT_TR_NOOP("Mesh segmentation...");
|
||||
sToolTipText = QT_TR_NOOP("Create mesh segments");
|
||||
sWhatsThis = "Reen_Segmentation";
|
||||
sStatusTip = sToolTipText;
|
||||
@@ -231,8 +331,8 @@ CmdMeshBoundary::CmdMeshBoundary()
|
||||
{
|
||||
sAppModule = "Reen";
|
||||
sGroup = QT_TR_NOOP("Reverse Engineering");
|
||||
sMenuText = QT_TR_NOOP("Wire from mesh...");
|
||||
sToolTipText = QT_TR_NOOP("Create wire from mesh");
|
||||
sMenuText = QT_TR_NOOP("Wire from mesh boundary...");
|
||||
sToolTipText = QT_TR_NOOP("Create wire from mesh boundaries");
|
||||
sWhatsThis = "Reen_Segmentation";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
@@ -252,6 +352,9 @@ void CmdMeshBoundary::activated(int)
|
||||
TopoDS_Compound compound;
|
||||
builder.MakeCompound(compound);
|
||||
|
||||
TopoDS_Shape shape;
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
|
||||
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) {
|
||||
@@ -259,12 +362,24 @@ void CmdMeshBoundary::activated(int)
|
||||
}
|
||||
if (mkPoly.IsDone()) {
|
||||
builder.Add(compound, mkPoly.Wire());
|
||||
wires.push_back(mkPoly.Wire());
|
||||
}
|
||||
}
|
||||
|
||||
Part::Feature* shapeFea = static_cast<Part::Feature*>(document->addObject("Part::Feature", "Wires from mesh"));
|
||||
shapeFea->Shape.setValue(compound);
|
||||
try {
|
||||
shape = Part::FaceMakerCheese::makeFace(wires);
|
||||
}
|
||||
catch (...) {
|
||||
}
|
||||
|
||||
if (!shape.IsNull()) {
|
||||
Part::Feature* shapeFea = static_cast<Part::Feature*>(document->addObject("Part::Feature", "Face from mesh"));
|
||||
shapeFea->Shape.setValue(shape);
|
||||
}
|
||||
else {
|
||||
Part::Feature* shapeFea = static_cast<Part::Feature*>(document->addObject("Part::Feature", "Wire from mesh"));
|
||||
shapeFea->Shape.setValue(compound);
|
||||
}
|
||||
}
|
||||
document->commitTransaction();
|
||||
}
|
||||
@@ -366,6 +481,8 @@ void CreateReverseEngineeringCommands(void)
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
rcCmdMgr.addCommand(new CmdApproxSurface());
|
||||
rcCmdMgr.addCommand(new CmdApproxPlane());
|
||||
rcCmdMgr.addCommand(new CmdApproxCylinder());
|
||||
rcCmdMgr.addCommand(new CmdApproxSphere());
|
||||
rcCmdMgr.addCommand(new CmdSegmentation());
|
||||
rcCmdMgr.addCommand(new CmdMeshBoundary());
|
||||
rcCmdMgr.addCommand(new CmdPoissonReconstruction());
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
# include <sstream>
|
||||
# include <BRep_Builder.hxx>
|
||||
# include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
# include <GeomAPI_ProjectPointOnSurf.hxx>
|
||||
# include <Geom_Plane.hxx>
|
||||
# include <Standard_Failure.hxx>
|
||||
# include <TopoDS_Compound.hxx>
|
||||
# include <TopoDS_Wire.hxx>
|
||||
@@ -94,6 +96,7 @@ void Segmentation::accept()
|
||||
MeshCore::MeshCurvature meshCurv(kernel);
|
||||
meshCurv.ComputePerVertex();
|
||||
|
||||
// First create segments by curavture to get the surface type
|
||||
std::vector<MeshCore::MeshSurfaceSegmentPtr> segm;
|
||||
if (ui->groupBoxPln->isChecked()) {
|
||||
segm.emplace_back(new MeshCore::MeshCurvaturePlanarSegment
|
||||
@@ -101,20 +104,23 @@ void Segmentation::accept()
|
||||
}
|
||||
finder.FindSegments(segm);
|
||||
|
||||
// For each planar segment compute a plane and use this then for a more accurate 2nd segmentation
|
||||
std::vector<MeshCore::MeshSurfaceSegmentPtr> segmSurf;
|
||||
for (std::vector<MeshCore::MeshSurfaceSegmentPtr>::iterator it = segm.begin(); it != segm.end(); ++it) {
|
||||
const std::vector<MeshCore::MeshSegment>& data = (*it)->GetSegments();
|
||||
for (std::vector<MeshCore::MeshSegment>::const_iterator jt = data.begin(); jt != data.end(); ++jt) {
|
||||
std::vector<unsigned long> indexes = kernel.GetFacetPoints(*jt);
|
||||
MeshCore::PlaneFit fit;
|
||||
fit.AddPoints(kernel.GetPoints(indexes));
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Vector3f axis = fit.GetNormal();
|
||||
MeshCore::AbstractSurfaceFit* fitter = new MeshCore::PlaneSurfaceFit(base, axis);
|
||||
segmSurf.emplace_back(new MeshCore::MeshDistanceGenericSurfaceFitSegment
|
||||
(fitter, kernel, ui->numPln->value(), ui->distToPln->value()));
|
||||
|
||||
// For each planar segment compute a plane and use this then for a more accurate 2nd segmentation
|
||||
if (strcmp((*it)->GetType(), "Plane") == 0) {
|
||||
for (std::vector<MeshCore::MeshSegment>::const_iterator jt = data.begin(); jt != data.end(); ++jt) {
|
||||
std::vector<unsigned long> indexes = kernel.GetFacetPoints(*jt);
|
||||
MeshCore::PlaneFit fit;
|
||||
fit.AddPoints(kernel.GetPoints(indexes));
|
||||
if (fit.Fit() < FLOAT_MAX) {
|
||||
Base::Vector3f base = fit.GetBase();
|
||||
Base::Vector3f axis = fit.GetNormal();
|
||||
MeshCore::AbstractSurfaceFit* fitter = new MeshCore::PlaneSurfaceFit(base, axis);
|
||||
segmSurf.emplace_back(new MeshCore::MeshDistanceGenericSurfaceFitSegment
|
||||
(fitter, kernel, ui->numPln->value(), ui->distToPln->value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,6 +146,7 @@ void Segmentation::accept()
|
||||
std::shared_ptr<MeshCore::MeshDistanceGenericSurfaceFitSegment> genSegm = std::dynamic_pointer_cast
|
||||
<MeshCore::MeshDistanceGenericSurfaceFitSegment>(*it);
|
||||
|
||||
bool isPlanar = (strcmp(genSegm->GetType(), "Plane") == 0);
|
||||
for (std::vector<MeshCore::MeshSegment>::const_iterator jt = data.begin(); jt != data.end(); ++jt) {
|
||||
// reset flag for facets of segment
|
||||
algo.ResetFacetsFlag(*jt, MeshCore::MeshFacet::TMP0);
|
||||
@@ -159,33 +166,47 @@ void Segmentation::accept()
|
||||
std::list<std::vector<Base::Vector3f> > bounds;
|
||||
algo.GetFacetBorders(*jt, bounds);
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
for (auto bt = bounds.begin(); bt != bounds.end(); ++bt) {
|
||||
// project the points onto the surface
|
||||
auto prj = genSegm->Project(*bt);
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (std::vector<Base::Vector3f>::reverse_iterator it = prj.rbegin(); it != prj.rend(); ++it) {
|
||||
mkPoly.Add(gp_Pnt(it->x,it->y,it->z));
|
||||
}
|
||||
if (mkPoly.IsDone()) {
|
||||
wires.push_back(mkPoly.Wire());
|
||||
}
|
||||
}
|
||||
// Handle planar segments
|
||||
if (isPlanar) {
|
||||
std::vector<float> par = genSegm->Parameters();
|
||||
gp_Pnt loc(par.at(0), par.at(1), par.at(2));
|
||||
gp_Dir dir(par.at(3), par.at(4), par.at(5));
|
||||
|
||||
try {
|
||||
TopoDS_Shape shape = Part::FaceMakerCheese::makeFace(wires);
|
||||
if (!shape.IsNull()) {
|
||||
builder.Add(compound, shape);
|
||||
Handle(Geom_Plane) hPlane(new Geom_Plane(loc, dir));
|
||||
|
||||
std::vector<TopoDS_Wire> wires;
|
||||
for (auto bt = bounds.begin(); bt != bounds.end(); ++bt) {
|
||||
// project the points onto the surface
|
||||
std::vector<gp_Pnt> polygon;
|
||||
std::transform(bt->begin(), bt->end(), std::back_inserter(polygon), [&hPlane](const Base::Vector3f v) {
|
||||
gp_Pnt p(v.x, v.y, v.z);
|
||||
return GeomAPI_ProjectPointOnSurf(p, hPlane).NearestPoint();
|
||||
});
|
||||
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (std::vector<gp_Pnt>::reverse_iterator it = polygon.rbegin(); it != polygon.rend(); ++it) {
|
||||
mkPoly.Add(*it);
|
||||
}
|
||||
if (mkPoly.IsDone()) {
|
||||
wires.push_back(mkPoly.Wire());
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
try {
|
||||
TopoDS_Shape shape = Part::FaceMakerCheese::makeFace(wires);
|
||||
if (!shape.IsNull()) {
|
||||
builder.Add(compound, shape);
|
||||
}
|
||||
else {
|
||||
failures.push_back(feaSegm);
|
||||
Base::Console().Warning("Failed to create face from %s\n", feaSegm->Label.getValue());
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
failures.push_back(feaSegm);
|
||||
Base::Console().Warning("Failed to create face from %s\n", feaSegm->Label.getValue());
|
||||
Base::Console().Error("Fatal failure to create face from %s\n", feaSegm->Label.getValue());
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure&) {
|
||||
failures.push_back(feaSegm);
|
||||
Base::Console().Error("Fatal failure to create face from %s\n", feaSegm->Label.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,9 +54,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::MenuItem* item = root->findItem("&Windows");
|
||||
Gui::MenuItem* reen = new Gui::MenuItem;
|
||||
root->insertItem(item, reen);
|
||||
reen->setCommand("&REEN");
|
||||
*reen << "Reen_ApproxPlane"
|
||||
<< "Reen_ApproxSurface";
|
||||
reen->setCommand("&Reverse Engineering");
|
||||
|
||||
Gui::MenuItem *reconstruct = new Gui::MenuItem();
|
||||
reconstruct->setCommand("Surface reconstruction");
|
||||
@@ -74,6 +72,15 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
<< "Reen_MeshBoundary";
|
||||
*reen << segm;
|
||||
|
||||
Gui::MenuItem *approx = new Gui::MenuItem();
|
||||
approx->setCommand("Approximation");
|
||||
*approx << "Reen_ApproxPlane"
|
||||
<< "Reen_ApproxCylinder"
|
||||
<< "Reen_ApproxSphere"
|
||||
<< "Separator"
|
||||
<< "Reen_ApproxSurface";
|
||||
*reen << approx;
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user