From d48542cf5659359774d920580ccecd283a22b90a Mon Sep 17 00:00:00 2001 From: jrheinlaender Date: Wed, 20 Feb 2013 20:24:38 +0430 Subject: [PATCH] Split code into separate files for each constraint type --- src/Mod/Fem/App/AppFem.cpp | 11 +- src/Mod/Fem/App/CMakeLists.txt | 18 +- src/Mod/Fem/App/FemConstraint.cpp | 252 +++++- src/Mod/Fem/App/FemConstraint.h | 25 +- src/Mod/Fem/App/FemConstraintBearing.cpp | 116 +++ src/Mod/Fem/App/FemConstraintBearing.h | 68 ++ src/Mod/Fem/App/FemConstraintFixed.cpp | 83 ++ src/Mod/Fem/App/FemConstraintFixed.h | 63 ++ src/Mod/Fem/App/FemConstraintForce.cpp | 125 +++ src/Mod/Fem/App/FemConstraintForce.h | 69 ++ src/Mod/Fem/App/FemConstraintGear.cpp | 58 ++ src/Mod/Fem/App/FemConstraintGear.h | 61 ++ src/Mod/Fem/App/FemConstraintPulley.cpp | 69 ++ src/Mod/Fem/App/FemConstraintPulley.h | 65 ++ src/Mod/Fem/Gui/AppFemGui.cpp | 10 + src/Mod/Fem/Gui/CMakeLists.txt | 65 +- src/Mod/Fem/Gui/Command.cpp | 156 +++- src/Mod/Fem/Gui/TaskFemConstraint.cpp | 639 +------------ src/Mod/Fem/Gui/TaskFemConstraint.h | 64 +- src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp | 345 +++++++ src/Mod/Fem/Gui/TaskFemConstraintBearing.h | 93 ++ .../Fem/Gui/TaskFemConstraintCylindrical.ui | 161 ++++ src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp | 217 +++++ src/Mod/Fem/Gui/TaskFemConstraintFixed.h | 84 ++ src/Mod/Fem/Gui/TaskFemConstraintFixed.ui | 44 + src/Mod/Fem/Gui/TaskFemConstraintForce.cpp | 363 ++++++++ src/Mod/Fem/Gui/TaskFemConstraintForce.h | 92 ++ src/Mod/Fem/Gui/TaskFemConstraintForce.ui | 89 ++ src/Mod/Fem/Gui/TaskFemConstraintGear.cpp | 150 ++++ src/Mod/Fem/Gui/TaskFemConstraintGear.h | 78 ++ src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp | 185 ++++ src/Mod/Fem/Gui/TaskFemConstraintPulley.h | 82 ++ src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp | 847 +++++------------- src/Mod/Fem/Gui/ViewProviderFemConstraint.h | 46 +- .../Gui/ViewProviderFemConstraintBearing.cpp | 142 +++ .../Gui/ViewProviderFemConstraintBearing.h | 74 ++ .../Gui/ViewProviderFemConstraintFixed.cpp | 147 +++ .../Fem/Gui/ViewProviderFemConstraintFixed.h | 74 ++ .../Gui/ViewProviderFemConstraintForce.cpp | 196 ++++ .../Fem/Gui/ViewProviderFemConstraintForce.h | 78 ++ .../Fem/Gui/ViewProviderFemConstraintGear.cpp | 154 ++++ .../Fem/Gui/ViewProviderFemConstraintGear.h | 74 ++ .../Gui/ViewProviderFemConstraintPulley.cpp | 166 ++++ .../Fem/Gui/ViewProviderFemConstraintPulley.h | 74 ++ src/Mod/Fem/Gui/Workbench.cpp | 12 +- src/Mod/PartDesign/WizardShaft/InitGui.py | 76 -- 46 files changed, 4703 insertions(+), 1457 deletions(-) create mode 100644 src/Mod/Fem/App/FemConstraintBearing.cpp create mode 100644 src/Mod/Fem/App/FemConstraintBearing.h create mode 100644 src/Mod/Fem/App/FemConstraintFixed.cpp create mode 100644 src/Mod/Fem/App/FemConstraintFixed.h create mode 100644 src/Mod/Fem/App/FemConstraintForce.cpp create mode 100644 src/Mod/Fem/App/FemConstraintForce.h create mode 100644 src/Mod/Fem/App/FemConstraintGear.cpp create mode 100644 src/Mod/Fem/App/FemConstraintGear.h create mode 100644 src/Mod/Fem/App/FemConstraintPulley.cpp create mode 100644 src/Mod/Fem/App/FemConstraintPulley.h create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintBearing.h create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintCylindrical.ui create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintFixed.h create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintFixed.ui create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintForce.cpp create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintForce.h create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintForce.ui create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintGear.cpp create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintGear.h create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp create mode 100644 src/Mod/Fem/Gui/TaskFemConstraintPulley.h create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp create mode 100644 src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h delete mode 100644 src/Mod/PartDesign/WizardShaft/InitGui.py diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index 7a29fcada..8f8d024eb 100755 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -41,7 +41,11 @@ #include "FemSetNodesObject.h" #include "HypothesisPy.h" -#include "FemConstraint.h" +#include "FemConstraintBearing.h" +#include "FemConstraintFixed.h" +#include "FemConstraintForce.h" +#include "FemConstraintGear.h" +#include "FemConstraintPulley.h" extern struct PyMethodDef Fem_methods[]; @@ -117,6 +121,11 @@ void AppFemExport initFem() Fem::FemSetNodesObject ::init(); Fem::Constraint ::init(); + Fem::ConstraintBearing ::init(); + Fem::ConstraintFixed ::init(); + Fem::ConstraintForce ::init(); + Fem::ConstraintGear ::init(); + Fem::ConstraintPulley ::init(); } } // extern "C" diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index ba1688999..62dd1bf10 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -24,10 +24,10 @@ set(Fem_LIBS Mesh FreeCADApp ) - -if(SMESH_FOUND) - include_directories( ${SMESH_INCLUDE_DIR} ) - list( APPEND Fem_LIBS ${SMESH_LIBRARIES} ) + +if(SMESH_FOUND) + include_directories( ${SMESH_INCLUDE_DIR} ) + list( APPEND Fem_LIBS ${SMESH_LIBRARIES} ) endif(SMESH_FOUND) generate_from_xml(FemMeshPy) @@ -66,6 +66,16 @@ SET(Fem_SRCS FemMeshProperty.h FemConstraint.cpp FemConstraint.h + FemConstraintBearing.h + FemConstraintBearing.cpp + FemConstraintFixed.cpp + FemConstraintFixed.h + FemConstraintForce.cpp + FemConstraintForce.h + FemConstraintGear.cpp + FemConstraintGear.h + FemConstraintPulley.cpp + FemConstraintPulley.h ${Mod_SRCS} ${Python_SRCS} ) diff --git a/src/Mod/Fem/App/FemConstraint.cpp b/src/Mod/Fem/App/FemConstraint.cpp index ae9ef45ec..008c0ec2a 100644 --- a/src/Mod/Fem/App/FemConstraint.cpp +++ b/src/Mod/Fem/App/FemConstraint.cpp @@ -24,33 +24,46 @@ #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 +# include +# include #endif #include "FemConstraint.h" +#include #include using namespace Fem; -const char* Constraint::TypeEnums[]= {"Force on geometry","Fixed", - "Bearing (radial free)", "Bearing (radial fixed)", - "Pulley", "Gear (straight toothed)", NULL}; - PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject); Constraint::Constraint() { - ADD_PROPERTY(Type,((long)0)); - Type.setEnums(TypeEnums); - ADD_PROPERTY(Force,(0.0)); ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); - ADD_PROPERTY_TYPE(Direction,(0),"Constraint",(App::PropertyType)(App::Prop_None),"Element giving direction of constraint"); - ADD_PROPERTY(Reversed,(0)); - ADD_PROPERTY(Distance,(0.0)); - ADD_PROPERTY_TYPE(Location,(0),"Constraint",(App::PropertyType)(App::Prop_None),"Element giving location where constraint is applied"); - ADD_PROPERTY(Diameter,(0.0)); - ADD_PROPERTY(OtherDiameter,(0.0)); - ADD_PROPERTY(CenterDistance,(0.0)); + ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3f(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid"); } Constraint::~Constraint() @@ -59,12 +72,219 @@ Constraint::~Constraint() App::DocumentObjectExecReturn *Constraint::execute(void) { - // Ensure that the constraint symbols follow the changed geometry References.touch(); - return DocumentObject::StdReturn; + return StdReturn; } void Constraint::onChanged(const App::Property* prop) { + //Base::Console().Error("Constraint::onChanged()\n"); + if (prop == &References) { + Base::Console().Error("References\n"); + // 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 (int 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._Shape.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... + DocumentObject::onChanged(prop); + return; + } + } + } + } + DocumentObject::onChanged(prop); } + +void Constraint::onDocumentRestored() +{ + Base::Console().Error("onDocumentRestored\n"); +} + + +void Constraint::onSettingDocument() +{ + Base::Console().Error("onSettingDocument\n"); +} + +void Constraint::getPoints(std::vector &points, std::vector &normals) const +{ + std::vector Objects = References.getValues(); + std::vector SubElements = References.getSubValues(); + + // Extract geometry from References + TopoDS_Shape sh; + + for (int i = 0; i < Objects.size(); i++) { + App::DocumentObject* obj = Objects[i]; + Part::Feature* feat = static_cast(obj); + const Part::TopoShape& toposhape = feat->Shape.getShape(); + 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.push_back(Base::Vector3f(p.X(), p.Y(), p.Z())); + normals.push_back(NormalDirection.getValue()); + } 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 >= 20) + steps = round(l / 10); + else + steps = 1; + double step = (lp - fp) / steps; + for (int i = 0; i < steps + 1; i++) { + gp_Pnt p = curve.Value(i * step); + points.push_back(Base::Vector3f(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(); + // 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, GeomAbs_IsoU, vfp); + double l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); + isoc.Load(GeomAbs_IsoU, vlp); + double lv = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; + isoc.Load(GeomAbs_IsoV, ufp); + l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()); + isoc.Load(GeomAbs_IsoV, ulp); + double lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0; + int stepsv; + if (lv >= 20.0) + stepsv = round(lv / 10); + else + stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed + int stepsu; + if (lu >= 20.0) + stepsu = round(lu / 10); + else + stepsu = 2; + 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.push_back(Base::Vector3f(p.X(), p.Y(), p.Z())); + props.Normal(u, v,center,normal); + normal.Normalize(); + normals.push_back(Base::Vector3f(normal.X(), normal.Y(), normal.Z())); + } + } + } + } + } +} + +void Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const +{ + std::vector Objects = References.getValues(); + std::vector SubElements = References.getSubValues(); + if (Objects.empty()) + return; + App::DocumentObject* obj = Objects[0]; + Part::Feature* feat = static_cast(obj); + TopoDS_Shape sh = feat->Shape.getShape().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::Vector3f(b.X(), b.Y(), b.Z()); + gp_Dir dir = cyl.Axis().Direction(); + axis = Base::Vector3f(dir.X(), dir.Y(), dir.Z()); +} + +Base::Vector3f Constraint::getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis, + const App::PropertyLinkSub& location, const float& dist) +{ + // Get the point specified by Location and Distance + App::DocumentObject* objLoc = location.getValue(); + std::string subName = location.getSubValues().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::Vector3f(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::Vector3f(0,0,0); + gp_Pnt inter = intersector.Point(1); + return Base::Vector3f(inter.X(), inter.Y(), inter.Z()); +} diff --git a/src/Mod/Fem/App/FemConstraint.h b/src/Mod/Fem/App/FemConstraint.h index 625ba95ae..02c0bfd9d 100644 --- a/src/Mod/Fem/App/FemConstraint.h +++ b/src/Mod/Fem/App/FemConstraint.h @@ -24,8 +24,10 @@ #ifndef FEM_CONSTRAINT_H #define FEM_CONSTRAINT_H +#include #include #include +#include namespace Fem { @@ -39,30 +41,29 @@ public: Constraint(void); virtual ~Constraint(); - App::PropertyEnumeration Type; App::PropertyLinkSubList References; - App::PropertyFloat Force; - App::PropertyLinkSub Direction; - App::PropertyBool Reversed; - App::PropertyLinkSub Location; - App::PropertyFloat Distance; - App::PropertyFloat Diameter; - App::PropertyFloat OtherDiameter; - App::PropertyFloat CenterDistance; + App::PropertyVector NormalDirection; /// recalculate the object virtual App::DocumentObjectExecReturn *execute(void); /// returns the type name of the ViewProvider - const char* getViewProviderName(void) const { + virtual const char* getViewProviderName(void) const { return "FemGui::ViewProviderFemConstraint"; } protected: virtual void onChanged(const App::Property* prop); + virtual void onDocumentRestored(); + virtual void onSettingDocument(); + +protected: + /// Calculate the points where symbols should be drawn + void getPoints(std::vector& points, std::vector& normals) const; + void getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const; + Base::Vector3f getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis, + const App::PropertyLinkSub &location, const float& dist); -private: - static const char* TypeEnums[]; }; } //namespace Fem diff --git a/src/Mod/Fem/App/FemConstraintBearing.cpp b/src/Mod/Fem/App/FemConstraintBearing.cpp new file mode 100644 index 000000000..3ecf7ea4c --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintBearing.cpp @@ -0,0 +1,116 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintBearing.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintBearing, Fem::Constraint); + +ConstraintBearing::ConstraintBearing() +{ + ADD_PROPERTY_TYPE(Location,(0),"ConstraintBearing",(App::PropertyType)(App::Prop_None), + "Element giving axial location of constraint"); + ADD_PROPERTY(Dist,(0.0)); + ADD_PROPERTY(AxialFree,(0)); + ADD_PROPERTY(Radius,(0.0)); + ADD_PROPERTY(Height,(0.0)); + ADD_PROPERTY_TYPE(BasePoint,(Base::Vector3f(0,0,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Base point of cylindrical bearing seat"); + ADD_PROPERTY_TYPE(Axis,(Base::Vector3f(0,1,0)),"ConstraintBearing",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Axis of bearing seat"); +} + +App::DocumentObjectExecReturn *ConstraintBearing::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintBearing::onChanged(const App::Property* prop) +{ + // Note: If we call this at the end, then the symbol ist not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + // Find data of cylinder + float radius, height; + Base::Vector3f base, axis; + getCylinder(radius, height, base, axis); + Radius.setValue(radius); + Axis.setValue(axis); + Height.setValue(height); + // Update base point + base = base + axis * height/2; + if (Location.getValue() != NULL) { + base = getBasePoint(base, axis, Location, Dist.getValue()); + } + Base::Console().Error("Basepoint2: %f, %f, %f\n", base.x, base.y, base.z); + BasePoint.setValue(base); + BasePoint.touch(); // This triggers ViewProvider::updateData() + } else if ((prop == &Location) || (prop == &Dist)) { + App::DocumentObject* obj = Location.getValue(); + std::vector names = Location.getSubValues(); + if (names.size() == 0) { + return; + } + std::string subName = names.front(); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape sh = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (sh.ShapeType() == TopAbs_FACE) { + BRepAdaptor_Surface surface(TopoDS::Face(sh)); + if (surface.GetType() != GeomAbs_Plane) { + return; // "Location must be a planar face or linear edge" + } + } else if (sh.ShapeType() == TopAbs_EDGE) { + BRepAdaptor_Curve line(TopoDS::Edge(sh)); + if (line.GetType() != GeomAbs_Line) { + return; // "Location must be a planar face or linear edge" + } + } + + float radius, height; + Base::Vector3f base, axis; + getCylinder(radius, height, base, axis); + base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue()); + Base::Console().Error("Basepoint: %f, %f, %f\n", base.x, base.y, base.z); + BasePoint.setValue(base); + BasePoint.touch(); + } +} diff --git a/src/Mod/Fem/App/FemConstraintBearing.h b/src/Mod/Fem/App/FemConstraintBearing.h new file mode 100644 index 000000000..6385e6b48 --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintBearing.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTBEARING_H +#define FEM_CONSTRAINTBEARING_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintBearing : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintBearing); + +public: + /// Constructor + ConstraintBearing(void); + + App::PropertyLinkSub Location; + App::PropertyFloat Dist; + App::PropertyBool AxialFree; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyFloat Radius; + App::PropertyFloat Height; + App::PropertyVector BasePoint; + App::PropertyVector Axis; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintBearing"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTBEARING_H diff --git a/src/Mod/Fem/App/FemConstraintFixed.cpp b/src/Mod/Fem/App/FemConstraintFixed.cpp new file mode 100644 index 000000000..1cde0061f --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintFixed.cpp @@ -0,0 +1,83 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintFixed.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintFixed, Fem::Constraint); + +ConstraintFixed::ConstraintFixed() +{ + ADD_PROPERTY_TYPE(Points,(Base::Vector3f()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Points where symbols are drawn"); + ADD_PROPERTY_TYPE(Normals,(Base::Vector3f()),"ConstraintFixed",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Normals where symbols are drawn"); + Points.setValues(std::vector()); + Normals.setValues(std::vector()); +} + +App::DocumentObjectExecReturn *ConstraintFixed::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintFixed::onChanged(const App::Property* prop) +{ + // Note: If we call this at the end, then the symbols are not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + std::vector points; + std::vector normals; + getPoints(points, normals); + Points.setValues(points); + Normals.setValues(normals); + Points.touch(); // This triggers ViewProvider::updateData() + } +} diff --git a/src/Mod/Fem/App/FemConstraintFixed.h b/src/Mod/Fem/App/FemConstraintFixed.h new file mode 100644 index 000000000..0294fbdaa --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintFixed.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTFIXED_H +#define FEM_CONSTRAINTFIXED_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintFixed : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintFixed); + +public: + /// Constructor + ConstraintFixed(void); + + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVectorList Points; + App::PropertyVectorList Normals; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintFixed"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTFIXED_H diff --git a/src/Mod/Fem/App/FemConstraintForce.cpp b/src/Mod/Fem/App/FemConstraintForce.cpp new file mode 100644 index 000000000..2fa97b777 --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintForce.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintForce.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintForce, Fem::Constraint); + +ConstraintForce::ConstraintForce() +{ + ADD_PROPERTY(Force,(0.0)); + ADD_PROPERTY_TYPE(Direction,(0),"ConstraintForce",(App::PropertyType)(App::Prop_None), + "Element giving direction of constraint"); + ADD_PROPERTY(Reversed,(0)); + ADD_PROPERTY_TYPE(Points,(Base::Vector3f()),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Points where arrows are drawn"); + ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3f(0,0,1)),"ConstraintForce",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Direction of arrows"); + naturalDirectionVector = Base::Vector3f(0,0,1); + Points.setValues(std::vector()); +} + +App::DocumentObjectExecReturn *ConstraintForce::execute(void) +{ + return Constraint::execute(); +} + +void ConstraintForce::onChanged(const App::Property* prop) +{ + // Note: If we call this at the end, then the arrows are not oriented correctly initially + // because the NormalDirection has not been calculated yet + Constraint::onChanged(prop); + + if (prop == &References) { + std::vector points; + std::vector normals; + getPoints(points, normals); + Points.setValues(points); // We don't use the normals because all arrows should have the same direction + Points.touch(); // This triggers ViewProvider::updateData() + } else if (prop == &Direction) { + App::DocumentObject* obj = Direction.getValue(); + std::vector names = Direction.getSubValues(); + if (names.size() == 0) { + return; + } + std::string subName = names.front(); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape sh = feat->Shape.getShape().getSubShape(subName.c_str()); + gp_Dir dir; + + if (sh.ShapeType() == TopAbs_FACE) { + BRepAdaptor_Surface surface(TopoDS::Face(sh)); + if (surface.GetType() == GeomAbs_Plane) { + dir = surface.Plane().Axis().Direction(); + } else { + return; // "Direction must be a planar face or linear edge" + } + } else if (sh.ShapeType() == TopAbs_EDGE) { + BRepAdaptor_Curve line(TopoDS::Edge(sh)); + if (line.GetType() == GeomAbs_Line) { + dir = line.Line().Direction(); + } else { + return; // "Direction must be a planar face or linear edge" + } + } + + Base::Vector3f direction(dir.X(), dir.Y(), dir.Z()); + direction.Normalize(); + naturalDirectionVector = direction; + if (Reversed.getValue()) + direction = -direction; + DirectionVector.setValue(direction); + DirectionVector.touch(); + } else if (prop == &Reversed) { + if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) { + DirectionVector.setValue(-naturalDirectionVector); + DirectionVector.touch(); + } else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) { + DirectionVector.setValue(naturalDirectionVector); + DirectionVector.touch(); + } + } else if (prop == &NormalDirection) { + // Set a default direction if no direction reference has been given + if (Direction.getValue() == NULL) { + DirectionVector.setValue(NormalDirection.getValue()); + naturalDirectionVector = NormalDirection.getValue(); + } + } +} diff --git a/src/Mod/Fem/App/FemConstraintForce.h b/src/Mod/Fem/App/FemConstraintForce.h new file mode 100644 index 000000000..1386e7d7d --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintForce.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTFORCE_H +#define FEM_CONSTRAINTFORCE_H + +#include +#include +#include + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintForce : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintForce); + +public: + /// Constructor + ConstraintForce(void); + + App::PropertyFloat Force; + App::PropertyLinkSub Direction; + App::PropertyBool Reversed; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyVectorList Points; + App::PropertyVector DirectionVector; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintForce"; + } + +protected: + virtual void onChanged(const App::Property* prop); + +private: + Base::Vector3f naturalDirectionVector; +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTFORCE_H diff --git a/src/Mod/Fem/App/FemConstraintGear.cpp b/src/Mod/Fem/App/FemConstraintGear.cpp new file mode 100644 index 000000000..7505b8bbf --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintGear.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintGear.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintGear, Fem::ConstraintBearing); + +ConstraintGear::ConstraintGear() +{ + ADD_PROPERTY(Diameter,(0)); +} + +App::DocumentObjectExecReturn *ConstraintGear::execute(void) +{ + return ConstraintBearing::execute(); +} + +void ConstraintGear::onChanged(const App::Property* prop) +{ + ConstraintBearing::onChanged(prop); +} diff --git a/src/Mod/Fem/App/FemConstraintGear.h b/src/Mod/Fem/App/FemConstraintGear.h new file mode 100644 index 000000000..a18053ff0 --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintGear.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTGear_H +#define FEM_CONSTRAINTGear_H + +#include +#include +#include + +#include "FemConstraintBearing.h" + +namespace Fem +{ + +class AppFemExport ConstraintGear : public Fem::ConstraintBearing +{ + PROPERTY_HEADER(Fem::ConstraintGear); + +public: + /// Constructor + ConstraintGear(void); + + App::PropertyFloat Diameter; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintGear"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTGear_H diff --git a/src/Mod/Fem/App/FemConstraintPulley.cpp b/src/Mod/Fem/App/FemConstraintPulley.cpp new file mode 100644 index 000000000..d4c5efbbe --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintPulley.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * 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 +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintPulley.h" + +#include +#include + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintPulley, Fem::ConstraintBearing); + +ConstraintPulley::ConstraintPulley() +{ + ADD_PROPERTY(Diameter,(0)); + ADD_PROPERTY(OtherDiameter,(0)); + ADD_PROPERTY(CenterDistance,(0)); + ADD_PROPERTY_TYPE(Angle,(0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Angle of pulley forces"); +} + +App::DocumentObjectExecReturn *ConstraintPulley::execute(void) +{ + return ConstraintBearing::execute(); +} + +void ConstraintPulley::onChanged(const App::Property* prop) +{ + ConstraintBearing::onChanged(prop); + + if ((prop == &Diameter) || (prop == &OtherDiameter) || (prop == &CenterDistance)) { + if (CenterDistance.getValue() > Precision::Confusion()) { + Angle.setValue(asin((Diameter.getValue() - OtherDiameter.getValue())/2/CenterDistance.getValue())); + Angle.touch(); + } + } +} diff --git a/src/Mod/Fem/App/FemConstraintPulley.h b/src/Mod/Fem/App/FemConstraintPulley.h new file mode 100644 index 000000000..5540d0ba6 --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintPulley.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef FEM_CONSTRAINTPulley_H +#define FEM_CONSTRAINTPulley_H + +#include +#include +#include + +#include "FemConstraintBearing.h" + +namespace Fem +{ + +class AppFemExport ConstraintPulley : public Fem::ConstraintBearing +{ + PROPERTY_HEADER(Fem::ConstraintPulley); + +public: + /// Constructor + ConstraintPulley(void); + + App::PropertyFloat Diameter; + App::PropertyFloat OtherDiameter; + App::PropertyFloat CenterDistance; + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyFloat Angle; + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const { + return "FemGui::ViewProviderFemConstraintPulley"; + } + +protected: + virtual void onChanged(const App::Property* prop); +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTPulley_H diff --git a/src/Mod/Fem/Gui/AppFemGui.cpp b/src/Mod/Fem/Gui/AppFemGui.cpp index 46e20afe8..f591b18a7 100755 --- a/src/Mod/Fem/Gui/AppFemGui.cpp +++ b/src/Mod/Fem/Gui/AppFemGui.cpp @@ -35,6 +35,11 @@ #include "ViewProviderSetFaces.h" #include "ViewProviderSetGeometry.h" #include "ViewProviderFemConstraint.h" +#include "ViewProviderFemConstraintBearing.h" +#include "ViewProviderFemConstraintFixed.h" +#include "ViewProviderFemConstraintForce.h" +#include "ViewProviderFemConstraintGear.h" +#include "ViewProviderFemConstraintPulley.h" #include "Workbench.h" //#include "resources/qrc_Fem.cpp" @@ -75,6 +80,11 @@ void FemGuiExport initFemGui() FemGui::ViewProviderSetFaces ::init(); FemGui::ViewProviderSetGeometry ::init(); FemGui::ViewProviderFemConstraint ::init(); + FemGui::ViewProviderFemConstraintBearing ::init(); + FemGui::ViewProviderFemConstraintFixed ::init(); + FemGui::ViewProviderFemConstraintForce ::init(); + FemGui::ViewProviderFemConstraintGear ::init(); + FemGui::ViewProviderFemConstraintPulley ::init(); // add resources and reloads the translators loadFemResource(); diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index 52c1c0dd7..162e3efaa 100755 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -23,10 +23,10 @@ set(FemGui_LIBS Fem FreeCADGui ) - -if(SMESH_FOUND) - include_directories( ${SMESH_INCLUDE_DIR} ) - list( APPEND FemGui_LIBS ${SMESH_LIBRARIES} ) + +if(SMESH_FOUND) + include_directories( ${SMESH_INCLUDE_DIR} ) + list( APPEND FemGui_LIBS ${SMESH_LIBRARIES} ) endif(SMESH_FOUND) set(FemGui_MOC_HDRS @@ -35,6 +35,11 @@ set(FemGui_MOC_HDRS TaskCreateNodeSet.h TaskDlgCreateNodeSet.h TaskFemConstraint.h + TaskFemConstraintBearing.h + TaskFemConstraintFixed.h + TaskFemConstraintForce.h + TaskFemConstraintGear.h + TaskFemConstraintPulley.h ) fc_wrap_cpp(FemGui_MOC_SRCS ${FemGui_MOC_HDRS}) SOURCE_GROUP("Moc" FILES ${FemGui_MOC_SRCS}) @@ -44,6 +49,9 @@ set(FemGui_UIC_SRCS TaskCreateNodeSet.ui TaskObjectName.ui TaskFemConstraint.ui + TaskFemConstraintCylindrical.ui + TaskFemConstraintFixed.ui + TaskFemConstraintForce.ui ) qt4_wrap_ui(FemGui_UIC_HDRS ${FemGui_UIC_SRCS}) @@ -55,8 +63,21 @@ SET(FemGui_DLG_SRCS TaskFemConstraint.ui TaskFemConstraint.cpp TaskFemConstraint.h -) -SOURCE_GROUP("Dialogs" FILES ${FemGui_DLG_SRCS}) + TaskFemConstraintCylindrical.ui + TaskFemConstraintBearing.cpp + TaskFemConstraintBearing.h + TaskFemConstraintFixed.ui + TaskFemConstraintFixed.cpp + TaskFemConstraintFixed.h + TaskFemConstraintForce.ui + TaskFemConstraintForce.cpp + TaskFemConstraintForce.h + TaskFemConstraintGear.cpp + TaskFemConstraintGear.h + TaskFemConstraintPulley.cpp + TaskFemConstraintPulley.h +) +SOURCE_GROUP("Dialogs" FILES ${FemGui_DLG_SRCS}) qt4_add_resources(FemResource_SRCS Resources/Fem.qrc) @@ -77,6 +98,16 @@ SET(FemGui_SRCS_ViewProvider FemSelectionGate.h ViewProviderFemConstraint.cpp ViewProviderFemConstraint.h + ViewProviderFemConstraintBearing.cpp + ViewProviderFemConstraintBearing.h + ViewProviderFemConstraintFixed.cpp + ViewProviderFemConstraintFixed.h + ViewProviderFemConstraintForce.cpp + ViewProviderFemConstraintForce.h + ViewProviderFemConstraintGear.cpp + ViewProviderFemConstraintGear.h + ViewProviderFemConstraintPulley.cpp + ViewProviderFemConstraintPulley.h ) SOURCE_GROUP("ViewProvider" FILES ${FemGui_SRCS_ViewProvider}) @@ -122,6 +153,18 @@ SET(FemGui_SRCS ${FemGui_SRCS_TaskDlg} ${FemGui_SRCS_TaskBoxes} ${FemGui_SRCS_Module} + ViewProviderFemConstraint.cpp + ViewProviderFemConstraint.h + ViewProviderFemConstraintBearing.cpp + ViewProviderFemConstraintBearing.h + ViewProviderFemConstraintFixed.cpp + ViewProviderFemConstraintFixed.h + ViewProviderFemConstraintForce.cpp + ViewProviderFemConstraintForce.h + ViewProviderFemConstraintGear.cpp + ViewProviderFemConstraintGear.h + ViewProviderFemConstraintPulley.cpp + ViewProviderFemConstraintPulley.h ) @@ -129,11 +172,11 @@ SET(FemGui_SRCS add_library(FemGui SHARED ${FemGui_SRCS}) target_link_libraries(FemGui ${FemGui_LIBS}) - -fc_target_copy_resource(FemGui - ${CMAKE_SOURCE_DIR}/src/Mod/Fem - ${CMAKE_BINARY_DIR}/Mod/Fem - InitGui.py) + +fc_target_copy_resource(FemGui + ${CMAKE_SOURCE_DIR}/src/Mod/Fem + ${CMAKE_BINARY_DIR}/Mod/Fem + InitGui.py) if(MSVC) set_target_properties(FemGui PROPERTIES SUFFIX ".pyd") diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index cd58e9714..f5bdf54da 100755 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -55,7 +55,6 @@ #include #include "Hypothesis.h" -#include "TaskFemConstraint.h" using namespace std; @@ -87,35 +86,157 @@ bool CmdFemCreateFromShape::isActive(void) return Gui::Selection().countObjectsOfType(type) > 0; } -DEF_STD_CMD_A(CmdFemConstraint); +DEF_STD_CMD_A(CmdFemConstraintBearing); -CmdFemConstraint::CmdFemConstraint() - : Command("Fem_Constraint") +CmdFemConstraintBearing::CmdFemConstraintBearing() + : Command("Fem_ConstraintBearing") { sAppModule = "Fem"; sGroup = QT_TR_NOOP("Fem"); - sMenuText = QT_TR_NOOP("Create FEM constraint"); - sToolTipText = QT_TR_NOOP("Create FEM constraint"); + sMenuText = QT_TR_NOOP("Create FEM bearing constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a bearing"); sWhatsThis = sToolTipText; sStatusTip = sToolTipText; - sPixmap = "Fem_Constraint"; + sPixmap = "Fem_ConstraintBearing"; } -void CmdFemConstraint::activated(int iMsg) +void CmdFemConstraintBearing::activated(int iMsg) { - std::string FeatName = getUniqueObjectName("FemConstraint"); + std::string FeatName = getUniqueObjectName("FemConstraintBearing"); - openCommand("Make FEM constraint"); - doCommand(Doc,"App.activeDocument().addObject(\"Fem::Constraint\",\"%s\")",FeatName.c_str()); - doCommand(Doc,"App.activeDocument().%s.Force = 0.0",FeatName.c_str()); + openCommand("Make FEM constraint for bearing"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintBearing\",\"%s\")",FeatName.c_str()); updateActive(); - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(App::GetApplication().getActiveDocument()->getActiveObject()); - doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); } -bool CmdFemConstraint::isActive(void) +bool CmdFemConstraintBearing::isActive(void) +{ + return hasActiveDocument(); +} + +DEF_STD_CMD_A(CmdFemConstraintFixed); + +CmdFemConstraintFixed::CmdFemConstraintFixed() + : Command("Fem_ConstraintFixed") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM fixed constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a fixed geometric entity"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Fem_ConstraintFixed"; +} + +void CmdFemConstraintFixed::activated(int iMsg) +{ + std::string FeatName = getUniqueObjectName("FemConstraintFixed"); + + openCommand("Make FEM constraint fixed geometry"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintFixed\",\"%s\")",FeatName.c_str()); + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintFixed::isActive(void) +{ + return hasActiveDocument(); +} + +DEF_STD_CMD_A(CmdFemConstraintForce); + +CmdFemConstraintForce::CmdFemConstraintForce() + : Command("Fem_ConstraintForce") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM force constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a force acting on a geometric entity"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Fem_ConstraintForce"; +} + +void CmdFemConstraintForce::activated(int iMsg) +{ + std::string FeatName = getUniqueObjectName("FemConstraintForce"); + + openCommand("Make FEM constraint force on geometry"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintForce\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Force = 0.0",FeatName.c_str()); + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintForce::isActive(void) +{ + return hasActiveDocument(); +} + +DEF_STD_CMD_A(CmdFemConstraintGear); + +CmdFemConstraintGear::CmdFemConstraintGear() + : Command("Fem_ConstraintGear") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM gear constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a gear"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Fem_ConstraintGear"; +} + +void CmdFemConstraintGear::activated(int iMsg) +{ + std::string FeatName = getUniqueObjectName("FemConstraintGear"); + + openCommand("Make FEM constraint for gear"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintGear\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str()); + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintGear::isActive(void) +{ + return hasActiveDocument(); +} + +DEF_STD_CMD_A(CmdFemConstraintPulley); + +CmdFemConstraintPulley::CmdFemConstraintPulley() + : Command("Fem_ConstraintPulley") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM pulley constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for a pulley"); + sWhatsThis = sToolTipText; + sStatusTip = sToolTipText; + sPixmap = "Fem_ConstraintPulley"; +} + +void CmdFemConstraintPulley::activated(int iMsg) +{ + std::string FeatName = getUniqueObjectName("FemConstraintPulley"); + + openCommand("Make FEM constraint for pulley"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPulley\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.OtherDiameter = 200.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.CenterDistance = 500.0",FeatName.c_str()); + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintPulley::isActive(void) { return hasActiveDocument(); } @@ -316,4 +437,9 @@ void CreateFemCommands(void) rcCmdMgr.addCommand(new CmdFemCreateNodesSet()); rcCmdMgr.addCommand(new CmdFemDefineNodesSet()); rcCmdMgr.addCommand(new CmdFemConstraint()); + rcCmdMgr.addCommand(new CmdFemConstraintBearing()); + rcCmdMgr.addCommand(new CmdFemConstraintFixed()); + rcCmdMgr.addCommand(new CmdFemConstraintForce()); + rcCmdMgr.addCommand(new CmdFemConstraintGear()); + rcCmdMgr.addCommand(new CmdFemConstraintPulley()); } diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.cpp b/src/Mod/Fem/Gui/TaskFemConstraint.cpp index b415eedeb..2a54ed956 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.cpp +++ b/src/Mod/Fem/Gui/TaskFemConstraint.cpp @@ -43,7 +43,7 @@ #include "TaskFemConstraint.h" #include #include -#include +//#include #include #include #include @@ -61,430 +61,26 @@ using namespace Gui; /* TRANSLATOR FemGui::TaskFemConstraint */ -const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) +TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent,const char* pixmapname) + : TaskBox(Gui::BitmapFactory().pixmap(pixmapname),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView) { - return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str()); -} - -TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent) - : TaskBox(Gui::BitmapFactory().pixmap("Fem_Constraint"),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView) -{ - // we need a separate container widget to add all controls to - proxy = new QWidget(this); - ui = new Ui_TaskFemConstraint(); - ui->setupUi(proxy); - QMetaObject::connectSlotsByName(this); - - // Create a context menu for the listview of the references - QAction* action = new QAction(tr("Delete"), ui->listReferences); - action->connect(action, SIGNAL(triggered()), - this, SLOT(onReferenceDeleted())); - ui->listReferences->addAction(action); - ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); - - connect(ui->comboType, SIGNAL(currentIndexChanged(int)), - this, SLOT(onTypeChanged(int))); - connect(ui->spinForce, SIGNAL(valueChanged(double)), - this, SLOT(onForceChanged(double))); - connect(ui->buttonReference, SIGNAL(pressed()), - this, SLOT(onButtonReference())); - connect(ui->buttonDirection, SIGNAL(pressed()), - this, SLOT(onButtonDirection())); - connect(ui->checkReverse, SIGNAL(toggled(bool)), - this, SLOT(onCheckReverse(bool))); - connect(ui->buttonLocation, SIGNAL(pressed()), - this, SLOT(onButtonLocation())); - connect(ui->spinDistance, SIGNAL(valueChanged(double)), - this, SLOT(onDistanceChanged(double))); - connect(ui->spinDiameter, SIGNAL(valueChanged(double)), - this, SLOT(onDiameterChanged(double))); - connect(ui->spinOtherDia, SIGNAL(valueChanged(double)), - this, SLOT(onOtherDiameterChanged(double))); - connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)), - this, SLOT(onCenterDistanceChanged(double))); - - this->groupLayout()->addWidget(proxy); - - // Temporarily prevent unnecessary feature recomputes - ui->comboType->blockSignals(true); - ui->spinForce->blockSignals(true); - ui->listReferences->blockSignals(true); - ui->buttonReference->blockSignals(true); - ui->buttonDirection->blockSignals(true); - ui->checkReverse->blockSignals(true); - ui->buttonLocation->blockSignals(true); - ui->spinDistance->blockSignals(true); - ui->spinDiameter->blockSignals(true); - ui->spinOtherDia->blockSignals(true); - ui->spinCenterDistance->blockSignals(true); - - // Get the feature data - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - int index = pcConstraint->Type.getValue(); - double f = pcConstraint->Force.getValue(); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - std::vector dirStrings = pcConstraint->Direction.getSubValues(); - QString dir; - if (!dirStrings.empty()) - dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); - bool reversed = pcConstraint->Reversed.getValue(); - std::vector locStrings = pcConstraint->Location.getSubValues(); - QString loc; - if (!locStrings.empty()) - loc = makeRefText(pcConstraint->Location.getValue(), locStrings.front()); - double d = pcConstraint->Distance.getValue(); - double dia = pcConstraint->Diameter.getValue(); - double otherdia = pcConstraint->OtherDiameter.getValue(); - double centerdist = pcConstraint->CenterDistance.getValue(); - - // Fill data into dialog elements - ui->comboType->clear(); - ui->comboType->insertItem(0, tr("Force on geometry")); - ui->comboType->insertItem(1, tr("Fixed")); - ui->comboType->insertItem(2, tr("Bearing (axial free)")); - ui->comboType->insertItem(3, tr("Bearing (axial fixed)")); - ui->comboType->insertItem(4, tr("Pulley")); - ui->comboType->insertItem(5, tr("Gear (straight toothed)")); - ui->comboType->setCurrentIndex(index); - ui->spinForce->setMinimum(0); - ui->spinForce->setMaximum(INT_MAX); - ui->spinForce->setValue(f); - ui->listReferences->clear(); - - for (int i = 0; i < Objects.size(); i++) - ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); - if (Objects.size() > 0) - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); - ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir); - ui->checkReverse->setChecked(reversed); - ui->lineDirection->setText(loc.isEmpty() ? tr("") : loc); - ui->spinDistance->setMinimum(INT_MIN); - ui->spinDistance->setMaximum(INT_MAX); - ui->spinDistance->setValue(d); - ui->spinDiameter->setMinimum(0); - ui->spinDiameter->setMaximum(INT_MAX); - ui->spinDiameter->setValue(dia); - ui->spinOtherDia->setMinimum(0); - ui->spinOtherDia->setMaximum(INT_MAX); - ui->spinOtherDia->setValue(otherdia); - ui->spinCenterDistance->setMinimum(0); - ui->spinCenterDistance->setMaximum(INT_MAX); - ui->spinCenterDistance->setValue(centerdist); - - // activate and de-activate dialog elements as appropriate - ui->comboType->blockSignals(false); - ui->spinForce->blockSignals(false); - ui->listReferences->blockSignals(false); - ui->buttonReference->blockSignals(false); - ui->buttonDirection->blockSignals(false); - ui->checkReverse->blockSignals(false); - ui->buttonLocation->blockSignals(false); - ui->spinDistance->blockSignals(false); - ui->spinDiameter->blockSignals(false); - ui->spinOtherDia->blockSignals(false); - ui->spinCenterDistance->blockSignals(false); - selectionMode = selref; - updateUI(); } -void TaskFemConstraint::updateUI() +const std::string TaskFemConstraint::getReferences(const std::vector& items) const { - if (ui->comboType->currentIndex() == 0) { - ui->labelForce->setVisible(true); - ui->spinForce->setVisible(true); - ui->buttonDirection->setVisible(true); - ui->lineDirection->setVisible(true); - ui->checkReverse->setVisible(true); - ui->buttonLocation->setVisible(false); - ui->lineLocation->setVisible(false); - ui->labelDistance->setVisible(false); - ui->spinDistance->setVisible(false); - ui->labelDiameter->setVisible(false); - ui->spinDiameter->setVisible(false); - ui->labelOtherDia->setVisible(false); - ui->spinOtherDia->setVisible(false); - ui->labelCenterDistance->setVisible(false); - ui->spinCenterDistance->setVisible(false); - } else if (ui->comboType->currentIndex() == 1) { - ui->labelForce->setVisible(false); - ui->spinForce->setVisible(false); - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReverse->setVisible(false); - ui->buttonLocation->setVisible(false); - ui->lineLocation->setVisible(false); - ui->labelDistance->setVisible(false); - ui->spinDistance->setVisible(false); - ui->labelDiameter->setVisible(false); - ui->spinDiameter->setVisible(false); - ui->labelOtherDia->setVisible(false); - ui->spinOtherDia->setVisible(false); - ui->labelCenterDistance->setVisible(false); - ui->spinCenterDistance->setVisible(false); - } else if ((ui->comboType->currentIndex() == 2) || (ui->comboType->currentIndex() == 3)) { - ui->labelForce->setVisible(false); - ui->spinForce->setVisible(false); - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReverse->setVisible(false); - ui->buttonLocation->setVisible(true); - ui->lineLocation->setVisible(true); - ui->labelDistance->setVisible(true); - ui->spinDistance->setVisible(true); - ui->labelDiameter->setVisible(false); - ui->spinDiameter->setVisible(false); - ui->labelOtherDia->setVisible(false); - ui->spinOtherDia->setVisible(false); - ui->labelCenterDistance->setVisible(false); - ui->spinCenterDistance->setVisible(false); - } else if (ui->comboType->currentIndex() == 4) { - ui->labelForce->setVisible(false); - ui->spinForce->setVisible(false); - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReverse->setVisible(false); - ui->buttonLocation->setVisible(true); - ui->lineLocation->setVisible(true); - ui->labelDistance->setVisible(true); - ui->spinDistance->setVisible(true); - ui->labelDiameter->setVisible(true); - ui->spinDiameter->setVisible(true); - ui->labelOtherDia->setVisible(true); - ui->spinOtherDia->setVisible(true); - ui->labelCenterDistance->setVisible(true); - ui->spinCenterDistance->setVisible(true); - } else if (ui->comboType->currentIndex() == 5) { - ui->labelForce->setVisible(false); - ui->spinForce->setVisible(false); - ui->buttonDirection->setVisible(false); - ui->lineDirection->setVisible(false); - ui->checkReverse->setVisible(false); - ui->buttonLocation->setVisible(true); - ui->lineLocation->setVisible(true); - ui->labelDistance->setVisible(true); - ui->spinDistance->setVisible(true); - ui->labelDiameter->setVisible(true); - ui->spinDiameter->setVisible(true); - ui->labelOtherDia->setVisible(true); - ui->spinOtherDia->setVisible(true); - ui->labelCenterDistance->setVisible(false); - ui->spinCenterDistance->setVisible(false); + std::string result; + for (std::vector::const_iterator i = items.begin(); i != items.end(); i++) { + int pos = i->find_last_of(":"); + std::string objStr = "App.ActiveDocument." + i->substr(0, pos); + std::string refStr = "\"" + i->substr(pos+1) + "\""; + result = result + (i != items.begin() ? ", " : "") + "(" + objStr + "," + refStr + ")"; } - if (ui->listReferences->model()->rowCount() == 0) { - // Go into reference selection mode if no reference has been selected yet - onButtonReference(true); - return; - } - - if (ui->comboType->currentIndex() == 0) { - std::string ref = ui->listReferences->item(0)->text().toStdString(); - int pos = ref.find_last_of(":"); - if (ref.substr(pos+1, 6) == "Vertex") - ui->labelForce->setText(tr("Force [N]")); - else if (ref.substr(pos+1, 4) == "Edge") - ui->labelForce->setText(tr("Force [N/mm]")); - else if (ref.substr(pos+1, 4) == "Face") - ui->labelForce->setText(tr("Force [N/mm²]")); - } + return result; } -void TaskFemConstraint::onSelectionChanged(const Gui::SelectionChanges& msg) -{ - if (msg.Type == Gui::SelectionChanges::AddSelection) { - // Don't allow selection in other document - if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) - return; - - if (!msg.pSubName || msg.pSubName[0] == '\0') - return; - std::string subName(msg.pSubName); - - if (selectionMode == selnone) - return; - - std::vector references(1,subName); - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); - //if (!obj->getClassTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) - // return; - Part::Feature* feat = static_cast(obj); - TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (selectionMode == selref) { - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - if (pcConstraint->Type.getValue() == 0) { - // Force on geometry elements: - // Ensure we don't have mixed reference types - if (SubElements.size() > 0) { - if (subName.substr(0,4) != SubElements.front().substr(0,4)) { - QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); - return; - } - } else { - if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); - return; - } - } - - // Avoid duplicates - int pos = 0; - for (; pos < Objects.size(); pos++) - if (obj == Objects[pos]) - break; - - if (pos != Objects.size()) - if (subName == SubElements[pos]) - return; - } else if (pcConstraint->Type.getValue() == 1) { - // Fixed - if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { - QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); - return; - } - - // Avoid duplicates - int pos = 0; - for (; pos < Objects.size(); pos++) - if (obj == Objects[pos]) - break; - - if (pos != Objects.size()) - if (subName == SubElements[pos]) - return; - } else if ((pcConstraint->Type.getValue() >= 2) && (pcConstraint->Type.getValue() <= 5)) { - // Bearing, pulley, gear - if (Objects.size() > 0) { - QMessageBox::warning(this, tr("Selection error"), tr("Please use only a single reference for bearing constraint")); - return; - } - // Only cylindrical faces allowed - if (subName.substr(0,4) != "Face") { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); - return; - } - - BRepAdaptor_Surface surface(TopoDS::Face(ref)); - if (surface.GetType() != GeomAbs_Cylinder) { - QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked")); - return; - } - } else { - return; - } - - // add the new reference - Objects.push_back(obj); - SubElements.push_back(subName); - pcConstraint->References.setValues(Objects,SubElements); - ui->listReferences->addItem(makeRefText(obj, subName)); - - // Turn off reference selection mode - onButtonReference(false); - } else if ((selectionMode == seldir) || (selectionMode == selloc)) { - if (subName.substr(0,4) == "Face") { - BRepAdaptor_Surface surface(TopoDS::Face(ref)); - if (surface.GetType() != GeomAbs_Plane) { - QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); - return; - } - } else if (subName.substr(0,4) == "Edge") { - BRepAdaptor_Curve line(TopoDS::Edge(ref)); - if (line.GetType() != GeomAbs_Line) { - QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); - return; - } - } else { - QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); - return; - } - if (selectionMode == seldir) { - pcConstraint->Direction.setValue(obj, references); - ui->lineDirection->setText(makeRefText(obj, subName)); - - // Turn off direction selection mode - onButtonDirection(false); - } else { - pcConstraint->Location.setValue(obj, references); - ui->lineLocation->setText(makeRefText(obj, subName)); - - // Turn off direction selection mode - onButtonLocation(false); - } - } - updateUI(); - } -} - -void TaskFemConstraint::onTypeChanged(int index) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - int oldType = pcConstraint->Type.getValue(); - pcConstraint->Type.setValue(index); - - if (((oldType == 2) && (index == 3)) || ((oldType == 3) && (index == 2))) { - pcConstraint->References.touch(); // Update visual - updateUI(); - } else { - // Clear all references if the old and new type mismatch - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - - Objects.clear(); - SubElements.clear(); - pcConstraint->References.setValues(Objects, SubElements); - - ui->listReferences->clear(); //model()->removeRows(0, ui->listReferences->model()->rowCount()); - updateUI(); - } -} - -void TaskFemConstraint::onForceChanged(double f) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Force.setValue((float)f); -} - -void TaskFemConstraint::onDistanceChanged(double f) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Distance.setValue((float)f); -} - -void TaskFemConstraint::onDiameterChanged(double f) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Diameter.setValue((float)f); -} - -void TaskFemConstraint::onOtherDiameterChanged(double f) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->OtherDiameter.setValue((float)f); -} - -void TaskFemConstraint::onCenterDistanceChanged(double d) -{ - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->CenterDistance.setValue((float)d); -} - -void TaskFemConstraint::onButtonReference(const bool pressed) { - if (pressed) - selectionMode = selref; - else - selectionMode = selnone; - ui->buttonReference->setChecked(pressed); - Gui::Selection().clearSelection(); -} - -void TaskFemConstraint::onReferenceDeleted() { - int row = ui->listReferences->currentIndex().row(); +void TaskFemConstraint::onReferenceDeleted(const int row) { Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); std::vector Objects = pcConstraint->References.getValues(); std::vector SubElements = pcConstraint->References.getSubValues(); @@ -492,156 +88,20 @@ void TaskFemConstraint::onReferenceDeleted() { Objects.erase(Objects.begin() + row); SubElements.erase(SubElements.begin() + row); pcConstraint->References.setValues(Objects, SubElements); - - ui->listReferences->model()->removeRow(row); - ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); } -void TaskFemConstraint::onButtonDirection(const bool pressed) { - if (pressed) { - selectionMode = seldir; - } else { +void TaskFemConstraint::onButtonReference(const bool pressed) { + if (pressed) + selectionMode = selref; + else selectionMode = selnone; - } - ui->buttonDirection->setChecked(pressed); + //ui->buttonReference->setChecked(pressed); Gui::Selection().clearSelection(); } -void TaskFemConstraint::onButtonLocation(const bool pressed) { - if (pressed) { - selectionMode = selloc; - } else { - selectionMode = selnone; - } - ui->buttonLocation->setChecked(pressed); - Gui::Selection().clearSelection(); -} - -void TaskFemConstraint::onCheckReverse(const bool pressed) +const QString TaskFemConstraint::makeRefText(const App::DocumentObject* obj, const std::string& subName) const { - Fem::Constraint* pcConstraint = static_cast(ConstraintView->getObject()); - pcConstraint->Reversed.setValue(pressed); -} - -int TaskFemConstraint::getType(void) const -{ - return ui->comboType->currentIndex(); -} - -double TaskFemConstraint::getForce(void) const -{ - return ui->spinForce->value(); -} - -double TaskFemConstraint::getDistance(void) const -{ - return ui->spinDistance->value(); -} - -double TaskFemConstraint::getDiameter(void) const -{ - return ui->spinDiameter->value(); -} - -double TaskFemConstraint::getOtherDiameter(void) const -{ - return ui->spinOtherDia->value(); -} - -double TaskFemConstraint::getCenterDistance(void) const -{ - return ui->spinCenterDistance->value(); -} - -const std::string TaskFemConstraint::getReferences(void) const -{ - int rows = ui->listReferences->model()->rowCount(); - if (rows == 0) - return ""; - - std::string result; - for (int r = 0; r < rows; r++) { - std::string item = ui->listReferences->item(r)->text().toStdString(); - int pos = item.find_last_of(":"); - std::string objStr = "App.ActiveDocument." + item.substr(0, pos); - std::string refStr = "\"" + item.substr(pos+1) + "\""; - result = result + (r > 0 ? ", " : "") + "(" + objStr + "," + refStr + ")"; - } - - return result; -} - -const std::string TaskFemConstraint::getDirectionName(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(0, pos).c_str(); -} - -const std::string TaskFemConstraint::getDirectionObject(void) const -{ - std::string dir = ui->lineDirection->text().toStdString(); - if (dir.empty()) - return ""; - - int pos = dir.find_last_of(":"); - return dir.substr(pos+1).c_str(); -} - -const std::string TaskFemConstraint::getLocationName(void) const -{ - std::string loc = ui->lineLocation->text().toStdString(); - if (loc.empty()) - return ""; - - int pos = loc.find_last_of(":"); - return loc.substr(0, pos).c_str(); -} - -const std::string TaskFemConstraint::getLocationObject(void) const -{ - std::string loc = ui->lineLocation->text().toStdString(); - if (loc.empty()) - return ""; - - int pos = loc.find_last_of(":"); - return loc.substr(pos+1).c_str(); -} - -bool TaskFemConstraint::getReverse() const -{ - return ui->checkReverse->isChecked(); -} - -TaskFemConstraint::~TaskFemConstraint() -{ - delete ui; -} - -void TaskFemConstraint::changeEvent(QEvent *e) -{ - TaskBox::changeEvent(e); - if (e->type() == QEvent::LanguageChange) { - ui->comboType->blockSignals(true); - ui->spinForce->blockSignals(true); - ui->spinDistance->blockSignals(true); - int index = ui->comboType->currentIndex(); - ui->comboType->clear(); - ui->comboType->insertItem(0, tr("Force on geometry")); - ui->comboType->insertItem(1, tr("Fixed")); - ui->comboType->insertItem(2, tr("Bearing (axial free)")); - ui->comboType->insertItem(3, tr("Bearing (axial fixed)")); - ui->comboType->insertItem(4, tr("Pulley")); - ui->comboType->insertItem(5, tr("Gear (straight toothed)")); - ui->comboType->setCurrentIndex(index); - ui->retranslateUi(proxy); - ui->comboType->blockSignals(false); - ui->spinForce->blockSignals(false); - ui->spinDistance->blockSignals(false); - } + return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str()); } //************************************************************************** @@ -649,41 +109,14 @@ void TaskFemConstraint::changeEvent(QEvent *e) // TaskDialog //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -TaskDlgFemConstraint::TaskDlgFemConstraint(ViewProviderFemConstraint *ConstraintView) - : TaskDialog(),ConstraintView(ConstraintView) -{ - assert(ConstraintView); - parameter = new TaskFemConstraint(ConstraintView); - - Content.push_back(parameter); -} - -TaskDlgFemConstraint::~TaskDlgFemConstraint() -{ - -} - //==== calls from the TaskView =============================================================== -void TaskDlgFemConstraint::open() -{ - -} - -void TaskDlgFemConstraint::clicked(int) -{ - -} - bool TaskDlgFemConstraint::accept() { std::string name = ConstraintView->getObject()->getNameInDocument(); try { - //Gui::Command::openCommand("FEM constraint changed"); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),parameter->getType()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(),parameter->getForce()); std::string refs = parameter->getReferences(); if (!refs.empty()) { @@ -693,37 +126,6 @@ bool TaskDlgFemConstraint::accept() return false; } - std::string dirname = parameter->getDirectionName().data(); - std::string dirobj = parameter->getDirectionObject().data(); - - if (!dirname.empty()) { - QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromStdString(dirname)); - buf = buf.arg(QString::fromStdString(dirobj)); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameter->getReverse() ? "True" : "False"); - - std::string locname = parameter->getLocationName().data(); - std::string locobj = parameter->getLocationObject().data(); - - if (!locname.empty()) { - QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); - buf = buf.arg(QString::fromStdString(locname)); - buf = buf.arg(QString::fromStdString(locobj)); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = %s", name.c_str(), buf.toStdString().c_str()); - } else { - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); - } - - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Distance = %f",name.c_str(),parameter->getDistance()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(),parameter->getDiameter()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(),parameter->getOtherDiameter()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(),parameter->getCenterDistance()); - Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); if (!ConstraintView->getObject()->isValid()) throw Base::Exception(ConstraintView->getObject()->getStatusString()); @@ -740,7 +142,7 @@ bool TaskDlgFemConstraint::accept() bool TaskDlgFemConstraint::reject() { - // roll back the done things + // roll back the changes Gui::Command::abortCommand(); Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); @@ -748,5 +150,4 @@ bool TaskDlgFemConstraint::reject() } - #include "moc_TaskFemConstraint.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraint.h b/src/Mod/Fem/Gui/TaskFemConstraint.h index d27da1983..f4d7ee0bd 100644 --- a/src/Mod/Fem/Gui/TaskFemConstraint.h +++ b/src/Mod/Fem/Gui/TaskFemConstraint.h @@ -29,9 +29,7 @@ #include #include "ViewProviderFemConstraint.h" - -class Ui_TaskFemConstraint; - +/* namespace App { class Property; } @@ -39,7 +37,7 @@ class Property; namespace Gui { class ViewProvider; } - +*/ namespace FemGui { class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionObserver @@ -47,45 +45,25 @@ class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionOb Q_OBJECT public: - TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0); - ~TaskFemConstraint(); + TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,const char* pixmapname = ""); + virtual ~TaskFemConstraint() {} - int getType(void) const; - double getForce(void) const; - const std::string getReferences(void) const; - const std::string getDirectionName(void) const; - const std::string getDirectionObject(void) const; - const std::string getLocationName(void) const; - const std::string getLocationObject(void) const; - double getDistance(void) const; - bool getReverse(void) const; - double getDiameter(void) const; - double getOtherDiameter(void) const; - double getCenterDistance(void) const; + virtual const std::string getReferences(void) const {} + const std::string getReferences(const std::vector& items) const; -private Q_SLOTS: - void onTypeChanged(int); - void onReferenceDeleted(); - void onForceChanged(double); +protected Q_SLOTS: + void onReferenceDeleted(const int row); void onButtonReference(const bool pressed = true); - void onButtonDirection(const bool pressed = true); - void onButtonLocation(const bool pressed = true); - void onDistanceChanged(double); - void onCheckReverse(bool); - void onDiameterChanged(double); - void onOtherDiameterChanged(double); - void onCenterDistanceChanged(double); protected: - void changeEvent(QEvent *e); + virtual void changeEvent(QEvent *e) {} + const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const; private: - void onSelectionChanged(const Gui::SelectionChanges& msg); - void updateUI(); + virtual void onSelectionChanged(const Gui::SelectionChanges& msg) {} -private: +protected: QWidget* proxy; - Ui_TaskFemConstraint* ui; ViewProviderFemConstraint *ConstraintView; enum {seldir, selref, selloc, selnone} selectionMode; }; @@ -95,19 +73,11 @@ class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog { Q_OBJECT -public: - TaskDlgFemConstraint(ViewProviderFemConstraint *ConstraintView); - ~TaskDlgFemConstraint(); - - ViewProviderFemConstraint* getConstraintView() const - { return ConstraintView; } - - public: /// is called the TaskView when the dialog is opened - virtual void open(); + virtual void open() {} /// is called by the framework if an button is clicked which has no accept or reject role - virtual void clicked(int); + virtual void clicked(int) {} /// is called by the framework if the dialog is accepted (Ok) virtual bool accept(); /// is called by the framework if the dialog is rejected (Cancel) @@ -120,9 +90,11 @@ public: virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const { return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; } -protected: - ViewProviderFemConstraint *ConstraintView; + ViewProviderFemConstraint* getConstraintView() const + { return ConstraintView; } +protected: + ViewProviderFemConstraint *ConstraintView; TaskFemConstraint *parameter; }; diff --git a/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp b/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp new file mode 100644 index 000000000..cf5b4374f --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintBearing.cpp @@ -0,0 +1,345 @@ +/*************************************************************************** + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintCylindrical.h" +#include "TaskFemConstraintBearing.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintBearing */ + +TaskFemConstraintBearing::TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView,QWidget *parent, const char *pixmapname) + : TaskFemConstraint(ConstraintView, parent, pixmapname) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintCylindrical(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->spinDistance, SIGNAL(valueChanged(double)), + this, SLOT(onDistanceChanged(double))); + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + connect(ui->buttonLocation, SIGNAL(pressed()), + this, SLOT(onButtonLocation())); + connect(ui->checkAxial, SIGNAL(toggled(bool)), + this, SLOT(onCheckAxial(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->spinDistance->blockSignals(true); + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + ui->buttonLocation->blockSignals(true); + ui->checkAxial->blockSignals(true); + + // Get the feature data + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + double d = pcConstraint->Dist.getValue(); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector locStrings = pcConstraint->Location.getSubValues(); + QString loc; + if (!locStrings.empty()) + loc = makeRefText(pcConstraint->Location.getValue(), locStrings.front()); + bool axialfree = pcConstraint->AxialFree.getValue(); + + // Fill data into dialog elements + ui->spinDistance->setMinimum(INT_MIN); + ui->spinDistance->setMaximum(INT_MAX); + ui->spinDistance->setValue(d); + ui->listReferences->clear(); + for (int i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + ui->lineLocation->setText(loc); + ui->checkAxial->setChecked(axialfree); + + // Adjust ui to constraint type + ui->labelDiameter->setVisible(false); + ui->spinDiameter->setVisible(false); + ui->labelOtherDiameter->setVisible(false); + ui->spinOtherDiameter->setVisible(false); + ui->labelCenterDistance->setVisible(false); + ui->spinCenterDistance->setVisible(false); + + ui->spinDistance->blockSignals(false); + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + ui->buttonLocation->blockSignals(false); + ui->checkAxial->blockSignals(false); + + onButtonReference(true); +} + +void TaskFemConstraintBearing::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + if (Objects.size() > 0) { + QMessageBox::warning(this, tr("Selection error"), tr("Please use only a single reference for bearing constraint")); + return; + } + // Only cylindrical faces allowed + if (subName.substr(0,4) != "Face") { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked")); + return; + } + + BRepAdaptor_Surface surface(TopoDS::Face(ref)); + if (surface.GetType() != GeomAbs_Cylinder) { + QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked")); + return; + } + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + + // Turn off reference selection mode + onButtonReference(false); + } else if (selectionMode == selloc) { + if (subName.substr(0,4) == "Face") { + BRepAdaptor_Surface surface(TopoDS::Face(ref)); + if (surface.GetType() != GeomAbs_Plane) { + QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); + return; + } + } else if (subName.substr(0,4) == "Edge") { + BRepAdaptor_Curve line(TopoDS::Edge(ref)); + if (line.GetType() != GeomAbs_Line) { + QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); + return; + } + } else { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); + return; + } + pcConstraint->Location.setValue(obj, references); + ui->lineLocation->setText(makeRefText(obj, subName)); + + // Turn off location selection mode + onButtonLocation(false); + } + + Gui::Selection().clearSelection(); + } +} + +void TaskFemConstraintBearing::onDistanceChanged(double l) +{ + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Dist.setValue((float)l); +} + +void TaskFemConstraintBearing::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +void TaskFemConstraintBearing::onButtonLocation(const bool pressed) { + if (pressed) { + selectionMode = selloc; + } else { + selectionMode = selnone; + } + ui->buttonLocation->setChecked(pressed); + Gui::Selection().clearSelection(); +} + +void TaskFemConstraintBearing::onCheckAxial(const bool pressed) +{ + Fem::ConstraintBearing* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->AxialFree.setValue(pressed); +} + +double TaskFemConstraintBearing::getDistance(void) const +{ + return ui->spinDistance->value(); +} + +const std::string TaskFemConstraintBearing::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +const std::string TaskFemConstraintBearing::getLocationName(void) const +{ + std::string loc = ui->lineLocation->text().toStdString(); + if (loc.empty()) + return ""; + + int pos = loc.find_last_of(":"); + return loc.substr(0, pos).c_str(); +} + +const std::string TaskFemConstraintBearing::getLocationObject(void) const +{ + std::string loc = ui->lineLocation->text().toStdString(); + if (loc.empty()) + return ""; + + int pos = loc.find_last_of(":"); + return loc.substr(pos+1).c_str(); +} + +bool TaskFemConstraintBearing::getAxial() const +{ + return ui->checkAxial->isChecked(); +} + +TaskFemConstraintBearing::~TaskFemConstraintBearing() +{ + delete ui; +} + +void TaskFemConstraintBearing::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinDistance->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinDistance->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintBearing::TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintBearing(ConstraintView); + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintBearing::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintBearing* parameterBearing = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Dist = %f",name.c_str(), parameterBearing->getDistance()); + + std::string locname = parameterBearing->getLocationName().data(); + std::string locobj = parameterBearing->getLocationObject().data(); + + if (!locname.empty()) { + QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); + buf = buf.arg(QString::fromStdString(locname)); + buf = buf.arg(QString::fromStdString(locobj)); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = %s", name.c_str(), buf.toStdString().c_str()); + } else { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = None", name.c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.AxialFree = %s", name.c_str(), parameterBearing->getAxial() ? "True" : "False"); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what())); + return false; + } + + return TaskDlgFemConstraint::accept(); +} + +#include "moc_TaskFemConstraintBearing.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintBearing.h b/src/Mod/Fem/Gui/TaskFemConstraintBearing.h new file mode 100644 index 000000000..671d114b4 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintBearing.h @@ -0,0 +1,93 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintBearing_H +#define GUI_TASKVIEW_TaskFemConstraintBearing_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintBearing.h" + +class Ui_TaskFemConstraintCylindrical; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintBearing : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView, QWidget *parent = 0, + const char* pixmapname = "Fem_ConstraintBearing"); + virtual ~TaskFemConstraintBearing(); + + double getDistance(void) const; + virtual const std::string getReferences() const; + const std::string getLocationName(void) const; + const std::string getLocationObject(void) const; + bool getAxial(void) const; + +private Q_SLOTS: + void onReferenceDeleted(void); + void onDistanceChanged(double l); + void onButtonLocation(const bool pressed = true); + void onCheckAxial(bool); + +protected: + virtual void changeEvent(QEvent *e); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + +protected: + Ui_TaskFemConstraintCylindrical* ui; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintBearing : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintBearing() {} + TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintBearing_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintCylindrical.ui b/src/Mod/Fem/Gui/TaskFemConstraintCylindrical.ui new file mode 100644 index 000000000..c0ee3cb29 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintCylindrical.ui @@ -0,0 +1,161 @@ + + + TaskFemConstraintCylindrical + + + + 0 + 0 + 257 + 338 + + + + Form + + + + + + Add reference + + + + + + + + + + + + Gear diameter + + + + + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 100.000000000000000 + + + + + + + + + + + Other diameter + + + + + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 200.000000000000000 + + + + + + + + + + + Center distance + + + + + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 500.000000000000000 + + + + + + + + + + + Location + + + + + + + + + + + + + + Distance + + + + + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 0.000000000000000 + + + + + + + + + Qt::Vertical + + + + 17 + 56 + + + + + + + + Axial free + + + + + + + + diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp new file mode 100644 index 000000000..cc9ad5217 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintFixed.h" +#include "TaskFemConstraintFixed.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintFixed */ + +TaskFemConstraintFixed::TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent) + : TaskFemConstraint(ConstraintView, parent, "Fem_ConstraintFixed") +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintFixed(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + + // Get the feature data + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Fill data into dialog elements + ui->listReferences->clear(); + for (int i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + + // Selection mode can be always on since there is nothing else in the UI + onButtonReference(true); +} + +void TaskFemConstraintFixed::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintFixed* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Ensure we don't have mixed reference types + if (SubElements.size() > 0) { + if (subName.substr(0,4) != SubElements.front().substr(0,4)) { + QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); + return; + } + } else { + if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); + return; + } + } + + // Avoid duplicates + int pos = 0; + for (; pos < Objects.size(); pos++) + if (obj == Objects[pos]) + break; + + if (pos != Objects.size()) + if (subName == SubElements[pos]) + return; + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + } + + Gui::Selection().clearSelection(); + } +} + +void TaskFemConstraintFixed::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +const std::string TaskFemConstraintFixed::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +TaskFemConstraintFixed::~TaskFemConstraintFixed() +{ + delete ui; +} + +void TaskFemConstraintFixed::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintFixed::TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintFixed(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintFixed::accept() +{ + return TaskDlgFemConstraint::accept(); +} + +#include "moc_TaskFemConstraintFixed.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.h b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h new file mode 100644 index 000000000..d6c404282 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintFixed_H +#define GUI_TASKVIEW_TaskFemConstraintFixed_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintFixed.h" + +class Ui_TaskFemConstraintFixed; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintFixed : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView,QWidget *parent = 0); + virtual ~TaskFemConstraintFixed(); + + virtual const std::string getReferences() const; + +private Q_SLOTS: + void onReferenceDeleted(void); + +protected: + virtual void changeEvent(QEvent *e); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + +private: + Ui_TaskFemConstraintFixed* ui; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintFixed : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintFixed(ViewProviderFemConstraintFixed *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintFixed_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui b/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui new file mode 100644 index 000000000..799fe1bb1 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintFixed.ui @@ -0,0 +1,44 @@ + + + TaskFemConstraintFixed + + + + 0 + 0 + 257 + 233 + + + + Form + + + + + + Add reference + + + + + + + + + + Qt::Vertical + + + + 17 + 56 + + + + + + + + + diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp new file mode 100644 index 000000000..4d0d5c3ff --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.cpp @@ -0,0 +1,363 @@ +/*************************************************************************** + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "ui_TaskFemConstraintForce.h" +#include "TaskFemConstraintForce.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintForce */ + +TaskFemConstraintForce::TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent) + : TaskFemConstraint(ConstraintView, parent, "Fem_ConstraintForce") +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintForce(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + // Create a context menu for the listview of the references + QAction* action = new QAction(tr("Delete"), ui->listReferences); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onReferenceDeleted())); + ui->listReferences->addAction(action); + ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->spinForce, SIGNAL(valueChanged(double)), + this, SLOT(onForceChanged(double))); + connect(ui->buttonReference, SIGNAL(pressed()), + this, SLOT(onButtonReference())); + connect(ui->buttonDirection, SIGNAL(pressed()), + this, SLOT(onButtonDirection())); + connect(ui->checkReverse, SIGNAL(toggled(bool)), + this, SLOT(onCheckReverse(bool))); + + this->groupLayout()->addWidget(proxy); + + // Temporarily prevent unnecessary feature recomputes + ui->spinForce->blockSignals(true); + ui->listReferences->blockSignals(true); + ui->buttonReference->blockSignals(true); + ui->buttonDirection->blockSignals(true); + ui->checkReverse->blockSignals(true); + + // Get the feature data + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + double f = pcConstraint->Force.getValue(); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector dirStrings = pcConstraint->Direction.getSubValues(); + QString dir; + if (!dirStrings.empty()) + dir = makeRefText(pcConstraint->Direction.getValue(), dirStrings.front()); + bool reversed = pcConstraint->Reversed.getValue(); + + // Fill data into dialog elements + ui->spinForce->setMinimum(0); + ui->spinForce->setMaximum(INT_MAX); + ui->spinForce->setValue(f); + ui->listReferences->clear(); + for (int i = 0; i < Objects.size(); i++) + ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i])); + if (Objects.size() > 0) + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir); + ui->checkReverse->setChecked(reversed); + + ui->spinForce->blockSignals(false); + ui->listReferences->blockSignals(false); + ui->buttonReference->blockSignals(false); + ui->buttonDirection->blockSignals(false); + ui->checkReverse->blockSignals(false); + + updateUI(); +} + +void TaskFemConstraintForce::updateUI() +{ + if (ui->listReferences->model()->rowCount() == 0) { + // Go into reference selection mode if no reference has been selected yet + onButtonReference(true); + return; + } + + std::string ref = ui->listReferences->item(0)->text().toStdString(); + int pos = ref.find_last_of(":"); + if (ref.substr(pos+1, 6) == "Vertex") + ui->labelForce->setText(tr("Force [N]")); + else if (ref.substr(pos+1, 4) == "Edge") + ui->labelForce->setText(tr("Force [N/mm]")); + else if (ref.substr(pos+1, 4) == "Face") + ui->labelForce->setText(tr("Force [N/mm²]")); +} + +void TaskFemConstraintForce::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (msg.Type == Gui::SelectionChanges::AddSelection) { + // Don't allow selection in other document + if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0) + return; + + if (!msg.pSubName || msg.pSubName[0] == '\0') + return; + std::string subName(msg.pSubName); + + if (selectionMode == selnone) + return; + + std::vector references(1,subName); + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName); + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str()); + + if (selectionMode == selref) { + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Ensure we don't have mixed reference types + if (SubElements.size() > 0) { + if (subName.substr(0,4) != SubElements.front().substr(0,4)) { + QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead")); + return; + } + } else { + if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked")); + return; + } + } + + // Avoid duplicates + int pos = 0; + for (; pos < Objects.size(); pos++) + if (obj == Objects[pos]) + break; + + if (pos != Objects.size()) + if (subName == SubElements[pos]) + return; + + // add the new reference + Objects.push_back(obj); + SubElements.push_back(subName); + pcConstraint->References.setValues(Objects,SubElements); + ui->listReferences->addItem(makeRefText(obj, subName)); + + // Turn off reference selection mode + onButtonReference(false); + } else if (selectionMode == seldir) { + if (subName.substr(0,4) == "Face") { + BRepAdaptor_Surface surface(TopoDS::Face(ref)); + if (surface.GetType() != GeomAbs_Plane) { + QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked")); + return; + } + } else if (subName.substr(0,4) == "Edge") { + BRepAdaptor_Curve line(TopoDS::Edge(ref)); + if (line.GetType() != GeomAbs_Line) { + QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked")); + return; + } + } else { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked")); + return; + } + pcConstraint->Direction.setValue(obj, references); + ui->lineDirection->setText(makeRefText(obj, subName)); + + // Turn off direction selection mode + onButtonDirection(false); + } + + Gui::Selection().clearSelection(); + updateUI(); + } +} + +void TaskFemConstraintForce::onForceChanged(double f) +{ + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Force.setValue((float)f); +} + +void TaskFemConstraintForce::onReferenceDeleted() { + int row = ui->listReferences->currentIndex().row(); + TaskFemConstraint::onReferenceDeleted(row); + ui->listReferences->model()->removeRow(row); + ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +void TaskFemConstraintForce::onButtonDirection(const bool pressed) { + if (pressed) { + selectionMode = seldir; + } else { + selectionMode = selnone; + } + ui->buttonDirection->setChecked(pressed); + Gui::Selection().clearSelection(); +} + +void TaskFemConstraintForce::onCheckReverse(const bool pressed) +{ + Fem::ConstraintForce* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Reversed.setValue(pressed); +} + +double TaskFemConstraintForce::getForce(void) const +{ + return ui->spinForce->value(); +} + +const std::string TaskFemConstraintForce::getReferences() const +{ + int rows = ui->listReferences->model()->rowCount(); + + std::vector items; + for (int r = 0; r < rows; r++) + items.push_back(ui->listReferences->item(r)->text().toStdString()); + return TaskFemConstraint::getReferences(items); +} + +const std::string TaskFemConstraintForce::getDirectionName(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(0, pos).c_str(); +} + +const std::string TaskFemConstraintForce::getDirectionObject(void) const +{ + std::string dir = ui->lineDirection->text().toStdString(); + if (dir.empty()) + return ""; + + int pos = dir.find_last_of(":"); + return dir.substr(pos+1).c_str(); +} + +bool TaskFemConstraintForce::getReverse() const +{ + return ui->checkReverse->isChecked(); +} + +TaskFemConstraintForce::~TaskFemConstraintForce() +{ + delete ui; +} + +void TaskFemConstraintForce::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinForce->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinForce->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintForce::TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintForce(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintForce::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintForce* parameterForce = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterForce->getForce()); + + std::string dirname = parameterForce->getDirectionName().data(); + std::string dirobj = parameterForce->getDirectionObject().data(); + + if (!dirname.empty()) { + QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); + buf = buf.arg(QString::fromStdString(dirname)); + buf = buf.arg(QString::fromStdString(dirobj)); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str()); + } else { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str()); + } + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameterForce->getReverse() ? "True" : "False"); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what())); + return false; + } + + return TaskDlgFemConstraint::accept(); +} + +#include "moc_TaskFemConstraintForce.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.h b/src/Mod/Fem/Gui/TaskFemConstraintForce.h new file mode 100644 index 000000000..5da592360 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintForce_H +#define GUI_TASKVIEW_TaskFemConstraintForce_H + +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintForce.h" + +class Ui_TaskFemConstraintForce; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintForce : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView,QWidget *parent = 0); + virtual ~TaskFemConstraintForce(); + + double getForce(void) const; + virtual const std::string getReferences() const; + const std::string getDirectionName(void) const; + const std::string getDirectionObject(void) const; + bool getReverse(void) const; + +private Q_SLOTS: + void onReferenceDeleted(void); + void onForceChanged(double); + void onButtonDirection(const bool pressed = true); + void onCheckReverse(bool); + +protected: + virtual void changeEvent(QEvent *e); + +private: + virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); + +private: + Ui_TaskFemConstraintForce* ui; +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintForce : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintForce(ViewProviderFemConstraintForce *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintForce_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintForce.ui b/src/Mod/Fem/Gui/TaskFemConstraintForce.ui new file mode 100644 index 000000000..83536403d --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintForce.ui @@ -0,0 +1,89 @@ + + + TaskFemConstraintForce + + + + 0 + 0 + 257 + 233 + + + + Form + + + + + + Add reference + + + + + + + + + + + + Load [N] + + + + + + + -99999.000000000000000 + + + 99999.000000000000000 + + + 500.000000000000000 + + + + + + + + + + + Direction + + + + + + + + + + + + Reverse direction + + + + + + + Qt::Vertical + + + + 17 + 56 + + + + + + + + + diff --git a/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp b/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp new file mode 100644 index 000000000..0ee3868e1 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintGear.cpp @@ -0,0 +1,150 @@ +/*************************************************************************** + * 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 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +*/ +#endif + +#include "ui_TaskFemConstraintCylindrical.h" +#include "TaskFemConstraintGear.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintGear */ + +TaskFemConstraintGear::TaskFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView,QWidget *parent) + : TaskFemConstraintBearing(ConstraintView, parent, "Fem_ConstraintGear") +{ + // we need a separate container widget to add all controls to + connect(ui->spinDiameter, SIGNAL(valueChanged(double)), + this, SLOT(onDiameterChanged(double))); + + // Temporarily prevent unnecessary feature recomputes + ui->spinDiameter->blockSignals(true); + + // Get the feature data + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + double dia = pcConstraint->Diameter.getValue(); + + // Fill data into dialog elements + ui->spinDiameter->setMinimum(0); + ui->spinDiameter->setMaximum(INT_MAX); + ui->spinDiameter->setValue(dia); + + // Adjust ui to specific constraint type + ui->checkAxial->setVisible(false); + ui->spinDiameter->setVisible(true); + ui->labelDiameter->setVisible(true); + + ui->spinDiameter->blockSignals(false); + + onButtonReference(true); +} +void TaskFemConstraintGear::onDiameterChanged(double l) +{ + Fem::ConstraintGear* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Diameter.setValue((float)l); +} + +double TaskFemConstraintGear::getDiameter(void) const +{ + return ui->spinDiameter->value(); +} + +void TaskFemConstraintGear::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinDiameter->blockSignals(true); + ui->spinDistance->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinDiameter->blockSignals(false); + ui->spinDistance->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintGear::TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintGear(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintGear::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintGear* parameterGear = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterGear->getDiameter()); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what())); + return false; + } + + return TaskDlgFemConstraintBearing::accept(); +} + +#include "moc_TaskFemConstraintGear.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintGear.h b/src/Mod/Fem/Gui/TaskFemConstraintGear.h new file mode 100644 index 000000000..bfc8eee09 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintGear.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintGear_H +#define GUI_TASKVIEW_TaskFemConstraintGear_H + +#include +#include +#include + +#include "TaskFemConstraintBearing.h" +#include "ViewProviderFemConstraintGear.h" + +class Ui_TaskFemConstraintGear; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintGear : public TaskFemConstraintBearing +{ + Q_OBJECT + +public: + TaskFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView,QWidget *parent = 0); + + double getDiameter(void) const; + +private Q_SLOTS: + void onDiameterChanged(double dia); + +protected: + virtual void changeEvent(QEvent *e); + +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintGear : public TaskDlgFemConstraintBearing +{ + Q_OBJECT + +public: + TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintGear_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp b/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp new file mode 100644 index 000000000..f239a37ec --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintPulley.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * 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_ +#endif + +#include "ui_TaskFemConstraintCylindrical.h" +#include "TaskFemConstraintPulley.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintPulley */ + +TaskFemConstraintPulley::TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent) + : TaskFemConstraintBearing(ConstraintView, parent, "Fem_ConstraintPulley") +{ + // we need a separate container widget to add all controls to + connect(ui->spinDiameter, SIGNAL(valueChanged(double)), + this, SLOT(onDiameterChanged(double))); + connect(ui->spinOtherDiameter, SIGNAL(valueChanged(double)), + this, SLOT(onOtherDiameterChanged(double))); + connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)), + this, SLOT(onCenterDistanceChanged(double))); + + // Temporarily prevent unnecessary feature recomputes + ui->spinDiameter->blockSignals(true); + ui->spinOtherDiameter->blockSignals(true); + ui->spinCenterDistance->blockSignals(true); + + // Get the feature data + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + double dia = pcConstraint->Diameter.getValue(); + double otherdia = pcConstraint->OtherDiameter.getValue(); + double centerdist = pcConstraint->CenterDistance.getValue(); + + // Fill data into dialog elements + ui->spinDiameter->setMinimum(0); + ui->spinDiameter->setMaximum(INT_MAX); + ui->spinDiameter->setValue(dia); + ui->spinOtherDiameter->setMinimum(0); + ui->spinOtherDiameter->setMaximum(INT_MAX); + ui->spinOtherDiameter->setValue(otherdia); + ui->spinCenterDistance->setMinimum(INT_MIN); + ui->spinCenterDistance->setMaximum(INT_MAX); + ui->spinCenterDistance->setValue(centerdist); + + // Adjust ui to specific constraint type + ui->checkAxial->setVisible(false); + ui->spinDiameter->setVisible(true); + ui->labelDiameter->setVisible(true); + ui->labelDiameter->setText(tr("Pulley diameter")); + ui->labelOtherDiameter->setVisible(true); + ui->spinOtherDiameter->setVisible(true); + ui->labelCenterDistance->setVisible(true); + ui->spinCenterDistance->setVisible(true); + + ui->spinDiameter->blockSignals(false); + ui->spinOtherDiameter->blockSignals(false); + ui->spinCenterDistance->blockSignals(false); + + onButtonReference(true); +} + +void TaskFemConstraintPulley::onDiameterChanged(double l) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->Diameter.setValue((float)l); +} + +void TaskFemConstraintPulley::onOtherDiameterChanged(double l) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->OtherDiameter.setValue((float)l); +} + +void TaskFemConstraintPulley::onCenterDistanceChanged(double l) +{ + Fem::ConstraintPulley* pcConstraint = static_cast(ConstraintView->getObject()); + pcConstraint->CenterDistance.setValue((float)l); +} + +double TaskFemConstraintPulley::getDiameter(void) const +{ + return ui->spinDiameter->value(); +} + +double TaskFemConstraintPulley::getOtherDiameter(void) const +{ + return ui->spinOtherDiameter->value(); +} + +double TaskFemConstraintPulley::getCenterDistance(void) const +{ + return ui->spinCenterDistance->value(); +} + +void TaskFemConstraintPulley::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->spinDiameter->blockSignals(true); + ui->spinDistance->blockSignals(true); + ui->spinOtherDiameter->blockSignals(true); + ui->spinCenterDistance->blockSignals(true); + ui->retranslateUi(proxy); + ui->spinDiameter->blockSignals(false); + ui->spinDistance->blockSignals(false); + ui->spinOtherDiameter->blockSignals(false); + ui->spinCenterDistance->blockSignals(false); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintPulley::TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintPulley(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +bool TaskDlgFemConstraintPulley::accept() +{ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintPulley* parameterPulley = static_cast(parameter); + + try { + //Gui::Command::openCommand("FEM force constraint changed"); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterPulley->getDiameter()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(), parameterPulley->getOtherDiameter()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(), parameterPulley->getCenterDistance()); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what())); + return false; + } + + return TaskDlgFemConstraintBearing::accept(); +} + +#include "moc_TaskFemConstraintPulley.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintPulley.h b/src/Mod/Fem/Gui/TaskFemConstraintPulley.h new file mode 100644 index 000000000..11196dafe --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintPulley.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_TASKVIEW_TaskFemConstraintPulley_H +#define GUI_TASKVIEW_TaskFemConstraintPulley_H + +#include +#include +#include + +#include "TaskFemConstraintBearing.h" +#include "ViewProviderFemConstraintPulley.h" + +class Ui_TaskFemConstraintPulley; + +namespace App { +class Property; +} + +namespace Gui { +class ViewProvider; +} + +namespace FemGui { + +class TaskFemConstraintPulley : public TaskFemConstraintBearing +{ + Q_OBJECT + +public: + TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent = 0); + + double getDiameter(void) const; + double getOtherDiameter(void) const; + double getCenterDistance(void) const; + +private Q_SLOTS: + void onDiameterChanged(double dia); + void onOtherDiameterChanged(double dia); + void onCenterDistanceChanged(double dia); + +protected: + virtual void changeEvent(QEvent *e); + +}; + +/// simulation dialog for the TaskView +class TaskDlgFemConstraintPulley : public TaskDlgFemConstraintBearing +{ + Q_OBJECT + +public: + TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView); + + /// is called by the framework if the dialog is accepted (Ok) + virtual bool accept(); + +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintPulley_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp index 2a58cc4bc..4bb6dabe3 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.cpp @@ -24,56 +24,25 @@ #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 -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include +# include +# include +# include +# include +# include +# include #endif #include "ViewProviderFemConstraint.h" #include "TaskFemConstraint.h" -#include "Gui/SoFCSelection.h" -#include "Gui/Application.h" + #include "Gui/Control.h" -#include "Gui/Command.h" -#include "Gui/Document.h" -#include "Gui/View3DInventorViewer.h" -#include "App/Document.h" - -#include -#include -#include -#include #include using namespace FemGui; @@ -85,6 +54,7 @@ ViewProviderFemConstraint::ViewProviderFemConstraint() { ADD_PROPERTY(TextColor,(0.0f,0.0f,0.0f)); ADD_PROPERTY(FaceColor,(1.0f,0.0f,0.2f)); + ADD_PROPERTY(ShapeColor,(1.0f,0.0f,0.2f)); ADD_PROPERTY(FontSize,(18)); ADD_PROPERTY(DistFactor,(1.0)); ADD_PROPERTY(Mirror,(false)); @@ -93,42 +63,66 @@ ViewProviderFemConstraint::ViewProviderFemConstraint() pFont->ref(); pLabel = new SoText2(); pLabel->ref(); - pColor = new SoBaseColor(); - pColor->ref(); pTextColor = new SoBaseColor(); pTextColor->ref(); - pTranslation = new SoTranslation(); - pTranslation->ref(); + + pMaterials = new SoMaterial(); + pMaterials->ref(); + pMaterials->diffuseColor.setValue(1.0f, 0.0f, 0.2f); + pMaterials->transparency.setValue(0.1); + //pMaterials->ambientColor.setValue(0.8f, 0.8f, 0.8f); + //pMaterials->shininess.setValue(1.0); + + pShapeSep = new SoSeparator(); + pShapeSep->ref(); TextColor.touch(); FontSize.touch(); - FaceColor.touch(); + FaceColor.touch(); - pCoords = new SoCoordinate3(); - pCoords->ref(); - pCoords->point.setNum(0); - - pFaces = new SoIndexedFaceSet(); - pFaces->ref(); - pFaces->coordIndex.setNum(0); - - sPixmap = "view-femconstraint"; - - normalDirection = new SbVec3f(0, 0, 1); - arrowDirection = NULL; + oldDlg = NULL; } ViewProviderFemConstraint::~ViewProviderFemConstraint() { pFont->unref(); pLabel->unref(); - pColor->unref(); pTextColor->unref(); - pTranslation->unref(); - pCoords->unref(); - pFaces->unref(); - delete arrowDirection; - delete normalDirection; + pMaterials->unref(); + pShapeSep->unref(); +} + +void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) +{ + ViewProviderDocumentObject::attach(pcObject); + + SoPickStyle* ps = new SoPickStyle(); + ps->style = SoPickStyle::UNPICKABLE; + + SoSeparator* sep = new SoSeparator(); + SoShapeHints* hints = new SoShapeHints(); + hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE); + hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE); + sep->addChild(ps); + sep->addChild(hints); + sep->addChild(pMaterials); + sep->addChild(pShapeSep); + addDisplayMaskMode(sep, "Base"); +} + +std::vector ViewProviderFemConstraint::getDisplayModes(void) const +{ + // add modes + std::vector StrList; + StrList.push_back("Base"); + return StrList; +} + +void ViewProviderFemConstraint::setDisplayMode(const char* ModeName) +{ + if (strcmp(ModeName, "Base") == 0) + setDisplayMaskMode("Base"); + ViewProviderDocumentObject::setDisplayMode(ModeName); } std::vector ViewProviderFemConstraint::claimChildren(void)const @@ -147,9 +141,9 @@ void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver, void ViewProviderFemConstraint::onChanged(const App::Property* prop) { if (this->getObject() != NULL) - Base::Console().Error("%s: onChanged: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + Base::Console().Error("%s: VP onChanged: %s\n", this->getObject()->getNameInDocument(), prop->getName()); else - Base::Console().Error("Anonymous: onChanged: %s\n", prop->getName()); + Base::Console().Error("Anonymous: VP onChanged: %s\n", prop->getName()); if (prop == &Mirror || prop == &DistFactor) { updateData(prop); @@ -160,7 +154,7 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop) } else if (prop == &FaceColor) { const App::Color& c = FaceColor.getValue(); - pColor->rgb.setValue(c.r,c.g,c.b); + pMaterials->diffuseColor.setValue(c.r,c.g,c.b); } else if (prop == &FontSize) { pFont->size = FontSize.getValue(); @@ -170,45 +164,6 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop) } } -bool ViewProviderFemConstraint::setEdit(int ModNum) -{ - if (ModNum == ViewProvider::Default ) { - // When double-clicking on the item for this constraint the - // object unsets and sets its edit mode without closing - // the task panel - Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); - TaskDlgFemConstraint *constrDlg = qobject_cast(dlg); - if (constrDlg && constrDlg->getConstraintView() != this) - constrDlg = 0; // another constraint left open its task panel - if (dlg && !constrDlg) { - 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().closeDialog(); - else - return false; - } - - // clear the selection (convenience) - Gui::Selection().clearSelection(); - - // start the edit dialog - if (constrDlg) - Gui::Control().showDialog(constrDlg); - else - Gui::Control().showDialog(new TaskDlgFemConstraint(this)); - - return true; - } - else { - return ViewProviderDocumentObject::setEdit(ModNum); - } -} - void ViewProviderFemConstraint::unsetEdit(int ModNum) { if (ModNum == ViewProvider::Default) { @@ -218,41 +173,13 @@ void ViewProviderFemConstraint::unsetEdit(int ModNum) else { ViewProviderDocumentObject::unsetEdit(ModNum); } + + if (oldDlg != NULL) { + Gui::Control().showDialog(oldDlg); + oldDlg = NULL; + } } - -std::vector ViewProviderFemConstraint::getDisplayModes(void) const -{ - // add modes - std::vector StrList; - StrList.push_back("Base"); - return StrList; -} - -void ViewProviderFemConstraint::setDisplayMode(const char* ModeName) -{ - if (strcmp(ModeName, "Base") == 0) - setDisplayMaskMode("Base"); - ViewProviderDocumentObject::setDisplayMode(ModeName); -} - -void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject) -{ - ViewProviderDocumentObject::attach(pcObject); - - SoPickStyle* ps = new SoPickStyle(); - ps->style = SoPickStyle::UNPICKABLE; - - SoSeparator *faceSep = new SoSeparator(); - faceSep->addChild(ps); - faceSep->addChild(pColor); - faceSep->addChild(pCoords); - faceSep->addChild(pFaces); - - SoSeparator* sep = new SoSeparator(); - sep->addChild(faceSep); - addDisplayMaskMode(sep, "Base"); -} - +/* // Create a local coordinate system with the z-axis given in dir void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x) { @@ -299,521 +226,163 @@ void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x) y = SbVec3f(y1, y2, y3); x = y.cross(z); } +*/ +#define PLACEMENT_CHILDREN 2 -#define FACETS 12 -#define CONEPOINTS (FACETS + 1) -#define CONEFACETPOINTS (FACETS * 4 + FACETS + 1) - -void createCone(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir, - const double height, const double radius, const bool update = false) +void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r) { - SbVec3f x, y; - getLocalCoordinateSystem(dir, y, x); - - point.set1Value(ipoints, base); // tip - - SbVec3f midpoint(base + dir * height); // centre of the circle - for (int i = 0; i < FACETS; i++) { - float angle = 2 * M_PI / FACETS * i; - point.set1Value(ipoints + i + 1, midpoint + cos(angle) * x * radius + sin(angle) * y * radius); - } - - if (update) - return; - - int32_t faces[CONEFACETPOINTS]; - int start_index = 1; - for (int f = 0; f < FACETS; f++) { - faces[f * 4] = ipoints; // tip of arrow - int idx = start_index; - faces[f * 4 + 1] = ipoints + idx; - idx++; - if (idx > FACETS) idx = 1; // Happens in the last iteration - faces[f * 4 + 2] = ipoints + idx; - faces[f * 4 + 3] = -1; - start_index++; - } - for (int f = 0; f < FACETS; f++) - faces[FACETS * 4 + f] = ipoints + f + 1; - faces[CONEFACETPOINTS - 1] = -1; - refs.setValues(ifaces, CONEFACETPOINTS, faces); + SoTranslation* trans = new SoTranslation(); + trans->ref(); + trans->translation.setValue(base); + sep->addChild(trans); + SoRotation* rot = new SoRotation(); + rot->ref(); + rot->rotation.setValue(r); + sep->addChild(rot); } -#define CYLPOINTS (FACETS * 2) -#define CYLFACETPOINTS (FACETS * 5 + 2 * FACETS + 2) - -void createCylinder(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir, - const double height, const double radius, const bool update = false) +void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r) { - SbVec3f x, y; - getLocalCoordinateSystem(dir, y, x); - - for (int i = 0; i < CYLPOINTS; i+=2) { - float angle = 2 * M_PI / FACETS * i/2; - point.set1Value(ipoints + i, base + cos(angle) * x * radius + sin(angle) * y * radius); - point.set1Value(ipoints + i + 1, base + dir * height + cos(angle) * x * radius + sin(angle) * y * radius); - } - - if (update) - return; - - int32_t faces[CYLFACETPOINTS]; - int start_index = 0; - for (int f = 0; f < FACETS; f++) { - int idx = start_index; - faces[f * 5] = ipoints + idx; - idx++; - faces[f * 5 + 1] = ipoints + idx; - idx++; - if (idx >= CYLPOINTS) idx = 0; // Happens in the last iteration - faces[f * 5 + 3] = ipoints + idx; - idx++; - faces[f * 5 + 2] = ipoints + idx; - faces[f * 5 + 4] = -1; - start_index += 2; - } - for (int f = 0; f < FACETS; f++) { - faces[FACETS * 5 + f] = ipoints + 2 * f; - faces[FACETS * 5 + FACETS + f + 1] = ipoints + 1 + 2 * f; - } - faces[FACETS * 5 + FACETS] = -1; - faces[CYLFACETPOINTS - 1] = -1; - refs.setValues(ifaces, CYLFACETPOINTS, faces); + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(base); + SoRotation* rot = static_cast(sep->getChild(idx+1)); + rot->rotation.setValue(r); } -#define ARROWPOINTS (CONEPOINTS + CYLPOINTS) -#define ARROWFACETPOINTS (CONEFACETPOINTS + CYLFACETPOINTS) +#define CONE_CHILDREN 2 -void createArrow(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir, - const double length, const double radius, const bool update = false) +void ViewProviderFemConstraint::createCone(SoSeparator* sep, const double height, const double radius) { - createCone(point, refs, ipoints, ifaces, base, dir, radius, radius, update); - createCylinder(point, refs, ipoints + CONEPOINTS, ifaces + CONEFACETPOINTS, base + dir * radius, dir, length-radius, radius/3, update); + // Adjust cone so that the tip is on base + SoTranslation* trans = new SoTranslation(); + trans->ref(); + trans->translation.setValue(SbVec3f(0,-height/2,0)); + sep->addChild(trans); + SoCone* cone = new SoCone(); + cone->ref(); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); + sep->addChild(cone); } -#define BOXPOINTS 8 -#define BOXFACEPOINTS 30 - -void createBox(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir, - const double width, const double length, const double height, const bool update = false) +SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius) { - SbVec3f x, y; - getLocalCoordinateSystem(dir, y, x); - - point.set1Value(ipoints, base + width/2 * y + length/2 * x); - point.set1Value(ipoints+1, base + width/2 * y - length/2 * x); - point.set1Value(ipoints+2, base - width/2 * y - length/2 * x); - point.set1Value(ipoints+3, base - width/2 * y + length/2 * x); - point.set1Value(ipoints+4, base + dir * height + width/2 * y + length/2 * x); - point.set1Value(ipoints+5, base + dir * height + width/2 * y - length/2 * x); - point.set1Value(ipoints+6, base + dir * height - width/2 * y - length/2 * x); - point.set1Value(ipoints+7, base + dir * height - width/2 * y + length/2 * x); - - if (update) - return; - - int32_t faces[BOXFACEPOINTS] = { - ipoints, ipoints+1, ipoints+2, ipoints+3, -1, - ipoints, ipoints+1, ipoints+5, ipoints+4, -1, - ipoints+1, ipoints+2, ipoints+6, ipoints+5, -1, - ipoints+2, ipoints+3, ipoints+7, ipoints+6, -1, - ipoints+3, ipoints, ipoints+4, ipoints+7, -1, - ipoints+4, ipoints+5, ipoints+6, ipoints+7, -1}; - refs.setValues(ifaces, BOXFACEPOINTS, faces); + // Create a new cone node + SoSeparator* sep = new SoSeparator(); + createCone(sep, height, radius); + return sep; } -void ViewProviderFemConstraint::findCylinderData(SbVec3f& z, SbVec3f& y, SbVec3f& x, SbVec3f& p, double& radius, double& height) { - Fem::Constraint* pcConstraint = static_cast(this->getObject()); - std::vector Objects = pcConstraint->References.getValues(); - std::vector SubElements = pcConstraint->References.getSubValues(); - if (Objects.empty()) - return; - App::DocumentObject* obj = Objects[0]; - Part::Feature* feat = static_cast(obj); - TopoDS_Shape sh = feat->Shape.getShape().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_Dir dirz = cyl.Axis().Direction(); - z = SbVec3f(dirz.X(), dirz.Y(), dirz.Z()); - gp_Dir diry = cyl.YAxis().Direction(); - y = SbVec3f(diry.X(), diry.Y(), diry.Z()); - gp_Dir dirx = cyl.XAxis().Direction(); - x = SbVec3f(dirx.X(), dirx.Y(), dirx.Z()); - - if (pcConstraint->Location.getValue() == NULL) { - // Get a point in the middle of the cylindrical face. - gp_Pnt centre = cyl.Location(); - SbVec3f base(centre.X(), centre.Y(), centre.Z()); - p = base + z * height/2; - } else { - // Get the point specified by Location and Distance - App::DocumentObject* objLoc = pcConstraint->Location.getValue(); - std::string subName = pcConstraint->Location.getSubValues().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; - 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(dirz); - 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); - GeomAPI_ProjectPointOnSurf proj(cyl.Location(), pln); - if (!proj.IsDone()) - return; - gp_Pnt projPnt = proj.NearestPoint(); - plane.Translate(gp_Vec(projPnt, cyl.Location()).Normalized().Multiplied(pcConstraint->Distance.getValue())); - Handle_Geom_Plane plnt = new Geom_Plane(plane); - // Intersect translated plane with cylinder axis - Handle_Geom_Curve crv = new Geom_Line(cyl.Axis()); - GeomAPI_IntCS intersector(crv, plnt); - if (!intersector.IsDone()) - return; - gp_Pnt inter = intersector.Point(1); - p.setValue(inter.X(), inter.Y(), inter.Z()); - } -} - -void ViewProviderFemConstraint::updateData(const App::Property* prop) +void ViewProviderFemConstraint::updateCone(const SoNode* node, const int idx, const double height, const double radius) { - // Gets called whenever a property of the attached object changes - if (this->getObject() != NULL) - Base::Console().Error("%s: updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); - else - Base::Console().Error("Anonymous: updateData: %s\n", prop->getName()); - Fem::Constraint* pcConstraint = static_cast(this->getObject()); - - if (strcmp(prop->getName(),"References") == 0) { - const App::PropertyLinkSubList* pr = static_cast(prop); - std::vector Objects = pr->getValues(); - std::vector SubElements = pr->getSubValues(); - - // Remove all arrows - pCoords->point.deleteValues(0, pCoords->point.getNum()); - pFaces->coordIndex.deleteValues(0, pFaces->coordIndex.getNum()); - if (Objects.empty()) { - Base::Console().Error(" updateData: No references\n"); - Objects = pcConstraint->References.getValues(); - SubElements = pcConstraint->References.getSubValues(); - if (Objects.empty()) - return; - } - - Base::Console().Error(" updateData: Found %u references\n", Objects.size()); - - // Re-create all arrows - int type = pcConstraint->Type.getValue(); - - if ((type == 0) || (type == 1)) { - // Force on geometry - std::vector points; - TopoDS_Shape sh; - - for (int 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()) { - Base::Console().Error(" updateData: Empty toposhape\n"); - return; - } - 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.push_back(p); - } 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(sh, props); - double l = props.Mass(); - int steps = round(l / 3); // TODO: Make number of steps depend on actual screen size of element! - double step = (lp - fp) / steps; - if (steps < 1) { - points.push_back(curve.Value(fp)); - points.push_back(curve.Value(lp)); - } else { - for (int i = 0; i < steps + 1; i++) - points.push_back(curve.Value(i * step)); - } - } else if (sh.ShapeType() == TopAbs_FACE) { - TopoDS_Face face = TopoDS::Face(sh); - BRepAdaptor_Surface surface(face); - double ufp = surface.FirstUParameter(); - double ulp = surface.LastUParameter(); - double vfp = surface.FirstVParameter(); - double vlp = surface.LastVParameter(); - double ustep = (ulp - ufp) / 6.0; - double vstep = (vlp - vfp) / 6.0; - // TODO: How to find the distance between ufp and ulp to get the number of steps? - for (int i = 0; i < 7; i++) { - for (int j = 0; j < 7; j++) { - gp_Pnt p = surface.Value(ufp + i * ustep, vfp + j * vstep); - BRepClass_FaceClassifier classifier(face, p, Precision::Confusion()); - if (classifier.State() != TopAbs_OUT) - points.push_back(p); - } - } - } - } - - // Get default direction (on first call to method) - if (arrowDirection == NULL) { - if (sh.ShapeType() == TopAbs_FACE) { - // Get face normal in center point - TopoDS_Face face = TopoDS::Face(sh); - BRepGProp_Face prop(face); - gp_Vec normal; - gp_Pnt center; - double u1,u2,v1,v2; - prop.Bounds(u1,u2,v1,v2); - prop.Normal((u1+u2)/2.0,(v1+v2)/2.0,center,normal); - normal.Normalize(); - normalDirection->setValue(normal.X(), normal.Y(), normal.Z()); - } // else use z axis - - arrowDirection = new SbVec3f(*normalDirection); - } - - if (type == 0) { - // Force on geometry - pCoords->point.setNum(ARROWPOINTS * points.size()); - pFaces->coordIndex.setNum(ARROWFACETPOINTS * points.size()); - int index = 0; - - for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { - SbVec3f v(p->X(), p->Y(), p->Z()); - if (*arrowDirection != *normalDirection) // Turn arrow around - v = v + *normalDirection * 5.0; - createArrow(pCoords->point, pFaces->coordIndex, - index * ARROWPOINTS, index * ARROWFACETPOINTS, - v, *arrowDirection, 5.0, 1.0); - index++; - } - } else if (type == 1) { - // Fixed - pCoords->point.setNum((CONEPOINTS + BOXPOINTS) * points.size()); - pFaces->coordIndex.setNum((CONEFACETPOINTS + BOXFACEPOINTS) * points.size()); - int index = 0; - - for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { - SbVec3f v(p->X(), p->Y(), p->Z()); - createCone(pCoords->point, pFaces->coordIndex, - index * (CONEPOINTS + BOXPOINTS), index * (CONEFACETPOINTS + BOXFACEPOINTS), - v, *normalDirection, 2.0, 1.0); - createBox(pCoords->point, pFaces->coordIndex, - index * (CONEPOINTS + BOXPOINTS) + CONEPOINTS, index * (CONEFACETPOINTS + BOXFACEPOINTS) + CONEFACETPOINTS, - v + *normalDirection * 2.0, *normalDirection, 2.0, 2.0, 0.5); - index++; - } - } - } else if ((type == 2) || (type == 3)) { - // Bearing. Note that only one face is allowed for this constraint - SbVec3f z, y, x, p; - double radius, height; - findCylinderData(z, y, x, p, radius, height); - p = p + y * radius; - - pCoords->point.setNum(CONEPOINTS + BOXPOINTS); - pFaces->coordIndex.setNum(CONEFACETPOINTS + BOXFACEPOINTS); - if (type == 2) - // axial free - createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2.5, radius/4); - else - // axial fixed - createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2, radius/4); - - createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10); - } else if ((type == 4) || (type == 5)) { - // Pulley, Gear - SbVec3f z, y, x, p; - double radius, height; - findCylinderData(z, y, x, p, radius, height); - - double dia = pcConstraint->Diameter.getValue(); - if (dia < Precision::Confusion()) - dia = radius * 4; - double otherdia = pcConstraint->OtherDiameter.getValue(); - if (otherdia < Precision::Confusion()) - otherdia = radius * 2; - double centerdist = pcConstraint->CenterDistance.getValue(); - if (fabs(centerdist) < Precision::Confusion()) - centerdist = 500; - - if (type == 4) { - // Pulley - pCoords->point.setNum(CYLPOINTS + 2 * ARROWPOINTS); - pFaces->coordIndex.setNum(CYLFACETPOINTS + 2 * ARROWFACETPOINTS); - createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia); - - double angle = asin((dia - otherdia)/2/centerdist); - SbVec3f p1 = p + y * dia * cos(angle) + x * dia * sin(angle); - SbVec3f dir1 = x - y * sin(angle); - dir1.normalize(); - p1 = p1 + dir1 * 2 * radius; - dir1.negate(); - SbVec3f p2 = p - y * dia * cos(angle) + x * dia * sin(angle); - SbVec3f dir2 = x + y * sin(angle); - dir2.normalize(); - p2 = p2 + dir2 * 2 * radius; - dir2.negate(); - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, dir1, 2 * radius, radius/5); - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS+ARROWPOINTS, CYLFACETPOINTS+ARROWFACETPOINTS, p2, dir2, 2 * radius, radius/5); - } else if (type == 5) { - // Gear - pCoords->point.setNum(CYLPOINTS + ARROWPOINTS); - pFaces->coordIndex.setNum(CYLFACETPOINTS + ARROWFACETPOINTS); - createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia); - SbVec3f p1 = p + y * dia; - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, x, radius, radius/5); - } - } - } else if (strcmp(prop->getName(),"Direction") == 0) { - if (arrowDirection == NULL) - return; - const App::PropertyLinkSub* pr = static_cast(prop); - App::DocumentObject* obj = pr->getValue(); - std::vector names = pr->getSubValues(); - if (names.size() == 0) - return; - std::string subName = names.front(); - Part::Feature* feat = static_cast(obj); - TopoDS_Shape sh = feat->Shape.getShape().getSubShape(subName.c_str()); - - if (sh.ShapeType() == TopAbs_FACE) { - BRepAdaptor_Surface surface(TopoDS::Face(sh)); - if (surface.GetType() == GeomAbs_Plane) { - gp_Dir dir = surface.Plane().Axis().Direction(); - arrowDirection->setValue(dir.X(), dir.Y(), dir.Z()); - } else { - return; // Not a planar face - } - } else if (sh.ShapeType() == TopAbs_EDGE) { - BRepAdaptor_Curve line(TopoDS::Edge(sh)); - if (line.GetType() == GeomAbs_Line) { - gp_Dir dir = line.Line().Direction(); - arrowDirection->setValue(dir.X(), dir.Y(), dir.Z()); - } else { - return; // Not a linear edge - } - } - - // TODO: Check whether direction points inside or outside of solid? But for which reference? - - arrowDirection->normalize(); - - *normalDirection = *arrowDirection; - bool reversed = pcConstraint->Reversed.getValue(); - if (reversed) - arrowDirection->negate(); - - // Re-orient all arrows - int numArrows = pCoords->point.getNum()/ARROWPOINTS; - - for (int i = 0; i < numArrows; i++) { - // Note: for update=true the pFaces->coordIndex is not touched - SbVec3f p = pCoords->point[i * ARROWPOINTS]; - if (reversed) - p = p + *normalDirection * 5.0; - createArrow(pCoords->point, pFaces->coordIndex, - i * ARROWPOINTS, 0, - p, *arrowDirection, 5.0, 1.0, true); - } - } else if (strcmp(prop->getName(),"Reversed") == 0) { - if (arrowDirection == NULL) - return; - bool reversed = static_cast(prop)->getValue(); - bool isReversed = (*arrowDirection != *normalDirection); - if (reversed == isReversed) - return; - - *arrowDirection = *normalDirection; - if (reversed) - arrowDirection->negate(); - - // Reverse all arrows - int numArrows = pCoords->point.getNum()/ARROWPOINTS; - - for (int i = 0; i < numArrows; i++) { - createArrow(pCoords->point, pFaces->coordIndex, - i * ARROWPOINTS, 0, - pCoords->point[i * ARROWPOINTS], *arrowDirection, 5.0, 1.0, true); - } - } else if ((strcmp(prop->getName(),"Location") == 0) || (strcmp(prop->getName(),"Distance") == 0)) { - // Move bearing constraint - SbVec3f z, y, x, p; - double radius, height; - findCylinderData(z, y, x, p, radius, height); - - int type = pcConstraint->Type.getValue(); - if (type == 2) { - // axial free - createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2.5, radius/4, true); - createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10, true); - } else if (type == 3) { - // axial fixed - createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2, radius/4, true); - createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10, true); - } else if ((type == 4) || (type == 5)) { - createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, pcConstraint->Diameter.getValue(), true); - } - } else if ((strcmp(prop->getName(),"Diameter") == 0) || (strcmp(prop->getName(),"OtherDiameter") == 0) || - (strcmp(prop->getName(),"CenterDistance") == 0)) { - // Update pulley/gear constraint - SbVec3f z, y, x, p; - double radius, height; - findCylinderData(z, y, x, p, radius, height); - - double dia = pcConstraint->Diameter.getValue(); - if (dia < Precision::Confusion()) - dia = radius * 4; - double otherdia = pcConstraint->OtherDiameter.getValue(); - if (otherdia < Precision::Confusion()) - otherdia = radius * 2; - double centerdist = pcConstraint->CenterDistance.getValue(); - if (fabs(centerdist) < Precision::Confusion()) - centerdist = 500; - int type = pcConstraint->Type.getValue(); - - if (type == 4) { - // Pulley - createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia, true); - - double angle = asin((dia - otherdia)/2/centerdist); - SbVec3f p1 = p + y * dia * cos(angle) + x * dia * sin(angle); - SbVec3f dir1 = x - y * sin(angle); - dir1.normalize(); - p1 = p1 + dir1 * 2 * radius; - dir1.negate(); - SbVec3f p2 = p - y * dia * cos(angle) + x * dia * sin(angle); - SbVec3f dir2 = x + y * sin(angle); - dir2.normalize(); - p2 = p2 + dir2 * 2 * radius; - dir2.negate(); - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, dir1, 2 * radius, radius/5, true); - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS+ARROWPOINTS, CYLFACETPOINTS+ARROWFACETPOINTS, p2, dir2, 2 * radius, radius/5, true); - } else if (type == 5) { - // Gear - createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia, true); - SbVec3f p1 = p + y * dia; - createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, x, 2 * radius, radius/5, true); - } - } - ViewProviderDocumentObject::updateData(prop); + const SoSeparator* sep = static_cast(node); + SoTranslation* trans = static_cast(sep->getChild(idx)); + trans->translation.setValue(SbVec3f(0,-height/2,0)); + SoCone* cone = static_cast(sep->getChild(idx+1)); + cone->height.setValue(height); + cone->bottomRadius.setValue(radius); } + +#define CYLINDER_CHILDREN 1 + +void ViewProviderFemConstraint::createCylinder(SoSeparator* sep, const double height, const double radius) +{ + SoCylinder* cyl = new SoCylinder(); + cyl->ref(); + cyl->height.setValue(height); + cyl->radius.setValue(radius); + sep->addChild(cyl); +} + +SoSeparator* ViewProviderFemConstraint::createCylinder(const double height, const double radius) +{ + // Create a new cylinder node + SoSeparator* sep = new SoSeparator(); + createCylinder(sep, height, radius); + return sep; +} + +void ViewProviderFemConstraint::updateCylinder(const SoNode* node, const int idx, const double height, const double radius) +{ + const SoSeparator* sep = static_cast(node); + SoCylinder* cyl = static_cast(sep->getChild(idx)); + cyl->height.setValue(height); + cyl->radius.setValue(radius); +} + +#define CUBE_CHILDREN 1 + +void ViewProviderFemConstraint::createCube(SoSeparator* sep, const double width, const double length, const double height) +{ + SoCube* cube = new SoCube(); + cube->ref(); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); + sep->addChild(cube); +} + +SoSeparator* ViewProviderFemConstraint::createCube(const double width, const double length, const double height) +{ + SoSeparator* sep = new SoSeparator(); + createCube(sep, width, length, height); + return sep; +} + +void ViewProviderFemConstraint::updateCube(const SoNode* node, const int idx, const double width, const double length, const double height) +{ + const SoSeparator* sep = static_cast(node); + SoCube* cube = static_cast(sep->getChild(idx)); + cube->width.setValue(width); + cube->depth.setValue(length); + cube->height.setValue(height); +} + +#define ARROW_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN) + +void ViewProviderFemConstraint::createArrow(SoSeparator* sep, const double length, const double radius) +{ + createCone(sep, radius, radius/2); + createPlacement(sep, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); + createCylinder(sep, length-radius, radius/5); +} + +SoSeparator* ViewProviderFemConstraint::createArrow(const double length, const double radius) +{ + SoSeparator* sep = new SoSeparator(); + createArrow(sep, length, radius); + return sep; +} + +void ViewProviderFemConstraint::updateArrow(const SoNode* node, const int idx, const double length, const double radius) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, radius, radius/2); + updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -radius/2-(length-radius)/2, 0), SbRotation()); + updateCylinder(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, length-radius, radius/5); +} + +#define FIXED_CHILDREN (CONE_CHILDREN + PLACEMENT_CHILDREN + CUBE_CHILDREN) + +void ViewProviderFemConstraint::createFixed(SoSeparator* sep, const double height, const double width, const bool gap) +{ + createCone(sep, height-width/4, height-width/4); + createPlacement(sep, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.1) * width/8, 0), SbRotation()); + createCube(sep, width, width, width/4); +} + +SoSeparator* ViewProviderFemConstraint::createFixed(const double height, const double width, const bool gap) +{ + SoSeparator* sep = new SoSeparator(); + createFixed(sep, height, width, gap); + return sep; +} + +void ViewProviderFemConstraint::updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap) +{ + const SoSeparator* sep = static_cast(node); + updateCone(sep, idx, height-width/4, height-width/4); + updatePlacement(sep, idx+CONE_CHILDREN, SbVec3f(0, -(height-width/4)/2-width/8 - (gap ? 1.0 : 0.0) * width/8, 0), SbRotation()); + updateCube(sep, idx+CONE_CHILDREN+PLACEMENT_CHILDREN, width, width, width/4); +} + diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h index 94b434d2a..09ca86eaf 100644 --- a/src/Mod/Fem/Gui/ViewProviderFemConstraint.h +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraint.h @@ -33,14 +33,14 @@ class SoFontStyle; class SoText2; class SoBaseColor; class SoTranslation; -class SoCoordinate3; -class SoIndexedLineSet; -class SoIndexedFaceSet; -class SoEventCallback; -class SoMarkerSet; +class SbRotation; +class SoMaterial; namespace Gui { class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } } namespace FemGui @@ -58,12 +58,13 @@ public: // Display properties App::PropertyColor TextColor; App::PropertyColor FaceColor; + App::PropertyColor ShapeColor; App::PropertyInteger FontSize; App::PropertyFloat DistFactor; App::PropertyBool Mirror; void attach(App::DocumentObject *); - void updateData(const App::Property*); + virtual void updateData(const App::Property*) {} std::vector getDisplayModes(void) const; void setDisplayMode(const char* ModeName); @@ -72,24 +73,37 @@ public: protected: void onChanged(const App::Property* prop); - virtual bool setEdit(int ModNum); + virtual bool setEdit(int ModNum) {} virtual void unsetEdit(int ModNum); + static void createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r); + static void updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r); + static void createCone(SoSeparator* sep, const double height, const double radius); + static SoSeparator* createCone(const double height, const double radius); + static void updateCone(const SoNode* node, const int idx, const double height, const double radius); + static void createCylinder(SoSeparator* sep, const double height, const double radius); + static SoSeparator* createCylinder(const double height, const double radius); + static void updateCylinder(const SoNode* node, const int idx, const double height, const double radius); + static void createCube(SoSeparator* sep, const double width, const double length, const double height); + static SoSeparator* createCube(const double width, const double length, const double height); + static void updateCube(const SoNode* node, const int idx, const double width, const double length, const double height); + static void createArrow(SoSeparator* sep, const double length, const double radius); + static SoSeparator* createArrow(const double length, const double radius); + static void updateArrow(const SoNode* node, const int idx, const double length, const double radius); + static void createFixed(SoSeparator* sep, const double height, const double width, const bool gap); + static SoSeparator* createFixed(const double height, const double width, const bool gap = false); + static void updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap = false); + private: SoFontStyle * pFont; SoText2 * pLabel; - SoBaseColor * pColor; SoBaseColor * pTextColor; - SoTranslation * pTranslation; - SoCoordinate3 * pCoords; - SoIndexedFaceSet * pFaces; + SoMaterial * pMaterials; - /// Direction pointing outside of the solid - SbVec3f * normalDirection; - /// Direction of the force - SbVec3f * arrowDirection; +protected: + SoSeparator * pShapeSep; - void findCylinderData(SbVec3f& z, SbVec3f& y, SbVec3f& x, SbVec3f& p, double& radius, double& height); + Gui::TaskView::TaskDialog *oldDlg; }; } //namespace FemGui diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp new file mode 100644 index 000000000..bf6a7cf41 --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.cpp @@ -0,0 +1,142 @@ +/*************************************************************************** + * 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 +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintBearing.h" +#include +#include "TaskFemConstraintBearing.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintBearing, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintBearing::ViewProviderFemConstraintBearing() +{ + sPixmap = "view-femconstraintbearing"; +} + +ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing() +{ +} + +bool ViewProviderFemConstraintBearing::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintBearing *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // Allow stacking of dialogs, for ShaftWizard application + // Note: If other features start to allow stacking, we need to check for oldDlg != NULL + oldDlg = dlg; + /* + 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().closeDialog(); + else + return false; + */ + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintBearing(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintBearing::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintBearing* pcConstraint = static_cast(this->getObject()); + if (this->getObject() != NULL) + Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + else + Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName()); + + if (strcmp(prop->getName(),"BasePoint") == 0) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + // This should always point outside of the cylinder + Base::Vector3f normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + float radius = pcConstraint->Radius.getValue(); + base = base + radius * normal; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(normal.x, normal.y, normal.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + createPlacement(pShapeSep, b, rot); + pShapeSep->addChild(createFixed(radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue())); + } else if (strcmp(prop->getName(),"AxialFree") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + Base::Vector3f normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + float radius = pcConstraint->Radius.getValue(); + base = base + radius * normal; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(normal.x, normal.y, normal.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + updatePlacement(pShapeSep, 0, b, rot); + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateFixed(sep, 0, radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue()); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h new file mode 100644 index 000000000..a7ceff6df --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintBearing.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H + +#include + +#include "ViewProviderFemConstraint.h" +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; +class SoLightModel; +class SoCoordinate3; +class SoIndexedLineSet; +class SoIndexedFaceSet; +class SoEventCallback; +class SoMarkerSet; + +namespace Gui { +class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } +} + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintBearing : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintBearing); + +public: + /// Constructor + ViewProviderFemConstraintBearing(); + virtual ~ViewProviderFemConstraintBearing(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp new file mode 100644 index 000000000..74727e5ac --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.cpp @@ -0,0 +1,147 @@ +/*************************************************************************** + * 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 + +# include +# include +# include +# include + +#endif + +#include "ViewProviderFemConstraintFixed.h" +#include +#include "TaskFemConstraintFixed.h" + +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed() +{ + sPixmap = "view-femconstraintfixed"; +} + +ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed() +{ +} + +bool ViewProviderFemConstraintFixed::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintFixed *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // Allow stacking of dialogs, for ShaftWizard application + // Note: If other features start to allow stacking, we need to check for oldDlg != NULL + oldDlg = dlg; + /* + 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().closeDialog(); + else + return false; + */ + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintFixed(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +#define HEIGHT 4 +#define WIDTH (1.5*HEIGHT) + +void ViewProviderFemConstraintFixed::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + if (this->getObject() != NULL) + Base::Console().Error("%s: VPF updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + else + Base::Console().Error("Anonymous: VPF updateData: %s\n", prop->getName()); + + Fem::ConstraintFixed* pcConstraint = static_cast(this->getObject()); + + if (pShapeSep->getNumChildren() == 0) { + // Set up the nodes + SoMultipleCopy* cp = new SoMultipleCopy(); + cp->ref(); + cp->matrix.setNum(0); + cp->addChild((SoNode*)createFixed(HEIGHT, WIDTH)); + pShapeSep->addChild(cp); + } + + if (strcmp(prop->getName(),"Points") == 0) { + // Note: Points and Normals are always updated together + + const std::vector& points = pcConstraint->Points.getValues(); + const std::vector& normals = pcConstraint->Normals.getValues(); + std::vector::const_iterator n = normals.begin(); + SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + int idx = 0; + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + SbVec3f dir(n->x, n->y, n->z); + SbRotation rot(SbVec3f(0,-1,0), dir); + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + cp->matrix.set1Value(idx, m); + n++; + idx++; + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h new file mode 100644 index 000000000..ff9825e8a --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintFixed.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H + +#include + +#include "ViewProviderFemConstraint.h" +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; +class SoLightModel; +class SoCoordinate3; +class SoIndexedLineSet; +class SoIndexedFaceSet; +class SoEventCallback; +class SoMarkerSet; + +namespace Gui { +class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } +} + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintFixed : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintFixed); + +public: + /// Constructor + ViewProviderFemConstraintFixed(); + virtual ~ViewProviderFemConstraintFixed(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp new file mode 100644 index 000000000..b29a65f9a --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * 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 +# include +# include +# include +# include + +#endif + +#include "ViewProviderFemConstraintForce.h" +#include +#include "TaskFemConstraintForce.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintForce::ViewProviderFemConstraintForce() +{ + sPixmap = "view-femconstraintforce"; +} + +ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce() +{ +} + +bool ViewProviderFemConstraintForce::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintForce *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // Allow stacking of dialogs, for ShaftWizard application + // Note: If other features start to allow stacking, we need to check for oldDlg != NULL + oldDlg = dlg; + /* + 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().closeDialog(); + else + return false; + */ + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintForce(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +#define ARROWLENGTH 9 +#define ARROWHEADRADIUS (ARROWLENGTH/3) + +void ViewProviderFemConstraintForce::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + if (this->getObject() != NULL) + Base::Console().Error("%s: VPF updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + else + Base::Console().Error("Anonymous: VPF updateData: %s\n", prop->getName()); + + Fem::ConstraintForce* pcConstraint = static_cast(this->getObject()); + + /* + if (pShapeSep->getNumChildren() == 0) { + // Set up the nodes + SoMultipleCopy* cp = new SoMultipleCopy(); + cp->ref(); + cp->matrix.setNum(0); + cp->addChild((SoNode*)createArrow(ARROWLENGTH, ARROWHEADRADIUS)); + pShapeSep->addChild(cp); + } + */ + + if (strcmp(prop->getName(),"Points") == 0) { + // Redraw all arrows + pShapeSep->removeAllChildren(); + + // This should always point outside of the solid + Base::Vector3f normal = pcConstraint->NormalDirection.getValue(); + + // Get default direction (on first call to method) + Base::Vector3f forceDirection = pcConstraint->DirectionVector.getValue(); + if (forceDirection.Length() < Precision::Confusion()) + forceDirection = normal; + + SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + const std::vector& points = pcConstraint->Points.getValues(); + + /* + SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + int idx = 0;*/ + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + if (forceDirection.GetAngle(normal) < M_PI_2) // Move arrow so it doesn't disappear inside the solid + base = base + dir * ARROWLENGTH; + /* + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + cp->matrix.set1Value(idx, m); + idx++; + */ + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, base, rot); + createArrow(sep, ARROWLENGTH, ARROWHEADRADIUS); + pShapeSep->addChild(sep); + } + } else if (strcmp(prop->getName(),"DirectionVector") == 0) { // Note: "Reversed" also triggers "DirectionVector" + // Re-orient all arrows + Base::Vector3f normal = pcConstraint->NormalDirection.getValue(); + Base::Vector3f forceDirection = pcConstraint->DirectionVector.getValue(); + if (forceDirection.Length() < Precision::Confusion()) + forceDirection = normal; + + SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + const std::vector& points = pcConstraint->Points.getValues(); + + /* + SoMultipleCopy* cp = static_cast(pShapeSep->getChild(0)); + cp->matrix.setNum(points.size()); + */ + int idx = 0; + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + if (forceDirection.GetAngle(normal) < M_PI_2) + base = base + dir * ARROWLENGTH; + /* + SbMatrix m; + m.setTransform(base, rot, SbVec3f(1,1,1)); + cp->matrix.set1Value(idx, m);*/ + + SoSeparator* sep = static_cast(pShapeSep->getChild(idx)); + updatePlacement(sep, 0, base, rot); + updateArrow(sep, 2, ARROWLENGTH, ARROWHEADRADIUS); + idx++; + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h new file mode 100644 index 000000000..ba6027fc6 --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintForce.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H + +#include + +#include "ViewProviderFemConstraint.h" +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; +class SoLightModel; +class SoCoordinate3; +class SoIndexedLineSet; +class SoIndexedFaceSet; +class SoEventCallback; +class SoMarkerSet; + +namespace Gui { +class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } +} + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintForce : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintForce); + +public: + /// Constructor + ViewProviderFemConstraintForce(); + virtual ~ViewProviderFemConstraintForce(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +private: + /// Direction of the force + Base::Vector3f forceDirection; + +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp new file mode 100644 index 000000000..16ff06f50 --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * 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 +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintGear.h" +#include +#include "TaskFemConstraintGear.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintGear, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintGear::ViewProviderFemConstraintGear() +{ + sPixmap = "view-femconstraintgear"; +} + +ViewProviderFemConstraintGear::~ViewProviderFemConstraintGear() +{ +} + +bool ViewProviderFemConstraintGear::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintGear *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // Allow stacking of dialogs, for ShaftWizard application + // Note: If other features start to allow stacking, we need to check for oldDlg != NULL + oldDlg = dlg; + /* + 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().closeDialog(); + else + return false; + */ + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintGear(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintGear::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintGear* pcConstraint = static_cast(this->getObject()); + if (this->getObject() != NULL) + Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + else + Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName()); + + if (strcmp(prop->getName(),"BasePoint") == 0) { + if (pcConstraint->Height.getValue() > Precision::Confusion()) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + // This should always point outside of the cylinder + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + Base::Vector3f axis = pcConstraint->Axis.getValue(); + float radius = pcConstraint->Radius.getValue(); + float dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(axis.x, axis.y, axis.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + createPlacement(pShapeSep, b, rot); + pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); + createPlacement(pShapeSep, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0))); + pShapeSep->addChild(createArrow(dia/2, dia/8)); + } + } else if (strcmp(prop->getName(),"Diameter") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + Base::Vector3f axis = pcConstraint->Axis.getValue(); + //float radius = pcConstraint->Radius.getValue(); + float dia = pcConstraint->Diameter.getValue(); + float radius = pcConstraint->Radius.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(axis.x, axis.y, axis.z); + SbRotation rot(SbVec3f(0,1,0), dir); + + updatePlacement(pShapeSep, 0, b, rot); + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); + updatePlacement(pShapeSep, 3, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0))); + sep = static_cast(pShapeSep->getChild(5)); + updateArrow(sep, 0, dia/2, dia/8); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h new file mode 100644 index 000000000..55f08a1ad --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintGear.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTGear_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTGear_H + +#include + +#include "ViewProviderFemConstraint.h" +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; +class SoLightModel; +class SoCoordinate3; +class SoIndexedLineSet; +class SoIndexedFaceSet; +class SoEventCallback; +class SoMarkerSet; + +namespace Gui { +class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } +} + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintGear : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintGear); + +public: + /// Constructor + ViewProviderFemConstraintGear(); + virtual ~ViewProviderFemConstraintGear(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTGear_H diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp new file mode 100644 index 000000000..abdd3ec3e --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.cpp @@ -0,0 +1,166 @@ +/*************************************************************************** + * 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 +# include +# include +# include +#endif + +#include "ViewProviderFemConstraintPulley.h" +#include +#include "TaskFemConstraintPulley.h" +#include "Gui/Control.h" + +#include + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPulley, FemGui::ViewProviderFemConstraint) + + +ViewProviderFemConstraintPulley::ViewProviderFemConstraintPulley() +{ + sPixmap = "view-femconstraintpulley"; +} + +ViewProviderFemConstraintPulley::~ViewProviderFemConstraintPulley() +{ +} + +bool ViewProviderFemConstraintPulley::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default ) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintPulley *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + // Allow stacking of dialogs, for ShaftWizard application + // Note: If other features start to allow stacking, we need to check for oldDlg != NULL + oldDlg = dlg; + /* + 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().closeDialog(); + else + return false; + */ + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintPulley(this)); + + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +void ViewProviderFemConstraintPulley::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintPulley* pcConstraint = static_cast(this->getObject()); + if (this->getObject() != NULL) + Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName()); + else + Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName()); + + if (strcmp(prop->getName(),"BasePoint") == 0) { + if (pcConstraint->Height.getValue() > Precision::Confusion()) { + // Remove and recreate the symbol + pShapeSep->removeAllChildren(); + + // This should always point outside of the cylinder + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + Base::Vector3f axis = pcConstraint->Axis.getValue(); + float radius = pcConstraint->Radius.getValue(); + float dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + float angle = pcConstraint->Angle.getValue(); + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(axis.x, axis.y, axis.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + createPlacement(pShapeSep, b, rot); // child 0 and 1 + pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); // child 2 + SoSeparator* sep = new SoSeparator(); + createPlacement(sep, SbVec3f(dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(sin(angle),0,cos(angle)))); + sep->addChild(createArrow(dia/2, dia/8)); + pShapeSep->addChild(sep); // child 3 + sep = new SoSeparator(); + createPlacement(sep, SbVec3f(-dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(angle),0,cos(angle)))); + sep->addChild(createArrow(dia/2, dia/8)); + pShapeSep->addChild(sep); // child 4 + } + } else if (strcmp(prop->getName(),"Angle") == 0) { + if (pShapeSep->getNumChildren() > 0) { + // Change the symbol + Base::Vector3f base = pcConstraint->BasePoint.getValue(); + Base::Vector3f axis = pcConstraint->Axis.getValue(); + float radius = pcConstraint->Radius.getValue(); + float dia = pcConstraint->Diameter.getValue(); + if (dia < 2 * radius) + dia = 2 * radius; + float angle = pcConstraint->Angle.getValue(); + + SbVec3f b(base.x, base.y, base.z); + SbVec3f dir(axis.x, axis.y, axis.z); + SbRotation rot(SbVec3f(0,-1,0), dir); + + updatePlacement(pShapeSep, 0, b, rot); + const SoSeparator* sep = static_cast(pShapeSep->getChild(2)); + updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2); + sep = static_cast(pShapeSep->getChild(3)); + updatePlacement(sep, 0, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,sin(angle)))); + const SoSeparator* subsep = static_cast(sep->getChild(2)); + updateArrow(subsep, 0, dia/2, dia/8); + sep = static_cast(pShapeSep->getChild(4)); + updatePlacement(sep, 0, SbVec3f(0,0,-dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,-sin(angle)))); + subsep = static_cast(sep->getChild(2)); + updateArrow(subsep, 0, dia/2, dia/8); + } + } + + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h new file mode 100644 index 000000000..50d14d650 --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintPulley.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 * + * * + ***************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H + +#include + +#include "ViewProviderFemConstraint.h" +#include + +class SoFontStyle; +class SoText2; +class SoBaseColor; +class SoTranslation; +class SbRotation; +class SoMaterial; +class SoLightModel; +class SoCoordinate3; +class SoIndexedLineSet; +class SoIndexedFaceSet; +class SoEventCallback; +class SoMarkerSet; + +namespace Gui { +class View3DInventorViewer; + namespace TaskView { + class TaskDialog; + } +} + +namespace FemGui +{ + +class FemGuiExport ViewProviderFemConstraintPulley : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintPulley); + +public: + /// Constructor + ViewProviderFemConstraintPulley(); + virtual ~ViewProviderFemConstraintPulley(); + + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); + +}; + +} //namespace FemGui + + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp index c4d3a7367..763c20475 100755 --- a/src/Mod/Fem/Gui/Workbench.cpp +++ b/src/Mod/Fem/Gui/Workbench.cpp @@ -57,7 +57,11 @@ Gui::ToolBarItem* Workbench::setupToolBars() const fem->setCommand("FEM"); *fem << "Fem_CreateFromShape" << "Fem_CreateNodesSet" - << "Fem_Constraint"; + << "Fem_ConstraintFixed" + << "Fem_ConstraintForce" + << "Fem_ConstraintBearing" + << "Fem_ConstraintGear" + << "Fem_ConstraintPulley"; return root; } @@ -70,7 +74,11 @@ Gui::MenuItem* Workbench::setupMenuBar() const fem->setCommand("&FEM"); *fem << "Fem_CreateFromShape" << "Fem_CreateNodesSet" - << "Fem_Constraint"; + << "Fem_ConstraintFixed" + << "Fem_ConstraintForce" + << "Fem_ConstraintBearing" + << "Fem_ConstraintGear" + << "Fem_ConstraintPulley"; return root; } diff --git a/src/Mod/PartDesign/WizardShaft/InitGui.py b/src/Mod/PartDesign/WizardShaft/InitGui.py deleted file mode 100644 index 73e570ce2..000000000 --- a/src/Mod/PartDesign/WizardShaft/InitGui.py +++ /dev/null @@ -1,76 +0,0 @@ -# PartDesign gui init module -# (c) 2003 Juergen Riegel -# -# Gathering all the information to start FreeCAD -# This is the second one of three init scripts, the third one -# runs when the gui is up - -#*************************************************************************** -#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 * -#* * -#* This file is part of the FreeCAD CAx development system. * -#* * -#* This program is free software; you can redistribute it and/or modify * -#* it under the terms of the GNU General Public License (GPL) * -#* as published by the Free Software Foundation; either version 2 of * -#* the License, or (at your option) any later version. * -#* for detail see the LICENCE text file. * -#* * -#* FreeCAD 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 FreeCAD; if not, write to the Free Software * -#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * -#* USA * -#* * -#* Juergen Riegel 2002 * -#***************************************************************************/ - -class PartDesignWorkbench ( Workbench ): - "PartDesign workbench object" - from WizardShaft import WizardShaft - Icon = """ - /* XPM */ - static char * partdesign_xpm[] = { - "16 16 9 1", - " c None", - ". c #040006", - "+ c #070F38", - "@ c #002196", - "# c #0030F3", - "$ c #5A4D20", - "% c #858EB2", - "& c #DEB715", - "* c #BFB99D", - " & ........ ", - "&&&$..@@@@@@+...", - "&&&&$@#####@..@.", - "&&&&&$......@#@.", - "&&&&&&@@@+.###@.", - "$&&&&&&@#@.###@.", - ".$&&&&&%#@.###@.", - ".@*&&&*%#@.###@.", - ".@#*&**%#@.###@.", - ".@#@%%%.@@.###@.", - ".@@@@@@@#@.###@.", - ".@#######@.###@.", - ".@#######@.##+. ", - ".+@@@####@.@.. ", - " ......+++.. ", - " ... "}; - """ - MenuText = "Part Design" - ToolTip = "Part Design workbench" - - def Initialize(self): - # load the module - import PartDesignGui - import PartDesign - def GetClassName(self): - return "PartDesignGui::Workbench" - -Gui.addWorkbench(PartDesignWorkbench()) -