Intgrate Jans FEM PullRequest

This commit is contained in:
jriegel
2013-03-22 12:49:05 +01:00
58 changed files with 10175 additions and 316 deletions

View File

@@ -41,6 +41,11 @@
#include "FemSetNodesObject.h"
#include "HypothesisPy.h"
#include "FemConstraintBearing.h"
#include "FemConstraintFixed.h"
#include "FemConstraintForce.h"
#include "FemConstraintGear.h"
#include "FemConstraintPulley.h"
extern struct PyMethodDef Fem_methods[];
@@ -115,6 +120,12 @@ void AppFemExport initFem()
Fem::FemSetGeometryObject ::init();
Fem::FemSetNodesObject ::init();
Fem::Constraint ::init();
Fem::ConstraintBearing ::init();
Fem::ConstraintFixed ::init();
Fem::ConstraintForce ::init();
Fem::ConstraintGear ::init();
Fem::ConstraintPulley ::init();
}
} // extern "C"

View File

@@ -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)
@@ -64,6 +64,18 @@ SET(Fem_SRCS
FemMesh.h
FemMeshProperty.cpp
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}
)

View File

@@ -0,0 +1,329 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <TopoDS.hxx>
# include <BRepGProp_Face.hxx>
# include <gp_Vec.hxx>
# include <gp_Pnt.hxx>
# include <gp_Pln.hxx>
# include <gp_Cylinder.hxx>
# include <gp_Ax3.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <GCPnts_AbscissaPoint.hxx>
# include <Adaptor3d_IsoCurve.hxx>
# include <Adaptor3d_HSurface.hxx>
# include <BRepAdaptor_HSurface.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
# include <TopoDS_Vertex.hxx>
# include <BRepClass_FaceClassifier.hxx>
# include <BRep_Tool.hxx>
# include <BRepGProp_Face.hxx>
# include <ShapeAnalysis.hxx>
# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <GeomAPI_IntCS.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Line.hxx>
# include <Precision.hxx>
#endif
#include "FemConstraint.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace Fem;
PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject);
Constraint::Constraint()
{
ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied");
ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3f(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid");
}
Constraint::~Constraint()
{
}
App::DocumentObjectExecReturn *Constraint::execute(void)
{
References.touch();
return StdReturn;
}
void Constraint::onChanged(const App::Property* prop)
{
//Base::Console().Error("Constraint::onChanged() %s\n", prop->getName());
if (prop == &References) {
// If References are changed, recalculate the normal direction. If no useful reference is found,
// use z axis or previous value. If several faces are selected, only the first one is used
std::vector<App::DocumentObject*> Objects = References.getValues();
std::vector<std::string> 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<Part::Feature*>(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...
App::DocumentObject::onChanged(prop);
return;
}
}
}
}
App::DocumentObject::onChanged(prop);
}
void Constraint::onDocumentRestored()
{
// This seems to be the only way to make the ViewProvider display the constraint
References.touch();
App::DocumentObject::onDocumentRestored();
}
const bool Constraint::getPoints(std::vector<Base::Vector3f> &points, std::vector<Base::Vector3f> &normals) const
{
std::vector<App::DocumentObject*> Objects = References.getValues();
std::vector<std::string> 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<Part::Feature*>(obj);
const Part::TopoShape& toposhape = feat->Shape.getShape();
if (toposhape.isNull())
return false;
sh = toposhape.getSubShape(SubElements[i].c_str());
if (sh.ShapeType() == TopAbs_VERTEX) {
const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
gp_Pnt p = BRep_Tool::Pnt(vertex);
points.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()));
}
}
}
}
}
return true;
}
const bool Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const
{
std::vector<App::DocumentObject*> Objects = References.getValues();
std::vector<std::string> SubElements = References.getSubValues();
if (Objects.empty())
return false;
App::DocumentObject* obj = Objects[0];
Part::Feature* feat = static_cast<Part::Feature*>(obj);
Part::TopoShape toposhape = feat->Shape.getShape();
if (toposhape.isNull())
return false;
TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str());
TopoDS_Face face = TopoDS::Face(sh);
BRepAdaptor_Surface surface(face);
gp_Cylinder cyl = surface.Cylinder();
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
height = start.Distance(end);
radius = cyl.Radius();
gp_Pnt b = cyl.Location();
base = Base::Vector3f(b.X(), b.Y(), b.Z());
gp_Dir dir = cyl.Axis().Direction();
axis = Base::Vector3f(dir.X(), dir.Y(), dir.Z());
return true;
}
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::vector<std::string> names = location.getSubValues();
if (names.size() == 0)
return Base::Vector3f(0,0,0);
std::string subName = names.front();
Part::Feature* featLoc = static_cast<Part::Feature*>(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());
}
const Base::Vector3f Constraint::getDirection(const App::PropertyLinkSub &direction)
{
App::DocumentObject* obj = direction.getValue();
std::vector<std::string> names = direction.getSubValues();
if (names.size() == 0)
return Base::Vector3f(0,0,0);
std::string subName = names.front();
Part::Feature* feat = static_cast<Part::Feature*>(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 Base::Vector3f(0,0,0); // "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 Base::Vector3f(0,0,0); // "Direction must be a planar face or linear edge"
}
}
Base::Vector3f the_direction(dir.X(), dir.Y(), dir.Z());
the_direction.Normalize();
return the_direction;
}

View File

@@ -0,0 +1,73 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINT_H
#define FEM_CONSTRAINT_H
#include <Base/Vector3D.h>
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
namespace Fem
{
class AppFemExport Constraint : public App::DocumentObject
{
PROPERTY_HEADER(Fem::Constraint);
public:
/// Constructor
Constraint(void);
virtual ~Constraint();
App::PropertyLinkSubList References;
// Read-only (calculated values). These trigger changes in the ViewProvider
App::PropertyVector NormalDirection;
/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);
/// returns the type name of the ViewProvider
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraint";
}
protected:
virtual void onChanged(const App::Property* prop);
virtual void onDocumentRestored();
protected:
/// Calculate the points where symbols should be drawn
const bool getPoints(std::vector<Base::Vector3f>& points, std::vector<Base::Vector3f>& normals) const;
const bool 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);
const Base::Vector3f getDirection(const App::PropertyLinkSub &direction);
};
} //namespace Fem
#endif // FEM_CONSTRAINT_H

View File

@@ -0,0 +1,117 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <TopoDS.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Precision.hxx>
#endif
#include "FemConstraintBearing.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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)
{
//Base::Console().Error("ConstraintBearing: onChanged %s\n", prop->getName());
// 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;
if (!getCylinder(radius, height, base, axis))
return;
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());
}
BasePoint.setValue(base);
BasePoint.touch(); // This triggers ViewProvider::updateData()
} else if ((prop == &Location) || (prop == &Dist)) {
App::DocumentObject* obj = Location.getValue();
std::vector<std::string> names = Location.getSubValues();
if (names.size() == 0) {
return;
}
std::string subName = names.front();
Part::Feature* feat = static_cast<Part::Feature*>(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;
if (!getCylinder(radius, height, base, axis))
return;
base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue());
BasePoint.setValue(base);
BasePoint.touch();
}
}

View File

@@ -0,0 +1,71 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINTBEARING_H
#define FEM_CONSTRAINTBEARING_H
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
#include "FemConstraint.h"
namespace Fem
{
class AppFemExport ConstraintBearing : public Fem::Constraint
{
PROPERTY_HEADER(Fem::ConstraintBearing);
public:
/// Constructor
ConstraintBearing(void);
/// Location reference
App::PropertyLinkSub Location;
/// Distance from location reference
App::PropertyFloat Dist;
/// Is the bearing free to move in axial direction?
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

View File

@@ -0,0 +1,84 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <Adaptor3d_IsoCurve.hxx>
#include <Adaptor3d_HSurface.hxx>
#include <BRepAdaptor_HSurface.hxx>
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopoDS.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRep_Tool.hxx>
#include <Precision.hxx>
#endif
#include "FemConstraintFixed.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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<Base::Vector3f>());
Normals.setValues(std::vector<Base::Vector3f>());
}
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<Base::Vector3f> points;
std::vector<Base::Vector3f> normals;
if (getPoints(points, normals)) {
Points.setValues(points);
Normals.setValues(normals);
Points.touch(); // This triggers ViewProvider::updateData()
}
}
}

View File

@@ -0,0 +1,63 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINTFIXED_H
#define FEM_CONSTRAINTFIXED_H
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
#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

View File

@@ -0,0 +1,101 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <TopoDS.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Precision.hxx>
#endif
#include "FemConstraintForce.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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<Base::Vector3f>());
}
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<Base::Vector3f> points;
std::vector<Base::Vector3f> normals;
if (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) {
Base::Vector3f direction = getDirection(Direction);
if (direction.Length() < Precision::Confusion())
return;
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();
}
}
}

View File

@@ -0,0 +1,69 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINTFORCE_H
#define FEM_CONSTRAINTFORCE_H
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
#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

View File

@@ -0,0 +1,86 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <TopoDS.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Precision.hxx>
#endif
#include "FemConstraintGear.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace Fem;
PROPERTY_SOURCE(Fem::ConstraintGear, Fem::ConstraintBearing);
ConstraintGear::ConstraintGear()
{
ADD_PROPERTY(Diameter,(100.0));
ADD_PROPERTY(Force,(1000.0));
ADD_PROPERTY(ForceAngle,(0.0));
ADD_PROPERTY_TYPE(Direction,(0),"ConstraintGear",(App::PropertyType)(App::Prop_None),
"Element giving direction of gear force");
ADD_PROPERTY(Reversed,(0));
ADD_PROPERTY_TYPE(DirectionVector,(Base::Vector3f(1,1,1).Normalize()),"ConstraintGear",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Direction of gear force");
naturalDirectionVector = Base::Vector3f(1,1,1).Normalize();
}
App::DocumentObjectExecReturn *ConstraintGear::execute(void)
{
return ConstraintBearing::execute();
}
void ConstraintGear::onChanged(const App::Property* prop)
{
ConstraintBearing::onChanged(prop);
if (prop == &Direction) {
Base::Vector3f direction = getDirection(Direction);
if (direction.Length() < Precision::Confusion())
return;
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();
}
}
// The computation for the force angle is simpler in the ViewProvider directly
}

View File

@@ -0,0 +1,70 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINTGear_H
#define FEM_CONSTRAINTGear_H
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
#include "FemConstraintBearing.h"
namespace Fem
{
class AppFemExport ConstraintGear : public Fem::ConstraintBearing
{
PROPERTY_HEADER(Fem::ConstraintGear);
public:
/// Constructor
ConstraintGear(void);
App::PropertyFloat Diameter;
App::PropertyFloat Force;
App::PropertyFloat ForceAngle;
App::PropertyLinkSub Direction;
App::PropertyBool Reversed;
// Read-only (calculated values). These trigger changes in the ViewProvider
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::ViewProviderFemConstraintGear";
}
protected:
virtual void onChanged(const App::Property* prop);
private:
Base::Vector3f naturalDirectionVector;
};
} //namespace Fem
#endif // FEM_CONSTRAINTGear_H

View File

@@ -0,0 +1,98 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Lin.hxx>
#include <TopoDS.hxx>
#include <BRepAdaptor_Surface.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <Precision.hxx>
#endif
#include "FemConstraintPulley.h"
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace Fem;
PROPERTY_SOURCE(Fem::ConstraintPulley, Fem::ConstraintGear);
ConstraintPulley::ConstraintPulley()
{
ADD_PROPERTY(OtherDiameter,(100.0));
ADD_PROPERTY(CenterDistance,(500.0));
ADD_PROPERTY(IsDriven,(0));
ADD_PROPERTY(TensionForce,(0.0));
ADD_PROPERTY_TYPE(BeltAngle,(0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Angle of belt forces");
ADD_PROPERTY_TYPE(BeltForce1,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"First belt force");
ADD_PROPERTY_TYPE(BeltForce2,(0.0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Second belt force");
ForceAngle.setValue(00.0);
Diameter.setValue(300.0);
// calculate initial values of read-only properties
onChanged(&Force);
}
App::DocumentObjectExecReturn *ConstraintPulley::execute(void)
{
return ConstraintBearing::execute();
}
void ConstraintPulley::onChanged(const App::Property* prop)
{
ConstraintGear::onChanged(prop);
if ((prop == &Diameter) || (prop == &OtherDiameter) || (prop == &CenterDistance)) {
if (CenterDistance.getValue() > Precision::Confusion()) {
BeltAngle.setValue(asin((Diameter.getValue() - OtherDiameter.getValue())/2/CenterDistance.getValue()));
BeltAngle.touch();
}
} else if ((prop == &Force) || (prop == &TensionForce) || (prop == &IsDriven)) {
double radius = Diameter.getValue() / 2.0;
if (radius < Precision::Confusion())
return;
double force = Force.getValue() / (radius/1000);
if (fabs(force) < Precision::Confusion())
return;
bool neg = (force < 0.0);
if (neg)
force *= -1.0;
if ((IsDriven.getValue() && neg) || (!IsDriven.getValue() && !neg)) {
BeltForce1.setValue(force + TensionForce.getValue());
BeltForce2.setValue(TensionForce.getValue());
} else {
BeltForce2.setValue(force + TensionForce.getValue());
BeltForce1.setValue(TensionForce.getValue());
}
BeltForce1.touch();
}
}

View File

@@ -0,0 +1,73 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef FEM_CONSTRAINTPulley_H
#define FEM_CONSTRAINTPulley_H
#include <App/DocumentObject.h>
#include <App/PropertyLinks.h>
#include <App/PropertyGeo.h>
#include "FemConstraintGear.h"
namespace Fem
{
class AppFemExport ConstraintPulley : public Fem::ConstraintGear
{
PROPERTY_HEADER(Fem::ConstraintPulley);
public:
/// Constructor
ConstraintPulley(void);
/// Other pulley diameter
App::PropertyFloat OtherDiameter;
/// Center distance between the pulleys
App::PropertyFloat CenterDistance;
/// Driven pulley or driving pulley?
App::PropertyBool IsDriven;
/// Belt tension force
App::PropertyFloat TensionForce;
// Read-only (calculated values). These trigger changes in the ViewProvider
App::PropertyFloat BeltAngle;
App::PropertyFloat BeltForce1;
App::PropertyFloat BeltForce2;
/// 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

View File

@@ -34,6 +34,12 @@
#include "ViewProviderSetElements.h"
#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"
@@ -63,16 +69,22 @@ void FemGuiExport initFemGui()
(void) Py_InitModule("FemGui", FemGui_Import_methods); /* mod name, table ptr */
Base::Console().Log("Loading GUI of Fem module... done\n");
// instanciating the commands
// instantiating the commands
CreateFemCommands();
// addition objects
FemGui::Workbench ::init();
FemGui::ViewProviderFemMesh ::init();
FemGui::ViewProviderSetNodes ::init();
FemGui::ViewProviderSetElements ::init();
FemGui::ViewProviderSetFaces ::init();
FemGui::ViewProviderSetGeometry ::init();
FemGui::ViewProviderFemMesh ::init();
FemGui::ViewProviderSetNodes ::init();
FemGui::ViewProviderSetElements ::init();
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();

View File

@@ -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
@@ -34,6 +34,12 @@ set(FemGui_MOC_HDRS
TaskObjectName.h
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})
@@ -42,9 +48,37 @@ set(FemGui_UIC_SRCS
Hypothesis.ui
TaskCreateNodeSet.ui
TaskObjectName.ui
TaskFemConstraint.ui
TaskFemConstraintBearing.ui
TaskFemConstraintFixed.ui
TaskFemConstraintForce.ui
)
qt4_wrap_ui(FemGui_UIC_HDRS ${FemGui_UIC_SRCS})
SET(FemGui_DLG_SRCS
${FemGui_UIC_HDRS}
Hypothesis.ui
Hypothesis.cpp
Hypothesis.h
TaskFemConstraint.ui
TaskFemConstraint.cpp
TaskFemConstraint.h
TaskFemConstraintBearing.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)
SOURCE_GROUP("Resources" FILES ${FemResource_SRCS})
@@ -62,14 +96,26 @@ SET(FemGui_SRCS_ViewProvider
ViewProviderSetGeometry.h
FemSelectionGate.cpp
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})
SET(FemGui_SRCS_TaskBoxes
TaskObjectName.ui
TaskObjectName.ui
TaskObjectName.cpp
TaskObjectName.h
TaskCreateNodeSet.ui
TaskCreateNodeSet.ui
TaskCreateNodeSet.cpp
TaskCreateNodeSet.h
)
@@ -81,6 +127,9 @@ SET(FemGui_SRCS_TaskDlg
Hypothesis.ui
Hypothesis.cpp
Hypothesis.h
TaskFemConstraint.ui
TaskFemConstraint.cpp
TaskFemConstraint.h
)
SOURCE_GROUP("Task_Dialogs" FILES ${FemGui_SRCS_TaskDlg})
@@ -104,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
)
@@ -111,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")

View File

@@ -52,6 +52,7 @@
#include <Mod/Fem/App/FemMeshObject.h>
#include <Mod/Fem/App/FemSetNodesObject.h>
#include <strstream>
#include <Mod/Fem/App/FemConstraint.h>
#include "Hypothesis.h"
@@ -85,6 +86,162 @@ bool CmdFemCreateFromShape::isActive(void)
return Gui::Selection().countObjectsOfType(type) > 0;
}
DEF_STD_CMD_A(CmdFemConstraintBearing);
CmdFemConstraintBearing::CmdFemConstraintBearing()
: Command("Fem_ConstraintBearing")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM bearing constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a bearing");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_ConstraintBearing";
}
void CmdFemConstraintBearing::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraintBearing");
openCommand("Make FEM constraint for bearing");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintBearing\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
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 = 300.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.OtherDiameter = 100.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.CenterDistance = 500.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Force = 100.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.TensionForce = 100.0",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraintPulley::isActive(void)
{
return hasActiveDocument();
}
// #####################################################################################################
@@ -281,4 +438,9 @@ void CreateFemCommands(void)
rcCmdMgr.addCommand(new CmdFemCreateFromShape());
rcCmdMgr.addCommand(new CmdFemCreateNodesSet());
rcCmdMgr.addCommand(new CmdFemDefineNodesSet());
rcCmdMgr.addCommand(new CmdFemConstraintBearing());
rcCmdMgr.addCommand(new CmdFemConstraintFixed());
rcCmdMgr.addCommand(new CmdFemConstraintForce());
rcCmdMgr.addCommand(new CmdFemConstraintGear());
rcCmdMgr.addCommand(new CmdFemConstraintPulley());
}

View File

@@ -2,6 +2,11 @@
<qresource>
<file>icons/Fem_FemMesh.svg</file>
<file>icons/Fem_FemMesh_createnodebypoly.svg</file>
<file>icons/Fem_ConstraintForce.svg</file>
<file>icons/Fem_ConstraintFixed.svg</file>
<file>icons/Fem_ConstraintBearing.svg</file>
<file>icons/Fem_ConstraintGear.svg</file>
<file>icons/Fem_ConstraintPulley.svg</file>
<file>translations/Fem_af.qm</file>
<file>translations/Fem_de.qm</file>
<file>translations/Fem_fi.qm</file>

View File

@@ -0,0 +1,435 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Fem_FemMesh_cylinder_bearing_constraint4.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2862">
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3705"
gradientUnits="userSpaceOnUse"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2868" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3705-4"
gradientUnits="userSpaceOnUse"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
<linearGradient
id="linearGradient3377-2">
<stop
id="stop3379-2"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381-3"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3703-3"
gradientUnits="userSpaceOnUse"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient
id="linearGradient3056">
<stop
id="stop3058"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3060"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
r="19.467436"
fy="97.369568"
fx="135.38333"
cy="97.369568"
cx="135.38333"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)"
gradientUnits="userSpaceOnUse"
id="radialGradient3074"
xlink:href="#linearGradient3377-2"
inkscape:collect="always" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3823"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3825"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3841"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-2"
id="radialGradient3843"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="12.375"
inkscape:cx="32"
inkscape:cy="32"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="964"
inkscape:window-x="-2"
inkscape:window-y="-3"
inkscape:window-maximized="1" />
<metadata
id="metadata2865">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3618"
transform="matrix(0.50599351,0,0,0.48648068,-35.672941,-25.74129)">
<path
style="fill:url(#radialGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.80832386;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 171.2941,68.210998 -21.70809,11.437026 12.47229,11.324747 5.1557,31.240899 20.33537,-16.92901 c 9.37869,-11.559736 8.48852,-22.165838 -1.72338,-32.960883 -6.6217,-4.568224 -7.83572,-4.118974 -14.53189,-4.112779 z"
id="rect3522"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 56.954382,8.9166822 C 53.935653,10.441822 49.573711,13.274107 45.130787,15.536369"
id="path2412"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 62.052587,14.762138 c -0.127218,0.135606 -10.177263,6.053378 -11.376976,6.603078"
id="path2414"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 61.489636,21.35739 c -1.899655,1.361624 -5.333235,3.65227 -7.277147,5.10191"
id="path2418"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 45.378285,10.474883 c 5.636128,0.561281 7.279784,1.491002 9.58545,4.465874 2.870922,3.797818 3.526904,5.848823 1.830644,12.314901"
id="path2424-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
sodipodi:type="arc"
style="fill:none;stroke:none"
id="path3036"
sodipodi:cx="16.722221"
sodipodi:cy="36.055557"
sodipodi:rx="8.0555553"
sodipodi:ry="10.055555"
d="m 24.777777,36.055557 a 8.0555553,10.055555 0 0 1 -1.128969,5.133794"
sodipodi:start="0"
sodipodi:end="0.53581627"
sodipodi:open="true"
transform="matrix(1.0128486,0.03420996,0,1.1009373,5.8744265,-9.7732447)" />
<path
sodipodi:type="arc"
style="fill:#b4b4b4;fill-opacity:1;stroke:#000000;stroke-width:1.28042458999999997;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
id="path3808"
sodipodi:cx="19.388889"
sodipodi:cy="40.555557"
sodipodi:rx="18.30003"
sodipodi:ry="13.222222"
d="m 37.688919,40.555557 a 18.30003,13.222222 0 1 1 -36.6000594,0 18.30003,13.222222 0 1 1 36.6000594,0 z"
transform="matrix(1.3441572,0.50475062,-0.12164844,1.7237278,5.1182762,-42.632996)" />
<path
sodipodi:type="arc"
style="fill:none;stroke:#000000;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3810"
sodipodi:cx="20.944445"
sodipodi:cy="41.611111"
sodipodi:rx="8.0555553"
sodipodi:ry="12.012263"
d="m 29,41.611111 a 8.0555553,12.012263 0 1 1 -16.111111,0 8.0555553,12.012263 0 1 1 16.111111,0 z"
transform="matrix(0.81018431,-0.63333461,0.60783522,0.90117726,-16.974202,12.338046)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,33.992641,21.934694)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-45"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,23.834069,27.254225)" />
<path
style="fill:#f40000;fill-opacity:1;stroke:#000000;stroke-width:1.05597484px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 21.153168,25.667519 C 21.025177,35.351544 25.561842,43.796806 33.286287,44.882935 26.131543,56.77873 6.263446,28.436375 21.153168,25.667519 z"
id="path3908"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:#f40000;fill-opacity:1;stroke:#000000;stroke-width:1.97466362;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 42.886744,59.384848 C 47.339312,56.803801 52.258805,53.102661 55.390107,50.35423 64.813086,34.837583 47.125365,7.7819532 25.168467,9.7931457 21.9589,10.700376 18.728875,11.583255 15.129401,12.569413 40.005982,9.4493588 64.467265,45.676332 42.886744,59.384848 z"
id="path3910"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-8"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,11.380788,22.293009)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-1"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,3.7905184,12.628982)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-2"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,1.5823369,-0.78273632)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-7"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,35.597133,9.8923117)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-9"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,28.78286,-2.1148497)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-14"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,18.240429,-9.1134328)" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:1.86111116;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-3"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(0.80789104,0.02728731,0,0.90607726,7.3572329,-9.1684755)" />
<g
id="g3618-4"
transform="matrix(0.50599351,0,0,0.48648068,-61.885654,-8.2655652)" />
<g
id="g3845">
<g
transform="translate(0.55555533,-0.22222218)"
id="g3811">
<path
transform="matrix(0.50599351,0,0,0.48648068,-61.885654,-8.2655652)"
style="fill:url(#radialGradient3841);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.80832386;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 162.52779,70.383423 -23.04725,9.71624 23.00405,9.747146 1.50426,35.076691 19.18669,-13.36515 c 6.73538,-10.17164 5.85327,-21.697968 -3.8551,-32.757432 -5.1144,-4.565872 -7.14987,-7.157434 -16.79265,-8.417495 z"
id="rect3522-3"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
transform="matrix(0.50599351,0,0,0.48648068,-61.885654,-8.2655652)"
style="fill:url(#radialGradient3843);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.80832386;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 132.82272,84.89331 c 10.75418,-10.005637 21.38515,-6.127815 31.80315,7.238395 8.01925,12.601635 7.23189,20.981435 -0.57918,32.709415 -9.97656,5.54633 -24.96587,2.99222 -33.00616,-9.97927 -5.69827,-10.29304 -6.15159,-21.332455 1.78219,-29.96854 z"
id="rect3520-5"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 16.20194,31.59182 0.05375,21.928308"
id="path2400-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 25.920467,27.206825 c -3.018729,1.525139 -5.388102,2.224723 -9.831027,4.486985"
id="path2412-6"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 32.955269,35.052415 c -0.127219,0.135606 -7.836626,4.886678 -9.036339,5.436379"
id="path2414-8"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 33.1042,41.289049 C 31.204544,42.650673 26.027118,46.11066 24.083206,47.5603"
id="path2418-3"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 3.0537409,37.805779 23.887483,40.53112"
id="path2424-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 23.908616,47.44324 3.310322,44.454882"
id="path2432-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 25.728346,32.193375 c 1.759441,2.263214 7.149518,8.424344 0.775134,16.648131"
id="path2400-7-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 15.571605,28.389271 c 6.072813,-0.100149 7.716092,1.272051 10.32724,3.920744"
id="path2424-3-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path2390-1"
d="m 9.0461086,30.888332 0.0051,20.906576"
style="fill:none;stroke:#000000;stroke-width:0.46444172;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Fem_fixed_geometry_constraint1.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2862">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3703"
gradientUnits="userSpaceOnUse"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3705"
gradientUnits="userSpaceOnUse"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2868" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="9.03125"
inkscape:cx="32"
inkscape:cy="32.055363"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1276"
inkscape:window-height="750"
inkscape:window-x="-13"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata2865">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3618"
transform="matrix(0.51498391,0,0,0.49033246,-43.844928,-28.337883)">
<path
style="fill:url(#radialGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.80832386;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 181.23365,60.447364 -41.75311,19.652299 22.79277,9.74401 1.71554,35.079827 34.90073,-21.47145 c 8.77297,-10.605473 11.81226,-24.974574 2.14058,-36.620683 -5.76166,-5.245683 -10.14552,-7.612661 -19.79651,-6.384003 z"
id="rect3522"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient3703);fill-opacity:1;fill-rule:evenodd;stroke:#ff2600;stroke-width:2.80792084999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 132.82272,84.89331 c 10.75418,-10.005637 21.38515,-6.127815 31.80315,7.238395 8.01928,12.601795 7.83274,24.767805 -0.57918,32.709415 -9.97656,5.54633 -24.96587,2.99222 -33.00616,-9.97927 -5.69827,-10.29304 -6.15159,-21.332455 1.78219,-29.96854 z"
id="rect3520"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
</g>
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 28.785325,11.12855 0.0052,21.515011"
id="path2390"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 36.737378,12.499439 36.570635,34.269187"
id="path2400"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 56.372527,2.2112135 C 53.300162,3.7484279 41.698378,10.10061 37.176513,12.380783"
id="path2412"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 61.760695,7.7936612 C 61.631216,7.9303412 44.151611,19.141175 42.930582,19.695228"
id="path2414"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 62.133726,14.965487 C 60.200318,16.337892 47.069308,24.807974 44.205044,26.601271"
id="path2418"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 22.13757,16.880244 20.65028,3.300552"
id="path2424"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 43.362992,26.815464 21.955804,23.581992"
id="path2432"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 36.981657,7.4999087 c 6.180714,-0.100942 7.85319,1.282121 10.423968,3.8930043 1.703939,2.222352 7.189786,8.432262 0.702143,16.721162"
id="path2424-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
sodipodi:type="arc"
style="fill:#fc0000;fill-opacity:1;stroke:#000000;stroke-width:0.35115141;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
id="path3812-6-9"
sodipodi:cx="8.333333"
sodipodi:cy="31"
sodipodi:rx="3.612802"
sodipodi:ry="3.569948"
d="m 11.946135,31 a 3.612802,3.569948 0 1 1 -7.225604,0 3.612802,3.569948 0 1 1 7.225604,0 z"
transform="matrix(2.3057079,0.01441438,1.3432008,0.88771711,-49.53095,16.068104)" />
<path
style="fill:#ff2600;fill-opacity:1;stroke:#000000;stroke-width:0.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 1.5501729,41.854671 1e-7,15.944636 c 4.0192826,4.935847 14.951421,5.673547 19.15571,3.98616 L 20.816609,45.730103 C 19.515769,47.578628 3.8647977,46.492346 1.5501729,41.854671 z"
id="path3800"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
style="fill:#ff2600;fill-opacity:1;stroke:#000000;stroke-width:0.50000000000000000;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 4.4290657,42.076124 0,-10.186851 c 1.2697887,-4.348714 4.2620171,-5.215101 7.5294113,-5.536332 4.248114,-0.09718 7.584697,4.89505 7.307959,9.522491 l -0.110727,8.747405 c -0.700644,0.514735 -3.488262,0.851874 -4.539792,-0.66436 l 0.221454,-9.079585 c -0.04849,-1.503613 -0.837387,-4.069575 -2.657441,-4.096885 -1.634568,-0.110783 -3.1977552,0.706119 -3.6539785,2.65744 l 0.1107267,9.633217 c -1.0949131,0.664208 -3.6999373,0.100965 -4.2076125,-0.99654 z"
id="path3802"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 43.384578,3.9792341 c 6.180714,-0.100942 7.410283,1.0606677 10.423967,3.893004 C 55.512484,10.09459 60.998331,16.3045 54.510688,24.5934"
id="path2424-3-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -0,0 +1,204 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64px"
height="64px"
id="svg2860"
sodipodi:version="0.32"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="Fem_force_on_geometry_constraint1.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
version="1.1">
<defs
id="defs2862">
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3703"
gradientUnits="userSpaceOnUse"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient
id="linearGradient3377">
<stop
id="stop3379"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377"
id="radialGradient3705"
gradientUnits="userSpaceOnUse"
cx="148.88333"
cy="81.869568"
fx="148.88333"
fy="81.869568"
r="19.467436"
gradientTransform="matrix(1.3852588,-0.05136783,0.03705629,0.9993132,-60.392403,7.7040438)" />
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 32 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="64 : 32 : 1"
inkscape:persp3d-origin="32 : 21.333333 : 1"
id="perspective2868" />
<radialGradient
inkscape:collect="always"
xlink:href="#linearGradient3377-4"
id="radialGradient3703-8"
gradientUnits="userSpaceOnUse"
cx="135.38333"
cy="97.369568"
fx="135.38333"
fy="97.369568"
r="19.467436"
gradientTransform="matrix(0.97435,0.2250379,-0.4623105,2.0016728,48.487554,-127.99883)" />
<linearGradient
id="linearGradient3377-4">
<stop
id="stop3379-3"
offset="0"
style="stop-color:#faff2b;stop-opacity:1;" />
<stop
id="stop3381-0"
offset="1"
style="stop-color:#ffaa00;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="9.03125"
inkscape:cx="32"
inkscape:cy="32"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:document-units="px"
inkscape:grid-bbox="true"
inkscape:window-width="1276"
inkscape:window-height="750"
inkscape:window-x="-13"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata2865">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer">
<g
id="g3618"
transform="matrix(0.51498391,0,0,0.49033246,-43.844928,-28.337883)">
<path
style="fill:url(#radialGradient3705);fill-opacity:1;fill-rule:evenodd;stroke:#7b5600;stroke-width:2.80832386;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 181.23365,60.447364 -42.39814,17.845743 23.4378,11.550566 3.43562,36.434747 33.18065,-22.82637 c 8.77297,-10.605473 11.81226,-24.974574 2.14058,-36.620683 -5.76166,-5.245683 -10.14552,-7.612661 -19.79651,-6.384003 z"
id="rect3522"
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0" />
<path
style="fill:url(#radialGradient3703);fill-opacity:1;fill-rule:evenodd;stroke:#ff2600;stroke-width:2.80792084999999991;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 132.82272,84.89331 c 10.75418,-10.005637 21.38515,-6.127815 31.80315,7.238395 8.01928,12.601795 7.83274,24.767805 -0.57918,32.709415 -9.97656,5.54633 -24.96587,2.99222 -33.00616,-9.97927 -5.69827,-10.29304 -6.15159,-21.332455 1.78219,-29.96854 z"
id="rect3520"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
</g>
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 28.785325,11.12855 0.0052,21.515011"
id="path2390"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 36.737378,12.499439 36.570635,34.269187"
id="path2400"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 56.372527,2.2112135 C 53.300162,3.7484279 42.030558,9.6577034 37.508693,11.937876"
id="path2412"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 61.760695,7.7936612 C 61.631216,7.9303412 44.705244,18.808995 43.484215,19.363048"
id="path2414"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 62.133726,14.965487 C 60.200318,16.337892 48.065848,24.254341 45.201584,26.047638"
id="path2418"
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 22.13757,16.880244 20.65028,3.300552"
id="path2424"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff2600;stroke-width:0.80000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 43.362992,26.815464 21.955804,23.581992"
id="path2432"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 36.760204,6.6140955 c 3.744727,-0.8760285 8.074643,2.1679342 10.645421,4.7788175 1.703939,2.222352 7.189786,9.318075 0.702143,17.606975"
id="path2424-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:#ff2600;fill-opacity:1;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="M 0.55363321,56.692041 11.737024,44.069203 c 1.269788,-1.580547 1.715304,-2.114755 2.989619,-3.653979 -2.284758,-1.979533 -3.598694,-2.523635 -6.2006916,-4.31834 7.0761596,-0.171163 8.8680506,0.05508 15.1695506,0.332181 l 5.314879,14.50519 c -2.927383,-2.167973 -3.827006,-2.630129 -6.6436,-4.318338 -1.557787,1.737623 -2.327923,2.683217 -3.764705,4.429066 L 8.1937713,63.335639 C 4.8843257,60.345868 3.4972946,59.339719 0.55363321,56.692041 z"
id="path3802"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.47040084;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
d="m 43.384578,3.9792341 c 6.180714,-0.100942 7.410283,1.0606677 10.423967,3.893004 C 55.512484,10.09459 60.998331,16.3045 54.510688,24.5934"
id="path2424-3-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;stroke:#7b5600;stroke-width:0.92551678;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 23.825095,12.352013 c 6.041975,-5.3755328 12.014726,-3.2921713 17.867828,3.888831 4.505436,6.77032 4.400633,13.306515 -0.3254,17.573147 -5.605087,2.979768 -14.026467,1.607572 -18.543708,-5.361367 -3.201435,-5.52994 -3.456121,-11.46087 1.00128,-16.100611 z"
id="rect3520-8"
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.6 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 46 KiB

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,212 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>
# include <TopoDS.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Geom_Plane.hxx>
# include <gp_Pln.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Line.hxx>
# include <gp_Lin.hxx>
#endif
#include "ui_TaskFemConstraint.h"
#include "TaskFemConstraint.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraint.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace FemGui;
using namespace Gui;
/* TRANSLATOR FemGui::TaskFemConstraint */
TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent,const char* pixmapname)
: TaskBox(Gui::BitmapFactory().pixmap(pixmapname),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView)
{
selectionMode = selref;
// Setup the dialog inside the Shaft Wizard dialog
if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL)) {
// Hide the shaft wizard table widget to make more space
ConstraintView->wizardSubLayout->itemAt(0)->widget()->hide();
QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild<QGridLayout*>();
for (int b = 0; b < buttons->count(); b++)
buttons->itemAt(b)->widget()->hide();
// Show this dialog for the FEM constraint
ConstraintView->wizardWidget->addWidget(this);
// Add buttons to finish editing the constraint without closing the shaft wizard dialog
okButton = new QPushButton(QObject::tr("Ok"));
cancelButton = new QPushButton(QObject::tr("Cancel"));
buttonBox = new QDialogButtonBox();
buttonBox->addButton(okButton, QDialogButtonBox::AcceptRole);
buttonBox->addButton(cancelButton, QDialogButtonBox::RejectRole);
QObject::connect(okButton, SIGNAL(clicked()), this, SLOT(onButtonWizOk()));
QObject::connect(cancelButton, SIGNAL(clicked()), this, SLOT(onButtonWizCancel()));
ConstraintView->wizardWidget->addWidget(buttonBox);
}
}
void TaskFemConstraint::keyPressEvent(QKeyEvent *ke)
{
if ((ConstraintView->wizardWidget != NULL) && (ConstraintView->wizardSubLayout != NULL))
// Prevent <Enter> from closing this dialog AND the shaft wizard dialog
// TODO: This should trigger an update in the shaft wizard but its difficult to access a python dialog from here...
if (ke->key() == Qt::Key_Return)
return;
TaskBox::keyPressEvent(ke);
}
const std::string TaskFemConstraint::getReferences(const std::vector<std::string>& items) const
{
std::string result;
for (std::vector<std::string>::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 + ")";
}
return result;
}
void TaskFemConstraint::onReferenceDeleted(const int row) {
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
Objects.erase(Objects.begin() + row);
SubElements.erase(SubElements.begin() + row);
pcConstraint->References.setValues(Objects, SubElements);
}
void TaskFemConstraint::onButtonReference(const bool pressed) {
if (pressed)
selectionMode = selref;
else
selectionMode = selnone;
Gui::Selection().clearSelection();
}
void TaskFemConstraint::onButtonWizOk()
{
// Remove dialog elements
buttonBox->removeButton(okButton);
delete okButton;
buttonBox->removeButton(cancelButton);
delete cancelButton;
ConstraintView->wizardWidget->removeWidget(buttonBox);
delete buttonBox;
ConstraintView->wizardWidget->removeWidget(this);
// Show the wizard shaft dialog again
ConstraintView->wizardSubLayout->itemAt(0)->widget()->show();
QGridLayout* buttons = ConstraintView->wizardSubLayout->findChild<QGridLayout*>();
for (int b = 0; b < buttons->count(); b++)
buttons->itemAt(b)->widget()->show();
Gui::Application::Instance->activeDocument()->resetEdit(); // Reaches ViewProviderFemConstraint::unsetEdit() eventually
}
void TaskFemConstraint::onButtonWizCancel()
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
if (pcConstraint != NULL)
pcConstraint->getDocument()->remObject(pcConstraint->getNameInDocument());
onButtonWizOk();
}
const QString TaskFemConstraint::makeRefText(const App::DocumentObject* obj, const std::string& subName) const
{
return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str());
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//==== calls from the TaskView ===============================================================
bool TaskDlgFemConstraint::accept()
{
std::string name = ConstraintView->getObject()->getNameInDocument();
try {
std::string refs = parameter->getReferences();
if (!refs.empty()) {
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.References = [%s]", name.c_str(), refs.c_str());
} else {
QMessageBox::warning(parameter, tr("Input error"), tr("You must specify at least one reference"));
return false;
}
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!ConstraintView->getObject()->isValid())
throw Base::Exception(ConstraintView->getObject()->getStatusString());
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
Gui::Command::commitCommand();
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return true;
}
bool TaskDlgFemConstraint::reject()
{
// roll back the changes
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
return true;
}
#include "moc_TaskFemConstraint.cpp"

View File

@@ -0,0 +1,107 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraint_H
#define GUI_TASKVIEW_TaskFemConstraint_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "ViewProviderFemConstraint.h"
namespace FemGui {
class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionObserver
{
Q_OBJECT
public:
TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,const char* pixmapname = "");
virtual ~TaskFemConstraint() {}
virtual const std::string getReferences(void) const {}
const std::string getReferences(const std::vector<std::string>& items) const;
protected Q_SLOTS:
void onReferenceDeleted(const int row);
void onButtonReference(const bool pressed = true);
// Shaft Wizard integration
void onButtonWizOk();
void onButtonWizCancel();
protected:
virtual void changeEvent(QEvent *e) { TaskBox::changeEvent(e); }
const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const;
virtual void keyPressEvent(QKeyEvent * ke);
private:
virtual void onSelectionChanged(const Gui::SelectionChanges&) {}
protected:
QWidget* proxy;
ViewProviderFemConstraint *ConstraintView;
enum {seldir, selref, selloc, selnone} selectionMode;
private:
// This seems to be the only way to access the widgets again in order to remove them from the dialog
QDialogButtonBox* buttonBox;
QPushButton* okButton;
QPushButton* cancelButton;
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
/*
/// is called the TaskView when the dialog is opened
virtual void open() {}
/// is called by the framework if an button is clicked which has no accept or reject role
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)
virtual bool reject();
/// is called by the framework if the user presses the help button
virtual bool isAllowedAlterDocument(void) const
{ return false; }
/// returns for Close and Help button
virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
ViewProviderFemConstraint* getConstraintView() const
{ return ConstraintView; }
protected:
ViewProviderFemConstraint *ConstraintView;
TaskFemConstraint *parameter;
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskFemConstraint_H

View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskFemConstraint</class>
<widget class="QWidget" name="TaskFemConstraint">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>461</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="comboType"/>
</item>
<item>
<widget class="QPushButton" name="buttonReference">
<property name="text">
<string>Add reference</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences"/>
</item>
<item>
<layout class="QHBoxLayout" name="layoutForce">
<item>
<widget class="QLabel" name="labelForce">
<property name="text">
<string>Load [N]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinForce">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>500.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDistance_2">
<item>
<widget class="QLabel" name="labelDiameter">
<property name="text">
<string>Diameter</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinDiameter">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDistance_3">
<item>
<widget class="QLabel" name="labelOtherDia">
<property name="text">
<string>Other diameter</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinOtherDia">
<property name="decimals">
<number>3</number>
</property>
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>200.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDistance_4">
<item>
<widget class="QLabel" name="labelCenterDistance">
<property name="text">
<string>Center distance</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinCenterDistance">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>500.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDirection">
<item>
<widget class="QPushButton" name="buttonDirection">
<property name="text">
<string>Direction</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDirection"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutLocation">
<item>
<widget class="QPushButton" name="buttonLocation">
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineLocation"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDistance">
<item>
<widget class="QLabel" name="labelDistance">
<property name="text">
<string>Distance</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinDistance">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>10.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,356 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>
# include <TopoDS.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Geom_Plane.hxx>
# include <gp_Pln.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Line.hxx>
# include <gp_Lin.hxx>
#endif
#include "ui_TaskFemConstraintBearing.h"
#include "TaskFemConstraintBearing.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraintBearing.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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_TaskFemConstraintBearing();
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<Fem::ConstraintBearing*>(ConstraintView->getObject());
double d = pcConstraint->Dist.getValue();
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
std::vector<std::string> 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(-FLOAT_MAX);
ui->spinDistance->setMaximum(FLOAT_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);
// Hide unwanted ui elements
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->checkIsDriven->setVisible(false);
ui->labelForce->setVisible(false);
ui->spinForce->setVisible(false);
ui->labelTensionForce->setVisible(false);
ui->spinTensionForce->setVisible(false);
ui->labelForceAngle->setVisible(false);
ui->spinForceAngle->setVisible(false);
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReversed->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;
Fem::ConstraintBearing* pcConstraint = static_cast<Fem::ConstraintBearing*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
if (selectionMode == selref) {
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> 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;
}
if (subName.substr(0,4) != "Face") {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked"));
return;
}
// Only cylindrical faces allowed
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;
}
std::vector<std::string> references(1,subName);
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<Fem::ConstraintBearing*>(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<Fem::ConstraintBearing*>(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<std::string> 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<const TaskFemConstraintBearing*>(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"

View File

@@ -0,0 +1,92 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraintBearing_H
#define GUI_TASKVIEW_TaskFemConstraintBearing_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskFemConstraint.h"
#include "ViewProviderFemConstraintBearing.h"
class Ui_TaskFemConstraintBearing;
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);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
protected:
Ui_TaskFemConstraintBearing* 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

View File

@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskFemConstraintBearing</class>
<widget class="QWidget" name="TaskFemConstraintBearing">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>534</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="buttonReference">
<property name="text">
<string>Add reference</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences"/>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_3">
<item>
<widget class="QLabel" name="labelDiameter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Gear diameter</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinDiameter">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_6">
<item>
<widget class="QLabel" name="labelOtherDiameter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Other pulley dia</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinOtherDiameter">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>100.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_7">
<item>
<widget class="QLabel" name="labelCenterDistance">
<property name="text">
<string>Center distance</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinCenterDistance">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_4">
<item>
<widget class="QLabel" name="labelForce">
<property name="text">
<string>Force</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinForce">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_8">
<item>
<widget class="QLabel" name="labelTensionForce">
<property name="text">
<string>Belt tension force</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinTensionForce">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>1000.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkIsDriven">
<property name="text">
<string>Driven pulley</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_5">
<item>
<widget class="QLabel" name="labelForceAngle">
<property name="text">
<string>Force location [deg]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinForceAngle">
<property name="decimals">
<number>1</number>
</property>
<property name="minimum">
<double>-360.000000000000000</double>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutLocation_2">
<item>
<widget class="QPushButton" name="buttonDirection">
<property name="text">
<string>Force Direction</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDirection"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReversed">
<property name="text">
<string>Reversed direction</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="checkAxial">
<property name="text">
<string>Axial free</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="layoutLocation">
<item>
<widget class="QPushButton" name="buttonLocation">
<property name="text">
<string>Location</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineLocation"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDistance">
<item>
<widget class="QLabel" name="labelDistance">
<property name="text">
<string>Distance</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinDistance">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>0.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,217 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>
# include <TopoDS.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Geom_Plane.hxx>
# include <gp_Pln.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Line.hxx>
# include <gp_Lin.hxx>
#endif
#include "ui_TaskFemConstraintFixed.h"
#include "TaskFemConstraintFixed.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraintFixed.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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<Fem::ConstraintFixed*>(ConstraintView->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> 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<std::string> references(1,subName);
Fem::ConstraintFixed* pcConstraint = static_cast<Fem::ConstraintFixed*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
if (selectionMode == selref) {
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> 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<std::string> 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"

View File

@@ -0,0 +1,84 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraintFixed_H
#define GUI_TASKVIEW_TaskFemConstraintFixed_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#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

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskFemConstraintFixed</class>
<widget class="QWidget" name="TaskFemConstraintFixed">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>233</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="buttonReference">
<property name="text">
<string>Add reference</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,363 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>
# include <TopoDS.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Geom_Plane.hxx>
# include <gp_Pln.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Line.hxx>
# include <gp_Lin.hxx>
#endif
#include "ui_TaskFemConstraintForce.h"
#include "TaskFemConstraintForce.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraintForce.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
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<Fem::ConstraintForce*>(ConstraintView->getObject());
double f = pcConstraint->Force.getValue();
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
std::vector<std::string> 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(FLOAT_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<std::string> references(1,subName);
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
if (selectionMode == selref) {
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> 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<Fem::ConstraintForce*>(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<Fem::ConstraintForce*>(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<std::string> 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<const TaskFemConstraintForce*>(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"

View File

@@ -0,0 +1,92 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraintForce_H
#define GUI_TASKVIEW_TaskFemConstraintForce_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#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

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskFemConstraintForce</class>
<widget class="QWidget" name="TaskFemConstraintForce">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>233</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="buttonReference">
<property name="text">
<string>Add reference</string>
</property>
</widget>
</item>
<item>
<widget class="QListWidget" name="listReferences"/>
</item>
<item>
<layout class="QHBoxLayout" name="layoutForce">
<item>
<widget class="QLabel" name="labelForce">
<property name="text">
<string>Load [N]</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="spinForce">
<property name="minimum">
<double>-99999.000000000000000</double>
</property>
<property name="maximum">
<double>99999.000000000000000</double>
</property>
<property name="value">
<double>500.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDirection">
<item>
<widget class="QPushButton" name="buttonDirection">
<property name="text">
<string>Direction</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineDirection"/>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="checkReverse">
<property name="text">
<string>Reverse direction</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>17</width>
<height>56</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@@ -0,0 +1,315 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
/*
# include <sstream>
# include <QRegExp>
# include <QTextStream>
# include <QMessageBox>
# include <Precision.hxx>*/
# include <TopoDS.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <Geom_Plane.hxx>
# include <gp_Pln.hxx>
# include <gp_Ax1.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <Geom_Line.hxx>
# include <gp_Lin.hxx>
#endif
#include "ui_TaskFemConstraintBearing.h"
#include "TaskFemConstraintGear.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraintGear.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace FemGui;
using namespace Gui;
/* TRANSLATOR FemGui::TaskFemConstraintGear */
TaskFemConstraintGear::TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent, const char *pixmapname)
: TaskFemConstraintBearing(ConstraintView, parent, pixmapname)
{
connect(ui->spinDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onDiameterChanged(double)));
connect(ui->spinForce, SIGNAL(valueChanged(double)),
this, SLOT(onForceChanged(double)));
connect(ui->spinForceAngle, SIGNAL(valueChanged(double)),
this, SLOT(onForceAngleChanged(double)));
connect(ui->buttonDirection, SIGNAL(pressed()),
this, SLOT(onButtonDirection()));
connect(ui->checkReversed, SIGNAL(toggled(bool)),
this, SLOT(onCheckReversed(bool)));
// Temporarily prevent unnecessary feature recomputes
ui->spinDiameter->blockSignals(true);
ui->spinForce->blockSignals(true);
ui->spinForceAngle->blockSignals(true);
ui->checkReversed->blockSignals(true);
// Get the feature data
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
double dia = pcConstraint->Diameter.getValue();
double force = pcConstraint->Force.getValue();
double angle = pcConstraint->ForceAngle.getValue();
std::vector<std::string> 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->spinDiameter->setMinimum(0);
ui->spinDiameter->setMaximum(FLOAT_MAX);
ui->spinDiameter->setValue(dia);
ui->spinForce->setMinimum(0);
ui->spinForce->setMaximum(FLOAT_MAX);
ui->spinForce->setValue(force);
ui->spinForceAngle->setMinimum(-360);
ui->spinForceAngle->setMaximum(360);
ui->spinForceAngle->setValue(angle);
ui->lineDirection->setText(dir);
ui->checkReversed->setChecked(reversed);
// Adjust ui
ui->labelDiameter->setVisible(true);
ui->spinDiameter->setVisible(true);
ui->labelForce->setVisible(true);
ui->spinForce->setVisible(true);
ui->labelForceAngle->setVisible(true);
ui->spinForceAngle->setVisible(true);
ui->buttonDirection->setVisible(true);
ui->lineDirection->setVisible(true);
ui->checkReversed->setVisible(true);
ui->checkAxial->setVisible(false);
ui->spinDiameter->blockSignals(false);
ui->spinForce->blockSignals(false);
ui->spinForceAngle->blockSignals(false);
ui->checkReversed->blockSignals(false);
}
void TaskFemConstraintGear::onSelectionChanged(const Gui::SelectionChanges& msg)
{
TaskFemConstraintBearing::onSelectionChanged(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<std::string> references(1,subName);
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subName.c_str());
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();
}
}
void TaskFemConstraintGear::onDiameterChanged(double l)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
pcConstraint->Diameter.setValue((float)l);
}
void TaskFemConstraintGear::onForceChanged(double f)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
pcConstraint->Force.setValue((float)f);
}
void TaskFemConstraintGear::onForceAngleChanged(double a)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
pcConstraint->ForceAngle.setValue((float)a);
}
void TaskFemConstraintGear::onButtonDirection(const bool pressed) {
if (pressed) {
selectionMode = seldir;
} else {
selectionMode = selnone;
}
ui->buttonDirection->setChecked(pressed);
Gui::Selection().clearSelection();
}
void TaskFemConstraintGear::onCheckReversed(const bool pressed)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
pcConstraint->Reversed.setValue(pressed);
}
double TaskFemConstraintGear::getForce(void) const
{
return ui->spinForce->value();
}
double TaskFemConstraintGear::getForceAngle(void) const
{
return ui->spinForceAngle->value();
}
const std::string TaskFemConstraintGear::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 TaskFemConstraintGear::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 TaskFemConstraintGear::getReverse() const
{
return ui->checkReversed->isChecked();
}
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->spinForce->blockSignals(true);
ui->spinForceAngle->blockSignals(true);
ui->checkReversed->blockSignals(true);
ui->retranslateUi(proxy);
ui->spinDiameter->blockSignals(false);
ui->spinForce->blockSignals(false);
ui->spinForceAngle->blockSignals(true);
ui->checkReversed->blockSignals(false);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgFemConstraintGear::TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView)
{
this->ConstraintView = ConstraintView;
assert(ConstraintView);
this->parameter = new TaskFemConstraintGear(ConstraintView, 0, "Fem_ConstraintGear");
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgFemConstraintGear::accept()
{
std::string name = ConstraintView->getObject()->getNameInDocument();
const TaskFemConstraintGear* parameterGear = static_cast<const TaskFemConstraintGear*>(parameter);
try {
//Gui::Command::openCommand("FEM force constraint changed");
std::string dirname = parameterGear->getDirectionName().data();
std::string dirobj = parameterGear->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(), parameterGear->getReverse() ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterGear->getDiameter());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(), parameterGear->getForce());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.ForceAngle = %f",name.c_str(), parameterGear->getForceAngle());
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return TaskDlgFemConstraintBearing::accept();
}
#include "moc_TaskFemConstraintGear.cpp"

View File

@@ -0,0 +1,79 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraintGear_H
#define GUI_TASKVIEW_TaskFemConstraintGear_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskFemConstraintBearing.h"
#include "ViewProviderFemConstraintGear.h"
namespace FemGui {
class TaskFemConstraintGear : public TaskFemConstraintBearing
{
Q_OBJECT
public:
TaskFemConstraintGear(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,
const char* pixmapname = "Fem_ConstraintGear");
double getDiameter(void) const;
double getForce(void) const;
double getForceAngle(void) const;
const std::string getDirectionName(void) const;
const std::string getDirectionObject(void) const;
bool getReverse(void) const;
private Q_SLOTS:
void onDiameterChanged(double dia);
void onForceChanged(double force);
void onForceAngleChanged(double angle);
void onButtonDirection(const bool pressed = true);
void onCheckReversed(bool);
protected:
virtual void changeEvent(QEvent *e);
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraintGear : public TaskDlgFemConstraintBearing
{
Q_OBJECT
public:
TaskDlgFemConstraintGear() {}
TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskFemConstraintGear_H

View File

@@ -0,0 +1,210 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#endif
#include "ui_TaskFemConstraintBearing.h"
#include "TaskFemConstraintPulley.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/Fem/App/FemConstraintPulley.h>
#include <Mod/Part/App/PartFeature.h>
#include <Base/Console.h>
using namespace FemGui;
using namespace Gui;
/* TRANSLATOR FemGui::TaskFemConstraintPulley */
TaskFemConstraintPulley::TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent)
: TaskFemConstraintGear(ConstraintView, parent, "Fem_ConstraintPulley")
{
connect(ui->spinOtherDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onOtherDiameterChanged(double)));
connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)),
this, SLOT(onCenterDistanceChanged(double)));
connect(ui->checkIsDriven, SIGNAL(toggled(bool)),
this, SLOT(onCheckIsDriven(bool)));
connect(ui->spinTensionForce, SIGNAL(valueChanged(double)),
this, SLOT(onTensionForceChanged(double)));
// Temporarily prevent unnecessary feature recomputes
ui->spinOtherDiameter->blockSignals(true);
ui->spinCenterDistance->blockSignals(true);
ui->checkIsDriven->blockSignals(true);
ui->spinTensionForce->blockSignals(true);
// Get the feature data
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
double otherdia = pcConstraint->OtherDiameter.getValue();
double centerdist = pcConstraint->CenterDistance.getValue();
bool isdriven = pcConstraint->IsDriven.getValue();
double tensionforce = pcConstraint->TensionForce.getValue();
// Fill data into dialog elements
ui->spinOtherDiameter->setMinimum(0);
ui->spinOtherDiameter->setMaximum(FLOAT_MAX);
ui->spinOtherDiameter->setValue(otherdia);
ui->spinCenterDistance->setMinimum(0);
ui->spinCenterDistance->setMaximum(FLOAT_MAX);
ui->spinCenterDistance->setValue(centerdist);
ui->checkIsDriven->setChecked(isdriven);
ui->spinForce->setMinimum(-FLOAT_MAX);
ui->spinTensionForce->setMinimum(0);
ui->spinTensionForce->setMaximum(FLOAT_MAX);
ui->spinTensionForce->setValue(tensionforce);
// Adjust ui
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReversed->setVisible(false);
ui->labelDiameter->setText(tr("Pulley diameter"));
ui->labelForce->setText(tr("Torque [Nm]"));
ui->labelOtherDiameter->setVisible(true);
ui->spinOtherDiameter->setVisible(true);
ui->labelCenterDistance->setVisible(true);
ui->spinCenterDistance->setVisible(true);
ui->checkIsDriven->setVisible(true);
ui->labelTensionForce->setVisible(true);
ui->spinTensionForce->setVisible(true);
ui->spinOtherDiameter->blockSignals(false);
ui->spinCenterDistance->blockSignals(false);
ui->checkIsDriven->blockSignals(false);
ui->spinTensionForce->blockSignals(false);
}
void TaskFemConstraintPulley::onOtherDiameterChanged(double l)
{
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
pcConstraint->OtherDiameter.setValue((float)l);
}
void TaskFemConstraintPulley::onCenterDistanceChanged(double l)
{
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
pcConstraint->CenterDistance.setValue((float)l);
}
void TaskFemConstraintPulley::onTensionForceChanged(double force)
{
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
pcConstraint->TensionForce.setValue((float)force);
}
void TaskFemConstraintPulley::onCheckIsDriven(const bool pressed)
{
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
pcConstraint->IsDriven.setValue(pressed);
}
double TaskFemConstraintPulley::getTorque(void) const
{
return ui->spinForce->value();
}
double TaskFemConstraintPulley::getTensionForce(void) const
{
return ui->spinTensionForce->value();
}
bool TaskFemConstraintPulley::getIsDriven() const
{
return ui->checkIsDriven->isChecked();
}
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->spinOtherDiameter->blockSignals(true);
ui->spinCenterDistance->blockSignals(true);
ui->checkIsDriven->blockSignals(true);
ui->spinTensionForce->blockSignals(true);
ui->retranslateUi(proxy);
ui->spinOtherDiameter->blockSignals(false);
ui->spinCenterDistance->blockSignals(false);
ui->checkIsDriven->blockSignals(false);
ui->spinTensionForce->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<const TaskFemConstraintPulley*>(parameter);
try {
//Gui::Command::openCommand("FEM pulley constraint changed");
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());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.IsDriven = %s",name.c_str(), parameterPulley->getIsDriven() ? "True" : "False");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TensionForce = %f",name.c_str(), parameterPulley->getTensionForce());
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return TaskDlgFemConstraintGear::accept();
}
#include "moc_TaskFemConstraintPulley.cpp"

View File

@@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender@users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_TASKVIEW_TaskFemConstraintPulley_H
#define GUI_TASKVIEW_TaskFemConstraintPulley_H
#include <Gui/TaskView/TaskView.h>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include "TaskFemConstraintGear.h"
#include "ViewProviderFemConstraintPulley.h"
namespace FemGui {
class TaskFemConstraintPulley : public TaskFemConstraintGear
{
Q_OBJECT
public:
TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent = 0);
double getOtherDiameter(void) const;
double getCenterDistance(void) const;
double getTensionForce(void) const;
double getTorque(void) const;
bool getIsDriven(void) const;
private Q_SLOTS:
void onOtherDiameterChanged(double dia);
void onCenterDistanceChanged(double dia);
void onTensionForceChanged(double force);
void onCheckIsDriven(bool);
protected:
virtual void changeEvent(QEvent *e);
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraintPulley : public TaskDlgFemConstraintGear
{
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

View File

@@ -0,0 +1,439 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <QApplication>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoCylinder.h>
# include <Inventor/nodes/SoCone.h>
# include <Inventor/nodes/SoCube.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoComplexity.h>
#endif
#include "ViewProviderFemConstraint.h"
#include "TaskFemConstraint.h"
#include "Gui/Control.h"
#include "Gui/MainWindow.h"
#include "Gui/Command.h"
#include "Gui/Application.h"
#include "Gui/Document.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraint, Gui::ViewProviderDocumentObject)
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));
pFont = new SoFontStyle();
pFont->ref();
pLabel = new SoText2();
pLabel->ref();
pTextColor = new SoBaseColor();
pTextColor->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();
wizardWidget = NULL;
wizardSubLayout = NULL;
constraintDialog = NULL;
}
ViewProviderFemConstraint::~ViewProviderFemConstraint()
{
pFont->unref();
pLabel->unref();
pTextColor->unref();
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<std::string> ViewProviderFemConstraint::getDisplayModes(void) const
{
// add modes
std::vector<std::string> 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<App::DocumentObject*> ViewProviderFemConstraint::claimChildren(void)const
{
return std::vector<App::DocumentObject*>();
}
void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver, const char* member)
{
QAction* act;
act = menu->addAction(QObject::tr("Edit constraint"), receiver, member);
act->setData(QVariant((int)ViewProvider::Default));
ViewProviderDocumentObject::setupContextMenu(menu, receiver, member);
}
void ViewProviderFemConstraint::onChanged(const App::Property* prop)
{
if (prop == &Mirror || prop == &DistFactor) {
updateData(prop);
}
else if (prop == &TextColor) {
const App::Color& c = TextColor.getValue();
pTextColor->rgb.setValue(c.r,c.g,c.b);
}
else if (prop == &FaceColor) {
const App::Color& c = FaceColor.getValue();
pMaterials->diffuseColor.setValue(c.r,c.g,c.b);
}
else if (prop == &FontSize) {
pFont->size = FontSize.getValue();
}
else {
ViewProviderDocumentObject::onChanged(prop);
}
}
bool ViewProviderFemConstraint::setEdit(int ModNum)
{
return Gui::ViewProviderGeometryObject::setEdit(ModNum);
}
void ViewProviderFemConstraint::unsetEdit(int ModNum)
{
if ((wizardWidget != NULL) && (wizardSubLayout != NULL) && (constraintDialog != NULL)) {
wizardWidget = NULL;
wizardSubLayout = NULL;
delete constraintDialog;
constraintDialog = NULL;
// Notify the Shaft Wizard that we have finished editing
// See WizardShaft.py on why we do it this way
Gui::Command::runCommand(Gui::Command::Doc, "Gui.runCommand('PartDesign_WizardShaftCallBack')");
} else {
if (ModNum == ViewProvider::Default) {
// when pressing ESC make sure to close the dialog
Gui::Control().closeDialog();
}
else {
ViewProviderDocumentObject::unsetEdit(ModNum);
}
}
}
/*
// Create a local coordinate system with the z-axis given in dir
void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x)
{
// Find the y axis in an arbitrary direction, normal to z
// Conditions:
// y1 * z1 + y2 * z2 + y3 * z3 = |y| |z| cos(90°) = 0
// |y| = sqrt(y1^2 + y2^2 + y3^2) = 1
float z1, z2, z3;
z.getValue(z1, z2, z3);
float y1, y2, y3;
if (fabs(z1) > Precision::Confusion()) {
// Choose: y3 = 0
// Solution:
// y1 * z1 + y2 * z2 = 0
// y1 = - z2/z1 y2
// sqrt(z2^2/z1^2 y2^2 + y2^2) = 1
// y2^2 ( 1 + z2^2/z1^2)) = +-1 -> choose +1 otherwise no solution
// y2 = +- sqrt(1 / (1 + z2^2/z1^2))
y3 = 0;
y2 = sqrt(1 / (1 + z2*z2 / (z1*z1)));
y1 = -z2/z1 * y2;
// Note: result might be (0, 1, 0)
} else if (fabs(z2) > Precision::Confusion()) {
// Given: z1 = 0
// Choose: y1 = 0
// Solution:
// y2 * z2 + y3 * z3 = 0
// y2 = - z3/z2 y3
// sqrt(z3^2/z2^2 y3^3 + y3^2) = 1
// y3^2 (1 + z3^2/z2^2)) = +1
// y3 = +- sqrt(1 / (1 + z3^2/z2^2))
y1 = 0;
y3 = sqrt(1 / (1 + z3*z3 / (z2*z2)));
y2 = -z3/z2 * y3;
// Note: result might be (0, 0, 1)
} else if (fabs(z3) > Precision::Confusion()) {
// Given: z1 = z2 = 0
// Choose the remaining possible axis
y1 = 1;
y2 = 0;
y3 = 0;
}
y = SbVec3f(y1, y2, y3);
x = y.cross(z);
}
*/
#define PLACEMENT_CHILDREN 2
void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r)
{
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);
}
void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r)
{
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
trans->translation.setValue(base);
SoRotation* rot = static_cast<SoRotation*>(sep->getChild(idx+1));
rot->rotation.setValue(r);
}
#define CONE_CHILDREN 2
void ViewProviderFemConstraint::createCone(SoSeparator* sep, const double height, const double radius)
{
// 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);
}
SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius)
{
// Create a new cone node
SoSeparator* sep = new SoSeparator();
createCone(sep, height, radius);
return sep;
}
void ViewProviderFemConstraint::updateCone(const SoNode* node, const int idx, const double height, const double radius)
{
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
trans->translation.setValue(SbVec3f(0,-height/2,0));
SoCone* cone = static_cast<SoCone*>(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<const SoSeparator*>(node);
SoCylinder* cyl = static_cast<SoCylinder*>(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<const SoSeparator*>(node);
SoCube* cube = static_cast<SoCube*>(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<const SoSeparator*>(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<const SoSeparator*>(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);
}
QObject* ViewProviderFemConstraint::findChildByName(const QObject* parent, const QString& name)
{
for (QObjectList::const_iterator o = parent->children().begin(); o != parent->children().end(); o++) {
if ((*o)->objectName() == name)
return *o;
if (!(*o)->children().empty()) {
QObject* result = findChildByName(*o, name);
if (result != NULL)
return result;
}
}
return NULL;
}
void ViewProviderFemConstraint::checkForWizard()
{
wizardWidget= NULL;
wizardSubLayout = NULL;
Gui::MainWindow* mw = Gui::getMainWindow();
if (mw == NULL) return;
QDockWidget* dw = mw->findChild<QDockWidget*>(QObject::tr("Combo View"));
if (dw == NULL) return;
QWidget* cw = dw->findChild<QWidget*>(QObject::tr("Combo View"));
if (cw == NULL) return;
QTabWidget* tw = cw->findChild<QTabWidget*>(QObject::tr("combiTab"));
if (tw == NULL) return;
QStackedWidget* sw = tw->findChild<QStackedWidget*>(QObject::tr("qt_tabwidget_stackedwidget"));
if (sw == NULL) return;
QScrollArea* sa = sw->findChild<QScrollArea*>();
if (sa== NULL) return;
QWidget* wd = sa->widget(); // This is the reason why we cannot use findChildByName() right away!!!
if (wd == NULL) return;
QObject* wiz = findChildByName(wd, QObject::tr("ShaftWizard")); // FIXME: Actually, we don't want to translate this...
if (wiz != NULL)
wizardWidget = static_cast<QVBoxLayout*>(wiz);
wizardSubLayout = wiz->findChild<QVBoxLayout*>(QObject::tr("ShaftWizardLayout"));
}

View File

@@ -0,0 +1,124 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINT_H
#define GUI_VIEWPROVIDERFEMCONSTRAINT_H
#include <TopoDS_Shape.hxx>
#include "Gui/ViewProviderGeometryObject.h"
#include <QObject>
#include <QVBoxLayout>
#include <QTableWidget>
class SoFontStyle;
class SoText2;
class SoBaseColor;
class SoTranslation;
class SbRotation;
class SoMaterial;
namespace Gui {
class View3DInventorViewer;
namespace TaskView {
class TaskDialog;
}
}
namespace FemGui
{
class TaskFemConstraint;
class FemGuiExport ViewProviderFemConstraint : public Gui::ViewProviderGeometryObject
{
PROPERTY_HEADER(FemGui::ViewProviderFemConstraint);
public:
/// Constructor
ViewProviderFemConstraint(void);
virtual ~ViewProviderFemConstraint();
// Display properties
App::PropertyColor TextColor;
App::PropertyColor FaceColor;
App::PropertyColor ShapeColor;
App::PropertyInteger FontSize;
App::PropertyFloat DistFactor;
App::PropertyBool Mirror;
void attach(App::DocumentObject *);
virtual void updateData(const App::Property* prop) { Gui::ViewProviderGeometryObject::updateData(prop); }
std::vector<std::string> getDisplayModes(void) const;
void setDisplayMode(const char* ModeName);
std::vector<App::DocumentObject*> claimChildren(void)const;
void setupContextMenu(QMenu*, QObject*, const char*);
protected:
void onChanged(const App::Property* prop);
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 = false);
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 * pTextColor;
SoMaterial * pMaterials;
protected:
SoSeparator * pShapeSep;
// Shaft design wizard integration
protected:
friend class TaskFemConstraint;
QVBoxLayout* wizardWidget;
QVBoxLayout* wizardSubLayout;
TaskFemConstraint* constraintDialog;
void checkForWizard();
static QObject* findChildByName(const QObject* parent, const QString& name);
};
} //namespace FemGui
#endif // GUI_VIEWPROVIDERFEMCONSTRAINT_H

View File

@@ -0,0 +1,153 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Precision.hxx>
#endif
#include "ViewProviderFemConstraintBearing.h"
#include <Mod/Fem/App/FemConstraintBearing.h>
#include "TaskFemConstraintBearing.h"
#include "Gui/Control.h"
#include "Gui/MainWindow.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintBearing, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintBearing::ViewProviderFemConstraintBearing()
{
sPixmap = "Fem_ConstraintBearing";
wizardWidget = NULL;
}
ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing()
{
}
bool ViewProviderFemConstraintBearing::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintBearing::setEdit()\n");
Base::Console().Error("Active dialog: %s\n", Gui::Control().activeDialog()->objectName().toStdString().c_str());
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<TaskDlgFemConstraintBearing *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// This case will occur in the ShaftWizard application
checkForWizard();
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
// No shaft wizard is running
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;
} else if (constraintDialog != NULL) {
// Another FemConstraint* dialog is already open inside the Shaft Wizard
// Ignore the request to open another dialog
return false;
} else {
constraintDialog = new TaskFemConstraintBearing(this);
return true;
}
}
// 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<Fem::ConstraintBearing*>(this->getObject());
if (strcmp(prop->getName(),"References") == 0)
Base::Console().Error("\n"); // enable a breakpoint here
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<SoSeparator*>(pShapeSep->getChild(2));
updateFixed(sep, 0, radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue());
}
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -0,0 +1,75 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_H
#include <TopoDS_Shape.hxx>
#include "ViewProviderFemConstraint.h"
#include <QObject>
#include <QVBoxLayout>
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

View File

@@ -0,0 +1,163 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Inventor/nodes/SoMultipleCopy.h>
# include <Precision.hxx>
#endif
#include "ViewProviderFemConstraintFixed.h"
#include <Mod/Fem/App/FemConstraintFixed.h>
#include "TaskFemConstraintFixed.h"
#include "Gui/Control.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed()
{
sPixmap = "Fem_ConstraintFixed";
}
ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed()
{
}
bool ViewProviderFemConstraintFixed::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintFixed::setEdit()\n");
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<TaskDlgFemConstraintFixed *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// This case will occur in the ShaftWizard application
checkForWizard();
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
// No shaft wizard is running
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;
} else if (constraintDialog != NULL) {
// Another FemConstraint* dialog is already open inside the Shaft Wizard
// Ignore the request to open another dialog
return false;
} else {
constraintDialog = new TaskFemConstraintFixed(this);
return true;
}
}
// 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
Fem::ConstraintFixed* pcConstraint = static_cast<Fem::ConstraintFixed*>(this->getObject());
/*
// This has a HUGE performance penalty as opposed to separate nodes for every symbol
// The problem seems to be SoCone
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
pShapeSep->removeAllChildren();
const std::vector<Base::Vector3f>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3f>& normals = pcConstraint->Normals.getValues();
std::vector<Base::Vector3f>::const_iterator n = normals.begin();
/*
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
int idx = 0;
*/
for (std::vector<Base::Vector3f>::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);
idx++
*/
SoSeparator* sep = new SoSeparator();
createPlacement(sep, base, rot);
createFixed(sep, HEIGHT, WIDTH);
pShapeSep->addChild(sep);
n++;
}
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTFIXED_H
#include <TopoDS_Shape.hxx>
#include "ViewProviderFemConstraint.h"
#include <QObject>
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

View File

@@ -0,0 +1,202 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Inventor/nodes/SoMultipleCopy.h>
# include <Precision.hxx>
#endif
#include "ViewProviderFemConstraintForce.h"
#include <Mod/Fem/App/FemConstraintForce.h>
#include "TaskFemConstraintForce.h"
#include "Gui/Control.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintForce::ViewProviderFemConstraintForce()
{
sPixmap = "Fem_ConstraintForce";
}
ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce()
{
}
bool ViewProviderFemConstraintForce::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintForce::setEdit(%u)\n", 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<TaskDlgFemConstraintForce *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// This case will occur in the ShaftWizard application
checkForWizard();
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
// No shaft wizard is running
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;
} else if (constraintDialog != NULL) {
// Another FemConstraint* dialog is already open inside the Shaft Wizard
// Ignore the request to open another dialog
return false;
} else {
constraintDialog = new TaskFemConstraintForce(this);
return true;
}
}
// 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
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(this->getObject());
/*
// This has a HUGE performance penalty as opposed to separate nodes for every symbol
// The problem seems to be SoCone
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<Base::Vector3f>& points = pcConstraint->Points.getValues();
/*
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
int idx = 0;*/
for (std::vector<Base::Vector3f>::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<Base::Vector3f>& points = pcConstraint->Points.getValues();
/*
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
*/
int idx = 0;
for (std::vector<Base::Vector3f>::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<SoSeparator*>(pShapeSep->getChild(idx));
updatePlacement(sep, 0, base, rot);
updateArrow(sep, 2, ARROWLENGTH, ARROWHEADRADIUS);
idx++;
}
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -0,0 +1,78 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTFORCE_H
#include <TopoDS_Shape.hxx>
#include "ViewProviderFemConstraint.h"
#include <QObject>
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

View File

@@ -0,0 +1,191 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Inventor/SbMatrix.h>
# include <Precision.hxx>
#endif
#include "ViewProviderFemConstraintGear.h"
#include <Mod/Fem/App/FemConstraintGear.h>
#include "TaskFemConstraintGear.h"
#include "Gui/Control.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintGear, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintGear::ViewProviderFemConstraintGear()
{
sPixmap = "Fem_ConstraintGear";
}
ViewProviderFemConstraintGear::~ViewProviderFemConstraintGear()
{
}
bool ViewProviderFemConstraintGear::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintGear::setEdit()\n");
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<TaskDlgFemConstraintGear *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// This case will occur in the ShaftWizard application
checkForWizard();
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
// No shaft wizard is running
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;
} else if (constraintDialog != NULL) {
// Another FemConstraint* dialog is already open inside the Shaft Wizard
// Ignore the request to open another dialog
return false;
} else {
constraintDialog = new TaskFemConstraintGear(this);
return true;
}
}
// 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)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(this->getObject());
// Gets called whenever a property of the attached object changes
if (strcmp(prop->getName(),"BasePoint") == 0) {
if (pcConstraint->Height.getValue() > Precision::Confusion()) {
// Remove and recreate the symbol
pShapeSep->removeAllChildren();
Base::Vector3f base = pcConstraint->BasePoint.getValue();
Base::Vector3f axis = pcConstraint->Axis.getValue();
Base::Vector3f direction = pcConstraint->DirectionVector.getValue();
if (direction.Length() < Precision::Confusion())
direction = Base::Vector3f(0,1,0);
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
SbVec3f b(base.x, base.y, base.z);
SbVec3f ax(axis.x, axis.y, axis.z);
SbVec3f dir(direction.x, direction.y, direction.z);
//Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y, direction.z);
createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax));
pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2));
createPlacement(pShapeSep, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir));
pShapeSep->addChild(createArrow(dia/2, dia/8));
}
} else if (strcmp(prop->getName(),"Diameter") == 0) {
if (pShapeSep->getNumChildren() > 0) {
// Change the symbol
Base::Vector3f axis = pcConstraint->Axis.getValue();
Base::Vector3f direction = pcConstraint->DirectionVector.getValue();
if (direction.Length() < Precision::Confusion())
direction = Base::Vector3f(0,1,0);
float dia = pcConstraint->Diameter.getValue();
float radius = pcConstraint->Radius.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
SbVec3f ax(axis.x, axis.y, axis.z);
SbVec3f dir(direction.x, direction.y, direction.z);
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2);
updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir));
sep = static_cast<SoSeparator*>(pShapeSep->getChild(5));
updateArrow(sep, 0, dia/2, dia/8);
}
} else if ((strcmp(prop->getName(),"DirectionVector") == 0) || (strcmp(prop->getName(),"ForceAngle") == 0)) {
// Note: "Reversed" also triggers "DirectionVector"
if (pShapeSep->getNumChildren() > 0) {
// Re-orient the symbol
Base::Vector3f axis = pcConstraint->Axis.getValue();
Base::Vector3f direction = pcConstraint->DirectionVector.getValue();
if (direction.Length() < Precision::Confusion())
direction = Base::Vector3f(0,1,0);
float dia = pcConstraint->Diameter.getValue();
float angle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
SbVec3f ax(axis.x, axis.y, axis.z);
SbVec3f dir(direction.x, direction.y, direction.z);
/*Base::Console().Error("Axis: %f, %f, %f\n", axis.x, axis.y, axis.z);
Base::Console().Error("Direction: %f, %f, %f\n", direction.x, direction.y, direction.z);
SbRotation rot = SbRotation(ax, dir);
SbMatrix m;
rot.getValue(m);
SbMat m2;
m.getValue(m2);
Base::Console().Error("Matrix: %f, %f, %f, %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
// Note: In spite of the fact that the rotation matrix takes on 3 different values if 3
// normal directions are chosen, the resulting arrow will only point in two different
// directions when ax = (1,0,0) (but for ax=(0,1,0) it points in 3 different directions!)
*/
updatePlacement(pShapeSep, 3, SbVec3f(dia/2 * sin(angle), 0, dia/2 * cos(angle)), SbRotation(ax, dir));
}
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTGear_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTGear_H
#include <TopoDS_Shape.hxx>
#include "ViewProviderFemConstraint.h"
#include <QObject>
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

View File

@@ -0,0 +1,225 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoRotation.h>
# include <Precision.hxx>
#endif
#include "ViewProviderFemConstraintPulley.h"
#include <Mod/Fem/App/FemConstraintPulley.h>
#include "TaskFemConstraintPulley.h"
#include "Gui/Control.h"
#include <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPulley, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintPulley::ViewProviderFemConstraintPulley()
{
sPixmap = "Fem_ConstraintPulley";
}
ViewProviderFemConstraintPulley::~ViewProviderFemConstraintPulley()
{
}
bool ViewProviderFemConstraintPulley::setEdit(int ModNum)
{
Base::Console().Error("ViewProviderFemConstraintPulley::setEdit()\n");
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<TaskDlgFemConstraintPulley *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// This case will occur in the ShaftWizard application
checkForWizard();
if ((wizardWidget == NULL) || (wizardSubLayout == NULL)) {
// No shaft wizard is running
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;
} else if (constraintDialog != NULL) {
// Another FemConstraint* dialog is already open inside the Shaft Wizard
// Ignore the request to open another dialog
return false;
} else {
constraintDialog = new TaskFemConstraintPulley(this);
return true;
}
}
// 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<Fem::ConstraintPulley*>(this->getObject());
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 forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
float beltAngle = pcConstraint->BeltAngle.getValue();
double rat1 = 0.8, rat2 = 0.2;
float f1 = pcConstraint->BeltForce1.getValue();
float f2 = pcConstraint->BeltForce2.getValue();
if (f1+f2 > Precision::Confusion()) {
rat1 = f1 / (f1+f2);
rat2 = f2 / (f1+f2);
}
SbVec3f b(base.x, base.y, base.z);
SbVec3f ax(axis.x, axis.y, axis.z);
createPlacement(pShapeSep, b, SbRotation(SbVec3f(0,1,0), ax)); // 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 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2))));
createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation());
sep->addChild(createArrow(dia/8 + dia/2 * rat1, dia/8));
pShapeSep->addChild(sep); // child 3
sep = new SoSeparator();
createPlacement(sep, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2))));
createPlacement(sep, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation());
sep->addChild(createArrow(dia/8 + dia/2 * rat2, dia/8));
pShapeSep->addChild(sep); // child 4
}
} else if (strcmp(prop->getName(),"Diameter") == 0) {
if (pShapeSep->getNumChildren() > 0) {
// Change the symbol
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
float beltAngle = pcConstraint->BeltAngle.getValue();
double rat1 = 0.8, rat2 = 0.2;
float f1 = pcConstraint->BeltForce1.getValue();
float f2 = pcConstraint->BeltForce2.getValue();
if (f1+f2 > Precision::Confusion()) {
rat1 = f1 / (f1+f2);
rat2 = f2 / (f1+f2);
}
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2);
sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2))));
updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation());
const SoSeparator* subsep = static_cast<SoSeparator*>(sep->getChild(4));
updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8);
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2))));
updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation());
subsep = static_cast<SoSeparator*>(sep->getChild(4));
updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8);
}
} else if ((strcmp(prop->getName(), "ForceAngle") == 0) || (strcmp(prop->getName(), "BeltAngle") == 0)) {
if (pShapeSep->getNumChildren() > 0) {
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float forceAngle = pcConstraint->ForceAngle.getValue() / 180 * M_PI;
float beltAngle = pcConstraint->BeltAngle.getValue();
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
updatePlacement(sep, 0, SbVec3f(dia/2 * sin(forceAngle+beltAngle), 0, dia/2 * cos(forceAngle+beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(sin(forceAngle+beltAngle+M_PI_2),0,cos(forceAngle+beltAngle+M_PI_2))));
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
updatePlacement(sep, 0, SbVec3f(-dia/2 * sin(forceAngle-beltAngle), 0, -dia/2 * cos(forceAngle-beltAngle)),
SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(forceAngle-beltAngle-M_PI_2),0,-cos(forceAngle-beltAngle-M_PI_2))));
}
} else if ((strcmp(prop->getName(), "BeltForce1") == 0) || (strcmp(prop->getName(), "BeltForce2") == 0)) {
if (pShapeSep->getNumChildren() > 0) {
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
double rat1 = 0.8, rat2 = 0.2;
float f1 = pcConstraint->BeltForce1.getValue();
float f2 = pcConstraint->BeltForce2.getValue();
if (f1+f2 > Precision::Confusion()) {
rat1 = f1 / (f1+f2);
rat2 = f2 / (f1+f2);
}
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat1, 0), SbRotation());
const SoSeparator* subsep = static_cast<SoSeparator*>(sep->getChild(4));
updateArrow(subsep, 0, dia/8 + dia/2 * rat1, dia/8);
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
updatePlacement(sep, 2, SbVec3f(0, dia/8 + dia/2 * rat2, 0), SbRotation());
subsep = static_cast<SoSeparator*>(sep->getChild(4));
updateArrow(subsep, 0, dia/8 + dia/2 * rat2, dia/8);
}
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (c) 2013 Jan Rheinländer <jrheinlaender[at]users.sourceforge.net> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTPulley_H
#include <TopoDS_Shape.hxx>
#include "ViewProviderFemConstraint.h"
#include <QObject>
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

View File

@@ -29,7 +29,7 @@
#include "Workbench.h"
#include <Gui/ToolBarManager.h>
#include <Gui/MenuManager.h>
#include <Gui/MenuManager.h>
using namespace FemGui;
@@ -56,7 +56,12 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
Gui::ToolBarItem* fem = new Gui::ToolBarItem(root);
fem->setCommand("FEM");
*fem << "Fem_CreateFromShape"
<< "Fem_CreateNodesSet";
<< "Fem_CreateNodesSet"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley";
return root;
}
@@ -68,7 +73,12 @@ Gui::MenuItem* Workbench::setupMenuBar() const
root->insertItem(item, fem);
fem->setCommand("&FEM");
*fem << "Fem_CreateFromShape"
<< "Fem_CreateNodesSet";
<< "Fem_CreateNodesSet"
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley";
return root;
}