From 46f5554c43383cc40f3ca4a8efe0d2632a9576a6 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 19 Feb 2017 14:05:00 +0100 Subject: [PATCH] command to creation section from plane and mesh --- src/Mod/Mesh/Gui/Command.cpp | 85 ++++++--------- src/Mod/Mesh/Gui/Workbench.cpp | 3 +- src/Mod/MeshPart/Gui/Command.cpp | 174 ++++++++++++++++++++++++++++++- 3 files changed, 205 insertions(+), 57 deletions(-) diff --git a/src/Mod/Mesh/Gui/Command.cpp b/src/Mod/Mesh/Gui/Command.cpp index e49d1bd6b..8f8fff683 100644 --- a/src/Mod/Mesh/Gui/Command.cpp +++ b/src/Mod/Mesh/Gui/Command.cpp @@ -943,61 +943,7 @@ CmdMeshTrimByPlane::CmdMeshTrimByPlane() void CmdMeshTrimByPlane::activated(int) { - Base::Type partType = Base::Type::fromName("Part::Plane"); - std::vector plane = getSelection().getObjectsOfType(partType); - if (plane.empty()) { - QMessageBox::warning(Gui::getMainWindow(), - qApp->translate("Mesh_TrimByPlane", "Select plane"), - qApp->translate("Mesh_TrimByPlane", "Please select a plane at which you trim the mesh.")); - return; - } - - Base::Placement plm = static_cast(plane.front())->Placement.getValue(); - Base::Vector3d normal(0,0,1); - plm.getRotation().multVec(normal, normal); - Base::Vector3d up(-1,0,0); - plm.getRotation().multVec(up, up); - Base::Vector3d view(0,1,0); - plm.getRotation().multVec(view, view); - - Base::Vector3d base = plm.getPosition(); - Base::Rotation rot(Base::Vector3d(0,0,1), view); - Base::Matrix4D mat; - rot.getValue(mat); - Base::ViewProjMatrix proj(mat); - - openCommand("Trim with plane"); - std::vector docObj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId()); - for (std::vector::iterator it = docObj.begin(); it != docObj.end(); ++it) { - Mesh::MeshObject* mesh = static_cast(*it)->Mesh.startEditing(); - Base::BoundBox3d bbox = mesh->getBoundBox(); - double len = bbox.CalcDiagonalLength(); - // project center of bbox onto plane and use this as base point - Base::Vector3d cnt = bbox.GetCenter(); - double dist = (cnt-base)*normal; - base = cnt - normal * dist; - - Base::Vector3d p1 = base + up * len; - Base::Vector3d p2 = base - up * len; - Base::Vector3d p3 = p2 + normal * len; - Base::Vector3d p4 = p1 + normal * len; - p1 = mat * p1; - p2 = mat * p2; - p3 = mat * p3; - p4 = mat * p4; - - Base::Polygon2d polygon2d; - polygon2d.Add(Base::Vector2d(p1.x, p1.y)); - polygon2d.Add(Base::Vector2d(p2.x, p2.y)); - polygon2d.Add(Base::Vector2d(p3.x, p3.y)); - polygon2d.Add(Base::Vector2d(p4.x, p4.y)); - - Mesh::MeshObject::CutType type = Mesh::MeshObject::INNER; - mesh->trim(polygon2d, proj, type); - static_cast(*it)->Mesh.finishEditing(); - (*it)->purgeTouched(); - } - commitCommand(); + doCommand(Doc,"import MeshPartGui, FreeCADGui\nFreeCADGui.runCommand('MeshPart_TrimByPlane')\n"); } bool CmdMeshTrimByPlane::isActive(void) @@ -1011,6 +957,34 @@ bool CmdMeshTrimByPlane::isActive(void) //-------------------------------------------------------------------------------------- +DEF_STD_CMD_A(CmdMeshSectionByPlane); + +CmdMeshSectionByPlane::CmdMeshSectionByPlane() + : Command("Mesh_SectionByPlane") +{ + sAppModule = "Mesh"; + sGroup = QT_TR_NOOP("Mesh"); + sMenuText = QT_TR_NOOP("Create section from mesh and plane"); + sToolTipText = QT_TR_NOOP("Section from mesh and plane"); + sStatusTip = QT_TR_NOOP("Section from mesh and plane"); +} + +void CmdMeshSectionByPlane::activated(int) +{ + doCommand(Doc,"import MeshPartGui, FreeCADGui\nFreeCADGui.runCommand('MeshPart_SectionByPlane')\n"); +} + +bool CmdMeshSectionByPlane::isActive(void) +{ + // Check for the selected mesh feature (all Mesh types) + if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1) + return false; + + return true; +} + +//-------------------------------------------------------------------------------------- + DEF_STD_CMD_A(CmdMeshPolySplit); CmdMeshPolySplit::CmdMeshPolySplit() @@ -1696,6 +1670,7 @@ void CreateMeshCommands(void) rcCmdMgr.addCommand(new CmdMeshPolySplit()); rcCmdMgr.addCommand(new CmdMeshPolyTrim()); rcCmdMgr.addCommand(new CmdMeshTrimByPlane()); + rcCmdMgr.addCommand(new CmdMeshSectionByPlane()); rcCmdMgr.addCommand(new CmdMeshToolMesh()); rcCmdMgr.addCommand(new CmdMeshTransform()); rcCmdMgr.addCommand(new CmdMeshEvaluation()); diff --git a/src/Mod/Mesh/Gui/Workbench.cpp b/src/Mod/Mesh/Gui/Workbench.cpp index 2953e97a1..204161801 100644 --- a/src/Mod/Mesh/Gui/Workbench.cpp +++ b/src/Mod/Mesh/Gui/Workbench.cpp @@ -190,7 +190,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Mesh_FillupHoles" << "Mesh_FillInteractiveHole" << "Mesh_RemoveComponents" << "Mesh_RemoveCompByHand" << "Mesh_AddFacet" << "Mesh_Smoothing" << "Separator" << "Mesh_BuildRegularSolid" << boolean << "Separator" << "Mesh_Merge" << "Mesh_PolySelect" << "Mesh_PolyCut" - << "Mesh_PolySplit" << "Mesh_PolySegm" << "Mesh_PolyTrim" << "Mesh_TrimByPlane" << "Mesh_Segmentation" + << "Mesh_PolySplit" << "Mesh_PolySegm" << "Mesh_PolyTrim" << "Separator" + << "Mesh_TrimByPlane" << "Mesh_SectionByPlane" << "Mesh_Segmentation" << "Mesh_VertexCurvature"; return root; } diff --git a/src/Mod/MeshPart/Gui/Command.cpp b/src/Mod/MeshPart/Gui/Command.cpp index 55958c51f..70145692d 100644 --- a/src/Mod/MeshPart/Gui/Command.cpp +++ b/src/Mod/MeshPart/Gui/Command.cpp @@ -23,8 +23,12 @@ #include "PreCompiled.h" #ifndef _PreComp_ +# include +# include #endif +#include + #include #include #include @@ -37,7 +41,7 @@ using namespace std; //=========================================================================== // MeshPart_Mesher //=========================================================================== -DEF_STD_CMD_A(CmdMeshPartMesher); +DEF_STD_CMD_A(CmdMeshPartMesher) CmdMeshPartMesher::CmdMeshPartMesher() : Command("MeshPart_Mesher") @@ -60,9 +64,177 @@ bool CmdMeshPartMesher::isActive(void) return (hasActiveDocument() && !Gui::Control().activeDialog()); } +//-------------------------------------------------------------------------------------- + +DEF_STD_CMD_A(CmdMeshPartTrimByPlane) + +CmdMeshPartTrimByPlane::CmdMeshPartTrimByPlane() + : 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"); +} + +void CmdMeshPartTrimByPlane::activated(int) +{ + Base::Type partType = Base::Type::fromName("Part::Plane"); + std::vector 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.")); + return; + } + + Base::Placement plm = static_cast(plane.front())->Placement.getValue(); + Base::Vector3d normal(0,0,1); + plm.getRotation().multVec(normal, normal); + Base::Vector3d up(-1,0,0); + plm.getRotation().multVec(up, up); + Base::Vector3d view(0,1,0); + plm.getRotation().multVec(view, view); + + Base::Vector3d base = plm.getPosition(); + Base::Rotation rot(Base::Vector3d(0,0,1), view); + Base::Matrix4D mat; + rot.getValue(mat); + Base::ViewProjMatrix proj(mat); + + openCommand("Trim with plane"); + std::vector docObj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId()); + for (std::vector::iterator it = docObj.begin(); it != docObj.end(); ++it) { + Mesh::MeshObject* mesh = static_cast(*it)->Mesh.startEditing(); + Base::BoundBox3d bbox = mesh->getBoundBox(); + double len = bbox.CalcDiagonalLength(); + // project center of bbox onto plane and use this as base point + Base::Vector3d cnt = bbox.GetCenter(); + double dist = (cnt-base)*normal; + base = cnt - normal * dist; + + Base::Vector3d p1 = base + up * len; + Base::Vector3d p2 = base - up * len; + Base::Vector3d p3 = p2 + normal * len; + Base::Vector3d p4 = p1 + normal * len; + p1 = mat * p1; + p2 = mat * p2; + p3 = mat * p3; + p4 = mat * p4; + + Base::Polygon2d polygon2d; + polygon2d.Add(Base::Vector2d(p1.x, p1.y)); + polygon2d.Add(Base::Vector2d(p2.x, p2.y)); + polygon2d.Add(Base::Vector2d(p3.x, p3.y)); + polygon2d.Add(Base::Vector2d(p4.x, p4.y)); + + Mesh::MeshObject::CutType type = Mesh::MeshObject::INNER; + mesh->trim(polygon2d, proj, type); + static_cast(*it)->Mesh.finishEditing(); + (*it)->purgeTouched(); + } + commitCommand(); +} + +bool CmdMeshPartTrimByPlane::isActive(void) +{ + // Check for the selected mesh feature (all Mesh types) + if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1) + return false; + + return true; +} + +//=========================================================================== +// MeshPart_Section +//=========================================================================== +DEF_STD_CMD_A(CmdMeshPartSection) + +CmdMeshPartSection::CmdMeshPartSection() + : 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; +} + +void CmdMeshPartSection::activated(int) +{ + Base::Type partType = Base::Type::fromName("Part::Plane"); + std::vector plane = getSelection().getObjectsOfType(partType); + if (plane.empty()) { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("MeshPart_Section", "Select plane"), + qApp->translate("MeshPart_Section", "Please select a plane at which you section the mesh.")); + return; + } + + Base::Placement plm = static_cast(plane.front())->Placement.getValue(); + Base::Vector3d normal(0,0,1); + plm.getRotation().multVec(normal, normal); + Base::Vector3d base = plm.getPosition(); + + openCommand("Section with plane"); + std::vector docObj = Gui::Selection().getObjectsOfType(Mesh::Feature::getClassTypeId()); + Mesh::MeshObject::TPlane tplane; + tplane.first = Base::convertTo(base); + tplane.second = Base::convertTo(normal); + std::vector sections; + sections.push_back(tplane); + + Py::Module partModule(PyImport_ImportModule("Part"), true); + Py::Callable makeWire(partModule.getAttr("makePolygon")); + Py::Module appModule(PyImport_ImportModule("FreeCAD"), true); + Py::Callable addObject(appModule.getAttr("ActiveDocument").getAttr("addObject")); + for (std::vector::iterator it = docObj.begin(); it != docObj.end(); ++it) { + const Mesh::MeshObject* mesh = static_cast(*it)->Mesh.getValuePtr(); + std::vector polylines; + mesh->crossSections(sections, polylines); + + for (auto it2 : polylines) { + for (auto it3 : it2) { + Py::Tuple arg(1); + Py::List list; + for (auto it4 : it3) { + Py::Tuple pnt(3); + pnt.setItem(0, Py::Float(it4.x)); + pnt.setItem(1, Py::Float(it4.y)); + pnt.setItem(2, Py::Float(it4.z)); + list.append(pnt); + } + arg.setItem(0, list); + Py::Object wire = makeWire.apply(arg); + + Py::Tuple arg2(2); + arg2.setItem(0, Py::String("Part::Feature")); + arg2.setItem(1, Py::String("Section")); + Py::Object obj = addObject.apply(arg2); + obj.setAttr("Shape", wire); + } + } + } + updateActive(); + commitCommand(); +} + +bool CmdMeshPartSection::isActive(void) +{ + // Check for the selected mesh feature (all Mesh types) + if (getSelection().countObjectsOfType(Mesh::Feature::getClassTypeId()) != 1) + return false; + + return true; +} + void CreateMeshPartCommands(void) { Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); rcCmdMgr.addCommand(new CmdMeshPartMesher()); + rcCmdMgr.addCommand(new CmdMeshPartTrimByPlane()); + rcCmdMgr.addCommand(new CmdMeshPartSection()); }