From 4caa464ebb8993b4833e4308c3929053278d7f2d Mon Sep 17 00:00:00 2001 From: Przemo Firszt Date: Mon, 15 Jun 2015 14:35:56 +0100 Subject: [PATCH] FEM: All FEM results are stored in a single object Functionality previously provided by setNodeColorByResult is now in setNodeColorByScalars. FemResult* object is no longer required, the function accepts list of elements and a list of values. Functionality previously provided by setNodeDisplacementByResult is now in setNodeDisplacementByVectors. FemResult* object is no longer required, the function accepts list of elements and a list of vectors. A side effect: FemResultValues and FemResultVector are no longer used and have bee removed. Signed-off-by: Przemo Firszt --- src/Mod/Fem/App/AppFem.cpp | 8 +- src/Mod/Fem/App/CMakeLists.txt | 4 - src/Mod/Fem/App/FemResultObject.cpp | 14 +- src/Mod/Fem/App/FemResultObject.h | 17 +- src/Mod/Fem/App/FemResultValue.cpp | 74 -------- src/Mod/Fem/App/FemResultValue.h | 66 -------- src/Mod/Fem/App/FemResultVector.cpp | 74 -------- src/Mod/Fem/App/FemResultVector.h | 64 ------- src/Mod/Fem/Gui/ViewProviderFemMeshPy.xml | 6 +- src/Mod/Fem/Gui/ViewProviderFemMeshPyImp.cpp | 169 +++++++------------ src/Mod/Fem/MechanicalAnalysis.py | 72 +++----- src/Mod/Fem/ccxFrdReader.py | 37 ++-- 12 files changed, 125 insertions(+), 480 deletions(-) delete mode 100644 src/Mod/Fem/App/FemResultValue.cpp delete mode 100644 src/Mod/Fem/App/FemResultValue.h delete mode 100644 src/Mod/Fem/App/FemResultVector.cpp delete mode 100644 src/Mod/Fem/App/FemResultVector.h diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index 5f6d0aa17..24a770871 100755 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -52,8 +52,6 @@ #include "FemConstraintPulley.h" #include "FemResultObject.h" -#include "FemResultValue.h" -#include "FemResultVector.h" extern struct PyMethodDef Fem_methods[]; @@ -141,11 +139,7 @@ void AppFemExport initFem() Fem::ConstraintPulley ::init(); Fem::FemResultObject ::init(); - Fem::FemResultPython ::init(); - Fem::FemResultValue ::init(); - Fem::FemResultValuePython ::init(); - Fem::FemResultVector ::init(); - Fem::FemResultVectorPython ::init(); + Fem::FemResultObjectPython ::init(); } } // extern "C" diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index e0efcf21e..685e8ed29 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -131,10 +131,6 @@ SET(FemConstraints_SRCS SOURCE_GROUP("Constraints" FILES ${FemConstraints_SRCS}) SET(FemResult_SRCS - FemResultValue.cpp - FemResultValue.h - FemResultVector.cpp - FemResultVector.h ) SOURCE_GROUP("ResultObjects" FILES ${FemResult_SRCS}) diff --git a/src/Mod/Fem/App/FemResultObject.cpp b/src/Mod/Fem/App/FemResultObject.cpp index 3c15af597..7b0a8bc63 100644 --- a/src/Mod/Fem/App/FemResultObject.cpp +++ b/src/Mod/Fem/App/FemResultObject.cpp @@ -37,10 +37,12 @@ PROPERTY_SOURCE(Fem::FemResultObject, App::DocumentObject) FemResultObject::FemResultObject() { - ADD_PROPERTY_TYPE(DataType,(""), "General",Prop_None,"Type identifier of the result data"); - ADD_PROPERTY_TYPE(Unit,(0), "General",Prop_None,"Unit of the data"); ADD_PROPERTY_TYPE(ElementNumbers,(0), "Data",Prop_None,"Numbers of the result elements"); - ADD_PROPERTY_TYPE(Mesh,(0), "General",Prop_None,"Link to the corosbonding mesh"); + ADD_PROPERTY_TYPE(Stats,(0), "Fem",Prop_None,"Statistics of the results"); + ADD_PROPERTY_TYPE(DisplacementVectors,(), "Fem",Prop_None,"List of displacement vectors"); + ADD_PROPERTY_TYPE(DisplacementLengths,(0), "Fem",Prop_None,"List of displacement lengths"); + ADD_PROPERTY_TYPE(StressValues,(0), "Fem",Prop_None,"List of Von Misses strass values"); + ADD_PROPERTY_TYPE(Mesh,(0), "General",Prop_None,"Link to the corrresponding mesh"); } FemResultObject::~FemResultObject() @@ -65,8 +67,8 @@ PyObject *FemResultObject::getPyObject() namespace App { /// @cond DOXERR -PROPERTY_SOURCE_TEMPLATE(Fem::FemResultPython, Fem::FemResultObject) -template<> const char* Fem::FemResultPython::getViewProviderName(void) const { +PROPERTY_SOURCE_TEMPLATE(Fem::FemResultObjectPython, Fem::FemResultObject) +template<> const char* Fem::FemResultObjectPython::getViewProviderName(void) const { return "FemGui::ViewProviderFemResultPython"; } /// @endcond @@ -74,4 +76,4 @@ template<> const char* Fem::FemResultPython::getViewProviderName(void) const { // explicit template instantiation template class AppFemExport FeaturePythonT; -} \ No newline at end of file +} diff --git a/src/Mod/Fem/App/FemResultObject.h b/src/Mod/Fem/App/FemResultObject.h index 2dd5ec4de..0f958a3df 100644 --- a/src/Mod/Fem/App/FemResultObject.h +++ b/src/Mod/Fem/App/FemResultObject.h @@ -42,14 +42,17 @@ public: FemResultObject(void); virtual ~FemResultObject(); - /// Data type specifier of the data stored in this object - App::PropertyString DataType; - /// Unit and factor of the values - App::PropertyQuantity Unit; - /// List of element numbers in this result object App::PropertyIntegerList ElementNumbers; - /// Link to the corosbonding mesh + /// Link to the corresponding mesh App::PropertyLink Mesh; + /// Stats of analysis + App::PropertyFloatList Stats; + /// Displacement vectors of analysis + App::PropertyVectorList DisplacementVectors; + /// Lengths of displacement vestors of analysis + App::PropertyFloatList DisplacementLengths; + /// Von Mises Stress values of analysis + App::PropertyFloatList StressValues; /// returns the type name of the ViewProvider virtual const char* getViewProviderName(void) const { @@ -64,7 +67,7 @@ public: }; -typedef App::FeaturePythonT FemResultPython; +typedef App::FeaturePythonT FemResultObjectPython; } //namespace Fem diff --git a/src/Mod/Fem/App/FemResultValue.cpp b/src/Mod/Fem/App/FemResultValue.cpp deleted file mode 100644 index 24d4a598b..000000000 --- a/src/Mod/Fem/App/FemResultValue.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * 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_ -#endif - -#include "FemResultValue.h" -#include - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemResultValue, Fem::FemResultObject) - - -FemResultValue::FemResultValue() -{ - ADD_PROPERTY_TYPE(Values,(0), "Fem",Prop_None,"List of values"); -} - -FemResultValue::~FemResultValue() -{ -} - -short FemResultValue::mustExecute(void) const -{ - return 0; -} - -PyObject *FemResultValue::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); -} - -// Python feature --------------------------------------------------------- - -namespace App { -/// @cond DOXERR -PROPERTY_SOURCE_TEMPLATE(Fem::FemResultValuePython, Fem::FemResultValue) -template<> const char* Fem::FemResultValuePython::getViewProviderName(void) const { - return "FemGui::ViewProviderResultPython"; -} -/// @endcond - -// explicit template instantiation -template class AppFemExport FeaturePythonT; - -} \ No newline at end of file diff --git a/src/Mod/Fem/App/FemResultValue.h b/src/Mod/Fem/App/FemResultValue.h deleted file mode 100644 index 31f6c8bf4..000000000 --- a/src/Mod/Fem/App/FemResultValue.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************** - * 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_FemResultValue_H -#define Fem_FemResultValue_H - - -#include -#include - -#include "FemResultObject.h" - -namespace Fem -{ -/// Father of all result data in a Fem Analysis -class AppFemExport FemResultValue : public Fem::FemResultObject -{ - PROPERTY_HEADER(Fem::FemResultValue); - -public: - /// Constructor - FemResultValue(void); - virtual ~FemResultValue(); - - /// List of values - App::PropertyFloatList Values; - - /// returns the type name of the ViewProvider - //virtual const char* getViewProviderName(void) const { - // return "FemGui::ViewProviderFemSet"; - //} - virtual App::DocumentObjectExecReturn *execute(void) { - return App::DocumentObject::StdReturn; - } - virtual short mustExecute(void) const; - virtual PyObject *getPyObject(void); - - -}; - -typedef App::FeaturePythonT FemResultValuePython; - -} //namespace Fem - - -#endif // Fem_FemResultValue_H diff --git a/src/Mod/Fem/App/FemResultVector.cpp b/src/Mod/Fem/App/FemResultVector.cpp deleted file mode 100644 index 680aa0172..000000000 --- a/src/Mod/Fem/App/FemResultVector.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/*************************************************************************** - * 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_ -#endif - -#include "FemResultVector.h" -#include - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemResultVector, Fem::FemResultObject) - - -FemResultVector::FemResultVector() -{ - ADD_PROPERTY_TYPE(Values,(), "Fem",Prop_None,"Vector values"); -} - -FemResultVector::~FemResultVector() -{ -} - -short FemResultVector::mustExecute(void) const -{ - return 0; -} - -PyObject *FemResultVector::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); -} - -// Python feature --------------------------------------------------------- - -namespace App { -/// @cond DOXERR -PROPERTY_SOURCE_TEMPLATE(Fem::FemResultVectorPython, Fem::FemResultVector) -template<> const char* Fem::FemResultVectorPython::getViewProviderName(void) const { - return "FemGui::ViewProviderResultPython"; -} -/// @endcond - -// explicit template instantiation -template class AppFemExport FeaturePythonT; - -} \ No newline at end of file diff --git a/src/Mod/Fem/App/FemResultVector.h b/src/Mod/Fem/App/FemResultVector.h deleted file mode 100644 index 8b050b705..000000000 --- a/src/Mod/Fem/App/FemResultVector.h +++ /dev/null @@ -1,64 +0,0 @@ -/*************************************************************************** - * 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_FemResultVector_H -#define Fem_FemResultVector_H - -#include -#include -#include "FemResultObject.h" - -namespace Fem -{ -/// Father of all result data in a Fem Analysis -class AppFemExport FemResultVector : public Fem::FemResultObject -{ - PROPERTY_HEADER(Fem::FemResultVector); - -public: - /// Constructor - FemResultVector(void); - virtual ~FemResultVector(); - - /// Data type specifier of the data stored in this object - App::PropertyVectorList Values; - - /// returns the type name of the ViewProvider - //virtual const char* getViewProviderName(void) const { - // return "FemGui::ViewProviderFemSet"; - //} - virtual App::DocumentObjectExecReturn *execute(void) { - return App::DocumentObject::StdReturn; - } - virtual short mustExecute(void) const; - virtual PyObject *getPyObject(void); - - -}; - -typedef App::FeaturePythonT FemResultVectorPython; - -} //namespace Fem - - -#endif // Fem_FemResultVector_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemMeshPy.xml b/src/Mod/Fem/Gui/ViewProviderFemMeshPy.xml index 20849b705..ee25591ae 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMeshPy.xml +++ b/src/Mod/Fem/Gui/ViewProviderFemMeshPy.xml @@ -20,12 +20,12 @@ - + - + Sets mesh node colors using element list and value list. - + diff --git a/src/Mod/Fem/Gui/ViewProviderFemMeshPyImp.cpp b/src/Mod/Fem/Gui/ViewProviderFemMeshPyImp.cpp index 55c1a7b85..698dcfbeb 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemMeshPyImp.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemMeshPyImp.cpp @@ -7,8 +7,7 @@ #include #include "Mod/Fem/Gui/ViewProviderFemMesh.h" -#include "Mod/Fem/App/FemResultVector.h" -#include "Mod/Fem/App/FemResultValue.h" +#include "Mod/Fem/App/FemResultObject.h" // inclusion of the generated files (generated out of ViewProviderFemMeshPy.xml) #include "ViewProviderFemMeshPy.h" @@ -58,122 +57,72 @@ App::Color calcColor(double value,double min, double max) } -PyObject* ViewProviderFemMeshPy::setNodeColorByResult(PyObject *args) +PyObject* ViewProviderFemMeshPy::setNodeColorByScalars(PyObject *args) { - // statistical values get collected and returned - double max = -1e12; + double max = -1e12; double min = +1e12; - double avg = 0; + PyObject *node_ids_py; + PyObject *values_py; - PyObject *object=0; - int type = 0; - if (PyArg_ParseTuple(args,"O!|i",&(App::DocumentObjectPy::Type), &object, &type)) { - App::DocumentObject* obj = static_cast(object)->getDocumentObjectPtr(); - if (obj && obj->getTypeId().isDerivedFrom(Fem::FemResultValue::getClassTypeId())){ - Fem::FemResultValue *result = static_cast(obj); - const std::vector & Ids = result->ElementNumbers.getValues() ; - const std::vector & Vals = result->Values.getValues() ; - std::vector NodeColors(Vals.size()); - for(std::vector::const_iterator it= Vals.begin();it!=Vals.end();++it){ - if(*it > max) - max = *it; - if(*it < min) - min = *it; - avg += *it; - } - avg /= Vals.size(); - - // fill up color vector - long i=0; - for(std::vector::const_iterator it= Vals.begin();it!=Vals.end();++it,i++) - NodeColors[i] = calcColor(*it,0.0,max); - - // set the color to the view-provider - this->getViewProviderFemMeshPtr()->setColorByNodeId(Ids,NodeColors); - - - }else if (obj && obj->getTypeId().isDerivedFrom(Fem::FemResultVector::getClassTypeId())){ - Fem::FemResultVector *result = static_cast(obj); - const std::vector & Ids = result->ElementNumbers.getValues() ; - const std::vector & Vecs = result->Values.getValues() ; - std::vector NodeColors(Vecs.size()); - - for(std::vector::const_iterator it= Vecs.begin();it!=Vecs.end();++it){ - double val; - if(type == 0) - val = it->Length(); - else if (type == 1) - val = it->x; - else if (type == 2) - val = it->y; - else if (type == 3) - val = it->z; - else - val = it->Length(); - - if(val > max) - max = val; - if(val < min) - min = val; - avg += val; - } - avg /= Vecs.size(); - - // fill up color vector - long i=0; - for(std::vector::const_iterator it= Vecs.begin();it!=Vecs.end();++it,i++) - if(type == 0) - NodeColors[i] = calcColor(it->Length(),0.0,max); - else if (type == 1) - NodeColors[i] = calcColor(it->x,min,max); - else if (type == 2) - NodeColors[i] = calcColor(it->y,min,max); - else if (type == 3) - NodeColors[i] = calcColor(it->z,min,max); - else - NodeColors[i] = calcColor(it->Length(),0.0,max); - - // set the color to the view-provider - this->getViewProviderFemMeshPtr()->setColorByNodeId(Ids,NodeColors); - - - }else{ - PyErr_SetString(Base::BaseExceptionFreeCADError, "Argument has to be a ResultValue or ResultVector!"); - return 0; + if (PyArg_ParseTuple(args,"O!O!",&PyList_Type, &node_ids_py, &PyList_Type, &values_py)) { + std::vector ids; + std::vector values; + int num_items = PyList_Size(node_ids_py); + if (num_items < 0) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "PyList_Size < 0. That is not a valid list!"); + Py_Return; } - } - - Py::Tuple res(3); - res[0] = Py::Float(min); - res[1] = Py::Float(max); - res[2] = Py::Float(avg); - - return Py::new_reference_to(res); - -} - -PyObject* ViewProviderFemMeshPy::setNodeDisplacementByResult(PyObject *args) -{ - PyObject *object=0; - if (PyArg_ParseTuple(args,"O!",&(App::DocumentObjectPy::Type), &object)) { - App::DocumentObject* obj = static_cast(object)->getDocumentObjectPtr(); - if (obj && obj->getTypeId().isDerivedFrom(Fem::FemResultVector::getClassTypeId())){ - Fem::FemResultVector *result = static_cast(obj); - const std::vector & Ids = result->ElementNumbers.getValues() ; - const std::vector & Vecs = result->Values.getValues() ; - // set the displacement to the view-provider - this->getViewProviderFemMeshPtr()->setDisplacementByNodeId(Ids,Vecs); - - - }else{ - PyErr_SetString(Base::BaseExceptionFreeCADError, "Argument has to be a ResultVector!"); - return 0; + std::vector node_colors(num_items); + for (int i=0; i max) + max = val; + if(val < min) + min = val; } + long i=0; + for(std::vector::const_iterator it=values.begin(); it!=values.end(); ++it, i++) + node_colors[i] = calcColor(*it, min, max); + this->getViewProviderFemMeshPtr()->setColorByNodeId(ids, node_colors); + } else { + PyErr_SetString(Base::BaseExceptionFreeCADError, "PyArg_ParseTuple failed. Invalid arguments used with setNodeByScalars"); } - Py_Return; - } + + +PyObject* ViewProviderFemMeshPy::setNodeDisplacementByVectors(PyObject *args) +{ + PyObject *node_ids_py; + PyObject *vectors_py; + if (PyArg_ParseTuple(args,"O!O!",&PyList_Type, &node_ids_py, &PyList_Type, &vectors_py)) { + std::vector ids; + std::vector vectors; + int num_items = PyList_Size(node_ids_py); + if (num_items < 0) { + PyErr_SetString(Base::BaseExceptionFreeCADError, "PyList_Size < 0. That is not a valid list!"); + Py_Return; + } + for (int i=0; i(vector_py); + vectors.push_back(vec); + } + this->getViewProviderFemMeshPtr()->setDisplacementByNodeId(ids, vectors); + } else { + PyErr_SetString(Base::BaseExceptionFreeCADError, "PyArg_ParseTuple failed. Invalid arguments used with setNodeDisplacementByVectors"); + } + Py_Return; +} + Py::Dict ViewProviderFemMeshPy::getNodeColor(void) const { //return Py::List(); diff --git a/src/Mod/Fem/MechanicalAnalysis.py b/src/Mod/Fem/MechanicalAnalysis.py index d9d791e54..1fcbc8d73 100644 --- a/src/Mod/Fem/MechanicalAnalysis.py +++ b/src/Mod/Fem/MechanicalAnalysis.py @@ -153,18 +153,12 @@ class _CommandMechanicalShowResult: 'ToolTip': QtCore.QT_TRANSLATE_NOOP("Fem_ResultDisplacement", "Show result information of an analysis")} def Activated(self): - DisplacementObject = None + self.result_object = None for i in FemGui.getActiveAnalysis().Member: - if i.isDerivedFrom("Fem::FemResultVector"): - if i.DataType == 'Displacement': - DisplacementObject = i - StressObject = None - for i in FemGui.getActiveAnalysis().Member: - if i.isDerivedFrom("Fem::FemResultValue"): - if i.DataType == 'VonMisesStress': - StressObject = i + if i.isDerivedFrom("Fem::FemResultObject"): + self.result_object = i - if not DisplacementObject and not StressObject: + if not self.result_object: QtGui.QMessageBox.critical(None, "Missing prerequisite", "No result found in active Analysis") return @@ -515,8 +509,6 @@ class _ResultControlTaskPanel: QtCore.QObject.connect(self.form.sb_displacement_factor, QtCore.SIGNAL("valueChanged(int)"), self.sb_disp_factor_changed) QtCore.QObject.connect(self.form.sb_displacement_factor_max, QtCore.SIGNAL("valueChanged(int)"), self.sb_disp_factor_max_changed) - self.DisplacementObject = None - self.StressObject = None self.update() self.restore_result_dialog() @@ -563,15 +555,14 @@ class _ResultControlTaskPanel: if analysis is None: analysis = FemGui.getActiveAnalysis() for i in analysis.Member: - if i.isDerivedFrom("Fem::FemResultValue"): - if i.DataType == 'AnalysisStats': - match_table = {"U1": (i.Values[0], i.Values[1], i.Values[2]), - "U2": (i.Values[3], i.Values[4], i.Values[5]), - "U3": (i.Values[6], i.Values[7], i.Values[8]), - "Uabs": (i.Values[9], i.Values[10], i.Values[11]), - "Sabs": (i.Values[12], i.Values[13], i.Values[14]), - "None": (0.0, 0.0, 0.0)} - return match_table[type_name] + if (i.isDerivedFrom("Fem::FemResultObject")) and ("Stats" in i.PropertiesList): + match_table = {"U1": (i.Stats[0], i.Stats[1], i.Stats[2]), + "U2": (i.Stats[3], i.Stats[4], i.Stats[5]), + "U3": (i.Stats[6], i.Stats[7], i.Stats[8]), + "Uabs": (i.Stats[9], i.Stats[10], i.Stats[11]), + "Sabs": (i.Stats[12], i.Stats[13], i.Stats[14]), + "None": (0.0, 0.0, 0.0)} + return match_table[type_name] return (0.0, 0.0, 0.0) def none_selected(self, state): @@ -598,20 +589,21 @@ class _ResultControlTaskPanel: def vm_stress_selected(self, state): FreeCAD.FEM_dialog["results_type"] = "Sabs" QApplication.setOverrideCursor(Qt.WaitCursor) - (minm, avg, maxm) = (0.0, 0.0, 0.0) - if self.StressObject: - self.MeshObject.ViewObject.setNodeColorByResult(self.StressObject) - (minm, avg, maxm) = self.get_result_stats("Sabs") + self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.StressValues) + (minm, avg, maxm) = self.get_result_stats("Sabs") self.set_result_stats("MPa", minm, avg, maxm) QtGui.qApp.restoreOverrideCursor() def select_displacement_type(self, disp_type): QApplication.setOverrideCursor(Qt.WaitCursor) - (minm, avg, maxm) = (0.0, 0.0, 0.0) - if self.DisplacementObject: - match = {"Uabs": 0, "U1": 1, "U2": 2, "U3": 3} - self.MeshObject.ViewObject.setNodeColorByResult(self.DisplacementObject, match[disp_type]) - (minm, avg, maxm) = self.get_result_stats(disp_type) + if disp_type == "Uabs": + self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, self.result_object.DisplacementLengths) + else: + match = {"U1": 0, "U2": 1, "U3": 2} + d = zip(*self.result_object.DisplacementVectors) + displacements = list(d[match[disp_type]]) + self.MeshObject.ViewObject.setNodeColorByScalars(self.result_object.ElementNumbers, displacements) + (minm, avg, maxm) = self.get_result_stats(disp_type) self.set_result_stats("mm", minm, avg, maxm) QtGui.qApp.restoreOverrideCursor() @@ -629,7 +621,7 @@ class _ResultControlTaskPanel: factor = 0.0 if checked: factor = self.form.hsb_displacement_factor.value() - self.MeshObject.ViewObject.setNodeDisplacementByResult(self.DisplacementObject) + self.MeshObject.ViewObject.setNodeDisplacementByVectors(self.result_object.ElementNumbers, self.result_object.DisplacementVectors) self.MeshObject.ViewObject.applyDisplacement(factor) QtGui.qApp.restoreOverrideCursor() @@ -650,12 +642,8 @@ class _ResultControlTaskPanel: for i in FemGui.getActiveAnalysis().Member: if i.isDerivedFrom("Fem::FemMeshObject"): self.MeshObject = i - elif i.isDerivedFrom("Fem::FemResultVector"): - if i.DataType == 'Displacement': - self.DisplacementObject = i - elif i.isDerivedFrom("Fem::FemResultValue"): - if i.DataType == 'VonMisesStress': - self.StressObject = i + elif i.isDerivedFrom('Fem::FemResultObject'): + self.result_object = i def accept(self): FreeCADGui.Control.closeDialog() @@ -670,9 +658,7 @@ def results_present(): results = False analysis_members = FemGui.getActiveAnalysis().Member for o in analysis_members: - if o.isDerivedFrom('Fem::FemResultVector'): - results = True - elif o.isDerivedFrom("Fem::FemResultValue") and o.DataType == 'VonMisesStress': + if o.isDerivedFrom('Fem::FemResultObject'): results = True return results @@ -683,9 +669,7 @@ def purge_fem_results(Analysis=None): else: analysis_members = FemGui.Analysis().Member for o in analysis_members: - if (o.isDerivedFrom('Fem::FemResultVector') or - (o.isDerivedFrom("Fem::FemResultValue") and o.DataType == 'VonMisesStress') or - (o.isDerivedFrom("Fem::FemResultValue") and o.DataType == 'AnalysisStats')): + if o.isDerivedFrom("Fem::FemResultObject"): FreeCAD.ActiveDocument.removeObject(o.Name) @@ -696,7 +680,7 @@ def reset_mesh_color(mesh=None): mesh = i mesh.ViewObject.NodeColor = {} mesh.ViewObject.ElementColor = {} - mesh.ViewObject.setNodeColorByResult() + mesh.ViewObject.setNodeColorByScalars() def reset_mesh_deformation(mesh=None): diff --git a/src/Mod/Fem/ccxFrdReader.py b/src/Mod/Fem/ccxFrdReader.py index 47e49524b..c79c9a80c 100644 --- a/src/Mod/Fem/ccxFrdReader.py +++ b/src/Mod/Fem/ccxFrdReader.py @@ -134,6 +134,7 @@ def importFrd(filename, Analysis=None): AnalysisObject.Label = AnalysisName else: AnalysisObject = Analysis + results = FreeCAD.ActiveDocument.addObject('Fem::FemResultObject', 'Results') if ('Tet10Elem' in m) and ('Nodes' in m) and (not Analysis): mesh = Fem.FemMesh() @@ -153,17 +154,13 @@ def importFrd(filename, Analysis=None): if 'Displacement' in m: disp = m['Displacement'] if len(disp) > 0: - o = FreeCAD.ActiveDocument.addObject('Fem::FemResultVector', 'Displacement') - o.Values = disp.values() - o.DataType = 'Displacement' - o.ElementNumbers = disp.keys() + results.DisplacementVectors = disp.values() + results.ElementNumbers = disp.keys() if(MeshObject): - o.Mesh = MeshObject - AnalysisObject.Member = AnalysisObject.Member + [o] + results.Mesh = MeshObject if 'Stress' in m: stress = m['Stress'] if len(stress) > 0: - o = FreeCAD.ActiveDocument.addObject('Fem::FemResultValue', 'MisesStress') for i in stress.values(): # Von mises stress (http://en.wikipedia.org/wiki/Von_Mises_yield_criterion) s11 = i[0] @@ -178,12 +175,12 @@ def importFrd(filename, Analysis=None): s12s23s31 = 6 * (pow(s12, 2) + pow(s23, 2) * pow(s31, 2)) mstress.append(sqrt(0.5 * (s11s22 + s22s33 + s33s11 + s12s23s31))) - o.Values = mstress - o.DataType = 'VonMisesStress' - o.ElementNumbers = stress.keys() + results.StressValues = mstress + if (results.ElementNumbers != 0 and results.ElementNumbers != stress.keys()): + print "Inconsistent FEM results: element number for Stress doesn't equal element number for Displacement" + results.ElementNumbers = stress.keys() if(MeshObject): - o.Mesh = MeshObject - AnalysisObject.Member = AnalysisObject.Member + [o] + results.Mesh = MeshObject l = len(displacement) x_max, y_max, z_max = map(max, zip(*displacement)) @@ -196,18 +193,16 @@ def importFrd(filename, Analysis=None): disp_abs = [] for d in displacement: disp_abs.append(sqrt(pow(d[0], 2) + pow(d[1], 2) + pow(d[2], 2))) + results.DisplacementLengths = disp_abs a_max = max(disp_abs) a_min = min(disp_abs) a_avg = sum(disp_abs) / l - stats = FreeCAD.ActiveDocument.addObject('Fem::FemResultValue', 'AnalysisStats') - stats.Values = [x_min, x_avg, x_max, - y_min, y_avg, y_max, - z_min, z_avg, z_max, - a_min, a_avg, a_max, - s_min, s_avg, s_max] - stats.DataType = 'AnalysisStats' - stats.ElementNumbers = len(stats.Values) - AnalysisObject.Member = AnalysisObject.Member + [stats] + results.Stats = [x_min, x_avg, x_max, + y_min, y_avg, y_max, + z_min, z_avg, z_max, + a_min, a_avg, a_max, + s_min, s_avg, s_max] + AnalysisObject.Member = AnalysisObject.Member + [results] if(FreeCAD.GuiUp): import FemGui