MeshPart: apply clang format
This commit is contained in:
@@ -43,13 +43,15 @@ void loadMeshPartResource()
|
||||
Gui::Translator::instance()->refresh();
|
||||
}
|
||||
|
||||
namespace MeshPartGui {
|
||||
class Module : public Py::ExtensionModule<Module>
|
||||
namespace MeshPartGui
|
||||
{
|
||||
class Module: public Py::ExtensionModule<Module>
|
||||
{
|
||||
public:
|
||||
Module() : Py::ExtensionModule<Module>("MeshPartGui")
|
||||
Module()
|
||||
: Py::ExtensionModule<Module>("MeshPartGui")
|
||||
{
|
||||
initialize("This module is the MeshPartGui module."); // register with Python
|
||||
initialize("This module is the MeshPartGui module.");// register with Python
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -60,7 +62,7 @@ PyObject* initModule()
|
||||
return Base::Interpreter().addModule(new Module);
|
||||
}
|
||||
|
||||
} // namespace MeshPartGui
|
||||
}// namespace MeshPartGui
|
||||
|
||||
|
||||
/* Python entry */
|
||||
@@ -74,12 +76,14 @@ PyMOD_INIT_FUNC(MeshPartGui)
|
||||
PyObject* mod = MeshPartGui::initModule();
|
||||
Base::Console().Log("Loading GUI of MeshPart module... done\n");
|
||||
|
||||
// clang-format off
|
||||
// instantiating the commands
|
||||
CreateMeshPartCommands();
|
||||
MeshPartGui::Workbench ::init();
|
||||
MeshPartGui::ViewProviderCurveOnMesh ::init();
|
||||
// clang-format on
|
||||
|
||||
// add resources and reloads the translators
|
||||
// add resources and reloads the translators
|
||||
loadMeshPartResource();
|
||||
|
||||
PyMOD_Return(mod);
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QApplication>
|
||||
# include <QMessageBox>
|
||||
# include <QPushButton>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
@@ -52,14 +52,14 @@ using namespace std;
|
||||
DEF_STD_CMD_A(CmdMeshPartMesher)
|
||||
|
||||
CmdMeshPartMesher::CmdMeshPartMesher()
|
||||
: Command("MeshPart_Mesher")
|
||||
: Command("MeshPart_Mesher")
|
||||
{
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Create mesh from shape...");
|
||||
sToolTipText = QT_TR_NOOP("Tessellate shape");
|
||||
sWhatsThis = "MeshPart_Mesher";
|
||||
sStatusTip = sToolTipText;
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Create mesh from shape...");
|
||||
sToolTipText = QT_TR_NOOP("Tessellate shape");
|
||||
sWhatsThis = "MeshPart_Mesher";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
|
||||
void CmdMeshPartMesher::activated(int)
|
||||
@@ -77,13 +77,13 @@ bool CmdMeshPartMesher::isActive()
|
||||
DEF_STD_CMD_A(CmdMeshPartTrimByPlane)
|
||||
|
||||
CmdMeshPartTrimByPlane::CmdMeshPartTrimByPlane()
|
||||
: Command("MeshPart_TrimByPlane")
|
||||
: Command("MeshPart_TrimByPlane")
|
||||
{
|
||||
sAppModule = "Mesh";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Trim mesh with a plane");
|
||||
sToolTipText = QT_TR_NOOP("Trims a mesh with a plane");
|
||||
sStatusTip = QT_TR_NOOP("Trims a mesh with a plane");
|
||||
sAppModule = "Mesh";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Trim mesh with a plane");
|
||||
sToolTipText = QT_TR_NOOP("Trims a mesh with a plane");
|
||||
sStatusTip = QT_TR_NOOP("Trims a mesh with a plane");
|
||||
}
|
||||
|
||||
void CmdMeshPartTrimByPlane::activated(int)
|
||||
@@ -92,18 +92,22 @@ void CmdMeshPartTrimByPlane::activated(int)
|
||||
std::vector<App::DocumentObject*> plane = getSelection().getObjectsOfType(partType);
|
||||
if (plane.empty()) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
qApp->translate("MeshPart_TrimByPlane", "Select plane"),
|
||||
qApp->translate("MeshPart_TrimByPlane", "Please select a plane at which you trim the mesh."));
|
||||
qApp->translate("MeshPart_TrimByPlane", "Select plane"),
|
||||
qApp->translate("MeshPart_TrimByPlane",
|
||||
"Please select a plane at which you trim the mesh."));
|
||||
return;
|
||||
}
|
||||
|
||||
QMessageBox msgBox(Gui::getMainWindow());
|
||||
msgBox.setIcon(QMessageBox::Question);
|
||||
msgBox.setWindowTitle(qApp->translate("MeshPart_TrimByPlane","Trim by plane"));
|
||||
msgBox.setText(qApp->translate("MeshPart_TrimByPlane","Select the side you want to keep."));
|
||||
QPushButton* inner = msgBox.addButton(qApp->translate("MeshPart_TrimByPlane","Below"), QMessageBox::ActionRole);
|
||||
QPushButton* outer = msgBox.addButton(qApp->translate("MeshPart_TrimByPlane","Above"), QMessageBox::ActionRole);
|
||||
QPushButton* split = msgBox.addButton(qApp->translate("MeshPart_TrimByPlane","Split"), QMessageBox::ActionRole);
|
||||
msgBox.setWindowTitle(qApp->translate("MeshPart_TrimByPlane", "Trim by plane"));
|
||||
msgBox.setText(qApp->translate("MeshPart_TrimByPlane", "Select the side you want to keep."));
|
||||
QPushButton* inner =
|
||||
msgBox.addButton(qApp->translate("MeshPart_TrimByPlane", "Below"), QMessageBox::ActionRole);
|
||||
QPushButton* outer =
|
||||
msgBox.addButton(qApp->translate("MeshPart_TrimByPlane", "Above"), QMessageBox::ActionRole);
|
||||
QPushButton* split =
|
||||
msgBox.addButton(qApp->translate("MeshPart_TrimByPlane", "Split"), QMessageBox::ActionRole);
|
||||
msgBox.addButton(QMessageBox::Cancel);
|
||||
msgBox.setDefaultButton(inner);
|
||||
msgBox.exec();
|
||||
@@ -124,12 +128,14 @@ void CmdMeshPartTrimByPlane::activated(int)
|
||||
return;
|
||||
}
|
||||
|
||||
Base::Placement plnPlacement = static_cast<App::GeoFeature*>(plane.front())->Placement.getValue();
|
||||
Base::Placement plnPlacement =
|
||||
static_cast<App::GeoFeature*>(plane.front())->Placement.getValue();
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Trim with plane"));
|
||||
std::vector<App::DocumentObject*> docObj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> docObj =
|
||||
Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
for (auto it : docObj) {
|
||||
Base::Vector3d normal(0,0,1);
|
||||
Base::Vector3d normal(0, 0, 1);
|
||||
plnPlacement.getRotation().multVec(normal, normal);
|
||||
Base::Vector3d base = plnPlacement.getPosition();
|
||||
|
||||
@@ -167,8 +173,9 @@ void CmdMeshPartTrimByPlane::activated(int)
|
||||
bool CmdMeshPartTrimByPlane::isActive()
|
||||
{
|
||||
// Check for the selected mesh feature (all Mesh types)
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1)
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -179,14 +186,14 @@ bool CmdMeshPartTrimByPlane::isActive()
|
||||
DEF_STD_CMD_A(CmdMeshPartSection)
|
||||
|
||||
CmdMeshPartSection::CmdMeshPartSection()
|
||||
: Command("MeshPart_SectionByPlane")
|
||||
: Command("MeshPart_SectionByPlane")
|
||||
{
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Create section from mesh and plane");
|
||||
sToolTipText = QT_TR_NOOP("Section");
|
||||
sWhatsThis = "MeshPart_Section";
|
||||
sStatusTip = sToolTipText;
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Create section from mesh and plane");
|
||||
sToolTipText = QT_TR_NOOP("Section");
|
||||
sWhatsThis = "MeshPart_Section";
|
||||
sStatusTip = sToolTipText;
|
||||
}
|
||||
|
||||
void CmdMeshPartSection::activated(int)
|
||||
@@ -194,19 +201,22 @@ void CmdMeshPartSection::activated(int)
|
||||
Base::Type partType = Base::Type::fromName("Part::Plane");
|
||||
std::vector<App::DocumentObject*> plane = getSelection().getObjectsOfType(partType);
|
||||
if (plane.empty()) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
QMessageBox::warning(
|
||||
Gui::getMainWindow(),
|
||||
qApp->translate("MeshPart_Section", "Select plane"),
|
||||
qApp->translate("MeshPart_Section", "Please select a plane at which you section the mesh."));
|
||||
qApp->translate("MeshPart_Section",
|
||||
"Please select a plane at which you section the mesh."));
|
||||
return;
|
||||
}
|
||||
|
||||
Base::Placement plm = static_cast<App::GeoFeature*>(plane.front())->Placement.getValue();
|
||||
Base::Vector3d normal(0,0,1);
|
||||
Base::Vector3d normal(0, 0, 1);
|
||||
plm.getRotation().multVec(normal, normal);
|
||||
Base::Vector3d base = plm.getPosition();
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Section with plane"));
|
||||
std::vector<App::DocumentObject*> docObj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> docObj =
|
||||
Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
Mesh::MeshObject::TPlane tplane;
|
||||
tplane.first = Base::convertTo<Base::Vector3f>(base);
|
||||
tplane.second = Base::convertTo<Base::Vector3f>(normal);
|
||||
@@ -251,8 +261,9 @@ void CmdMeshPartSection::activated(int)
|
||||
bool CmdMeshPartSection::isActive()
|
||||
{
|
||||
// Check for the selected mesh feature (all Mesh types)
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1)
|
||||
if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -263,15 +274,15 @@ bool CmdMeshPartSection::isActive()
|
||||
DEF_STD_CMD_A(CmdMeshPartCrossSections)
|
||||
|
||||
CmdMeshPartCrossSections::CmdMeshPartCrossSections()
|
||||
:Command("MeshPart_CrossSections")
|
||||
: Command("MeshPart_CrossSections")
|
||||
{
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("MeshPart");
|
||||
sMenuText = QT_TR_NOOP("Cross-sections...");
|
||||
sToolTipText = QT_TR_NOOP("Cross-sections");
|
||||
sWhatsThis = "MeshPart_CrossSections";
|
||||
sStatusTip = sToolTipText;
|
||||
//sPixmap = "MeshPart_CrossSections";
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("MeshPart");
|
||||
sMenuText = QT_TR_NOOP("Cross-sections...");
|
||||
sToolTipText = QT_TR_NOOP("Cross-sections");
|
||||
sWhatsThis = "MeshPart_CrossSections";
|
||||
sStatusTip = sToolTipText;
|
||||
// sPixmap = "MeshPart_CrossSections";
|
||||
}
|
||||
|
||||
void CmdMeshPartCrossSections::activated(int iMsg)
|
||||
@@ -279,8 +290,8 @@ void CmdMeshPartCrossSections::activated(int iMsg)
|
||||
Q_UNUSED(iMsg);
|
||||
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
|
||||
if (!dlg) {
|
||||
std::vector<App::DocumentObject*> obj = Gui::Selection().getObjectsOfType
|
||||
(Mesh::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> obj =
|
||||
Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
Base::BoundBox3d bbox;
|
||||
for (auto it : obj) {
|
||||
bbox.Add(static_cast<Mesh::Feature*>(it)->Mesh.getBoundingBox());
|
||||
@@ -292,23 +303,23 @@ void CmdMeshPartCrossSections::activated(int iMsg)
|
||||
|
||||
bool CmdMeshPartCrossSections::isActive()
|
||||
{
|
||||
return (Gui::Selection().countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0 &&
|
||||
!Gui::Control().activeDialog());
|
||||
return (Gui::Selection().countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0
|
||||
&& !Gui::Control().activeDialog());
|
||||
}
|
||||
|
||||
DEF_STD_CMD_A(CmdMeshPartCurveOnMesh)
|
||||
|
||||
CmdMeshPartCurveOnMesh::CmdMeshPartCurveOnMesh()
|
||||
: Command("MeshPart_CurveOnMesh")
|
||||
: Command("MeshPart_CurveOnMesh")
|
||||
{
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Curve on mesh...");
|
||||
sToolTipText = QT_TR_NOOP("Creates an approximated curve on top of a mesh.\n"
|
||||
"This command only works with a 'mesh' object.");
|
||||
sWhatsThis = "MeshPart_CurveOnMesh";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "MeshPart_CurveOnMesh";
|
||||
sAppModule = "MeshPart";
|
||||
sGroup = QT_TR_NOOP("Mesh");
|
||||
sMenuText = QT_TR_NOOP("Curve on mesh...");
|
||||
sToolTipText = QT_TR_NOOP("Creates an approximated curve on top of a mesh.\n"
|
||||
"This command only works with a 'mesh' object.");
|
||||
sWhatsThis = "MeshPart_CurveOnMesh";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "MeshPart_CurveOnMesh";
|
||||
}
|
||||
|
||||
void CmdMeshPartCurveOnMesh::activated(int)
|
||||
@@ -319,18 +330,21 @@ void CmdMeshPartCurveOnMesh::activated(int)
|
||||
return;
|
||||
}
|
||||
|
||||
Gui::Control().showDialog(new MeshPartGui::TaskCurveOnMesh(static_cast<Gui::View3DInventor*>(mdis.front())));
|
||||
Gui::Control().showDialog(
|
||||
new MeshPartGui::TaskCurveOnMesh(static_cast<Gui::View3DInventor*>(mdis.front())));
|
||||
}
|
||||
|
||||
bool CmdMeshPartCurveOnMesh::isActive()
|
||||
{
|
||||
if (Gui::Control().activeDialog())
|
||||
if (Gui::Control().activeDialog()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for the selected mesh feature (all Mesh types)
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
if (doc && doc->countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0)
|
||||
if (doc && doc->countObjectsOfType(Mesh::Feature::getClassTypeId()) > 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -338,7 +352,7 @@ bool CmdMeshPartCurveOnMesh::isActive()
|
||||
|
||||
void CreateMeshPartCommands()
|
||||
{
|
||||
Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
Gui::CommandManager& rcCmdMgr = Gui::Application::Instance->commandManager();
|
||||
rcCmdMgr.addCommand(new CmdMeshPartMesher());
|
||||
rcCmdMgr.addCommand(new CmdMeshPartTrimByPlane());
|
||||
rcCmdMgr.addCommand(new CmdMeshPartSection());
|
||||
|
||||
@@ -22,24 +22,24 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <cfloat>
|
||||
# include <sstream>
|
||||
#include <cfloat>
|
||||
#include <sstream>
|
||||
|
||||
# include <BRep_Builder.hxx>
|
||||
# include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
# include <TopoDS.hxx>
|
||||
# include <TopoDS_Compound.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
|
||||
# include <QFuture>
|
||||
# include <QKeyEvent>
|
||||
# include <QMessageBox>
|
||||
# include <QtConcurrentMap>
|
||||
#include <QFuture>
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QtConcurrentMap>
|
||||
|
||||
# include <Inventor/nodes/SoBaseColor.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoBaseColor.h>
|
||||
#include <Inventor/nodes/SoCoordinate3.h>
|
||||
#include <Inventor/nodes/SoDrawStyle.h>
|
||||
#include <Inventor/nodes/SoLineSet.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
@@ -47,14 +47,14 @@
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/Tools.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
|
||||
#include "CrossSections.h"
|
||||
#include "ui_CrossSections.h"
|
||||
@@ -63,8 +63,9 @@
|
||||
using namespace MeshPartGui;
|
||||
namespace sp = std::placeholders;
|
||||
|
||||
namespace MeshPartGui {
|
||||
class ViewProviderCrossSections : public Gui::ViewProvider
|
||||
namespace MeshPartGui
|
||||
{
|
||||
class ViewProviderCrossSections: public Gui::ViewProvider
|
||||
{
|
||||
public:
|
||||
ViewProviderCrossSections()
|
||||
@@ -88,8 +89,7 @@ public:
|
||||
planes->unref();
|
||||
}
|
||||
void updateData(const App::Property*) override
|
||||
{
|
||||
}
|
||||
{}
|
||||
const char* getDefaultDisplayMode() const override
|
||||
{
|
||||
return "";
|
||||
@@ -102,15 +102,15 @@ public:
|
||||
{
|
||||
coords->point.setNum(v.size());
|
||||
SbVec3f* p = coords->point.startEditing();
|
||||
for (unsigned int i=0; i<v.size(); i++) {
|
||||
for (unsigned int i = 0; i < v.size(); i++) {
|
||||
const Base::Vector3f& pt = v[i];
|
||||
p[i].setValue(pt.x,pt.y,pt.z);
|
||||
p[i].setValue(pt.x, pt.y, pt.z);
|
||||
}
|
||||
coords->point.finishEditing();
|
||||
unsigned int count = v.size()/5;
|
||||
unsigned int count = v.size() / 5;
|
||||
planes->numVertices.setNum(count);
|
||||
int32_t* l = planes->numVertices.startEditing();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
l[i] = 5;
|
||||
}
|
||||
planes->numVertices.finishEditing();
|
||||
@@ -121,12 +121,16 @@ private:
|
||||
SoLineSet* planes;
|
||||
};
|
||||
|
||||
class MeshCrossSection {
|
||||
class MeshCrossSection
|
||||
{
|
||||
public:
|
||||
MeshCrossSection(const MeshCore::MeshKernel& mesh,
|
||||
const MeshCore::MeshFacetGrid& grid,
|
||||
double x, double y, double z,
|
||||
bool connectEdges, double eps)
|
||||
double x,
|
||||
double y,
|
||||
double z,
|
||||
bool connectEdges,
|
||||
double eps)
|
||||
: mesh(mesh)
|
||||
, grid(grid)
|
||||
, x(x)
|
||||
@@ -134,25 +138,25 @@ public:
|
||||
, z(z)
|
||||
, connectEdges(connectEdges)
|
||||
, epsilon(eps)
|
||||
{
|
||||
}
|
||||
{}
|
||||
std::list<TopoDS_Wire> section(double d)
|
||||
{
|
||||
Mesh::MeshObject::TPolylines polylines;
|
||||
MeshCore::MeshAlgorithm algo(mesh);
|
||||
Base::Vector3f p(x*d, y*d, z*d);
|
||||
Base::Vector3f p(x * d, y * d, z * d);
|
||||
Base::Vector3f n(x, y, z);
|
||||
algo.CutWithPlane(p, n, grid, polylines, epsilon, connectEdges);
|
||||
|
||||
std::list<TopoDS_Wire> wires;
|
||||
for (const auto & polyline : polylines) {
|
||||
for (const auto& polyline : polylines) {
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (auto jt : polyline) {
|
||||
mkPoly.Add(Base::convertTo<gp_Pnt>(jt));
|
||||
}
|
||||
|
||||
if (mkPoly.IsDone())
|
||||
if (mkPoly.IsDone()) {
|
||||
wires.push_back(mkPoly.Wire());
|
||||
}
|
||||
}
|
||||
|
||||
return wires;
|
||||
@@ -161,14 +165,15 @@ public:
|
||||
private:
|
||||
const MeshCore::MeshKernel& mesh;
|
||||
const MeshCore::MeshFacetGrid& grid;
|
||||
double x,y,z;
|
||||
double x, y, z;
|
||||
bool connectEdges;
|
||||
double epsilon;
|
||||
};
|
||||
}
|
||||
}// namespace MeshPartGui
|
||||
|
||||
CrossSections::CrossSections(const Base::BoundBox3d& bb, QWidget* parent, Qt::WindowFlags fl)
|
||||
: QDialog(parent, fl), bbox(bb)
|
||||
: QDialog(parent, fl)
|
||||
, bbox(bb)
|
||||
{
|
||||
ui = new Ui_CrossSections();
|
||||
ui->setupUi(this);
|
||||
@@ -207,13 +212,14 @@ CrossSections::~CrossSections()
|
||||
|
||||
void CrossSections::setupConnections()
|
||||
{
|
||||
// clang-format off
|
||||
connect(ui->xyPlane, &QRadioButton::clicked,
|
||||
this, &CrossSections::xyPlaneClicked);
|
||||
connect(ui->xzPlane, &QRadioButton::clicked,
|
||||
this, &CrossSections::xzPlaneClicked);
|
||||
connect(ui->yzPlane, &QRadioButton::clicked,
|
||||
this, &CrossSections::yzPlaneClicked);
|
||||
connect(ui->position, qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
|
||||
connect(ui->position,qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
|
||||
this, &CrossSections::positionValueChanged);
|
||||
connect(ui->distance, qOverload<double>(&Gui::QuantitySpinBox::valueChanged),
|
||||
this, &CrossSections::distanceValueChanged);
|
||||
@@ -223,20 +229,23 @@ void CrossSections::setupConnections()
|
||||
this, &CrossSections::checkBothSidesToggled);
|
||||
connect(ui->sectionsBox, &QGroupBox::toggled,
|
||||
this, &CrossSections::sectionsBoxToggled);
|
||||
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
CrossSections::Plane CrossSections::plane() const
|
||||
{
|
||||
if (ui->xyPlane->isChecked())
|
||||
if (ui->xyPlane->isChecked()) {
|
||||
return CrossSections::XY;
|
||||
else if (ui->xzPlane->isChecked())
|
||||
}
|
||||
else if (ui->xzPlane->isChecked()) {
|
||||
return CrossSections::XZ;
|
||||
else
|
||||
}
|
||||
else {
|
||||
return CrossSections::YZ;
|
||||
}
|
||||
}
|
||||
|
||||
void CrossSections::changeEvent(QEvent *e)
|
||||
void CrossSections::changeEvent(QEvent* e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
@@ -261,15 +270,17 @@ void CrossSections::accept()
|
||||
|
||||
void CrossSections::apply()
|
||||
{
|
||||
std::vector<App::DocumentObject*> obj = Gui::Selection().
|
||||
getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
std::vector<App::DocumentObject*> obj =
|
||||
Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId());
|
||||
|
||||
std::vector<double> d;
|
||||
if (ui->sectionsBox->isChecked())
|
||||
if (ui->sectionsBox->isChecked()) {
|
||||
d = getPlanes();
|
||||
else
|
||||
}
|
||||
else {
|
||||
d.push_back(ui->position->value().getValue());
|
||||
double a=0,b=0,c=0;
|
||||
}
|
||||
double a = 0, b = 0, c = 0;
|
||||
switch (plane()) {
|
||||
case CrossSections::XY:
|
||||
c = 1.0;
|
||||
@@ -285,7 +296,7 @@ void CrossSections::apply()
|
||||
bool connectEdges = ui->checkBoxConnect->isChecked();
|
||||
double eps = ui->spinEpsilon->value();
|
||||
|
||||
#if 1 // multi-threaded sections
|
||||
#if 1// multi-threaded sections
|
||||
for (auto it : obj) {
|
||||
const Mesh::MeshObject& mesh = static_cast<Mesh::Feature*>(it)->Mesh.getValue();
|
||||
|
||||
@@ -294,29 +305,30 @@ void CrossSections::apply()
|
||||
|
||||
MeshCore::MeshFacetGrid grid(kernel);
|
||||
|
||||
//NOLINTBEGIN
|
||||
// NOLINTBEGIN
|
||||
MeshCrossSection cs(kernel, grid, a, b, c, connectEdges, eps);
|
||||
QFuture< std::list<TopoDS_Wire> > future = QtConcurrent::mapped
|
||||
(d, std::bind(&MeshCrossSection::section, &cs, sp::_1));
|
||||
QFuture<std::list<TopoDS_Wire>> future =
|
||||
QtConcurrent::mapped(d, std::bind(&MeshCrossSection::section, &cs, sp::_1));
|
||||
future.waitForFinished();
|
||||
//NOLINTEND
|
||||
// NOLINTEND
|
||||
|
||||
TopoDS_Compound comp;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(comp);
|
||||
|
||||
for (const auto & w : future) {
|
||||
for (const auto & wt : w) {
|
||||
if (!wt.IsNull())
|
||||
for (const auto& w : future) {
|
||||
for (const auto& wt : w) {
|
||||
if (!wt.IsNull()) {
|
||||
builder.Add(comp, wt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
App::Document* doc = it->getDocument();
|
||||
std::string s = it->getNameInDocument();
|
||||
s += "_cs";
|
||||
Part::Feature* section = static_cast<Part::Feature*>
|
||||
(doc->addObject("Part::Feature",s.c_str()));
|
||||
Part::Feature* section =
|
||||
static_cast<Part::Feature*>(doc->addObject("Part::Feature", s.c_str()));
|
||||
section->Shape.setValue(comp);
|
||||
section->purgeTouched();
|
||||
}
|
||||
@@ -330,8 +342,8 @@ void CrossSections::apply()
|
||||
for (std::vector<double>::iterator jt = d.begin(); jt != d.end(); ++jt) {
|
||||
double d = *jt;
|
||||
str << "("
|
||||
<< "App.Vector(" << a*d << ", " << b*d << ", " << c*d << "), "
|
||||
<< "App.Vector(" << a << ", " << b << ", " << c << ")"
|
||||
<< "App.Vector(" << a * d << ", " << b * d << ", " << c * d << "), "
|
||||
<< "App.Vector(" << a << ", " << b << ", " << c << ")"
|
||||
<< "), ";
|
||||
}
|
||||
str << "]";
|
||||
@@ -341,26 +353,31 @@ void CrossSections::apply()
|
||||
App::Document* doc = (*it)->getDocument();
|
||||
std::string s = (*it)->getNameInDocument();
|
||||
s += "_cs";
|
||||
Gui::Command::runCommand(Gui::Command::App, QString::fromLatin1(
|
||||
"points=FreeCAD.getDocument(\"%1\").%2.Mesh.crossSections(%3, %4, %5)\n"
|
||||
"wires=[]\n"
|
||||
"for i in points:\n"
|
||||
" wires.extend([Part.makePolygon(j) for j in i])\n")
|
||||
.arg(QLatin1String(doc->getName()))
|
||||
.arg(QLatin1String((*it)->getNameInDocument()))
|
||||
.arg(planes)
|
||||
.arg(eps)
|
||||
.arg(connectEdges ? QLatin1String("True") : QLatin1String("False"))
|
||||
.toLatin1());
|
||||
Gui::Command::runCommand(
|
||||
Gui::Command::App,
|
||||
QString::fromLatin1(
|
||||
"points=FreeCAD.getDocument(\"%1\").%2.Mesh.crossSections(%3, %4, %5)\n"
|
||||
"wires=[]\n"
|
||||
"for i in points:\n"
|
||||
" wires.extend([Part.makePolygon(j) for j in i])\n")
|
||||
.arg(QLatin1String(doc->getName()))
|
||||
.arg(QLatin1String((*it)->getNameInDocument()))
|
||||
.arg(planes)
|
||||
.arg(eps)
|
||||
.arg(connectEdges ? QLatin1String("True") : QLatin1String("False"))
|
||||
.toLatin1());
|
||||
|
||||
Gui::Command::runCommand(Gui::Command::App, QString::fromLatin1(
|
||||
"comp=Part.Compound(wires)\n"
|
||||
"slice=FreeCAD.getDocument(\"%1\").addObject(\"Part::Feature\",\"%2\")\n"
|
||||
"slice.Shape=comp\n"
|
||||
"slice.purgeTouched()\n"
|
||||
"del slice,comp,wires,points")
|
||||
.arg(QLatin1String(doc->getName()))
|
||||
.arg(QLatin1String(s.c_str())).toLatin1());
|
||||
Gui::Command::runCommand(
|
||||
Gui::Command::App,
|
||||
QString::fromLatin1(
|
||||
"comp=Part.Compound(wires)\n"
|
||||
"slice=FreeCAD.getDocument(\"%1\").addObject(\"Part::Feature\",\"%2\")\n"
|
||||
"slice.Shape=comp\n"
|
||||
"slice.purgeTouched()\n"
|
||||
"del slice,comp,wires,points")
|
||||
.arg(QLatin1String(doc->getName()))
|
||||
.arg(QLatin1String(s.c_str()))
|
||||
.toLatin1());
|
||||
}
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
@@ -378,8 +395,9 @@ void CrossSections::xyPlaneClicked()
|
||||
}
|
||||
else {
|
||||
double dist = bbox.LengthZ() / ui->countSections->value();
|
||||
if (!ui->checkBothSides->isChecked())
|
||||
if (!ui->checkBothSides->isChecked()) {
|
||||
dist *= 0.5f;
|
||||
}
|
||||
ui->distance->setValue(dist);
|
||||
calcPlanes(CrossSections::XY);
|
||||
}
|
||||
@@ -394,8 +412,9 @@ void CrossSections::xzPlaneClicked()
|
||||
}
|
||||
else {
|
||||
double dist = bbox.LengthY() / ui->countSections->value();
|
||||
if (!ui->checkBothSides->isChecked())
|
||||
if (!ui->checkBothSides->isChecked()) {
|
||||
dist *= 0.5f;
|
||||
}
|
||||
ui->distance->setValue(dist);
|
||||
calcPlanes(CrossSections::XZ);
|
||||
}
|
||||
@@ -410,8 +429,9 @@ void CrossSections::yzPlaneClicked()
|
||||
}
|
||||
else {
|
||||
double dist = bbox.LengthX() / ui->countSections->value();
|
||||
if (!ui->checkBothSides->isChecked())
|
||||
if (!ui->checkBothSides->isChecked()) {
|
||||
dist *= 0.5f;
|
||||
}
|
||||
ui->distance->setValue(dist);
|
||||
calcPlanes(CrossSections::YZ);
|
||||
}
|
||||
@@ -476,8 +496,9 @@ void CrossSections::countSectionsValueChanged(int v)
|
||||
dist = bbox.LengthX() / v;
|
||||
break;
|
||||
}
|
||||
if (!ui->checkBothSides->isChecked())
|
||||
if (!ui->checkBothSides->isChecked()) {
|
||||
dist *= 0.5f;
|
||||
}
|
||||
ui->distance->setValue(dist);
|
||||
calcPlanes(type);
|
||||
}
|
||||
@@ -553,14 +574,14 @@ std::vector<double> CrossSections::getPlanes() const
|
||||
|
||||
std::vector<double> d;
|
||||
if (both) {
|
||||
double start = pos-0.5f*(count-1)*stp;
|
||||
for (int i=0; i<count; i++) {
|
||||
d.push_back(start+i*stp);
|
||||
double start = pos - 0.5f * (count - 1) * stp;
|
||||
for (int i = 0; i < count; i++) {
|
||||
d.push_back(start + i * stp);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i=0; i<count; i++) {
|
||||
d.push_back(pos+i*stp);
|
||||
for (int i = 0; i < count; i++) {
|
||||
d.push_back(pos + i * stp);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
@@ -573,22 +594,22 @@ void CrossSections::makePlanes(Plane type, const std::vector<double>& d, double
|
||||
Base::Vector3f v[4];
|
||||
switch (type) {
|
||||
case XY:
|
||||
v[0].Set(bound[0],bound[2],it);
|
||||
v[1].Set(bound[1],bound[2],it);
|
||||
v[2].Set(bound[1],bound[3],it);
|
||||
v[3].Set(bound[0],bound[3],it);
|
||||
v[0].Set(bound[0], bound[2], it);
|
||||
v[1].Set(bound[1], bound[2], it);
|
||||
v[2].Set(bound[1], bound[3], it);
|
||||
v[3].Set(bound[0], bound[3], it);
|
||||
break;
|
||||
case XZ:
|
||||
v[0].Set(bound[0],it,bound[2]);
|
||||
v[1].Set(bound[1],it,bound[2]);
|
||||
v[2].Set(bound[1],it,bound[3]);
|
||||
v[3].Set(bound[0],it,bound[3]);
|
||||
v[0].Set(bound[0], it, bound[2]);
|
||||
v[1].Set(bound[1], it, bound[2]);
|
||||
v[2].Set(bound[1], it, bound[3]);
|
||||
v[3].Set(bound[0], it, bound[3]);
|
||||
break;
|
||||
case YZ:
|
||||
v[0].Set(it,bound[0],bound[2]);
|
||||
v[1].Set(it,bound[1],bound[2]);
|
||||
v[2].Set(it,bound[1],bound[3]);
|
||||
v[3].Set(it,bound[0],bound[3]);
|
||||
v[0].Set(it, bound[0], bound[2]);
|
||||
v[1].Set(it, bound[1], bound[2]);
|
||||
v[2].Set(it, bound[1], bound[3]);
|
||||
v[3].Set(it, bound[0], bound[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -606,9 +627,10 @@ void CrossSections::makePlanes(Plane type, const std::vector<double>& d, double
|
||||
TaskCrossSections::TaskCrossSections(const Base::BoundBox3d& bb)
|
||||
{
|
||||
widget = new CrossSections(bb);
|
||||
taskbox = new Gui::TaskView::TaskBox(
|
||||
Gui::BitmapFactory().pixmap("Mesh_CrossSections"),
|
||||
widget->windowTitle(), true, nullptr);
|
||||
taskbox = new Gui::TaskView::TaskBox(Gui::BitmapFactory().pixmap("Mesh_CrossSections"),
|
||||
widget->windowTitle(),
|
||||
true,
|
||||
nullptr);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
@@ -31,28 +31,37 @@
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
|
||||
|
||||
namespace Gui {
|
||||
namespace Gui
|
||||
{
|
||||
class View3DInventor;
|
||||
}
|
||||
|
||||
namespace MeshPartGui {
|
||||
namespace MeshPartGui
|
||||
{
|
||||
|
||||
class ViewProviderCrossSections;
|
||||
class Ui_CrossSections;
|
||||
class CrossSections : public QDialog
|
||||
class CrossSections: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum Plane { XY, XZ, YZ };
|
||||
enum Plane
|
||||
{
|
||||
XY,
|
||||
XZ,
|
||||
YZ
|
||||
};
|
||||
|
||||
public:
|
||||
explicit CrossSections(const Base::BoundBox3d& bb, QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
|
||||
explicit CrossSections(const Base::BoundBox3d& bb,
|
||||
QWidget* parent = nullptr,
|
||||
Qt::WindowFlags fl = Qt::WindowFlags());
|
||||
~CrossSections() override;
|
||||
void accept() override;
|
||||
void apply();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
void keyPressEvent(QKeyEvent*) override;
|
||||
|
||||
private:
|
||||
@@ -69,7 +78,7 @@ private:
|
||||
private:
|
||||
std::vector<double> getPlanes() const;
|
||||
void calcPlane(Plane, double);
|
||||
void calcPlanes(Plane/*, double, bool, int*/);
|
||||
void calcPlanes(Plane /*, double, bool, int*/);
|
||||
void makePlanes(Plane, const std::vector<double>&, double[4]);
|
||||
Plane plane() const;
|
||||
|
||||
@@ -80,7 +89,7 @@ private:
|
||||
QPointer<Gui::View3DInventor> view;
|
||||
};
|
||||
|
||||
class TaskCrossSections : public Gui::TaskView::TaskDialog
|
||||
class TaskCrossSections: public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -92,13 +101,15 @@ public:
|
||||
void clicked(int id) override;
|
||||
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{ return QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel; }
|
||||
{
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel;
|
||||
}
|
||||
|
||||
private:
|
||||
CrossSections* widget;
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
} // namespace MeshPartGui
|
||||
}// namespace MeshPartGui
|
||||
|
||||
#endif // MESHPARTGUI_CROSSSECTIONS_H
|
||||
#endif// MESHPARTGUI_CROSSSECTIONS_H
|
||||
|
||||
@@ -23,32 +23,32 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <QMenu>
|
||||
# include <QPointer>
|
||||
# include <QStatusBar>
|
||||
# include <QTimer>
|
||||
#include <QMenu>
|
||||
#include <QPointer>
|
||||
#include <QStatusBar>
|
||||
#include <QTimer>
|
||||
|
||||
# include <gp_Pnt.hxx>
|
||||
# include <TColgp_Array1OfPnt.hxx>
|
||||
# include <GeomAPI_PointsToBSpline.hxx>
|
||||
# include <Geom_BSplineCurve.hxx>
|
||||
# include <BRep_Tool.hxx>
|
||||
# include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
# include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
# include <BRepMesh_IncrementalMesh.hxx>
|
||||
# include <Poly_Polygon3D.hxx>
|
||||
# include <TopoDS_Edge.hxx>
|
||||
# include <TopoDS_Wire.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <GeomAPI_PointsToBSpline.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/details/SoFaceDetail.h>
|
||||
# include <Inventor/events/SoMouseButtonEvent.h>
|
||||
# include <Inventor/nodes/SoBaseColor.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoPointSet.h>
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/SoPickedPoint.h>
|
||||
#include <Inventor/details/SoFaceDetail.h>
|
||||
#include <Inventor/events/SoMouseButtonEvent.h>
|
||||
#include <Inventor/nodes/SoBaseColor.h>
|
||||
#include <Inventor/nodes/SoCoordinate3.h>
|
||||
#include <Inventor/nodes/SoDrawStyle.h>
|
||||
#include <Inventor/nodes/SoLineSet.h>
|
||||
#include <Inventor/nodes/SoPointSet.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
@@ -58,11 +58,11 @@
|
||||
#include <Gui/Utilities.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Mesh/App/Core/Algorithm.h>
|
||||
#include <Mod/Mesh/App/Core/Grid.h>
|
||||
#include <Mod/Mesh/App/Core/MeshKernel.h>
|
||||
#include <Mod/Mesh/App/Core/Projection.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Mesh/Gui/ViewProvider.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
@@ -80,9 +80,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* XPM */
|
||||
static const char *cursor_curveonmesh[]={
|
||||
// clang-format off
|
||||
static const char* cursor_curveonmesh[] = {
|
||||
"32 32 3 1",
|
||||
"+ c white",
|
||||
"# c red",
|
||||
@@ -119,6 +119,7 @@ static const char *cursor_curveonmesh[]={
|
||||
"................................",
|
||||
"................................",
|
||||
"................................"};
|
||||
// clang-format on
|
||||
|
||||
using namespace MeshPartGui;
|
||||
|
||||
@@ -138,7 +139,7 @@ ViewProviderCurveOnMesh::ViewProviderCurveOnMesh()
|
||||
|
||||
SoGroup* pcLineRoot = new SoSeparator();
|
||||
pcLineRoot->addChild(pcLinesStyle);
|
||||
SoBaseColor * linecol = new SoBaseColor;
|
||||
SoBaseColor* linecol = new SoBaseColor;
|
||||
linecol->rgb.setValue(1.0f, 1.0f, 0.0f);
|
||||
pcLineRoot->addChild(linecol);
|
||||
pcLineRoot->addChild(pcCoords);
|
||||
@@ -156,7 +157,7 @@ ViewProviderCurveOnMesh::ViewProviderCurveOnMesh()
|
||||
|
||||
SoGroup* pcPointRoot = new SoSeparator();
|
||||
pcPointRoot->addChild(pcPointStyle);
|
||||
SoBaseColor * pointcol = new SoBaseColor;
|
||||
SoBaseColor* pointcol = new SoBaseColor;
|
||||
pointcol->rgb.setValue(1.0f, 0.5f, 0.0f);
|
||||
pcPointRoot->addChild(pointcol);
|
||||
pcPointRoot->addChild(pcNodes);
|
||||
@@ -231,7 +232,8 @@ public:
|
||||
int maxDegree;
|
||||
GeomAbs_Shape cont;
|
||||
|
||||
ApproxPar() {
|
||||
ApproxPar()
|
||||
{
|
||||
weight1 = 0.2;
|
||||
weight2 = 0.4;
|
||||
weight3 = 0.2;
|
||||
@@ -243,14 +245,13 @@ public:
|
||||
Private()
|
||||
: curve(new ViewProviderCurveOnMesh)
|
||||
, editcursor(QPixmap(cursor_curveonmesh), 7, 7)
|
||||
{
|
||||
}
|
||||
{}
|
||||
~Private()
|
||||
{
|
||||
delete curve;
|
||||
delete grid;
|
||||
}
|
||||
static void vertexCallback(void * ud, SoEventCallback * n);
|
||||
static void vertexCallback(void* ud, SoEventCallback* n);
|
||||
std::vector<SbVec3f> convert(const std::vector<Base::Vector3f>& points) const
|
||||
{
|
||||
std::vector<SbVec3f> pts;
|
||||
@@ -279,7 +280,8 @@ public:
|
||||
MeshCore::MeshProjection meshProjection(kernel);
|
||||
Base::Vector3f v1 = Base::convertTo<Base::Vector3f>(last.point);
|
||||
Base::Vector3f v2 = Base::convertTo<Base::Vector3f>(pick.point);
|
||||
Base::Vector3f vd = Base::convertTo<Base::Vector3f>(viewer->getViewer()->getViewDirection());
|
||||
Base::Vector3f vd =
|
||||
Base::convertTo<Base::Vector3f>(viewer->getViewer()->getViewDirection());
|
||||
if (meshProjection.projectLineOnMesh(*grid, v1, last.facet, v2, pick.facet, vd, polyline)) {
|
||||
if (polyline.size() > 1) {
|
||||
if (cutLines.empty()) {
|
||||
@@ -291,7 +293,7 @@ public:
|
||||
dir2.normalize();
|
||||
std::size_t num = pickedPoints.size();
|
||||
if (num >= 2) {
|
||||
dir1 = pickedPoints[num-1].point - pickedPoints[num-2].point;
|
||||
dir1 = pickedPoints[num - 1].point - pickedPoints[num - 2].point;
|
||||
dir1.normalize();
|
||||
}
|
||||
|
||||
@@ -302,7 +304,7 @@ public:
|
||||
}
|
||||
else {
|
||||
std::vector<Base::Vector3f>& segm = cutLines.back();
|
||||
segm.insert(segm.end(), polyline.begin()+1, polyline.end());
|
||||
segm.insert(segm.end(), polyline.begin() + 1, polyline.end());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,14 +316,14 @@ public:
|
||||
}
|
||||
|
||||
std::vector<PickedPoint> pickedPoints;
|
||||
std::list<std::vector<Base::Vector3f> > cutLines;
|
||||
bool wireClosed{false};
|
||||
double distance{1};
|
||||
double cosAngle{0.7071}; // 45 degree
|
||||
bool approximate{true};
|
||||
std::list<std::vector<Base::Vector3f>> cutLines;
|
||||
bool wireClosed {false};
|
||||
double distance {1};
|
||||
double cosAngle {0.7071};// 45 degree
|
||||
bool approximate {true};
|
||||
ViewProviderCurveOnMesh* curve;
|
||||
Gui::ViewProviderDocumentObject* mesh{0};
|
||||
MeshCore::MeshFacetGrid* grid{nullptr};
|
||||
Gui::ViewProviderDocumentObject* mesh {0};
|
||||
MeshCore::MeshFacetGrid* grid {nullptr};
|
||||
MeshCore::MeshKernel kernel;
|
||||
QPointer<Gui::View3DInventor> viewer;
|
||||
QCursor editcursor;
|
||||
@@ -329,9 +331,9 @@ public:
|
||||
};
|
||||
|
||||
CurveOnMeshHandler::CurveOnMeshHandler(QObject* parent)
|
||||
: QObject(parent), d_ptr(new Private)
|
||||
{
|
||||
}
|
||||
: QObject(parent)
|
||||
, d_ptr(new Private)
|
||||
{}
|
||||
|
||||
CurveOnMeshHandler::~CurveOnMeshHandler()
|
||||
{
|
||||
@@ -343,7 +345,10 @@ void CurveOnMeshHandler::enableApproximation(bool on)
|
||||
d_ptr->approximate = on;
|
||||
}
|
||||
|
||||
void CurveOnMeshHandler::setParameters(int maxDegree, GeomAbs_Shape cont, double tol3d, double angle)
|
||||
void CurveOnMeshHandler::setParameters(int maxDegree,
|
||||
GeomAbs_Shape cont,
|
||||
double tol3d,
|
||||
double angle)
|
||||
{
|
||||
d_ptr->par.maxDegree = maxDegree;
|
||||
d_ptr->par.cont = cont;
|
||||
@@ -369,13 +374,15 @@ void CurveOnMeshHandler::onCreate()
|
||||
std::vector<SbVec3f> segm = d_ptr->convert(*it);
|
||||
if (d_ptr->approximate) {
|
||||
Handle(Geom_BSplineCurve) spline = approximateSpline(segm);
|
||||
if (!spline.IsNull())
|
||||
if (!spline.IsNull()) {
|
||||
displaySpline(spline);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TopoDS_Wire wire;
|
||||
if (makePolyline(segm, wire))
|
||||
if (makePolyline(segm, wire)) {
|
||||
displayPolyline(wire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,8 +457,9 @@ std::vector<SbVec3f> CurveOnMeshHandler::getVertexes() const
|
||||
{
|
||||
std::vector<SbVec3f> pts;
|
||||
pts.reserve(d_ptr->pickedPoints.size());
|
||||
for (const auto & it : d_ptr->pickedPoints)
|
||||
for (const auto& it : d_ptr->pickedPoints) {
|
||||
pts.push_back(it.point);
|
||||
}
|
||||
return pts;
|
||||
}
|
||||
|
||||
@@ -467,19 +475,24 @@ std::vector<SbVec3f> CurveOnMeshHandler::getPoints() const
|
||||
|
||||
Handle(Geom_BSplineCurve) CurveOnMeshHandler::approximateSpline(const std::vector<SbVec3f>& points)
|
||||
{
|
||||
TColgp_Array1OfPnt pnts(1,points.size());
|
||||
TColgp_Array1OfPnt pnts(1, points.size());
|
||||
Standard_Integer index = 1;
|
||||
for (const auto& it : points) {
|
||||
float x,y,z;
|
||||
it.getValue(x,y,z);
|
||||
pnts(index++) = gp_Pnt(x,y,z);
|
||||
float x, y, z;
|
||||
it.getValue(x, y, z);
|
||||
pnts(index++) = gp_Pnt(x, y, z);
|
||||
}
|
||||
|
||||
try {
|
||||
//GeomAPI_PointsToBSpline fit(pnts, 1, 2, GeomAbs_C0, 1.0e-3);
|
||||
//GeomAPI_PointsToBSpline fit(pnts, d_ptr->par.weight1, d_ptr->par.weight2, d_ptr->par.weight3,
|
||||
// d_ptr->par.maxDegree, d_ptr->par.cont, d_ptr->par.tol3d);
|
||||
GeomAPI_PointsToBSpline fit(pnts, 1, d_ptr->par.maxDegree, d_ptr->par.cont, d_ptr->par.tol3d);
|
||||
// GeomAPI_PointsToBSpline fit(pnts, 1, 2, GeomAbs_C0, 1.0e-3);
|
||||
// GeomAPI_PointsToBSpline fit(pnts, d_ptr->par.weight1, d_ptr->par.weight2,
|
||||
// d_ptr->par.weight3,
|
||||
// d_ptr->par.maxDegree, d_ptr->par.cont, d_ptr->par.tol3d);
|
||||
GeomAPI_PointsToBSpline fit(pnts,
|
||||
1,
|
||||
d_ptr->par.maxDegree,
|
||||
d_ptr->par.cont,
|
||||
d_ptr->par.tol3d);
|
||||
Handle(Geom_BSplineCurve) spline = fit.Curve();
|
||||
return spline;
|
||||
}
|
||||
@@ -498,18 +511,18 @@ void CurveOnMeshHandler::approximateEdge(const TopoDS_Edge& edge, double toleran
|
||||
const TColgp_Array1OfPnt& aNodes = aPoly->Nodes();
|
||||
std::vector<SbVec3f> pts;
|
||||
pts.reserve(numNodes);
|
||||
for (int i=aNodes.Lower(); i<=aNodes.Upper(); i++) {
|
||||
for (int i = aNodes.Lower(); i <= aNodes.Upper(); i++) {
|
||||
const gp_Pnt& p = aNodes.Value(i);
|
||||
pts.emplace_back(static_cast<float>(p.X()),
|
||||
static_cast<float>(p.Y()),
|
||||
static_cast<float>(p.Z()));
|
||||
static_cast<float>(p.Y()),
|
||||
static_cast<float>(p.Z()));
|
||||
}
|
||||
|
||||
d_ptr->curve->setPoints(pts);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveOnMeshHandler::displaySpline(const Handle(Geom_BSplineCurve)& spline)
|
||||
void CurveOnMeshHandler::displaySpline(const Handle(Geom_BSplineCurve) & spline)
|
||||
{
|
||||
if (d_ptr->viewer) {
|
||||
double u = spline->FirstParameter();
|
||||
@@ -530,9 +543,9 @@ bool CurveOnMeshHandler::makePolyline(const std::vector<SbVec3f>& points, TopoDS
|
||||
{
|
||||
BRepBuilderAPI_MakePolygon mkPoly;
|
||||
for (const auto& it : points) {
|
||||
float x,y,z;
|
||||
it.getValue(x,y,z);
|
||||
mkPoly.Add(gp_Pnt(x,y,z));
|
||||
float x, y, z;
|
||||
it.getValue(x, y, z);
|
||||
mkPoly.Add(gp_Pnt(x, y, z));
|
||||
}
|
||||
|
||||
if (mkPoly.IsDone()) {
|
||||
@@ -549,7 +562,8 @@ void CurveOnMeshHandler::displayPolyline(const TopoDS_Wire& wire)
|
||||
Gui::View3DInventorViewer* view3d = d_ptr->viewer->getViewer();
|
||||
App::Document* doc = view3d->getDocument()->getDocument();
|
||||
doc->openTransaction("Add polyline");
|
||||
Part::Feature* part = static_cast<Part::Feature*>(doc->addObject("Part::Feature", "Polyline"));
|
||||
Part::Feature* part =
|
||||
static_cast<Part::Feature*>(doc->addObject("Part::Feature", "Polyline"));
|
||||
part->Shape.setValue(wire);
|
||||
doc->commitTransaction();
|
||||
}
|
||||
@@ -579,23 +593,27 @@ void CurveOnMeshHandler::closeWire()
|
||||
}
|
||||
}
|
||||
|
||||
void CurveOnMeshHandler::Private::vertexCallback(void * ud, SoEventCallback * cb)
|
||||
void CurveOnMeshHandler::Private::vertexCallback(void* ud, SoEventCallback* cb)
|
||||
{
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(cb->getUserData());
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(cb->getUserData());
|
||||
const SoEvent* ev = cb->getEvent();
|
||||
if (ev->getTypeId() == SoMouseButtonEvent::getClassTypeId()) {
|
||||
// set as handled
|
||||
cb->setHandled();
|
||||
|
||||
const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ev);
|
||||
if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
|
||||
const SoPickedPoint * pp = cb->getPickedPoint();
|
||||
const SoMouseButtonEvent* mbe = static_cast<const SoMouseButtonEvent*>(ev);
|
||||
if (mbe->getButton() == SoMouseButtonEvent::BUTTON1
|
||||
&& mbe->getState() == SoButtonEvent::DOWN) {
|
||||
const SoPickedPoint* pp = cb->getPickedPoint();
|
||||
if (pp) {
|
||||
CurveOnMeshHandler* self = static_cast<CurveOnMeshHandler*>(ud);
|
||||
if (!self->d_ptr->wireClosed) {
|
||||
Gui::ViewProvider* vp = view->getViewProviderByPathFromTail(pp->getPath());
|
||||
if (vp && vp->getTypeId().isDerivedFrom(MeshGui::ViewProviderMesh::getClassTypeId())) {
|
||||
MeshGui::ViewProviderMesh* mesh = static_cast<MeshGui::ViewProviderMesh*>(vp);
|
||||
if (vp
|
||||
&& vp->getTypeId().isDerivedFrom(
|
||||
MeshGui::ViewProviderMesh::getClassTypeId())) {
|
||||
MeshGui::ViewProviderMesh* mesh =
|
||||
static_cast<MeshGui::ViewProviderMesh*>(vp);
|
||||
const SoDetail* detail = pp->getDetail();
|
||||
if (detail && detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
|
||||
// get the mesh and build a grid
|
||||
@@ -635,7 +653,9 @@ void CurveOnMeshHandler::Private::vertexCallback(void * ud, SoEventCallback * cb
|
||||
}
|
||||
}
|
||||
// try to 'complete' the curve
|
||||
else if (vp && vp->getTypeId().isDerivedFrom(ViewProviderCurveOnMesh::getClassTypeId())) {
|
||||
else if (vp
|
||||
&& vp->getTypeId().isDerivedFrom(
|
||||
ViewProviderCurveOnMesh::getClassTypeId())) {
|
||||
const SbVec3f& p = pp->getPoint();
|
||||
if (self->tryCloseWire(p)) {
|
||||
self->closeWire();
|
||||
@@ -644,11 +664,11 @@ void CurveOnMeshHandler::Private::vertexCallback(void * ud, SoEventCallback * cb
|
||||
}
|
||||
}
|
||||
else {
|
||||
Gui::getMainWindow()->statusBar()->showMessage(
|
||||
tr("No point was picked"));
|
||||
Gui::getMainWindow()->statusBar()->showMessage(tr("No point was picked"));
|
||||
}
|
||||
}
|
||||
else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
|
||||
else if (mbe->getButton() == SoMouseButtonEvent::BUTTON2
|
||||
&& mbe->getState() == SoButtonEvent::UP) {
|
||||
CurveOnMeshHandler* self = static_cast<CurveOnMeshHandler*>(ud);
|
||||
QTimer::singleShot(100, self, &CurveOnMeshHandler::onContextMenu);
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@
|
||||
#ifndef MESHPARTGUI_CURVEONMESH_H
|
||||
#define MESHPARTGUI_CURVEONMESH_H
|
||||
|
||||
#include <memory>
|
||||
#include <QObject>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <GeomAbs_Shape.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <QObject>
|
||||
#include <memory>
|
||||
|
||||
#include <Gui/ViewProviderDocumentObject.h>
|
||||
|
||||
@@ -37,15 +37,16 @@ class SoDrawStyle;
|
||||
class TopoDS_Edge;
|
||||
class TopoDS_Wire;
|
||||
|
||||
namespace Gui {
|
||||
namespace Gui
|
||||
{
|
||||
class View3DInventor;
|
||||
class ViewProvider;
|
||||
}
|
||||
}// namespace Gui
|
||||
|
||||
namespace MeshPartGui
|
||||
{
|
||||
|
||||
class ViewProviderCurveOnMesh : public Gui::ViewProviderDocumentObject
|
||||
class ViewProviderCurveOnMesh: public Gui::ViewProviderDocumentObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(MeshPartGui::ViewProviderCurveOnMesh);
|
||||
|
||||
@@ -59,13 +60,13 @@ public:
|
||||
void setDisplayMode(const char* ModeName) override;
|
||||
|
||||
private:
|
||||
SoCoordinate3 * pcCoords;
|
||||
SoCoordinate3 * pcNodes;
|
||||
SoDrawStyle * pcPointStyle;
|
||||
SoDrawStyle * pcLinesStyle;
|
||||
SoCoordinate3* pcCoords;
|
||||
SoCoordinate3* pcNodes;
|
||||
SoDrawStyle* pcPointStyle;
|
||||
SoDrawStyle* pcLinesStyle;
|
||||
};
|
||||
|
||||
class CurveOnMeshHandler : public QObject
|
||||
class CurveOnMeshHandler: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -81,7 +82,7 @@ public:
|
||||
private:
|
||||
Handle(Geom_BSplineCurve) approximateSpline(const std::vector<SbVec3f>& points);
|
||||
void approximateEdge(const TopoDS_Edge&, double tolerance);
|
||||
void displaySpline(const Handle(Geom_BSplineCurve)&);
|
||||
void displaySpline(const Handle(Geom_BSplineCurve) &);
|
||||
bool makePolyline(const std::vector<SbVec3f>& points, TopoDS_Wire& wire);
|
||||
void displayPolyline(const TopoDS_Wire& wire);
|
||||
std::vector<SbVec3f> getPoints() const;
|
||||
@@ -101,6 +102,6 @@ private:
|
||||
std::unique_ptr<Private> d_ptr;
|
||||
};
|
||||
|
||||
}
|
||||
}// namespace MeshPartGui
|
||||
|
||||
#endif // MESHPARTGUI_CURVEONMESH_H
|
||||
#endif// MESHPARTGUI_CURVEONMESH_H
|
||||
|
||||
@@ -1,24 +1,24 @@
|
||||
#***************************************************************************
|
||||
#* Copyright (c) 2017 Lorenz Lechner *
|
||||
#* *
|
||||
#* 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 *
|
||||
#* *
|
||||
#***************************************************************************/
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2017 Lorenz Lechner *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * *
|
||||
# ***************************************************************************/
|
||||
|
||||
import Mesh
|
||||
import FreeCAD as App
|
||||
@@ -26,7 +26,8 @@ import FreeCADGui as Gui
|
||||
import Part
|
||||
import MeshPartGui
|
||||
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP # for translations
|
||||
from PySide.QtCore import QT_TRANSLATE_NOOP # for translations
|
||||
|
||||
|
||||
class BaseCommand(object):
|
||||
def __init__(self):
|
||||
@@ -43,21 +44,28 @@ class CreateFlatMesh(BaseCommand):
|
||||
"""create flat wires from a meshed face"""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'MeshPart_CreateFlatMesh.svg',
|
||||
'MenuText': QT_TRANSLATE_NOOP("MeshPart_CreateFlatMesh", "Unwrap Mesh"),
|
||||
'ToolTip': QT_TRANSLATE_NOOP("MeshPart_CreateFlatMesh", "Find a flat representation of a mesh.")}
|
||||
return {
|
||||
"Pixmap": "MeshPart_CreateFlatMesh.svg",
|
||||
"MenuText": QT_TRANSLATE_NOOP("MeshPart_CreateFlatMesh", "Unwrap Mesh"),
|
||||
"ToolTip": QT_TRANSLATE_NOOP(
|
||||
"MeshPart_CreateFlatMesh", "Find a flat representation of a mesh."
|
||||
),
|
||||
}
|
||||
|
||||
def Activated(self):
|
||||
import numpy as np
|
||||
import flatmesh
|
||||
obj = Gui.Selection.getSelection()[0] # obj must be a Mesh (Mesh-Design->Meshes->Create-Mesh)
|
||||
|
||||
obj = Gui.Selection.getSelection()[
|
||||
0
|
||||
] # obj must be a Mesh (Mesh-Design->Meshes->Create-Mesh)
|
||||
points = np.array([[i.x, i.y, i.z] for i in obj.Mesh.Points])
|
||||
faces = np.array([list(i) for i in obj.Mesh.Topology[1]])
|
||||
faces = np.array([list(i) for i in obj.Mesh.Topology[1]])
|
||||
flattener = flatmesh.FaceUnwrapper(points, faces)
|
||||
flattener.findFlatNodes(5, 0.95)
|
||||
boundaries = flattener.getFlatBoundaryNodes()
|
||||
#print('number of nodes: {}'.format(len(flattener.ze_nodes)))
|
||||
#print('number of faces: {}'.format(len(flattener.tris)))
|
||||
# print('number of nodes: {}'.format(len(flattener.ze_nodes)))
|
||||
# print('number of faces: {}'.format(len(flattener.tris)))
|
||||
|
||||
wires = []
|
||||
for edge in boundaries:
|
||||
@@ -65,23 +73,28 @@ class CreateFlatMesh(BaseCommand):
|
||||
Part.show(Part.Wire(pi))
|
||||
|
||||
def IsActive(self):
|
||||
assert(super(CreateFlatMesh, self).IsActive())
|
||||
assert(isinstance(Gui.Selection.getSelection()[0].Mesh, Mesh.Mesh))
|
||||
assert super(CreateFlatMesh, self).IsActive()
|
||||
assert isinstance(Gui.Selection.getSelection()[0].Mesh, Mesh.Mesh)
|
||||
return True
|
||||
|
||||
|
||||
class CreateFlatFace(BaseCommand):
|
||||
"""create a flat face from a single face
|
||||
only full faces are supported right now"""
|
||||
only full faces are supported right now"""
|
||||
|
||||
def GetResources(self):
|
||||
return {'Pixmap': 'MeshPart_CreateFlatFace.svg',
|
||||
'MenuText': QT_TRANSLATE_NOOP("MeshPart_CreateFlatFace", "Unwrap Face"),
|
||||
'ToolTip': QT_TRANSLATE_NOOP("MeshPart_CreateFlatFace", "Find a flat representation of a face.")}
|
||||
return {
|
||||
"Pixmap": "MeshPart_CreateFlatFace.svg",
|
||||
"MenuText": QT_TRANSLATE_NOOP("MeshPart_CreateFlatFace", "Unwrap Face"),
|
||||
"ToolTip": QT_TRANSLATE_NOOP(
|
||||
"MeshPart_CreateFlatFace", "Find a flat representation of a face."
|
||||
),
|
||||
}
|
||||
|
||||
def Activated(self):
|
||||
import numpy as np
|
||||
import flatmesh
|
||||
|
||||
face = Gui.Selection.getSelectionEx()[0].SubObjects[0]
|
||||
shape = face.toNurbs()
|
||||
face = shape.Faces[0]
|
||||
@@ -104,16 +117,17 @@ class CreateFlatFace(BaseCommand):
|
||||
Part.show(bs.toShape())
|
||||
|
||||
def IsActive(self):
|
||||
assert(super(CreateFlatFace, self).IsActive())
|
||||
assert(isinstance(Gui.Selection.getSelectionEx()[0].SubObjects[0], Part.Face))
|
||||
assert super(CreateFlatFace, self).IsActive()
|
||||
assert isinstance(Gui.Selection.getSelectionEx()[0].SubObjects[0], Part.Face)
|
||||
return True
|
||||
|
||||
|
||||
# Test if pybind11 dependency is available
|
||||
try:
|
||||
import flatmesh
|
||||
Gui.addCommand('MeshPart_CreateFlatMesh', CreateFlatMesh())
|
||||
Gui.addCommand('MeshPart_CreateFlatFace', CreateFlatFace())
|
||||
|
||||
Gui.addCommand("MeshPart_CreateFlatMesh", CreateFlatMesh())
|
||||
Gui.addCommand("MeshPart_CreateFlatFace", CreateFlatFace())
|
||||
except ImportError:
|
||||
App.Console.PrintLog("flatmesh-commands are not available\n")
|
||||
App.Console.PrintLog("flatmesh needs pybind11 as build dependency\n")
|
||||
|
||||
@@ -26,9 +26,9 @@
|
||||
#include <FCConfig.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# pragma warning(disable : 4005)
|
||||
# pragma warning(disable : 4290)
|
||||
# pragma warning(disable : 4275)
|
||||
#pragma warning(disable : 4005)
|
||||
#pragma warning(disable : 4290)
|
||||
#pragma warning(disable : 4275)
|
||||
#endif
|
||||
|
||||
#ifdef _PreComp_
|
||||
@@ -40,31 +40,30 @@
|
||||
// Qt Toolkit
|
||||
#include <QApplication>
|
||||
#include <QFuture>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QMenu>
|
||||
#include <QMessageBox>
|
||||
#include <QPointer>
|
||||
#include <QPushButton>
|
||||
#include <QStatusBar>
|
||||
#include <QtConcurrentMap>
|
||||
#include <QTimer>
|
||||
#include <QtConcurrentMap>
|
||||
|
||||
// OCCT
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
#include <BRepMesh_IncrementalMesh.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <GeomAPI_PointsToBSpline.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Poly_Polygon3D.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
|
||||
// Inventor
|
||||
#include <Inventor/SoPickedPoint.h>
|
||||
@@ -77,6 +76,6 @@
|
||||
#include <Inventor/nodes/SoPointSet.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
|
||||
#endif //_PreComp_
|
||||
#endif//_PreComp_
|
||||
|
||||
#endif // __PRECOMPILED_GUI__
|
||||
#endif// __PRECOMPILED_GUI__
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
|
||||
#include <Gui/View3DInventor.h>
|
||||
|
||||
#include "CurveOnMesh.h"
|
||||
#include "TaskCurveOnMesh.h"
|
||||
#include "ui_TaskCurveOnMesh.h"
|
||||
#include "CurveOnMesh.h"
|
||||
|
||||
|
||||
using namespace MeshPartGui;
|
||||
@@ -38,8 +38,7 @@ CurveOnMeshWidget::CurveOnMeshWidget(Gui::View3DInventor* view, QWidget* parent)
|
||||
, myView(view)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
connect(ui->startButton, &QPushButton::clicked,
|
||||
this, &CurveOnMeshWidget::onStartButtonClicked);
|
||||
connect(ui->startButton, &QPushButton::clicked, this, &CurveOnMeshWidget::onStartButtonClicked);
|
||||
this->setup();
|
||||
}
|
||||
|
||||
@@ -61,12 +60,13 @@ void CurveOnMeshWidget::setup()
|
||||
ui->continuity->addItem(QString::fromLatin1("C3"), static_cast<int>(GeomAbs_C3));
|
||||
ui->continuity->setCurrentIndex(2);
|
||||
|
||||
for (int i=0; i<8; i++)
|
||||
ui->maxDegree->addItem(QString::number(i+1));
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ui->maxDegree->addItem(QString::number(i + 1));
|
||||
}
|
||||
ui->maxDegree->setCurrentIndex(4);
|
||||
}
|
||||
|
||||
void CurveOnMeshWidget::changeEvent(QEvent *e)
|
||||
void CurveOnMeshWidget::changeEvent(QEvent* e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
ui->retranslateUi(this);
|
||||
@@ -97,9 +97,7 @@ void CurveOnMeshWidget::reject()
|
||||
TaskCurveOnMesh::TaskCurveOnMesh(Gui::View3DInventor* view)
|
||||
{
|
||||
widget = new CurveOnMeshWidget(view);
|
||||
taskbox = new Gui::TaskView::TaskBox(
|
||||
QPixmap(),
|
||||
widget->windowTitle(), true, nullptr);
|
||||
taskbox = new Gui::TaskView::TaskBox(QPixmap(), widget->windowTitle(), true, nullptr);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
|
||||
|
||||
namespace Gui {
|
||||
namespace Gui
|
||||
{
|
||||
class View3DInventor;
|
||||
}
|
||||
|
||||
@@ -39,18 +40,18 @@ namespace MeshPartGui
|
||||
class Ui_TaskCurveOnMesh;
|
||||
class CurveOnMeshHandler;
|
||||
|
||||
class CurveOnMeshWidget : public QWidget
|
||||
class CurveOnMeshWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit CurveOnMeshWidget(Gui::View3DInventor* view, QWidget* parent=nullptr);
|
||||
explicit CurveOnMeshWidget(Gui::View3DInventor* view, QWidget* parent = nullptr);
|
||||
~CurveOnMeshWidget() override;
|
||||
|
||||
void reject();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
void setup();
|
||||
|
||||
private:
|
||||
@@ -62,7 +63,7 @@ private:
|
||||
QPointer<Gui::View3DInventor> myView;
|
||||
};
|
||||
|
||||
class TaskCurveOnMesh : public Gui::TaskView::TaskDialog
|
||||
class TaskCurveOnMesh: public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -73,13 +74,15 @@ public:
|
||||
bool reject() override;
|
||||
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{ return QDialogButtonBox::Close; }
|
||||
{
|
||||
return QDialogButtonBox::Close;
|
||||
}
|
||||
|
||||
private:
|
||||
CurveOnMeshWidget* widget;
|
||||
Gui::TaskView::TaskBox* taskbox;
|
||||
};
|
||||
|
||||
} //namespace MeshPartGui
|
||||
}// namespace MeshPartGui
|
||||
|
||||
#endif // MESHPART_GUI_TASKCURVEONMESH_H
|
||||
#endif// MESHPART_GUI_TASKCURVEONMESH_H
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <QMessageBox>
|
||||
#include <QMessageBox>
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Stream.h>
|
||||
#include <Base/Tools.h>
|
||||
#include <App/Application.h>
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
@@ -39,8 +39,8 @@
|
||||
#include <Gui/Selection.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
#include <Mod/Mesh/App/MeshFeature.h>
|
||||
#include <Mod/Part/App/BodyBase.h>
|
||||
#include <Mod/Mesh/Gui/ViewProvider.h>
|
||||
#include <Mod/Part/App/BodyBase.h>
|
||||
#include <Mod/Part/Gui/ViewProvider.h>
|
||||
|
||||
#include "Tessellation.h"
|
||||
@@ -52,7 +52,8 @@ using namespace MeshPartGui;
|
||||
/* TRANSLATOR MeshPartGui::Tessellation */
|
||||
|
||||
Tessellation::Tessellation(QWidget* parent)
|
||||
: QWidget(parent), ui(new Ui_Tessellation)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui_Tessellation)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
gmsh = new Mesh2ShapeGmsh(this);
|
||||
@@ -60,8 +61,8 @@ Tessellation::Tessellation(QWidget* parent)
|
||||
|
||||
ui->stackedWidget->addTab(gmsh, tr("Gmsh"));
|
||||
|
||||
ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Mod/Mesh/Meshing/Standard");
|
||||
ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Mesh/Meshing/Standard");
|
||||
double value = ui->spinSurfaceDeviation->value().getValue();
|
||||
value = handle->GetFloat("LinearDeflection", value);
|
||||
double angle = ui->spinAngularDeviation->value().getValue();
|
||||
@@ -79,10 +80,10 @@ Tessellation::Tessellation(QWidget* parent)
|
||||
ui->comboFineness->setCurrentIndex(2);
|
||||
onComboFinenessCurrentIndexChanged(2);
|
||||
|
||||
#if !defined (HAVE_MEFISTO)
|
||||
#if !defined(HAVE_MEFISTO)
|
||||
ui->stackedWidget->setTabEnabled(Mefisto, false);
|
||||
#endif
|
||||
#if !defined (HAVE_NETGEN)
|
||||
#if !defined(HAVE_NETGEN)
|
||||
ui->stackedWidget->setTabEnabled(Netgen, false);
|
||||
#endif
|
||||
|
||||
@@ -101,14 +102,22 @@ Tessellation::~Tessellation() = default;
|
||||
void Tessellation::setupConnections()
|
||||
{
|
||||
connect(gmsh, &Mesh2ShapeGmsh::processed, this, &Tessellation::gmshProcessed);
|
||||
connect(ui->estimateMaximumEdgeLength, &QPushButton::clicked,
|
||||
this, &Tessellation::onEstimateMaximumEdgeLengthClicked);
|
||||
connect(ui->comboFineness, qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this, &Tessellation::onComboFinenessCurrentIndexChanged);
|
||||
connect(ui->checkSecondOrder, &QCheckBox::toggled,
|
||||
this, &Tessellation::onCheckSecondOrderToggled);
|
||||
connect(ui->checkQuadDominated, &QCheckBox::toggled,
|
||||
this, &Tessellation::onCheckQuadDominatedToggled);
|
||||
connect(ui->estimateMaximumEdgeLength,
|
||||
&QPushButton::clicked,
|
||||
this,
|
||||
&Tessellation::onEstimateMaximumEdgeLengthClicked);
|
||||
connect(ui->comboFineness,
|
||||
qOverload<int>(&QComboBox::currentIndexChanged),
|
||||
this,
|
||||
&Tessellation::onComboFinenessCurrentIndexChanged);
|
||||
connect(ui->checkSecondOrder,
|
||||
&QCheckBox::toggled,
|
||||
this,
|
||||
&Tessellation::onCheckSecondOrderToggled);
|
||||
connect(ui->checkQuadDominated,
|
||||
&QCheckBox::toggled,
|
||||
this,
|
||||
&Tessellation::onCheckQuadDominatedToggled);
|
||||
}
|
||||
|
||||
void Tessellation::meshingMethod(int id)
|
||||
@@ -130,56 +139,59 @@ void Tessellation::onComboFinenessCurrentIndexChanged(int index)
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case VeryCoarse:
|
||||
ui->doubleGrading->setValue(0.7);
|
||||
ui->spinEdgeElements->setValue(0.3);
|
||||
ui->spinCurvatureElements->setValue(1.0);
|
||||
break;
|
||||
case Coarse:
|
||||
ui->doubleGrading->setValue(0.5);
|
||||
ui->spinEdgeElements->setValue(0.5);
|
||||
ui->spinCurvatureElements->setValue(1.5);
|
||||
break;
|
||||
case Moderate:
|
||||
ui->doubleGrading->setValue(0.3);
|
||||
ui->spinEdgeElements->setValue(1.0);
|
||||
ui->spinCurvatureElements->setValue(2.0);
|
||||
break;
|
||||
case Fine:
|
||||
ui->doubleGrading->setValue(0.2);
|
||||
ui->spinEdgeElements->setValue(2.0);
|
||||
ui->spinCurvatureElements->setValue(3.0);
|
||||
break;
|
||||
case VeryFine:
|
||||
ui->doubleGrading->setValue(0.1);
|
||||
ui->spinEdgeElements->setValue(3.0);
|
||||
ui->spinCurvatureElements->setValue(5.0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case VeryCoarse:
|
||||
ui->doubleGrading->setValue(0.7);
|
||||
ui->spinEdgeElements->setValue(0.3);
|
||||
ui->spinCurvatureElements->setValue(1.0);
|
||||
break;
|
||||
case Coarse:
|
||||
ui->doubleGrading->setValue(0.5);
|
||||
ui->spinEdgeElements->setValue(0.5);
|
||||
ui->spinCurvatureElements->setValue(1.5);
|
||||
break;
|
||||
case Moderate:
|
||||
ui->doubleGrading->setValue(0.3);
|
||||
ui->spinEdgeElements->setValue(1.0);
|
||||
ui->spinCurvatureElements->setValue(2.0);
|
||||
break;
|
||||
case Fine:
|
||||
ui->doubleGrading->setValue(0.2);
|
||||
ui->spinEdgeElements->setValue(2.0);
|
||||
ui->spinCurvatureElements->setValue(3.0);
|
||||
break;
|
||||
case VeryFine:
|
||||
ui->doubleGrading->setValue(0.1);
|
||||
ui->spinEdgeElements->setValue(3.0);
|
||||
ui->spinCurvatureElements->setValue(5.0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Tessellation::onCheckSecondOrderToggled(bool on)
|
||||
{
|
||||
if (on)
|
||||
if (on) {
|
||||
ui->checkQuadDominated->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Tessellation::onCheckQuadDominatedToggled(bool on)
|
||||
{
|
||||
if (on)
|
||||
if (on) {
|
||||
ui->checkSecondOrder->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
void Tessellation::gmshProcessed()
|
||||
{
|
||||
bool doClose = !ui->checkBoxDontQuit->isChecked();
|
||||
if (doClose)
|
||||
if (doClose) {
|
||||
Gui::Control().reject();
|
||||
}
|
||||
}
|
||||
|
||||
void Tessellation::changeEvent(QEvent *e)
|
||||
void Tessellation::changeEvent(QEvent* e)
|
||||
{
|
||||
if (e->type() == QEvent::LanguageChange) {
|
||||
int index = ui->comboFineness->currentIndex();
|
||||
@@ -202,8 +214,8 @@ void Tessellation::onEstimateMaximumEdgeLengthClicked()
|
||||
}
|
||||
|
||||
double edgeLen = 0;
|
||||
for (auto &sel : Gui::Selection().getSelection("*", Gui::ResolveMode::NoResolve)) {
|
||||
auto shape = Part::Feature::getTopoShape(sel.pObject,sel.SubName);
|
||||
for (auto& sel : Gui::Selection().getSelection("*", Gui::ResolveMode::NoResolve)) {
|
||||
auto shape = Part::Feature::getTopoShape(sel.pObject, sel.SubName);
|
||||
if (shape.hasSubShape(TopAbs_FACE)) {
|
||||
Base::BoundBox3d bbox = shape.getBoundBox();
|
||||
edgeLen = std::max<double>(edgeLen, bbox.LengthX());
|
||||
@@ -212,7 +224,7 @@ void Tessellation::onEstimateMaximumEdgeLengthClicked()
|
||||
}
|
||||
}
|
||||
|
||||
ui->spinMaximumEdgeLength->setValue(edgeLen/10);
|
||||
ui->spinMaximumEdgeLength->setValue(edgeLen / 10);
|
||||
}
|
||||
|
||||
bool Tessellation::accept()
|
||||
@@ -234,8 +246,8 @@ bool Tessellation::accept()
|
||||
|
||||
bool bodyWithNoTip = false;
|
||||
bool partWithNoFace = false;
|
||||
for (auto &sel : Gui::Selection().getSelection("*", Gui::ResolveMode::NoResolve)) {
|
||||
auto shape = Part::Feature::getTopoShape(sel.pObject,sel.SubName);
|
||||
for (auto& sel : Gui::Selection().getSelection("*", Gui::ResolveMode::NoResolve)) {
|
||||
auto shape = Part::Feature::getTopoShape(sel.pObject, sel.SubName);
|
||||
if (shape.hasSubShape(TopAbs_FACE)) {
|
||||
shapeObjects.emplace_back(sel.pObject, sel.SubName);
|
||||
}
|
||||
@@ -254,12 +266,17 @@ bool Tessellation::accept()
|
||||
|
||||
if (shapeObjects.empty()) {
|
||||
if (bodyWithNoTip) {
|
||||
QMessageBox::critical(this, windowTitle(), tr("You have selected a body without tip.\n"
|
||||
"Either set the tip of the body or select a different shape, please."));
|
||||
QMessageBox::critical(
|
||||
this,
|
||||
windowTitle(),
|
||||
tr("You have selected a body without tip.\n"
|
||||
"Either set the tip of the body or select a different shape, please."));
|
||||
}
|
||||
else if (partWithNoFace) {
|
||||
QMessageBox::critical(this, windowTitle(), tr("You have selected a shape without faces.\n"
|
||||
"Select a different shape, please."));
|
||||
QMessageBox::critical(this,
|
||||
windowTitle(),
|
||||
tr("You have selected a shape without faces.\n"
|
||||
"Select a different shape, please."));
|
||||
}
|
||||
else {
|
||||
QMessageBox::critical(this, windowTitle(), tr("Select a shape for meshing, first."));
|
||||
@@ -282,7 +299,9 @@ bool Tessellation::accept()
|
||||
}
|
||||
}
|
||||
|
||||
void Tessellation::process(int method, App::Document* doc, const std::list<App::SubObjectT>& shapeObjects)
|
||||
void Tessellation::process(int method,
|
||||
App::Document* doc,
|
||||
const std::list<App::SubObjectT>& shapeObjects)
|
||||
{
|
||||
try {
|
||||
Gui::WaitCursor wc;
|
||||
@@ -290,37 +309,36 @@ void Tessellation::process(int method, App::Document* doc, const std::list<App::
|
||||
saveParameters(method);
|
||||
|
||||
doc->openTransaction("Meshing");
|
||||
for (auto &info : shapeObjects) {
|
||||
for (auto& info : shapeObjects) {
|
||||
QString subname = QString::fromLatin1(info.getSubName().c_str());
|
||||
QString objname = QString::fromLatin1(info.getObjectName().c_str());
|
||||
|
||||
auto obj = info.getObject();
|
||||
if (!obj)
|
||||
if (!obj) {
|
||||
continue;
|
||||
}
|
||||
auto sobj = obj->getSubObject(info.getSubName().c_str());
|
||||
if (!sobj)
|
||||
if (!sobj) {
|
||||
continue;
|
||||
}
|
||||
sobj = sobj->getLinkedObject(true);
|
||||
if (!sobj)
|
||||
if (!sobj) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString label = QString::fromUtf8(sobj->Label.getValue());
|
||||
|
||||
QString param = getMeshingParameters(method, sobj);
|
||||
|
||||
QString cmd = QString::fromLatin1(
|
||||
"__doc__=FreeCAD.getDocument(\"%1\")\n"
|
||||
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
|
||||
"__part__=__doc__.getObject(\"%2\")\n"
|
||||
"__shape__=Part.getShape(__part__,\"%3\")\n"
|
||||
"__mesh__.Mesh=MeshPart.meshFromShape(%4)\n"
|
||||
"__mesh__.Label=\"%5 (Meshed)\"\n"
|
||||
"del __doc__, __mesh__, __part__, __shape__\n")
|
||||
.arg(this->document,
|
||||
objname,
|
||||
subname,
|
||||
param,
|
||||
label);
|
||||
QString cmd =
|
||||
QString::fromLatin1("__doc__=FreeCAD.getDocument(\"%1\")\n"
|
||||
"__mesh__=__doc__.addObject(\"Mesh::Feature\",\"Mesh\")\n"
|
||||
"__part__=__doc__.getObject(\"%2\")\n"
|
||||
"__shape__=Part.getShape(__part__,\"%3\")\n"
|
||||
"__mesh__.Mesh=MeshPart.meshFromShape(%4)\n"
|
||||
"__mesh__.Label=\"%5 (Meshed)\"\n"
|
||||
"del __doc__, __mesh__, __part__, __shape__\n")
|
||||
.arg(this->document, objname, subname, param, label);
|
||||
|
||||
Gui::Command::runCommand(Gui::Command::Doc, cmd.toUtf8());
|
||||
|
||||
@@ -337,8 +355,8 @@ void Tessellation::process(int method, App::Document* doc, const std::list<App::
|
||||
void Tessellation::saveParameters(int method)
|
||||
{
|
||||
if (method == Standard) {
|
||||
ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath
|
||||
("User parameter:BaseApp/Preferences/Mod/Mesh/Meshing/Standard");
|
||||
ParameterGrp::handle handle = App::GetApplication().GetParameterGroupByPath(
|
||||
"User parameter:BaseApp/Preferences/Mod/Mesh/Meshing/Standard");
|
||||
double value = ui->spinSurfaceDeviation->value().getValue();
|
||||
handle->SetFloat("LinearDeflection", value);
|
||||
double angle = ui->spinAngularDeviation->value().getValue();
|
||||
@@ -353,12 +371,12 @@ void Tessellation::setFaceColors(int method, App::Document* doc, App::DocumentOb
|
||||
// if Standard mesher is used and face colors should be applied
|
||||
if (method == Standard) {
|
||||
if (ui->meshShapeColors->isChecked()) {
|
||||
Gui::ViewProvider* vpm = Gui::Application::Instance->getViewProvider
|
||||
(doc->getActiveObject());
|
||||
Gui::ViewProvider* vpm =
|
||||
Gui::Application::Instance->getViewProvider(doc->getActiveObject());
|
||||
MeshGui::ViewProviderMesh* vpmesh = dynamic_cast<MeshGui::ViewProviderMesh*>(vpm);
|
||||
|
||||
auto svp = Base::freecad_dynamic_cast<PartGui::ViewProviderPartExt>(
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
if (vpmesh && svp) {
|
||||
std::vector<App::Color> diff_col = svp->DiffuseColor.getValues();
|
||||
if (ui->groupsFaceColors->isChecked()) {
|
||||
@@ -374,12 +392,14 @@ std::vector<App::Color> Tessellation::getUniqueColors(const std::vector<App::Col
|
||||
{
|
||||
// unique colors
|
||||
std::set<uint32_t> col_set;
|
||||
for (const auto& it : colors)
|
||||
for (const auto& it : colors) {
|
||||
col_set.insert(it.getPackedValue());
|
||||
}
|
||||
|
||||
std::vector<App::Color> unique;
|
||||
for (const auto& it : col_set)
|
||||
for (const auto& it : col_set) {
|
||||
unique.emplace_back(it);
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
@@ -411,14 +431,15 @@ QString Tessellation::getStandardParameters(App::DocumentObject* obj) const
|
||||
"LinearDeflection=%1, "
|
||||
"AngularDeflection=%2, "
|
||||
"Relative=%3")
|
||||
.arg(devFace)
|
||||
.arg(devAngle)
|
||||
.arg(relative ? QString::fromLatin1("True") : QString::fromLatin1("False"));
|
||||
if (ui->meshShapeColors->isChecked())
|
||||
.arg(devFace)
|
||||
.arg(devAngle)
|
||||
.arg(relative ? QString::fromLatin1("True") : QString::fromLatin1("False"));
|
||||
if (ui->meshShapeColors->isChecked()) {
|
||||
param += QString::fromLatin1(",Segments=True");
|
||||
}
|
||||
|
||||
auto svp = Base::freecad_dynamic_cast<PartGui::ViewProviderPartExt>(
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
Gui::Application::Instance->getViewProvider(obj));
|
||||
if (ui->groupsFaceColors->isChecked() && svp) {
|
||||
// TODO: currently, we can only retrieve part feature
|
||||
// color. The problem is that if the feature is linked,
|
||||
@@ -431,7 +452,8 @@ QString Tessellation::getStandardParameters(App::DocumentObject* obj) const
|
||||
//
|
||||
// PartGui::ViewProviderPartExt::getShapeColors().
|
||||
//
|
||||
param += QString::fromLatin1(",GroupColors=Gui.getDocument('%1').getObject('%2').DiffuseColor")
|
||||
param +=
|
||||
QString::fromLatin1(",GroupColors=Gui.getDocument('%1').getObject('%2').DiffuseColor")
|
||||
.arg(QString::fromLatin1(obj->getDocument()->getName()),
|
||||
QString::fromLatin1(obj->getNameInDocument()));
|
||||
}
|
||||
@@ -442,8 +464,9 @@ QString Tessellation::getStandardParameters(App::DocumentObject* obj) const
|
||||
QString Tessellation::getMefistoParameters() const
|
||||
{
|
||||
double maxEdge = ui->spinMaximumEdgeLength->value().getValue();
|
||||
if (!ui->spinMaximumEdgeLength->isEnabled())
|
||||
if (!ui->spinMaximumEdgeLength->isEnabled()) {
|
||||
maxEdge = 0;
|
||||
}
|
||||
return QString::fromLatin1("Shape=__shape__,MaxLength=%1").arg(maxEdge);
|
||||
}
|
||||
|
||||
@@ -459,21 +482,22 @@ QString Tessellation::getNetgenParameters() const
|
||||
bool allowquad = ui->checkQuadDominated->isChecked();
|
||||
if (fineness < 5) {
|
||||
param = QString::fromLatin1("Shape=__shape__,"
|
||||
"Fineness=%1,SecondOrder=%2,Optimize=%3,AllowQuad=%4")
|
||||
.arg(fineness)
|
||||
.arg(secondOrder ? 1 : 0)
|
||||
.arg(optimize ? 1 : 0)
|
||||
.arg(allowquad ? 1 : 0);
|
||||
"Fineness=%1,SecondOrder=%2,Optimize=%3,AllowQuad=%4")
|
||||
.arg(fineness)
|
||||
.arg(secondOrder ? 1 : 0)
|
||||
.arg(optimize ? 1 : 0)
|
||||
.arg(allowquad ? 1 : 0);
|
||||
}
|
||||
else {
|
||||
param = QString::fromLatin1("Shape=__shape__,"
|
||||
"GrowthRate=%1,SegPerEdge=%2,SegPerRadius=%3,SecondOrder=%4,Optimize=%5,AllowQuad=%6")
|
||||
.arg(growthRate)
|
||||
.arg(nbSegPerEdge)
|
||||
.arg(nbSegPerRadius)
|
||||
.arg(secondOrder ? 1 : 0)
|
||||
.arg(optimize ? 1 : 0)
|
||||
.arg(allowquad ? 1 : 0);
|
||||
"GrowthRate=%1,SegPerEdge=%2,SegPerRadius=%3,SecondOrder=%4,"
|
||||
"Optimize=%5,AllowQuad=%6")
|
||||
.arg(growthRate)
|
||||
.arg(nbSegPerEdge)
|
||||
.arg(nbSegPerRadius)
|
||||
.arg(secondOrder ? 1 : 0)
|
||||
.arg(optimize ? 1 : 0)
|
||||
.arg(allowquad ? 1 : 0);
|
||||
}
|
||||
|
||||
return param;
|
||||
@@ -481,7 +505,8 @@ QString Tessellation::getNetgenParameters() const
|
||||
|
||||
// ---------------------------------------
|
||||
|
||||
class Mesh2ShapeGmsh::Private {
|
||||
class Mesh2ShapeGmsh::Private
|
||||
{
|
||||
public:
|
||||
std::string label;
|
||||
std::list<App::SubObjectT> shapes;
|
||||
@@ -492,8 +517,8 @@ public:
|
||||
};
|
||||
|
||||
Mesh2ShapeGmsh::Mesh2ShapeGmsh(QWidget* parent, Qt::WindowFlags fl)
|
||||
: GmshWidget(parent, fl)
|
||||
, d(new Private())
|
||||
: GmshWidget(parent, fl)
|
||||
, d(new Private())
|
||||
{
|
||||
d->cadFile = App::Application::getTempFileName() + "mesh.brep";
|
||||
d->stlFile = App::Application::getTempFileName() + "mesh.stl";
|
||||
@@ -526,40 +551,46 @@ bool Mesh2ShapeGmsh::writeProject(QString& inpFile, QString& outFile)
|
||||
// Parameters
|
||||
int algorithm = meshingAlgorithm();
|
||||
double maxSize = getMaxSize();
|
||||
if (maxSize == 0.0)
|
||||
if (maxSize == 0.0) {
|
||||
maxSize = 1.0e22;
|
||||
}
|
||||
double minSize = getMinSize();
|
||||
|
||||
// Gmsh geo file
|
||||
Base::FileInfo geo(d->geoFile);
|
||||
Base::ofstream geoOut(geo, std::ios::out);
|
||||
geoOut << "// geo file for meshing with Gmsh meshing software created by FreeCAD\n"
|
||||
<< "// open brep geometry\n"
|
||||
<< "Merge \"" << d->cadFile << "\";\n\n"
|
||||
<< "// Characteristic Length\n"
|
||||
<< "// no boundary layer settings for this mesh\n"
|
||||
<< "// min, max Characteristic Length\n"
|
||||
<< "Mesh.CharacteristicLengthMax = " << maxSize << ";\n"
|
||||
<< "Mesh.CharacteristicLengthMin = " << minSize << ";\n\n"
|
||||
<< "// optimize the mesh\n"
|
||||
<< "Mesh.Optimize = 1;\n"
|
||||
<< "Mesh.OptimizeNetgen = 0;\n"
|
||||
<< "// High-order meshes optimization (0=none, 1=optimization, 2=elastic+optimization, 3=elastic, 4=fast curving)\n"
|
||||
<< "Mesh.HighOrderOptimize = 0;\n\n"
|
||||
<< "// mesh order\n"
|
||||
<< "Mesh.ElementOrder = 2;\n"
|
||||
<< "// Second order nodes are created by linear interpolation instead by curvilinear\n"
|
||||
<< "Mesh.SecondOrderLinear = 1;\n\n"
|
||||
<< "// mesh algorithm, only a few algorithms are usable with 3D boundary layer generation\n"
|
||||
<< "// 2D mesh algorithm (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, 7=BAMG, 8=DelQuad, 9=Packing of Parallelograms)\n"
|
||||
<< "Mesh.Algorithm = " << algorithm << ";\n"
|
||||
<< "// 3D mesh algorithm (1=Delaunay, 2=New Delaunay, 4=Frontal, 7=MMG3D, 9=R-tree, 10=HTX)\n"
|
||||
<< "Mesh.Algorithm3D = 1;\n\n"
|
||||
<< "// meshing\n"
|
||||
<< "// set geometrical tolerance (also used for merging nodes)\n"
|
||||
<< "Geometry.Tolerance = 1e-06;\n"
|
||||
<< "Mesh 2;\n"
|
||||
<< "Coherence Mesh; // Remove duplicate vertices\n";
|
||||
<< "// open brep geometry\n"
|
||||
<< "Merge \"" << d->cadFile << "\";\n\n"
|
||||
<< "// Characteristic Length\n"
|
||||
<< "// no boundary layer settings for this mesh\n"
|
||||
<< "// min, max Characteristic Length\n"
|
||||
<< "Mesh.CharacteristicLengthMax = " << maxSize << ";\n"
|
||||
<< "Mesh.CharacteristicLengthMin = " << minSize << ";\n\n"
|
||||
<< "// optimize the mesh\n"
|
||||
<< "Mesh.Optimize = 1;\n"
|
||||
<< "Mesh.OptimizeNetgen = 0;\n"
|
||||
<< "// High-order meshes optimization (0=none, 1=optimization, "
|
||||
"2=elastic+optimization, 3=elastic, 4=fast curving)\n"
|
||||
<< "Mesh.HighOrderOptimize = 0;\n\n"
|
||||
<< "// mesh order\n"
|
||||
<< "Mesh.ElementOrder = 2;\n"
|
||||
<< "// Second order nodes are created by linear interpolation instead by "
|
||||
"curvilinear\n"
|
||||
<< "Mesh.SecondOrderLinear = 1;\n\n"
|
||||
<< "// mesh algorithm, only a few algorithms are usable with 3D boundary layer "
|
||||
"generation\n"
|
||||
<< "// 2D mesh algorithm (1=MeshAdapt, 2=Automatic, 5=Delaunay, 6=Frontal, "
|
||||
"7=BAMG, 8=DelQuad, 9=Packing of Parallelograms)\n"
|
||||
<< "Mesh.Algorithm = " << algorithm << ";\n"
|
||||
<< "// 3D mesh algorithm (1=Delaunay, 2=New Delaunay, 4=Frontal, 7=MMG3D, "
|
||||
"9=R-tree, 10=HTX)\n"
|
||||
<< "Mesh.Algorithm3D = 1;\n\n"
|
||||
<< "// meshing\n"
|
||||
<< "// set geometrical tolerance (also used for merging nodes)\n"
|
||||
<< "Geometry.Tolerance = 1e-06;\n"
|
||||
<< "Mesh 2;\n"
|
||||
<< "Coherence Mesh; // Remove duplicate vertices\n";
|
||||
geoOut.close();
|
||||
|
||||
inpFile = QString::fromUtf8(d->geoFile.c_str());
|
||||
@@ -570,8 +601,9 @@ bool Mesh2ShapeGmsh::writeProject(QString& inpFile, QString& outFile)
|
||||
}
|
||||
else {
|
||||
App::Document* doc = d->doc.getDocument();
|
||||
if (doc)
|
||||
if (doc) {
|
||||
doc->commitTransaction();
|
||||
}
|
||||
|
||||
Q_EMIT processed();
|
||||
}
|
||||
@@ -582,8 +614,9 @@ bool Mesh2ShapeGmsh::writeProject(QString& inpFile, QString& outFile)
|
||||
bool Mesh2ShapeGmsh::loadOutput()
|
||||
{
|
||||
App::Document* doc = d->doc.getDocument();
|
||||
if (!doc)
|
||||
if (!doc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now read-in the mesh
|
||||
Base::FileInfo stl(d->stlFile);
|
||||
@@ -613,20 +646,20 @@ bool Mesh2ShapeGmsh::loadOutput()
|
||||
TaskTessellation::TaskTessellation()
|
||||
{
|
||||
widget = new Tessellation();
|
||||
Gui::TaskView::TaskBox* taskbox = new Gui::TaskView::TaskBox(
|
||||
QPixmap()/*Gui::BitmapFactory().pixmap("MeshPart_Mesher")*/,
|
||||
widget->windowTitle(), true, nullptr);
|
||||
Gui::TaskView::TaskBox* taskbox =
|
||||
new Gui::TaskView::TaskBox(QPixmap() /*Gui::BitmapFactory().pixmap("MeshPart_Mesher")*/,
|
||||
widget->windowTitle(),
|
||||
true,
|
||||
nullptr);
|
||||
taskbox->groupLayout()->addWidget(widget);
|
||||
Content.push_back(taskbox);
|
||||
}
|
||||
|
||||
void TaskTessellation::open()
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
void TaskTessellation::clicked(int)
|
||||
{
|
||||
}
|
||||
{}
|
||||
|
||||
bool TaskTessellation::accept()
|
||||
{
|
||||
|
||||
@@ -23,25 +23,27 @@
|
||||
#ifndef MESHPARTGUI_TESSELLATION_H
|
||||
#define MESHPARTGUI_TESSELLATION_H
|
||||
|
||||
#include <memory>
|
||||
#include <QPointer>
|
||||
#include <memory>
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Mod/Mesh/Gui/RemeshGmsh.h>
|
||||
|
||||
|
||||
namespace App {
|
||||
namespace App
|
||||
{
|
||||
class Document;
|
||||
class SubObjectT;
|
||||
}
|
||||
namespace MeshPartGui {
|
||||
}// namespace App
|
||||
namespace MeshPartGui
|
||||
{
|
||||
|
||||
/**
|
||||
* Non-modal dialog to mesh a shape.
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class Mesh2ShapeGmsh : public MeshGui::GmshWidget
|
||||
class Mesh2ShapeGmsh: public MeshGui::GmshWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -64,18 +66,20 @@ private:
|
||||
};
|
||||
|
||||
class Ui_Tessellation;
|
||||
class Tessellation : public QWidget
|
||||
class Tessellation: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
Standard,
|
||||
Mefisto,
|
||||
Netgen,
|
||||
Gmsh
|
||||
};
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
VeryCoarse = 0,
|
||||
Coarse = 1,
|
||||
Moderate = 2,
|
||||
@@ -89,7 +93,7 @@ public:
|
||||
bool accept();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
void process(int method, App::Document* doc, const std::list<App::SubObjectT>&);
|
||||
void saveParameters(int method);
|
||||
void setFaceColors(int method, App::Document* doc, App::DocumentObject* obj);
|
||||
@@ -114,7 +118,7 @@ private:
|
||||
std::unique_ptr<Ui_Tessellation> ui;
|
||||
};
|
||||
|
||||
class TaskTessellation : public Gui::TaskView::TaskDialog
|
||||
class TaskTessellation: public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -128,12 +132,14 @@ public:
|
||||
bool reject() override;
|
||||
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
|
||||
{
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||
}
|
||||
|
||||
private:
|
||||
Tessellation* widget;
|
||||
};
|
||||
|
||||
} // namespace MeshPartGui
|
||||
}// namespace MeshPartGui
|
||||
|
||||
#endif // MESHPARTGUI_TESSELLATION_H
|
||||
#endif// MESHPARTGUI_TESSELLATION_H
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
# include <qobject.h>
|
||||
#include <qobject.h>
|
||||
#endif
|
||||
|
||||
#include <Gui/ToolBarManager.h>
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
using namespace MeshPartGui;
|
||||
|
||||
#if 0 // needed for Qt's lupdate utility
|
||||
#if 0// needed for Qt's lupdate utility
|
||||
qApp->translate("Workbench", "MeshPart");
|
||||
#endif
|
||||
|
||||
@@ -49,7 +49,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
Gui::ToolBarItem* part = new Gui::ToolBarItem(root);
|
||||
part->setCommand("MeshPart");
|
||||
*part << "MeshPart_Mesher";
|
||||
return root;
|
||||
return root;
|
||||
}
|
||||
|
||||
Gui::ToolBarItem* Workbench::setupCommandBars() const
|
||||
@@ -58,4 +58,3 @@ Gui::ToolBarItem* Workbench::setupCommandBars() const
|
||||
Gui::ToolBarItem* root = new Gui::ToolBarItem;
|
||||
return root;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,25 +26,26 @@
|
||||
|
||||
#include <Gui/Workbench.h>
|
||||
|
||||
namespace MeshPartGui {
|
||||
namespace MeshPartGui
|
||||
{
|
||||
|
||||
/**
|
||||
* @author Werner Mayer
|
||||
*/
|
||||
class Workbench : public Gui::StdWorkbench
|
||||
class Workbench: public Gui::StdWorkbench
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
Workbench();
|
||||
~Workbench() override;
|
||||
Workbench();
|
||||
~Workbench() override;
|
||||
|
||||
protected:
|
||||
Gui::ToolBarItem* setupToolBars() const override;
|
||||
Gui::ToolBarItem* setupCommandBars() const override;
|
||||
Gui::ToolBarItem* setupToolBars() const override;
|
||||
Gui::ToolBarItem* setupCommandBars() const override;
|
||||
};
|
||||
|
||||
} // namespace MeshPartGui
|
||||
}// namespace MeshPartGui
|
||||
|
||||
|
||||
#endif // MESHPARTGUI_WORKBENCH_H
|
||||
#endif// MESHPARTGUI_WORKBENCH_H
|
||||
|
||||
Reference in New Issue
Block a user