Merge pull request #11492 from mac-the-bike/erase-version-4
Version 4 of the Erasing Elements Code
This commit is contained in:
@@ -177,6 +177,7 @@
|
||||
<FCText Name="FEM_ConstraintTemperature"></FCText>
|
||||
<FCText Name="FEM_ConstraintTie"></FCText>
|
||||
<FCText Name="FEM_ConstraintTransform"></FCText>
|
||||
<FCText Name="FEM_CreateElementsSet"></FCText>
|
||||
<FCText Name="FEM_CreateNodesSet"></FCText>
|
||||
<FCText Name="FEM_DefineNodesSet"></FCText>
|
||||
<FCText Name="FEM_ElementFluid1D"></FCText>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* additional statement(s) for element sets *
|
||||
* *
|
||||
* added to: AppFem.cpp *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
@@ -52,6 +56,7 @@
|
||||
#include "FemMeshShapeNetgenObject.h"
|
||||
#include "FemMeshShapeObject.h"
|
||||
#include "FemResultObject.h"
|
||||
#include "FemSetElementNodesObject.h"
|
||||
#include "FemSetElementsObject.h"
|
||||
#include "FemSetFacesObject.h"
|
||||
#include "FemSetGeometryObject.h"
|
||||
@@ -167,6 +172,7 @@ PyMOD_INIT_FUNC(Fem)
|
||||
Fem::FemResultObjectPython ::init();
|
||||
|
||||
Fem::FemSetObject ::init();
|
||||
Fem::FemSetElementNodesObject ::init();
|
||||
Fem::FemSetElementsObject ::init();
|
||||
Fem::FemSetFacesObject ::init();
|
||||
Fem::FemSetGeometryObject ::init();
|
||||
|
||||
@@ -133,6 +133,8 @@ SET(FemSet_SRCS
|
||||
FemSetObject.h
|
||||
FemSetNodesObject.cpp
|
||||
FemSetNodesObject.h
|
||||
FemSetElementNodesObject.cpp
|
||||
FemSetElementNodesObject.h
|
||||
FemSetElementsObject.cpp
|
||||
FemSetElementsObject.h
|
||||
FemSetFacesObject.cpp
|
||||
|
||||
62
src/Mod/Fem/App/FemSetElementNodesObject.cpp
Normal file
62
src/Mod/Fem/App/FemSetElementNodesObject.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: FemSetNodesObject.cpp *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <App/DocumentObjectPy.h>
|
||||
|
||||
#include "FemSetElementNodesObject.h"
|
||||
|
||||
|
||||
using namespace Fem;
|
||||
using namespace App;
|
||||
|
||||
PROPERTY_SOURCE(Fem::FemSetElementNodesObject, Fem::FemSetObject)
|
||||
|
||||
|
||||
FemSetElementNodesObject::FemSetElementNodesObject()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(Elements,
|
||||
(),
|
||||
"Element indexes",
|
||||
Prop_None,
|
||||
"Elements belonging to the ElementSet");
|
||||
}
|
||||
|
||||
FemSetElementNodesObject::~FemSetElementNodesObject() = default;
|
||||
|
||||
short FemSetElementNodesObject::mustExecute() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* FemSetElementNodesObject::getPyObject()
|
||||
{
|
||||
if (PythonObject.is(Py::_None())) {
|
||||
// ref counter is set to 1
|
||||
PythonObject = Py::Object(new DocumentObjectPy(this), true);
|
||||
}
|
||||
return Py::new_reference_to(PythonObject);
|
||||
}
|
||||
66
src/Mod/Fem/App/FemSetElementNodesObject.h
Normal file
66
src/Mod/Fem/App/FemSetElementNodesObject.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: FemSetNodesObject.h *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef Fem_FemSetElementNodesObject_H
|
||||
#define Fem_FemSetElementNodesObject_H
|
||||
|
||||
#include "FemSetObject.h"
|
||||
#include <App/DocumentObject.h>
|
||||
#include <App/PropertyStandard.h>
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
class FemExport FemSetElementNodesObject: public FemSetObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Fem::FemSetElementNodesObject);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
FemSetElementNodesObject();
|
||||
~FemSetElementNodesObject() override;
|
||||
|
||||
App::PropertyIntegerSet Elements;
|
||||
|
||||
// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "FemGui::ViewProviderSetElementNodes";
|
||||
}
|
||||
App::DocumentObjectExecReturn* execute() override
|
||||
{
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
short mustExecute() const override;
|
||||
PyObject* getPyObject() override;
|
||||
static std::string elementsName; // = "ElementsSet";
|
||||
static std::string uniqueElementsName; // "ElementsSet" latest name
|
||||
};
|
||||
|
||||
} // namespace Fem
|
||||
|
||||
|
||||
#endif // Fem_FemSetElementNodesObject_H
|
||||
@@ -1,4 +1,8 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* additional statement(s) for element sets *
|
||||
* *
|
||||
* added to: AppFemGui.cpp *
|
||||
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
@@ -42,6 +46,7 @@
|
||||
#include "ViewProviderFemMeshShape.h"
|
||||
#include "ViewProviderFemMeshShapeNetgen.h"
|
||||
#include "ViewProviderSetElements.h"
|
||||
#include "ViewProviderSetElementNodes.h"
|
||||
#include "ViewProviderSetFaces.h"
|
||||
#include "ViewProviderSetGeometry.h"
|
||||
#include "ViewProviderSetNodes.h"
|
||||
@@ -141,6 +146,7 @@ PyMOD_INIT_FUNC(FemGui)
|
||||
FemGui::PropertyFemMeshItem ::init();
|
||||
|
||||
FemGui::ViewProviderSetElements ::init();
|
||||
FemGui::ViewProviderSetElementNodes ::init();
|
||||
FemGui::ViewProviderSetFaces ::init();
|
||||
FemGui::ViewProviderSetGeometry ::init();
|
||||
FemGui::ViewProviderSetNodes ::init();
|
||||
|
||||
@@ -49,6 +49,7 @@ SET(Python_SRCS
|
||||
)
|
||||
SOURCE_GROUP("Python" FILES ${Python_SRCS})
|
||||
|
||||
|
||||
set(FemGui_UIC_SRCS
|
||||
DlgSettingsFemCcx.ui
|
||||
DlgSettingsFemElmer.ui
|
||||
@@ -58,6 +59,7 @@ set(FemGui_UIC_SRCS
|
||||
DlgSettingsFemInOutVtk.ui
|
||||
DlgSettingsFemMystran.ui
|
||||
DlgSettingsFemZ88.ui
|
||||
TaskCreateElementSet.ui
|
||||
TaskCreateNodeSet.ui
|
||||
TaskObjectName.ui
|
||||
TaskFemConstraint.ui
|
||||
@@ -198,6 +200,8 @@ SET(FemGui_SRCS_ViewProvider
|
||||
ViewProviderSolver.h
|
||||
ViewProviderSetNodes.cpp
|
||||
ViewProviderSetNodes.h
|
||||
ViewProviderSetElementNodes.cpp
|
||||
ViewProviderSetElementNodes.h
|
||||
ViewProviderSetElements.cpp
|
||||
ViewProviderSetElements.h
|
||||
ViewProviderSetFaces.cpp
|
||||
@@ -251,6 +255,9 @@ SET(FemGui_SRCS_TaskBoxes
|
||||
TaskObjectName.ui
|
||||
TaskObjectName.cpp
|
||||
TaskObjectName.h
|
||||
TaskCreateElementSet.ui
|
||||
TaskCreateElementSet.cpp
|
||||
TaskCreateElementSet.h
|
||||
TaskCreateNodeSet.ui
|
||||
TaskCreateNodeSet.cpp
|
||||
TaskCreateNodeSet.h
|
||||
@@ -288,6 +295,8 @@ endif(BUILD_FEM_VTK)
|
||||
SOURCE_GROUP("Task_Boxes" FILES ${FemGui_SRCS_TaskBoxes})
|
||||
|
||||
SET(FemGui_SRCS_TaskDlg
|
||||
TaskDlgCreateElementSet.h
|
||||
TaskDlgCreateElementSet.cpp
|
||||
TaskDlgCreateNodeSet.h
|
||||
TaskDlgCreateNodeSet.cpp
|
||||
TaskDlgMeshShapeNetgen.h
|
||||
@@ -319,6 +328,7 @@ SET(FemGui_SRCS_Module
|
||||
)
|
||||
SOURCE_GROUP("Module" FILES ${FemGui_SRCS_Module})
|
||||
|
||||
|
||||
if(BUILD_FEM_VTK)
|
||||
SET(FemGui_SRCS_Post
|
||||
ViewProviderFemPostObject.h
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Peter McB *
|
||||
* added erase elements function *
|
||||
* *
|
||||
* added to: Command.cpp *
|
||||
* *
|
||||
* Copyright (c) 2008 Jürgen Riegel <juergen.riegel@web.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
@@ -51,6 +56,7 @@
|
||||
#include <Mod/Fem/App/FemAnalysis.h>
|
||||
#include <Mod/Fem/App/FemConstraint.h>
|
||||
#include <Mod/Fem/App/FemMeshObject.h>
|
||||
#include <Mod/Fem/App/FemSetElementNodesObject.h>
|
||||
#include <Mod/Fem/App/FemSetNodesObject.h>
|
||||
|
||||
#include "ActiveAnalysisObserver.h"
|
||||
@@ -1242,6 +1248,213 @@ bool CmdFemCreateNodesSet::isActive()
|
||||
return hasActiveDocument();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// start of Erase Elements code
|
||||
//===========================================================================
|
||||
std::string Fem::FemSetElementNodesObject::elementsName;
|
||||
std::string Fem::FemSetElementNodesObject::uniqueElementsName;
|
||||
|
||||
|
||||
DEF_STD_CMD_A(CmdFemDefineElementsSet);
|
||||
|
||||
void DefineElementsCallback(void* ud, SoEventCallback* n)
|
||||
{
|
||||
Fem::FemAnalysis* Analysis;
|
||||
|
||||
if (getConstraintPrerequisits(&Analysis)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// show the wait cursor because this could take quite some time
|
||||
Gui::WaitCursor wc;
|
||||
|
||||
// When this callback function is invoked we must in either case leave the edit mode
|
||||
Gui::View3DInventorViewer* view = static_cast<Gui::View3DInventorViewer*>(n->getUserData());
|
||||
view->setEditing(false);
|
||||
view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineElementsCallback, ud);
|
||||
n->setHandled();
|
||||
|
||||
Gui::SelectionRole role;
|
||||
std::vector<SbVec2f> clPoly = view->getGLPolygon(&role);
|
||||
if (clPoly.size() < 3) {
|
||||
return;
|
||||
}
|
||||
if (clPoly.front() != clPoly.back()) {
|
||||
clPoly.push_back(clPoly.front());
|
||||
}
|
||||
|
||||
SoCamera* cam = view->getSoRenderManager()->getCamera();
|
||||
SbViewVolume vv = cam->getViewVolume();
|
||||
Gui::ViewVolumeProjection proj(vv);
|
||||
Base::Polygon2d polygon;
|
||||
for (std::vector<SbVec2f>::const_iterator it = clPoly.begin(); it != clPoly.end(); ++it) {
|
||||
polygon.Add(Base::Vector2d((*it)[0], (*it)[1]));
|
||||
}
|
||||
|
||||
std::vector<App::DocumentObject*> docObj =
|
||||
Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId());
|
||||
if (docObj.size() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const SMESHDS_Mesh* data =
|
||||
static_cast<Fem::FemMeshObject*>(docObj[0])->FemMesh.getValue().getSMesh()->GetMeshDS();
|
||||
|
||||
SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator();
|
||||
Base::Vector3f pt2d;
|
||||
std::set<int> IntSet;
|
||||
|
||||
while (aNodeIter->more()) {
|
||||
const SMDS_MeshNode* aNode = aNodeIter->next();
|
||||
Base::Vector3f vec(aNode->X(), aNode->Y(), aNode->Z());
|
||||
pt2d = proj(vec);
|
||||
if (polygon.Contains(Base::Vector2d(pt2d.x, pt2d.y))) {
|
||||
IntSet.insert(aNode->GetID());
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream set;
|
||||
|
||||
set << "[";
|
||||
for (std::set<int>::const_iterator it = IntSet.begin(); it != IntSet.end(); ++it) {
|
||||
if (it == IntSet.begin()) {
|
||||
set << *it;
|
||||
}
|
||||
else {
|
||||
set << "," << *it;
|
||||
}
|
||||
}
|
||||
set << "]";
|
||||
|
||||
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Place robot"));
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc,
|
||||
"App.ActiveDocument.addObject('Fem::FemSetElementNodesObject','ElementSet')");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.ActiveObject.Nodes = %s",
|
||||
set.str().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.activeDocument().%s.addObject(App.activeDocument().ElementSet)",
|
||||
Analysis->getNameInDocument());
|
||||
|
||||
Gui::Command::commitCommand();
|
||||
}
|
||||
|
||||
CmdFemDefineElementsSet::CmdFemDefineElementsSet()
|
||||
: Command("FEM_DefineElementsSet")
|
||||
{
|
||||
sAppModule = "Fem";
|
||||
sGroup = QT_TR_NOOP("Fem");
|
||||
sMenuText = QT_TR_NOOP("Element set by poly");
|
||||
sToolTipText = QT_TR_NOOP("Create Element set by Poly");
|
||||
sWhatsThis = "FEM_DefineElementsSet";
|
||||
sStatusTip = QT_TR_NOOP("Create Element set by Poly");
|
||||
sPixmap = "FEM_CreateElementsSet";
|
||||
}
|
||||
|
||||
void CmdFemDefineElementsSet::activated(int)
|
||||
{
|
||||
std::vector<App::DocumentObject*> docObj =
|
||||
Gui::Selection().getObjectsOfType(Fem::FemMeshObject::getClassTypeId());
|
||||
|
||||
for (std::vector<App::DocumentObject*>::iterator it = docObj.begin(); it != docObj.end();
|
||||
++it) {
|
||||
if (it == docObj.begin()) {
|
||||
Gui::Document* doc = getActiveGuiDocument();
|
||||
Gui::MDIView* view = doc->getActiveView();
|
||||
if (view->getTypeId().isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
Gui::View3DInventorViewer* viewer = ((Gui::View3DInventor*)view)->getViewer();
|
||||
viewer->setEditing(true);
|
||||
viewer->startSelection(Gui::View3DInventorViewer::Clip);
|
||||
viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
|
||||
DefineElementsCallback);
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdFemDefineElementsSet::isActive()
|
||||
{
|
||||
// Check for the selected mesh feature (all Mesh types)
|
||||
if (getSelection().countObjectsOfType(Fem::FemMeshObject::getClassTypeId()) != 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Gui::MDIView* view = Gui::getMainWindow()->activeWindow();
|
||||
if (view && view->isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
|
||||
return !viewer->isEditing();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//================================================================================================
|
||||
DEF_STD_CMD_A(CmdFemCreateElementsSet);
|
||||
|
||||
CmdFemCreateElementsSet::CmdFemCreateElementsSet()
|
||||
: Command("FEM_CreateElementsSet")
|
||||
{
|
||||
sAppModule = "Fem";
|
||||
sGroup = QT_TR_NOOP("Fem");
|
||||
sMenuText = QT_TR_NOOP("Erase Elements");
|
||||
sToolTipText = QT_TR_NOOP("Creates a FEM mesh elements set");
|
||||
sWhatsThis = "FEM_CreateElementsSet";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "FEM_CreateElementsSet";
|
||||
}
|
||||
|
||||
void CmdFemCreateElementsSet::activated(int)
|
||||
{
|
||||
Gui::SelectionFilter ObjectFilter("SELECT Fem::FemSetElementNodesObject COUNT 1");
|
||||
Gui::SelectionFilter FemMeshFilter("SELECT Fem::FemMeshObject COUNT 1");
|
||||
|
||||
if (ObjectFilter.match()) {
|
||||
Fem::FemSetElementNodesObject* NodesObj =
|
||||
static_cast<Fem::FemSetElementNodesObject*>(ObjectFilter.Result[0][0].getObject());
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Edit Elements set"));
|
||||
doCommand(Gui, "Gui.activeDocument().setEdit('%s')", NodesObj->getNameInDocument());
|
||||
}
|
||||
// start
|
||||
else if (FemMeshFilter.match()) {
|
||||
Fem::FemMeshObject* MeshObj =
|
||||
static_cast<Fem::FemMeshObject*>(FemMeshFilter.Result[0][0].getObject());
|
||||
|
||||
Fem::FemSetElementNodesObject::elementsName = "ElementsSet";
|
||||
Fem::FemSetElementNodesObject::uniqueElementsName =
|
||||
Command::getUniqueObjectName(Fem::FemSetElementNodesObject::elementsName.c_str());
|
||||
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Create Elements set"));
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().addObject('Fem::FemSetElementNodesObject','%s')",
|
||||
Fem::FemSetElementNodesObject::uniqueElementsName.c_str());
|
||||
doCommand(Gui,
|
||||
"App.activeDocument().%s.FemMesh = App.activeDocument().%s",
|
||||
Fem::FemSetElementNodesObject::uniqueElementsName.c_str(),
|
||||
MeshObj->getNameInDocument());
|
||||
doCommand(Gui,
|
||||
"Gui.activeDocument().setEdit('%s')",
|
||||
Fem::FemSetElementNodesObject::uniqueElementsName.c_str());
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(
|
||||
Gui::getMainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Wrong selection"),
|
||||
qApp->translate("CmdFemCreateNodesSet", "Select a single FEM Mesh, please."));
|
||||
}
|
||||
}
|
||||
|
||||
bool CmdFemCreateElementsSet::isActive()
|
||||
{
|
||||
return hasActiveDocument();
|
||||
}
|
||||
//===========================================================================
|
||||
// end of Erase Elements code
|
||||
//===========================================================================
|
||||
|
||||
//===========================================================================
|
||||
// FEM_CompEmConstraints (dropdown toolbar button for electromagnetic constraints)
|
||||
@@ -2689,6 +2902,8 @@ void CreateFemCommands()
|
||||
// mesh
|
||||
rcCmdMgr.addCommand(new CmdFemCreateNodesSet());
|
||||
rcCmdMgr.addCommand(new CmdFemDefineNodesSet());
|
||||
rcCmdMgr.addCommand(new CmdFemCreateElementsSet());
|
||||
rcCmdMgr.addCommand(new CmdFemDefineElementsSet());
|
||||
|
||||
// equations
|
||||
rcCmdMgr.addCommand(new CmdFemCompEmEquations());
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
<file>icons/FEM_EquationMagnetodynamic2D.svg</file>
|
||||
|
||||
<!-- gui command icons: meshes -->
|
||||
<file>icons/FEM_CreateElementsSet.svg</file>
|
||||
<file>icons/FEM_CreateNodesSet.svg</file>
|
||||
<file>icons/FEM_FEMMesh2Mesh.svg</file>
|
||||
<file>icons/FEM_MeshBoundaryLayer.svg</file>
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 6.1 KiB |
820
src/Mod/Fem/Gui/TaskCreateElementSet.cpp
Normal file
820
src/Mod/Fem/Gui/TaskCreateElementSet.cpp
Normal file
@@ -0,0 +1,820 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* implementation of the erase elements function *
|
||||
* *
|
||||
* loosely based on: TaskCreateNodeSet.cpp *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
#ifndef _PreComp_
|
||||
#include <Inventor/events/SoMouseButtonEvent.h>
|
||||
#include <Inventor/nodes/SoCamera.h>
|
||||
#include <Inventor/nodes/SoEventCallback.h>
|
||||
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QMessageBox>
|
||||
#include <SMESH_Mesh.hxx>
|
||||
#include <SMESHDS_Mesh.hxx>
|
||||
#include <Standard_math.hxx>
|
||||
#include <SMESH_MeshEditor.hxx>
|
||||
#endif
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
#include <Gui/Utilities.h>
|
||||
#include <Gui/View3DInventor.h>
|
||||
#include <Gui/View3DInventorViewer.h>
|
||||
#include <Gui/ViewProvider.h>
|
||||
#include <Gui/WaitCursor.h>
|
||||
|
||||
#include <Mod/Fem/App/FemMeshObject.h>
|
||||
#include <Mod/Fem/App/FemSetElementNodesObject.h>
|
||||
|
||||
#include "FemSelectionGate.h"
|
||||
#include "TaskCreateElementSet.h"
|
||||
#include "ViewProviderFemMesh.h"
|
||||
#include "ui_TaskCreateElementSet.h"
|
||||
|
||||
#include <Gui/CommandT.h>
|
||||
#include <Gui/MainWindow.h>
|
||||
|
||||
|
||||
using namespace Gui;
|
||||
// using namespace Fem;
|
||||
using namespace FemGui;
|
||||
using namespace std;
|
||||
|
||||
std::string inp_file = "abaqusOutputFileEraseElements.inp";
|
||||
|
||||
std::string createdMesh = "cDUMMY";
|
||||
std::string startResultMesh = "StartResultMesh"; // StartResultMesh";
|
||||
std::string newResultMesh = "NewResultMesh";
|
||||
std::string newFemMesh = "NewFemMesh";
|
||||
|
||||
std::string TaskCreateElementSet::currentProject = "";
|
||||
|
||||
std::string uniqueMesh = "";
|
||||
std::string newProject = "";
|
||||
std::string resultMesh = "Result";
|
||||
std::string actualResultMesh = "XXXXXX";
|
||||
std::string lastName = "";
|
||||
std::string highLightMesh; // name of highlighted mesh
|
||||
std::string meshType; // type of - either 'result' or 'femmesh'
|
||||
int passResult = 0;
|
||||
int passFemMesh = 0;
|
||||
int maxProject = 10;
|
||||
double** nodeCoords; // these are node coords
|
||||
int* nodeNumbers; // these are node numbers - probably not required[100];
|
||||
|
||||
|
||||
string myToUpper(std::string str)
|
||||
{
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
str[i] = toupper(str[i]);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
void addFaceToMesh(const std::vector<const SMDS_MeshNode*> nodes, SMESHDS_Mesh* MeshDS, int EID)
|
||||
{
|
||||
int nbNodes = nodes.size();
|
||||
switch (nbNodes) {
|
||||
case 3: // 3 node triangle
|
||||
MeshDS->AddFaceWithID(nodes[0], nodes[1], nodes[2], EID);
|
||||
break;
|
||||
case 4: // 4 node quadrilateral
|
||||
MeshDS->AddFaceWithID(nodes[0], nodes[1], nodes[2], nodes[3], EID);
|
||||
break;
|
||||
case 6: // 6 node triangle
|
||||
MeshDS->AddFaceWithID(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], EID);
|
||||
break;
|
||||
case 8: // 8 node quadrilateral
|
||||
MeshDS->AddFaceWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
EID);
|
||||
break;
|
||||
}
|
||||
} // addFaceToMesh
|
||||
|
||||
void addVolumeToMesh(const std::vector<const SMDS_MeshNode*> nodes, SMESHDS_Mesh* MeshDS, int EID)
|
||||
{
|
||||
|
||||
int nbNodes = nodes.size();
|
||||
|
||||
switch (nbNodes) {
|
||||
case 4: // 4 node tetrahedron
|
||||
MeshDS->AddVolumeWithID(nodes[0], nodes[1], nodes[2], nodes[3], EID);
|
||||
break;
|
||||
case 5: // 5 node pyramid
|
||||
MeshDS->AddVolumeWithID(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], EID);
|
||||
break;
|
||||
case 6: // 6 node pentahedron
|
||||
MeshDS
|
||||
->AddVolumeWithID(nodes[0], nodes[1], nodes[2], nodes[3], nodes[4], nodes[5], EID);
|
||||
break;
|
||||
case 8: // 8 node hexahedron
|
||||
MeshDS->AddVolumeWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
EID);
|
||||
break;
|
||||
case 10: // 10 node tetrahedron
|
||||
MeshDS->AddVolumeWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
nodes[8],
|
||||
nodes[9],
|
||||
EID);
|
||||
break;
|
||||
case 13: // 13 node pyramid
|
||||
MeshDS->AddVolumeWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
nodes[8],
|
||||
nodes[9],
|
||||
nodes[10],
|
||||
nodes[11],
|
||||
nodes[12],
|
||||
EID);
|
||||
break;
|
||||
case 15: // 15 node pentahedron
|
||||
MeshDS->AddVolumeWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
nodes[8],
|
||||
nodes[9],
|
||||
nodes[10],
|
||||
nodes[11],
|
||||
nodes[12],
|
||||
nodes[13],
|
||||
nodes[14],
|
||||
EID);
|
||||
break;
|
||||
case 20: // 20 node hexahedron
|
||||
MeshDS->AddVolumeWithID(nodes[0],
|
||||
nodes[1],
|
||||
nodes[2],
|
||||
nodes[3],
|
||||
nodes[4],
|
||||
nodes[5],
|
||||
nodes[6],
|
||||
nodes[7],
|
||||
nodes[8],
|
||||
nodes[9],
|
||||
nodes[10],
|
||||
nodes[11],
|
||||
nodes[12],
|
||||
nodes[13],
|
||||
nodes[14],
|
||||
nodes[15],
|
||||
nodes[16],
|
||||
nodes[17],
|
||||
nodes[18],
|
||||
nodes[19],
|
||||
EID);
|
||||
break;
|
||||
} // default: {}
|
||||
|
||||
} // addVolumeToMesh
|
||||
|
||||
void myCopyResultsMesh(std::string oldName, std::string newName)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
Base::Console().Warning("copy: %s and %s\n", oldName.c_str(), newName.c_str());
|
||||
if (oldName.compare(newName) == 0 && error == 0) {
|
||||
error = 1;
|
||||
Base::Console().Warning("Can't copy ResultMesh to ResultMesh: %s and %s\n",
|
||||
oldName.c_str(),
|
||||
newName.c_str());
|
||||
QMessageBox::warning(
|
||||
Gui::getMainWindow(),
|
||||
// QMessageBox::warning(Gui::MainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Wrong selection"),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Can't copy ResultMesh to ResultMesh"));
|
||||
}
|
||||
if ((oldName.find("Result") == std::string::npos || newName.find("Result") == std::string::npos)
|
||||
&& error == 0) {
|
||||
error = 1;
|
||||
Base::Console().Warning("Mesh must be results: %s\n", oldName.c_str());
|
||||
QMessageBox::warning(
|
||||
Gui::getMainWindow(),
|
||||
// QMessageBox::warning(Gui::MainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Wrong selection"),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Mesh must be a Results mesh"));
|
||||
}
|
||||
if (error == 0) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"c = FreeCADGui.ActiveDocument.getObject(\'%s\')",
|
||||
oldName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"FreeCAD.ActiveDocument.%s.FemMesh = c.Object.FemMesh",
|
||||
newName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').BackfaceCulling = False",
|
||||
newName.c_str());
|
||||
}
|
||||
} // copyresultsmesh
|
||||
|
||||
void generateMesh(std::string meshType)
|
||||
{
|
||||
if (passResult + passFemMesh == 0) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "import Fem,os");
|
||||
}
|
||||
|
||||
if (strcmp(meshType.c_str(), "result") == 0) {
|
||||
if (passResult == 0) {
|
||||
string xstr(startResultMesh.c_str());
|
||||
createdMesh = newResultMesh.c_str();
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc,
|
||||
"obj1 = App.ActiveDocument.addObject('Fem::FemMeshObject', \'%s\')",
|
||||
startResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').Visibility = False",
|
||||
startResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"ne = Gui.ActiveDocument.getObject(\'%s\')",
|
||||
actualResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "obj1.FemMesh = ne.Object.FemMesh");
|
||||
}
|
||||
else if (passResult > 0) {
|
||||
createdMesh = newResultMesh.c_str();
|
||||
}
|
||||
passResult += 1;
|
||||
}
|
||||
else if (strcmp(meshType.c_str(), "femmesh") == 0) {
|
||||
if (passFemMesh == 0) {
|
||||
string xstr("no rename required");
|
||||
createdMesh = newFemMesh.c_str();
|
||||
}
|
||||
else if (passFemMesh > 0) {
|
||||
createdMesh = newFemMesh.c_str();
|
||||
}
|
||||
passFemMesh += 1;
|
||||
}
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
uniqueMesh = doc->getUniqueObjectName(createdMesh.c_str());
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').Visibility = False",
|
||||
highLightMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "newermesh = Fem.read(\'%s\')", inp_file.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"obj = App.ActiveDocument.addObject('Fem::FemMeshObject', \'%s\')",
|
||||
uniqueMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "obj.FemMesh = newermesh");
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').BackfaceCulling = False",
|
||||
uniqueMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').Visibility = True",
|
||||
uniqueMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "os.remove(\'%s\')", inp_file.c_str());
|
||||
|
||||
if (strcmp(meshType.c_str(), "result") == 0) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"c = FreeCADGui.ActiveDocument.getObject(\'%s\')",
|
||||
uniqueMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"FreeCAD.ActiveDocument.%s.FemMesh = c.Object.FemMesh",
|
||||
actualResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').BackfaceCulling = False",
|
||||
actualResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').Visibility = True",
|
||||
actualResultMesh.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"Gui.ActiveDocument.getObject(\'%s\').Visibility = False",
|
||||
uniqueMesh.c_str());
|
||||
}
|
||||
} // generate mesh
|
||||
|
||||
void writeToFile(std::string fileName,
|
||||
SMESHDS_Mesh* newMesh,
|
||||
int* nodeNumbers,
|
||||
double** nodeCoords,
|
||||
int rows,
|
||||
int requiredType)
|
||||
{
|
||||
std::map<int, std::string> elType2D;
|
||||
std::map<int, std::string> elType3D;
|
||||
|
||||
elType2D[3] = "S3"; // 3 node triangle
|
||||
elType2D[6] = "S6"; // 4 node quadrilateral
|
||||
elType2D[4] = "S4"; // 6 node triangle
|
||||
elType2D[8] = "S8"; // 8 node quadrilateral
|
||||
|
||||
elType3D[4] = "C3D4"; // 4 node tetrahedron
|
||||
elType3D[6] = "C3D6"; // 6 node pentahedron
|
||||
elType3D[8] = "C3D8"; // 8 node hexahedron
|
||||
elType3D[10] = "C3D10"; // 10 node tetrahedron
|
||||
elType3D[15] = "C3D15"; // 15 node pentahedron
|
||||
elType3D[20] = "C3D20"; // 20 node hexahedron
|
||||
// no pyramid elements
|
||||
FILE* fptr = fopen(fileName.c_str(), "w");
|
||||
if (fptr == NULL) {
|
||||
return;
|
||||
}
|
||||
fprintf(fptr, "** written by Erase Elements inp file writer for CalculiX,Abaqus meshes\n");
|
||||
fprintf(fptr, "** all mesh elements.\n");
|
||||
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "** Nodes\n");
|
||||
fprintf(fptr, "*Node, NSET=Nall\n");
|
||||
|
||||
for (int i = 1; i < rows + 1; i++) {
|
||||
if (nodeNumbers[i] > 0) {
|
||||
fprintf(fptr,
|
||||
"%d, %e, %e, %e\n",
|
||||
nodeNumbers[i],
|
||||
nodeCoords[i][0],
|
||||
nodeCoords[i][1],
|
||||
nodeCoords[i][2]);
|
||||
}
|
||||
}
|
||||
|
||||
SMDS_ElemIteratorPtr srcElemIt;
|
||||
SMDS_NodeIteratorPtr srcNodeIt;
|
||||
srcElemIt = newMesh->elementsIterator();
|
||||
srcNodeIt = newMesh->nodesIterator();
|
||||
const SMDS_MeshNode* nSrc;
|
||||
int NID, EID;
|
||||
while (srcNodeIt->more()) {
|
||||
const SMDS_MeshNode* node = srcNodeIt->next();
|
||||
NID = node->GetID();
|
||||
}
|
||||
int numberNodes = -1;
|
||||
while (srcElemIt->more()) {
|
||||
const SMDS_MeshElement* elem = srcElemIt->next();
|
||||
EID = elem->GetID();
|
||||
if (elem->GetType() != requiredType) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (numberNodes != elem->NbNodes()) {
|
||||
if (requiredType == 4) {
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "%s", "** Volume elements\n");
|
||||
fprintf(fptr,
|
||||
"*Element, TYPE=%s, ELSET=Evolumes\n",
|
||||
elType3D[elem->NbNodes()].c_str());
|
||||
}
|
||||
else if (requiredType == 3) {
|
||||
fprintf(fptr, "%s", "** Face elements\n");
|
||||
fprintf(fptr,
|
||||
"*Element, TYPE=%s, ELSET=Efaces\n",
|
||||
elType2D[elem->NbNodes()].c_str());
|
||||
}
|
||||
numberNodes = elem->NbNodes();
|
||||
}
|
||||
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
||||
fprintf(fptr, "%d", EID);
|
||||
for (int iN = 0; nIt->more(); ++iN) {
|
||||
nSrc = static_cast<const SMDS_MeshNode*>(nIt->next());
|
||||
NID = nSrc->GetID();
|
||||
fprintf(fptr, ", %d", NID);
|
||||
} // for iN
|
||||
fprintf(fptr, "\n");
|
||||
} // while print
|
||||
if (requiredType == 4) {
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "\n");
|
||||
fprintf(fptr, "%s", "** Define element set Eall\n");
|
||||
fprintf(fptr, "%s", "*ELSET, ELSET=Eall\n");
|
||||
fprintf(fptr, "%s", "Evolumes\n");
|
||||
}
|
||||
else if (requiredType == 3) {
|
||||
fprintf(fptr, "%s", "** Define element set Eall\n");
|
||||
fprintf(fptr, "%s", "*ELSET, ELSET=Eall\n");
|
||||
fprintf(fptr, "%s", "Efaces\n");
|
||||
}
|
||||
|
||||
fclose(fptr);
|
||||
return;
|
||||
}
|
||||
|
||||
TaskCreateElementSet::TaskCreateElementSet(Fem::FemSetElementNodesObject* pcObject, QWidget* parent)
|
||||
: TaskBox(Gui::BitmapFactory().pixmap("FEM_CreateElementsSet"),
|
||||
tr("Elements set"),
|
||||
true,
|
||||
parent)
|
||||
, pcObject(pcObject)
|
||||
, selectionMode(none)
|
||||
{
|
||||
proxy = new QWidget(this);
|
||||
ui = new Ui_TaskCreateElementSet();
|
||||
ui->setupUi(proxy);
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
this->groupLayout()->addWidget(proxy);
|
||||
QObject::connect(ui->toolButton_Poly, SIGNAL(clicked()), this, SLOT(Poly()));
|
||||
QObject::connect(ui->toolButton_Restore, SIGNAL(clicked()), this, SLOT(Restore()));
|
||||
QObject::connect(ui->toolButton_Rename, SIGNAL(clicked()), this, SLOT(CopyResultsMesh()));
|
||||
// check if the Link to the FemMesh is defined
|
||||
assert(pcObject->FemMesh.getValue<Fem::FemMeshObject*>());
|
||||
MeshViewProvider =
|
||||
dynamic_cast<ViewProviderFemMesh*>(Gui::Application::Instance->getViewProvider(
|
||||
pcObject->FemMesh.getValue<Fem::FemMeshObject*>()));
|
||||
assert(MeshViewProvider);
|
||||
|
||||
elementTempSet = pcObject->Elements.getValues();
|
||||
std::set<long int>::iterator it;
|
||||
std::string info;
|
||||
info = "Delete the generated data in the other project: " + std::string(currentProject);
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
newProject = doc->Label.getValue();
|
||||
if (strcmp(currentProject.c_str(), newProject.c_str()) != 0
|
||||
&& (passResult + passFemMesh != 0)) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
// QMessageBox::warning(Gui::MainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Wrong selection"),
|
||||
qApp->translate("CmdFemCreateElementsSet", info.c_str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TaskCreateElementSet::Poly(void)
|
||||
{
|
||||
Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
Gui::MDIView* view = doc->getActiveView();
|
||||
if (view->getTypeId().isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
|
||||
Gui::View3DInventorViewer* viewer = ((Gui::View3DInventor*)view)->getViewer();
|
||||
viewer->setEditing(true);
|
||||
viewer->startSelection(Gui::View3DInventorViewer::Clip);
|
||||
viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(),
|
||||
DefineElementsCallback,
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskCreateElementSet::CopyResultsMesh(void)
|
||||
{
|
||||
std::vector<Gui::SelectionSingleton::SelObj> selection =
|
||||
Gui::Selection().getSelection(); // [0];
|
||||
highLightMesh = selection[0].FeatName;
|
||||
myCopyResultsMesh(highLightMesh, actualResultMesh);
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "Gui.activeDocument().resetEdit()");
|
||||
}
|
||||
|
||||
void TaskCreateElementSet::Restore(void)
|
||||
{
|
||||
App::Document* doc = App::GetApplication().getActiveDocument();
|
||||
const std::vector<App::DocumentObject*>& all = doc->getObjects();
|
||||
int number = 0, xpos = 0;
|
||||
int elList = 0;
|
||||
// put reverse here
|
||||
|
||||
std::vector<string> STR;
|
||||
for (std::vector<App::DocumentObject*>::const_iterator it = all.begin(); it != all.end();
|
||||
++it) {
|
||||
std::string objectN = all[xpos]->getNameInDocument();
|
||||
STR.push_back(objectN);
|
||||
xpos++;
|
||||
}
|
||||
|
||||
// iterate through in reverse order
|
||||
for (std::vector<string>::reverse_iterator it = STR.rbegin(); it != STR.rend(); ++it) {
|
||||
std::string objectN = (*it);
|
||||
if (objectN.find(startResultMesh) != std::string::npos) {
|
||||
number++;
|
||||
myCopyResultsMesh(objectN, actualResultMesh);
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.removeObject(\'%s\')",
|
||||
objectN.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
else if (objectN.find(newResultMesh) != std::string::npos) {
|
||||
number++;
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.removeObject(\'%s\')",
|
||||
objectN.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
else if (objectN.find(actualResultMesh) != std::string::npos) {}
|
||||
else if (objectN.find(newFemMesh) != std::string::npos) {
|
||||
number++;
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.removeObject(\'%s\')",
|
||||
objectN.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
else if (objectN.find(Fem::FemSetElementNodesObject::elementsName) != std::string::npos) {
|
||||
if (elList > 0) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.removeObject(\'%s\')",
|
||||
objectN.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
}
|
||||
else if (elList == 0) {
|
||||
elList++;
|
||||
lastName = objectN;
|
||||
}
|
||||
}
|
||||
} // for
|
||||
if (strcmp(lastName.c_str(), "") != 0) {
|
||||
// blank last name - no action
|
||||
}
|
||||
else if (number == 0) {
|
||||
QMessageBox::warning(Gui::getMainWindow(),
|
||||
// QMessageBox::warning(Gui::MainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Wrong selection"),
|
||||
qApp->translate("CmdFemCreateElementsSet", "No Data To Restore\n"));
|
||||
return;
|
||||
}
|
||||
passResult = 0;
|
||||
passFemMesh = 0;
|
||||
currentProject = "";
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "Gui.activeDocument().resetEdit()");
|
||||
return;
|
||||
} // restore
|
||||
|
||||
void TaskCreateElementSet::DefineElementsCallback(void* ud, SoEventCallback* n)
|
||||
{
|
||||
Gui::WaitCursor wc;
|
||||
TaskCreateElementSet* taskBox = static_cast<TaskCreateElementSet*>(ud);
|
||||
// When this callback function is invoked we must in either case leave the edit mode
|
||||
Gui::View3DInventorViewer* view =
|
||||
reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
|
||||
view->setEditing(false);
|
||||
view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), DefineElementsCallback, ud);
|
||||
n->setHandled();
|
||||
|
||||
Gui::SelectionRole role;
|
||||
std::vector<SbVec2f> clPoly = view->getGLPolygon(&role);
|
||||
if (clPoly.size() < 3) {
|
||||
return;
|
||||
}
|
||||
if (clPoly.front() != clPoly.back()) {
|
||||
clPoly.push_back(clPoly.front());
|
||||
}
|
||||
|
||||
SoCamera* cam = view->getSoRenderManager()->getCamera();
|
||||
SbViewVolume vv = cam->getViewVolume();
|
||||
Gui::ViewVolumeProjection proj(vv);
|
||||
Base::Polygon2d polygon;
|
||||
for (std::vector<SbVec2f>::const_iterator it = clPoly.begin(); it != clPoly.end(); ++it) {
|
||||
polygon.Add(Base::Vector2d((*it)[0], (*it)[1]));
|
||||
}
|
||||
|
||||
taskBox->DefineNodes(polygon, proj, role == Gui::SelectionRole::Inner ? true : false);
|
||||
} // DefineElementsCallback
|
||||
|
||||
void TaskCreateElementSet::DefineNodes(const Base::Polygon2d& polygon,
|
||||
const Gui::ViewVolumeProjection& proj,
|
||||
bool inner)
|
||||
{
|
||||
const SMESHDS_Mesh* srcMeshDS =
|
||||
const_cast<SMESH_Mesh*>(
|
||||
pcObject->FemMesh.getValue<Fem::FemMeshObject*>()->FemMesh.getValue().getSMesh())
|
||||
->GetMeshDS();
|
||||
|
||||
std::vector<Gui::SelectionSingleton::SelObj> selection =
|
||||
Gui::Selection().getSelection(); // [0];
|
||||
highLightMesh = selection[0].FeatName;
|
||||
|
||||
meshType = "NULL";
|
||||
std::size_t found = myToUpper(highLightMesh).find(myToUpper(resultMesh));
|
||||
actualResultMesh = highLightMesh;
|
||||
// highLightMesh.find(myToUpper(resultMesh));
|
||||
|
||||
if (found != std::string::npos) {
|
||||
meshType = "result";
|
||||
}
|
||||
else {
|
||||
meshType = "femmesh";
|
||||
}
|
||||
// std::string lightMesh = selection[0].FeatID;
|
||||
|
||||
elementTempSet.clear();
|
||||
int nElements = srcMeshDS->GetMeshInfo().NbElements();
|
||||
int nVolumes = srcMeshDS->GetMeshInfo().NbVolumes();
|
||||
int requiredType = nVolumes > 0 ? 4 : 3; // type = 4 - 3D, type = 3 - 2D
|
||||
|
||||
double cOfGX, cOfGY, cOfGZ;
|
||||
const SMDS_MeshNode* nSrc;
|
||||
int EID;
|
||||
currentProject = newProject;
|
||||
|
||||
SMESHDS_Mesh* newMeshDS = new SMESHDS_Mesh(nElements, true);
|
||||
// FemMesh femMesh = FemMesh(); // *getFemMeshPtr();
|
||||
Base::Vector3f pt2d;
|
||||
|
||||
SMDS_ElemIteratorPtr srcElemIt = srcMeshDS->elementsIterator();
|
||||
SMDS_NodeIteratorPtr srcNode = srcMeshDS->nodesIterator();
|
||||
|
||||
const SMDS_MeshNode* nTgt;
|
||||
std::vector<const SMDS_MeshNode*> nodes;
|
||||
int keepElement = 0, maxNode = -1;
|
||||
while (srcNode->more()) {
|
||||
const SMDS_MeshNode* aNode = srcNode->next();
|
||||
if (aNode->GetID() > maxNode) {
|
||||
maxNode = aNode->GetID();
|
||||
}
|
||||
}
|
||||
|
||||
nodeNumbers = new int[maxNode + 2];
|
||||
nodeCoords = new double*[maxNode + 2]; // these are node coords
|
||||
for (int i = 0; i < maxNode + 2; i++) {
|
||||
nodeCoords[i] = new double[3]; // x,y,z
|
||||
nodeNumbers[i] = 0;
|
||||
}
|
||||
|
||||
elementTempSet.insert(requiredType * -1); // the type of elements
|
||||
int pNodes; // the first pnodes are used in the cofg calc
|
||||
|
||||
while (srcElemIt->more()) {
|
||||
|
||||
pNodes = 4; // the first pnodes are used in the cofg calc
|
||||
const SMDS_MeshElement* elem = srcElemIt->next();
|
||||
nodes.resize(elem->NbNodes());
|
||||
EID = elem->GetID();
|
||||
if (elem->GetType() != requiredType) {
|
||||
continue;
|
||||
}
|
||||
SMDS_ElemIteratorPtr nIt = elem->nodesIterator();
|
||||
|
||||
if (requiredType == 4) // 3D
|
||||
{
|
||||
if (elem->NbNodes() == 8 || elem->NbNodes() == 20) { // 8 or 20 node brick
|
||||
pNodes = 8;
|
||||
}
|
||||
if (elem->NbNodes() == 6 || elem->NbNodes() == 15) { // 6 or 15 node penta
|
||||
pNodes = 8;
|
||||
}
|
||||
}
|
||||
else if (requiredType == 3) // 2D
|
||||
{
|
||||
if (elem->NbNodes() == 3 || elem->NbNodes() == 6) { // 3 or 6 node triangles
|
||||
pNodes = 3;
|
||||
}
|
||||
}
|
||||
cOfGX = 0.0;
|
||||
cOfGY = 0.0;
|
||||
cOfGZ = 0.0;
|
||||
for (int iN = 0; nIt->more(); ++iN) {
|
||||
nSrc = static_cast<const SMDS_MeshNode*>(nIt->next());
|
||||
nTgt = srcMeshDS->FindNode(nSrc->GetID());
|
||||
nodes[iN] = nTgt;
|
||||
newMeshDS->AddNodeWithID(nSrc->X(), nSrc->Y(), nSrc->Z(), nSrc->GetID());
|
||||
if (nodeNumbers[nSrc->GetID()] == 0) {
|
||||
nodeCoords[nSrc->GetID()][0] = nSrc->X();
|
||||
nodeCoords[nSrc->GetID()][1] = nSrc->Y();
|
||||
nodeCoords[nSrc->GetID()][2] = nSrc->Z();
|
||||
// write all nodes if result mesh
|
||||
if (strcmp(meshType.c_str(), "result") == 0) {
|
||||
nodeNumbers[nSrc->GetID()] = nSrc->GetID();
|
||||
}
|
||||
}
|
||||
if (iN < pNodes) {
|
||||
cOfGX += nSrc->X() / pNodes;
|
||||
cOfGY += nSrc->Y() / pNodes;
|
||||
cOfGZ += nSrc->Z() / pNodes;
|
||||
}
|
||||
} // for iN
|
||||
|
||||
SMESH_MeshEditor::ElemFeatures elemFeat(elem->GetType(), elem->IsPoly());
|
||||
elemFeat.SetID(EID);
|
||||
|
||||
/* add the bit to determine which elements are outside the poly */
|
||||
Base::Vector3f vec(cOfGX, cOfGY, cOfGZ);
|
||||
pt2d = proj(vec);
|
||||
if (polygon.Contains(Base::Vector2d(pt2d.x, pt2d.y)) != inner) {
|
||||
if (strcmp(meshType.c_str(), "femmesh") == 0) {
|
||||
for (long unsigned int i = 0; i < nodes.size(); i++) {
|
||||
nodeNumbers[nodes[i]->GetID()] = nodes[i]->GetID();
|
||||
}
|
||||
}
|
||||
|
||||
elementTempSet.insert(EID);
|
||||
keepElement += 1;
|
||||
if (requiredType == 4) {
|
||||
addVolumeToMesh(nodes, newMeshDS, EID);
|
||||
}
|
||||
else if (requiredType == 3) {
|
||||
addFaceToMesh(nodes, newMeshDS, EID);
|
||||
}
|
||||
}
|
||||
} // while
|
||||
int erase;
|
||||
if (nVolumes != 0) {
|
||||
erase = nVolumes - keepElement;
|
||||
}
|
||||
else {
|
||||
erase = nElements - keepElement;
|
||||
}
|
||||
if (keepElement > 0) {
|
||||
Base::Console().Warning("Number of Elements Kept: %d, Number of Elements Erased: %d\n",
|
||||
keepElement,
|
||||
erase);
|
||||
writeToFile(inp_file, newMeshDS, nodeNumbers, nodeCoords, maxNode, requiredType);
|
||||
generateMesh(meshType);
|
||||
}
|
||||
else {
|
||||
QMessageBox::warning(
|
||||
Gui::getMainWindow(),
|
||||
// QMessageBox::warning(Gui::MainWindow(),
|
||||
qApp->translate("CmdFemCreateElementsSet", "Erased Elements"),
|
||||
qApp->translate("CmdFemCreateElementsSet", "All Elements Erased - no mesh generated."));
|
||||
}
|
||||
newMeshDS->Modified();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "Gui.activeDocument().resetEdit()");
|
||||
|
||||
} // void TaskCreateElementSet::DefineNodes
|
||||
|
||||
void TaskCreateElementSet::onSelectionChanged(const Gui::SelectionChanges& msg)
|
||||
{
|
||||
if (selectionMode == none) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.Type == Gui::SelectionChanges::AddSelection) {
|
||||
std::string subName(msg.pSubName);
|
||||
unsigned int i = 0;
|
||||
for (; i < subName.size(); i++) {
|
||||
if (msg.pSubName[i] == 'F') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
int elem = atoi(subName.substr(4).c_str());
|
||||
int face = atoi(subName.substr(i + 1).c_str());
|
||||
elementTempSet.clear();
|
||||
std::set<long> tmp =
|
||||
pcObject->FemMesh.getValue<Fem::FemMeshObject*>()->FemMesh.getValue().getSurfaceNodes(
|
||||
elem,
|
||||
face);
|
||||
elementTempSet.insert(tmp.begin(), tmp.end());
|
||||
|
||||
selectionMode = none;
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
TaskCreateElementSet::~TaskCreateElementSet()
|
||||
{
|
||||
// delete last elementsset
|
||||
if (strcmp(lastName.c_str(), "") != 0) {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.removeObject(\'%s\')",
|
||||
lastName.c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.recompute()");
|
||||
lastName = "";
|
||||
}
|
||||
delete ui;
|
||||
}
|
||||
|
||||
#include "moc_TaskCreateElementSet.cpp"
|
||||
96
src/Mod/Fem/Gui/TaskCreateElementSet.h
Normal file
96
src/Mod/Fem/Gui/TaskCreateElementSet.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: TaskCreateNodeSet.h *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GUI_TASKVIEW_TaskCreateElementSet_H
|
||||
#define GUI_TASKVIEW_TaskCreateElementSet_H
|
||||
|
||||
#include <Gui/TaskView/TaskView.h>
|
||||
#include <Mod/Fem/App/FemSetElementNodesObject.h>
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
class Ui_TaskCreateElementSet;
|
||||
class SoEventCallback;
|
||||
|
||||
namespace Base
|
||||
{
|
||||
class Polygon2d;
|
||||
}
|
||||
namespace App
|
||||
{
|
||||
class Property;
|
||||
}
|
||||
|
||||
namespace Gui
|
||||
{
|
||||
class ViewProvider;
|
||||
class ViewVolumeProjection;
|
||||
} // namespace Gui
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
class ViewProviderFemMesh;
|
||||
|
||||
|
||||
class TaskCreateElementSet: public Gui::TaskView::TaskBox, public Gui::SelectionObserver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskCreateElementSet(Fem::FemSetElementNodesObject* pcObject,
|
||||
QWidget* parent = nullptr);
|
||||
~TaskCreateElementSet() override;
|
||||
|
||||
std::set<long> elementTempSet;
|
||||
ViewProviderFemMesh* MeshViewProvider;
|
||||
static std::string currentProject;
|
||||
|
||||
private Q_SLOTS:
|
||||
void Poly();
|
||||
void Restore();
|
||||
void CopyResultsMesh();
|
||||
|
||||
protected:
|
||||
Fem::FemSetElementNodesObject* pcObject;
|
||||
static void DefineElementsCallback(void* ud, SoEventCallback* n);
|
||||
void DefineNodes(const Base::Polygon2d& polygon, const Gui::ViewVolumeProjection& proj, bool);
|
||||
|
||||
protected:
|
||||
void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
enum selectionModes
|
||||
{
|
||||
none,
|
||||
PickElement
|
||||
} selectionMode;
|
||||
|
||||
private:
|
||||
QWidget* proxy;
|
||||
Ui_TaskCreateElementSet* ui;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
#endif // GUI_TASKVIEW_TaskCreateElementSet_H
|
||||
87
src/Mod/Fem/Gui/TaskCreateElementSet.ui
Normal file
87
src/Mod/Fem/Gui/TaskCreateElementSet.ui
Normal file
@@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TaskCreateElementSet</class>
|
||||
<widget class="QWidget" name="TaskCreateElementSet">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>407</width>
|
||||
<height>270</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0">
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton_Poly">
|
||||
<property name="text">
|
||||
<string>Poly</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Erase Elements by Polygon</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton_Restore">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Restore</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Delete New Meshes</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QToolButton" name="toolButton_Rename">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Copy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Copy Result Mesh</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
104
src/Mod/Fem/Gui/TaskDlgCreateElementSet.cpp
Normal file
104
src/Mod/Fem/Gui/TaskDlgCreateElementSet.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: TaskDlgCreateNodeSet.cpp *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "PreCompiled.h"
|
||||
|
||||
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
#include <Gui/Application.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/Document.h>
|
||||
|
||||
#include "TaskDlgCreateElementSet.h"
|
||||
#include "ViewProviderFemMesh.h"
|
||||
|
||||
|
||||
using namespace FemGui;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
//**************************************************************************
|
||||
// TaskDialog
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TaskDlgCreateElementSet::TaskDlgCreateElementSet(Fem::FemSetElementNodesObject* obj)
|
||||
: TaskDialog()
|
||||
, FemSetElementNodesObject(obj)
|
||||
{
|
||||
name = new TaskObjectName(obj);
|
||||
param = new TaskCreateElementSet(obj);
|
||||
|
||||
Content.push_back(name);
|
||||
Content.push_back(param);
|
||||
}
|
||||
|
||||
TaskDlgCreateElementSet::~TaskDlgCreateElementSet()
|
||||
{}
|
||||
|
||||
//==== calls from the TaskView ===============================================================
|
||||
|
||||
|
||||
void TaskDlgCreateElementSet::open()
|
||||
{
|
||||
// select->activate();
|
||||
// Edge2TaskObject->execute();
|
||||
// param->setEdgeAndClusterNbr(Edge2TaskObject->NbrOfEdges,Edge2TaskObject->NbrOfCluster);
|
||||
}
|
||||
|
||||
bool TaskDlgCreateElementSet::accept()
|
||||
{
|
||||
try {
|
||||
FemSetElementNodesObject->Elements.setValues(param->elementTempSet);
|
||||
FemSetElementNodesObject->recomputeFeature();
|
||||
// Gui::Document* doc = Gui::Application::Instance->activeDocument();
|
||||
// if(doc)
|
||||
// doc->resetEdit();
|
||||
param->MeshViewProvider->resetHighlightNodes();
|
||||
FemSetElementNodesObject->Label.setValue(name->name);
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
Base::Console().Warning("TaskDlgCreateElementSet::accept(): %s\n", e.what());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TaskDlgCreateElementSet::reject()
|
||||
{
|
||||
FemSetElementNodesObject->execute();
|
||||
param->MeshViewProvider->resetHighlightNodes();
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TaskDlgCreateElementSet::helpRequested()
|
||||
{}
|
||||
|
||||
#include "moc_TaskDlgCreateElementSet.cpp"
|
||||
86
src/Mod/Fem/Gui/TaskDlgCreateElementSet.h
Normal file
86
src/Mod/Fem/Gui/TaskDlgCreateElementSet.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: FemSetNodesObject.h *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef ROBOTGUI_TaskDlgCreateElementSet_H
|
||||
#define ROBOTGUI_TaskDlgCreateElementSet_H
|
||||
|
||||
#include <Gui/TaskView/TaskDialog.h>
|
||||
#include <Mod/Fem/App/FemSetElementNodesObject.h>
|
||||
|
||||
#include "TaskCreateElementSet.h"
|
||||
#include "TaskObjectName.h"
|
||||
|
||||
|
||||
// forward
|
||||
namespace Gui
|
||||
{
|
||||
namespace TaskView
|
||||
{
|
||||
class TaskSelectLinkProperty;
|
||||
}
|
||||
} // namespace Gui
|
||||
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
|
||||
/// simulation dialog for the TaskView
|
||||
class TaskDlgCreateElementSet: public Gui::TaskView::TaskDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TaskDlgCreateElementSet(Fem::FemSetElementNodesObject*);
|
||||
~TaskDlgCreateElementSet() override;
|
||||
|
||||
public:
|
||||
/// is called the TaskView when the dialog is opened
|
||||
void open() override;
|
||||
/// is called by the framework if the dialog is accepted (Ok)
|
||||
bool accept() override;
|
||||
/// is called by the framework if the dialog is rejected (Cancel)
|
||||
bool reject() override;
|
||||
/// is called by the framework if the user press the help button
|
||||
void helpRequested() override;
|
||||
|
||||
/// returns for Close and Help button
|
||||
QDialogButtonBox::StandardButtons getStandardButtons() const override
|
||||
{
|
||||
return QDialogButtonBox::Ok | QDialogButtonBox::Cancel;
|
||||
}
|
||||
|
||||
protected:
|
||||
TaskCreateElementSet* param;
|
||||
TaskObjectName* name;
|
||||
|
||||
Fem::FemSetElementNodesObject* FemSetElementNodesObject;
|
||||
};
|
||||
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
#endif // ROBOTGUI_TASKDLGSIMULATE_H
|
||||
57
src/Mod/Fem/Gui/ViewProviderSetElementNodes.cpp
Normal file
57
src/Mod/Fem/Gui/ViewProviderSetElementNodes.cpp
Normal file
@@ -0,0 +1,57 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: ViewProviderSetNodes.cpp *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include <Gui/Control.h>
|
||||
#include <Mod/Fem/App/FemSetElementNodesObject.h>
|
||||
#include <Mod/Fem/Gui/TaskDlgCreateElementSet.h>
|
||||
|
||||
#include "ViewProviderSetElementNodes.h"
|
||||
|
||||
|
||||
using namespace FemGui;
|
||||
|
||||
PROPERTY_SOURCE(FemGui::ViewProviderSetElementNodes, Gui::ViewProviderGeometryObject)
|
||||
|
||||
bool ViewProviderSetElementNodes::doubleClicked()
|
||||
{
|
||||
Gui::TaskView::TaskDialog* dlg =
|
||||
new TaskDlgCreateElementSet(static_cast<Fem::FemSetElementNodesObject*>(getObject()));
|
||||
Gui::Control().showDialog(dlg);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ViewProviderSetElementNodes::setEdit(int)
|
||||
{
|
||||
Gui::TaskView::TaskDialog* dlg =
|
||||
new TaskDlgCreateElementSet(static_cast<Fem::FemSetElementNodesObject*>(getObject()));
|
||||
Gui::Control().showDialog(dlg);
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewProviderSetElementNodes::unsetEdit(int)
|
||||
{}
|
||||
50
src/Mod/Fem/Gui/ViewProviderSetElementNodes.h
Normal file
50
src/Mod/Fem/Gui/ViewProviderSetElementNodes.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* *
|
||||
* based on: ViewProviderSetNodes.h *
|
||||
* Copyright (c) 2013 Jürgen Riegel (FreeCAD@juergen-riegel.net) *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef FEM_ViewProviderSetElementNodes_H
|
||||
#define FEM_ViewProviderSetElementNodes_H
|
||||
|
||||
#include <Gui/ViewProviderGeometryObject.h>
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
class ViewProviderSetElementNodes: public Gui::ViewProviderGeometryObject
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderSetElementNodes);
|
||||
|
||||
public:
|
||||
bool doubleClicked() override;
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
void unsetEdit(int ModNum) override;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
|
||||
#endif // FEM_ViewProviderSetElementNodes_H
|
||||
@@ -1,4 +1,9 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2023 Peter McB *
|
||||
* additional statement(s) for element sets: *
|
||||
* added entry to Gui::MenuItem* mesh *
|
||||
* *
|
||||
* added to: Workbench.cpp
|
||||
* Copyright (c) 2008 Werner Mayer <werner.wm.mayer@gmx.de> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
@@ -319,7 +324,8 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
<< "FEM_MeshRegion"
|
||||
<< "FEM_MeshGroup"
|
||||
<< "Separator"
|
||||
// << "FEM_CreateNodesSet"
|
||||
// << "FEM_CreateNodesSet"
|
||||
<< "FEM_CreateElementsSet"
|
||||
<< "FEM_FEMMesh2Mesh";
|
||||
|
||||
Gui::MenuItem* solve = new Gui::MenuItem;
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2023 Peter McB *
|
||||
# * added the function, mesh_2_femmesh, to convert the MESH *
|
||||
# * into a triangular FEMMESH *
|
||||
# * *
|
||||
# * Copyright (c) 2016 Frantisek Loeffelmann <LoffF@email.cz> *
|
||||
# * extension to the work of: *
|
||||
# Frantisek Loeffelmann, Ulrich Brammer, Bernd Hahnebach *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -21,7 +26,7 @@
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FemMesh to Mesh converter"
|
||||
__author__ = "Frantisek Loeffelmann, Ulrich Brammer, Bernd Hahnebach"
|
||||
__author__ = "Frantisek Loeffelmann, Ulrich Brammer, Bernd Hahnebach, Peter McB"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
## @package FwmMesh2Mesh
|
||||
@@ -30,6 +35,7 @@ __url__ = "https://www.freecad.org"
|
||||
import time
|
||||
|
||||
import FreeCAD
|
||||
import Fem
|
||||
# import Mesh
|
||||
|
||||
|
||||
@@ -202,4 +208,53 @@ def femmesh_2_mesh(myFemMesh, myResults=None, myDispScale=1):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Mesh by surface search method: {}\n".format(end_time - start_time)
|
||||
)
|
||||
# call to mesh_2_femmesh to convert mesh to femmesh before return statement
|
||||
mesh2femmesh = mesh_2_femmesh(myFemMesh, singleFaces, faceCodeDict)
|
||||
return output_mesh
|
||||
|
||||
# additional function to convert mesh to femmesh
|
||||
def mesh_2_femmesh(myFemMesh, singleFaces, faceCodeDict):
|
||||
start_time = time.process_time()
|
||||
femmesh = Fem.FemMesh()
|
||||
myfemmesh = myFemMesh.Nodes
|
||||
# nodes contains the nodes that are used
|
||||
nodes = {}
|
||||
for myFace in singleFaces:
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
for j in (0, 1, 2):
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
if len(face_nodes) == 4:
|
||||
j = 3
|
||||
try:
|
||||
nodes[face_nodes[j]] += 1
|
||||
except:
|
||||
nodes[face_nodes[j]] = 0
|
||||
sfNode = femmesh.addNode
|
||||
sfFace = femmesh.addFace
|
||||
for key in myFemMesh.Nodes:
|
||||
mynode = myfemmesh[key]
|
||||
try:
|
||||
if(nodes[key] >= 0):
|
||||
sfNode(mynode[0], mynode[1], mynode[2], key)
|
||||
except:
|
||||
pass
|
||||
|
||||
output_mesh = []
|
||||
|
||||
for myFace in singleFaces:
|
||||
face_nodes = faceCodeDict[myFace]
|
||||
sfFace(face_nodes[0], face_nodes[1], face_nodes[2])
|
||||
if len(face_nodes) == 4:
|
||||
sfFace(face_nodes[2], face_nodes[3], face_nodes[0])
|
||||
obj = FreeCAD.ActiveDocument.addObject(
|
||||
"Fem::FemMeshObject", "Mesh2Fem")
|
||||
obj.FemMesh = femmesh
|
||||
end_time = time.process_time()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Convert to FemMesh: {}\n".format(end_time - start_time)
|
||||
)
|
||||
return obj
|
||||
# end of mesh_2_femmesh
|
||||
|
||||
Reference in New Issue
Block a user