From 2f9e70af09ec9b66ba650e81727d79869b9cb288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sat, 14 Nov 2015 12:14:02 +0100 Subject: [PATCH] FEM Post: Command for creation of post pipeline from result --- src/Mod/Fem/App/FemPostPipeline.cpp | 167 ++++++++++++++++++ src/Mod/Fem/App/FemPostPipeline.h | 4 + src/Mod/Fem/Gui/Command.cpp | 48 +++++ src/Mod/Fem/Gui/Command.cpp.orig | 143 ++++++++++++--- src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp | 26 ++- src/Mod/Fem/Gui/ViewProviderFemPostObject.h | 5 +- src/Mod/Fem/Gui/Workbench.cpp | 1 + 7 files changed, 358 insertions(+), 36 deletions(-) diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp index dc5c2ff8c..88a36f91c 100644 --- a/src/Mod/Fem/App/FemPostPipeline.cpp +++ b/src/Mod/Fem/App/FemPostPipeline.cpp @@ -27,8 +27,11 @@ #endif #include "FemPostPipeline.h" +#include "FemMesh.h" +#include "FemMeshObject.h" #include #include +#include #include #include #include @@ -36,6 +39,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include using namespace Fem; using namespace App; @@ -174,3 +184,160 @@ FemPostObject* FemPostPipeline::getLastPostObject() { return static_cast(Filter.getValues().back()); } + + +void FemPostPipeline::load(FemResultObject* res) { + + vtkSmartPointer grid = vtkUnstructuredGrid::New(); + source = grid; + + //first copy the mesh over + //######################## + + if(!res->Mesh.getValue() || !res->Mesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) + return; + + const FemMesh& mesh = static_cast(res->Mesh.getValue())->FemMesh.getValue(); + SMESH_Mesh* smesh = const_cast(mesh.getSMesh()); + SMESHDS_Mesh* meshDS = smesh->GetMeshDS(); + const SMDS_MeshInfo& info = meshDS->GetMeshInfo(); + + //start with the nodes + vtkSmartPointer points = vtkPoints::New(); + SMDS_NodeIteratorPtr aNodeIter = meshDS->nodesIterator(); + + points->SetNumberOfPoints(info.NbNodes()); + for(; aNodeIter->more(); ) { + const SMDS_MeshNode* node = aNodeIter->next(); + float coords[3] = {float(node->X()), float(node->Y()), float(node->Z())}; + points->SetPoint(node->GetID()-1, coords); + } + grid->SetPoints(points); + + //start with 2d elements + vtkSmartPointer triangleArray = vtkSmartPointer::New(); + vtkSmartPointer quadTriangleArray = vtkSmartPointer::New(); + vtkSmartPointer quadArray = vtkSmartPointer::New(); + + SMDS_FaceIteratorPtr aFaceIter = meshDS->facesIterator(); + for (;aFaceIter->more();) { + const SMDS_MeshFace* aFace = aFaceIter->next(); + + //triangle + if(aFace->NbNodes() == 3) { + vtkSmartPointer tria = vtkTriangle::New(); + tria->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID()-1); + tria->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID()-1); + tria->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID()-1); + + triangleArray->InsertNextCell(tria); + } + //quad + else if(aFace->NbNodes() == 4) { + vtkSmartPointer quad = vtkQuad::New(); + quad->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID()-1); + quad->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID()-1); + quad->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID()-1); + + quadArray->InsertNextCell(quad); + } + else if (aFace->NbNodes() == 6) { + vtkSmartPointer tria = vtkQuadraticTriangle::New(); + tria->GetPointIds()->SetId(0, aFace->GetNode(0)->GetID()-1); + tria->GetPointIds()->SetId(1, aFace->GetNode(1)->GetID()-1); + tria->GetPointIds()->SetId(2, aFace->GetNode(2)->GetID()-1); + tria->GetPointIds()->SetId(3, aFace->GetNode(3)->GetID()-1); + tria->GetPointIds()->SetId(4, aFace->GetNode(4)->GetID()-1); + tria->GetPointIds()->SetId(5, aFace->GetNode(5)->GetID()-1); + quadTriangleArray->InsertNextCell(tria); + } + } + if(triangleArray->GetNumberOfCells()>0) + grid->SetCells(VTK_TRIANGLE, triangleArray); + + if(quadArray->GetNumberOfCells()>0) + grid->SetCells(VTK_QUAD, quadArray); + + if(quadTriangleArray->GetNumberOfCells()>0) + grid->SetCells(VTK_QUADRATIC_TRIANGLE, quadTriangleArray); + + + //now all volumes + vtkSmartPointer tetraArray = vtkSmartPointer::New(); + vtkSmartPointer quadTetraArray = vtkSmartPointer::New(); + + tetraArray->SetNumberOfCells(info.NbTetras()); + SMDS_VolumeIteratorPtr aVolIter = meshDS->volumesIterator(); + for (;aVolIter->more();) { + const SMDS_MeshVolume* aVol = aVolIter->next(); + + //tetrahedra + if(aVol->NbNodes() == 4) { + vtkSmartPointer tetra = vtkTetra::New(); + tetra->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID()-1); + tetra->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID()-1); + tetra->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID()-1); + tetra->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID()-1); + + tetraArray->InsertNextCell(tetra); + } + //quadratic tetrahedra + else if( aVol->NbNodes() == 10) { + + vtkSmartPointer tetra = vtkQuadraticTetra::New(); + tetra->GetPointIds()->SetId(0, aVol->GetNode(0)->GetID()-1); + tetra->GetPointIds()->SetId(1, aVol->GetNode(1)->GetID()-1); + tetra->GetPointIds()->SetId(2, aVol->GetNode(2)->GetID()-1); + tetra->GetPointIds()->SetId(3, aVol->GetNode(3)->GetID()-1); + tetra->GetPointIds()->SetId(4, aVol->GetNode(4)->GetID()-1); + tetra->GetPointIds()->SetId(5, aVol->GetNode(5)->GetID()-1); + tetra->GetPointIds()->SetId(6, aVol->GetNode(6)->GetID()-1); + tetra->GetPointIds()->SetId(7, aVol->GetNode(7)->GetID()-1); + tetra->GetPointIds()->SetId(8, aVol->GetNode(8)->GetID()-1); + tetra->GetPointIds()->SetId(9, aVol->GetNode(9)->GetID()-1); + + quadTetraArray->InsertNextCell(tetra); + } + } + if(tetraArray->GetNumberOfCells()>0) + grid->SetCells(VTK_TETRA, tetraArray); + + if(quadTetraArray->GetNumberOfCells()>0) + grid->SetCells(VTK_QUADRATIC_TETRA, quadTetraArray); + + + //Now copy the point data over + //############################ + + if(!res->StressValues.getValues().empty()) { + const std::vector& vec = res->StressValues.getValues(); + vtkSmartPointer data = vtkDoubleArray::New(); + data->SetNumberOfValues(vec.size()); + data->SetName("Stress"); + + for(size_t i=0; iSetValue(i, vec[i]); + + grid->GetPointData()->AddArray(data); + } + + if(!res->StressValues.getValues().empty()) { + const std::vector& vec = res->DisplacementVectors.getValues(); + vtkSmartPointer data = vtkDoubleArray::New(); + data->SetNumberOfComponents(3); + data->SetName("Displacement"); + + for(std::vector::const_iterator it=vec.begin(); it!=vec.end(); ++it) { + double tuple[] = {it->x, it->y, it->z}; + Base::Console().Message("disp mag; %f\n", it->Length()); + data->InsertNextTuple(tuple); + } + + grid->GetPointData()->AddArray(data); + } + + + polyDataSource = vtkGeometryFilter::New(); + polyDataSource->SetInputData(source); + polyDataSource->Update(); +} diff --git a/src/Mod/Fem/App/FemPostPipeline.h b/src/Mod/Fem/App/FemPostPipeline.h index c3ad8ca52..2d561ea7c 100644 --- a/src/Mod/Fem/App/FemPostPipeline.h +++ b/src/Mod/Fem/App/FemPostPipeline.h @@ -27,6 +27,7 @@ #include "FemPostObject.h" #include "FemPostFilter.h" #include "FemPostFunction.h" +#include "FemResultObject.h" #include #include @@ -59,6 +60,9 @@ public: static bool canRead(Base::FileInfo file); void read(Base::FileInfo file); + //load from results + void load(FemResultObject* res); + //Pipeline handling vtkSmartPointer getSource() {return source;}; FemPostObject* getLastPostObject(); diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 9a53ad21c..0849c422c 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -1023,6 +1023,53 @@ Gui::Action * CmdFemPostApllyChanges::createAction(void) #endif + + +DEF_STD_CMD_A(CmdFemPostPipelineFromResult); + +CmdFemPostPipelineFromResult::CmdFemPostPipelineFromResult() + : Command("Fem_PostPipelineFromResult") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Creates a post processing pipeline from a result object"); + sToolTipText = QT_TR_NOOP("Creates a post processing pipeline from a result object"); + sWhatsThis = "Fem_PostPipelineFromResult"; + sStatusTip = sToolTipText; + sPixmap = "fem-fem-mesh-create-node-by-poly"; +} + +void CmdFemPostPipelineFromResult::activated(int iMsg) +{ + Gui::SelectionFilter ResultFilter("SELECT Fem::FemResultObject COUNT 1"); + + if (ResultFilter.match()) { + + Fem::FemResultObject* result = static_cast(ResultFilter.Result[0][0].getObject()); + std::string FeatName = getUniqueObjectName("Pipeline"); + + openCommand("Create pipeline from result"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostPipeline','%s')",FeatName.c_str()); + + //TODO: use python function call for this + static_cast(getDocument()->getObject(FeatName.c_str()))->load(result); + + this->updateActive(); + + } + else { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("CmdFemPostCreateClipFilter", "Wrong selection"), + qApp->translate("CmdFemPostCreateClipFilter", "Select a result, please.")); + } +} + +bool CmdFemPostPipelineFromResult::isActive(void) +{ + return hasActiveDocument(); +} + + //-------------------------------------------------------------------------------------- @@ -1047,5 +1094,6 @@ void CreateFemCommands(void) rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter); rcCmdMgr.addCommand(new CmdFemPostFunctions); rcCmdMgr.addCommand(new CmdFemPostApllyChanges); + rcCmdMgr.addCommand(new CmdFemPostPipelineFromResult); #endif } diff --git a/src/Mod/Fem/Gui/Command.cpp.orig b/src/Mod/Fem/Gui/Command.cpp.orig index ee2618df2..d5061363b 100644 --- a/src/Mod/Fem/Gui/Command.cpp.orig +++ b/src/Mod/Fem/Gui/Command.cpp.orig @@ -1,4 +1,4 @@ -<<<<<<< 387862dfe753cf0cb062032e97840353b14dcbae +<<<<<<< 146d87b88ef2e7376f2633828c2341a44c146220 /*************************************************************************** * Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de) * * * @@ -776,8 +776,8 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter() { sAppModule = "Fem"; sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Define/create a clip filter for a post processing pipeline..."); - sToolTipText = QT_TR_NOOP("Define/create a clip filter for a post processing pipeline..."); + sMenuText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region"); + sToolTipText = QT_TR_NOOP("Define/create a clip filter which uses functions to define the cliped region"); sWhatsThis = "Fem_PostCreateClipFilter"; sStatusTip = sToolTipText; sPixmap = "fem-fem-mesh-create-node-by-poly"; @@ -785,10 +785,9 @@ CmdFemPostCreateClipFilter::CmdFemPostCreateClipFilter() void CmdFemPostCreateClipFilter::activated(int iMsg) { - Gui::SelectionFilter ObjectFilter("SELECT Fem::FemPostPipeline COUNT 1"); - - if (ObjectFilter.match()) { - Fem::FemPostPipeline *pipeline = static_cast(ObjectFilter.Result[0][0].getObject()); + std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); + if (!pipelines.empty()) { + Fem::FemPostPipeline *pipeline = pipelines.front(); std::string FeatName = getUniqueObjectName("Clip"); @@ -800,6 +799,8 @@ void CmdFemPostCreateClipFilter::activated(int iMsg) doCommand(Doc,"del __list__"); this->updateActive(); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } else { QMessageBox::warning(Gui::getMainWindow(), @@ -813,6 +814,50 @@ bool CmdFemPostCreateClipFilter::isActive(void) return hasActiveDocument(); } +DEF_STD_CMD_A(CmdFemPostCreateScalarClipFilter); + +CmdFemPostCreateScalarClipFilter::CmdFemPostCreateScalarClipFilter() + : Command("Fem_PostCreateScalarClipFilter") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value"); + sToolTipText = QT_TR_NOOP("Define/create a clip filter which clips a field with a scalar value"); + sWhatsThis = "Fem_PostCreateScalarClipFilter"; + sStatusTip = sToolTipText; + sPixmap = "fem-fem-mesh-create-node-by-poly"; +} + +void CmdFemPostCreateScalarClipFilter::activated(int iMsg) +{ + std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); + if (!pipelines.empty()) { + Fem::FemPostPipeline *pipeline = pipelines.front(); + + std::string FeatName = getUniqueObjectName("ScalarClip"); + + openCommand("Create scalar clip filter"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostScalarClipFilter','%s')",FeatName.c_str()); + doCommand(Doc,"__list__ = App.ActiveDocument.%s.Filter", pipeline->getNameInDocument()); + doCommand(Doc,"__list__.append(App.ActiveDocument.%s)", FeatName.c_str()); + doCommand(Doc,"App.ActiveDocument.%s.Filter = __list__", pipeline->getNameInDocument()); + doCommand(Doc,"del __list__"); + + this->updateActive(); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); + } + else { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("CmdFemPostCreateScalarClipFilter", "Wrong selection"), + qApp->translate("CmdFemPostCreateScalarClipFilter", "Select a pipeline, please.")); + } +} + +bool CmdFemPostCreateScalarClipFilter::isActive(void) +{ + return hasActiveDocument(); +} + // ##################################################################################################### @@ -827,31 +872,30 @@ CmdFemPostFunctions::CmdFemPostFunctions() sToolTipText = QT_TR_NOOP("Functions for use in postprocessing filter..."); sWhatsThis = "Fem_PostCreateFunctions"; sStatusTip = sToolTipText; + eType = eType|ForEdit; } void CmdFemPostFunctions::activated(int iMsg) { - Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager(); + std::string name; if (iMsg==0) name = "Plane"; else if (iMsg==1) - rcCmdMgr.runCommandByName("Part_JoinEmbed"); - else if (iMsg==2) - rcCmdMgr.runCommandByName("Part_JoinCutout"); + name = "Sphere"; else return; //create the object - Gui::SelectionFilter ObjectFilter("SELECT Fem::FemPostPipeline COUNT 1"); - if (ObjectFilter.match()) { - Fem::FemPostPipeline *pipeline = static_cast(ObjectFilter.Result[0][0].getObject()); + std::vector pipelines = App::GetApplication().getActiveDocument()->getObjectsOfType(); + if (!pipelines.empty()) { + Fem::FemPostPipeline *pipeline = pipelines.front(); openCommand("Create function"); //check if the pipeline has a filter provider and add one if needed Fem::FemPostFunctionProvider* provider; - if(!pipeline->Function.getValue() || pipeline->Function.getValue()->getTypeId() == Fem::FemPostFunctionProvider::getClassTypeId()) { + if(!pipeline->Function.getValue() || pipeline->Function.getValue()->getTypeId() != Fem::FemPostFunctionProvider::getClassTypeId()) { std::string FuncName = getUniqueObjectName("Functions"); doCommand(Doc,"App.ActiveDocument.addObject('Fem::FemPostFunctionProvider','%s')", FuncName.c_str()); doCommand(Doc,"App.ActiveDocument.%s.Function = App.ActiveDocument.%s", pipeline->getNameInDocument(), FuncName.c_str()); @@ -869,6 +913,7 @@ void CmdFemPostFunctions::activated(int iMsg) doCommand(Doc,"del __list__"); this->updateActive(); + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); } else { QMessageBox::warning(Gui::getMainWindow(), @@ -892,7 +937,7 @@ Gui::Action * CmdFemPostFunctions::createAction(void) applyCommandData(this->className(), pcAction); QAction* cmd0 = pcAction->addAction(QString()); - //cmd0->setIcon(Gui::BitmapFactory().pixmap("Part_JoinConnect")); + pcAction->addAction(QString()); _pcAction = pcAction; languageChange(); @@ -913,10 +958,15 @@ void CmdFemPostFunctions::languageChange() Gui::ActionGroup* pcAction = qobject_cast(_pcAction); QList a = pcAction->actions(); - QAction* cmd0 = a[0]; - cmd0->setText(QApplication::translate("CmdFemPostFunctions","Plane")); - cmd0->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a plane function, defined by its orgin and normal")); - cmd0->setStatusTip(cmd0->toolTip()); + QAction* cmd = a[0]; + cmd->setText(QApplication::translate("CmdFemPostFunctions","Plane")); + cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a plane function, defined by its orgin and normal")); + cmd->setStatusTip(cmd->toolTip()); + + cmd = a[1]; + cmd->setText(QApplication::translate("CmdFemPostFunctions","Sphere")); + cmd->setToolTip(QApplication::translate("Fem_PostCreateFunctions","Create a phere function, defined by its center and radius")); + cmd->setStatusTip(cmd->toolTip()); } @@ -928,6 +978,7 @@ bool CmdFemPostFunctions::isActive(void) return false; } + DEF_STD_CMD_AC(CmdFemPostApllyChanges); CmdFemPostApllyChanges::CmdFemPostApllyChanges() @@ -940,6 +991,7 @@ CmdFemPostApllyChanges::CmdFemPostApllyChanges() sWhatsThis = "Fem_PostApplyChanges"; sStatusTip = sToolTipText; sPixmap = "view-refresh"; + eType = eType|ForEdit; } void CmdFemPostApllyChanges::activated(int iMsg) @@ -993,6 +1045,7 @@ void CreateFemCommands(void) #ifdef FC_USE_VTK rcCmdMgr.addCommand(new CmdFemPostCreateClipFilter); + rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter); rcCmdMgr.addCommand(new CmdFemPostFunctions); rcCmdMgr.addCommand(new CmdFemPostApllyChanges); #endif @@ -2023,6 +2076,53 @@ Gui::Action * CmdFemPostApllyChanges::createAction(void) #endif + + +DEF_STD_CMD_A(CmdFemPostPipelineFromResult); + +CmdFemPostPipelineFromResult::CmdFemPostPipelineFromResult() + : Command("Fem_PostPipelineFromResult") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Creates a post processing pipeline from a result object"); + sToolTipText = QT_TR_NOOP("Creates a post processing pipeline from a result object"); + sWhatsThis = "Fem_PostPipelineFromResult"; + sStatusTip = sToolTipText; + sPixmap = "fem-fem-mesh-create-node-by-poly"; +} + +void CmdFemPostPipelineFromResult::activated(int iMsg) +{ + Gui::SelectionFilter ResultFilter("SELECT Fem::FemResultObject COUNT 1"); + + if (ResultFilter.match()) { + + Fem::FemResultObject* result = static_cast(ResultFilter.Result[0][0].getObject()); + std::string FeatName = getUniqueObjectName("Pipeline"); + + openCommand("Create pipeline from result"); + doCommand(Doc,"App.activeDocument().addObject('Fem::FemPostPipeline','%s')",FeatName.c_str()); + + //TODO: use python function call for this + static_cast(getDocument()->getObject(FeatName.c_str()))->load(result); + + this->updateActive(); + + } + else { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate("CmdFemPostCreateClipFilter", "Wrong selection"), + qApp->translate("CmdFemPostCreateClipFilter", "Select a result, please.")); + } +} + +bool CmdFemPostPipelineFromResult::isActive(void) +{ + return hasActiveDocument(); +} + + //-------------------------------------------------------------------------------------- @@ -2047,6 +2147,7 @@ void CreateFemCommands(void) rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter); rcCmdMgr.addCommand(new CmdFemPostFunctions); rcCmdMgr.addCommand(new CmdFemPostApllyChanges); + rcCmdMgr.addCommand(new CmdFemPostPipelineFromResult); #endif } ->>>>>>> Detail filter infrastructure +>>>>>>> Command for creation of post pipeline from result diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp index a258f7790..7ea4e1576 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp @@ -25,7 +25,7 @@ #ifndef _PreComp_ #include -#include +#include #include #include #include @@ -85,7 +85,7 @@ ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges( m_faces->ref(); m_triangleStrips = new SoIndexedTriangleStripSet(); m_triangleStrips->ref(); - m_markers = new SoIndexedMarkerSet(); + m_markers = new SoIndexedPointSet(); m_markers->ref(); m_lines = new SoIndexedLineSet(); m_lines->ref(); @@ -155,8 +155,8 @@ void ViewProviderFemPostObject::setDisplayMode(const char* ModeName) m_currentAlgorithm = static_cast(getObject())->getPolyAlgorithm(); else if (strcmp("Wireframe",ModeName)==0) m_currentAlgorithm = m_wireframe; - /*else if (strcmp("Nodes",ModeName)==0) - setDisplayMaskMode("Nodes");*/ + else if (strcmp("Nodes",ModeName)==0) + m_currentAlgorithm = m_points; update(); @@ -167,7 +167,7 @@ std::vector ViewProviderFemPostObject::getDisplayModes(void) const { std::vector StrList; StrList.push_back("Outline"); - // StrList.push_back("Points"); + StrList.push_back("Nodes"); StrList.push_back("Surface"); StrList.push_back("Surface with Edges"); StrList.push_back("Wireframe"); @@ -344,22 +344,17 @@ void ViewProviderFemPostObject::update3D() { m_lines->coordIndex.setNum(0); // write out verts if any - // (more complex because there is no IndexedPointSet) if (pd->GetNumberOfVerts() > 0){ - Base::Console().Message("render verts\n"); + Base::Console().Message("render verts: %i\n", pd->GetNumberOfVerts()); int soidx = 0; cells = pd->GetVerts(); m_markers->coordIndex.startEditing(); + m_markers->coordIndex.setNum(pd->GetNumberOfVerts()); for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { - for (int i = 0; i < npts; i++) { - m_markers->coordIndex.set1Value(soidx, static_cast(indx[i])); - ++soidx; - } - m_markers->coordIndex.set1Value(soidx, -1); - ++soidx; + m_markers->coordIndex.set1Value(soidx, static_cast(indx[0])); + ++soidx; } - m_markers->coordIndex.setNum(soidx); m_markers->coordIndex.finishEditing(); } else @@ -487,6 +482,9 @@ bool ViewProviderFemPostObject::setupPipeline() { m_outline = vtkOutlineCornerFilter::New(); m_outline->SetInputConnection(algorithm->GetOutputPort()); + m_points = vtkVertexGlyphFilter::New(); + m_points->SetInputConnection(algorithm->GetOutputPort()); + m_surface = vtkGeometryFilter::New(); m_surface->SetInputConnection(algorithm->GetOutputPort()); diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h index 938878708..5883a96c2 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h @@ -35,7 +35,9 @@ #include #include #include +#include +class SoIndexedPointSet; class vtkUnsignedCharArray; class vtkDataArray; class vtkPoints; @@ -107,7 +109,7 @@ protected: void update(); SoCoordinate3* m_coordinates; - SoIndexedMarkerSet* m_markers; + SoIndexedPointSet* m_markers; SoIndexedLineSet* m_lines; SoIndexedFaceSet* m_faces; SoIndexedTriangleStripSet* m_triangleStrips; @@ -124,6 +126,7 @@ protected: vtkSmartPointer m_surfaceEdges; vtkSmartPointer m_outline; vtkSmartPointer m_wireframe; + vtkSmartPointer m_points; vtkSmartPointer m_lookup; private: diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp index 81f10435d..626c3b15c 100755 --- a/src/Mod/Fem/Gui/Workbench.cpp +++ b/src/Mod/Fem/Gui/Workbench.cpp @@ -83,6 +83,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const Gui::ToolBarItem* post = new Gui::ToolBarItem(root); post->setCommand("Post Processing"); *post << "Fem_PostApplyChanges" + << "Fem_PostPipelineFromResult" << "Separator" << "Fem_PostCreateClipFilter" << "Fem_PostCreateScalarClipFilter"