From e680701037fe0a22e08af348dabae2c58a617fcd Mon Sep 17 00:00:00 2001 From: Bernd Hahnebach Date: Tue, 10 Dec 2019 22:13:03 +0100 Subject: [PATCH] FEM: add gitattributes file to let git manage file endings and normalize them --- src/Mod/Fem/.gitattributes | 62 + src/Mod/Fem/App/FemConstraint.cpp | 938 ++++++------ src/Mod/Fem/App/FemPostFilter.cpp | 1252 ++++++++-------- src/Mod/Fem/App/FemPostFilter.h | 492 +++---- src/Mod/Fem/App/FemPostFunction.cpp | 262 ++-- src/Mod/Fem/App/FemPostFunction.h | 270 ++-- src/Mod/Fem/App/FemPostObject.cpp | 126 +- src/Mod/Fem/App/FemPostObject.h | 106 +- src/Mod/Fem/App/FemPostPipeline.cpp | 550 +++---- src/Mod/Fem/App/FemPostPipeline.h | 176 +-- src/Mod/Fem/App/PropertyPostDataObject.cpp | 716 +++++----- src/Mod/Fem/App/PropertyPostDataObject.h | 180 +-- .../Fem/Gui/DlgSettingsFemExportAbaqusImp.cpp | 172 +-- .../Fem/Gui/DlgSettingsFemExportAbaqusImp.h | 106 +- src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.cpp | 170 +-- src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.h | 106 +- src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp | 302 ++-- src/Mod/Fem/Gui/ViewProviderFemPostFilter.h | 224 +-- .../Fem/Gui/ViewProviderFemPostFunction.cpp | 1228 ++++++++-------- src/Mod/Fem/Gui/ViewProviderFemPostFunction.h | 444 +++--- src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp | 1268 ++++++++--------- src/Mod/Fem/Gui/ViewProviderFemPostObject.h | 324 ++--- .../Fem/Gui/ViewProviderFemPostPipeline.cpp | 180 +-- src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h | 106 +- src/Mod/Fem/femtest/data/ccx/spine_points.csv | 90 +- .../Fem/femtest/data/ccx/spine_volumes.csv | 24 +- 26 files changed, 4968 insertions(+), 4906 deletions(-) create mode 100644 src/Mod/Fem/.gitattributes diff --git a/src/Mod/Fem/.gitattributes b/src/Mod/Fem/.gitattributes new file mode 100644 index 0000000000..0ecfd3db6a --- /dev/null +++ b/src/Mod/Fem/.gitattributes @@ -0,0 +1,62 @@ +# In case people don't have core.autocrlf set, this will manage the default line-ending +# behaviour for all files recursively +# * text=auto +# to be save this will be commented + + +# for more information see forum topic and pull request +# https://github.com/FreeCAD/FreeCAD/pull/2752 +# https://forum.freecadweb.org/viewtopic.php?f=17&t=41117 + + +# get all used file types +# in a directory in a bash use +# find . -type f -name '*.*' | sed 's|.*\.||' | sort -u +# add all of them either to text or binary + + +# Explicitly declare which files we wish to always normalize line-endings on + +# standard endings +*.bat text +*.cpp text +*.csv text +*.h text +*.md text +*.py text +*.qrc text +*.ts text +*.txt text +*.ui text +*.xml text +*.yml text + +# Fem specific endings +*.dat text +*.frd text +*.geo text +*.inp text +*.sif text +*.unv text +*.vtk text +*.z88 text + + +# These files will always be checked out with CRLF, i.e. windows-style line endings. This +# really should not be needed... +# *.SomeWindowsFileExtensionThatReallyRequiresCRLFEvenInLinux eol=crlf + + +# These files should be ignored as it pertains to line-endings, because they are binary. +# Since auto normalize is deactivated all these could be commented too. +# *.dox binary +# *.FCStd binary +# *.jpg binary +# *.png binary +# *.pyc binary +# *.qm binary +# *.svg binary + + +# use git to manually correct the file endings +# git add --renormalize . diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index 20d9745dce..4e51b50b14 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -1,469 +1,469 @@ -/*************************************************************************** - * Copyright (c) 2013 Jan Rheinländer * - * * - * 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 //OvG: Required for log10 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "FemConstraint.h" -#include "FemTools.h" - -#include -#include - -#include -#include -#include - - -using namespace Fem; - -// maybe in the c++ standard later, older compiler don't have round() -#if _MSC_VER <= 1700 -double round(double r) { - return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); -} -#endif - -PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject) - -Constraint::Constraint() -{ - ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); - ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3d(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid"); - ADD_PROPERTY_TYPE(Scale,(1),"Base",App::PropertyType(App::Prop_Output),"Scale used for drawing constraints"); //OvG: Add scale parameter inherited by all derived constraints - - References.setScope(App::LinkScope::Global); -} - -Constraint::~Constraint() -{ -} - -App::DocumentObjectExecReturn *Constraint::execute(void) -{ - References.touch(); - Scale.touch(); - return StdReturn; -} - -//OvG: Provide the ability to determine how big to draw constraint arrows etc. -int Constraint::calcDrawScaleFactor(double lparam) const -{ - return ((int)round(log(lparam)*log(lparam)*log(lparam)/10)>1)?((int)round(log(lparam)*log(lparam)*log(lparam)/10)):1; -} - -int Constraint::calcDrawScaleFactor(double lvparam, double luparam) const -{ - return calcDrawScaleFactor((lvparam+luparam)/2.0); -} - -int Constraint::calcDrawScaleFactor() const -{ - return 1; -} -#define CONSTRAINTSTEPLIMIT 50 - -void Constraint::onChanged(const App::Property* prop) -{ - if (prop == &References) { - // If References are changed, recalculate the normal direction. If no useful reference is found, - // use z axis or previous value. If several faces are selected, only the first one is used - std::vector Objects = References.getValues(); - std::vector SubElements = References.getSubValues(); - - // Extract geometry from References - TopoDS_Shape sh; - - for (std::size_t i = 0; i < Objects.size(); i++) { - App::DocumentObject* obj = Objects[i]; - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (!toposhape.getShape().IsNull()) { - sh = toposhape.getSubShape(SubElements[i].c_str()); - - if (sh.ShapeType() == TopAbs_FACE) { - // Get face normal in center point - TopoDS_Face face = TopoDS::Face(sh); - BRepGProp_Face props(face); - gp_Vec normal; - gp_Pnt center; - double u1,u2,v1,v2; - props.Bounds(u1,u2,v1,v2); - props.Normal((u1+u2)/2.0,(v1+v2)/2.0,center,normal); - normal.Normalize(); - NormalDirection.setValue(normal.X(), normal.Y(), normal.Z()); - // One face is enough... - App::DocumentObject::onChanged(prop); - return; - } - } - } - } - - App::DocumentObject::onChanged(prop); -} - -void Constraint::onDocumentRestored() -{ - // This seems to be the only way to make the ViewProvider display the constraint - References.touch(); - App::DocumentObject::onDocumentRestored(); -} - -bool Constraint::getPoints(std::vector &points, std::vector &normals, int * scale) const -{ - std::vector Objects = References.getValues(); - std::vector SubElements = References.getSubValues(); - - // Extract geometry from References - TopoDS_Shape sh; - - for (std::size_t i = 0; i < Objects.size(); i++) { - App::DocumentObject* obj = Objects[i]; - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (toposhape.isNull()) - return false; - - sh = toposhape.getSubShape(SubElements[i].c_str()); - - if (sh.ShapeType() == TopAbs_VERTEX) { - const TopoDS_Vertex& vertex = TopoDS::Vertex(sh); - gp_Pnt p = BRep_Tool::Pnt(vertex); - points.emplace_back(p.X(), p.Y(), p.Z()); - normals.push_back(NormalDirection.getValue()); - //OvG: Scale by whole object mass in case of a vertex - GProp_GProps props; - BRepGProp::VolumeProperties(toposhape.getShape(), props); - double lx = props.Mass(); - *scale = this->calcDrawScaleFactor(sqrt(lx)*0.5); //OvG: setup draw scale for constraint - } - else if (sh.ShapeType() == TopAbs_EDGE) { - BRepAdaptor_Curve curve(TopoDS::Edge(sh)); - double fp = curve.FirstParameter(); - double lp = curve.LastParameter(); - GProp_GProps props; - BRepGProp::LinearProperties(TopoDS::Edge(sh), props); - double l = props.Mass(); - // Create points with 10 units distance, but at least one at the beginning and end of the edge - int steps; - if (l >= 30) //OvG: Increase 10 units distance proportionately to l for larger objects. - { - *scale = this->calcDrawScaleFactor(l); //OvG: setup draw scale for constraint - steps = (int)round(l / (10*( *scale))); - steps = steps<3?3:steps; - } - else if (l >= 20) - { - steps = (int)round(l / 10); - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - else - { - steps = 1; - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - - steps = steps>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:steps; //OvG: Place upper limit on number of steps - double step = (lp - fp) / steps; - for (int i = 0; i < steps + 1; i++) { - // Parameter values must be in the range [fp, lp] (#0003683) - gp_Pnt p = curve.Value(fp + i * step); - points.emplace_back(p.X(), p.Y(), p.Z()); - normals.push_back(NormalDirection.getValue()); - } - } - else if (sh.ShapeType() == TopAbs_FACE) { - TopoDS_Face face = TopoDS::Face(sh); - - // Surface boundaries - BRepAdaptor_Surface surface(face); - double ufp = surface.FirstUParameter(); - double ulp = surface.LastUParameter(); - double vfp = surface.FirstVParameter(); - double vlp = surface.LastVParameter(); - double l; - double lv, lu; - - // Surface normals - BRepGProp_Face props(face); - gp_Vec normal; - gp_Pnt center; - - // Get an estimate for the number of arrows by finding the average length of curves - Handle(Adaptor3d_HSurface) hsurf; - hsurf = new BRepAdaptor_HSurface(surface); - - Adaptor3d_IsoCurve isoc(hsurf); - try { - isoc.Load(GeomAbs_IsoU, ufp); - l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); - } - catch (const Standard_Failure&) { - gp_Pnt p1 = hsurf->Value(ufp, vfp); - gp_Pnt p2 = hsurf->Value(ufp, vlp); - l = p1.Distance(p2); - } - - try { - isoc.Load(GeomAbs_IsoU, ulp); - lv = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; - } - catch (const Standard_Failure&) { - gp_Pnt p1 = hsurf->Value(ulp, vfp); - gp_Pnt p2 = hsurf->Value(ulp, vlp); - lv = (l + p1.Distance(p2))/2.0; - } - - try { - isoc.Load(GeomAbs_IsoV, vfp); - l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); - } - catch (const Standard_Failure&) { - gp_Pnt p1 = hsurf->Value(ufp, vfp); - gp_Pnt p2 = hsurf->Value(ulp, vfp); - l = p1.Distance(p2); - } - - try { - isoc.Load(GeomAbs_IsoV, vlp); - lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; - } - catch (const Standard_Failure&) { - gp_Pnt p1 = hsurf->Value(ufp, vlp); - gp_Pnt p2 = hsurf->Value(ulp, vlp); - lu = (l + p1.Distance(p2))/2.0; - } - - int stepsv; - if (lv >= 30) //OvG: Increase 10 units distance proportionately to lv for larger objects. - { - *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint - stepsv = (int)round(lv / (10*( *scale))); - stepsv = stepsv<3?3:stepsv; - } - else if (lv >= 20.0) - { - stepsv = (int)round(lv / 10); - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - else - { - stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - - stepsv = stepsv>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsv; //OvG: Place upper limit on number of steps - int stepsu; - if (lu >= 30) //OvG: Increase 10 units distance proportionately to lu for larger objects. - { - *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint - stepsu = (int)round(lu / (10*( *scale))); - stepsu = stepsu<3?3:stepsu; - } - else if (lu >= 20.0) - { - stepsu = (int)round(lu / 10); - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - else - { - stepsu = 2; - *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint - } - - stepsu = stepsu>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsu; //OvG: Place upper limit on number of steps - double stepv = (vlp - vfp) / stepsv; - double stepu = (ulp - ufp) / stepsu; - // Create points and normals - for (int i = 0; i < stepsv + 1; i++) { - for (int j = 0; j < stepsu + 1; j++) { - double v = vfp + i * stepv; - double u = ufp + j * stepu; - gp_Pnt p = surface.Value(u, v); - BRepClass_FaceClassifier classifier(face, p, Precision::Confusion()); - if (classifier.State() != TopAbs_OUT) { - points.emplace_back(p.X(), p.Y(), p.Z()); - props.Normal(u, v,center,normal); - normal.Normalize(); - normals.emplace_back(normal.X(), normal.Y(), normal.Z()); - } - } - } - } - } - - return true; -} - -bool Constraint::getCylinder(double &radius, double &height, Base::Vector3d& base, Base::Vector3d& axis) const -{ - std::vector Objects = References.getValues(); - std::vector SubElements = References.getSubValues(); - if (Objects.empty()) - return false; - App::DocumentObject* obj = Objects[0]; - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& toposhape = feat->Shape.getShape(); - if (toposhape.isNull()) - return false; - TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str()); - - TopoDS_Face face = TopoDS::Face(sh); - BRepAdaptor_Surface surface(face); - gp_Cylinder cyl = surface.Cylinder(); - gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter()); - gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter()); - height = start.Distance(end); - radius = cyl.Radius(); - - gp_Pnt b = cyl.Location(); - base = Base::Vector3d(b.X(), b.Y(), b.Z()); - gp_Dir dir = cyl.Axis().Direction(); - axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z()); - - return true; -} - -Base::Vector3d Constraint::getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, - const App::PropertyLinkSub& location, const double& dist) -{ - // Get the point specified by Location and Distance - App::DocumentObject* objLoc = location.getValue(); - std::vector names = location.getSubValues(); - if (names.size() == 0) - return Base::Vector3d(0,0,0); - std::string subName = names.front(); - Part::Feature* featLoc = static_cast(objLoc); - TopoDS_Shape shloc = featLoc->Shape.getShape().getSubShape(subName.c_str()); - - // Get a plane from the Location reference - gp_Pln plane; - gp_Dir cylaxis(axis.x, axis.y, axis.z); - if (shloc.ShapeType() == TopAbs_FACE) { - BRepAdaptor_Surface surface(TopoDS::Face(shloc)); - plane = surface.Plane(); - } else { - BRepAdaptor_Curve curve(TopoDS::Edge(shloc)); - gp_Lin line = curve.Line(); - gp_Dir tang = line.Direction().Crossed(cylaxis); - gp_Dir norm = line.Direction().Crossed(tang); - plane = gp_Pln(line.Location(), norm); - } - - // Translate the plane in direction of the cylinder (for positive values of Distance) - Handle(Geom_Plane) pln = new Geom_Plane(plane); - gp_Pnt cylbase(base.x, base.y, base.z); - GeomAPI_ProjectPointOnSurf proj(cylbase, pln); - if (!proj.IsDone()) - return Base::Vector3d(0,0,0); - - gp_Pnt projPnt = proj.NearestPoint(); - if ((fabs(dist) > Precision::Confusion()) && (projPnt.IsEqual(cylbase, Precision::Confusion()) == Standard_False)) - plane.Translate(gp_Vec(projPnt, cylbase).Normalized().Multiplied(dist)); - Handle(Geom_Plane) plnt = new Geom_Plane(plane); - - // Intersect translated plane with cylinder axis - Handle(Geom_Curve) crv = new Geom_Line(cylbase, cylaxis); - GeomAPI_IntCS intersector(crv, plnt); - if (!intersector.IsDone()) - return Base::Vector3d(0,0,0); - gp_Pnt inter = intersector.Point(1); - return Base::Vector3d(inter.X(), inter.Y(), inter.Z()); -} - -const Base::Vector3d Constraint::getDirection(const App::PropertyLinkSub &direction) -{ - App::DocumentObject* obj = direction.getValue(); - std::vector names = direction.getSubValues(); - if (names.size() == 0) - return Base::Vector3d(0,0,0); - std::string subName = names.front(); - Part::Feature* feat = static_cast(obj); - const Part::TopoShape& shape = feat->Shape.getShape(); - if (shape.isNull()) - return Base::Vector3d(0,0,0); - TopoDS_Shape sh; - try { - sh = shape.getSubShape(subName.c_str()); - } - catch (Standard_Failure&) { - std::stringstream str; - str << "No such sub-element '" << subName << "'"; - throw Base::AttributeError(str.str()); - } - - return Fem::Tools::getDirectionFromShape(sh); -} - -// Python feature --------------------------------------------------------- - -namespace App { -/// @cond DOXERR -PROPERTY_SOURCE_TEMPLATE(Fem::ConstraintPython, Fem::Constraint) -template<> const char* Fem::ConstraintPython::getViewProviderName(void) const { - return "FemGui::ViewProviderFemConstraintPython"; -} - -template<> PyObject* Fem::ConstraintPython::getPyObject(void) { - if (PythonObject.is(Py::_None())) { - // ref counter is set to 1 - PythonObject = Py::Object(new App::FeaturePythonPyT(this),true); - } - return Py::new_reference_to(PythonObject); -} - -// explicit template instantiation -template class AppFemExport FeaturePythonT; - -/// @endcond - -} +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 //OvG: Required for log10 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "FemConstraint.h" +#include "FemTools.h" + +#include +#include + +#include +#include +#include + + +using namespace Fem; + +// maybe in the c++ standard later, older compiler don't have round() +#if _MSC_VER <= 1700 +double round(double r) { + return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); +} +#endif + +PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject) + +Constraint::Constraint() +{ + ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); + ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3d(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid"); + ADD_PROPERTY_TYPE(Scale,(1),"Base",App::PropertyType(App::Prop_Output),"Scale used for drawing constraints"); //OvG: Add scale parameter inherited by all derived constraints + + References.setScope(App::LinkScope::Global); +} + +Constraint::~Constraint() +{ +} + +App::DocumentObjectExecReturn *Constraint::execute(void) +{ + References.touch(); + Scale.touch(); + return StdReturn; +} + +//OvG: Provide the ability to determine how big to draw constraint arrows etc. +int Constraint::calcDrawScaleFactor(double lparam) const +{ + return ((int)round(log(lparam)*log(lparam)*log(lparam)/10)>1)?((int)round(log(lparam)*log(lparam)*log(lparam)/10)):1; +} + +int Constraint::calcDrawScaleFactor(double lvparam, double luparam) const +{ + return calcDrawScaleFactor((lvparam+luparam)/2.0); +} + +int Constraint::calcDrawScaleFactor() const +{ + return 1; +} +#define CONSTRAINTSTEPLIMIT 50 + +void Constraint::onChanged(const App::Property* prop) +{ + if (prop == &References) { + // If References are changed, recalculate the normal direction. If no useful reference is found, + // use z axis or previous value. If several faces are selected, only the first one is used + std::vector Objects = References.getValues(); + std::vector SubElements = References.getSubValues(); + + // Extract geometry from References + TopoDS_Shape sh; + + for (std::size_t i = 0; i < Objects.size(); i++) { + App::DocumentObject* obj = Objects[i]; + Part::Feature* feat = static_cast(obj); + const Part::TopoShape& toposhape = feat->Shape.getShape(); + if (!toposhape.getShape().IsNull()) { + sh = toposhape.getSubShape(SubElements[i].c_str()); + + if (sh.ShapeType() == TopAbs_FACE) { + // Get face normal in center point + TopoDS_Face face = TopoDS::Face(sh); + BRepGProp_Face props(face); + gp_Vec normal; + gp_Pnt center; + double u1,u2,v1,v2; + props.Bounds(u1,u2,v1,v2); + props.Normal((u1+u2)/2.0,(v1+v2)/2.0,center,normal); + normal.Normalize(); + NormalDirection.setValue(normal.X(), normal.Y(), normal.Z()); + // One face is enough... + App::DocumentObject::onChanged(prop); + return; + } + } + } + } + + App::DocumentObject::onChanged(prop); +} + +void Constraint::onDocumentRestored() +{ + // This seems to be the only way to make the ViewProvider display the constraint + References.touch(); + App::DocumentObject::onDocumentRestored(); +} + +bool Constraint::getPoints(std::vector &points, std::vector &normals, int * scale) const +{ + std::vector Objects = References.getValues(); + std::vector SubElements = References.getSubValues(); + + // Extract geometry from References + TopoDS_Shape sh; + + for (std::size_t i = 0; i < Objects.size(); i++) { + App::DocumentObject* obj = Objects[i]; + Part::Feature* feat = static_cast(obj); + const Part::TopoShape& toposhape = feat->Shape.getShape(); + if (toposhape.isNull()) + return false; + + sh = toposhape.getSubShape(SubElements[i].c_str()); + + if (sh.ShapeType() == TopAbs_VERTEX) { + const TopoDS_Vertex& vertex = TopoDS::Vertex(sh); + gp_Pnt p = BRep_Tool::Pnt(vertex); + points.emplace_back(p.X(), p.Y(), p.Z()); + normals.push_back(NormalDirection.getValue()); + //OvG: Scale by whole object mass in case of a vertex + GProp_GProps props; + BRepGProp::VolumeProperties(toposhape.getShape(), props); + double lx = props.Mass(); + *scale = this->calcDrawScaleFactor(sqrt(lx)*0.5); //OvG: setup draw scale for constraint + } + else if (sh.ShapeType() == TopAbs_EDGE) { + BRepAdaptor_Curve curve(TopoDS::Edge(sh)); + double fp = curve.FirstParameter(); + double lp = curve.LastParameter(); + GProp_GProps props; + BRepGProp::LinearProperties(TopoDS::Edge(sh), props); + double l = props.Mass(); + // Create points with 10 units distance, but at least one at the beginning and end of the edge + int steps; + if (l >= 30) //OvG: Increase 10 units distance proportionately to l for larger objects. + { + *scale = this->calcDrawScaleFactor(l); //OvG: setup draw scale for constraint + steps = (int)round(l / (10*( *scale))); + steps = steps<3?3:steps; + } + else if (l >= 20) + { + steps = (int)round(l / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + else + { + steps = 1; + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + + steps = steps>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:steps; //OvG: Place upper limit on number of steps + double step = (lp - fp) / steps; + for (int i = 0; i < steps + 1; i++) { + // Parameter values must be in the range [fp, lp] (#0003683) + gp_Pnt p = curve.Value(fp + i * step); + points.emplace_back(p.X(), p.Y(), p.Z()); + normals.push_back(NormalDirection.getValue()); + } + } + else if (sh.ShapeType() == TopAbs_FACE) { + TopoDS_Face face = TopoDS::Face(sh); + + // Surface boundaries + BRepAdaptor_Surface surface(face); + double ufp = surface.FirstUParameter(); + double ulp = surface.LastUParameter(); + double vfp = surface.FirstVParameter(); + double vlp = surface.LastVParameter(); + double l; + double lv, lu; + + // Surface normals + BRepGProp_Face props(face); + gp_Vec normal; + gp_Pnt center; + + // Get an estimate for the number of arrows by finding the average length of curves + Handle(Adaptor3d_HSurface) hsurf; + hsurf = new BRepAdaptor_HSurface(surface); + + Adaptor3d_IsoCurve isoc(hsurf); + try { + isoc.Load(GeomAbs_IsoU, ufp); + l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); + } + catch (const Standard_Failure&) { + gp_Pnt p1 = hsurf->Value(ufp, vfp); + gp_Pnt p2 = hsurf->Value(ufp, vlp); + l = p1.Distance(p2); + } + + try { + isoc.Load(GeomAbs_IsoU, ulp); + lv = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; + } + catch (const Standard_Failure&) { + gp_Pnt p1 = hsurf->Value(ulp, vfp); + gp_Pnt p2 = hsurf->Value(ulp, vlp); + lv = (l + p1.Distance(p2))/2.0; + } + + try { + isoc.Load(GeomAbs_IsoV, vfp); + l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); + } + catch (const Standard_Failure&) { + gp_Pnt p1 = hsurf->Value(ufp, vfp); + gp_Pnt p2 = hsurf->Value(ulp, vfp); + l = p1.Distance(p2); + } + + try { + isoc.Load(GeomAbs_IsoV, vlp); + lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; + } + catch (const Standard_Failure&) { + gp_Pnt p1 = hsurf->Value(ufp, vlp); + gp_Pnt p2 = hsurf->Value(ulp, vlp); + lu = (l + p1.Distance(p2))/2.0; + } + + int stepsv; + if (lv >= 30) //OvG: Increase 10 units distance proportionately to lv for larger objects. + { + *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint + stepsv = (int)round(lv / (10*( *scale))); + stepsv = stepsv<3?3:stepsv; + } + else if (lv >= 20.0) + { + stepsv = (int)round(lv / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + else + { + stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + + stepsv = stepsv>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsv; //OvG: Place upper limit on number of steps + int stepsu; + if (lu >= 30) //OvG: Increase 10 units distance proportionately to lu for larger objects. + { + *scale = this->calcDrawScaleFactor(lv,lu); //OvG: setup draw scale for constraint + stepsu = (int)round(lu / (10*( *scale))); + stepsu = stepsu<3?3:stepsu; + } + else if (lu >= 20.0) + { + stepsu = (int)round(lu / 10); + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + else + { + stepsu = 2; + *scale = this->calcDrawScaleFactor(); //OvG: setup draw scale for constraint + } + + stepsu = stepsu>CONSTRAINTSTEPLIMIT?CONSTRAINTSTEPLIMIT:stepsu; //OvG: Place upper limit on number of steps + double stepv = (vlp - vfp) / stepsv; + double stepu = (ulp - ufp) / stepsu; + // Create points and normals + for (int i = 0; i < stepsv + 1; i++) { + for (int j = 0; j < stepsu + 1; j++) { + double v = vfp + i * stepv; + double u = ufp + j * stepu; + gp_Pnt p = surface.Value(u, v); + BRepClass_FaceClassifier classifier(face, p, Precision::Confusion()); + if (classifier.State() != TopAbs_OUT) { + points.emplace_back(p.X(), p.Y(), p.Z()); + props.Normal(u, v,center,normal); + normal.Normalize(); + normals.emplace_back(normal.X(), normal.Y(), normal.Z()); + } + } + } + } + } + + return true; +} + +bool Constraint::getCylinder(double &radius, double &height, Base::Vector3d& base, Base::Vector3d& axis) const +{ + std::vector Objects = References.getValues(); + std::vector SubElements = References.getSubValues(); + if (Objects.empty()) + return false; + App::DocumentObject* obj = Objects[0]; + Part::Feature* feat = static_cast(obj); + const Part::TopoShape& toposhape = feat->Shape.getShape(); + if (toposhape.isNull()) + return false; + TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str()); + + TopoDS_Face face = TopoDS::Face(sh); + BRepAdaptor_Surface surface(face); + gp_Cylinder cyl = surface.Cylinder(); + gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter()); + gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter()); + height = start.Distance(end); + radius = cyl.Radius(); + + gp_Pnt b = cyl.Location(); + base = Base::Vector3d(b.X(), b.Y(), b.Z()); + gp_Dir dir = cyl.Axis().Direction(); + axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z()); + + return true; +} + +Base::Vector3d Constraint::getBasePoint(const Base::Vector3d& base, const Base::Vector3d& axis, + const App::PropertyLinkSub& location, const double& dist) +{ + // Get the point specified by Location and Distance + App::DocumentObject* objLoc = location.getValue(); + std::vector names = location.getSubValues(); + if (names.size() == 0) + return Base::Vector3d(0,0,0); + std::string subName = names.front(); + Part::Feature* featLoc = static_cast(objLoc); + TopoDS_Shape shloc = featLoc->Shape.getShape().getSubShape(subName.c_str()); + + // Get a plane from the Location reference + gp_Pln plane; + gp_Dir cylaxis(axis.x, axis.y, axis.z); + if (shloc.ShapeType() == TopAbs_FACE) { + BRepAdaptor_Surface surface(TopoDS::Face(shloc)); + plane = surface.Plane(); + } else { + BRepAdaptor_Curve curve(TopoDS::Edge(shloc)); + gp_Lin line = curve.Line(); + gp_Dir tang = line.Direction().Crossed(cylaxis); + gp_Dir norm = line.Direction().Crossed(tang); + plane = gp_Pln(line.Location(), norm); + } + + // Translate the plane in direction of the cylinder (for positive values of Distance) + Handle(Geom_Plane) pln = new Geom_Plane(plane); + gp_Pnt cylbase(base.x, base.y, base.z); + GeomAPI_ProjectPointOnSurf proj(cylbase, pln); + if (!proj.IsDone()) + return Base::Vector3d(0,0,0); + + gp_Pnt projPnt = proj.NearestPoint(); + if ((fabs(dist) > Precision::Confusion()) && (projPnt.IsEqual(cylbase, Precision::Confusion()) == Standard_False)) + plane.Translate(gp_Vec(projPnt, cylbase).Normalized().Multiplied(dist)); + Handle(Geom_Plane) plnt = new Geom_Plane(plane); + + // Intersect translated plane with cylinder axis + Handle(Geom_Curve) crv = new Geom_Line(cylbase, cylaxis); + GeomAPI_IntCS intersector(crv, plnt); + if (!intersector.IsDone()) + return Base::Vector3d(0,0,0); + gp_Pnt inter = intersector.Point(1); + return Base::Vector3d(inter.X(), inter.Y(), inter.Z()); +} + +const Base::Vector3d Constraint::getDirection(const App::PropertyLinkSub &direction) +{ + App::DocumentObject* obj = direction.getValue(); + std::vector names = direction.getSubValues(); + if (names.size() == 0) + return Base::Vector3d(0,0,0); + std::string subName = names.front(); + Part::Feature* feat = static_cast(obj); + const Part::TopoShape& shape = feat->Shape.getShape(); + if (shape.isNull()) + return Base::Vector3d(0,0,0); + TopoDS_Shape sh; + try { + sh = shape.getSubShape(subName.c_str()); + } + catch (Standard_Failure&) { + std::stringstream str; + str << "No such sub-element '" << subName << "'"; + throw Base::AttributeError(str.str()); + } + + return Fem::Tools::getDirectionFromShape(sh); +} + +// Python feature --------------------------------------------------------- + +namespace App { +/// @cond DOXERR +PROPERTY_SOURCE_TEMPLATE(Fem::ConstraintPython, Fem::Constraint) +template<> const char* Fem::ConstraintPython::getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintPython"; +} + +template<> PyObject* Fem::ConstraintPython::getPyObject(void) { + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new App::FeaturePythonPyT(this),true); + } + return Py::new_reference_to(PythonObject); +} + +// explicit template instantiation +template class AppFemExport FeaturePythonT; + +/// @endcond + +} diff --git a/src/Mod/Fem/App/FemPostFilter.cpp b/src/Mod/Fem/App/FemPostFilter.cpp index 1c4f1b8f9b..bd8a7e85e1 100644 --- a/src/Mod/Fem/App/FemPostFilter.cpp +++ b/src/Mod/Fem/App/FemPostFilter.cpp @@ -1,626 +1,626 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -#endif - -#include "FemPostFilter.h" -#include "FemPostPipeline.h" -#include -#include -#include - - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemPostFilter, Fem::FemPostObject) - - -FemPostFilter::FemPostFilter() -{ - ADD_PROPERTY(Input,(0)); -} - -FemPostFilter::~FemPostFilter() -{ - -} - -void FemPostFilter::addFilterPipeline(const FemPostFilter::FilterPipeline& p, std::string name) { - m_pipelines[name] = p; -} - -FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name) { - return m_pipelines[name]; -} - -void FemPostFilter::setActiveFilterPipeline(std::string name) { - - if(m_activePipeline != name && isValid()) { - m_activePipeline = name; - } -} - -DocumentObjectExecReturn* FemPostFilter::execute(void) { - - if(!m_pipelines.empty() && !m_activePipeline.empty()) { - FemPostFilter::FilterPipeline& pipe = m_pipelines[m_activePipeline]; - if ((m_activePipeline.length() >= 13) || (m_activePipeline.length() >= 11)) { - std::string LineClip = m_activePipeline.substr(0,13); - std::string PointClip = m_activePipeline.substr(0,11); - if ((LineClip == "DataAlongLine") || (PointClip == "DataAtPoint")) { - pipe.filterSource->SetSourceData(getInputData()); - pipe.filterTarget->Update(); - - Data.setValue(pipe.filterTarget->GetOutputDataObject(0)); - } - } else { - pipe.source->SetInputDataObject(getInputData()); - pipe.target->Update(); - Data.setValue(pipe.target->GetOutputDataObject(0)); - } - - } - return StdReturn; -} - -vtkDataObject* FemPostFilter::getInputData() { - - if(Input.getValue()) { - return Input.getValue()->Data.getValue(); - } - else { - //get the pipeline and use the pipelinedata - std::vector objs = getDocument()->getObjectsOfType(FemPostPipeline::getClassTypeId()); - for(std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { - - if(static_cast(*it)->holdsPostObject(this)) { - - return static_cast(*it)->Data.getValue(); - } - } - } - - return NULL; -} - - -PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter) - -FemPostClipFilter::FemPostClipFilter(void) : FemPostFilter() { - - ADD_PROPERTY_TYPE(Function, (0), "Clip", App::Prop_None, "The function object which defines the clip regions"); - ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); - ADD_PROPERTY_TYPE(CutCells, (false), "Clip", App::Prop_None, "Decides if cells are cuttet and interpolated or if the cells are kept as a whole"); - - FilterPipeline clip; - m_clipper = vtkSmartPointer::New(); - clip.source = m_clipper; - clip.target = m_clipper; - addFilterPipeline(clip, "clip"); - - FilterPipeline extr; - m_extractor = vtkSmartPointer::New(); - extr.source = m_extractor; - extr.target = m_extractor; - addFilterPipeline(extr, "extract"); - - m_extractor->SetExtractInside(0); - setActiveFilterPipeline("extract"); -} - -FemPostClipFilter::~FemPostClipFilter() { - -} - -void FemPostClipFilter::onChanged(const Property* prop) { - - if(prop == &Function) { - - if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { - m_clipper->SetClipFunction(static_cast(Function.getValue())->getImplicitFunction()); - m_extractor->SetImplicitFunction(static_cast(Function.getValue())->getImplicitFunction()); - } - } - else if(prop == &InsideOut) { - - m_clipper->SetInsideOut(InsideOut.getValue()); - m_extractor->SetExtractInside( (InsideOut.getValue()) ? 1 : 0 ); - } - else if(prop == &CutCells) { - - if(!CutCells.getValue()) - setActiveFilterPipeline("extract"); - else - setActiveFilterPipeline("clip"); - }; - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostClipFilter::mustExecute(void) const { - - if(Function.isTouched() || - InsideOut.isTouched() || - CutCells.isTouched()) { - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - -DocumentObjectExecReturn* FemPostClipFilter::execute(void) { - - if(!m_extractor->GetImplicitFunction()) - return StdReturn; - - return Fem::FemPostFilter::execute(); -} - -PROPERTY_SOURCE(Fem::FemPostDataAlongLineFilter, Fem::FemPostFilter) - -FemPostDataAlongLineFilter::FemPostDataAlongLineFilter(void) : FemPostFilter() { - - ADD_PROPERTY_TYPE(Point1,(Base::Vector3d(0.0,0.0,0.0)), "DataAlongLine", App::Prop_None, "The point 1 used to define end point of line"); - ADD_PROPERTY_TYPE(Point2,(Base::Vector3d(0.0,0.0,1.0)), "DataAlongLine", App::Prop_None, "The point 2 used to define end point of line"); - ADD_PROPERTY_TYPE(Resolution,(100), "DataAlongLine", App::Prop_None, "The number of intervals between the 2 end points of line"); - ADD_PROPERTY_TYPE(XAxisData,(0), "DataAlongLine",App::Prop_None,"X axis data values used for plotting"); - ADD_PROPERTY_TYPE(YAxisData,(0), "DataAlongLine",App::Prop_None,"Y axis data values used for plotting"); - ADD_PROPERTY_TYPE(PlotData ,(""),"DataAlongLine",App::Prop_None,"Field used for plotting"); - - PlotData.setStatus(App::Property::ReadOnly, true); - XAxisData.setStatus(App::Property::ReadOnly, true); - YAxisData.setStatus(App::Property::ReadOnly, true); - - FilterPipeline clip; - - m_line = vtkSmartPointer::New(); - const Base::Vector3d& vec1 = Point1.getValue(); - m_line->SetPoint1(vec1.x, vec1.y, vec1.z); - const Base::Vector3d& vec2 = Point2.getValue(); - m_line->SetPoint2(vec2.x, vec2.y, vec2.z); - m_line->SetResolution(Resolution.getValue()); - - - m_probe = vtkSmartPointer::New(); - m_probe->SetInputConnection(m_line->GetOutputPort()); - m_probe->SetValidPointMaskArrayName("ValidPointArray"); - m_probe->SetPassPointArrays(1); - m_probe->SetPassCellArrays(1); - // needs vtk > 6.1 -#if (VTK_MAJOR_VERSION > 6) || (VTK_MINOR_VERSION > 1) - m_probe->ComputeToleranceOff(); - m_probe->SetTolerance(0.01); -#endif - - clip.filterSource = m_probe; - clip.filterTarget = m_probe; - - addFilterPipeline(clip, "DataAlongLine"); - setActiveFilterPipeline("DataAlongLine"); -} - -FemPostDataAlongLineFilter::~FemPostDataAlongLineFilter() { - -} - -DocumentObjectExecReturn* FemPostDataAlongLineFilter::execute(void) { - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - - -void FemPostDataAlongLineFilter::onChanged(const Property* prop) { - if(prop == &Point1) { - const Base::Vector3d& vec1 = Point1.getValue(); - m_line->SetPoint1(vec1.x, vec1.y, vec1.z); - } - else if(prop == &Point2) { - const Base::Vector3d& vec2 = Point2.getValue(); - m_line->SetPoint2(vec2.x, vec2.y, vec2.z); - } - else if(prop == &Resolution) { - m_line->SetResolution(Resolution.getValue()); - } - else if(prop == &PlotData) { - GetAxisData(); - } - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostDataAlongLineFilter::mustExecute(void) const { - - if(Point1.isTouched() || - Point2.isTouched() || - Resolution.isTouched()){ - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - -void FemPostDataAlongLineFilter::GetAxisData() { - - std::vector coords; - std::vector values; - - vtkSmartPointer data = m_probe->GetOutputDataObject(0); - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkDataArray* pdata = dset->GetPointData()->GetArray(PlotData.getValue()); - vtkDataArray *tcoords = dset->GetPointData()->GetTCoords("Texture Coordinates"); - - int component = 0; - - const Base::Vector3d& vec1 = Point1.getValue(); - const Base::Vector3d& vec2 = Point2.getValue(); - const Base::Vector3d diff = vec1 - vec2; - double Len = diff.Length(); - - for(int i=0; iGetNumberOfPoints(); ++i) { - - double value = 0; - if(pdata->GetNumberOfComponents() == 1) - value = pdata->GetComponent(i, component); - else { - for(int j=0; jGetNumberOfComponents(); ++j) - value += std::pow(pdata->GetComponent(i, j),2); - - value = std::sqrt(value); - } - values.push_back(value); - double tcoord = tcoords->GetComponent(i, component); - coords.push_back(tcoord*Len); - } - YAxisData.setValues(values); - XAxisData.setValues(coords); -} - -PROPERTY_SOURCE(Fem::FemPostDataAtPointFilter, Fem::FemPostFilter) - -FemPostDataAtPointFilter::FemPostDataAtPointFilter(void) : FemPostFilter() { - - ADD_PROPERTY_TYPE(Center,(Base::Vector3d(0.0,0.0,1.0)), "DataAtPoint", App::Prop_None, "The center used to define the center of the point"); - ADD_PROPERTY_TYPE(Radius,(0), "DataAtPoint", App::Prop_None, "The point 2 used to define end point of line"); - ADD_PROPERTY_TYPE(PointData,(0), "DataAtPoint",App::Prop_None,"Point data values used for plotting"); - ADD_PROPERTY_TYPE(FieldName,(""),"DataAtPoint",App::Prop_None,"Field used for plotting"); - ADD_PROPERTY_TYPE(Unit,(""),"DataAtPoint",App::Prop_None,"Unit used for Field"); - - PointData.setStatus(App::Property::ReadOnly, true); - FieldName.setStatus(App::Property::ReadOnly, true); - Unit.setStatus(App::Property::ReadOnly, true); - - FilterPipeline clip; - - m_point = vtkSmartPointer::New(); - const Base::Vector3d& vec = Center.getValue(); - m_point->SetCenter(vec.x, vec.y, vec.z); - m_point->SetRadius(0); - - m_probe = vtkSmartPointer::New(); - m_probe->SetInputConnection(m_point->GetOutputPort()); - m_probe->SetValidPointMaskArrayName("ValidPointArray"); - m_probe->SetPassPointArrays(1); - m_probe->SetPassCellArrays(1); - // needs vtk > 6.1 -#if (VTK_MAJOR_VERSION > 6) || (VTK_MINOR_VERSION > 1) - m_probe->ComputeToleranceOff(); - m_probe->SetTolerance(0.01); -#endif - - clip.filterSource = m_probe; - clip.filterTarget = m_probe; - - addFilterPipeline(clip, "DataAtPoint"); - setActiveFilterPipeline("DataAtPoint"); -} - -FemPostDataAtPointFilter::~FemPostDataAtPointFilter() { - -} - -DocumentObjectExecReturn* FemPostDataAtPointFilter::execute(void) { - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - - -void FemPostDataAtPointFilter::onChanged(const Property* prop) { - if(prop == &Center) { - const Base::Vector3d& vec = Center.getValue(); - m_point->SetCenter(vec.x, vec.y, vec.z); - } - else if(prop == &FieldName) { - GetPointData(); - } - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostDataAtPointFilter::mustExecute(void) const { - - if(Center.isTouched()){ - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - -void FemPostDataAtPointFilter::GetPointData() { - - std::vector values; - - vtkSmartPointer data = m_probe->GetOutputDataObject(0); - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkDataArray* pdata = dset->GetPointData()->GetArray(FieldName.getValue()); - - int component = 0; - - for(int i=0; iGetNumberOfPoints(); ++i) { - - double value = 0; - if(pdata->GetNumberOfComponents() == 1) - value = pdata->GetComponent(i, component); - else { - for(int j=0; jGetNumberOfComponents(); ++j) - value += std::pow(pdata->GetComponent(i, j),2); - - value = std::sqrt(value); - } - values.push_back(value); - } - PointData.setValues(values); -} - -PROPERTY_SOURCE(Fem::FemPostScalarClipFilter, Fem::FemPostFilter) - -FemPostScalarClipFilter::FemPostScalarClipFilter(void) : FemPostFilter() { - - ADD_PROPERTY_TYPE(Value, (0), "Clip", App::Prop_None, "The scalar value used to clip the selected field"); - ADD_PROPERTY_TYPE(Scalars, (long(0)), "Clip", App::Prop_None, "The field used to clip"); - ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); - - Value.setConstraints(&m_constraints); - - FilterPipeline clip; - m_clipper = vtkSmartPointer::New(); - clip.source = m_clipper; - clip.target = m_clipper; - addFilterPipeline(clip, "clip"); - setActiveFilterPipeline("clip"); -} - -FemPostScalarClipFilter::~FemPostScalarClipFilter() { - -} - -DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { - - std::string val; - if(m_scalarFields.getEnums() && Scalars.getValue() >= 0) - val = Scalars.getValueAsString(); - - std::vector array; - - vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) - return StdReturn; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkPointData* pd = dset->GetPointData(); - - for(int i=0; iGetNumberOfArrays(); ++i) { - if(pd->GetArray(i)->GetNumberOfComponents()==1) - array.push_back(pd->GetArrayName(i)); - } - - App::Enumeration empty; - Scalars.setValue(empty); - m_scalarFields.setEnums(array); - Scalars.setValue(m_scalarFields); - - std::vector::iterator it = std::find(array.begin(), array.end(), val); - if(!val.empty() && it != array.end()) - Scalars.setValue(val.c_str()); - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - - -void FemPostScalarClipFilter::onChanged(const Property* prop) { - - if(prop == &Value) { - m_clipper->SetValue(Value.getValue()); - } - else if(prop == &InsideOut) { - m_clipper->SetInsideOut(InsideOut.getValue()); - } - else if(prop == &Scalars && (Scalars.getValue() >= 0)) { - m_clipper->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString() ); - setConstraintForField(); - } - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostScalarClipFilter::mustExecute(void) const { - - if(Value.isTouched() || - InsideOut.isTouched() || - Scalars.isTouched()) { - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - -void FemPostScalarClipFilter::setConstraintForField() { - - vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) - return; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - - vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString()); - double p[2]; - pdata->GetRange(p); - m_constraints.LowerBound = p[0]; - m_constraints.UpperBound = p[1]; - m_constraints.StepSize = (p[1]-p[0])/100.; -} - - -PROPERTY_SOURCE(Fem::FemPostWarpVectorFilter, Fem::FemPostFilter) - -FemPostWarpVectorFilter::FemPostWarpVectorFilter(void): FemPostFilter() { - - ADD_PROPERTY_TYPE(Factor, (0), "Warp", App::Prop_None, "The factor by which the vector is added to the node positions"); - ADD_PROPERTY_TYPE(Vector, (long(0)), "Warp", App::Prop_None, "The field added to the node position"); - - FilterPipeline warp; - m_warp = vtkSmartPointer::New(); - warp.source = m_warp; - warp.target = m_warp; - addFilterPipeline(warp, "warp"); - setActiveFilterPipeline("warp"); -} - -FemPostWarpVectorFilter::~FemPostWarpVectorFilter() { - -} - - -DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { - - std::string val; - if(m_vectorFields.getEnums() && Vector.getValue() >= 0) - val = Vector.getValueAsString(); - - std::vector array; - - vtkSmartPointer data = getInputData(); - if(!data || !data->IsA("vtkDataSet")) - return StdReturn; - - vtkDataSet* dset = vtkDataSet::SafeDownCast(data); - vtkPointData* pd = dset->GetPointData(); - - for(int i=0; iGetNumberOfArrays(); ++i) { - if(pd->GetArray(i)->GetNumberOfComponents()==3) - array.push_back(pd->GetArrayName(i)); - } - - App::Enumeration empty; - Vector.setValue(empty); - m_vectorFields.setEnums(array); - Vector.setValue(m_vectorFields); - - std::vector::iterator it = std::find(array.begin(), array.end(), val); - if(!val.empty() && it != array.end()) - Vector.setValue(val.c_str()); - - //recalculate the filter - return Fem::FemPostFilter::execute(); -} - - -void FemPostWarpVectorFilter::onChanged(const Property* prop) { - - if(prop == &Factor) { - m_warp->SetScaleFactor(Factor.getValue()); - } - else if(prop == &Vector && (Vector.getValue() >= 0)) { - m_warp->SetInputArrayToProcess(0, 0, 0, - vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString() ); - } - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostWarpVectorFilter::mustExecute(void) const { - - if(Factor.isTouched() || - Vector.isTouched()) { - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - - -PROPERTY_SOURCE(Fem::FemPostCutFilter, Fem::FemPostFilter) - -FemPostCutFilter::FemPostCutFilter(void) : FemPostFilter() { - - ADD_PROPERTY_TYPE(Function, (0), "Cut", App::Prop_None, "The function object which defines the clip cut function"); - - FilterPipeline clip; - m_cutter = vtkSmartPointer::New(); - clip.source = m_cutter; - clip.target = m_cutter; - addFilterPipeline(clip, "cut"); - setActiveFilterPipeline("cut"); -} - -FemPostCutFilter::~FemPostCutFilter() { - -} - -void FemPostCutFilter::onChanged(const Property* prop) { - - if(prop == &Function) { - - if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { - m_cutter->SetCutFunction(static_cast(Function.getValue())->getImplicitFunction()); - } - } - - Fem::FemPostFilter::onChanged(prop); -} - -short int FemPostCutFilter::mustExecute(void) const { - - if(Function.isTouched()) { - - return 1; - } - else return App::DocumentObject::mustExecute(); -} - -DocumentObjectExecReturn* FemPostCutFilter::execute(void) { - - if(!m_cutter->GetCutFunction()) - return StdReturn; - - return Fem::FemPostFilter::execute(); -} - - +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +#endif + +#include "FemPostFilter.h" +#include "FemPostPipeline.h" +#include +#include +#include + + +using namespace Fem; +using namespace App; + +PROPERTY_SOURCE(Fem::FemPostFilter, Fem::FemPostObject) + + +FemPostFilter::FemPostFilter() +{ + ADD_PROPERTY(Input,(0)); +} + +FemPostFilter::~FemPostFilter() +{ + +} + +void FemPostFilter::addFilterPipeline(const FemPostFilter::FilterPipeline& p, std::string name) { + m_pipelines[name] = p; +} + +FemPostFilter::FilterPipeline& FemPostFilter::getFilterPipeline(std::string name) { + return m_pipelines[name]; +} + +void FemPostFilter::setActiveFilterPipeline(std::string name) { + + if(m_activePipeline != name && isValid()) { + m_activePipeline = name; + } +} + +DocumentObjectExecReturn* FemPostFilter::execute(void) { + + if(!m_pipelines.empty() && !m_activePipeline.empty()) { + FemPostFilter::FilterPipeline& pipe = m_pipelines[m_activePipeline]; + if ((m_activePipeline.length() >= 13) || (m_activePipeline.length() >= 11)) { + std::string LineClip = m_activePipeline.substr(0,13); + std::string PointClip = m_activePipeline.substr(0,11); + if ((LineClip == "DataAlongLine") || (PointClip == "DataAtPoint")) { + pipe.filterSource->SetSourceData(getInputData()); + pipe.filterTarget->Update(); + + Data.setValue(pipe.filterTarget->GetOutputDataObject(0)); + } + } else { + pipe.source->SetInputDataObject(getInputData()); + pipe.target->Update(); + Data.setValue(pipe.target->GetOutputDataObject(0)); + } + + } + return StdReturn; +} + +vtkDataObject* FemPostFilter::getInputData() { + + if(Input.getValue()) { + return Input.getValue()->Data.getValue(); + } + else { + //get the pipeline and use the pipelinedata + std::vector objs = getDocument()->getObjectsOfType(FemPostPipeline::getClassTypeId()); + for(std::vector::iterator it = objs.begin(); it != objs.end(); ++it) { + + if(static_cast(*it)->holdsPostObject(this)) { + + return static_cast(*it)->Data.getValue(); + } + } + } + + return NULL; +} + + +PROPERTY_SOURCE(Fem::FemPostClipFilter, Fem::FemPostFilter) + +FemPostClipFilter::FemPostClipFilter(void) : FemPostFilter() { + + ADD_PROPERTY_TYPE(Function, (0), "Clip", App::Prop_None, "The function object which defines the clip regions"); + ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); + ADD_PROPERTY_TYPE(CutCells, (false), "Clip", App::Prop_None, "Decides if cells are cuttet and interpolated or if the cells are kept as a whole"); + + FilterPipeline clip; + m_clipper = vtkSmartPointer::New(); + clip.source = m_clipper; + clip.target = m_clipper; + addFilterPipeline(clip, "clip"); + + FilterPipeline extr; + m_extractor = vtkSmartPointer::New(); + extr.source = m_extractor; + extr.target = m_extractor; + addFilterPipeline(extr, "extract"); + + m_extractor->SetExtractInside(0); + setActiveFilterPipeline("extract"); +} + +FemPostClipFilter::~FemPostClipFilter() { + +} + +void FemPostClipFilter::onChanged(const Property* prop) { + + if(prop == &Function) { + + if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { + m_clipper->SetClipFunction(static_cast(Function.getValue())->getImplicitFunction()); + m_extractor->SetImplicitFunction(static_cast(Function.getValue())->getImplicitFunction()); + } + } + else if(prop == &InsideOut) { + + m_clipper->SetInsideOut(InsideOut.getValue()); + m_extractor->SetExtractInside( (InsideOut.getValue()) ? 1 : 0 ); + } + else if(prop == &CutCells) { + + if(!CutCells.getValue()) + setActiveFilterPipeline("extract"); + else + setActiveFilterPipeline("clip"); + }; + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostClipFilter::mustExecute(void) const { + + if(Function.isTouched() || + InsideOut.isTouched() || + CutCells.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + +DocumentObjectExecReturn* FemPostClipFilter::execute(void) { + + if(!m_extractor->GetImplicitFunction()) + return StdReturn; + + return Fem::FemPostFilter::execute(); +} + +PROPERTY_SOURCE(Fem::FemPostDataAlongLineFilter, Fem::FemPostFilter) + +FemPostDataAlongLineFilter::FemPostDataAlongLineFilter(void) : FemPostFilter() { + + ADD_PROPERTY_TYPE(Point1,(Base::Vector3d(0.0,0.0,0.0)), "DataAlongLine", App::Prop_None, "The point 1 used to define end point of line"); + ADD_PROPERTY_TYPE(Point2,(Base::Vector3d(0.0,0.0,1.0)), "DataAlongLine", App::Prop_None, "The point 2 used to define end point of line"); + ADD_PROPERTY_TYPE(Resolution,(100), "DataAlongLine", App::Prop_None, "The number of intervals between the 2 end points of line"); + ADD_PROPERTY_TYPE(XAxisData,(0), "DataAlongLine",App::Prop_None,"X axis data values used for plotting"); + ADD_PROPERTY_TYPE(YAxisData,(0), "DataAlongLine",App::Prop_None,"Y axis data values used for plotting"); + ADD_PROPERTY_TYPE(PlotData ,(""),"DataAlongLine",App::Prop_None,"Field used for plotting"); + + PlotData.setStatus(App::Property::ReadOnly, true); + XAxisData.setStatus(App::Property::ReadOnly, true); + YAxisData.setStatus(App::Property::ReadOnly, true); + + FilterPipeline clip; + + m_line = vtkSmartPointer::New(); + const Base::Vector3d& vec1 = Point1.getValue(); + m_line->SetPoint1(vec1.x, vec1.y, vec1.z); + const Base::Vector3d& vec2 = Point2.getValue(); + m_line->SetPoint2(vec2.x, vec2.y, vec2.z); + m_line->SetResolution(Resolution.getValue()); + + + m_probe = vtkSmartPointer::New(); + m_probe->SetInputConnection(m_line->GetOutputPort()); + m_probe->SetValidPointMaskArrayName("ValidPointArray"); + m_probe->SetPassPointArrays(1); + m_probe->SetPassCellArrays(1); + // needs vtk > 6.1 +#if (VTK_MAJOR_VERSION > 6) || (VTK_MINOR_VERSION > 1) + m_probe->ComputeToleranceOff(); + m_probe->SetTolerance(0.01); +#endif + + clip.filterSource = m_probe; + clip.filterTarget = m_probe; + + addFilterPipeline(clip, "DataAlongLine"); + setActiveFilterPipeline("DataAlongLine"); +} + +FemPostDataAlongLineFilter::~FemPostDataAlongLineFilter() { + +} + +DocumentObjectExecReturn* FemPostDataAlongLineFilter::execute(void) { + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + + +void FemPostDataAlongLineFilter::onChanged(const Property* prop) { + if(prop == &Point1) { + const Base::Vector3d& vec1 = Point1.getValue(); + m_line->SetPoint1(vec1.x, vec1.y, vec1.z); + } + else if(prop == &Point2) { + const Base::Vector3d& vec2 = Point2.getValue(); + m_line->SetPoint2(vec2.x, vec2.y, vec2.z); + } + else if(prop == &Resolution) { + m_line->SetResolution(Resolution.getValue()); + } + else if(prop == &PlotData) { + GetAxisData(); + } + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostDataAlongLineFilter::mustExecute(void) const { + + if(Point1.isTouched() || + Point2.isTouched() || + Resolution.isTouched()){ + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + +void FemPostDataAlongLineFilter::GetAxisData() { + + std::vector coords; + std::vector values; + + vtkSmartPointer data = m_probe->GetOutputDataObject(0); + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkDataArray* pdata = dset->GetPointData()->GetArray(PlotData.getValue()); + vtkDataArray *tcoords = dset->GetPointData()->GetTCoords("Texture Coordinates"); + + int component = 0; + + const Base::Vector3d& vec1 = Point1.getValue(); + const Base::Vector3d& vec2 = Point2.getValue(); + const Base::Vector3d diff = vec1 - vec2; + double Len = diff.Length(); + + for(int i=0; iGetNumberOfPoints(); ++i) { + + double value = 0; + if(pdata->GetNumberOfComponents() == 1) + value = pdata->GetComponent(i, component); + else { + for(int j=0; jGetNumberOfComponents(); ++j) + value += std::pow(pdata->GetComponent(i, j),2); + + value = std::sqrt(value); + } + values.push_back(value); + double tcoord = tcoords->GetComponent(i, component); + coords.push_back(tcoord*Len); + } + YAxisData.setValues(values); + XAxisData.setValues(coords); +} + +PROPERTY_SOURCE(Fem::FemPostDataAtPointFilter, Fem::FemPostFilter) + +FemPostDataAtPointFilter::FemPostDataAtPointFilter(void) : FemPostFilter() { + + ADD_PROPERTY_TYPE(Center,(Base::Vector3d(0.0,0.0,1.0)), "DataAtPoint", App::Prop_None, "The center used to define the center of the point"); + ADD_PROPERTY_TYPE(Radius,(0), "DataAtPoint", App::Prop_None, "The point 2 used to define end point of line"); + ADD_PROPERTY_TYPE(PointData,(0), "DataAtPoint",App::Prop_None,"Point data values used for plotting"); + ADD_PROPERTY_TYPE(FieldName,(""),"DataAtPoint",App::Prop_None,"Field used for plotting"); + ADD_PROPERTY_TYPE(Unit,(""),"DataAtPoint",App::Prop_None,"Unit used for Field"); + + PointData.setStatus(App::Property::ReadOnly, true); + FieldName.setStatus(App::Property::ReadOnly, true); + Unit.setStatus(App::Property::ReadOnly, true); + + FilterPipeline clip; + + m_point = vtkSmartPointer::New(); + const Base::Vector3d& vec = Center.getValue(); + m_point->SetCenter(vec.x, vec.y, vec.z); + m_point->SetRadius(0); + + m_probe = vtkSmartPointer::New(); + m_probe->SetInputConnection(m_point->GetOutputPort()); + m_probe->SetValidPointMaskArrayName("ValidPointArray"); + m_probe->SetPassPointArrays(1); + m_probe->SetPassCellArrays(1); + // needs vtk > 6.1 +#if (VTK_MAJOR_VERSION > 6) || (VTK_MINOR_VERSION > 1) + m_probe->ComputeToleranceOff(); + m_probe->SetTolerance(0.01); +#endif + + clip.filterSource = m_probe; + clip.filterTarget = m_probe; + + addFilterPipeline(clip, "DataAtPoint"); + setActiveFilterPipeline("DataAtPoint"); +} + +FemPostDataAtPointFilter::~FemPostDataAtPointFilter() { + +} + +DocumentObjectExecReturn* FemPostDataAtPointFilter::execute(void) { + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + + +void FemPostDataAtPointFilter::onChanged(const Property* prop) { + if(prop == &Center) { + const Base::Vector3d& vec = Center.getValue(); + m_point->SetCenter(vec.x, vec.y, vec.z); + } + else if(prop == &FieldName) { + GetPointData(); + } + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostDataAtPointFilter::mustExecute(void) const { + + if(Center.isTouched()){ + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + +void FemPostDataAtPointFilter::GetPointData() { + + std::vector values; + + vtkSmartPointer data = m_probe->GetOutputDataObject(0); + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkDataArray* pdata = dset->GetPointData()->GetArray(FieldName.getValue()); + + int component = 0; + + for(int i=0; iGetNumberOfPoints(); ++i) { + + double value = 0; + if(pdata->GetNumberOfComponents() == 1) + value = pdata->GetComponent(i, component); + else { + for(int j=0; jGetNumberOfComponents(); ++j) + value += std::pow(pdata->GetComponent(i, j),2); + + value = std::sqrt(value); + } + values.push_back(value); + } + PointData.setValues(values); +} + +PROPERTY_SOURCE(Fem::FemPostScalarClipFilter, Fem::FemPostFilter) + +FemPostScalarClipFilter::FemPostScalarClipFilter(void) : FemPostFilter() { + + ADD_PROPERTY_TYPE(Value, (0), "Clip", App::Prop_None, "The scalar value used to clip the selected field"); + ADD_PROPERTY_TYPE(Scalars, (long(0)), "Clip", App::Prop_None, "The field used to clip"); + ADD_PROPERTY_TYPE(InsideOut, (false), "Clip", App::Prop_None, "Invert the clip direction"); + + Value.setConstraints(&m_constraints); + + FilterPipeline clip; + m_clipper = vtkSmartPointer::New(); + clip.source = m_clipper; + clip.target = m_clipper; + addFilterPipeline(clip, "clip"); + setActiveFilterPipeline("clip"); +} + +FemPostScalarClipFilter::~FemPostScalarClipFilter() { + +} + +DocumentObjectExecReturn* FemPostScalarClipFilter::execute(void) { + + std::string val; + if(m_scalarFields.getEnums() && Scalars.getValue() >= 0) + val = Scalars.getValueAsString(); + + std::vector array; + + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) + return StdReturn; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkPointData* pd = dset->GetPointData(); + + for(int i=0; iGetNumberOfArrays(); ++i) { + if(pd->GetArray(i)->GetNumberOfComponents()==1) + array.push_back(pd->GetArrayName(i)); + } + + App::Enumeration empty; + Scalars.setValue(empty); + m_scalarFields.setEnums(array); + Scalars.setValue(m_scalarFields); + + std::vector::iterator it = std::find(array.begin(), array.end(), val); + if(!val.empty() && it != array.end()) + Scalars.setValue(val.c_str()); + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + + +void FemPostScalarClipFilter::onChanged(const Property* prop) { + + if(prop == &Value) { + m_clipper->SetValue(Value.getValue()); + } + else if(prop == &InsideOut) { + m_clipper->SetInsideOut(InsideOut.getValue()); + } + else if(prop == &Scalars && (Scalars.getValue() >= 0)) { + m_clipper->SetInputArrayToProcess(0, 0, 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, Scalars.getValueAsString() ); + setConstraintForField(); + } + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostScalarClipFilter::mustExecute(void) const { + + if(Value.isTouched() || + InsideOut.isTouched() || + Scalars.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + +void FemPostScalarClipFilter::setConstraintForField() { + + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) + return; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + + vtkDataArray* pdata = dset->GetPointData()->GetArray(Scalars.getValueAsString()); + double p[2]; + pdata->GetRange(p); + m_constraints.LowerBound = p[0]; + m_constraints.UpperBound = p[1]; + m_constraints.StepSize = (p[1]-p[0])/100.; +} + + +PROPERTY_SOURCE(Fem::FemPostWarpVectorFilter, Fem::FemPostFilter) + +FemPostWarpVectorFilter::FemPostWarpVectorFilter(void): FemPostFilter() { + + ADD_PROPERTY_TYPE(Factor, (0), "Warp", App::Prop_None, "The factor by which the vector is added to the node positions"); + ADD_PROPERTY_TYPE(Vector, (long(0)), "Warp", App::Prop_None, "The field added to the node position"); + + FilterPipeline warp; + m_warp = vtkSmartPointer::New(); + warp.source = m_warp; + warp.target = m_warp; + addFilterPipeline(warp, "warp"); + setActiveFilterPipeline("warp"); +} + +FemPostWarpVectorFilter::~FemPostWarpVectorFilter() { + +} + + +DocumentObjectExecReturn* FemPostWarpVectorFilter::execute(void) { + + std::string val; + if(m_vectorFields.getEnums() && Vector.getValue() >= 0) + val = Vector.getValueAsString(); + + std::vector array; + + vtkSmartPointer data = getInputData(); + if(!data || !data->IsA("vtkDataSet")) + return StdReturn; + + vtkDataSet* dset = vtkDataSet::SafeDownCast(data); + vtkPointData* pd = dset->GetPointData(); + + for(int i=0; iGetNumberOfArrays(); ++i) { + if(pd->GetArray(i)->GetNumberOfComponents()==3) + array.push_back(pd->GetArrayName(i)); + } + + App::Enumeration empty; + Vector.setValue(empty); + m_vectorFields.setEnums(array); + Vector.setValue(m_vectorFields); + + std::vector::iterator it = std::find(array.begin(), array.end(), val); + if(!val.empty() && it != array.end()) + Vector.setValue(val.c_str()); + + //recalculate the filter + return Fem::FemPostFilter::execute(); +} + + +void FemPostWarpVectorFilter::onChanged(const Property* prop) { + + if(prop == &Factor) { + m_warp->SetScaleFactor(Factor.getValue()); + } + else if(prop == &Vector && (Vector.getValue() >= 0)) { + m_warp->SetInputArrayToProcess(0, 0, 0, + vtkDataObject::FIELD_ASSOCIATION_POINTS, Vector.getValueAsString() ); + } + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostWarpVectorFilter::mustExecute(void) const { + + if(Factor.isTouched() || + Vector.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + + +PROPERTY_SOURCE(Fem::FemPostCutFilter, Fem::FemPostFilter) + +FemPostCutFilter::FemPostCutFilter(void) : FemPostFilter() { + + ADD_PROPERTY_TYPE(Function, (0), "Cut", App::Prop_None, "The function object which defines the clip cut function"); + + FilterPipeline clip; + m_cutter = vtkSmartPointer::New(); + clip.source = m_cutter; + clip.target = m_cutter; + addFilterPipeline(clip, "cut"); + setActiveFilterPipeline("cut"); +} + +FemPostCutFilter::~FemPostCutFilter() { + +} + +void FemPostCutFilter::onChanged(const Property* prop) { + + if(prop == &Function) { + + if(Function.getValue() && Function.getValue()->isDerivedFrom(FemPostFunction::getClassTypeId())) { + m_cutter->SetCutFunction(static_cast(Function.getValue())->getImplicitFunction()); + } + } + + Fem::FemPostFilter::onChanged(prop); +} + +short int FemPostCutFilter::mustExecute(void) const { + + if(Function.isTouched()) { + + return 1; + } + else return App::DocumentObject::mustExecute(); +} + +DocumentObjectExecReturn* FemPostCutFilter::execute(void) { + + if(!m_cutter->GetCutFunction()) + return StdReturn; + + return Fem::FemPostFilter::execute(); +} + + diff --git a/src/Mod/Fem/App/FemPostFilter.h b/src/Mod/Fem/App/FemPostFilter.h index c7be676711..578f098b82 100644 --- a/src/Mod/Fem/App/FemPostFilter.h +++ b/src/Mod/Fem/App/FemPostFilter.h @@ -1,246 +1,246 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_FemPostFilter_H -#define Fem_FemPostFilter_H - -#include "FemPostObject.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Fem -{ - -class AppFemExport FemPostFilter : public Fem::FemPostObject -{ - PROPERTY_HEADER(Fem::FemPostFilter); - -public: - /// Constructor - FemPostFilter(void); - virtual ~FemPostFilter(); - - App::PropertyLink Input; - - virtual App::DocumentObjectExecReturn* execute(void); - -protected: - vtkDataObject* getInputData(); - - //pipeline handling for derived filter - struct FilterPipeline { - vtkSmartPointer source, target; - vtkSmartPointer filterSource, filterTarget; - std::vector > algorithmStorage; - }; - - void addFilterPipeline(const FilterPipeline& p, std::string name); - void setActiveFilterPipeline(std::string name); - FilterPipeline& getFilterPipeline(std::string name); -private: - //handling of multiple pipelines which can be the filter - std::map m_pipelines; - std::string m_activePipeline; -}; - -class AppFemExport FemPostClipFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostClipFilter); - -public: - FemPostClipFilter(void); - virtual ~FemPostClipFilter(); - - App::PropertyLink Function; - App::PropertyBool InsideOut; - App::PropertyBool CutCells; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostClip"; - } - virtual short int mustExecute(void) const; - virtual App::DocumentObjectExecReturn* execute(void); - -protected: - virtual void onChanged(const App::Property* prop); - -private: - vtkSmartPointer m_clipper; - vtkSmartPointer m_extractor; -}; - -class AppFemExport FemPostDataAlongLineFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostDataAlongLineFilter); - -public: - FemPostDataAlongLineFilter(void); - virtual ~FemPostDataAlongLineFilter(); - - App::PropertyVector Point2; - App::PropertyVector Point1; - App::PropertyInteger Resolution; - App::PropertyFloatList XAxisData; - App::PropertyFloatList YAxisData; - App::PropertyString PlotData; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostDataAlongLine"; - } - virtual short int mustExecute(void) const; - -protected: - virtual App::DocumentObjectExecReturn* execute(void); - virtual void onChanged(const App::Property* prop); - void GetAxisData(); - -private: - - vtkSmartPointer m_line; - vtkSmartPointer m_probe; - -}; - -class AppFemExport FemPostDataAtPointFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostDataAtPointFilter); - -public: - FemPostDataAtPointFilter(void); - virtual ~FemPostDataAtPointFilter(); - - App::PropertyVectorDistance Center; - App::PropertyDistance Radius; - App::PropertyString FieldName; - App::PropertyFloatList PointData; - App::PropertyString Unit; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostDataAtPoint"; - } - virtual short int mustExecute(void) const; - -protected: - virtual App::DocumentObjectExecReturn* execute(void); - virtual void onChanged(const App::Property* prop); - void GetPointData(); - -private: - - vtkSmartPointer m_point; - vtkSmartPointer m_probe; - -}; - -class AppFemExport FemPostScalarClipFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostScalarClipFilter); - -public: - FemPostScalarClipFilter(void); - virtual ~FemPostScalarClipFilter(); - - App::PropertyBool InsideOut; - App::PropertyFloatConstraint Value; - App::PropertyEnumeration Scalars; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostScalarClip"; - } - virtual short int mustExecute(void) const; - -protected: - virtual App::DocumentObjectExecReturn* execute(void); - virtual void onChanged(const App::Property* prop); - void setConstraintForField(); - -private: - vtkSmartPointer m_clipper; - App::Enumeration m_scalarFields; - App::PropertyFloatConstraint::Constraints m_constraints; -}; - -class AppFemExport FemPostWarpVectorFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostWarpVectorFilter); - -public: - FemPostWarpVectorFilter(void); - virtual ~FemPostWarpVectorFilter(); - - App::PropertyFloat Factor; - App::PropertyEnumeration Vector; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostWarpVector"; - } - virtual short int mustExecute(void) const; - -protected: - virtual App::DocumentObjectExecReturn* execute(void); - virtual void onChanged(const App::Property* prop); - -private: - vtkSmartPointer m_warp; - App::Enumeration m_vectorFields; -}; - -class AppFemExport FemPostCutFilter : public FemPostFilter { - - PROPERTY_HEADER(Fem::FemPostCutFilter); - -public: - FemPostCutFilter(void); - virtual ~FemPostCutFilter(); - - App::PropertyLink Function; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostCut"; - } - virtual short int mustExecute(void) const; - virtual App::DocumentObjectExecReturn* execute(void); - -protected: - virtual void onChanged(const App::Property* prop); - -private: - vtkSmartPointer m_cutter; -}; - -} //namespace Fem - - -#endif // Fem_FemPostFilter_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_FemPostFilter_H +#define Fem_FemPostFilter_H + +#include "FemPostObject.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Fem +{ + +class AppFemExport FemPostFilter : public Fem::FemPostObject +{ + PROPERTY_HEADER(Fem::FemPostFilter); + +public: + /// Constructor + FemPostFilter(void); + virtual ~FemPostFilter(); + + App::PropertyLink Input; + + virtual App::DocumentObjectExecReturn* execute(void); + +protected: + vtkDataObject* getInputData(); + + //pipeline handling for derived filter + struct FilterPipeline { + vtkSmartPointer source, target; + vtkSmartPointer filterSource, filterTarget; + std::vector > algorithmStorage; + }; + + void addFilterPipeline(const FilterPipeline& p, std::string name); + void setActiveFilterPipeline(std::string name); + FilterPipeline& getFilterPipeline(std::string name); +private: + //handling of multiple pipelines which can be the filter + std::map m_pipelines; + std::string m_activePipeline; +}; + +class AppFemExport FemPostClipFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostClipFilter); + +public: + FemPostClipFilter(void); + virtual ~FemPostClipFilter(); + + App::PropertyLink Function; + App::PropertyBool InsideOut; + App::PropertyBool CutCells; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostClip"; + } + virtual short int mustExecute(void) const; + virtual App::DocumentObjectExecReturn* execute(void); + +protected: + virtual void onChanged(const App::Property* prop); + +private: + vtkSmartPointer m_clipper; + vtkSmartPointer m_extractor; +}; + +class AppFemExport FemPostDataAlongLineFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostDataAlongLineFilter); + +public: + FemPostDataAlongLineFilter(void); + virtual ~FemPostDataAlongLineFilter(); + + App::PropertyVector Point2; + App::PropertyVector Point1; + App::PropertyInteger Resolution; + App::PropertyFloatList XAxisData; + App::PropertyFloatList YAxisData; + App::PropertyString PlotData; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostDataAlongLine"; + } + virtual short int mustExecute(void) const; + +protected: + virtual App::DocumentObjectExecReturn* execute(void); + virtual void onChanged(const App::Property* prop); + void GetAxisData(); + +private: + + vtkSmartPointer m_line; + vtkSmartPointer m_probe; + +}; + +class AppFemExport FemPostDataAtPointFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostDataAtPointFilter); + +public: + FemPostDataAtPointFilter(void); + virtual ~FemPostDataAtPointFilter(); + + App::PropertyVectorDistance Center; + App::PropertyDistance Radius; + App::PropertyString FieldName; + App::PropertyFloatList PointData; + App::PropertyString Unit; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostDataAtPoint"; + } + virtual short int mustExecute(void) const; + +protected: + virtual App::DocumentObjectExecReturn* execute(void); + virtual void onChanged(const App::Property* prop); + void GetPointData(); + +private: + + vtkSmartPointer m_point; + vtkSmartPointer m_probe; + +}; + +class AppFemExport FemPostScalarClipFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostScalarClipFilter); + +public: + FemPostScalarClipFilter(void); + virtual ~FemPostScalarClipFilter(); + + App::PropertyBool InsideOut; + App::PropertyFloatConstraint Value; + App::PropertyEnumeration Scalars; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostScalarClip"; + } + virtual short int mustExecute(void) const; + +protected: + virtual App::DocumentObjectExecReturn* execute(void); + virtual void onChanged(const App::Property* prop); + void setConstraintForField(); + +private: + vtkSmartPointer m_clipper; + App::Enumeration m_scalarFields; + App::PropertyFloatConstraint::Constraints m_constraints; +}; + +class AppFemExport FemPostWarpVectorFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostWarpVectorFilter); + +public: + FemPostWarpVectorFilter(void); + virtual ~FemPostWarpVectorFilter(); + + App::PropertyFloat Factor; + App::PropertyEnumeration Vector; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostWarpVector"; + } + virtual short int mustExecute(void) const; + +protected: + virtual App::DocumentObjectExecReturn* execute(void); + virtual void onChanged(const App::Property* prop); + +private: + vtkSmartPointer m_warp; + App::Enumeration m_vectorFields; +}; + +class AppFemExport FemPostCutFilter : public FemPostFilter { + + PROPERTY_HEADER(Fem::FemPostCutFilter); + +public: + FemPostCutFilter(void); + virtual ~FemPostCutFilter(); + + App::PropertyLink Function; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostCut"; + } + virtual short int mustExecute(void) const; + virtual App::DocumentObjectExecReturn* execute(void); + +protected: + virtual void onChanged(const App::Property* prop); + +private: + vtkSmartPointer m_cutter; +}; + +} //namespace Fem + + +#endif // Fem_FemPostFilter_H diff --git a/src/Mod/Fem/App/FemPostFunction.cpp b/src/Mod/Fem/App/FemPostFunction.cpp index e97f5c8084..3a6b927c0a 100644 --- a/src/Mod/Fem/App/FemPostFunction.cpp +++ b/src/Mod/Fem/App/FemPostFunction.cpp @@ -1,131 +1,131 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 "FemPostFunction.h" -#include - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemPostFunctionProvider, App::DocumentObject) - -FemPostFunctionProvider::FemPostFunctionProvider(void): DocumentObject() { - - ADD_PROPERTY(Functions, (0)); -} - -FemPostFunctionProvider::~FemPostFunctionProvider() { - -} - -void FemPostFunctionProvider::onChanged(const Property* prop) { - App::DocumentObject::onChanged(prop); -} - - -PROPERTY_SOURCE(Fem::FemPostFunction, App::DocumentObject) - -FemPostFunction::FemPostFunction() -{ -} - -FemPostFunction::~FemPostFunction() -{ -} - -DocumentObjectExecReturn* FemPostFunction::execute(void) { - - return DocumentObject::StdReturn; -} - - -PROPERTY_SOURCE(Fem::FemPostPlaneFunction, Fem::FemPostFunction) - -FemPostPlaneFunction::FemPostPlaneFunction(void): FemPostFunction() { - - ADD_PROPERTY(Origin,(Base::Vector3d(0.0,0.0,0.0))); - ADD_PROPERTY(Normal,(Base::Vector3d(0.0,0.0,1.0))); - - m_plane = vtkSmartPointer::New(); - m_implicit = m_plane; - - m_plane->SetOrigin(0., 0., 0.); - m_plane->SetNormal(0., 0., 1.); -} - -FemPostPlaneFunction::~FemPostPlaneFunction() { - -} - -void FemPostPlaneFunction::onChanged(const Property* prop) { - - if(prop == &Origin) { - const Base::Vector3d& vec = Origin.getValue(); - m_plane->SetOrigin(vec[0], vec[1], vec[2]); - } - else if(prop == &Normal) { - const Base::Vector3d& vec = Normal.getValue(); - m_plane->SetNormal(vec[0], vec[1], vec[2]); - } - - Fem::FemPostFunction::onChanged(prop); -} - - - - -PROPERTY_SOURCE(Fem::FemPostSphereFunction, Fem::FemPostFunction) - -FemPostSphereFunction::FemPostSphereFunction(void): FemPostFunction() { - - ADD_PROPERTY(Radius,(5)); - ADD_PROPERTY(Center,(Base::Vector3d(1.0,0.0,0.0))); - - m_sphere = vtkSmartPointer::New(); - m_implicit = m_sphere; - - m_sphere->SetCenter(0., 0., 0.); - m_sphere->SetRadius(5); -} - -FemPostSphereFunction::~FemPostSphereFunction() { - -} - -void FemPostSphereFunction::onChanged(const Property* prop) { - - if(prop == &Center) { - const Base::Vector3d& vec = Center.getValue(); - m_sphere->SetCenter(vec[0], vec[1], vec[2]); - } - else if(prop == &Radius) { - m_sphere->SetRadius(Radius.getValue()); - } - - Fem::FemPostFunction::onChanged(prop); -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 "FemPostFunction.h" +#include + +using namespace Fem; +using namespace App; + +PROPERTY_SOURCE(Fem::FemPostFunctionProvider, App::DocumentObject) + +FemPostFunctionProvider::FemPostFunctionProvider(void): DocumentObject() { + + ADD_PROPERTY(Functions, (0)); +} + +FemPostFunctionProvider::~FemPostFunctionProvider() { + +} + +void FemPostFunctionProvider::onChanged(const Property* prop) { + App::DocumentObject::onChanged(prop); +} + + +PROPERTY_SOURCE(Fem::FemPostFunction, App::DocumentObject) + +FemPostFunction::FemPostFunction() +{ +} + +FemPostFunction::~FemPostFunction() +{ +} + +DocumentObjectExecReturn* FemPostFunction::execute(void) { + + return DocumentObject::StdReturn; +} + + +PROPERTY_SOURCE(Fem::FemPostPlaneFunction, Fem::FemPostFunction) + +FemPostPlaneFunction::FemPostPlaneFunction(void): FemPostFunction() { + + ADD_PROPERTY(Origin,(Base::Vector3d(0.0,0.0,0.0))); + ADD_PROPERTY(Normal,(Base::Vector3d(0.0,0.0,1.0))); + + m_plane = vtkSmartPointer::New(); + m_implicit = m_plane; + + m_plane->SetOrigin(0., 0., 0.); + m_plane->SetNormal(0., 0., 1.); +} + +FemPostPlaneFunction::~FemPostPlaneFunction() { + +} + +void FemPostPlaneFunction::onChanged(const Property* prop) { + + if(prop == &Origin) { + const Base::Vector3d& vec = Origin.getValue(); + m_plane->SetOrigin(vec[0], vec[1], vec[2]); + } + else if(prop == &Normal) { + const Base::Vector3d& vec = Normal.getValue(); + m_plane->SetNormal(vec[0], vec[1], vec[2]); + } + + Fem::FemPostFunction::onChanged(prop); +} + + + + +PROPERTY_SOURCE(Fem::FemPostSphereFunction, Fem::FemPostFunction) + +FemPostSphereFunction::FemPostSphereFunction(void): FemPostFunction() { + + ADD_PROPERTY(Radius,(5)); + ADD_PROPERTY(Center,(Base::Vector3d(1.0,0.0,0.0))); + + m_sphere = vtkSmartPointer::New(); + m_implicit = m_sphere; + + m_sphere->SetCenter(0., 0., 0.); + m_sphere->SetRadius(5); +} + +FemPostSphereFunction::~FemPostSphereFunction() { + +} + +void FemPostSphereFunction::onChanged(const Property* prop) { + + if(prop == &Center) { + const Base::Vector3d& vec = Center.getValue(); + m_sphere->SetCenter(vec[0], vec[1], vec[2]); + } + else if(prop == &Radius) { + m_sphere->SetRadius(Radius.getValue()); + } + + Fem::FemPostFunction::onChanged(prop); +} diff --git a/src/Mod/Fem/App/FemPostFunction.h b/src/Mod/Fem/App/FemPostFunction.h index 6b7141927c..a2ca7c404a 100644 --- a/src/Mod/Fem/App/FemPostFunction.h +++ b/src/Mod/Fem/App/FemPostFunction.h @@ -1,135 +1,135 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_FemPostFunction_H -#define Fem_FemPostFunction_H - -#include "FemPostObject.h" -#include - -#include -#include -#include -#include -#include - -namespace Fem -{ - -class AppFemExport FemPostFunction : public App::DocumentObject -{ - PROPERTY_HEADER(Fem::FemPostFunction); - -public: - /// Constructor - FemPostFunction(void); - virtual ~FemPostFunction(); - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostFunction"; - } - - virtual App::DocumentObjectExecReturn* execute(void); - - //bound box handling - void setBoundingBox(vtkBoundingBox b) {m_boundingBox = b;}; - - //get the algorithm or the data - vtkSmartPointer getImplicitFunction() {return m_implicit;}; - -protected: - vtkSmartPointer m_implicit; - vtkBoundingBox m_boundingBox; -}; - -class AppFemExport FemPostFunctionProvider : public App::DocumentObject { - - PROPERTY_HEADER(Fem::FemPostFunctionProvider); - -public: - FemPostFunctionProvider(void); - virtual ~FemPostFunctionProvider(); - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostFunctionProvider"; - } - - App::PropertyLinkList Functions; - -protected: - virtual void onChanged(const App::Property* prop); -}; - - -// --------------------------------------------------------------------------- - -class AppFemExport FemPostPlaneFunction : public FemPostFunction -{ - PROPERTY_HEADER(Fem::FemPostPlaneFunction); - -public: - - FemPostPlaneFunction(void); - virtual ~FemPostPlaneFunction(); - - App::PropertyVector Normal; - App::PropertyVectorDistance Origin; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostPlaneFunction"; - } - -protected: - virtual void onChanged(const App::Property* prop); - - vtkSmartPointer m_plane; -}; - -// --------------------------------------------------------------------------- - -class AppFemExport FemPostSphereFunction : public FemPostFunction -{ - PROPERTY_HEADER(Fem::FemPostSphereFunction); - -public: - - FemPostSphereFunction(void); - virtual ~FemPostSphereFunction(); - - App::PropertyDistance Radius; - App::PropertyVectorDistance Center; - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostSphereFunction"; - } - -protected: - virtual void onChanged(const App::Property* prop); - - vtkSmartPointer m_sphere; -}; - -} //namespace Fem - - -#endif // Fem_FemPostFunction_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_FemPostFunction_H +#define Fem_FemPostFunction_H + +#include "FemPostObject.h" +#include + +#include +#include +#include +#include +#include + +namespace Fem +{ + +class AppFemExport FemPostFunction : public App::DocumentObject +{ + PROPERTY_HEADER(Fem::FemPostFunction); + +public: + /// Constructor + FemPostFunction(void); + virtual ~FemPostFunction(); + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostFunction"; + } + + virtual App::DocumentObjectExecReturn* execute(void); + + //bound box handling + void setBoundingBox(vtkBoundingBox b) {m_boundingBox = b;}; + + //get the algorithm or the data + vtkSmartPointer getImplicitFunction() {return m_implicit;}; + +protected: + vtkSmartPointer m_implicit; + vtkBoundingBox m_boundingBox; +}; + +class AppFemExport FemPostFunctionProvider : public App::DocumentObject { + + PROPERTY_HEADER(Fem::FemPostFunctionProvider); + +public: + FemPostFunctionProvider(void); + virtual ~FemPostFunctionProvider(); + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostFunctionProvider"; + } + + App::PropertyLinkList Functions; + +protected: + virtual void onChanged(const App::Property* prop); +}; + + +// --------------------------------------------------------------------------- + +class AppFemExport FemPostPlaneFunction : public FemPostFunction +{ + PROPERTY_HEADER(Fem::FemPostPlaneFunction); + +public: + + FemPostPlaneFunction(void); + virtual ~FemPostPlaneFunction(); + + App::PropertyVector Normal; + App::PropertyVectorDistance Origin; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostPlaneFunction"; + } + +protected: + virtual void onChanged(const App::Property* prop); + + vtkSmartPointer m_plane; +}; + +// --------------------------------------------------------------------------- + +class AppFemExport FemPostSphereFunction : public FemPostFunction +{ + PROPERTY_HEADER(Fem::FemPostSphereFunction); + +public: + + FemPostSphereFunction(void); + virtual ~FemPostSphereFunction(); + + App::PropertyDistance Radius; + App::PropertyVectorDistance Center; + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostSphereFunction"; + } + +protected: + virtual void onChanged(const App::Property* prop); + + vtkSmartPointer m_sphere; +}; + +} //namespace Fem + + +#endif // Fem_FemPostFunction_H diff --git a/src/Mod/Fem/App/FemPostObject.cpp b/src/Mod/Fem/App/FemPostObject.cpp index 21c7d01371..02b9abf026 100644 --- a/src/Mod/Fem/App/FemPostObject.cpp +++ b/src/Mod/Fem/App/FemPostObject.cpp @@ -1,63 +1,63 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -#endif - -#include "FemPostObject.h" -#include -#include -#include -#include - - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemPostObject, App::GeoFeature) - - -FemPostObject::FemPostObject() -{ - ADD_PROPERTY(Data,(0)); -} - -FemPostObject::~FemPostObject() -{ -} - -vtkBoundingBox FemPostObject::getBoundingBox() { - - vtkBoundingBox box; - - if(Data.getValue() && Data.getValue()->IsA("vtkDataSet")) - box.AddBounds(vtkDataSet::SafeDownCast(Data.getValue())->GetBounds()); - - //TODO: add calculation of multiblock and Multipiece datasets - - return box; -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +#endif + +#include "FemPostObject.h" +#include +#include +#include +#include + + +using namespace Fem; +using namespace App; + +PROPERTY_SOURCE(Fem::FemPostObject, App::GeoFeature) + + +FemPostObject::FemPostObject() +{ + ADD_PROPERTY(Data,(0)); +} + +FemPostObject::~FemPostObject() +{ +} + +vtkBoundingBox FemPostObject::getBoundingBox() { + + vtkBoundingBox box; + + if(Data.getValue() && Data.getValue()->IsA("vtkDataSet")) + box.AddBounds(vtkDataSet::SafeDownCast(Data.getValue())->GetBounds()); + + //TODO: add calculation of multiblock and Multipiece datasets + + return box; +} diff --git a/src/Mod/Fem/App/FemPostObject.h b/src/Mod/Fem/App/FemPostObject.h index bb0547b21f..d80b649d66 100644 --- a/src/Mod/Fem/App/FemPostObject.h +++ b/src/Mod/Fem/App/FemPostObject.h @@ -1,53 +1,53 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_FemPostObject_H -#define Fem_FemPostObject_H - -#include -#include "PropertyPostDataObject.h" -#include - - -namespace Fem -{ - -//poly data is the only data we can visualize, hence every post processing object needs to expose it -class AppFemExport FemPostObject : public App::GeoFeature -{ - PROPERTY_HEADER(Fem::FemPostObject); - -public: - /// Constructor - FemPostObject(void); - virtual ~FemPostObject(); - - Fem::PropertyPostDataObject Data; - - vtkBoundingBox getBoundingBox(); -}; - -} //namespace Fem - - -#endif // Fem_FemPostObject_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_FemPostObject_H +#define Fem_FemPostObject_H + +#include +#include "PropertyPostDataObject.h" +#include + + +namespace Fem +{ + +//poly data is the only data we can visualize, hence every post processing object needs to expose it +class AppFemExport FemPostObject : public App::GeoFeature +{ + PROPERTY_HEADER(Fem::FemPostObject); + +public: + /// Constructor + FemPostObject(void); + virtual ~FemPostObject(); + + Fem::PropertyPostDataObject Data; + + vtkBoundingBox getBoundingBox(); +}; + +} //namespace Fem + + +#endif // Fem_FemPostObject_H diff --git a/src/Mod/Fem/App/FemPostPipeline.cpp b/src/Mod/Fem/App/FemPostPipeline.cpp index fa435f6658..01249cd35f 100644 --- a/src/Mod/Fem/App/FemPostPipeline.cpp +++ b/src/Mod/Fem/App/FemPostPipeline.cpp @@ -1,275 +1,275 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include "FemPostPipeline.h" -#include "FemMesh.h" -#include "FemMeshObject.h" -#include "FemVTKTools.h" - -#include -#include - -#include -#include - - -using namespace Fem; -using namespace App; - -PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject) -const char* FemPostPipeline::ModeEnums[]= {"Serial","Parallel",NULL}; - -FemPostPipeline::FemPostPipeline() -{ - ADD_PROPERTY_TYPE(Filter, (0), "Pipeline", App::Prop_None, "The filter used in in this pipeline"); - ADD_PROPERTY_TYPE(Functions, (0), "Pipeline", App::Prop_Hidden, "The function provider which groups all pipeline functions"); - ADD_PROPERTY_TYPE(Mode,(long(0)), "Pipeline", App::Prop_None, "Selects the pipeline data transition mode. In serial every filter" - "gets the output of the previous one as input, in parallel every" - "filter gets the pipelien source as input."); - Mode.setEnums(ModeEnums); -} - -FemPostPipeline::~FemPostPipeline() -{ -} - -short FemPostPipeline::mustExecute(void) const -{ - if(Mode.isTouched()) - return 1; - - return FemPostFilter::mustExecute(); -} - -DocumentObjectExecReturn* FemPostPipeline::execute(void) { - - //if we are the toplevel pipeline our data object is not created by filters, we are the main source! - if(!Input.getValue()) - return StdReturn; - - //now if we are a filter than our data object is created by the filter we hold - - //if we are in serial mode we just copy over the data of the last filter, - //but if we are in parallel we need to combine all filter results - if(Mode.getValue() == 0) { - - //serial - Data.setValue(getLastPostObject()->Data.getValue()); - } - else { - - //parallel. go through all filters and append the result - const std::vector& filters = Filter.getValues(); - std::vector::const_iterator it = filters.begin(); - - vtkSmartPointer append = vtkSmartPointer::New(); - for(;it != filters.end(); ++it) { - - append->AddInputDataObject(static_cast(*it)->Data.getValue()); - } - - append->Update(); - Data.setValue(append->GetOutputDataObject(0)); - } - - - return Fem::FemPostObject::execute(); -} - - -bool FemPostPipeline::canRead(Base::FileInfo File) { - - if (File.hasExtension("vtk") || - // from FemResult only unstructural mesh is supported in femvtktoools.cpp - File.hasExtension("vtp") || - File.hasExtension("vts") || - File.hasExtension("vtr") || - File.hasExtension("vti") || - File.hasExtension("vtu")) - return true; - - return false; -} - -void FemPostPipeline::read(Base::FileInfo File) { - - // checking on the file - if (!File.isReadable()) - throw Base::FileException("File to load not existing or not readable", File); - - if (File.hasExtension("vtu")) - readXMLFile(File.filePath()); - else if (File.hasExtension("vtp")) - readXMLFile(File.filePath()); - else if (File.hasExtension("vts")) - readXMLFile(File.filePath()); - else if (File.hasExtension("vtr")) - readXMLFile(File.filePath()); - else if (File.hasExtension("vti")) - readXMLFile(File.filePath()); - else if (File.hasExtension("vtk")) - readXMLFile(File.filePath()); - else - throw Base::FileException("Unknown extension"); -} - - -// PyObject *FemPostPipeline::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); -// } - -void FemPostPipeline::onChanged(const Property* prop) -{ - if(prop == &Filter || prop == &Mode) { - - //we check if all connections are right and add new ones if needed - std::vector objs = Filter.getValues(); - - if(objs.empty()) - return; - - std::vector::iterator it = objs.begin(); - FemPostFilter* filter = static_cast(*it); - - //If we have a Input we need to ensure our filters are connected correctly - if(Input.getValue()) { - - //the first filter is always connected to the input - if(filter->Input.getValue() != Input.getValue()) - filter->Input.setValue(Input.getValue()); - - //all the others need to be connected to the previous filter or the source, dependent on the mode - ++it; - for(; it != objs.end(); ++it) { - FemPostFilter* nextFilter = static_cast(*it); - - if(Mode.getValue() == 0) { //serial mode - if( nextFilter->Input.getValue() != filter) - nextFilter->Input.setValue(filter); - } - else { //Parallel mode - if( nextFilter->Input.getValue() != Input.getValue()) - nextFilter->Input.setValue(Input.getValue()); - } - - filter = nextFilter; - }; - } - //if we have no input the filters are responsible of grabbing the pipeline data themself - else { - //the first filter must always grab the data - if(filter->Input.getValue() != NULL) - filter->Input.setValue(NULL); - - //all the others need to be connected to the previous filter or grab the data, dependent on mode - ++it; - for(; it != objs.end(); ++it) { - FemPostFilter* nextFilter = static_cast(*it); - - if(Mode.getValue() == 0) { //serial mode - if( nextFilter->Input.getValue() != filter) - nextFilter->Input.setValue(filter); - } - else { //Parallel mode - if( nextFilter->Input.getValue() != NULL) - nextFilter->Input.setValue(NULL); - } - - filter = nextFilter; - }; - } - } - - App::GeoFeature::onChanged(prop); - -} - -FemPostObject* FemPostPipeline::getLastPostObject() { - - if(Filter.getValues().empty()) - return this; - - return static_cast(Filter.getValues().back()); -} - -bool FemPostPipeline::holdsPostObject(FemPostObject* obj) { - - std::vector::const_iterator it = Filter.getValues().begin(); - for(; it != Filter.getValues().end(); ++it) { - - if(*it == obj) - return true; - } - return false; -} - -void FemPostPipeline::load(FemResultObject* res) { - if(!res->Mesh.getValue() || !res->Mesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) { - Base::Console().Warning("Mesh of result object is empty or not derived from Fem::FemMeshObject\n"); - return; - } - - //first copy the mesh over - // *************************** - const FemMesh& mesh = static_cast(res->Mesh.getValue())->FemMesh.getValue(); - vtkSmartPointer grid = vtkSmartPointer::New(); - FemVTKTools::exportVTKMesh(&mesh, grid); - - //Now copy the point data over - // *************************** - FemVTKTools::exportFreeCADResult(res, grid); - - Data.setValue(grid); -} - -PyObject* FemPostPipeline::getPyObject(void) -{ - if (PythonObject.is(Py::_None())) { - // ref counter is set to 1 - PythonObject = Py::Object(new FemPostPipelinePy(this),true); - } - return Py::new_reference_to(PythonObject); -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "FemPostPipeline.h" +#include "FemMesh.h" +#include "FemMeshObject.h" +#include "FemVTKTools.h" + +#include +#include + +#include +#include + + +using namespace Fem; +using namespace App; + +PROPERTY_SOURCE(Fem::FemPostPipeline, Fem::FemPostObject) +const char* FemPostPipeline::ModeEnums[]= {"Serial","Parallel",NULL}; + +FemPostPipeline::FemPostPipeline() +{ + ADD_PROPERTY_TYPE(Filter, (0), "Pipeline", App::Prop_None, "The filter used in in this pipeline"); + ADD_PROPERTY_TYPE(Functions, (0), "Pipeline", App::Prop_Hidden, "The function provider which groups all pipeline functions"); + ADD_PROPERTY_TYPE(Mode,(long(0)), "Pipeline", App::Prop_None, "Selects the pipeline data transition mode. In serial every filter" + "gets the output of the previous one as input, in parallel every" + "filter gets the pipelien source as input."); + Mode.setEnums(ModeEnums); +} + +FemPostPipeline::~FemPostPipeline() +{ +} + +short FemPostPipeline::mustExecute(void) const +{ + if(Mode.isTouched()) + return 1; + + return FemPostFilter::mustExecute(); +} + +DocumentObjectExecReturn* FemPostPipeline::execute(void) { + + //if we are the toplevel pipeline our data object is not created by filters, we are the main source! + if(!Input.getValue()) + return StdReturn; + + //now if we are a filter than our data object is created by the filter we hold + + //if we are in serial mode we just copy over the data of the last filter, + //but if we are in parallel we need to combine all filter results + if(Mode.getValue() == 0) { + + //serial + Data.setValue(getLastPostObject()->Data.getValue()); + } + else { + + //parallel. go through all filters and append the result + const std::vector& filters = Filter.getValues(); + std::vector::const_iterator it = filters.begin(); + + vtkSmartPointer append = vtkSmartPointer::New(); + for(;it != filters.end(); ++it) { + + append->AddInputDataObject(static_cast(*it)->Data.getValue()); + } + + append->Update(); + Data.setValue(append->GetOutputDataObject(0)); + } + + + return Fem::FemPostObject::execute(); +} + + +bool FemPostPipeline::canRead(Base::FileInfo File) { + + if (File.hasExtension("vtk") || + // from FemResult only unstructural mesh is supported in femvtktoools.cpp + File.hasExtension("vtp") || + File.hasExtension("vts") || + File.hasExtension("vtr") || + File.hasExtension("vti") || + File.hasExtension("vtu")) + return true; + + return false; +} + +void FemPostPipeline::read(Base::FileInfo File) { + + // checking on the file + if (!File.isReadable()) + throw Base::FileException("File to load not existing or not readable", File); + + if (File.hasExtension("vtu")) + readXMLFile(File.filePath()); + else if (File.hasExtension("vtp")) + readXMLFile(File.filePath()); + else if (File.hasExtension("vts")) + readXMLFile(File.filePath()); + else if (File.hasExtension("vtr")) + readXMLFile(File.filePath()); + else if (File.hasExtension("vti")) + readXMLFile(File.filePath()); + else if (File.hasExtension("vtk")) + readXMLFile(File.filePath()); + else + throw Base::FileException("Unknown extension"); +} + + +// PyObject *FemPostPipeline::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); +// } + +void FemPostPipeline::onChanged(const Property* prop) +{ + if(prop == &Filter || prop == &Mode) { + + //we check if all connections are right and add new ones if needed + std::vector objs = Filter.getValues(); + + if(objs.empty()) + return; + + std::vector::iterator it = objs.begin(); + FemPostFilter* filter = static_cast(*it); + + //If we have a Input we need to ensure our filters are connected correctly + if(Input.getValue()) { + + //the first filter is always connected to the input + if(filter->Input.getValue() != Input.getValue()) + filter->Input.setValue(Input.getValue()); + + //all the others need to be connected to the previous filter or the source, dependent on the mode + ++it; + for(; it != objs.end(); ++it) { + FemPostFilter* nextFilter = static_cast(*it); + + if(Mode.getValue() == 0) { //serial mode + if( nextFilter->Input.getValue() != filter) + nextFilter->Input.setValue(filter); + } + else { //Parallel mode + if( nextFilter->Input.getValue() != Input.getValue()) + nextFilter->Input.setValue(Input.getValue()); + } + + filter = nextFilter; + }; + } + //if we have no input the filters are responsible of grabbing the pipeline data themself + else { + //the first filter must always grab the data + if(filter->Input.getValue() != NULL) + filter->Input.setValue(NULL); + + //all the others need to be connected to the previous filter or grab the data, dependent on mode + ++it; + for(; it != objs.end(); ++it) { + FemPostFilter* nextFilter = static_cast(*it); + + if(Mode.getValue() == 0) { //serial mode + if( nextFilter->Input.getValue() != filter) + nextFilter->Input.setValue(filter); + } + else { //Parallel mode + if( nextFilter->Input.getValue() != NULL) + nextFilter->Input.setValue(NULL); + } + + filter = nextFilter; + }; + } + } + + App::GeoFeature::onChanged(prop); + +} + +FemPostObject* FemPostPipeline::getLastPostObject() { + + if(Filter.getValues().empty()) + return this; + + return static_cast(Filter.getValues().back()); +} + +bool FemPostPipeline::holdsPostObject(FemPostObject* obj) { + + std::vector::const_iterator it = Filter.getValues().begin(); + for(; it != Filter.getValues().end(); ++it) { + + if(*it == obj) + return true; + } + return false; +} + +void FemPostPipeline::load(FemResultObject* res) { + if(!res->Mesh.getValue() || !res->Mesh.getValue()->isDerivedFrom(Fem::FemMeshObject::getClassTypeId())) { + Base::Console().Warning("Mesh of result object is empty or not derived from Fem::FemMeshObject\n"); + return; + } + + //first copy the mesh over + // *************************** + const FemMesh& mesh = static_cast(res->Mesh.getValue())->FemMesh.getValue(); + vtkSmartPointer grid = vtkSmartPointer::New(); + FemVTKTools::exportVTKMesh(&mesh, grid); + + //Now copy the point data over + // *************************** + FemVTKTools::exportFreeCADResult(res, grid); + + Data.setValue(grid); +} + +PyObject* FemPostPipeline::getPyObject(void) +{ + if (PythonObject.is(Py::_None())) { + // ref counter is set to 1 + PythonObject = Py::Object(new FemPostPipelinePy(this),true); + } + return Py::new_reference_to(PythonObject); +} diff --git a/src/Mod/Fem/App/FemPostPipeline.h b/src/Mod/Fem/App/FemPostPipeline.h index 1e77771781..959b1b52a8 100644 --- a/src/Mod/Fem/App/FemPostPipeline.h +++ b/src/Mod/Fem/App/FemPostPipeline.h @@ -1,88 +1,88 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_FemPostPipeline_H -#define Fem_FemPostPipeline_H - -#include "FemPostObject.h" -#include "FemPostFilter.h" -#include "FemPostFunction.h" -#include "FemResultObject.h" - -#include -#include - -namespace Fem -{ - -class AppFemExport FemPostPipeline : public Fem::FemPostFilter -{ - PROPERTY_HEADER(Fem::FemPostPipeline); - -public: - /// Constructor - FemPostPipeline(void); - virtual ~FemPostPipeline(); - - App::PropertyLinkList Filter; - App::PropertyLink Functions; - App::PropertyEnumeration Mode; - - short mustExecute(void) const; - virtual App::DocumentObjectExecReturn* execute(void); - PyObject* getPyObject(); - - virtual const char* getViewProviderName(void) const { - return "FemGui::ViewProviderFemPostPipeline"; - } - - //load data from files - static bool canRead(Base::FileInfo file); - void read(Base::FileInfo file); - - //load from results - void load(FemResultObject* res); - - //Pipeline handling - FemPostObject* getLastPostObject(); - bool holdsPostObject(FemPostObject* obj); - -protected: - virtual void onChanged(const App::Property* prop); - -private: - static const char* ModeEnums[]; - - template void readXMLFile(std::string file) { - - vtkSmartPointer reader = vtkSmartPointer::New(); - reader->SetFileName(file.c_str()); - reader->Update(); - Data.setValue(reader->GetOutput()); - } -}; - -} //namespace Fem - - -#endif // Fem_FemPostPipeline_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_FemPostPipeline_H +#define Fem_FemPostPipeline_H + +#include "FemPostObject.h" +#include "FemPostFilter.h" +#include "FemPostFunction.h" +#include "FemResultObject.h" + +#include +#include + +namespace Fem +{ + +class AppFemExport FemPostPipeline : public Fem::FemPostFilter +{ + PROPERTY_HEADER(Fem::FemPostPipeline); + +public: + /// Constructor + FemPostPipeline(void); + virtual ~FemPostPipeline(); + + App::PropertyLinkList Filter; + App::PropertyLink Functions; + App::PropertyEnumeration Mode; + + short mustExecute(void) const; + virtual App::DocumentObjectExecReturn* execute(void); + PyObject* getPyObject(); + + virtual const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemPostPipeline"; + } + + //load data from files + static bool canRead(Base::FileInfo file); + void read(Base::FileInfo file); + + //load from results + void load(FemResultObject* res); + + //Pipeline handling + FemPostObject* getLastPostObject(); + bool holdsPostObject(FemPostObject* obj); + +protected: + virtual void onChanged(const App::Property* prop); + +private: + static const char* ModeEnums[]; + + template void readXMLFile(std::string file) { + + vtkSmartPointer reader = vtkSmartPointer::New(); + reader->SetFileName(file.c_str()); + reader->Update(); + Data.setValue(reader->GetOutput()); + } +}; + +} //namespace Fem + + +#endif // Fem_FemPostPipeline_H diff --git a/src/Mod/Fem/App/PropertyPostDataObject.cpp b/src/Mod/Fem/App/PropertyPostDataObject.cpp index d655b52e38..128ba86d92 100644 --- a/src/Mod/Fem/App/PropertyPostDataObject.cpp +++ b/src/Mod/Fem/App/PropertyPostDataObject.cpp @@ -1,358 +1,358 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -#endif - -#include -#include -#include -#include -#include -#include - -#include "PropertyPostDataObject.h" - -#ifndef _PreComp_ - -#endif - -using namespace Fem; - -TYPESYSTEM_SOURCE(Fem::PropertyPostDataObject , App::Property) - -PropertyPostDataObject::PropertyPostDataObject() -{ -} - -PropertyPostDataObject::~PropertyPostDataObject() -{ -} - -void PropertyPostDataObject::setValue(const vtkSmartPointer& ds) -{ - aboutToSetValue(); - - if(ds) { - createDataObjectByExternalType(ds); - m_dataObject->DeepCopy(ds); - } - else - m_dataObject = NULL; - - hasSetValue(); -} - -const vtkSmartPointer& PropertyPostDataObject::getValue(void)const -{ - return m_dataObject; -} - -bool PropertyPostDataObject::isComposite() { - - return m_dataObject && !m_dataObject->IsA("vtkDataSet"); -} - -bool PropertyPostDataObject::isDataSet() { - - return m_dataObject && m_dataObject->IsA("vtkDataSet"); -} - -int PropertyPostDataObject::getDataType() { - - if(!m_dataObject) - return -1; - - return m_dataObject->GetDataObjectType(); -} - - - -PyObject *PropertyPostDataObject::getPyObject(void) -{ - //TODO: fetch the vtk python object from the data set and return it - return new PyObject(); -} - -void PropertyPostDataObject::setPyObject(PyObject * /*value*/) -{ -} - -App::Property *PropertyPostDataObject::Copy(void) const -{ - PropertyPostDataObject *prop = new PropertyPostDataObject(); - if (m_dataObject) { - - prop->createDataObjectByExternalType(m_dataObject); - prop->m_dataObject->DeepCopy(m_dataObject); - } - - return prop; -} - -void PropertyPostDataObject::createDataObjectByExternalType(vtkSmartPointer< vtkDataObject > ex) { - - switch( ex->GetDataObjectType() ) { - - case VTK_POLY_DATA: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_STRUCTURED_GRID: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_RECTILINEAR_GRID: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_UNSTRUCTURED_GRID: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_UNIFORM_GRID: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_COMPOSITE_DATA_SET: - m_dataObject = vtkCompositeDataSet::New(); - break; - case VTK_MULTIBLOCK_DATA_SET: - m_dataObject = vtkSmartPointer::New(); - break; - case VTK_MULTIPIECE_DATA_SET: - m_dataObject = vtkSmartPointer::New(); - break; - default: - break; - }; -} - - -void PropertyPostDataObject::Paste(const App::Property &from) -{ - aboutToSetValue(); - m_dataObject = dynamic_cast(from).m_dataObject; - hasSetValue(); -} - -unsigned int PropertyPostDataObject::getMemSize (void) const -{ - return m_dataObject->GetActualMemorySize(); -} - -void PropertyPostDataObject::getPaths(std::vector & /*paths*/) const -{ -// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) -// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("ShapeType"))); -// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) -// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Orientation"))); -// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) -// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Length"))); -// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) -// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Area"))); -// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) -// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Volume"))); -} - -void PropertyPostDataObject::Save (Base::Writer &writer) const -{ - std::string extension; - if(!m_dataObject) - return; - - switch( m_dataObject->GetDataObjectType() ) { - - case VTK_POLY_DATA: - extension = "vtp"; - break; - case VTK_STRUCTURED_GRID: - extension = "vts"; - break; - case VTK_RECTILINEAR_GRID: - extension = "vtr"; - break; - case VTK_UNSTRUCTURED_GRID: - extension = "vtu"; - break; - case VTK_UNIFORM_GRID: - extension = "vti"; //image data - break; - //TODO:multi-datasets use multiple files, this needs to be implemented specially -// case VTK_COMPOSITE_DATA_SET: -// prop->m_dataObject = vtkCompositeDataSet::New(); -// break; -// case VTK_MULTIBLOCK_DATA_SET: -// prop->m_dataObject = vtkMultiBlockDataSet::New(); -// break; -// case VTK_MULTIPIECE_DATA_SET: -// prop->m_dataObject = vtkMultiPieceDataSet::New(); -// break; - default: - break; - }; - - if(!writer.isForceXML()) { - std::string file = "Data." + extension; - writer.Stream() << writer.ind() << "" << std::endl; - } -} - -void PropertyPostDataObject::Restore(Base::XMLReader &reader) -{ - reader.readElement("Data"); - if(!reader.hasAttribute("file")) - return; - - std::string file (reader.getAttribute("file") ); - - if (!file.empty()) { - // initiate a file read - reader.addFile(file.c_str(),this); - } -} - -void PropertyPostDataObject::SaveDocFile (Base::Writer &writer) const -{ - // If the shape is empty we simply store nothing. The file size will be 0 which - // can be checked when reading in the data. - if (!m_dataObject) - return; - - // create a temporary file and copy the content to the zip stream - // once the tmp. filename is known use always the same because otherwise - // we may run into some problems on the Linux platform - static Base::FileInfo fi(App::Application::getTempFileName()); - - vtkSmartPointer xmlWriter = vtkSmartPointer::New(); - xmlWriter->SetInputDataObject(m_dataObject); - xmlWriter->SetFileName(fi.filePath().c_str()); - xmlWriter->SetDataModeToBinary(); - - if ( xmlWriter->Write() != 1 ) { - // Note: Do NOT throw an exception here because if the tmp. file could - // not be created we should not abort. - // We only print an error message but continue writing the next files to the - // stream... - App::PropertyContainer* father = this->getContainer(); - if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - App::DocumentObject* obj = static_cast(father); - Base::Console().Error("Dataset of '%s' cannot be written to vtk file '%s'\n", - obj->Label.getValue(),fi.filePath().c_str()); - } - else { - Base::Console().Error("Cannot save vtk file '%s'\n", fi.filePath().c_str()); - } - - std::stringstream ss; - ss << "Cannot save vtk file '" << fi.filePath() << "'"; - writer.addError(ss.str()); - } - - Base::ifstream file(fi, std::ios::in | std::ios::binary); - if (file){ - std::streambuf* buf = file.rdbuf(); - writer.Stream() << buf; - } - - file.close(); - // remove temp file - fi.deleteFile(); -} - -void PropertyPostDataObject::RestoreDocFile(Base::Reader &reader) -{ - Base::FileInfo xml(reader.getFileName()); - // create a temporary file and copy the content from the zip stream - Base::FileInfo fi(App::Application::getTempFileName()); - - // read in the ASCII file and write back to the file stream - Base::ofstream file(fi, std::ios::out | std::ios::binary); - unsigned long ulSize = 0; - if (reader) { - std::streambuf* buf = file.rdbuf(); - reader >> buf; - file.flush(); - ulSize = buf->pubseekoff(0, std::ios::cur, std::ios::in); - } - file.close(); - - // Read the data from the temp file - if (ulSize > 0) { - std::string extension = xml.extension(); - - //TODO: read in of composite data structures need to be coded, including replace of "GetOutputAsDataSet()" - vtkSmartPointer xmlReader; - if(extension == "vtp") - xmlReader = vtkSmartPointer::New(); - else if (extension == "vts") - xmlReader = vtkSmartPointer::New(); - else if (extension == "vtr") - xmlReader = vtkSmartPointer::New(); - else if (extension == "vtu") - xmlReader = vtkSmartPointer::New(); - else if (extension == "vti") - xmlReader = vtkSmartPointer::New(); - - xmlReader->SetFileName(fi.filePath().c_str()); - xmlReader->Update(); - - if (!xmlReader->GetOutputAsDataSet()) { - // Note: Do NOT throw an exception here because if the tmp. created file could - // not be read it's NOT an indication for an invalid input stream 'reader'. - // We only print an error message but continue reading the next files from the - // stream... - App::PropertyContainer* father = this->getContainer(); - if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) { - App::DocumentObject* obj = static_cast(father); - Base::Console().Error("Dataset file '%s' with data of '%s' seems to be empty\n", - fi.filePath().c_str(),obj->Label.getValue()); - } - else { - Base::Console().Warning("Loaded Dataset file '%s' seems to be empty\n", fi.filePath().c_str()); - } - } - else { - aboutToSetValue(); - createDataObjectByExternalType(xmlReader->GetOutputAsDataSet()); - m_dataObject->DeepCopy(xmlReader->GetOutputAsDataSet()); - hasSetValue(); - } - } - - // delete the temp file - fi.deleteFile(); -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include +#include +#include +#include +#include +#include + +#include "PropertyPostDataObject.h" + +#ifndef _PreComp_ + +#endif + +using namespace Fem; + +TYPESYSTEM_SOURCE(Fem::PropertyPostDataObject , App::Property) + +PropertyPostDataObject::PropertyPostDataObject() +{ +} + +PropertyPostDataObject::~PropertyPostDataObject() +{ +} + +void PropertyPostDataObject::setValue(const vtkSmartPointer& ds) +{ + aboutToSetValue(); + + if(ds) { + createDataObjectByExternalType(ds); + m_dataObject->DeepCopy(ds); + } + else + m_dataObject = NULL; + + hasSetValue(); +} + +const vtkSmartPointer& PropertyPostDataObject::getValue(void)const +{ + return m_dataObject; +} + +bool PropertyPostDataObject::isComposite() { + + return m_dataObject && !m_dataObject->IsA("vtkDataSet"); +} + +bool PropertyPostDataObject::isDataSet() { + + return m_dataObject && m_dataObject->IsA("vtkDataSet"); +} + +int PropertyPostDataObject::getDataType() { + + if(!m_dataObject) + return -1; + + return m_dataObject->GetDataObjectType(); +} + + + +PyObject *PropertyPostDataObject::getPyObject(void) +{ + //TODO: fetch the vtk python object from the data set and return it + return new PyObject(); +} + +void PropertyPostDataObject::setPyObject(PyObject * /*value*/) +{ +} + +App::Property *PropertyPostDataObject::Copy(void) const +{ + PropertyPostDataObject *prop = new PropertyPostDataObject(); + if (m_dataObject) { + + prop->createDataObjectByExternalType(m_dataObject); + prop->m_dataObject->DeepCopy(m_dataObject); + } + + return prop; +} + +void PropertyPostDataObject::createDataObjectByExternalType(vtkSmartPointer< vtkDataObject > ex) { + + switch( ex->GetDataObjectType() ) { + + case VTK_POLY_DATA: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_STRUCTURED_GRID: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_RECTILINEAR_GRID: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_UNSTRUCTURED_GRID: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_UNIFORM_GRID: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_COMPOSITE_DATA_SET: + m_dataObject = vtkCompositeDataSet::New(); + break; + case VTK_MULTIBLOCK_DATA_SET: + m_dataObject = vtkSmartPointer::New(); + break; + case VTK_MULTIPIECE_DATA_SET: + m_dataObject = vtkSmartPointer::New(); + break; + default: + break; + }; +} + + +void PropertyPostDataObject::Paste(const App::Property &from) +{ + aboutToSetValue(); + m_dataObject = dynamic_cast(from).m_dataObject; + hasSetValue(); +} + +unsigned int PropertyPostDataObject::getMemSize (void) const +{ + return m_dataObject->GetActualMemorySize(); +} + +void PropertyPostDataObject::getPaths(std::vector & /*paths*/) const +{ +// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) +// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("ShapeType"))); +// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) +// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Orientation"))); +// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) +// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Length"))); +// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) +// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Area"))); +// paths.push_back(App::ObjectIdentifier(getContainer()) << App::ObjectIdentifier::Component::SimpleComponent(getName()) +// << App::ObjectIdentifier::Component::SimpleComponent(App::ObjectIdentifier::String("Volume"))); +} + +void PropertyPostDataObject::Save (Base::Writer &writer) const +{ + std::string extension; + if(!m_dataObject) + return; + + switch( m_dataObject->GetDataObjectType() ) { + + case VTK_POLY_DATA: + extension = "vtp"; + break; + case VTK_STRUCTURED_GRID: + extension = "vts"; + break; + case VTK_RECTILINEAR_GRID: + extension = "vtr"; + break; + case VTK_UNSTRUCTURED_GRID: + extension = "vtu"; + break; + case VTK_UNIFORM_GRID: + extension = "vti"; //image data + break; + //TODO:multi-datasets use multiple files, this needs to be implemented specially +// case VTK_COMPOSITE_DATA_SET: +// prop->m_dataObject = vtkCompositeDataSet::New(); +// break; +// case VTK_MULTIBLOCK_DATA_SET: +// prop->m_dataObject = vtkMultiBlockDataSet::New(); +// break; +// case VTK_MULTIPIECE_DATA_SET: +// prop->m_dataObject = vtkMultiPieceDataSet::New(); +// break; + default: + break; + }; + + if(!writer.isForceXML()) { + std::string file = "Data." + extension; + writer.Stream() << writer.ind() << "" << std::endl; + } +} + +void PropertyPostDataObject::Restore(Base::XMLReader &reader) +{ + reader.readElement("Data"); + if(!reader.hasAttribute("file")) + return; + + std::string file (reader.getAttribute("file") ); + + if (!file.empty()) { + // initiate a file read + reader.addFile(file.c_str(),this); + } +} + +void PropertyPostDataObject::SaveDocFile (Base::Writer &writer) const +{ + // If the shape is empty we simply store nothing. The file size will be 0 which + // can be checked when reading in the data. + if (!m_dataObject) + return; + + // create a temporary file and copy the content to the zip stream + // once the tmp. filename is known use always the same because otherwise + // we may run into some problems on the Linux platform + static Base::FileInfo fi(App::Application::getTempFileName()); + + vtkSmartPointer xmlWriter = vtkSmartPointer::New(); + xmlWriter->SetInputDataObject(m_dataObject); + xmlWriter->SetFileName(fi.filePath().c_str()); + xmlWriter->SetDataModeToBinary(); + + if ( xmlWriter->Write() != 1 ) { + // Note: Do NOT throw an exception here because if the tmp. file could + // not be created we should not abort. + // We only print an error message but continue writing the next files to the + // stream... + App::PropertyContainer* father = this->getContainer(); + if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* obj = static_cast(father); + Base::Console().Error("Dataset of '%s' cannot be written to vtk file '%s'\n", + obj->Label.getValue(),fi.filePath().c_str()); + } + else { + Base::Console().Error("Cannot save vtk file '%s'\n", fi.filePath().c_str()); + } + + std::stringstream ss; + ss << "Cannot save vtk file '" << fi.filePath() << "'"; + writer.addError(ss.str()); + } + + Base::ifstream file(fi, std::ios::in | std::ios::binary); + if (file){ + std::streambuf* buf = file.rdbuf(); + writer.Stream() << buf; + } + + file.close(); + // remove temp file + fi.deleteFile(); +} + +void PropertyPostDataObject::RestoreDocFile(Base::Reader &reader) +{ + Base::FileInfo xml(reader.getFileName()); + // create a temporary file and copy the content from the zip stream + Base::FileInfo fi(App::Application::getTempFileName()); + + // read in the ASCII file and write back to the file stream + Base::ofstream file(fi, std::ios::out | std::ios::binary); + unsigned long ulSize = 0; + if (reader) { + std::streambuf* buf = file.rdbuf(); + reader >> buf; + file.flush(); + ulSize = buf->pubseekoff(0, std::ios::cur, std::ios::in); + } + file.close(); + + // Read the data from the temp file + if (ulSize > 0) { + std::string extension = xml.extension(); + + //TODO: read in of composite data structures need to be coded, including replace of "GetOutputAsDataSet()" + vtkSmartPointer xmlReader; + if(extension == "vtp") + xmlReader = vtkSmartPointer::New(); + else if (extension == "vts") + xmlReader = vtkSmartPointer::New(); + else if (extension == "vtr") + xmlReader = vtkSmartPointer::New(); + else if (extension == "vtu") + xmlReader = vtkSmartPointer::New(); + else if (extension == "vti") + xmlReader = vtkSmartPointer::New(); + + xmlReader->SetFileName(fi.filePath().c_str()); + xmlReader->Update(); + + if (!xmlReader->GetOutputAsDataSet()) { + // Note: Do NOT throw an exception here because if the tmp. created file could + // not be read it's NOT an indication for an invalid input stream 'reader'. + // We only print an error message but continue reading the next files from the + // stream... + App::PropertyContainer* father = this->getContainer(); + if (father && father->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* obj = static_cast(father); + Base::Console().Error("Dataset file '%s' with data of '%s' seems to be empty\n", + fi.filePath().c_str(),obj->Label.getValue()); + } + else { + Base::Console().Warning("Loaded Dataset file '%s' seems to be empty\n", fi.filePath().c_str()); + } + } + else { + aboutToSetValue(); + createDataObjectByExternalType(xmlReader->GetOutputAsDataSet()); + m_dataObject->DeepCopy(xmlReader->GetOutputAsDataSet()); + hasSetValue(); + } + } + + // delete the temp file + fi.deleteFile(); +} diff --git a/src/Mod/Fem/App/PropertyPostDataObject.h b/src/Mod/Fem/App/PropertyPostDataObject.h index 382f44f239..b48bc64d68 100644 --- a/src/Mod/Fem/App/PropertyPostDataObject.h +++ b/src/Mod/Fem/App/PropertyPostDataObject.h @@ -1,90 +1,90 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_PROPERTYPOSTDATASET_H -#define FEM_PROPERTYPOSTDATASET_H - -#include "PreCompiled.h" - -#include -#include -#include -#include - -namespace Fem -{ - -/** The vtk data set property class. - * @author Stefan Tröger - */ -class FemExport PropertyPostDataObject : public App::Property -{ - TYPESYSTEM_HEADER(); - -public: - PropertyPostDataObject(); - ~PropertyPostDataObject(); - - /** @name Getter/setter */ - //@{ - /// set the dataset - void setValue(const vtkSmartPointer&); - /// get the part shape - const vtkSmartPointer& getValue(void) const; - /// check if we hold a dataset or a dataobject (which would mean a composite data structure) - bool isDataSet(); - bool isComposite(); - int getDataType(); - //@} - - /** @name Python interface */ - //@{ - PyObject* getPyObject(void); - void setPyObject(PyObject *value); - //@} - - /** @name Save/restore */ - //@{ - void Save (Base::Writer &writer) const; - void Restore(Base::XMLReader &reader); - - void SaveDocFile (Base::Writer &writer) const; - void RestoreDocFile(Base::Reader &reader); - - App::Property *Copy(void) const; - void Paste(const App::Property &from); - unsigned int getMemSize (void) const; - //@} - - /// Get valid paths for this property; used by auto completer - virtual void getPaths(std::vector & paths) const; - -protected: - void createDataObjectByExternalType(vtkSmartPointer ex); - vtkSmartPointer m_dataObject; -}; - -} //namespace FEM - - -#endif // FEM_PROPERTYPOSTDATASET_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_PROPERTYPOSTDATASET_H +#define FEM_PROPERTYPOSTDATASET_H + +#include "PreCompiled.h" + +#include +#include +#include +#include + +namespace Fem +{ + +/** The vtk data set property class. + * @author Stefan Tröger + */ +class FemExport PropertyPostDataObject : public App::Property +{ + TYPESYSTEM_HEADER(); + +public: + PropertyPostDataObject(); + ~PropertyPostDataObject(); + + /** @name Getter/setter */ + //@{ + /// set the dataset + void setValue(const vtkSmartPointer&); + /// get the part shape + const vtkSmartPointer& getValue(void) const; + /// check if we hold a dataset or a dataobject (which would mean a composite data structure) + bool isDataSet(); + bool isComposite(); + int getDataType(); + //@} + + /** @name Python interface */ + //@{ + PyObject* getPyObject(void); + void setPyObject(PyObject *value); + //@} + + /** @name Save/restore */ + //@{ + void Save (Base::Writer &writer) const; + void Restore(Base::XMLReader &reader); + + void SaveDocFile (Base::Writer &writer) const; + void RestoreDocFile(Base::Reader &reader); + + App::Property *Copy(void) const; + void Paste(const App::Property &from); + unsigned int getMemSize (void) const; + //@} + + /// Get valid paths for this property; used by auto completer + virtual void getPaths(std::vector & paths) const; + +protected: + void createDataObjectByExternalType(vtkSmartPointer ex); + vtkSmartPointer m_dataObject; +}; + +} //namespace FEM + + +#endif // FEM_PROPERTYPOSTDATASET_H diff --git a/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.cpp index 65b3e120f3..c7b91287bb 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.cpp @@ -1,86 +1,86 @@ -/*************************************************************************** - * Copyright (c) 2017 FreeCAD Developers * - * Author: Bernd Hahnebach * - * Based on src/Mod/Fem/Gui/DlgSettingsFemCcx.cpp * - * * - * 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/Application.h" -#include "DlgSettingsFemExportAbaqusImp.h" -#include "ui_DlgSettingsFemExportAbaqus.h" -#include - -using namespace FemGui; - -DlgSettingsFemExportAbaqusImp::DlgSettingsFemExportAbaqusImp( QWidget* parent ) - : PreferencePage( parent ), ui(new Ui_DlgSettingsFemExportAbaqus) -{ - ui->setupUi(this); -} - -/* - * Destroys the object and frees any allocated resources - */ -DlgSettingsFemExportAbaqusImp::~DlgSettingsFemExportAbaqusImp() -{ - // no need to delete child widgets, Qt does it all for us - delete ui; -} - -void DlgSettingsFemExportAbaqusImp::saveSettings() -{ - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Mod/Fem/Abaqus"); - hGrp->SetInt("AbaqusElementChoice", ui->comboBoxElemChoiceParam->currentIndex()); - - ui->comboBoxElemChoiceParam->onSave(); - ui->checkBoxWriteGroups->onSave(); -} - -void DlgSettingsFemExportAbaqusImp::loadSettings() -{ - ui->comboBoxElemChoiceParam->onRestore(); - ui->checkBoxWriteGroups->onRestore(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Mod/Fem/Abaqus"); - int index = hGrp->GetInt("AbaqusElementChoice", 0); - if (index > -1) ui->comboBoxElemChoiceParam->setCurrentIndex(index); -} - -/** - * Sets the strings of the subwidgets using the current language. - */ -void DlgSettingsFemExportAbaqusImp::changeEvent(QEvent *e) -{ - if (e->type() == QEvent::LanguageChange) { - int c_index = ui->comboBoxElemChoiceParam->currentIndex(); - ui->retranslateUi(this); - ui->comboBoxElemChoiceParam->setCurrentIndex(c_index); - } - else { - QWidget::changeEvent(e); - } -} - -#include "moc_DlgSettingsFemExportAbaqusImp.cpp" +/*************************************************************************** + * Copyright (c) 2017 FreeCAD Developers * + * Author: Bernd Hahnebach * + * Based on src/Mod/Fem/Gui/DlgSettingsFemCcx.cpp * + * * + * 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/Application.h" +#include "DlgSettingsFemExportAbaqusImp.h" +#include "ui_DlgSettingsFemExportAbaqus.h" +#include + +using namespace FemGui; + +DlgSettingsFemExportAbaqusImp::DlgSettingsFemExportAbaqusImp( QWidget* parent ) + : PreferencePage( parent ), ui(new Ui_DlgSettingsFemExportAbaqus) +{ + ui->setupUi(this); +} + +/* + * Destroys the object and frees any allocated resources + */ +DlgSettingsFemExportAbaqusImp::~DlgSettingsFemExportAbaqusImp() +{ + // no need to delete child widgets, Qt does it all for us + delete ui; +} + +void DlgSettingsFemExportAbaqusImp::saveSettings() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/Mod/Fem/Abaqus"); + hGrp->SetInt("AbaqusElementChoice", ui->comboBoxElemChoiceParam->currentIndex()); + + ui->comboBoxElemChoiceParam->onSave(); + ui->checkBoxWriteGroups->onSave(); +} + +void DlgSettingsFemExportAbaqusImp::loadSettings() +{ + ui->comboBoxElemChoiceParam->onRestore(); + ui->checkBoxWriteGroups->onRestore(); + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/Mod/Fem/Abaqus"); + int index = hGrp->GetInt("AbaqusElementChoice", 0); + if (index > -1) ui->comboBoxElemChoiceParam->setCurrentIndex(index); +} + +/** + * Sets the strings of the subwidgets using the current language. + */ +void DlgSettingsFemExportAbaqusImp::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + int c_index = ui->comboBoxElemChoiceParam->currentIndex(); + ui->retranslateUi(this); + ui->comboBoxElemChoiceParam->setCurrentIndex(c_index); + } + else { + QWidget::changeEvent(e); + } +} + +#include "moc_DlgSettingsFemExportAbaqusImp.cpp" diff --git a/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.h b/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.h index 182d461e78..2dbc784ae4 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.h +++ b/src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusImp.h @@ -1,53 +1,53 @@ -/*************************************************************************** - * Copyright (c) 2017 FreeCAD Developers * - * Author: Bernd Hahnebach * - * Based on src/Mod/Fem/Gui/DlgSettingsFemCcx.h * - * * - * 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 FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H -#define FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H - -#include - -namespace FemGui { - -class Ui_DlgSettingsFemExportAbaqus; -class DlgSettingsFemExportAbaqusImp : public Gui::Dialog::PreferencePage -{ - Q_OBJECT - -public: - DlgSettingsFemExportAbaqusImp( QWidget* parent = 0 ); - ~DlgSettingsFemExportAbaqusImp(); - -protected: - void saveSettings(); - void loadSettings(); - void changeEvent(QEvent *e); - -private: - Ui_DlgSettingsFemExportAbaqus* ui; -}; - -} // namespace FemGui - -#endif // FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H +/*************************************************************************** + * Copyright (c) 2017 FreeCAD Developers * + * Author: Bernd Hahnebach * + * Based on src/Mod/Fem/Gui/DlgSettingsFemCcx.h * + * * + * 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 FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H +#define FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H + +#include + +namespace FemGui { + +class Ui_DlgSettingsFemExportAbaqus; +class DlgSettingsFemExportAbaqusImp : public Gui::Dialog::PreferencePage +{ + Q_OBJECT + +public: + DlgSettingsFemExportAbaqusImp( QWidget* parent = 0 ); + ~DlgSettingsFemExportAbaqusImp(); + +protected: + void saveSettings(); + void loadSettings(); + void changeEvent(QEvent *e); + +private: + Ui_DlgSettingsFemExportAbaqus* ui; +}; + +} // namespace FemGui + +#endif // FEMGUI_DLGSETTINGSFEMEXPORTABAQUSIMP_H diff --git a/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.cpp b/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.cpp index e6bf2048ca..5a54298703 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.cpp +++ b/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.cpp @@ -1,85 +1,85 @@ -/************************************************************************** - * Copyright (c) 2018 FreeCAD Developers * - * Author: Bernd Hahnebach * - * Based on src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusCcxImp.cpp * - * * - * 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/Application.h" -#include "DlgSettingsFemInOutVtkImp.h" -#include "ui_DlgSettingsFemInOutVtk.h" -#include - -using namespace FemGui; - -DlgSettingsFemInOutVtkImp::DlgSettingsFemInOutVtkImp( QWidget* parent ) - : PreferencePage( parent ), ui(new Ui_DlgSettingsFemInOutVtk) -{ - ui->setupUi(this); -} - -/* - * Destroys the object and frees any allocated resources - */ -DlgSettingsFemInOutVtkImp::~DlgSettingsFemInOutVtkImp() -{ - // no need to delete child widgets, Qt does it all for us - delete ui; -} - -void DlgSettingsFemInOutVtkImp::saveSettings() -{ - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk"); - hGrp->SetInt("ImportObject", ui->comboBoxVtkImportObject->currentIndex()); - - ui->comboBoxVtkImportObject->onSave(); -} - -void DlgSettingsFemInOutVtkImp::loadSettings() -{ - ui->comboBoxVtkImportObject->onRestore(); - - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath - ("User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk"); - int index = hGrp->GetInt("ImportObject", 0); - // 0 is standard on first initialize, 0 .. vtk res obj, 1 .. FEM mesh obj, 2 .. FreeCAD res obj - if (index > -1) ui->comboBoxVtkImportObject->setCurrentIndex(index); -} - -/** - * Sets the strings of the subwidgets using the current language. - */ -void DlgSettingsFemInOutVtkImp::changeEvent(QEvent *e) -{ - if (e->type() == QEvent::LanguageChange) { - int c_index = ui->comboBoxVtkImportObject->currentIndex(); - ui->retranslateUi(this); - ui->comboBoxVtkImportObject->setCurrentIndex(c_index); - } - else { - QWidget::changeEvent(e); - } -} - -#include "moc_DlgSettingsFemInOutVtkImp.cpp" +/************************************************************************** + * Copyright (c) 2018 FreeCAD Developers * + * Author: Bernd Hahnebach * + * Based on src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusCcxImp.cpp * + * * + * 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/Application.h" +#include "DlgSettingsFemInOutVtkImp.h" +#include "ui_DlgSettingsFemInOutVtk.h" +#include + +using namespace FemGui; + +DlgSettingsFemInOutVtkImp::DlgSettingsFemInOutVtkImp( QWidget* parent ) + : PreferencePage( parent ), ui(new Ui_DlgSettingsFemInOutVtk) +{ + ui->setupUi(this); +} + +/* + * Destroys the object and frees any allocated resources + */ +DlgSettingsFemInOutVtkImp::~DlgSettingsFemInOutVtkImp() +{ + // no need to delete child widgets, Qt does it all for us + delete ui; +} + +void DlgSettingsFemInOutVtkImp::saveSettings() +{ + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk"); + hGrp->SetInt("ImportObject", ui->comboBoxVtkImportObject->currentIndex()); + + ui->comboBoxVtkImportObject->onSave(); +} + +void DlgSettingsFemInOutVtkImp::loadSettings() +{ + ui->comboBoxVtkImportObject->onRestore(); + + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath + ("User parameter:BaseApp/Preferences/Mod/Fem/InOutVtk"); + int index = hGrp->GetInt("ImportObject", 0); + // 0 is standard on first initialize, 0 .. vtk res obj, 1 .. FEM mesh obj, 2 .. FreeCAD res obj + if (index > -1) ui->comboBoxVtkImportObject->setCurrentIndex(index); +} + +/** + * Sets the strings of the subwidgets using the current language. + */ +void DlgSettingsFemInOutVtkImp::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + int c_index = ui->comboBoxVtkImportObject->currentIndex(); + ui->retranslateUi(this); + ui->comboBoxVtkImportObject->setCurrentIndex(c_index); + } + else { + QWidget::changeEvent(e); + } +} + +#include "moc_DlgSettingsFemInOutVtkImp.cpp" diff --git a/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.h b/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.h index 6c64638807..92533971d2 100644 --- a/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.h +++ b/src/Mod/Fem/Gui/DlgSettingsFemInOutVtkImp.h @@ -1,53 +1,53 @@ -/*************************************************************************** - * Copyright (c) 2018 FreeCAD Developers * - * Author: Bernd Hahnebach * - * Based on src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusCcxImp.h * - * * - * 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 FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H -#define FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H - -#include - -namespace FemGui { - -class Ui_DlgSettingsFemInOutVtk; -class DlgSettingsFemInOutVtkImp : public Gui::Dialog::PreferencePage -{ - Q_OBJECT - -public: - DlgSettingsFemInOutVtkImp( QWidget* parent = 0 ); - ~DlgSettingsFemInOutVtkImp(); - -protected: - void saveSettings(); - void loadSettings(); - void changeEvent(QEvent *e); - -private: - Ui_DlgSettingsFemInOutVtk* ui; -}; - -} // namespace FemGui - -#endif // FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H +/*************************************************************************** + * Copyright (c) 2018 FreeCAD Developers * + * Author: Bernd Hahnebach * + * Based on src/Mod/Fem/Gui/DlgSettingsFemExportAbaqusCcxImp.h * + * * + * 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 FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H +#define FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H + +#include + +namespace FemGui { + +class Ui_DlgSettingsFemInOutVtk; +class DlgSettingsFemInOutVtkImp : public Gui::Dialog::PreferencePage +{ + Q_OBJECT + +public: + DlgSettingsFemInOutVtkImp( QWidget* parent = 0 ); + ~DlgSettingsFemInOutVtkImp(); + +protected: + void saveSettings(); + void loadSettings(); + void changeEvent(QEvent *e); + +private: + Ui_DlgSettingsFemInOutVtk* ui; +}; + +} // namespace FemGui + +#endif // FEMGUI_DLGSETTINGSFEMINOUTVTKIMP_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp index 6dc831d5ea..2c4bdf0efa 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.cpp @@ -1,151 +1,151 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 "ViewProviderFemPostFilter.h" -#include "TaskPostBoxes.h" -#include -#include - -using namespace FemGui; - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostClip, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostClip::ViewProviderFemPostClip() { - - sPixmap = "fem-post-filter-clip-region"; -} - -ViewProviderFemPostClip::~ViewProviderFemPostClip() { - -} - -void ViewProviderFemPostClip::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostClip(dlg->getView(), - &static_cast(dlg->getView()->getObject())->Function)); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAlongLine, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostDataAlongLine::ViewProviderFemPostDataAlongLine() { - - sPixmap = "fem-post-filter-data-along-line"; -} - -ViewProviderFemPostDataAlongLine::~ViewProviderFemPostDataAlongLine() { - -} - -void ViewProviderFemPostDataAlongLine::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostDataAlongLine(dlg->getView())); - -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAtPoint, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostDataAtPoint::ViewProviderFemPostDataAtPoint() { - - sPixmap = "fem-post-filter-data-at-point"; -} - -ViewProviderFemPostDataAtPoint::~ViewProviderFemPostDataAtPoint() { - -} - -void ViewProviderFemPostDataAtPoint::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostDataAtPoint(dlg->getView())); - -} - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostScalarClip, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostScalarClip::ViewProviderFemPostScalarClip() { - - sPixmap = "fem-post-filter-clip-scalar"; -} - -ViewProviderFemPostScalarClip::~ViewProviderFemPostScalarClip() { - -} - -void ViewProviderFemPostScalarClip::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostScalarClip(dlg->getView())); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostWarpVector, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostWarpVector::ViewProviderFemPostWarpVector() { - - sPixmap = "fem-post-filter-warp"; -} - -ViewProviderFemPostWarpVector::~ViewProviderFemPostWarpVector() { - -} - -void ViewProviderFemPostWarpVector::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostWarpVector(dlg->getView())); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostCut, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostCut::ViewProviderFemPostCut() { - - sPixmap = "fem-post-filter-cut-function"; -} - -ViewProviderFemPostCut::~ViewProviderFemPostCut() { - -} - -void ViewProviderFemPostCut::setupTaskDialog(TaskDlgPost* dlg) { - - //add the function box - dlg->appendBox(new TaskPostCut(dlg->getView(), - &static_cast(dlg->getView()->getObject())->Function)); - - //add the display options - FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 "ViewProviderFemPostFilter.h" +#include "TaskPostBoxes.h" +#include +#include + +using namespace FemGui; + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostClip, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostClip::ViewProviderFemPostClip() { + + sPixmap = "fem-post-filter-clip-region"; +} + +ViewProviderFemPostClip::~ViewProviderFemPostClip() { + +} + +void ViewProviderFemPostClip::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostClip(dlg->getView(), + &static_cast(dlg->getView()->getObject())->Function)); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAlongLine, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostDataAlongLine::ViewProviderFemPostDataAlongLine() { + + sPixmap = "fem-post-filter-data-along-line"; +} + +ViewProviderFemPostDataAlongLine::~ViewProviderFemPostDataAlongLine() { + +} + +void ViewProviderFemPostDataAlongLine::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostDataAlongLine(dlg->getView())); + +} + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostDataAtPoint, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostDataAtPoint::ViewProviderFemPostDataAtPoint() { + + sPixmap = "fem-post-filter-data-at-point"; +} + +ViewProviderFemPostDataAtPoint::~ViewProviderFemPostDataAtPoint() { + +} + +void ViewProviderFemPostDataAtPoint::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostDataAtPoint(dlg->getView())); + +} + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostScalarClip, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostScalarClip::ViewProviderFemPostScalarClip() { + + sPixmap = "fem-post-filter-clip-scalar"; +} + +ViewProviderFemPostScalarClip::~ViewProviderFemPostScalarClip() { + +} + +void ViewProviderFemPostScalarClip::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostScalarClip(dlg->getView())); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostWarpVector, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostWarpVector::ViewProviderFemPostWarpVector() { + + sPixmap = "fem-post-filter-warp"; +} + +ViewProviderFemPostWarpVector::~ViewProviderFemPostWarpVector() { + +} + +void ViewProviderFemPostWarpVector::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostWarpVector(dlg->getView())); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostCut, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostCut::ViewProviderFemPostCut() { + + sPixmap = "fem-post-filter-cut-function"; +} + +ViewProviderFemPostCut::~ViewProviderFemPostCut() { + +} + +void ViewProviderFemPostCut::setupTaskDialog(TaskDlgPost* dlg) { + + //add the function box + dlg->appendBox(new TaskPostCut(dlg->getView(), + &static_cast(dlg->getView()->getObject())->Function)); + + //add the display options + FemGui::ViewProviderFemPostObject::setupTaskDialog(dlg); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h index f97f1bcf2f..79d3eb2374 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFilter.h @@ -1,112 +1,112 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_VIEWPROVIDERFEMPOSTFILTER_H -#define FEM_VIEWPROVIDERFEMPOSTFILTER_H - -#include "ViewProviderFemPostObject.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemPostClip : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostClip); - -public: - /// constructor. - ViewProviderFemPostClip(); - ~ViewProviderFemPostClip(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; - -class FemGuiExport ViewProviderFemPostDataAlongLine : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostDataAlongLine); - -public: - /// constructor. - ViewProviderFemPostDataAlongLine(); - ~ViewProviderFemPostDataAlongLine(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; - -class FemGuiExport ViewProviderFemPostDataAtPoint: public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostDataAtPoint); - -public: - /// constructor. - ViewProviderFemPostDataAtPoint(); - ~ViewProviderFemPostDataAtPoint(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; -class FemGuiExport ViewProviderFemPostScalarClip : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostScalarClip); - -public: - /// constructor. - ViewProviderFemPostScalarClip(); - ~ViewProviderFemPostScalarClip(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; - -class FemGuiExport ViewProviderFemPostWarpVector : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostWarpVector); - -public: - /// constructor. - ViewProviderFemPostWarpVector(); - ~ViewProviderFemPostWarpVector(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; - -class FemGuiExport ViewProviderFemPostCut : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostCut); - -public: - /// constructor. - ViewProviderFemPostCut(); - ~ViewProviderFemPostCut(); - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); -}; - -} //namespace FemGui - - -#endif // FEM_VIEWPROVIDERFEMPOSTFILTER_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_VIEWPROVIDERFEMPOSTFILTER_H +#define FEM_VIEWPROVIDERFEMPOSTFILTER_H + +#include "ViewProviderFemPostObject.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemPostClip : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostClip); + +public: + /// constructor. + ViewProviderFemPostClip(); + ~ViewProviderFemPostClip(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; + +class FemGuiExport ViewProviderFemPostDataAlongLine : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostDataAlongLine); + +public: + /// constructor. + ViewProviderFemPostDataAlongLine(); + ~ViewProviderFemPostDataAlongLine(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; + +class FemGuiExport ViewProviderFemPostDataAtPoint: public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostDataAtPoint); + +public: + /// constructor. + ViewProviderFemPostDataAtPoint(); + ~ViewProviderFemPostDataAtPoint(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; +class FemGuiExport ViewProviderFemPostScalarClip : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostScalarClip); + +public: + /// constructor. + ViewProviderFemPostScalarClip(); + ~ViewProviderFemPostScalarClip(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; + +class FemGuiExport ViewProviderFemPostWarpVector : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostWarpVector); + +public: + /// constructor. + ViewProviderFemPostWarpVector(); + ~ViewProviderFemPostWarpVector(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; + +class FemGuiExport ViewProviderFemPostCut : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostCut); + +public: + /// constructor. + ViewProviderFemPostCut(); + ~ViewProviderFemPostCut(); + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); +}; + +} //namespace FemGui + + +#endif // FEM_VIEWPROVIDERFEMPOSTFILTER_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp index a876a3b047..7bded0611b 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.cpp @@ -1,614 +1,614 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include - -# include - -# include -#endif - -#include "ViewProviderFemPostFunction.h" -#include "TaskPostBoxes.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ui_PlaneWidget.h" -#include "ui_SphereWidget.h" - -using namespace FemGui; - -void FunctionWidget::setViewProvider(ViewProviderFemPostFunction* view) { - - m_view = view; - m_object = static_cast(view->getObject()); - m_connection = m_object->getDocument()->signalChangedObject.connect(boost::bind(&FunctionWidget::onObjectsChanged, this, _1, _2)); -} - -void FunctionWidget::onObjectsChanged(const App::DocumentObject& obj, const App::Property& p) { - - if(&obj == m_object) - onChange(p); -} - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunctionProvider, Gui::ViewProviderDocumentObject) - -ViewProviderFemPostFunctionProvider::ViewProviderFemPostFunctionProvider() { - -} - -ViewProviderFemPostFunctionProvider::~ViewProviderFemPostFunctionProvider() { - -} - -std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren(void) const { - - return static_cast(getObject())->Functions.getValues(); -} - -std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren3D(void) const { - return claimChildren(); -} - -void ViewProviderFemPostFunctionProvider::onChanged(const App::Property* prop) { - Gui::ViewProviderDocumentObject::onChanged(prop); - - updateSize(); -} - -void ViewProviderFemPostFunctionProvider::updateData(const App::Property* prop) { - Gui::ViewProviderDocumentObject::updateData(prop); - - if(strcmp(prop->getName(), "Functions") == 0) { - updateSize(); - } -} - -void ViewProviderFemPostFunctionProvider::updateSize() { - - std::vector< App::DocumentObject* > vec = claimChildren(); - for(std::vector< App::DocumentObject* >::iterator it = vec.begin(); it != vec.end(); ++it) { - - if(!(*it)->isDerivedFrom(Fem::FemPostFunction::getClassTypeId())) - continue; - - ViewProviderFemPostFunction* vp = static_cast(Gui::Application::Instance->getViewProvider(*it)); - vp->AutoScaleFactorX.setValue(SizeX.getValue()); - vp->AutoScaleFactorY.setValue(SizeY.getValue()); - vp->AutoScaleFactorZ.setValue(SizeZ.getValue()); - } -} - - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunction, Gui::ViewProviderDocumentObject) - -ViewProviderFemPostFunction::ViewProviderFemPostFunction() : m_autoscale(false), m_isDragging(false) -{ - - ADD_PROPERTY_TYPE(AutoScaleFactorX, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); - ADD_PROPERTY_TYPE(AutoScaleFactorY, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); - ADD_PROPERTY_TYPE(AutoScaleFactorZ, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); - - m_geometrySeperator = new SoSeparator(); - m_geometrySeperator->ref(); - - m_transform = new SoTransform(); - m_transform->ref(); - - m_scale = new SoScale(); - m_scale->ref(); - m_scale->scaleFactor = SbVec3f(1,1,1); -} - -ViewProviderFemPostFunction::~ViewProviderFemPostFunction() -{ - m_geometrySeperator->unref(); - m_manip->unref(); - m_scale->unref(); - //transform is unref'd when it is replaced by the dragger -} - -void ViewProviderFemPostFunction::attach(App::DocumentObject *pcObj) -{ - ViewProviderDocumentObject::attach(pcObj); - - // setup the graph for editing the function unit geometry - SoMaterial* color = new SoMaterial(); - color->diffuseColor.setValue(0,0,1); - color->transparency.setValue(0.5); - - m_transform = new SoTransform; - - m_manip = setupManipulator(); - m_manip->ref(); - - SoSeparator* pcEditNode = new SoSeparator(); - - pcEditNode->addChild(color); - pcEditNode->addChild(m_transform); - pcEditNode->addChild(m_geometrySeperator); - - m_geometrySeperator->insertChild(m_scale, 0); - - // Now we replace the SoTransform node by a manipulator - // Note: Even SoCenterballManip inherits from SoTransform - // we cannot use it directly (in above code) because the - // translation and center fields are overridden. - SoSearchAction sa; - sa.setInterest(SoSearchAction::FIRST); - sa.setSearchingAll(FALSE); - sa.setNode(m_transform); - sa.apply(pcEditNode); - SoPath * path = sa.getPath(); - if (path) { - m_manip->replaceNode(path); - - SoDragger* dragger = m_manip->getDragger(); - dragger->addStartCallback(dragStartCallback, this); - dragger->addFinishCallback(dragFinishCallback, this); - dragger->addMotionCallback(dragMotionCallback, this); - } - - addDisplayMaskMode(pcEditNode, "Default"); - setDisplayMaskMode("Default"); -} - -bool ViewProviderFemPostFunction::doubleClicked(void) { - Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default); - return true; -} - - -SoTransformManip* ViewProviderFemPostFunction::setupManipulator() { - - return new SoCenterballManip; -} - - -std::vector ViewProviderFemPostFunction::getDisplayModes(void) const -{ - std::vector StrList; - StrList.push_back("Default"); - return StrList; -} - -void ViewProviderFemPostFunction::dragStartCallback(void *data, SoDragger *) -{ - // This is called when a manipulator is about to manipulating - Gui::Application::Instance->activeDocument()->openCommand("Edit Mirror"); - reinterpret_cast(data)->m_isDragging = true; - - ViewProviderFemPostFunction* that = reinterpret_cast(data); - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem"); - that->m_autoRecompute = hGrp->GetBool("PostAutoRecompute", false); -} - -void ViewProviderFemPostFunction::dragFinishCallback(void *data, SoDragger *) -{ - // This is called when a manipulator has done manipulating - Gui::Application::Instance->activeDocument()->commitCommand(); - - ViewProviderFemPostFunction* that = reinterpret_cast(data); - if(that->m_autoRecompute) - that->getObject()->getDocument()->recompute(); - - reinterpret_cast(data)->m_isDragging = false; -} - -void ViewProviderFemPostFunction::dragMotionCallback(void *data, SoDragger *drag) -{ - ViewProviderFemPostFunction* that = reinterpret_cast(data); - that->draggerUpdate(drag); - - if(that->m_autoRecompute) - that->getObject()->getDocument()->recompute(); -} - - -bool ViewProviderFemPostFunction::setEdit(int ModNum) { - - - if (ModNum == ViewProvider::Default || ModNum == 1 ) { - - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgPost *postDlg = qobject_cast(dlg); - if (postDlg && postDlg->getView() != this) - postDlg = 0; // another pad left open its task panel - if (dlg && !postDlg) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } - - // start the edit dialog - if (postDlg) - Gui::Control().showDialog(postDlg); - else { - postDlg = new TaskDlgPost(this); - postDlg->appendBox(new TaskPostFunction(this)); - Gui::Control().showDialog(postDlg); - } - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -void ViewProviderFemPostFunction::unsetEdit(int ModNum) { - - if (ModNum == ViewProvider::Default) { - // when pressing ESC make sure to close the dialog - Gui::Control().closeDialog(); - } - else { - ViewProviderDocumentObject::unsetEdit(ModNum); - } -} - -void ViewProviderFemPostFunction::onChanged(const App::Property* prop) { - - Gui::ViewProviderDocumentObject::onChanged(prop); - - if(m_autoscale) - m_scale->scaleFactor = SbVec3f(AutoScaleFactorX.getValue(), AutoScaleFactorY.getValue(), AutoScaleFactorZ.getValue()); -} - - - -// *************************************************************************** - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostPlaneFunction, FemGui::ViewProviderFemPostFunction) - -ViewProviderFemPostPlaneFunction::ViewProviderFemPostPlaneFunction() { - - sPixmap = "fem-post-geo-plane"; - - setAutoScale(true); - - //setup the visualisation geometry - SoCoordinate3* points = new SoCoordinate3(); - points->point.setNum(4); - points->point.set1Value(0, -0.5, -0.5, 0); - points->point.set1Value(1, -0.5, 0.5, 0); - points->point.set1Value(2, 0.5, 0.5, 0); - points->point.set1Value(3, 0.5, -0.5, 0); - points->point.set1Value(4, -0.5, -0.5, 0); - SoLineSet* line = new SoLineSet(); - getGeometryNode()->addChild(points); - getGeometryNode()->addChild(line); -} - -ViewProviderFemPostPlaneFunction::~ViewProviderFemPostPlaneFunction() { - -} - -void ViewProviderFemPostPlaneFunction::draggerUpdate(SoDragger* m) { - - Fem::FemPostPlaneFunction* func = static_cast(getObject()); - SoCenterballDragger* dragger = static_cast(m); - - // the new axis of the plane - SbRotation rot, scaleDir; - const SbVec3f& center = dragger->center.getValue(); - - SbVec3f norm(0,0,1); - dragger->rotation.getValue().multVec(norm,norm); - func->Origin.setValue(center[0], center[1], center[2]); - func->Normal.setValue(norm[0],norm[1],norm[2]); - - SbVec3f t = static_cast(getManipulator())->translation.getValue(); - SbVec3f rt, irt; - dragger->rotation.getValue().multVec(t,rt); - dragger->rotation.getValue().inverse().multVec(t,irt); -} - -void ViewProviderFemPostPlaneFunction::updateData(const App::Property* p) { - - Fem::FemPostPlaneFunction* func = static_cast(getObject()); - - if(!isDragging() && (p == &func->Origin || p == &func->Normal)) { - - Base::Vector3d trans = func->Origin.getValue(); - Base::Vector3d norm = func->Normal.getValue(); - - norm = norm / norm.Length(); - SbRotation rot(SbVec3f(0.,0.,1.), SbVec3f(norm.x, norm.y, norm.z)); - - SbMatrix t, translate; - t.setRotate(rot); - translate.setTranslate(SbVec3f(trans.x, trans.y, trans.z)); - t.multRight(translate); - getManipulator()->setMatrix(t); - } - Gui::ViewProviderDocumentObject::updateData(p); -} - - -FunctionWidget* ViewProviderFemPostPlaneFunction::createControlWidget() { - return new PlaneWidget(); -} - - -PlaneWidget::PlaneWidget() { - - ui = new Ui_PlaneWidget(); - ui->setupUi(this); - - connect(ui->originX, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); - connect(ui->originY, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); - connect(ui->originZ, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); - connect(ui->normalX, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); - connect(ui->normalY, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); - connect(ui->normalZ, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); - -} - -PlaneWidget::~PlaneWidget() { - -} - -void PlaneWidget::applyPythonCode() { - -} - -void PlaneWidget::setViewProvider(ViewProviderFemPostFunction* view) { - - FemGui::FunctionWidget::setViewProvider(view); - onChange(static_cast(getObject())->Normal); - onChange(static_cast(getObject())->Origin); -} - -void PlaneWidget::onChange(const App::Property& p) { - - setBlockObjectUpdates(true); - if(strcmp(p.getName(), "Normal") == 0) { - const Base::Vector3d& vec = static_cast(&p)->getValue(); - ui->normalX->setValue(vec.x); - ui->normalY->setValue(vec.y); - ui->normalZ->setValue(vec.z); - } - else if(strcmp(p.getName(), "Origin") == 0) { - const Base::Vector3d& vec = static_cast(&p)->getValue(); - ui->originX->setValue(vec.x); - ui->originY->setValue(vec.y); - ui->originZ->setValue(vec.z); - } - setBlockObjectUpdates(false); -} - -void PlaneWidget::normalChanged(double) { - - if(!blockObjectUpdates()) { - Base::Vector3d vec(ui->normalX->value(), ui->normalY->value(), ui->normalZ->value()); - static_cast(getObject())->Normal.setValue(vec); - } -} - -void PlaneWidget::originChanged(double) { - - if(!blockObjectUpdates()) { - Base::Vector3d vec(ui->originX->value(), ui->originY->value(), ui->originZ->value()); - static_cast(getObject())->Origin.setValue(vec); - } -} - - - -// *************************************************************************** - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostSphereFunction, FemGui::ViewProviderFemPostFunction) - -ViewProviderFemPostSphereFunction::ViewProviderFemPostSphereFunction() { - - sPixmap = "fem-post-geo-sphere"; - - setAutoScale(false); - - //setup the visualisation geometry - SoCoordinate3* points = new SoCoordinate3(); - points->point.setNum(2*84); - int idx = 0; - for(int i=0; i<4; i++) { - for(int j=0; j<21; j++) { - points->point.set1Value(idx, SbVec3f(std::sin(2*M_PI/20*j) * std::cos(M_PI/4*i), - std::sin(2*M_PI/20*j) * std::sin(M_PI/4*i), - std::cos(2*M_PI/20*j) )); - ++idx; - } - } - for(int i=0; i<4; i++) { - for(int j=0; j<21; j++) { - points->point.set1Value(idx, SbVec3f(std::sin(M_PI/4*i) * std::cos(2*M_PI/20*j), - std::sin(M_PI/4*i) * std::sin(2*M_PI/20*j), - std::cos(M_PI/4*i) )); - ++idx; - } - } - - SoLineSet* line = new SoLineSet(); - getGeometryNode()->addChild(points); - getGeometryNode()->addChild(line); -} - -ViewProviderFemPostSphereFunction::~ViewProviderFemPostSphereFunction() { -} - -SoTransformManip* ViewProviderFemPostSphereFunction::setupManipulator() { - SoHandleBoxManip* manip = new SoHandleBoxManip(); - manip->getDragger()->setPart("extruder1", new SoSeparator); - manip->getDragger()->setPart("extruder2", new SoSeparator); - manip->getDragger()->setPart("extruder3", new SoSeparator); - manip->getDragger()->setPart("extruder4", new SoSeparator); - manip->getDragger()->setPart("extruder5", new SoSeparator); - manip->getDragger()->setPart("extruder6", new SoSeparator); - manip->getDragger()->setPart("extruder1Active", new SoSeparator); - manip->getDragger()->setPart("extruder2Active", new SoSeparator); - manip->getDragger()->setPart("extruder3Active", new SoSeparator); - manip->getDragger()->setPart("extruder4Active", new SoSeparator); - manip->getDragger()->setPart("extruder5Active", new SoSeparator); - manip->getDragger()->setPart("extruder6Active", new SoSeparator); - - return manip; -} - - -void ViewProviderFemPostSphereFunction::draggerUpdate(SoDragger* m) { - - Fem::FemPostSphereFunction* func = static_cast(getObject()); - SoHandleBoxDragger* dragger = static_cast(m); - - // the new axis of the plane - SbRotation rot, scaleDir; - const SbVec3f& center = dragger->translation.getValue(); - - SbVec3f norm(0,0,1); - func->Center.setValue(center[0], center[1], center[2]); - func->Radius.setValue(dragger->scaleFactor.getValue()[0]); -} - -void ViewProviderFemPostSphereFunction::updateData(const App::Property* p) { - - Fem::FemPostSphereFunction* func = static_cast(getObject()); - - if(!isDragging() && (p == &func->Center || p == &func->Radius)) { - - Base::Vector3d trans = func->Center.getValue(); - double radius = func->Radius.getValue(); - - SbMatrix t, translate; - t.setScale(radius); - translate.setTranslate(SbVec3f(trans.x, trans.y, trans.z)); - t.multRight(translate); - getManipulator()->setMatrix(t); - - } - Gui::ViewProviderDocumentObject::updateData(p); -} - - -FunctionWidget* ViewProviderFemPostSphereFunction::createControlWidget() { - return new SphereWidget(); -} - - -SphereWidget::SphereWidget() { - - ui = new Ui_SphereWidget(); - ui->setupUi(this); - - connect(ui->centerX, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); - connect(ui->centerY, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); - connect(ui->centerZ, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); - connect(ui->radius, SIGNAL(valueChanged(double)), this, SLOT(radiusChanged(double))); -} - -SphereWidget::~SphereWidget() { - -} - -void SphereWidget::applyPythonCode() { - -} - -void SphereWidget::setViewProvider(ViewProviderFemPostFunction* view) { - - FemGui::FunctionWidget::setViewProvider(view); - onChange(static_cast(getObject())->Center); - onChange(static_cast(getObject())->Radius); -} - -void SphereWidget::onChange(const App::Property& p) { - - setBlockObjectUpdates(true); - if(strcmp(p.getName(), "Radius") == 0) { - double val = static_cast(&p)->getValue(); - ui->radius->setValue(val); - } - else if(strcmp(p.getName(), "Center") == 0) { - const Base::Vector3d& vec = static_cast(&p)->getValue(); - ui->centerX->setValue(vec.x); - ui->centerY->setValue(vec.y); - ui->centerZ->setValue(vec.z); - } - setBlockObjectUpdates(false); -} - -void SphereWidget::centerChanged(double) { - - if(!blockObjectUpdates()) { - Base::Vector3d vec(ui->centerX->value(), ui->centerY->value(), ui->centerZ->value()); - static_cast(getObject())->Center.setValue(vec); - } -} - -void SphereWidget::radiusChanged(double) { - - if(!blockObjectUpdates()) { - static_cast(getObject())->Radius.setValue(ui->radius->value()); - } -} - -#include "moc_ViewProviderFemPostFunction.cpp" +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include + +# include + +# include +#endif + +#include "ViewProviderFemPostFunction.h" +#include "TaskPostBoxes.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ui_PlaneWidget.h" +#include "ui_SphereWidget.h" + +using namespace FemGui; + +void FunctionWidget::setViewProvider(ViewProviderFemPostFunction* view) { + + m_view = view; + m_object = static_cast(view->getObject()); + m_connection = m_object->getDocument()->signalChangedObject.connect(boost::bind(&FunctionWidget::onObjectsChanged, this, _1, _2)); +} + +void FunctionWidget::onObjectsChanged(const App::DocumentObject& obj, const App::Property& p) { + + if(&obj == m_object) + onChange(p); +} + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunctionProvider, Gui::ViewProviderDocumentObject) + +ViewProviderFemPostFunctionProvider::ViewProviderFemPostFunctionProvider() { + +} + +ViewProviderFemPostFunctionProvider::~ViewProviderFemPostFunctionProvider() { + +} + +std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren(void) const { + + return static_cast(getObject())->Functions.getValues(); +} + +std::vector< App::DocumentObject* > ViewProviderFemPostFunctionProvider::claimChildren3D(void) const { + return claimChildren(); +} + +void ViewProviderFemPostFunctionProvider::onChanged(const App::Property* prop) { + Gui::ViewProviderDocumentObject::onChanged(prop); + + updateSize(); +} + +void ViewProviderFemPostFunctionProvider::updateData(const App::Property* prop) { + Gui::ViewProviderDocumentObject::updateData(prop); + + if(strcmp(prop->getName(), "Functions") == 0) { + updateSize(); + } +} + +void ViewProviderFemPostFunctionProvider::updateSize() { + + std::vector< App::DocumentObject* > vec = claimChildren(); + for(std::vector< App::DocumentObject* >::iterator it = vec.begin(); it != vec.end(); ++it) { + + if(!(*it)->isDerivedFrom(Fem::FemPostFunction::getClassTypeId())) + continue; + + ViewProviderFemPostFunction* vp = static_cast(Gui::Application::Instance->getViewProvider(*it)); + vp->AutoScaleFactorX.setValue(SizeX.getValue()); + vp->AutoScaleFactorY.setValue(SizeY.getValue()); + vp->AutoScaleFactorZ.setValue(SizeZ.getValue()); + } +} + + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostFunction, Gui::ViewProviderDocumentObject) + +ViewProviderFemPostFunction::ViewProviderFemPostFunction() : m_autoscale(false), m_isDragging(false) +{ + + ADD_PROPERTY_TYPE(AutoScaleFactorX, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); + ADD_PROPERTY_TYPE(AutoScaleFactorY, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); + ADD_PROPERTY_TYPE(AutoScaleFactorZ, (1), "AutoScale", App::Prop_Hidden, "Automatic scaling factor"); + + m_geometrySeperator = new SoSeparator(); + m_geometrySeperator->ref(); + + m_transform = new SoTransform(); + m_transform->ref(); + + m_scale = new SoScale(); + m_scale->ref(); + m_scale->scaleFactor = SbVec3f(1,1,1); +} + +ViewProviderFemPostFunction::~ViewProviderFemPostFunction() +{ + m_geometrySeperator->unref(); + m_manip->unref(); + m_scale->unref(); + //transform is unref'd when it is replaced by the dragger +} + +void ViewProviderFemPostFunction::attach(App::DocumentObject *pcObj) +{ + ViewProviderDocumentObject::attach(pcObj); + + // setup the graph for editing the function unit geometry + SoMaterial* color = new SoMaterial(); + color->diffuseColor.setValue(0,0,1); + color->transparency.setValue(0.5); + + m_transform = new SoTransform; + + m_manip = setupManipulator(); + m_manip->ref(); + + SoSeparator* pcEditNode = new SoSeparator(); + + pcEditNode->addChild(color); + pcEditNode->addChild(m_transform); + pcEditNode->addChild(m_geometrySeperator); + + m_geometrySeperator->insertChild(m_scale, 0); + + // Now we replace the SoTransform node by a manipulator + // Note: Even SoCenterballManip inherits from SoTransform + // we cannot use it directly (in above code) because the + // translation and center fields are overridden. + SoSearchAction sa; + sa.setInterest(SoSearchAction::FIRST); + sa.setSearchingAll(FALSE); + sa.setNode(m_transform); + sa.apply(pcEditNode); + SoPath * path = sa.getPath(); + if (path) { + m_manip->replaceNode(path); + + SoDragger* dragger = m_manip->getDragger(); + dragger->addStartCallback(dragStartCallback, this); + dragger->addFinishCallback(dragFinishCallback, this); + dragger->addMotionCallback(dragMotionCallback, this); + } + + addDisplayMaskMode(pcEditNode, "Default"); + setDisplayMaskMode("Default"); +} + +bool ViewProviderFemPostFunction::doubleClicked(void) { + Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default); + return true; +} + + +SoTransformManip* ViewProviderFemPostFunction::setupManipulator() { + + return new SoCenterballManip; +} + + +std::vector ViewProviderFemPostFunction::getDisplayModes(void) const +{ + std::vector StrList; + StrList.push_back("Default"); + return StrList; +} + +void ViewProviderFemPostFunction::dragStartCallback(void *data, SoDragger *) +{ + // This is called when a manipulator is about to manipulating + Gui::Application::Instance->activeDocument()->openCommand("Edit Mirror"); + reinterpret_cast(data)->m_isDragging = true; + + ViewProviderFemPostFunction* that = reinterpret_cast(data); + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Fem"); + that->m_autoRecompute = hGrp->GetBool("PostAutoRecompute", false); +} + +void ViewProviderFemPostFunction::dragFinishCallback(void *data, SoDragger *) +{ + // This is called when a manipulator has done manipulating + Gui::Application::Instance->activeDocument()->commitCommand(); + + ViewProviderFemPostFunction* that = reinterpret_cast(data); + if(that->m_autoRecompute) + that->getObject()->getDocument()->recompute(); + + reinterpret_cast(data)->m_isDragging = false; +} + +void ViewProviderFemPostFunction::dragMotionCallback(void *data, SoDragger *drag) +{ + ViewProviderFemPostFunction* that = reinterpret_cast(data); + that->draggerUpdate(drag); + + if(that->m_autoRecompute) + that->getObject()->getDocument()->recompute(); +} + + +bool ViewProviderFemPostFunction::setEdit(int ModNum) { + + + if (ModNum == ViewProvider::Default || ModNum == 1 ) { + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgPost *postDlg = qobject_cast(dlg); + if (postDlg && postDlg->getView() != this) + postDlg = 0; // another pad left open its task panel + if (dlg && !postDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } + + // start the edit dialog + if (postDlg) + Gui::Control().showDialog(postDlg); + else { + postDlg = new TaskDlgPost(this); + postDlg->appendBox(new TaskPostFunction(this)); + Gui::Control().showDialog(postDlg); + } + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemPostFunction::unsetEdit(int ModNum) { + + if (ModNum == ViewProvider::Default) { + // when pressing ESC make sure to close the dialog + Gui::Control().closeDialog(); + } + else { + ViewProviderDocumentObject::unsetEdit(ModNum); + } +} + +void ViewProviderFemPostFunction::onChanged(const App::Property* prop) { + + Gui::ViewProviderDocumentObject::onChanged(prop); + + if(m_autoscale) + m_scale->scaleFactor = SbVec3f(AutoScaleFactorX.getValue(), AutoScaleFactorY.getValue(), AutoScaleFactorZ.getValue()); +} + + + +// *************************************************************************** + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostPlaneFunction, FemGui::ViewProviderFemPostFunction) + +ViewProviderFemPostPlaneFunction::ViewProviderFemPostPlaneFunction() { + + sPixmap = "fem-post-geo-plane"; + + setAutoScale(true); + + //setup the visualisation geometry + SoCoordinate3* points = new SoCoordinate3(); + points->point.setNum(4); + points->point.set1Value(0, -0.5, -0.5, 0); + points->point.set1Value(1, -0.5, 0.5, 0); + points->point.set1Value(2, 0.5, 0.5, 0); + points->point.set1Value(3, 0.5, -0.5, 0); + points->point.set1Value(4, -0.5, -0.5, 0); + SoLineSet* line = new SoLineSet(); + getGeometryNode()->addChild(points); + getGeometryNode()->addChild(line); +} + +ViewProviderFemPostPlaneFunction::~ViewProviderFemPostPlaneFunction() { + +} + +void ViewProviderFemPostPlaneFunction::draggerUpdate(SoDragger* m) { + + Fem::FemPostPlaneFunction* func = static_cast(getObject()); + SoCenterballDragger* dragger = static_cast(m); + + // the new axis of the plane + SbRotation rot, scaleDir; + const SbVec3f& center = dragger->center.getValue(); + + SbVec3f norm(0,0,1); + dragger->rotation.getValue().multVec(norm,norm); + func->Origin.setValue(center[0], center[1], center[2]); + func->Normal.setValue(norm[0],norm[1],norm[2]); + + SbVec3f t = static_cast(getManipulator())->translation.getValue(); + SbVec3f rt, irt; + dragger->rotation.getValue().multVec(t,rt); + dragger->rotation.getValue().inverse().multVec(t,irt); +} + +void ViewProviderFemPostPlaneFunction::updateData(const App::Property* p) { + + Fem::FemPostPlaneFunction* func = static_cast(getObject()); + + if(!isDragging() && (p == &func->Origin || p == &func->Normal)) { + + Base::Vector3d trans = func->Origin.getValue(); + Base::Vector3d norm = func->Normal.getValue(); + + norm = norm / norm.Length(); + SbRotation rot(SbVec3f(0.,0.,1.), SbVec3f(norm.x, norm.y, norm.z)); + + SbMatrix t, translate; + t.setRotate(rot); + translate.setTranslate(SbVec3f(trans.x, trans.y, trans.z)); + t.multRight(translate); + getManipulator()->setMatrix(t); + } + Gui::ViewProviderDocumentObject::updateData(p); +} + + +FunctionWidget* ViewProviderFemPostPlaneFunction::createControlWidget() { + return new PlaneWidget(); +} + + +PlaneWidget::PlaneWidget() { + + ui = new Ui_PlaneWidget(); + ui->setupUi(this); + + connect(ui->originX, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); + connect(ui->originY, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); + connect(ui->originZ, SIGNAL(valueChanged(double)), this, SLOT(originChanged(double))); + connect(ui->normalX, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); + connect(ui->normalY, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); + connect(ui->normalZ, SIGNAL(valueChanged(double)), this, SLOT(normalChanged(double))); + +} + +PlaneWidget::~PlaneWidget() { + +} + +void PlaneWidget::applyPythonCode() { + +} + +void PlaneWidget::setViewProvider(ViewProviderFemPostFunction* view) { + + FemGui::FunctionWidget::setViewProvider(view); + onChange(static_cast(getObject())->Normal); + onChange(static_cast(getObject())->Origin); +} + +void PlaneWidget::onChange(const App::Property& p) { + + setBlockObjectUpdates(true); + if(strcmp(p.getName(), "Normal") == 0) { + const Base::Vector3d& vec = static_cast(&p)->getValue(); + ui->normalX->setValue(vec.x); + ui->normalY->setValue(vec.y); + ui->normalZ->setValue(vec.z); + } + else if(strcmp(p.getName(), "Origin") == 0) { + const Base::Vector3d& vec = static_cast(&p)->getValue(); + ui->originX->setValue(vec.x); + ui->originY->setValue(vec.y); + ui->originZ->setValue(vec.z); + } + setBlockObjectUpdates(false); +} + +void PlaneWidget::normalChanged(double) { + + if(!blockObjectUpdates()) { + Base::Vector3d vec(ui->normalX->value(), ui->normalY->value(), ui->normalZ->value()); + static_cast(getObject())->Normal.setValue(vec); + } +} + +void PlaneWidget::originChanged(double) { + + if(!blockObjectUpdates()) { + Base::Vector3d vec(ui->originX->value(), ui->originY->value(), ui->originZ->value()); + static_cast(getObject())->Origin.setValue(vec); + } +} + + + +// *************************************************************************** + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostSphereFunction, FemGui::ViewProviderFemPostFunction) + +ViewProviderFemPostSphereFunction::ViewProviderFemPostSphereFunction() { + + sPixmap = "fem-post-geo-sphere"; + + setAutoScale(false); + + //setup the visualisation geometry + SoCoordinate3* points = new SoCoordinate3(); + points->point.setNum(2*84); + int idx = 0; + for(int i=0; i<4; i++) { + for(int j=0; j<21; j++) { + points->point.set1Value(idx, SbVec3f(std::sin(2*M_PI/20*j) * std::cos(M_PI/4*i), + std::sin(2*M_PI/20*j) * std::sin(M_PI/4*i), + std::cos(2*M_PI/20*j) )); + ++idx; + } + } + for(int i=0; i<4; i++) { + for(int j=0; j<21; j++) { + points->point.set1Value(idx, SbVec3f(std::sin(M_PI/4*i) * std::cos(2*M_PI/20*j), + std::sin(M_PI/4*i) * std::sin(2*M_PI/20*j), + std::cos(M_PI/4*i) )); + ++idx; + } + } + + SoLineSet* line = new SoLineSet(); + getGeometryNode()->addChild(points); + getGeometryNode()->addChild(line); +} + +ViewProviderFemPostSphereFunction::~ViewProviderFemPostSphereFunction() { +} + +SoTransformManip* ViewProviderFemPostSphereFunction::setupManipulator() { + SoHandleBoxManip* manip = new SoHandleBoxManip(); + manip->getDragger()->setPart("extruder1", new SoSeparator); + manip->getDragger()->setPart("extruder2", new SoSeparator); + manip->getDragger()->setPart("extruder3", new SoSeparator); + manip->getDragger()->setPart("extruder4", new SoSeparator); + manip->getDragger()->setPart("extruder5", new SoSeparator); + manip->getDragger()->setPart("extruder6", new SoSeparator); + manip->getDragger()->setPart("extruder1Active", new SoSeparator); + manip->getDragger()->setPart("extruder2Active", new SoSeparator); + manip->getDragger()->setPart("extruder3Active", new SoSeparator); + manip->getDragger()->setPart("extruder4Active", new SoSeparator); + manip->getDragger()->setPart("extruder5Active", new SoSeparator); + manip->getDragger()->setPart("extruder6Active", new SoSeparator); + + return manip; +} + + +void ViewProviderFemPostSphereFunction::draggerUpdate(SoDragger* m) { + + Fem::FemPostSphereFunction* func = static_cast(getObject()); + SoHandleBoxDragger* dragger = static_cast(m); + + // the new axis of the plane + SbRotation rot, scaleDir; + const SbVec3f& center = dragger->translation.getValue(); + + SbVec3f norm(0,0,1); + func->Center.setValue(center[0], center[1], center[2]); + func->Radius.setValue(dragger->scaleFactor.getValue()[0]); +} + +void ViewProviderFemPostSphereFunction::updateData(const App::Property* p) { + + Fem::FemPostSphereFunction* func = static_cast(getObject()); + + if(!isDragging() && (p == &func->Center || p == &func->Radius)) { + + Base::Vector3d trans = func->Center.getValue(); + double radius = func->Radius.getValue(); + + SbMatrix t, translate; + t.setScale(radius); + translate.setTranslate(SbVec3f(trans.x, trans.y, trans.z)); + t.multRight(translate); + getManipulator()->setMatrix(t); + + } + Gui::ViewProviderDocumentObject::updateData(p); +} + + +FunctionWidget* ViewProviderFemPostSphereFunction::createControlWidget() { + return new SphereWidget(); +} + + +SphereWidget::SphereWidget() { + + ui = new Ui_SphereWidget(); + ui->setupUi(this); + + connect(ui->centerX, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); + connect(ui->centerY, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); + connect(ui->centerZ, SIGNAL(valueChanged(double)), this, SLOT(centerChanged(double))); + connect(ui->radius, SIGNAL(valueChanged(double)), this, SLOT(radiusChanged(double))); +} + +SphereWidget::~SphereWidget() { + +} + +void SphereWidget::applyPythonCode() { + +} + +void SphereWidget::setViewProvider(ViewProviderFemPostFunction* view) { + + FemGui::FunctionWidget::setViewProvider(view); + onChange(static_cast(getObject())->Center); + onChange(static_cast(getObject())->Radius); +} + +void SphereWidget::onChange(const App::Property& p) { + + setBlockObjectUpdates(true); + if(strcmp(p.getName(), "Radius") == 0) { + double val = static_cast(&p)->getValue(); + ui->radius->setValue(val); + } + else if(strcmp(p.getName(), "Center") == 0) { + const Base::Vector3d& vec = static_cast(&p)->getValue(); + ui->centerX->setValue(vec.x); + ui->centerY->setValue(vec.y); + ui->centerZ->setValue(vec.z); + } + setBlockObjectUpdates(false); +} + +void SphereWidget::centerChanged(double) { + + if(!blockObjectUpdates()) { + Base::Vector3d vec(ui->centerX->value(), ui->centerY->value(), ui->centerZ->value()); + static_cast(getObject())->Center.setValue(vec); + } +} + +void SphereWidget::radiusChanged(double) { + + if(!blockObjectUpdates()) { + static_cast(getObject())->Radius.setValue(ui->radius->value()); + } +} + +#include "moc_ViewProviderFemPostFunction.cpp" diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h index 08302634dc..f3cd3c6a6a 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostFunction.h @@ -1,222 +1,222 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_VIEWPROVIDERFEMPOSTFUNCTION_H -#define FEM_VIEWPROVIDERFEMPOSTFUNCTION_H - -#include -#include -#include -#include -#include - -class SoScale; -class SoSurroundScale; -class SoTransformManip; -class SoComposeMatrix; -class SoMatrixTransform; -class SoDragger; -class SoSphere; -class Ui_PlaneWidget; -class Ui_SphereWidget; - -namespace FemGui -{ - -class ViewProviderFemPostFunction; - -class FemGuiExport FunctionWidget : public QWidget { - - Q_OBJECT -public: - FunctionWidget() {} - virtual ~FunctionWidget() {} - - virtual void applyPythonCode() = 0; - virtual void setViewProvider(ViewProviderFemPostFunction* view); - void onObjectsChanged(const App::DocumentObject& obj, const App::Property&); - -protected: - ViewProviderFemPostFunction* getView() {return m_view;} - Fem::FemPostFunction* getObject(){return m_object;} - - bool blockObjectUpdates() {return m_block;} - void setBlockObjectUpdates(bool val) {m_block = val;} - - virtual void onChange(const App::Property& p) = 0; - -private: - bool m_block; - ViewProviderFemPostFunction* m_view; - Fem::FemPostFunction* m_object; - boost::signals2::scoped_connection m_connection; -}; - -class FemGuiExport ViewProviderFemPostFunctionProvider : public Gui::ViewProviderDocumentObject -{ - PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction); - -public: - ViewProviderFemPostFunctionProvider(); - virtual ~ViewProviderFemPostFunctionProvider(); - - App::PropertyFloat SizeX; - App::PropertyFloat SizeY; - App::PropertyFloat SizeZ; - -protected: - virtual std::vector< App::DocumentObject* > claimChildren(void) const; - virtual std::vector< App::DocumentObject* > claimChildren3D(void) const; - virtual void onChanged(const App::Property* prop); - virtual void updateData(const App::Property*); - - void updateSize(); -}; - -class FemGuiExport ViewProviderFemPostFunction : public Gui::ViewProviderDocumentObject -{ - PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction); - -public: - /// constructor. - ViewProviderFemPostFunction(); - ~ViewProviderFemPostFunction(); - - App::PropertyFloat AutoScaleFactorX; - App::PropertyFloat AutoScaleFactorY; - App::PropertyFloat AutoScaleFactorZ; - - void attach(App::DocumentObject *pcObject); - bool doubleClicked(void); - std::vector getDisplayModes() const; - - //creates the widget used in the task dalogs, either for the function itself or for - //the fiter using it - virtual FunctionWidget* createControlWidget() {return NULL;} - -protected: - virtual bool setEdit(int ModNum); - virtual void unsetEdit(int ModNum); - virtual void onChanged(const App::Property* prop); - - void setAutoScale(bool value) {m_autoscale = value;} - bool autoScale() {return m_autoscale;} - - bool isDragging() {return m_isDragging;} - - virtual SoTransformManip* setupManipulator(); - virtual void draggerUpdate(SoDragger*) {} - SoTransformManip* getManipulator() {return m_manip;} - SoSeparator* getGeometryNode() {return m_geometrySeperator;} - SoScale* getScaleNode() {return m_scale;} - SoTransform* getTransformNode() {return m_transform;} - -private: - static void dragStartCallback(void * data, SoDragger * d); - static void dragFinishCallback(void * data, SoDragger * d); - static void dragMotionCallback(void * data, SoDragger * d); - - SoSeparator* m_geometrySeperator; - SoTransformManip* m_manip; - SoScale* m_scale; - SoTransform* m_transform; - bool m_autoscale, m_isDragging, m_autoRecompute; -}; - - -// *************************************************************************** -class FemGuiExport PlaneWidget : public FunctionWidget { - - Q_OBJECT -public: - PlaneWidget(); - virtual ~PlaneWidget(); - - virtual void applyPythonCode(); - virtual void onChange(const App::Property& p); - virtual void setViewProvider(ViewProviderFemPostFunction* view); - -private Q_SLOTS: - void originChanged(double); - void normalChanged(double); - -private: - Ui_PlaneWidget* ui; -}; - -class FemGuiExport ViewProviderFemPostPlaneFunction : public ViewProviderFemPostFunction { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostPlaneFunction); - -public: - ViewProviderFemPostPlaneFunction(); - virtual ~ViewProviderFemPostPlaneFunction(); - - virtual FunctionWidget* createControlWidget(); - -protected: - virtual void draggerUpdate(SoDragger* mat); - virtual void updateData(const App::Property*); -}; - - -// *************************************************************************** -class FemGuiExport SphereWidget : public FunctionWidget { - - Q_OBJECT -public: - SphereWidget(); - virtual ~SphereWidget(); - - virtual void applyPythonCode(); - virtual void onChange(const App::Property& p); - virtual void setViewProvider(ViewProviderFemPostFunction* view); - -private Q_SLOTS: - void centerChanged(double); - void radiusChanged(double); - -private: - Ui_SphereWidget* ui; -}; - -class FemGuiExport ViewProviderFemPostSphereFunction : public ViewProviderFemPostFunction { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostSphereFunction); - -public: - ViewProviderFemPostSphereFunction(); - virtual ~ViewProviderFemPostSphereFunction(); - - virtual SoTransformManip* setupManipulator(); - virtual FunctionWidget* createControlWidget(); - -protected: - virtual void draggerUpdate(SoDragger* mat); - virtual void updateData(const App::Property*); -}; - -} //namespace FemGui - - -#endif // FEM_VIEWPROVIDERFEMPOSTFUNCTION_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_VIEWPROVIDERFEMPOSTFUNCTION_H +#define FEM_VIEWPROVIDERFEMPOSTFUNCTION_H + +#include +#include +#include +#include +#include + +class SoScale; +class SoSurroundScale; +class SoTransformManip; +class SoComposeMatrix; +class SoMatrixTransform; +class SoDragger; +class SoSphere; +class Ui_PlaneWidget; +class Ui_SphereWidget; + +namespace FemGui +{ + +class ViewProviderFemPostFunction; + +class FemGuiExport FunctionWidget : public QWidget { + + Q_OBJECT +public: + FunctionWidget() {} + virtual ~FunctionWidget() {} + + virtual void applyPythonCode() = 0; + virtual void setViewProvider(ViewProviderFemPostFunction* view); + void onObjectsChanged(const App::DocumentObject& obj, const App::Property&); + +protected: + ViewProviderFemPostFunction* getView() {return m_view;} + Fem::FemPostFunction* getObject(){return m_object;} + + bool blockObjectUpdates() {return m_block;} + void setBlockObjectUpdates(bool val) {m_block = val;} + + virtual void onChange(const App::Property& p) = 0; + +private: + bool m_block; + ViewProviderFemPostFunction* m_view; + Fem::FemPostFunction* m_object; + boost::signals2::scoped_connection m_connection; +}; + +class FemGuiExport ViewProviderFemPostFunctionProvider : public Gui::ViewProviderDocumentObject +{ + PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction); + +public: + ViewProviderFemPostFunctionProvider(); + virtual ~ViewProviderFemPostFunctionProvider(); + + App::PropertyFloat SizeX; + App::PropertyFloat SizeY; + App::PropertyFloat SizeZ; + +protected: + virtual std::vector< App::DocumentObject* > claimChildren(void) const; + virtual std::vector< App::DocumentObject* > claimChildren3D(void) const; + virtual void onChanged(const App::Property* prop); + virtual void updateData(const App::Property*); + + void updateSize(); +}; + +class FemGuiExport ViewProviderFemPostFunction : public Gui::ViewProviderDocumentObject +{ + PROPERTY_HEADER(FemGui::ViewProviderFemPostFunction); + +public: + /// constructor. + ViewProviderFemPostFunction(); + ~ViewProviderFemPostFunction(); + + App::PropertyFloat AutoScaleFactorX; + App::PropertyFloat AutoScaleFactorY; + App::PropertyFloat AutoScaleFactorZ; + + void attach(App::DocumentObject *pcObject); + bool doubleClicked(void); + std::vector getDisplayModes() const; + + //creates the widget used in the task dalogs, either for the function itself or for + //the fiter using it + virtual FunctionWidget* createControlWidget() {return NULL;} + +protected: + virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); + virtual void onChanged(const App::Property* prop); + + void setAutoScale(bool value) {m_autoscale = value;} + bool autoScale() {return m_autoscale;} + + bool isDragging() {return m_isDragging;} + + virtual SoTransformManip* setupManipulator(); + virtual void draggerUpdate(SoDragger*) {} + SoTransformManip* getManipulator() {return m_manip;} + SoSeparator* getGeometryNode() {return m_geometrySeperator;} + SoScale* getScaleNode() {return m_scale;} + SoTransform* getTransformNode() {return m_transform;} + +private: + static void dragStartCallback(void * data, SoDragger * d); + static void dragFinishCallback(void * data, SoDragger * d); + static void dragMotionCallback(void * data, SoDragger * d); + + SoSeparator* m_geometrySeperator; + SoTransformManip* m_manip; + SoScale* m_scale; + SoTransform* m_transform; + bool m_autoscale, m_isDragging, m_autoRecompute; +}; + + +// *************************************************************************** +class FemGuiExport PlaneWidget : public FunctionWidget { + + Q_OBJECT +public: + PlaneWidget(); + virtual ~PlaneWidget(); + + virtual void applyPythonCode(); + virtual void onChange(const App::Property& p); + virtual void setViewProvider(ViewProviderFemPostFunction* view); + +private Q_SLOTS: + void originChanged(double); + void normalChanged(double); + +private: + Ui_PlaneWidget* ui; +}; + +class FemGuiExport ViewProviderFemPostPlaneFunction : public ViewProviderFemPostFunction { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostPlaneFunction); + +public: + ViewProviderFemPostPlaneFunction(); + virtual ~ViewProviderFemPostPlaneFunction(); + + virtual FunctionWidget* createControlWidget(); + +protected: + virtual void draggerUpdate(SoDragger* mat); + virtual void updateData(const App::Property*); +}; + + +// *************************************************************************** +class FemGuiExport SphereWidget : public FunctionWidget { + + Q_OBJECT +public: + SphereWidget(); + virtual ~SphereWidget(); + + virtual void applyPythonCode(); + virtual void onChange(const App::Property& p); + virtual void setViewProvider(ViewProviderFemPostFunction* view); + +private Q_SLOTS: + void centerChanged(double); + void radiusChanged(double); + +private: + Ui_SphereWidget* ui; +}; + +class FemGuiExport ViewProviderFemPostSphereFunction : public ViewProviderFemPostFunction { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostSphereFunction); + +public: + ViewProviderFemPostSphereFunction(); + virtual ~ViewProviderFemPostSphereFunction(); + + virtual SoTransformManip* setupManipulator(); + virtual FunctionWidget* createControlWidget(); + +protected: + virtual void draggerUpdate(SoDragger* mat); + virtual void updateData(const App::Property*); +}; + +} //namespace FemGui + + +#endif // FEM_VIEWPROVIDERFEMPOSTFUNCTION_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp index 65ef8ff9fa..ab760c7d13 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.cpp @@ -1,634 +1,634 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -# include -# include -# include -# include - -# include -#endif - -#include "ViewProviderFemPostObject.h" -#include "TaskPostBoxes.h" -#include -#include -#include -#include -#include -#include -#include - -using namespace FemGui; - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostObject, Gui::ViewProviderDocumentObject) - -ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges(false) -{ - //initialize the properties - ADD_PROPERTY_TYPE(Field,((long)0), "Coloring", App::Prop_None, "Select the field used for calculating the color"); - ADD_PROPERTY_TYPE(VectorMode,((long)0), "Coloring", App::Prop_None, "Select what to show for a vector field"); - ADD_PROPERTY(Transparency, (0)); - - sPixmap = "fem-femmesh-from-shape"; - - //create the subnodes which do the visualization work - m_shapeHints = new SoShapeHints(); - m_shapeHints->ref(); - m_shapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; - m_coordinates = new SoCoordinate3(); - m_coordinates->ref(); - m_materialBinding = new SoMaterialBinding(); - m_materialBinding->ref(); - m_material = new SoMaterial(); - m_material->ref(); - m_normalBinding = new SoNormalBinding(); - m_normalBinding->ref(); - m_normals = new SoNormal(); - m_normals->ref(); - m_faces = new SoIndexedFaceSet(); - m_faces->ref(); - m_triangleStrips = new SoIndexedTriangleStripSet(); - m_triangleStrips->ref(); - m_markers = new SoIndexedPointSet(); - m_markers->ref(); - m_lines = new SoIndexedLineSet(); - m_lines->ref(); - m_drawStyle = new SoDrawStyle(); - m_drawStyle->ref(); - m_drawStyle->lineWidth.setValue(2); - m_drawStyle->pointSize.setValue(3); - m_seperator = new SoSeparator(); - m_seperator->ref(); - - // simple color bar - m_colorRoot = new SoSeparator(); - m_colorRoot->ref(); - m_colorStyle = new SoDrawStyle(); - m_colorStyle->ref(); - m_colorRoot->addChild(m_colorStyle); - m_colorBar = new Gui::SoFCColorBar; - m_colorBar->Attach(this); - m_colorBar->ref(); - - //create the vtk algorithms we use for visualisation - m_outline = vtkSmartPointer::New(); - m_points = vtkSmartPointer::New(); - m_pointsSurface = vtkSmartPointer::New(); - m_surface = vtkSmartPointer::New(); - m_wireframe = vtkSmartPointer::New(); - m_wireframeSurface = vtkSmartPointer::New(); - m_surfaceEdges = vtkSmartPointer::New(); - m_pointsSurface->AddInputConnection(m_surface->GetOutputPort()); - m_wireframeSurface->AddInputConnection(m_surface->GetOutputPort()); - m_surfaceEdges->AddInputConnection(m_surface->GetOutputPort()); - m_surfaceEdges->AddInputConnection(m_wireframeSurface->GetOutputPort()); - - m_currentAlgorithm = m_outline; - - updateProperties(); // initialize the enums -} - -ViewProviderFemPostObject::~ViewProviderFemPostObject() -{ - m_shapeHints->unref(); - m_coordinates->unref(); - m_materialBinding->unref(); - m_drawStyle->unref(); - m_normalBinding->unref(); - m_normals->unref(); - m_faces->unref(); - m_triangleStrips->unref(); - m_markers->unref(); - m_lines->unref(); - m_seperator->unref(); - m_material->unref(); - m_colorBar->Detach(this); - m_colorBar->unref(); - m_colorStyle->unref(); - m_colorRoot->unref(); -} - -void ViewProviderFemPostObject::attach(App::DocumentObject *pcObj) -{ - ViewProviderDocumentObject::attach(pcObj); - - // face nodes - m_seperator->addChild(m_shapeHints); - m_seperator->addChild(m_drawStyle); - m_seperator->addChild(m_materialBinding); - m_seperator->addChild(m_material); - m_seperator->addChild(m_coordinates); - m_seperator->addChild(m_markers); - m_seperator->addChild(m_lines); - m_seperator->addChild(m_faces); - - // Check for an already existing color bar - Gui::SoFCColorBar* pcBar = ((Gui::SoFCColorBar*)findFrontRootOfType( Gui::SoFCColorBar::getClassTypeId() )); - if ( pcBar ) { - float fMin = m_colorBar->getMinValue(); - float fMax = m_colorBar->getMaxValue(); - - // Attach to the foreign color bar and delete our own bar - pcBar->Attach(this); - pcBar->ref(); - pcBar->setRange(fMin, fMax, 3); - pcBar->Notify(0); - m_colorBar->Detach(this); - m_colorBar->unref(); - m_colorBar = pcBar; - } - - m_colorRoot->addChild(m_colorBar); - - //all - addDisplayMaskMode(m_seperator, "Default"); - setDisplayMaskMode("Default"); - - setupPipeline(); -} - -SoSeparator* ViewProviderFemPostObject::getFrontRoot(void) const { - - return m_colorRoot; -} - - -void ViewProviderFemPostObject::setDisplayMode(const char* ModeName) -{ - if (strcmp("Outline",ModeName)==0) - m_currentAlgorithm = m_outline; - else if (strcmp("Surface with Edges",ModeName)==0) - m_currentAlgorithm = m_surfaceEdges; - else if (strcmp("Surface",ModeName)==0) - m_currentAlgorithm = m_surface; - else if (strcmp("Wireframe",ModeName)==0) - m_currentAlgorithm = m_wireframe; - else if (strcmp("Wireframe (surface only)",ModeName)==0) - m_currentAlgorithm = m_wireframeSurface; - else if (strcmp("Nodes",ModeName)==0) - m_currentAlgorithm = m_points; - else if (strcmp("Nodes (surface only)",ModeName)==0) - m_currentAlgorithm = m_pointsSurface; - - update(); - - ViewProviderDocumentObject::setDisplayMode( ModeName ); -} - -std::vector ViewProviderFemPostObject::getDisplayModes(void) const -{ - std::vector StrList; - StrList.push_back("Outline"); - StrList.push_back("Nodes"); - //StrList.push_back("Nodes (surface only)"); somehow this filter does not work - StrList.push_back("Surface"); - StrList.push_back("Surface with Edges"); - StrList.push_back("Wireframe"); - StrList.push_back("Wireframe (surface only)"); - return StrList; -} - -void ViewProviderFemPostObject::update() { - - if(!setupPipeline()) - return; - - m_currentAlgorithm->Update(); - updateProperties(); - update3D(); -} - -void ViewProviderFemPostObject::updateProperties() { - - m_blockPropertyChanges = true; - vtkPolyData* poly = m_currentAlgorithm->GetOutput(); - - //coloring - std::string val; - if(Field.getEnums() && Field.getValue() >= 0) - val = Field.getValueAsString(); - - std::vector colorArrays; - colorArrays.push_back("None"); - - vtkPointData* point = poly->GetPointData(); - for(int i=0; iGetNumberOfArrays(); ++i) { - std::string FieldName = point->GetArrayName(i); - if (FieldName != "Texture Coordinates") - colorArrays.push_back(FieldName); - } - - vtkCellData* cell = poly->GetCellData(); - for(int i=0; iGetNumberOfArrays(); ++i) - colorArrays.push_back(cell->GetArrayName(i)); - - App::Enumeration empty; - Field.setValue(empty); - m_coloringEnum.setEnums(colorArrays); - Field.setValue(m_coloringEnum); - - std::vector::iterator it = std::find(colorArrays.begin(), colorArrays.end(), val); - if(!val.empty() && it != colorArrays.end()) - Field.setValue(val.c_str()); - - Field.purgeTouched(); - - //Vector mode - if(VectorMode.getEnums() && VectorMode.getValue() >= 0) - val = VectorMode.getValueAsString(); - - colorArrays.clear(); - if(Field.getValue() == 0) - colorArrays.push_back("Not a vector"); - else { - int array = Field.getValue() - 1; //0 is none - vtkPolyData* pd = m_currentAlgorithm->GetOutput(); - vtkDataArray* data = pd->GetPointData()->GetArray(array); - - if(data->GetNumberOfComponents() == 1) - colorArrays.push_back("Not a vector"); - else { - colorArrays.push_back("Magnitude"); - if(data->GetNumberOfComponents() >= 2) { - colorArrays.push_back("X"); - colorArrays.push_back("Y"); - } - if(data->GetNumberOfComponents() >= 3) - colorArrays.push_back("Z"); - } - } - - VectorMode.setValue(empty); - m_vectorEnum.setEnums(colorArrays); - VectorMode.setValue(m_vectorEnum); - - it = std::find(colorArrays.begin(), colorArrays.end(), val); - if(!val.empty() && it != colorArrays.end()) - VectorMode.setValue(val.c_str()); - - m_blockPropertyChanges = false; -} - -void ViewProviderFemPostObject::update3D() { - - vtkPolyData* pd = m_currentAlgorithm->GetOutput(); - - vtkPointData *pntData; - vtkPoints *points; - vtkDataArray *normals = NULL; - vtkDataArray *tcoords = NULL; - vtkCellArray *cells; - vtkIdType npts = 0; - vtkIdType *indx = 0; - - points = pd->GetPoints(); - pntData = pd->GetPointData(); - normals = pntData->GetNormals(); - tcoords = pntData->GetTCoords(); - - // write out point data if any - WritePointData(points, normals, tcoords); - bool ResetColorBarRange = true; - WriteColorData(ResetColorBarRange); - WriteTransparency(); - - // write out polys if any - if (pd->GetNumberOfPolys() > 0) { - - m_faces->coordIndex.startEditing(); - int soidx = 0; - cells = pd->GetPolys(); - for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { - - for (int i = 0; i < npts; i++) { - m_faces->coordIndex.set1Value(soidx, static_cast(indx[i])); - ++soidx; - } - m_faces->coordIndex.set1Value(soidx, -1); - ++soidx; - } - m_faces->coordIndex.setNum(soidx); - m_faces->coordIndex.finishEditing(); - } - else - m_faces->coordIndex.setNum(0); - - - // write out tstrips if any - if (pd->GetNumberOfStrips() > 0) { - - int soidx = 0; - cells = pd->GetStrips(); - m_triangleStrips->coordIndex.startEditing(); - for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { - - for (int i = 0; i < npts; i++) { - m_triangleStrips->coordIndex.set1Value(soidx, static_cast(indx[i])); - ++soidx; - } - m_triangleStrips->coordIndex.set1Value(soidx, -1); - ++soidx; - } - m_triangleStrips->coordIndex.setNum(soidx); - m_triangleStrips->coordIndex.finishEditing(); - } - else - m_triangleStrips->coordIndex.setNum(0); - - // write out lines if any - if (pd->GetNumberOfLines() > 0) { - - int soidx = 0; - cells = pd->GetLines(); - m_lines->coordIndex.startEditing(); - for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { - for (int i = 0; i < npts; i++) { - m_lines->coordIndex.set1Value(soidx, static_cast(indx[i])); - ++soidx; - } - m_lines->coordIndex.set1Value(soidx, -1); - ++soidx; - } - m_lines->coordIndex.setNum(soidx); - m_lines->coordIndex.finishEditing(); - } - else - m_lines->coordIndex.setNum(0); - - // write out verts if any - if (pd->GetNumberOfVerts() > 0){ - - int soidx = 0; - cells = pd->GetVerts(); - m_markers->coordIndex.startEditing(); - m_markers->coordIndex.setNum(pd->GetNumberOfVerts()); - for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { - m_markers->coordIndex.set1Value(soidx, static_cast(indx[0])); - ++soidx; - } - m_markers->coordIndex.finishEditing(); - } - else - m_markers->coordIndex.setNum(0); -} - -void ViewProviderFemPostObject::WritePointData(vtkPoints* points, vtkDataArray* normals, vtkDataArray* tcoords) { - - Q_UNUSED(tcoords) - double *p; - int i; - - if(!points) - return; - - m_coordinates->point.startEditing(); - m_coordinates->point.setNum(points->GetNumberOfPoints()); - for (i = 0; i < points->GetNumberOfPoints(); i++) { - p = points->GetPoint(i); - m_coordinates->point.set1Value(i, p[0], p[1], p[2]); - } - m_coordinates->point.finishEditing(); - - // write out the point normal data - if (normals) { - - m_normals->vector.startEditing(); - m_normals->vector.setNum(normals->GetNumberOfTuples()); - for (i = 0; i < normals->GetNumberOfTuples(); i++) { - p = normals->GetTuple(i); - m_normals->vector.set1Value(i, SbVec3f(p[0], p[1], p[2])); - } - m_normals->vector.finishEditing(); - - m_normalBinding->value = SoNormalBinding::PER_VERTEX_INDEXED; - m_normalBinding->value.touch(); - } -} - -void ViewProviderFemPostObject::WriteColorData(bool ResetColorBarRange) { - - if(!setupPipeline()) - return; - - if(Field.getEnumVector().empty() || Field.getValue() == 0) { - - m_material->diffuseColor.setValue(SbColor(0.8,0.8,0.8)); - m_material->transparency.setValue(0.); - m_materialBinding->value = SoMaterialBinding::OVERALL; - m_materialBinding->touch(); - return; - }; - - - int array = Field.getValue() - 1; //0 is none - vtkPolyData* pd = m_currentAlgorithm->GetOutput(); - vtkDataArray* data = pd->GetPointData()->GetArray(array); - - int component = VectorMode.getValue() - 1; //0 is either "Not a vector" or magnitude, for -1 is correct for magnitude. x y and z are one number too high - if(strcmp(VectorMode.getValueAsString(), "Not a vector")==0) - component = 0; - - //build the lookuptable - if (ResetColorBarRange == true) { - double range[2]; - data->GetRange(range, component); - m_colorBar->setRange(range[0], range[1]); - } - - m_material->diffuseColor.startEditing(); - - for (int i = 0; i < pd->GetNumberOfPoints(); i++) { - - double value = 0; - if(component >= 0) - value = data->GetComponent(i, component); - else { - for(int j=0; jGetNumberOfComponents(); ++j) - value += std::pow(data->GetComponent(i, j),2); - - value = std::sqrt(value); - } - App::Color c = m_colorBar->getColor(value); - m_material->diffuseColor.set1Value(i, c.r, c.g, c.b); - } - m_material->diffuseColor.finishEditing(); - m_materialBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; - m_materialBinding->touch(); -} - -void ViewProviderFemPostObject::WriteTransparency() { - - float trans = float(Transparency.getValue()) / 100.; - m_material->transparency.setValue(trans); -} - - - -void ViewProviderFemPostObject::updateData(const App::Property* p) { - - if( strcmp(p->getName(), "Data") == 0 ) { - update(); - } -} - -bool ViewProviderFemPostObject::setupPipeline() { - - vtkDataObject* data = static_cast(getObject())->Data.getValue(); - - if(!data) - return false; - - - m_outline->SetInputData(data); - m_surface->SetInputData(data); - m_wireframe->SetInputData(data); - m_points->SetInputData(data); - - return true; -} - - -void ViewProviderFemPostObject::onChanged(const App::Property* prop) { - - if(m_blockPropertyChanges) - return; - - bool ResetColorBarRange = true; - if(prop == &Field && setupPipeline()) { - updateProperties(); - WriteColorData(ResetColorBarRange); - WriteTransparency(); - } - else if(prop == &VectorMode && setupPipeline()) { - WriteColorData(ResetColorBarRange); - WriteTransparency(); - } - else if(prop == &Transparency) { - WriteTransparency(); - } - - ViewProviderDocumentObject::onChanged(prop); -} - -bool ViewProviderFemPostObject::doubleClicked(void) { - // work around for a problem in VTK implementation: https://forum.freecadweb.org/viewtopic.php?t=10587&start=130#p125688 - // check if backlight is enabled - ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); - bool isBackLightEnabled = hGrp->GetBool("EnableBacklight", false); - if (isBackLightEnabled == false) - Base::Console().Error("Backlight is not enabled. Due to a VTK implementation problem you really should consider to enable backlight in FreeCAD display preferences if you work with VTK post processing.\n"); - // set edit - Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default); - return true; -} - - -bool ViewProviderFemPostObject::setEdit(int ModNum) { - - if (ModNum == ViewProvider::Default || ModNum == 1 ) { - - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgPost *postDlg = qobject_cast(dlg); - if (postDlg && postDlg->getView() != this) - postDlg = 0; // another pad left open its task panel - if (dlg && !postDlg) { - QMessageBox msgBox; - msgBox.setText(QObject::tr("A dialog is already open in the task panel")); - msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); - msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - msgBox.setDefaultButton(QMessageBox::Yes); - int ret = msgBox.exec(); - if (ret == QMessageBox::Yes) - Gui::Control().reject(); - else - return false; - } - - // start the edit dialog - if (postDlg) - Gui::Control().showDialog(postDlg); - else { - postDlg = new TaskDlgPost(this); - setupTaskDialog(postDlg); - Gui::Control().showDialog(postDlg); - } - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - -void ViewProviderFemPostObject::setupTaskDialog(TaskDlgPost* dlg) { - - dlg->appendBox(new TaskPostDisplay(this)); -} - -void ViewProviderFemPostObject::unsetEdit(int ModNum) { - - if (ModNum == ViewProvider::Default) { - // and update the pad - //getSketchObject()->getDocument()->recompute(); - - // when pressing ESC make sure to close the dialog - Gui::Control().closeDialog(); - } - else { - ViewProviderDocumentObject::unsetEdit(ModNum); - } -} - -void ViewProviderFemPostObject::hide(void) { - Gui::ViewProviderDocumentObject::hide(); - m_colorStyle->style = SoDrawStyle::INVISIBLE; -} - -void ViewProviderFemPostObject::show(void) { - Gui::ViewProviderDocumentObject::show(); - m_colorStyle->style = SoDrawStyle::FILLED; -} - - -void ViewProviderFemPostObject::OnChange(Base::Subject< int >& /*rCaller*/, int /*rcReason*/) { - bool ResetColorBarRange = false; - WriteColorData(ResetColorBarRange); -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +# include +# include +# include +# include + +# include +#endif + +#include "ViewProviderFemPostObject.h" +#include "TaskPostBoxes.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace FemGui; + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostObject, Gui::ViewProviderDocumentObject) + +ViewProviderFemPostObject::ViewProviderFemPostObject() : m_blockPropertyChanges(false) +{ + //initialize the properties + ADD_PROPERTY_TYPE(Field,((long)0), "Coloring", App::Prop_None, "Select the field used for calculating the color"); + ADD_PROPERTY_TYPE(VectorMode,((long)0), "Coloring", App::Prop_None, "Select what to show for a vector field"); + ADD_PROPERTY(Transparency, (0)); + + sPixmap = "fem-femmesh-from-shape"; + + //create the subnodes which do the visualization work + m_shapeHints = new SoShapeHints(); + m_shapeHints->ref(); + m_shapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; + m_coordinates = new SoCoordinate3(); + m_coordinates->ref(); + m_materialBinding = new SoMaterialBinding(); + m_materialBinding->ref(); + m_material = new SoMaterial(); + m_material->ref(); + m_normalBinding = new SoNormalBinding(); + m_normalBinding->ref(); + m_normals = new SoNormal(); + m_normals->ref(); + m_faces = new SoIndexedFaceSet(); + m_faces->ref(); + m_triangleStrips = new SoIndexedTriangleStripSet(); + m_triangleStrips->ref(); + m_markers = new SoIndexedPointSet(); + m_markers->ref(); + m_lines = new SoIndexedLineSet(); + m_lines->ref(); + m_drawStyle = new SoDrawStyle(); + m_drawStyle->ref(); + m_drawStyle->lineWidth.setValue(2); + m_drawStyle->pointSize.setValue(3); + m_seperator = new SoSeparator(); + m_seperator->ref(); + + // simple color bar + m_colorRoot = new SoSeparator(); + m_colorRoot->ref(); + m_colorStyle = new SoDrawStyle(); + m_colorStyle->ref(); + m_colorRoot->addChild(m_colorStyle); + m_colorBar = new Gui::SoFCColorBar; + m_colorBar->Attach(this); + m_colorBar->ref(); + + //create the vtk algorithms we use for visualisation + m_outline = vtkSmartPointer::New(); + m_points = vtkSmartPointer::New(); + m_pointsSurface = vtkSmartPointer::New(); + m_surface = vtkSmartPointer::New(); + m_wireframe = vtkSmartPointer::New(); + m_wireframeSurface = vtkSmartPointer::New(); + m_surfaceEdges = vtkSmartPointer::New(); + m_pointsSurface->AddInputConnection(m_surface->GetOutputPort()); + m_wireframeSurface->AddInputConnection(m_surface->GetOutputPort()); + m_surfaceEdges->AddInputConnection(m_surface->GetOutputPort()); + m_surfaceEdges->AddInputConnection(m_wireframeSurface->GetOutputPort()); + + m_currentAlgorithm = m_outline; + + updateProperties(); // initialize the enums +} + +ViewProviderFemPostObject::~ViewProviderFemPostObject() +{ + m_shapeHints->unref(); + m_coordinates->unref(); + m_materialBinding->unref(); + m_drawStyle->unref(); + m_normalBinding->unref(); + m_normals->unref(); + m_faces->unref(); + m_triangleStrips->unref(); + m_markers->unref(); + m_lines->unref(); + m_seperator->unref(); + m_material->unref(); + m_colorBar->Detach(this); + m_colorBar->unref(); + m_colorStyle->unref(); + m_colorRoot->unref(); +} + +void ViewProviderFemPostObject::attach(App::DocumentObject *pcObj) +{ + ViewProviderDocumentObject::attach(pcObj); + + // face nodes + m_seperator->addChild(m_shapeHints); + m_seperator->addChild(m_drawStyle); + m_seperator->addChild(m_materialBinding); + m_seperator->addChild(m_material); + m_seperator->addChild(m_coordinates); + m_seperator->addChild(m_markers); + m_seperator->addChild(m_lines); + m_seperator->addChild(m_faces); + + // Check for an already existing color bar + Gui::SoFCColorBar* pcBar = ((Gui::SoFCColorBar*)findFrontRootOfType( Gui::SoFCColorBar::getClassTypeId() )); + if ( pcBar ) { + float fMin = m_colorBar->getMinValue(); + float fMax = m_colorBar->getMaxValue(); + + // Attach to the foreign color bar and delete our own bar + pcBar->Attach(this); + pcBar->ref(); + pcBar->setRange(fMin, fMax, 3); + pcBar->Notify(0); + m_colorBar->Detach(this); + m_colorBar->unref(); + m_colorBar = pcBar; + } + + m_colorRoot->addChild(m_colorBar); + + //all + addDisplayMaskMode(m_seperator, "Default"); + setDisplayMaskMode("Default"); + + setupPipeline(); +} + +SoSeparator* ViewProviderFemPostObject::getFrontRoot(void) const { + + return m_colorRoot; +} + + +void ViewProviderFemPostObject::setDisplayMode(const char* ModeName) +{ + if (strcmp("Outline",ModeName)==0) + m_currentAlgorithm = m_outline; + else if (strcmp("Surface with Edges",ModeName)==0) + m_currentAlgorithm = m_surfaceEdges; + else if (strcmp("Surface",ModeName)==0) + m_currentAlgorithm = m_surface; + else if (strcmp("Wireframe",ModeName)==0) + m_currentAlgorithm = m_wireframe; + else if (strcmp("Wireframe (surface only)",ModeName)==0) + m_currentAlgorithm = m_wireframeSurface; + else if (strcmp("Nodes",ModeName)==0) + m_currentAlgorithm = m_points; + else if (strcmp("Nodes (surface only)",ModeName)==0) + m_currentAlgorithm = m_pointsSurface; + + update(); + + ViewProviderDocumentObject::setDisplayMode( ModeName ); +} + +std::vector ViewProviderFemPostObject::getDisplayModes(void) const +{ + std::vector StrList; + StrList.push_back("Outline"); + StrList.push_back("Nodes"); + //StrList.push_back("Nodes (surface only)"); somehow this filter does not work + StrList.push_back("Surface"); + StrList.push_back("Surface with Edges"); + StrList.push_back("Wireframe"); + StrList.push_back("Wireframe (surface only)"); + return StrList; +} + +void ViewProviderFemPostObject::update() { + + if(!setupPipeline()) + return; + + m_currentAlgorithm->Update(); + updateProperties(); + update3D(); +} + +void ViewProviderFemPostObject::updateProperties() { + + m_blockPropertyChanges = true; + vtkPolyData* poly = m_currentAlgorithm->GetOutput(); + + //coloring + std::string val; + if(Field.getEnums() && Field.getValue() >= 0) + val = Field.getValueAsString(); + + std::vector colorArrays; + colorArrays.push_back("None"); + + vtkPointData* point = poly->GetPointData(); + for(int i=0; iGetNumberOfArrays(); ++i) { + std::string FieldName = point->GetArrayName(i); + if (FieldName != "Texture Coordinates") + colorArrays.push_back(FieldName); + } + + vtkCellData* cell = poly->GetCellData(); + for(int i=0; iGetNumberOfArrays(); ++i) + colorArrays.push_back(cell->GetArrayName(i)); + + App::Enumeration empty; + Field.setValue(empty); + m_coloringEnum.setEnums(colorArrays); + Field.setValue(m_coloringEnum); + + std::vector::iterator it = std::find(colorArrays.begin(), colorArrays.end(), val); + if(!val.empty() && it != colorArrays.end()) + Field.setValue(val.c_str()); + + Field.purgeTouched(); + + //Vector mode + if(VectorMode.getEnums() && VectorMode.getValue() >= 0) + val = VectorMode.getValueAsString(); + + colorArrays.clear(); + if(Field.getValue() == 0) + colorArrays.push_back("Not a vector"); + else { + int array = Field.getValue() - 1; //0 is none + vtkPolyData* pd = m_currentAlgorithm->GetOutput(); + vtkDataArray* data = pd->GetPointData()->GetArray(array); + + if(data->GetNumberOfComponents() == 1) + colorArrays.push_back("Not a vector"); + else { + colorArrays.push_back("Magnitude"); + if(data->GetNumberOfComponents() >= 2) { + colorArrays.push_back("X"); + colorArrays.push_back("Y"); + } + if(data->GetNumberOfComponents() >= 3) + colorArrays.push_back("Z"); + } + } + + VectorMode.setValue(empty); + m_vectorEnum.setEnums(colorArrays); + VectorMode.setValue(m_vectorEnum); + + it = std::find(colorArrays.begin(), colorArrays.end(), val); + if(!val.empty() && it != colorArrays.end()) + VectorMode.setValue(val.c_str()); + + m_blockPropertyChanges = false; +} + +void ViewProviderFemPostObject::update3D() { + + vtkPolyData* pd = m_currentAlgorithm->GetOutput(); + + vtkPointData *pntData; + vtkPoints *points; + vtkDataArray *normals = NULL; + vtkDataArray *tcoords = NULL; + vtkCellArray *cells; + vtkIdType npts = 0; + vtkIdType *indx = 0; + + points = pd->GetPoints(); + pntData = pd->GetPointData(); + normals = pntData->GetNormals(); + tcoords = pntData->GetTCoords(); + + // write out point data if any + WritePointData(points, normals, tcoords); + bool ResetColorBarRange = true; + WriteColorData(ResetColorBarRange); + WriteTransparency(); + + // write out polys if any + if (pd->GetNumberOfPolys() > 0) { + + m_faces->coordIndex.startEditing(); + int soidx = 0; + cells = pd->GetPolys(); + for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { + + for (int i = 0; i < npts; i++) { + m_faces->coordIndex.set1Value(soidx, static_cast(indx[i])); + ++soidx; + } + m_faces->coordIndex.set1Value(soidx, -1); + ++soidx; + } + m_faces->coordIndex.setNum(soidx); + m_faces->coordIndex.finishEditing(); + } + else + m_faces->coordIndex.setNum(0); + + + // write out tstrips if any + if (pd->GetNumberOfStrips() > 0) { + + int soidx = 0; + cells = pd->GetStrips(); + m_triangleStrips->coordIndex.startEditing(); + for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { + + for (int i = 0; i < npts; i++) { + m_triangleStrips->coordIndex.set1Value(soidx, static_cast(indx[i])); + ++soidx; + } + m_triangleStrips->coordIndex.set1Value(soidx, -1); + ++soidx; + } + m_triangleStrips->coordIndex.setNum(soidx); + m_triangleStrips->coordIndex.finishEditing(); + } + else + m_triangleStrips->coordIndex.setNum(0); + + // write out lines if any + if (pd->GetNumberOfLines() > 0) { + + int soidx = 0; + cells = pd->GetLines(); + m_lines->coordIndex.startEditing(); + for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { + for (int i = 0; i < npts; i++) { + m_lines->coordIndex.set1Value(soidx, static_cast(indx[i])); + ++soidx; + } + m_lines->coordIndex.set1Value(soidx, -1); + ++soidx; + } + m_lines->coordIndex.setNum(soidx); + m_lines->coordIndex.finishEditing(); + } + else + m_lines->coordIndex.setNum(0); + + // write out verts if any + if (pd->GetNumberOfVerts() > 0){ + + int soidx = 0; + cells = pd->GetVerts(); + m_markers->coordIndex.startEditing(); + m_markers->coordIndex.setNum(pd->GetNumberOfVerts()); + for (cells->InitTraversal(); cells->GetNextCell(npts,indx); ) { + m_markers->coordIndex.set1Value(soidx, static_cast(indx[0])); + ++soidx; + } + m_markers->coordIndex.finishEditing(); + } + else + m_markers->coordIndex.setNum(0); +} + +void ViewProviderFemPostObject::WritePointData(vtkPoints* points, vtkDataArray* normals, vtkDataArray* tcoords) { + + Q_UNUSED(tcoords) + double *p; + int i; + + if(!points) + return; + + m_coordinates->point.startEditing(); + m_coordinates->point.setNum(points->GetNumberOfPoints()); + for (i = 0; i < points->GetNumberOfPoints(); i++) { + p = points->GetPoint(i); + m_coordinates->point.set1Value(i, p[0], p[1], p[2]); + } + m_coordinates->point.finishEditing(); + + // write out the point normal data + if (normals) { + + m_normals->vector.startEditing(); + m_normals->vector.setNum(normals->GetNumberOfTuples()); + for (i = 0; i < normals->GetNumberOfTuples(); i++) { + p = normals->GetTuple(i); + m_normals->vector.set1Value(i, SbVec3f(p[0], p[1], p[2])); + } + m_normals->vector.finishEditing(); + + m_normalBinding->value = SoNormalBinding::PER_VERTEX_INDEXED; + m_normalBinding->value.touch(); + } +} + +void ViewProviderFemPostObject::WriteColorData(bool ResetColorBarRange) { + + if(!setupPipeline()) + return; + + if(Field.getEnumVector().empty() || Field.getValue() == 0) { + + m_material->diffuseColor.setValue(SbColor(0.8,0.8,0.8)); + m_material->transparency.setValue(0.); + m_materialBinding->value = SoMaterialBinding::OVERALL; + m_materialBinding->touch(); + return; + }; + + + int array = Field.getValue() - 1; //0 is none + vtkPolyData* pd = m_currentAlgorithm->GetOutput(); + vtkDataArray* data = pd->GetPointData()->GetArray(array); + + int component = VectorMode.getValue() - 1; //0 is either "Not a vector" or magnitude, for -1 is correct for magnitude. x y and z are one number too high + if(strcmp(VectorMode.getValueAsString(), "Not a vector")==0) + component = 0; + + //build the lookuptable + if (ResetColorBarRange == true) { + double range[2]; + data->GetRange(range, component); + m_colorBar->setRange(range[0], range[1]); + } + + m_material->diffuseColor.startEditing(); + + for (int i = 0; i < pd->GetNumberOfPoints(); i++) { + + double value = 0; + if(component >= 0) + value = data->GetComponent(i, component); + else { + for(int j=0; jGetNumberOfComponents(); ++j) + value += std::pow(data->GetComponent(i, j),2); + + value = std::sqrt(value); + } + App::Color c = m_colorBar->getColor(value); + m_material->diffuseColor.set1Value(i, c.r, c.g, c.b); + } + m_material->diffuseColor.finishEditing(); + m_materialBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED; + m_materialBinding->touch(); +} + +void ViewProviderFemPostObject::WriteTransparency() { + + float trans = float(Transparency.getValue()) / 100.; + m_material->transparency.setValue(trans); +} + + + +void ViewProviderFemPostObject::updateData(const App::Property* p) { + + if( strcmp(p->getName(), "Data") == 0 ) { + update(); + } +} + +bool ViewProviderFemPostObject::setupPipeline() { + + vtkDataObject* data = static_cast(getObject())->Data.getValue(); + + if(!data) + return false; + + + m_outline->SetInputData(data); + m_surface->SetInputData(data); + m_wireframe->SetInputData(data); + m_points->SetInputData(data); + + return true; +} + + +void ViewProviderFemPostObject::onChanged(const App::Property* prop) { + + if(m_blockPropertyChanges) + return; + + bool ResetColorBarRange = true; + if(prop == &Field && setupPipeline()) { + updateProperties(); + WriteColorData(ResetColorBarRange); + WriteTransparency(); + } + else if(prop == &VectorMode && setupPipeline()) { + WriteColorData(ResetColorBarRange); + WriteTransparency(); + } + else if(prop == &Transparency) { + WriteTransparency(); + } + + ViewProviderDocumentObject::onChanged(prop); +} + +bool ViewProviderFemPostObject::doubleClicked(void) { + // work around for a problem in VTK implementation: https://forum.freecadweb.org/viewtopic.php?t=10587&start=130#p125688 + // check if backlight is enabled + ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View"); + bool isBackLightEnabled = hGrp->GetBool("EnableBacklight", false); + if (isBackLightEnabled == false) + Base::Console().Error("Backlight is not enabled. Due to a VTK implementation problem you really should consider to enable backlight in FreeCAD display preferences if you work with VTK post processing.\n"); + // set edit + Gui::Application::Instance->activeDocument()->setEdit(this, (int)ViewProvider::Default); + return true; +} + + +bool ViewProviderFemPostObject::setEdit(int ModNum) { + + if (ModNum == ViewProvider::Default || ModNum == 1 ) { + + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgPost *postDlg = qobject_cast(dlg); + if (postDlg && postDlg->getView() != this) + postDlg = 0; // another pad left open its task panel + if (dlg && !postDlg) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } + + // start the edit dialog + if (postDlg) + Gui::Control().showDialog(postDlg); + else { + postDlg = new TaskDlgPost(this); + setupTaskDialog(postDlg); + Gui::Control().showDialog(postDlg); + } + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemPostObject::setupTaskDialog(TaskDlgPost* dlg) { + + dlg->appendBox(new TaskPostDisplay(this)); +} + +void ViewProviderFemPostObject::unsetEdit(int ModNum) { + + if (ModNum == ViewProvider::Default) { + // and update the pad + //getSketchObject()->getDocument()->recompute(); + + // when pressing ESC make sure to close the dialog + Gui::Control().closeDialog(); + } + else { + ViewProviderDocumentObject::unsetEdit(ModNum); + } +} + +void ViewProviderFemPostObject::hide(void) { + Gui::ViewProviderDocumentObject::hide(); + m_colorStyle->style = SoDrawStyle::INVISIBLE; +} + +void ViewProviderFemPostObject::show(void) { + Gui::ViewProviderDocumentObject::show(); + m_colorStyle->style = SoDrawStyle::FILLED; +} + + +void ViewProviderFemPostObject::OnChange(Base::Subject< int >& /*rCaller*/, int /*rcReason*/) { + bool ResetColorBarRange = false; + WriteColorData(ResetColorBarRange); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h index 89fe259b31..7ab69ba01e 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostObject.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostObject.h @@ -1,162 +1,162 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_VIEWPROVIDERFEMPOSTOBJECT_H -#define FEM_VIEWPROVIDERFEMPOSTOBJECT_H - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -class SoIndexedPointSet; -class vtkUnsignedCharArray; -class vtkDataArray; -class vtkPoints; -class SoSeparator; -class SoNormal; -class SoNormalBinding; -class SoMaterial; -class SoShapeHints; -class SoMaterialBinding; -class SoIndexedFaceSet; -class SoIndexedLineSet; -class SoIndexedMarkerSet; -class SoCoordinate3; -class SoDrawStyle; -class SoIndexedFaceSet; -class SoIndexedLineSet; -class SoIndexedTriangleStripSet; - -namespace Gui { - class SoFCColorBar; -} - -namespace FemGui -{ - -class TaskDlgPost; - -class FemGuiExport ViewProviderFemPostObject : public Gui::ViewProviderDocumentObject, - public Base::Observer -{ - PROPERTY_HEADER(FemGui::ViewProviderFemPostObject); - -public: - /// constructor. - ViewProviderFemPostObject(); - - /// destructor. - ~ViewProviderFemPostObject(); - - App::PropertyEnumeration Field; - App::PropertyEnumeration VectorMode; - App::PropertyPercent Transparency; - - void attach(App::DocumentObject *pcObject); - void setDisplayMode(const char* ModeName); - std::vector getDisplayModes() const; - void updateData(const App::Property*); - void onChanged(const App::Property* prop); - - //edit handling - virtual bool doubleClicked(void); - virtual bool setEdit(int ModNum); - virtual void unsetEdit(int ModNum); - - virtual void hide(void); - virtual void show(void); - - virtual SoSeparator* getFrontRoot(void) const; - - //observer for the color bar - virtual void OnChange(Base::Subject< int >& rCaller, int rcReason); - - /** @name Selection handling - * This group of methods do the selection handling. - * Here you can define how the selection for your ViewProvider - * works. - */ - //@{ -// /// indicates if the ViewProvider use the new Selection model -// virtual bool useNewSelectionModel(void) const {return true;} -// /// return a hit element to the selection path or 0 -// virtual std::string getElement(const SoDetail*) const; -// virtual SoDetail* getDetail(const char*) const; -// /// return the highlight lines for a given element or the whole shape -// virtual std::vector getSelectionShape(const char* Element) const; -// //@} - -protected: - virtual void setupTaskDialog(TaskDlgPost* dlg); - bool setupPipeline(); - void update(); - - SoCoordinate3* m_coordinates; - SoIndexedPointSet* m_markers; - SoIndexedLineSet* m_lines; - SoIndexedFaceSet* m_faces; - SoIndexedTriangleStripSet* m_triangleStrips; - SoMaterial* m_material; - SoMaterialBinding* m_materialBinding; - SoShapeHints* m_shapeHints; - SoNormalBinding* m_normalBinding; - SoNormal* m_normals; - SoDrawStyle* m_drawStyle; - SoSeparator* m_seperator; - Gui::SoFCColorBar* m_colorBar; - SoSeparator* m_colorRoot; - SoDrawStyle* m_colorStyle; - - vtkSmartPointer m_currentAlgorithm; - vtkSmartPointer m_surface; - vtkSmartPointer m_surfaceEdges; - vtkSmartPointer m_outline; - vtkSmartPointer m_wireframe, m_wireframeSurface; - vtkSmartPointer m_points, m_pointsSurface; - -private: - void updateProperties(); - void update3D(); - void WritePointData(vtkPoints *points, vtkDataArray *normals, - vtkDataArray *tcoords); - void WriteColorData(bool ResetColorBarRange); - void WriteTransparency(); - - App::Enumeration m_coloringEnum, m_vectorEnum; - bool m_blockPropertyChanges; -}; - -} //namespace FemGui - - -#endif // FEM_VIEWPROVIDERFEMPOSTOBJECT_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_VIEWPROVIDERFEMPOSTOBJECT_H +#define FEM_VIEWPROVIDERFEMPOSTOBJECT_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class SoIndexedPointSet; +class vtkUnsignedCharArray; +class vtkDataArray; +class vtkPoints; +class SoSeparator; +class SoNormal; +class SoNormalBinding; +class SoMaterial; +class SoShapeHints; +class SoMaterialBinding; +class SoIndexedFaceSet; +class SoIndexedLineSet; +class SoIndexedMarkerSet; +class SoCoordinate3; +class SoDrawStyle; +class SoIndexedFaceSet; +class SoIndexedLineSet; +class SoIndexedTriangleStripSet; + +namespace Gui { + class SoFCColorBar; +} + +namespace FemGui +{ + +class TaskDlgPost; + +class FemGuiExport ViewProviderFemPostObject : public Gui::ViewProviderDocumentObject, + public Base::Observer +{ + PROPERTY_HEADER(FemGui::ViewProviderFemPostObject); + +public: + /// constructor. + ViewProviderFemPostObject(); + + /// destructor. + ~ViewProviderFemPostObject(); + + App::PropertyEnumeration Field; + App::PropertyEnumeration VectorMode; + App::PropertyPercent Transparency; + + void attach(App::DocumentObject *pcObject); + void setDisplayMode(const char* ModeName); + std::vector getDisplayModes() const; + void updateData(const App::Property*); + void onChanged(const App::Property* prop); + + //edit handling + virtual bool doubleClicked(void); + virtual bool setEdit(int ModNum); + virtual void unsetEdit(int ModNum); + + virtual void hide(void); + virtual void show(void); + + virtual SoSeparator* getFrontRoot(void) const; + + //observer for the color bar + virtual void OnChange(Base::Subject< int >& rCaller, int rcReason); + + /** @name Selection handling + * This group of methods do the selection handling. + * Here you can define how the selection for your ViewProvider + * works. + */ + //@{ +// /// indicates if the ViewProvider use the new Selection model +// virtual bool useNewSelectionModel(void) const {return true;} +// /// return a hit element to the selection path or 0 +// virtual std::string getElement(const SoDetail*) const; +// virtual SoDetail* getDetail(const char*) const; +// /// return the highlight lines for a given element or the whole shape +// virtual std::vector getSelectionShape(const char* Element) const; +// //@} + +protected: + virtual void setupTaskDialog(TaskDlgPost* dlg); + bool setupPipeline(); + void update(); + + SoCoordinate3* m_coordinates; + SoIndexedPointSet* m_markers; + SoIndexedLineSet* m_lines; + SoIndexedFaceSet* m_faces; + SoIndexedTriangleStripSet* m_triangleStrips; + SoMaterial* m_material; + SoMaterialBinding* m_materialBinding; + SoShapeHints* m_shapeHints; + SoNormalBinding* m_normalBinding; + SoNormal* m_normals; + SoDrawStyle* m_drawStyle; + SoSeparator* m_seperator; + Gui::SoFCColorBar* m_colorBar; + SoSeparator* m_colorRoot; + SoDrawStyle* m_colorStyle; + + vtkSmartPointer m_currentAlgorithm; + vtkSmartPointer m_surface; + vtkSmartPointer m_surfaceEdges; + vtkSmartPointer m_outline; + vtkSmartPointer m_wireframe, m_wireframeSurface; + vtkSmartPointer m_points, m_pointsSurface; + +private: + void updateProperties(); + void update3D(); + void WritePointData(vtkPoints *points, vtkDataArray *normals, + vtkDataArray *tcoords); + void WriteColorData(bool ResetColorBarRange); + void WriteTransparency(); + + App::Enumeration m_coloringEnum, m_vectorEnum; + bool m_blockPropertyChanges; +}; + +} //namespace FemGui + + +#endif // FEM_VIEWPROVIDERFEMPOSTOBJECT_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp index 1aebd6d5c3..04d5292f1b 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.cpp @@ -1,90 +1,90 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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 "ViewProviderFemPostPipeline.h" -#include "ViewProviderFemPostFunction.h" -#include -#include -#include - -using namespace FemGui; - - -PROPERTY_SOURCE(FemGui::ViewProviderFemPostPipeline, FemGui::ViewProviderFemPostObject) - -ViewProviderFemPostPipeline::ViewProviderFemPostPipeline() -{ - sPixmap = "fem-post-data-pipline"; -} - -ViewProviderFemPostPipeline::~ViewProviderFemPostPipeline() -{ -} - -std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren(void) const { - - Fem::FemPostPipeline* pipeline = static_cast(getObject()); - std::vector children; - - if(pipeline->Functions.getValue()) - children.push_back(pipeline->Functions.getValue()); - - children.insert(children.end(), pipeline->Filter.getValues().begin(), pipeline->Filter.getValues().end()); - return children; -} - -std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren3D(void) const { - - return claimChildren(); -} - -void ViewProviderFemPostPipeline::updateData(const App::Property* prop) { - FemGui::ViewProviderFemPostObject::onChanged(prop); - - if(strcmp(prop->getName(), "Function") == 0) { - updateFunctionSize(); - } - -} - -void ViewProviderFemPostPipeline::updateFunctionSize() { - - //we need to get the bounding box and set the function provider size - Fem::FemPostPipeline* obj = static_cast(getObject()); - - if(!obj->Functions.getValue() || !obj->Functions.getValue()->isDerivedFrom(Fem::FemPostFunctionProvider::getClassTypeId())) - return; - - //get the function provider - FemGui::ViewProviderFemPostFunctionProvider* vp = static_cast( - Gui::Application::Instance->getViewProvider(obj->Functions.getValue())); - - if(obj->Data.getValue() && obj->Data.getValue()->IsA("vtkDataSet")) { - vtkBoundingBox box = obj->getBoundingBox(); - - vp->SizeX.setValue(box.GetLength(0)*1.2); - vp->SizeY.setValue(box.GetLength(1)*1.2); - vp->SizeZ.setValue(box.GetLength(2)*1.2); - } -} +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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 "ViewProviderFemPostPipeline.h" +#include "ViewProviderFemPostFunction.h" +#include +#include +#include + +using namespace FemGui; + + +PROPERTY_SOURCE(FemGui::ViewProviderFemPostPipeline, FemGui::ViewProviderFemPostObject) + +ViewProviderFemPostPipeline::ViewProviderFemPostPipeline() +{ + sPixmap = "fem-post-data-pipline"; +} + +ViewProviderFemPostPipeline::~ViewProviderFemPostPipeline() +{ +} + +std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren(void) const { + + Fem::FemPostPipeline* pipeline = static_cast(getObject()); + std::vector children; + + if(pipeline->Functions.getValue()) + children.push_back(pipeline->Functions.getValue()); + + children.insert(children.end(), pipeline->Filter.getValues().begin(), pipeline->Filter.getValues().end()); + return children; +} + +std::vector< App::DocumentObject* > ViewProviderFemPostPipeline::claimChildren3D(void) const { + + return claimChildren(); +} + +void ViewProviderFemPostPipeline::updateData(const App::Property* prop) { + FemGui::ViewProviderFemPostObject::onChanged(prop); + + if(strcmp(prop->getName(), "Function") == 0) { + updateFunctionSize(); + } + +} + +void ViewProviderFemPostPipeline::updateFunctionSize() { + + //we need to get the bounding box and set the function provider size + Fem::FemPostPipeline* obj = static_cast(getObject()); + + if(!obj->Functions.getValue() || !obj->Functions.getValue()->isDerivedFrom(Fem::FemPostFunctionProvider::getClassTypeId())) + return; + + //get the function provider + FemGui::ViewProviderFemPostFunctionProvider* vp = static_cast( + Gui::Application::Instance->getViewProvider(obj->Functions.getValue())); + + if(obj->Data.getValue() && obj->Data.getValue()->IsA("vtkDataSet")) { + vtkBoundingBox box = obj->getBoundingBox(); + + vp->SizeX.setValue(box.GetLength(0)*1.2); + vp->SizeY.setValue(box.GetLength(1)*1.2); + vp->SizeZ.setValue(box.GetLength(2)*1.2); + } +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h index 15290227b6..9d7126a569 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h +++ b/src/Mod/Fem/Gui/ViewProviderFemPostPipeline.h @@ -1,53 +1,53 @@ -/*************************************************************************** - * Copyright (c) 2015 Stefan Tröger * - * * - * 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_VIEWPROVIDERFEMPOSTPIPELINE_H -#define FEM_VIEWPROVIDERFEMPOSTPIPELINE_H - -#include "ViewProviderFemPostObject.h" - -namespace FemGui -{ - -class FemGuiExport ViewProviderFemPostPipeline : public ViewProviderFemPostObject { - - PROPERTY_HEADER(FemGui::ViewProviderFemPostPipeline); - -public: - /// constructor. - ViewProviderFemPostPipeline(); - ~ViewProviderFemPostPipeline(); - - virtual std::vector< App::DocumentObject* > claimChildren(void) const; - virtual std::vector< App::DocumentObject* > claimChildren3D(void) const; - virtual void updateData(const App::Property* prop); - -protected: - void updateFunctionSize(); - -}; - -} //namespace FemGui - - -#endif // FEM_VIEWPROVIDERFEMPOSTPIPELINE_H +/*************************************************************************** + * Copyright (c) 2015 Stefan Tröger * + * * + * 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_VIEWPROVIDERFEMPOSTPIPELINE_H +#define FEM_VIEWPROVIDERFEMPOSTPIPELINE_H + +#include "ViewProviderFemPostObject.h" + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemPostPipeline : public ViewProviderFemPostObject { + + PROPERTY_HEADER(FemGui::ViewProviderFemPostPipeline); + +public: + /// constructor. + ViewProviderFemPostPipeline(); + ~ViewProviderFemPostPipeline(); + + virtual std::vector< App::DocumentObject* > claimChildren(void) const; + virtual std::vector< App::DocumentObject* > claimChildren3D(void) const; + virtual void updateData(const App::Property* prop); + +protected: + void updateFunctionSize(); + +}; + +} //namespace FemGui + + +#endif // FEM_VIEWPROVIDERFEMPOSTPIPELINE_H diff --git a/src/Mod/Fem/femtest/data/ccx/spine_points.csv b/src/Mod/Fem/femtest/data/ccx/spine_points.csv index 59fa48e362..c34b0e4e8d 100644 --- a/src/Mod/Fem/femtest/data/ccx/spine_points.csv +++ b/src/Mod/Fem/femtest/data/ccx/spine_points.csv @@ -1,45 +1,45 @@ -1,203.2,25.4,0 -2,203.2,25.4,25.4 -3,203.2,0,0 -4,203.2,0,25.4 -5,0,25.4,0 -6,0,25.4,25.4 -7,0,0,0 -8,0,0,25.4 -9,98.3488,25.4,25.4 -10,102.616,0,25.4 -11,98.3488,25.4,0 -12,102.616,0,0 -13,0,12.7,25.4 -14,49.1744,25.4,25.4 -15,150.774,25.4,25.4 -16,203.2,12.7,25.4 -17,51.308,0,25.4 -18,152.908,0,25.4 -19,0,12.7,0 -20,49.1744,25.4,0 -21,150.774,25.4,0 -22,203.2,12.7,0 -23,51.308,0,0 -24,152.908,0,0 -25,203.2,25.4,12.7 -26,0,25.4,12.7 -27,203.2,0,12.7 -28,0,0,12.7 -29,0,12.7,12.7 -30,51.308,12.7,25.4 -31,100.482,12.7,25.4 -32,152.908,12.7,25.4 -33,51.308,12.7,0 -34,100.482,12.7,0 -35,152.908,12.7,0 -36,203.2,12.7,12.7 -37,49.1744,25.4,12.7 -38,150.774,25.4,12.7 -39,98.3488,25.4,12.7 -40,51.308,0,12.7 -41,152.908,0,12.7 -42,102.616,0,12.7 -43,51.308,12.7,12.7 -44,100.482,12.7,12.7 -45,152.908,12.7,12.7 +1,203.2,25.4,0 +2,203.2,25.4,25.4 +3,203.2,0,0 +4,203.2,0,25.4 +5,0,25.4,0 +6,0,25.4,25.4 +7,0,0,0 +8,0,0,25.4 +9,98.3488,25.4,25.4 +10,102.616,0,25.4 +11,98.3488,25.4,0 +12,102.616,0,0 +13,0,12.7,25.4 +14,49.1744,25.4,25.4 +15,150.774,25.4,25.4 +16,203.2,12.7,25.4 +17,51.308,0,25.4 +18,152.908,0,25.4 +19,0,12.7,0 +20,49.1744,25.4,0 +21,150.774,25.4,0 +22,203.2,12.7,0 +23,51.308,0,0 +24,152.908,0,0 +25,203.2,25.4,12.7 +26,0,25.4,12.7 +27,203.2,0,12.7 +28,0,0,12.7 +29,0,12.7,12.7 +30,51.308,12.7,25.4 +31,100.482,12.7,25.4 +32,152.908,12.7,25.4 +33,51.308,12.7,0 +34,100.482,12.7,0 +35,152.908,12.7,0 +36,203.2,12.7,12.7 +37,49.1744,25.4,12.7 +38,150.774,25.4,12.7 +39,98.3488,25.4,12.7 +40,51.308,0,12.7 +41,152.908,0,12.7 +42,102.616,0,12.7 +43,51.308,12.7,12.7 +44,100.482,12.7,12.7 +45,152.908,12.7,12.7 diff --git a/src/Mod/Fem/femtest/data/ccx/spine_volumes.csv b/src/Mod/Fem/femtest/data/ccx/spine_volumes.csv index 314f14cede..0c0eb6fa4e 100644 --- a/src/Mod/Fem/femtest/data/ccx/spine_volumes.csv +++ b/src/Mod/Fem/femtest/data/ccx/spine_volumes.csv @@ -1,12 +1,12 @@ -1,5,6,12,11,26,43,33,20,37,34 -2,9,12,11,2,44,34,39,15,45,38 -3,3,4,1,12,27,36,22,24,41,35 -4,2,12,11,1,45,34,38,25,35,21 -5,2,12,1,4,45,35,25,16,41,36 -6,9,12,2,10,44,45,15,31,42,32 -7,2,12,4,10,45,41,16,32,42,18 -8,9,12,10,6,44,42,31,14,43,30 -9,9,12,6,11,44,43,14,39,34,37 -10,6,7,5,12,29,19,26,43,23,33 -11,8,7,6,12,28,29,13,40,23,43 -12,12,10,6,8,42,30,43,40,17,13 +1,5,6,12,11,26,43,33,20,37,34 +2,9,12,11,2,44,34,39,15,45,38 +3,3,4,1,12,27,36,22,24,41,35 +4,2,12,11,1,45,34,38,25,35,21 +5,2,12,1,4,45,35,25,16,41,36 +6,9,12,2,10,44,45,15,31,42,32 +7,2,12,4,10,45,41,16,32,42,18 +8,9,12,10,6,44,42,31,14,43,30 +9,9,12,6,11,44,43,14,39,34,37 +10,6,7,5,12,29,19,26,43,23,33 +11,8,7,6,12,28,29,13,40,23,43 +12,12,10,6,8,42,30,43,40,17,13