Split code into separate files for each constraint type

This commit is contained in:
jrheinlaender 2013-02-20 20:24:38 +04:30
parent 918291f81f
commit d48542cf56
46 changed files with 4703 additions and 1457 deletions

View File

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

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)
@ -66,6 +66,16 @@ SET(Fem_SRCS
FemMeshProperty.h
FemConstraint.cpp
FemConstraint.h
FemConstraintBearing.h
FemConstraintBearing.cpp
FemConstraintFixed.cpp
FemConstraintFixed.h
FemConstraintForce.cpp
FemConstraintForce.h
FemConstraintGear.cpp
FemConstraintGear.h
FemConstraintPulley.cpp
FemConstraintPulley.h
${Mod_SRCS}
${Python_SRCS}
)

View File

@ -24,33 +24,46 @@
#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;
const char* Constraint::TypeEnums[]= {"Force on geometry","Fixed",
"Bearing (radial free)", "Bearing (radial fixed)",
"Pulley", "Gear (straight toothed)", NULL};
PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject);
Constraint::Constraint()
{
ADD_PROPERTY(Type,((long)0));
Type.setEnums(TypeEnums);
ADD_PROPERTY(Force,(0.0));
ADD_PROPERTY_TYPE(References,(0,0),"Constraint",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied");
ADD_PROPERTY_TYPE(Direction,(0),"Constraint",(App::PropertyType)(App::Prop_None),"Element giving direction of constraint");
ADD_PROPERTY(Reversed,(0));
ADD_PROPERTY(Distance,(0.0));
ADD_PROPERTY_TYPE(Location,(0),"Constraint",(App::PropertyType)(App::Prop_None),"Element giving location where constraint is applied");
ADD_PROPERTY(Diameter,(0.0));
ADD_PROPERTY(OtherDiameter,(0.0));
ADD_PROPERTY(CenterDistance,(0.0));
ADD_PROPERTY_TYPE(NormalDirection,(Base::Vector3f(0,0,1)),"Constraint",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),"Normal direction pointing outside of solid");
}
Constraint::~Constraint()
@ -59,12 +72,219 @@ Constraint::~Constraint()
App::DocumentObjectExecReturn *Constraint::execute(void)
{
// Ensure that the constraint symbols follow the changed geometry
References.touch();
return DocumentObject::StdReturn;
return StdReturn;
}
void Constraint::onChanged(const App::Property* prop)
{
//Base::Console().Error("Constraint::onChanged()\n");
if (prop == &References) {
Base::Console().Error("References\n");
// If References are changed, recalculate the normal direction. If no useful reference is found,
// use z axis or previous value. If several faces are selected, only the first one is used
std::vector<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...
DocumentObject::onChanged(prop);
return;
}
}
}
}
DocumentObject::onChanged(prop);
}
void Constraint::onDocumentRestored()
{
Base::Console().Error("onDocumentRestored\n");
}
void Constraint::onSettingDocument()
{
Base::Console().Error("onSettingDocument\n");
}
void Constraint::getPoints(std::vector<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();
sh = toposhape.getSubShape(SubElements[i].c_str());
if (sh.ShapeType() == TopAbs_VERTEX) {
const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
gp_Pnt p = BRep_Tool::Pnt(vertex);
points.push_back(Base::Vector3f(p.X(), p.Y(), p.Z()));
normals.push_back(NormalDirection.getValue());
} else if (sh.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve curve(TopoDS::Edge(sh));
double fp = curve.FirstParameter();
double lp = curve.LastParameter();
GProp_GProps props;
BRepGProp::LinearProperties(TopoDS::Edge(sh), props);
double l = props.Mass();
// Create points with 10 units distance, but at least one at the beginning and end of the edge
int steps;
if (l >= 20)
steps = round(l / 10);
else
steps = 1;
double step = (lp - fp) / steps;
for (int i = 0; i < steps + 1; i++) {
gp_Pnt p = curve.Value(i * step);
points.push_back(Base::Vector3f(p.X(), p.Y(), p.Z()));
normals.push_back(NormalDirection.getValue());
}
} else if (sh.ShapeType() == TopAbs_FACE) {
TopoDS_Face face = TopoDS::Face(sh);
// Surface boundaries
BRepAdaptor_Surface surface(face);
double ufp = surface.FirstUParameter();
double ulp = surface.LastUParameter();
double vfp = surface.FirstVParameter();
double vlp = surface.LastVParameter();
// Surface normals
BRepGProp_Face props(face);
gp_Vec normal;
gp_Pnt center;
// Get an estimate for the number of arrows by finding the average length of curves
Handle(Adaptor3d_HSurface) hsurf;
hsurf = new BRepAdaptor_HSurface(surface);
Adaptor3d_IsoCurve isoc(hsurf, GeomAbs_IsoU, vfp);
double l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion());
isoc.Load(GeomAbs_IsoU, vlp);
double lv = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0;
isoc.Load(GeomAbs_IsoV, ufp);
l = GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion());
isoc.Load(GeomAbs_IsoV, ulp);
double lu = (l + GCPnts_AbscissaPoint::Length(isoc, Precision::Confusion()))/2.0;
int stepsv;
if (lv >= 20.0)
stepsv = round(lv / 10);
else
stepsv = 2; // Minimum of three arrows to ensure (as much as possible) that at least one is displayed
int stepsu;
if (lu >= 20.0)
stepsu = round(lu / 10);
else
stepsu = 2;
double stepv = (vlp - vfp) / stepsv;
double stepu = (ulp - ufp) / stepsu;
// Create points and normals
for (int i = 0; i < stepsv + 1; i++) {
for (int j = 0; j < stepsu + 1; j++) {
double v = vfp + i * stepv;
double u = ufp + j * stepu;
gp_Pnt p = surface.Value(u, v);
BRepClass_FaceClassifier classifier(face, p, Precision::Confusion());
if (classifier.State() != TopAbs_OUT) {
points.push_back(Base::Vector3f(p.X(), p.Y(), p.Z()));
props.Normal(u, v,center,normal);
normal.Normalize();
normals.push_back(Base::Vector3f(normal.X(), normal.Y(), normal.Z()));
}
}
}
}
}
}
void Constraint::getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const
{
std::vector<App::DocumentObject*> Objects = References.getValues();
std::vector<std::string> SubElements = References.getSubValues();
if (Objects.empty())
return;
App::DocumentObject* obj = Objects[0];
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape sh = feat->Shape.getShape().getSubShape(SubElements[0].c_str());
TopoDS_Face face = TopoDS::Face(sh);
BRepAdaptor_Surface surface(face);
gp_Cylinder cyl = surface.Cylinder();
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
height = start.Distance(end);
radius = cyl.Radius();
gp_Pnt b = cyl.Location();
base = Base::Vector3f(b.X(), b.Y(), b.Z());
gp_Dir dir = cyl.Axis().Direction();
axis = Base::Vector3f(dir.X(), dir.Y(), dir.Z());
}
Base::Vector3f Constraint::getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis,
const App::PropertyLinkSub& location, const float& dist)
{
// Get the point specified by Location and Distance
App::DocumentObject* objLoc = location.getValue();
std::string subName = location.getSubValues().front();
Part::Feature* featLoc = static_cast<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());
}

View File

@ -24,8 +24,10 @@
#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
{
@ -39,30 +41,29 @@ public:
Constraint(void);
virtual ~Constraint();
App::PropertyEnumeration Type;
App::PropertyLinkSubList References;
App::PropertyFloat Force;
App::PropertyLinkSub Direction;
App::PropertyBool Reversed;
App::PropertyLinkSub Location;
App::PropertyFloat Distance;
App::PropertyFloat Diameter;
App::PropertyFloat OtherDiameter;
App::PropertyFloat CenterDistance;
App::PropertyVector NormalDirection;
/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);
/// returns the type name of the ViewProvider
const char* getViewProviderName(void) const {
virtual const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraint";
}
protected:
virtual void onChanged(const App::Property* prop);
virtual void onDocumentRestored();
virtual void onSettingDocument();
protected:
/// Calculate the points where symbols should be drawn
void getPoints(std::vector<Base::Vector3f>& points, std::vector<Base::Vector3f>& normals) const;
void getCylinder(float& radius, float& height, Base::Vector3f& base, Base::Vector3f& axis) const;
Base::Vector3f getBasePoint(const Base::Vector3f& base, const Base::Vector3f& axis,
const App::PropertyLinkSub &location, const float& dist);
private:
static const char* TypeEnums[];
};
} //namespace Fem

View File

@ -0,0 +1,116 @@
/***************************************************************************
* 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)
{
// Note: If we call this at the end, then the symbol ist not oriented correctly initially
// because the NormalDirection has not been calculated yet
Constraint::onChanged(prop);
if (prop == &References) {
// Find data of cylinder
float radius, height;
Base::Vector3f base, axis;
getCylinder(radius, height, base, axis);
Radius.setValue(radius);
Axis.setValue(axis);
Height.setValue(height);
// Update base point
base = base + axis * height/2;
if (Location.getValue() != NULL) {
base = getBasePoint(base, axis, Location, Dist.getValue());
}
Base::Console().Error("Basepoint2: %f, %f, %f\n", base.x, base.y, base.z);
BasePoint.setValue(base);
BasePoint.touch(); // This triggers ViewProvider::updateData()
} else if ((prop == &Location) || (prop == &Dist)) {
App::DocumentObject* obj = Location.getValue();
std::vector<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;
getCylinder(radius, height, base, axis);
base = getBasePoint(base + axis * height/2, axis, Location, Dist.getValue());
Base::Console().Error("Basepoint: %f, %f, %f\n", base.x, base.y, base.z);
BasePoint.setValue(base);
BasePoint.touch();
}
}

View File

@ -0,0 +1,68 @@
/***************************************************************************
* 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);
App::PropertyLinkSub Location;
App::PropertyFloat Dist;
App::PropertyBool AxialFree;
// Read-only (calculated values). These trigger changes in the ViewProvider
App::PropertyFloat Radius;
App::PropertyFloat Height;
App::PropertyVector BasePoint;
App::PropertyVector Axis;
/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);
/// returns the type name of the ViewProvider
const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraintBearing";
}
protected:
virtual void onChanged(const App::Property* prop);
};
} //namespace Fem
#endif // FEM_CONSTRAINTBEARING_H

View File

@ -0,0 +1,83 @@
/***************************************************************************
* 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;
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,125 @@
/***************************************************************************
* 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;
getPoints(points, normals);
Points.setValues(points); // We don't use the normals because all arrows should have the same direction
Points.touch(); // This triggers ViewProvider::updateData()
} else if (prop == &Direction) {
App::DocumentObject* obj = Direction.getValue();
std::vector<std::string> names = Direction.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());
gp_Dir dir;
if (sh.ShapeType() == TopAbs_FACE) {
BRepAdaptor_Surface surface(TopoDS::Face(sh));
if (surface.GetType() == GeomAbs_Plane) {
dir = surface.Plane().Axis().Direction();
} else {
return; // "Direction must be a planar face or linear edge"
}
} else if (sh.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve line(TopoDS::Edge(sh));
if (line.GetType() == GeomAbs_Line) {
dir = line.Line().Direction();
} else {
return; // "Direction must be a planar face or linear edge"
}
}
Base::Vector3f direction(dir.X(), dir.Y(), dir.Z());
direction.Normalize();
naturalDirectionVector = direction;
if (Reversed.getValue())
direction = -direction;
DirectionVector.setValue(direction);
DirectionVector.touch();
} else if (prop == &Reversed) {
if (Reversed.getValue() && (DirectionVector.getValue() == naturalDirectionVector)) {
DirectionVector.setValue(-naturalDirectionVector);
DirectionVector.touch();
} else if (!Reversed.getValue() && (DirectionVector.getValue() != naturalDirectionVector)) {
DirectionVector.setValue(naturalDirectionVector);
DirectionVector.touch();
}
} else if (prop == &NormalDirection) {
// Set a default direction if no direction reference has been given
if (Direction.getValue() == NULL) {
DirectionVector.setValue(NormalDirection.getValue());
naturalDirectionVector = NormalDirection.getValue();
}
}
}

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,58 @@
/***************************************************************************
* 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,(0));
}
App::DocumentObjectExecReturn *ConstraintGear::execute(void)
{
return ConstraintBearing::execute();
}
void ConstraintGear::onChanged(const App::Property* prop)
{
ConstraintBearing::onChanged(prop);
}

View File

@ -0,0 +1,61 @@
/***************************************************************************
* 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;
/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);
/// returns the type name of the ViewProvider
const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraintGear";
}
protected:
virtual void onChanged(const App::Property* prop);
};
} //namespace Fem
#endif // FEM_CONSTRAINTGear_H

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 *
* *
***************************************************************************/
#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::ConstraintBearing);
ConstraintPulley::ConstraintPulley()
{
ADD_PROPERTY(Diameter,(0));
ADD_PROPERTY(OtherDiameter,(0));
ADD_PROPERTY(CenterDistance,(0));
ADD_PROPERTY_TYPE(Angle,(0),"ConstraintPulley",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output),
"Angle of pulley forces");
}
App::DocumentObjectExecReturn *ConstraintPulley::execute(void)
{
return ConstraintBearing::execute();
}
void ConstraintPulley::onChanged(const App::Property* prop)
{
ConstraintBearing::onChanged(prop);
if ((prop == &Diameter) || (prop == &OtherDiameter) || (prop == &CenterDistance)) {
if (CenterDistance.getValue() > Precision::Confusion()) {
Angle.setValue(asin((Diameter.getValue() - OtherDiameter.getValue())/2/CenterDistance.getValue()));
Angle.touch();
}
}
}

View File

@ -0,0 +1,65 @@
/***************************************************************************
* 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 "FemConstraintBearing.h"
namespace Fem
{
class AppFemExport ConstraintPulley : public Fem::ConstraintBearing
{
PROPERTY_HEADER(Fem::ConstraintPulley);
public:
/// Constructor
ConstraintPulley(void);
App::PropertyFloat Diameter;
App::PropertyFloat OtherDiameter;
App::PropertyFloat CenterDistance;
// Read-only (calculated values). These trigger changes in the ViewProvider
App::PropertyFloat Angle;
/// recalculate the object
virtual App::DocumentObjectExecReturn *execute(void);
/// returns the type name of the ViewProvider
const char* getViewProviderName(void) const {
return "FemGui::ViewProviderFemConstraintPulley";
}
protected:
virtual void onChanged(const App::Property* prop);
};
} //namespace Fem
#endif // FEM_CONSTRAINTPulley_H

View File

@ -35,6 +35,11 @@
#include "ViewProviderSetFaces.h"
#include "ViewProviderSetGeometry.h"
#include "ViewProviderFemConstraint.h"
#include "ViewProviderFemConstraintBearing.h"
#include "ViewProviderFemConstraintFixed.h"
#include "ViewProviderFemConstraintForce.h"
#include "ViewProviderFemConstraintGear.h"
#include "ViewProviderFemConstraintPulley.h"
#include "Workbench.h"
//#include "resources/qrc_Fem.cpp"
@ -75,6 +80,11 @@ void FemGuiExport initFemGui()
FemGui::ViewProviderSetFaces ::init();
FemGui::ViewProviderSetGeometry ::init();
FemGui::ViewProviderFemConstraint ::init();
FemGui::ViewProviderFemConstraintBearing ::init();
FemGui::ViewProviderFemConstraintFixed ::init();
FemGui::ViewProviderFemConstraintForce ::init();
FemGui::ViewProviderFemConstraintGear ::init();
FemGui::ViewProviderFemConstraintPulley ::init();
// add resources and reloads the translators
loadFemResource();

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
@ -35,6 +35,11 @@ set(FemGui_MOC_HDRS
TaskCreateNodeSet.h
TaskDlgCreateNodeSet.h
TaskFemConstraint.h
TaskFemConstraintBearing.h
TaskFemConstraintFixed.h
TaskFemConstraintForce.h
TaskFemConstraintGear.h
TaskFemConstraintPulley.h
)
fc_wrap_cpp(FemGui_MOC_SRCS ${FemGui_MOC_HDRS})
SOURCE_GROUP("Moc" FILES ${FemGui_MOC_SRCS})
@ -44,6 +49,9 @@ set(FemGui_UIC_SRCS
TaskCreateNodeSet.ui
TaskObjectName.ui
TaskFemConstraint.ui
TaskFemConstraintCylindrical.ui
TaskFemConstraintFixed.ui
TaskFemConstraintForce.ui
)
qt4_wrap_ui(FemGui_UIC_HDRS ${FemGui_UIC_SRCS})
@ -55,8 +63,21 @@ SET(FemGui_DLG_SRCS
TaskFemConstraint.ui
TaskFemConstraint.cpp
TaskFemConstraint.h
)
SOURCE_GROUP("Dialogs" FILES ${FemGui_DLG_SRCS})
TaskFemConstraintCylindrical.ui
TaskFemConstraintBearing.cpp
TaskFemConstraintBearing.h
TaskFemConstraintFixed.ui
TaskFemConstraintFixed.cpp
TaskFemConstraintFixed.h
TaskFemConstraintForce.ui
TaskFemConstraintForce.cpp
TaskFemConstraintForce.h
TaskFemConstraintGear.cpp
TaskFemConstraintGear.h
TaskFemConstraintPulley.cpp
TaskFemConstraintPulley.h
)
SOURCE_GROUP("Dialogs" FILES ${FemGui_DLG_SRCS})
qt4_add_resources(FemResource_SRCS Resources/Fem.qrc)
@ -77,6 +98,16 @@ SET(FemGui_SRCS_ViewProvider
FemSelectionGate.h
ViewProviderFemConstraint.cpp
ViewProviderFemConstraint.h
ViewProviderFemConstraintBearing.cpp
ViewProviderFemConstraintBearing.h
ViewProviderFemConstraintFixed.cpp
ViewProviderFemConstraintFixed.h
ViewProviderFemConstraintForce.cpp
ViewProviderFemConstraintForce.h
ViewProviderFemConstraintGear.cpp
ViewProviderFemConstraintGear.h
ViewProviderFemConstraintPulley.cpp
ViewProviderFemConstraintPulley.h
)
SOURCE_GROUP("ViewProvider" FILES ${FemGui_SRCS_ViewProvider})
@ -122,6 +153,18 @@ SET(FemGui_SRCS
${FemGui_SRCS_TaskDlg}
${FemGui_SRCS_TaskBoxes}
${FemGui_SRCS_Module}
ViewProviderFemConstraint.cpp
ViewProviderFemConstraint.h
ViewProviderFemConstraintBearing.cpp
ViewProviderFemConstraintBearing.h
ViewProviderFemConstraintFixed.cpp
ViewProviderFemConstraintFixed.h
ViewProviderFemConstraintForce.cpp
ViewProviderFemConstraintForce.h
ViewProviderFemConstraintGear.cpp
ViewProviderFemConstraintGear.h
ViewProviderFemConstraintPulley.cpp
ViewProviderFemConstraintPulley.h
)
@ -129,11 +172,11 @@ SET(FemGui_SRCS
add_library(FemGui SHARED ${FemGui_SRCS})
target_link_libraries(FemGui ${FemGui_LIBS})
fc_target_copy_resource(FemGui
${CMAKE_SOURCE_DIR}/src/Mod/Fem
${CMAKE_BINARY_DIR}/Mod/Fem
InitGui.py)
fc_target_copy_resource(FemGui
${CMAKE_SOURCE_DIR}/src/Mod/Fem
${CMAKE_BINARY_DIR}/Mod/Fem
InitGui.py)
if(MSVC)
set_target_properties(FemGui PROPERTIES SUFFIX ".pyd")

View File

@ -55,7 +55,6 @@
#include <Mod/Fem/App/FemConstraint.h>
#include "Hypothesis.h"
#include "TaskFemConstraint.h"
using namespace std;
@ -87,35 +86,157 @@ bool CmdFemCreateFromShape::isActive(void)
return Gui::Selection().countObjectsOfType(type) > 0;
}
DEF_STD_CMD_A(CmdFemConstraint);
DEF_STD_CMD_A(CmdFemConstraintBearing);
CmdFemConstraint::CmdFemConstraint()
: Command("Fem_Constraint")
CmdFemConstraintBearing::CmdFemConstraintBearing()
: Command("Fem_ConstraintBearing")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint");
sMenuText = QT_TR_NOOP("Create FEM bearing constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a bearing");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_Constraint";
sPixmap = "Fem_ConstraintBearing";
}
void CmdFemConstraint::activated(int iMsg)
void CmdFemConstraintBearing::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraint");
std::string FeatName = getUniqueObjectName("FemConstraintBearing");
openCommand("Make FEM constraint");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::Constraint\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Force = 0.0",FeatName.c_str());
openCommand("Make FEM constraint for bearing");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintBearing\",\"%s\")",FeatName.c_str());
updateActive();
Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(App::GetApplication().getActiveDocument()->getActiveObject());
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraint::isActive(void)
bool CmdFemConstraintBearing::isActive(void)
{
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemConstraintFixed);
CmdFemConstraintFixed::CmdFemConstraintFixed()
: Command("Fem_ConstraintFixed")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM fixed constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a fixed geometric entity");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_ConstraintFixed";
}
void CmdFemConstraintFixed::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraintFixed");
openCommand("Make FEM constraint fixed geometry");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintFixed\",\"%s\")",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraintFixed::isActive(void)
{
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemConstraintForce);
CmdFemConstraintForce::CmdFemConstraintForce()
: Command("Fem_ConstraintForce")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM force constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a force acting on a geometric entity");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_ConstraintForce";
}
void CmdFemConstraintForce::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraintForce");
openCommand("Make FEM constraint force on geometry");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintForce\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Force = 0.0",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraintForce::isActive(void)
{
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemConstraintGear);
CmdFemConstraintGear::CmdFemConstraintGear()
: Command("Fem_ConstraintGear")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM gear constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a gear");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_ConstraintGear";
}
void CmdFemConstraintGear::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraintGear");
openCommand("Make FEM constraint for gear");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintGear\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraintGear::isActive(void)
{
return hasActiveDocument();
}
DEF_STD_CMD_A(CmdFemConstraintPulley);
CmdFemConstraintPulley::CmdFemConstraintPulley()
: Command("Fem_ConstraintPulley")
{
sAppModule = "Fem";
sGroup = QT_TR_NOOP("Fem");
sMenuText = QT_TR_NOOP("Create FEM pulley constraint");
sToolTipText = QT_TR_NOOP("Create FEM constraint for a pulley");
sWhatsThis = sToolTipText;
sStatusTip = sToolTipText;
sPixmap = "Fem_ConstraintPulley";
}
void CmdFemConstraintPulley::activated(int iMsg)
{
std::string FeatName = getUniqueObjectName("FemConstraintPulley");
openCommand("Make FEM constraint for pulley");
doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintPulley\",\"%s\")",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.Diameter = 100.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.OtherDiameter = 200.0",FeatName.c_str());
doCommand(Doc,"App.activeDocument().%s.CenterDistance = 500.0",FeatName.c_str());
updateActive();
doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str());
}
bool CmdFemConstraintPulley::isActive(void)
{
return hasActiveDocument();
}
@ -316,4 +437,9 @@ void CreateFemCommands(void)
rcCmdMgr.addCommand(new CmdFemCreateNodesSet());
rcCmdMgr.addCommand(new CmdFemDefineNodesSet());
rcCmdMgr.addCommand(new CmdFemConstraint());
rcCmdMgr.addCommand(new CmdFemConstraintBearing());
rcCmdMgr.addCommand(new CmdFemConstraintFixed());
rcCmdMgr.addCommand(new CmdFemConstraintForce());
rcCmdMgr.addCommand(new CmdFemConstraintGear());
rcCmdMgr.addCommand(new CmdFemConstraintPulley());
}

View File

@ -43,7 +43,7 @@
#include "TaskFemConstraint.h"
#include <App/Application.h>
#include <App/Document.h>
#include <App/PropertyGeo.h>
//#include <App/PropertyGeo.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
@ -61,430 +61,26 @@ using namespace Gui;
/* TRANSLATOR FemGui::TaskFemConstraint */
const QString makeRefText(const App::DocumentObject* obj, const std::string& subName)
TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent,const char* pixmapname)
: TaskBox(Gui::BitmapFactory().pixmap(pixmapname),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView)
{
return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str());
}
TaskFemConstraint::TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent)
: TaskBox(Gui::BitmapFactory().pixmap("Fem_Constraint"),tr("FEM constraint parameters"),true, parent),ConstraintView(ConstraintView)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);
ui = new Ui_TaskFemConstraint();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
// Create a context menu for the listview of the references
QAction* action = new QAction(tr("Delete"), ui->listReferences);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onReferenceDeleted()));
ui->listReferences->addAction(action);
ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu);
connect(ui->comboType, SIGNAL(currentIndexChanged(int)),
this, SLOT(onTypeChanged(int)));
connect(ui->spinForce, SIGNAL(valueChanged(double)),
this, SLOT(onForceChanged(double)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->buttonDirection, SIGNAL(pressed()),
this, SLOT(onButtonDirection()));
connect(ui->checkReverse, SIGNAL(toggled(bool)),
this, SLOT(onCheckReverse(bool)));
connect(ui->buttonLocation, SIGNAL(pressed()),
this, SLOT(onButtonLocation()));
connect(ui->spinDistance, SIGNAL(valueChanged(double)),
this, SLOT(onDistanceChanged(double)));
connect(ui->spinDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onDiameterChanged(double)));
connect(ui->spinOtherDia, SIGNAL(valueChanged(double)),
this, SLOT(onOtherDiameterChanged(double)));
connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)),
this, SLOT(onCenterDistanceChanged(double)));
this->groupLayout()->addWidget(proxy);
// Temporarily prevent unnecessary feature recomputes
ui->comboType->blockSignals(true);
ui->spinForce->blockSignals(true);
ui->listReferences->blockSignals(true);
ui->buttonReference->blockSignals(true);
ui->buttonDirection->blockSignals(true);
ui->checkReverse->blockSignals(true);
ui->buttonLocation->blockSignals(true);
ui->spinDistance->blockSignals(true);
ui->spinDiameter->blockSignals(true);
ui->spinOtherDia->blockSignals(true);
ui->spinCenterDistance->blockSignals(true);
// Get the feature data
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
int index = pcConstraint->Type.getValue();
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();
std::vector<std::string> locStrings = pcConstraint->Location.getSubValues();
QString loc;
if (!locStrings.empty())
loc = makeRefText(pcConstraint->Location.getValue(), locStrings.front());
double d = pcConstraint->Distance.getValue();
double dia = pcConstraint->Diameter.getValue();
double otherdia = pcConstraint->OtherDiameter.getValue();
double centerdist = pcConstraint->CenterDistance.getValue();
// Fill data into dialog elements
ui->comboType->clear();
ui->comboType->insertItem(0, tr("Force on geometry"));
ui->comboType->insertItem(1, tr("Fixed"));
ui->comboType->insertItem(2, tr("Bearing (axial free)"));
ui->comboType->insertItem(3, tr("Bearing (axial fixed)"));
ui->comboType->insertItem(4, tr("Pulley"));
ui->comboType->insertItem(5, tr("Gear (straight toothed)"));
ui->comboType->setCurrentIndex(index);
ui->spinForce->setMinimum(0);
ui->spinForce->setMaximum(INT_MAX);
ui->spinForce->setValue(f);
ui->listReferences->clear();
for (int i = 0; i < Objects.size(); i++)
ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i]));
if (Objects.size() > 0)
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir);
ui->checkReverse->setChecked(reversed);
ui->lineDirection->setText(loc.isEmpty() ? tr("") : loc);
ui->spinDistance->setMinimum(INT_MIN);
ui->spinDistance->setMaximum(INT_MAX);
ui->spinDistance->setValue(d);
ui->spinDiameter->setMinimum(0);
ui->spinDiameter->setMaximum(INT_MAX);
ui->spinDiameter->setValue(dia);
ui->spinOtherDia->setMinimum(0);
ui->spinOtherDia->setMaximum(INT_MAX);
ui->spinOtherDia->setValue(otherdia);
ui->spinCenterDistance->setMinimum(0);
ui->spinCenterDistance->setMaximum(INT_MAX);
ui->spinCenterDistance->setValue(centerdist);
// activate and de-activate dialog elements as appropriate
ui->comboType->blockSignals(false);
ui->spinForce->blockSignals(false);
ui->listReferences->blockSignals(false);
ui->buttonReference->blockSignals(false);
ui->buttonDirection->blockSignals(false);
ui->checkReverse->blockSignals(false);
ui->buttonLocation->blockSignals(false);
ui->spinDistance->blockSignals(false);
ui->spinDiameter->blockSignals(false);
ui->spinOtherDia->blockSignals(false);
ui->spinCenterDistance->blockSignals(false);
selectionMode = selref;
updateUI();
}
void TaskFemConstraint::updateUI()
const std::string TaskFemConstraint::getReferences(const std::vector<std::string>& items) const
{
if (ui->comboType->currentIndex() == 0) {
ui->labelForce->setVisible(true);
ui->spinForce->setVisible(true);
ui->buttonDirection->setVisible(true);
ui->lineDirection->setVisible(true);
ui->checkReverse->setVisible(true);
ui->buttonLocation->setVisible(false);
ui->lineLocation->setVisible(false);
ui->labelDistance->setVisible(false);
ui->spinDistance->setVisible(false);
ui->labelDiameter->setVisible(false);
ui->spinDiameter->setVisible(false);
ui->labelOtherDia->setVisible(false);
ui->spinOtherDia->setVisible(false);
ui->labelCenterDistance->setVisible(false);
ui->spinCenterDistance->setVisible(false);
} else if (ui->comboType->currentIndex() == 1) {
ui->labelForce->setVisible(false);
ui->spinForce->setVisible(false);
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReverse->setVisible(false);
ui->buttonLocation->setVisible(false);
ui->lineLocation->setVisible(false);
ui->labelDistance->setVisible(false);
ui->spinDistance->setVisible(false);
ui->labelDiameter->setVisible(false);
ui->spinDiameter->setVisible(false);
ui->labelOtherDia->setVisible(false);
ui->spinOtherDia->setVisible(false);
ui->labelCenterDistance->setVisible(false);
ui->spinCenterDistance->setVisible(false);
} else if ((ui->comboType->currentIndex() == 2) || (ui->comboType->currentIndex() == 3)) {
ui->labelForce->setVisible(false);
ui->spinForce->setVisible(false);
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReverse->setVisible(false);
ui->buttonLocation->setVisible(true);
ui->lineLocation->setVisible(true);
ui->labelDistance->setVisible(true);
ui->spinDistance->setVisible(true);
ui->labelDiameter->setVisible(false);
ui->spinDiameter->setVisible(false);
ui->labelOtherDia->setVisible(false);
ui->spinOtherDia->setVisible(false);
ui->labelCenterDistance->setVisible(false);
ui->spinCenterDistance->setVisible(false);
} else if (ui->comboType->currentIndex() == 4) {
ui->labelForce->setVisible(false);
ui->spinForce->setVisible(false);
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReverse->setVisible(false);
ui->buttonLocation->setVisible(true);
ui->lineLocation->setVisible(true);
ui->labelDistance->setVisible(true);
ui->spinDistance->setVisible(true);
ui->labelDiameter->setVisible(true);
ui->spinDiameter->setVisible(true);
ui->labelOtherDia->setVisible(true);
ui->spinOtherDia->setVisible(true);
ui->labelCenterDistance->setVisible(true);
ui->spinCenterDistance->setVisible(true);
} else if (ui->comboType->currentIndex() == 5) {
ui->labelForce->setVisible(false);
ui->spinForce->setVisible(false);
ui->buttonDirection->setVisible(false);
ui->lineDirection->setVisible(false);
ui->checkReverse->setVisible(false);
ui->buttonLocation->setVisible(true);
ui->lineLocation->setVisible(true);
ui->labelDistance->setVisible(true);
ui->spinDistance->setVisible(true);
ui->labelDiameter->setVisible(true);
ui->spinDiameter->setVisible(true);
ui->labelOtherDia->setVisible(true);
ui->spinOtherDia->setVisible(true);
ui->labelCenterDistance->setVisible(false);
ui->spinCenterDistance->setVisible(false);
std::string result;
for (std::vector<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 + ")";
}
if (ui->listReferences->model()->rowCount() == 0) {
// Go into reference selection mode if no reference has been selected yet
onButtonReference(true);
return;
}
if (ui->comboType->currentIndex() == 0) {
std::string ref = ui->listReferences->item(0)->text().toStdString();
int pos = ref.find_last_of(":");
if (ref.substr(pos+1, 6) == "Vertex")
ui->labelForce->setText(tr("Force [N]"));
else if (ref.substr(pos+1, 4) == "Edge")
ui->labelForce->setText(tr("Force [N/mm]"));
else if (ref.substr(pos+1, 4) == "Face")
ui->labelForce->setText(tr("Force [N/mm²]"));
}
return result;
}
void TaskFemConstraint::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// Don't allow selection in other document
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
return;
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string subName(msg.pSubName);
if (selectionMode == selnone)
return;
std::vector<std::string> references(1,subName);
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(msg.pObjectName);
//if (!obj->getClassTypeId().isDerivedFrom(Part::Feature::getClassTypeId()))
// return;
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 (pcConstraint->Type.getValue() == 0) {
// Force on geometry elements:
// Ensure we don't have mixed reference types
if (SubElements.size() > 0) {
if (subName.substr(0,4) != SubElements.front().substr(0,4)) {
QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead"));
return;
}
} else {
if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces, edges and vertices can be picked"));
return;
}
}
// Avoid duplicates
int pos = 0;
for (; pos < Objects.size(); pos++)
if (obj == Objects[pos])
break;
if (pos != Objects.size())
if (subName == SubElements[pos])
return;
} else if (pcConstraint->Type.getValue() == 1) {
// Fixed
if ((subName.substr(0,4) != "Face") && (subName.substr(0,4) != "Edge") && (subName.substr(0,6) != "Vertex")) {
QMessageBox::warning(this, tr("Selection error"), tr("Mixed shape types are not possible. Use a second constraint instead"));
return;
}
// Avoid duplicates
int pos = 0;
for (; pos < Objects.size(); pos++)
if (obj == Objects[pos])
break;
if (pos != Objects.size())
if (subName == SubElements[pos])
return;
} else if ((pcConstraint->Type.getValue() >= 2) && (pcConstraint->Type.getValue() <= 5)) {
// Bearing, pulley, gear
if (Objects.size() > 0) {
QMessageBox::warning(this, tr("Selection error"), tr("Please use only a single reference for bearing constraint"));
return;
}
// Only cylindrical faces allowed
if (subName.substr(0,4) != "Face") {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked"));
return;
}
BRepAdaptor_Surface surface(TopoDS::Face(ref));
if (surface.GetType() != GeomAbs_Cylinder) {
QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked"));
return;
}
} else {
return;
}
// add the new reference
Objects.push_back(obj);
SubElements.push_back(subName);
pcConstraint->References.setValues(Objects,SubElements);
ui->listReferences->addItem(makeRefText(obj, subName));
// Turn off reference selection mode
onButtonReference(false);
} else if ((selectionMode == seldir) || (selectionMode == selloc)) {
if (subName.substr(0,4) == "Face") {
BRepAdaptor_Surface surface(TopoDS::Face(ref));
if (surface.GetType() != GeomAbs_Plane) {
QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked"));
return;
}
} else if (subName.substr(0,4) == "Edge") {
BRepAdaptor_Curve line(TopoDS::Edge(ref));
if (line.GetType() != GeomAbs_Line) {
QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked"));
return;
}
} else {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked"));
return;
}
if (selectionMode == seldir) {
pcConstraint->Direction.setValue(obj, references);
ui->lineDirection->setText(makeRefText(obj, subName));
// Turn off direction selection mode
onButtonDirection(false);
} else {
pcConstraint->Location.setValue(obj, references);
ui->lineLocation->setText(makeRefText(obj, subName));
// Turn off direction selection mode
onButtonLocation(false);
}
}
updateUI();
}
}
void TaskFemConstraint::onTypeChanged(int index)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
int oldType = pcConstraint->Type.getValue();
pcConstraint->Type.setValue(index);
if (((oldType == 2) && (index == 3)) || ((oldType == 3) && (index == 2))) {
pcConstraint->References.touch(); // Update visual
updateUI();
} else {
// Clear all references if the old and new type mismatch
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
Objects.clear();
SubElements.clear();
pcConstraint->References.setValues(Objects, SubElements);
ui->listReferences->clear(); //model()->removeRows(0, ui->listReferences->model()->rowCount());
updateUI();
}
}
void TaskFemConstraint::onForceChanged(double f)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->Force.setValue((float)f);
}
void TaskFemConstraint::onDistanceChanged(double f)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->Distance.setValue((float)f);
}
void TaskFemConstraint::onDiameterChanged(double f)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->Diameter.setValue((float)f);
}
void TaskFemConstraint::onOtherDiameterChanged(double f)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->OtherDiameter.setValue((float)f);
}
void TaskFemConstraint::onCenterDistanceChanged(double d)
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->CenterDistance.setValue((float)d);
}
void TaskFemConstraint::onButtonReference(const bool pressed) {
if (pressed)
selectionMode = selref;
else
selectionMode = selnone;
ui->buttonReference->setChecked(pressed);
Gui::Selection().clearSelection();
}
void TaskFemConstraint::onReferenceDeleted() {
int row = ui->listReferences->currentIndex().row();
void TaskFemConstraint::onReferenceDeleted(const int row) {
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
@ -492,156 +88,20 @@ void TaskFemConstraint::onReferenceDeleted() {
Objects.erase(Objects.begin() + row);
SubElements.erase(SubElements.begin() + row);
pcConstraint->References.setValues(Objects, SubElements);
ui->listReferences->model()->removeRow(row);
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
}
void TaskFemConstraint::onButtonDirection(const bool pressed) {
if (pressed) {
selectionMode = seldir;
} else {
void TaskFemConstraint::onButtonReference(const bool pressed) {
if (pressed)
selectionMode = selref;
else
selectionMode = selnone;
}
ui->buttonDirection->setChecked(pressed);
//ui->buttonReference->setChecked(pressed);
Gui::Selection().clearSelection();
}
void TaskFemConstraint::onButtonLocation(const bool pressed) {
if (pressed) {
selectionMode = selloc;
} else {
selectionMode = selnone;
}
ui->buttonLocation->setChecked(pressed);
Gui::Selection().clearSelection();
}
void TaskFemConstraint::onCheckReverse(const bool pressed)
const QString TaskFemConstraint::makeRefText(const App::DocumentObject* obj, const std::string& subName) const
{
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(ConstraintView->getObject());
pcConstraint->Reversed.setValue(pressed);
}
int TaskFemConstraint::getType(void) const
{
return ui->comboType->currentIndex();
}
double TaskFemConstraint::getForce(void) const
{
return ui->spinForce->value();
}
double TaskFemConstraint::getDistance(void) const
{
return ui->spinDistance->value();
}
double TaskFemConstraint::getDiameter(void) const
{
return ui->spinDiameter->value();
}
double TaskFemConstraint::getOtherDiameter(void) const
{
return ui->spinOtherDia->value();
}
double TaskFemConstraint::getCenterDistance(void) const
{
return ui->spinCenterDistance->value();
}
const std::string TaskFemConstraint::getReferences(void) const
{
int rows = ui->listReferences->model()->rowCount();
if (rows == 0)
return "";
std::string result;
for (int r = 0; r < rows; r++) {
std::string item = ui->listReferences->item(r)->text().toStdString();
int pos = item.find_last_of(":");
std::string objStr = "App.ActiveDocument." + item.substr(0, pos);
std::string refStr = "\"" + item.substr(pos+1) + "\"";
result = result + (r > 0 ? ", " : "") + "(" + objStr + "," + refStr + ")";
}
return result;
}
const std::string TaskFemConstraint::getDirectionName(void) const
{
std::string dir = ui->lineDirection->text().toStdString();
if (dir.empty())
return "";
int pos = dir.find_last_of(":");
return dir.substr(0, pos).c_str();
}
const std::string TaskFemConstraint::getDirectionObject(void) const
{
std::string dir = ui->lineDirection->text().toStdString();
if (dir.empty())
return "";
int pos = dir.find_last_of(":");
return dir.substr(pos+1).c_str();
}
const std::string TaskFemConstraint::getLocationName(void) const
{
std::string loc = ui->lineLocation->text().toStdString();
if (loc.empty())
return "";
int pos = loc.find_last_of(":");
return loc.substr(0, pos).c_str();
}
const std::string TaskFemConstraint::getLocationObject(void) const
{
std::string loc = ui->lineLocation->text().toStdString();
if (loc.empty())
return "";
int pos = loc.find_last_of(":");
return loc.substr(pos+1).c_str();
}
bool TaskFemConstraint::getReverse() const
{
return ui->checkReverse->isChecked();
}
TaskFemConstraint::~TaskFemConstraint()
{
delete ui;
}
void TaskFemConstraint::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->comboType->blockSignals(true);
ui->spinForce->blockSignals(true);
ui->spinDistance->blockSignals(true);
int index = ui->comboType->currentIndex();
ui->comboType->clear();
ui->comboType->insertItem(0, tr("Force on geometry"));
ui->comboType->insertItem(1, tr("Fixed"));
ui->comboType->insertItem(2, tr("Bearing (axial free)"));
ui->comboType->insertItem(3, tr("Bearing (axial fixed)"));
ui->comboType->insertItem(4, tr("Pulley"));
ui->comboType->insertItem(5, tr("Gear (straight toothed)"));
ui->comboType->setCurrentIndex(index);
ui->retranslateUi(proxy);
ui->comboType->blockSignals(false);
ui->spinForce->blockSignals(false);
ui->spinDistance->blockSignals(false);
}
return QString::fromUtf8((std::string(obj->getNameInDocument()) + ":" + subName).c_str());
}
//**************************************************************************
@ -649,41 +109,14 @@ void TaskFemConstraint::changeEvent(QEvent *e)
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgFemConstraint::TaskDlgFemConstraint(ViewProviderFemConstraint *ConstraintView)
: TaskDialog(),ConstraintView(ConstraintView)
{
assert(ConstraintView);
parameter = new TaskFemConstraint(ConstraintView);
Content.push_back(parameter);
}
TaskDlgFemConstraint::~TaskDlgFemConstraint()
{
}
//==== calls from the TaskView ===============================================================
void TaskDlgFemConstraint::open()
{
}
void TaskDlgFemConstraint::clicked(int)
{
}
bool TaskDlgFemConstraint::accept()
{
std::string name = ConstraintView->getObject()->getNameInDocument();
try {
//Gui::Command::openCommand("FEM constraint changed");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),parameter->getType());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Force = %f",name.c_str(),parameter->getForce());
std::string refs = parameter->getReferences();
if (!refs.empty()) {
@ -693,37 +126,6 @@ bool TaskDlgFemConstraint::accept()
return false;
}
std::string dirname = parameter->getDirectionName().data();
std::string dirobj = parameter->getDirectionObject().data();
if (!dirname.empty()) {
QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
buf = buf.arg(QString::fromStdString(dirname));
buf = buf.arg(QString::fromStdString(dirobj));
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = %s", name.c_str(), buf.toStdString().c_str());
} else {
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str());
}
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Reversed = %s", name.c_str(), parameter->getReverse() ? "True" : "False");
std::string locname = parameter->getLocationName().data();
std::string locobj = parameter->getLocationObject().data();
if (!locname.empty()) {
QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])");
buf = buf.arg(QString::fromStdString(locname));
buf = buf.arg(QString::fromStdString(locobj));
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Location = %s", name.c_str(), buf.toStdString().c_str());
} else {
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Direction = None", name.c_str());
}
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Distance = %f",name.c_str(),parameter->getDistance());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(),parameter->getDiameter());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(),parameter->getOtherDiameter());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(),parameter->getCenterDistance());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()");
if (!ConstraintView->getObject()->isValid())
throw Base::Exception(ConstraintView->getObject()->getStatusString());
@ -740,7 +142,7 @@ bool TaskDlgFemConstraint::accept()
bool TaskDlgFemConstraint::reject()
{
// roll back the done things
// roll back the changes
Gui::Command::abortCommand();
Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()");
@ -748,5 +150,4 @@ bool TaskDlgFemConstraint::reject()
}
#include "moc_TaskFemConstraint.cpp"

View File

@ -29,9 +29,7 @@
#include <Gui/TaskView/TaskDialog.h>
#include "ViewProviderFemConstraint.h"
class Ui_TaskFemConstraint;
/*
namespace App {
class Property;
}
@ -39,7 +37,7 @@ class Property;
namespace Gui {
class ViewProvider;
}
*/
namespace FemGui {
class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionObserver
@ -47,45 +45,25 @@ class TaskFemConstraint : public Gui::TaskView::TaskBox, public Gui::SelectionOb
Q_OBJECT
public:
TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0);
~TaskFemConstraint();
TaskFemConstraint(ViewProviderFemConstraint *ConstraintView,QWidget *parent = 0,const char* pixmapname = "");
virtual ~TaskFemConstraint() {}
int getType(void) const;
double getForce(void) const;
const std::string getReferences(void) const;
const std::string getDirectionName(void) const;
const std::string getDirectionObject(void) const;
const std::string getLocationName(void) const;
const std::string getLocationObject(void) const;
double getDistance(void) const;
bool getReverse(void) const;
double getDiameter(void) const;
double getOtherDiameter(void) const;
double getCenterDistance(void) const;
virtual const std::string getReferences(void) const {}
const std::string getReferences(const std::vector<std::string>& items) const;
private Q_SLOTS:
void onTypeChanged(int);
void onReferenceDeleted();
void onForceChanged(double);
protected Q_SLOTS:
void onReferenceDeleted(const int row);
void onButtonReference(const bool pressed = true);
void onButtonDirection(const bool pressed = true);
void onButtonLocation(const bool pressed = true);
void onDistanceChanged(double);
void onCheckReverse(bool);
void onDiameterChanged(double);
void onOtherDiameterChanged(double);
void onCenterDistanceChanged(double);
protected:
void changeEvent(QEvent *e);
virtual void changeEvent(QEvent *e) {}
const QString makeRefText(const App::DocumentObject* obj, const std::string& subName) const;
private:
void onSelectionChanged(const Gui::SelectionChanges& msg);
void updateUI();
virtual void onSelectionChanged(const Gui::SelectionChanges& msg) {}
private:
protected:
QWidget* proxy;
Ui_TaskFemConstraint* ui;
ViewProviderFemConstraint *ConstraintView;
enum {seldir, selref, selloc, selnone} selectionMode;
};
@ -95,19 +73,11 @@ class TaskDlgFemConstraint : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDlgFemConstraint(ViewProviderFemConstraint *ConstraintView);
~TaskDlgFemConstraint();
ViewProviderFemConstraint* getConstraintView() const
{ return ConstraintView; }
public:
/// is called the TaskView when the dialog is opened
virtual void open();
virtual void open() {}
/// is called by the framework if an button is clicked which has no accept or reject role
virtual void clicked(int);
virtual void clicked(int) {}
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
/// is called by the framework if the dialog is rejected (Cancel)
@ -120,9 +90,11 @@ public:
virtual QDialogButtonBox::StandardButtons getStandardButtons(void) const
{ return QDialogButtonBox::Ok|QDialogButtonBox::Cancel; }
protected:
ViewProviderFemConstraint *ConstraintView;
ViewProviderFemConstraint* getConstraintView() const
{ return ConstraintView; }
protected:
ViewProviderFemConstraint *ConstraintView;
TaskFemConstraint *parameter;
};

View File

@ -0,0 +1,345 @@
/***************************************************************************
* 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_TaskFemConstraintCylindrical.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_TaskFemConstraintCylindrical();
ui->setupUi(proxy);
QMetaObject::connectSlotsByName(this);
// Create a context menu for the listview of the references
QAction* action = new QAction(tr("Delete"), ui->listReferences);
action->connect(action, SIGNAL(triggered()),
this, SLOT(onReferenceDeleted()));
ui->listReferences->addAction(action);
ui->listReferences->setContextMenuPolicy(Qt::ActionsContextMenu);
connect(ui->spinDistance, SIGNAL(valueChanged(double)),
this, SLOT(onDistanceChanged(double)));
connect(ui->buttonReference, SIGNAL(pressed()),
this, SLOT(onButtonReference()));
connect(ui->buttonLocation, SIGNAL(pressed()),
this, SLOT(onButtonLocation()));
connect(ui->checkAxial, SIGNAL(toggled(bool)),
this, SLOT(onCheckAxial(bool)));
this->groupLayout()->addWidget(proxy);
// Temporarily prevent unnecessary feature recomputes
ui->spinDistance->blockSignals(true);
ui->listReferences->blockSignals(true);
ui->buttonReference->blockSignals(true);
ui->buttonLocation->blockSignals(true);
ui->checkAxial->blockSignals(true);
// Get the feature data
Fem::ConstraintBearing* pcConstraint = static_cast<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(INT_MIN);
ui->spinDistance->setMaximum(INT_MAX);
ui->spinDistance->setValue(d);
ui->listReferences->clear();
for (int i = 0; i < Objects.size(); i++)
ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i]));
if (Objects.size() > 0)
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
ui->lineLocation->setText(loc);
ui->checkAxial->setChecked(axialfree);
// Adjust ui to constraint type
ui->labelDiameter->setVisible(false);
ui->spinDiameter->setVisible(false);
ui->labelOtherDiameter->setVisible(false);
ui->spinOtherDiameter->setVisible(false);
ui->labelCenterDistance->setVisible(false);
ui->spinCenterDistance->setVisible(false);
ui->spinDistance->blockSignals(false);
ui->listReferences->blockSignals(false);
ui->buttonReference->blockSignals(false);
ui->buttonLocation->blockSignals(false);
ui->checkAxial->blockSignals(false);
onButtonReference(true);
}
void TaskFemConstraintBearing::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// Don't allow selection in other document
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
return;
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string subName(msg.pSubName);
if (selectionMode == selnone)
return;
std::vector<std::string> references(1,subName);
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;
}
// Only cylindrical faces allowed
if (subName.substr(0,4) != "Face") {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces can be picked"));
return;
}
BRepAdaptor_Surface surface(TopoDS::Face(ref));
if (surface.GetType() != GeomAbs_Cylinder) {
QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked"));
return;
}
// add the new reference
Objects.push_back(obj);
SubElements.push_back(subName);
pcConstraint->References.setValues(Objects,SubElements);
ui->listReferences->addItem(makeRefText(obj, subName));
// Turn off reference selection mode
onButtonReference(false);
} else if (selectionMode == selloc) {
if (subName.substr(0,4) == "Face") {
BRepAdaptor_Surface surface(TopoDS::Face(ref));
if (surface.GetType() != GeomAbs_Plane) {
QMessageBox::warning(this, tr("Selection error"), tr("Only planar faces can be picked"));
return;
}
} else if (subName.substr(0,4) == "Edge") {
BRepAdaptor_Curve line(TopoDS::Edge(ref));
if (line.GetType() != GeomAbs_Line) {
QMessageBox::warning(this, tr("Selection error"), tr("Only linear edges can be picked"));
return;
}
} else {
QMessageBox::warning(this, tr("Selection error"), tr("Only faces and edges can be picked"));
return;
}
pcConstraint->Location.setValue(obj, references);
ui->lineLocation->setText(makeRefText(obj, subName));
// Turn off location selection mode
onButtonLocation(false);
}
Gui::Selection().clearSelection();
}
}
void TaskFemConstraintBearing::onDistanceChanged(double l)
{
Fem::ConstraintBearing* pcConstraint = static_cast<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,93 @@
/***************************************************************************
* 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_TaskFemConstraintCylindrical;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace FemGui {
class TaskFemConstraintBearing : public TaskFemConstraint
{
Q_OBJECT
public:
TaskFemConstraintBearing(ViewProviderFemConstraint *ConstraintView, QWidget *parent = 0,
const char* pixmapname = "Fem_ConstraintBearing");
virtual ~TaskFemConstraintBearing();
double getDistance(void) const;
virtual const std::string getReferences() const;
const std::string getLocationName(void) const;
const std::string getLocationObject(void) const;
bool getAxial(void) const;
private Q_SLOTS:
void onReferenceDeleted(void);
void onDistanceChanged(double l);
void onButtonLocation(const bool pressed = true);
void onCheckAxial(bool);
protected:
virtual void changeEvent(QEvent *e);
private:
virtual void onSelectionChanged(const Gui::SelectionChanges& msg);
protected:
Ui_TaskFemConstraintCylindrical* ui;
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraintBearing : public TaskDlgFemConstraint
{
Q_OBJECT
public:
TaskDlgFemConstraintBearing() {}
TaskDlgFemConstraintBearing(ViewProviderFemConstraintBearing *ConstraintView);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskFemConstraintBearing_H

View File

@ -0,0 +1,161 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TaskFemConstraintCylindrical</class>
<widget class="QWidget" name="TaskFemConstraintCylindrical">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>257</width>
<height>338</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">
<item>
<widget class="QLabel" name="labelDiameter">
<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_3">
<item>
<widget class="QLabel" name="labelOtherDiameter">
<property name="text">
<string>Other diameter</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>200.000000000000000</double>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="layoutDiameter_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="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>
<item>
<widget class="QCheckBox" name="checkAxial">
<property name="text">
<string>Axial free</string>
</property>
</widget>
</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(INT_MAX);
ui->spinForce->setValue(f);
ui->listReferences->clear();
for (int i = 0; i < Objects.size(); i++)
ui->listReferences->addItem(makeRefText(Objects[i], SubElements[i]));
if (Objects.size() > 0)
ui->listReferences->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
ui->lineDirection->setText(dir.isEmpty() ? tr("") : dir);
ui->checkReverse->setChecked(reversed);
ui->spinForce->blockSignals(false);
ui->listReferences->blockSignals(false);
ui->buttonReference->blockSignals(false);
ui->buttonDirection->blockSignals(false);
ui->checkReverse->blockSignals(false);
updateUI();
}
void TaskFemConstraintForce::updateUI()
{
if (ui->listReferences->model()->rowCount() == 0) {
// Go into reference selection mode if no reference has been selected yet
onButtonReference(true);
return;
}
std::string ref = ui->listReferences->item(0)->text().toStdString();
int pos = ref.find_last_of(":");
if (ref.substr(pos+1, 6) == "Vertex")
ui->labelForce->setText(tr("Force [N]"));
else if (ref.substr(pos+1, 4) == "Edge")
ui->labelForce->setText(tr("Force [N/mm]"));
else if (ref.substr(pos+1, 4) == "Face")
ui->labelForce->setText(tr("Force [N/mm²]"));
}
void TaskFemConstraintForce::onSelectionChanged(const Gui::SelectionChanges& msg)
{
if (msg.Type == Gui::SelectionChanges::AddSelection) {
// Don't allow selection in other document
if (strcmp(msg.pDocName, ConstraintView->getObject()->getDocument()->getName()) != 0)
return;
if (!msg.pSubName || msg.pSubName[0] == '\0')
return;
std::string subName(msg.pSubName);
if (selectionMode == selnone)
return;
std::vector<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,150 @@
/***************************************************************************
* 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_TaskFemConstraintCylindrical.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(ViewProviderFemConstraintGear *ConstraintView,QWidget *parent)
: TaskFemConstraintBearing(ConstraintView, parent, "Fem_ConstraintGear")
{
// we need a separate container widget to add all controls to
connect(ui->spinDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onDiameterChanged(double)));
// Temporarily prevent unnecessary feature recomputes
ui->spinDiameter->blockSignals(true);
// Get the feature data
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
double dia = pcConstraint->Diameter.getValue();
// Fill data into dialog elements
ui->spinDiameter->setMinimum(0);
ui->spinDiameter->setMaximum(INT_MAX);
ui->spinDiameter->setValue(dia);
// Adjust ui to specific constraint type
ui->checkAxial->setVisible(false);
ui->spinDiameter->setVisible(true);
ui->labelDiameter->setVisible(true);
ui->spinDiameter->blockSignals(false);
onButtonReference(true);
}
void TaskFemConstraintGear::onDiameterChanged(double l)
{
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(ConstraintView->getObject());
pcConstraint->Diameter.setValue((float)l);
}
double TaskFemConstraintGear::getDiameter(void) const
{
return ui->spinDiameter->value();
}
void TaskFemConstraintGear::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->spinDiameter->blockSignals(true);
ui->spinDistance->blockSignals(true);
ui->retranslateUi(proxy);
ui->spinDiameter->blockSignals(false);
ui->spinDistance->blockSignals(false);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgFemConstraintGear::TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView)
{
this->ConstraintView = ConstraintView;
assert(ConstraintView);
this->parameter = new TaskFemConstraintGear(ConstraintView);;
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgFemConstraintGear::accept()
{
std::string name = ConstraintView->getObject()->getNameInDocument();
const TaskFemConstraintGear* parameterGear = static_cast<const TaskFemConstraintGear*>(parameter);
try {
//Gui::Command::openCommand("FEM force constraint changed");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterGear->getDiameter());
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return TaskDlgFemConstraintBearing::accept();
}
#include "moc_TaskFemConstraintGear.cpp"

View File

@ -0,0 +1,78 @@
/***************************************************************************
* 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"
class Ui_TaskFemConstraintGear;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace FemGui {
class TaskFemConstraintGear : public TaskFemConstraintBearing
{
Q_OBJECT
public:
TaskFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView,QWidget *parent = 0);
double getDiameter(void) const;
private Q_SLOTS:
void onDiameterChanged(double dia);
protected:
virtual void changeEvent(QEvent *e);
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraintGear : public TaskDlgFemConstraintBearing
{
Q_OBJECT
public:
TaskDlgFemConstraintGear(ViewProviderFemConstraintGear *ConstraintView);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskFemConstraintGear_H

View File

@ -0,0 +1,185 @@
/***************************************************************************
* 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_TaskFemConstraintCylindrical.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)
: TaskFemConstraintBearing(ConstraintView, parent, "Fem_ConstraintPulley")
{
// we need a separate container widget to add all controls to
connect(ui->spinDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onDiameterChanged(double)));
connect(ui->spinOtherDiameter, SIGNAL(valueChanged(double)),
this, SLOT(onOtherDiameterChanged(double)));
connect(ui->spinCenterDistance, SIGNAL(valueChanged(double)),
this, SLOT(onCenterDistanceChanged(double)));
// Temporarily prevent unnecessary feature recomputes
ui->spinDiameter->blockSignals(true);
ui->spinOtherDiameter->blockSignals(true);
ui->spinCenterDistance->blockSignals(true);
// Get the feature data
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
double dia = pcConstraint->Diameter.getValue();
double otherdia = pcConstraint->OtherDiameter.getValue();
double centerdist = pcConstraint->CenterDistance.getValue();
// Fill data into dialog elements
ui->spinDiameter->setMinimum(0);
ui->spinDiameter->setMaximum(INT_MAX);
ui->spinDiameter->setValue(dia);
ui->spinOtherDiameter->setMinimum(0);
ui->spinOtherDiameter->setMaximum(INT_MAX);
ui->spinOtherDiameter->setValue(otherdia);
ui->spinCenterDistance->setMinimum(INT_MIN);
ui->spinCenterDistance->setMaximum(INT_MAX);
ui->spinCenterDistance->setValue(centerdist);
// Adjust ui to specific constraint type
ui->checkAxial->setVisible(false);
ui->spinDiameter->setVisible(true);
ui->labelDiameter->setVisible(true);
ui->labelDiameter->setText(tr("Pulley diameter"));
ui->labelOtherDiameter->setVisible(true);
ui->spinOtherDiameter->setVisible(true);
ui->labelCenterDistance->setVisible(true);
ui->spinCenterDistance->setVisible(true);
ui->spinDiameter->blockSignals(false);
ui->spinOtherDiameter->blockSignals(false);
ui->spinCenterDistance->blockSignals(false);
onButtonReference(true);
}
void TaskFemConstraintPulley::onDiameterChanged(double l)
{
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(ConstraintView->getObject());
pcConstraint->Diameter.setValue((float)l);
}
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);
}
double TaskFemConstraintPulley::getDiameter(void) const
{
return ui->spinDiameter->value();
}
double TaskFemConstraintPulley::getOtherDiameter(void) const
{
return ui->spinOtherDiameter->value();
}
double TaskFemConstraintPulley::getCenterDistance(void) const
{
return ui->spinCenterDistance->value();
}
void TaskFemConstraintPulley::changeEvent(QEvent *e)
{
TaskBox::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
ui->spinDiameter->blockSignals(true);
ui->spinDistance->blockSignals(true);
ui->spinOtherDiameter->blockSignals(true);
ui->spinCenterDistance->blockSignals(true);
ui->retranslateUi(proxy);
ui->spinDiameter->blockSignals(false);
ui->spinDistance->blockSignals(false);
ui->spinOtherDiameter->blockSignals(false);
ui->spinCenterDistance->blockSignals(false);
}
}
//**************************************************************************
//**************************************************************************
// TaskDialog
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
TaskDlgFemConstraintPulley::TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView)
{
this->ConstraintView = ConstraintView;
assert(ConstraintView);
this->parameter = new TaskFemConstraintPulley(ConstraintView);;
Content.push_back(parameter);
}
//==== calls from the TaskView ===============================================================
bool TaskDlgFemConstraintPulley::accept()
{
std::string name = ConstraintView->getObject()->getNameInDocument();
const TaskFemConstraintPulley* parameterPulley = static_cast<const TaskFemConstraintPulley*>(parameter);
try {
//Gui::Command::openCommand("FEM force constraint changed");
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Diameter = %f",name.c_str(), parameterPulley->getDiameter());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.OtherDiameter = %f",name.c_str(), parameterPulley->getOtherDiameter());
Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.CenterDistance = %f",name.c_str(), parameterPulley->getCenterDistance());
}
catch (const Base::Exception& e) {
QMessageBox::warning(parameter, tr("Input error"), QString::fromAscii(e.what()));
return false;
}
return TaskDlgFemConstraintBearing::accept();
}
#include "moc_TaskFemConstraintPulley.cpp"

View File

@ -0,0 +1,82 @@
/***************************************************************************
* 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 "TaskFemConstraintBearing.h"
#include "ViewProviderFemConstraintPulley.h"
class Ui_TaskFemConstraintPulley;
namespace App {
class Property;
}
namespace Gui {
class ViewProvider;
}
namespace FemGui {
class TaskFemConstraintPulley : public TaskFemConstraintBearing
{
Q_OBJECT
public:
TaskFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView,QWidget *parent = 0);
double getDiameter(void) const;
double getOtherDiameter(void) const;
double getCenterDistance(void) const;
private Q_SLOTS:
void onDiameterChanged(double dia);
void onOtherDiameterChanged(double dia);
void onCenterDistanceChanged(double dia);
protected:
virtual void changeEvent(QEvent *e);
};
/// simulation dialog for the TaskView
class TaskDlgFemConstraintPulley : public TaskDlgFemConstraintBearing
{
Q_OBJECT
public:
TaskDlgFemConstraintPulley(ViewProviderFemConstraintPulley *ConstraintView);
/// is called by the framework if the dialog is accepted (Ok)
virtual bool accept();
};
} //namespace FemGui
#endif // GUI_TASKVIEW_TaskFemConstraintPulley_H

View File

@ -24,56 +24,25 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <sstream>
# include <QApplication>
# include <Inventor/SoPickedPoint.h>
# include <Inventor/events/SoMouseButtonEvent.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoFontStyle.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoIndexedLineSet.h>
# include <Inventor/nodes/SoIndexedFaceSet.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <TopoDS.hxx>
# include <TopoDS_Vertex.hxx>
# include <BRep_Tool.hxx>
# include <gp_Pnt.hxx>
# include <gp_Pln.hxx>
# include <gp_Cylinder.hxx>
# include <BRepAdaptor_Curve.hxx>
# include <GProp_GProps.hxx>
# include <BRepGProp.hxx>
# include <BRepGProp_Face.hxx>
# include <BRepAdaptor_Surface.hxx>
# include <ShapeAnalysis.hxx>
# include <BRepClass_FaceClassifier.hxx>
# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <GeomAPI_IntCS.hxx>
# include <Geom_Plane.hxx>
# include <Geom_Line.hxx>
# include <Precision.hxx>
# 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>
#endif
#include "ViewProviderFemConstraint.h"
#include "TaskFemConstraint.h"
#include "Gui/SoFCSelection.h"
#include "Gui/Application.h"
#include "Gui/Control.h"
#include "Gui/Command.h"
#include "Gui/Document.h"
#include "Gui/View3DInventorViewer.h"
#include "App/Document.h"
#include <App/PropertyGeo.h>
#include <App/PropertyStandard.h>
#include <Mod/Part/App/PartFeature.h>
#include <Mod/Fem/App/FemConstraint.h>
#include <Base/Console.h>
using namespace FemGui;
@ -85,6 +54,7 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
{
ADD_PROPERTY(TextColor,(0.0f,0.0f,0.0f));
ADD_PROPERTY(FaceColor,(1.0f,0.0f,0.2f));
ADD_PROPERTY(ShapeColor,(1.0f,0.0f,0.2f));
ADD_PROPERTY(FontSize,(18));
ADD_PROPERTY(DistFactor,(1.0));
ADD_PROPERTY(Mirror,(false));
@ -93,42 +63,66 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
pFont->ref();
pLabel = new SoText2();
pLabel->ref();
pColor = new SoBaseColor();
pColor->ref();
pTextColor = new SoBaseColor();
pTextColor->ref();
pTranslation = new SoTranslation();
pTranslation->ref();
pMaterials = new SoMaterial();
pMaterials->ref();
pMaterials->diffuseColor.setValue(1.0f, 0.0f, 0.2f);
pMaterials->transparency.setValue(0.1);
//pMaterials->ambientColor.setValue(0.8f, 0.8f, 0.8f);
//pMaterials->shininess.setValue(1.0);
pShapeSep = new SoSeparator();
pShapeSep->ref();
TextColor.touch();
FontSize.touch();
FaceColor.touch();
FaceColor.touch();
pCoords = new SoCoordinate3();
pCoords->ref();
pCoords->point.setNum(0);
pFaces = new SoIndexedFaceSet();
pFaces->ref();
pFaces->coordIndex.setNum(0);
sPixmap = "view-femconstraint";
normalDirection = new SbVec3f(0, 0, 1);
arrowDirection = NULL;
oldDlg = NULL;
}
ViewProviderFemConstraint::~ViewProviderFemConstraint()
{
pFont->unref();
pLabel->unref();
pColor->unref();
pTextColor->unref();
pTranslation->unref();
pCoords->unref();
pFaces->unref();
delete arrowDirection;
delete normalDirection;
pMaterials->unref();
pShapeSep->unref();
}
void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject)
{
ViewProviderDocumentObject::attach(pcObject);
SoPickStyle* ps = new SoPickStyle();
ps->style = SoPickStyle::UNPICKABLE;
SoSeparator* sep = new SoSeparator();
SoShapeHints* hints = new SoShapeHints();
hints->shapeType.setValue(SoShapeHints::UNKNOWN_SHAPE_TYPE);
hints->vertexOrdering.setValue(SoShapeHints::COUNTERCLOCKWISE);
sep->addChild(ps);
sep->addChild(hints);
sep->addChild(pMaterials);
sep->addChild(pShapeSep);
addDisplayMaskMode(sep, "Base");
}
std::vector<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
@ -147,9 +141,9 @@ void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver,
void ViewProviderFemConstraint::onChanged(const App::Property* prop)
{
if (this->getObject() != NULL)
Base::Console().Error("%s: onChanged: %s\n", this->getObject()->getNameInDocument(), prop->getName());
Base::Console().Error("%s: VP onChanged: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: onChanged: %s\n", prop->getName());
Base::Console().Error("Anonymous: VP onChanged: %s\n", prop->getName());
if (prop == &Mirror || prop == &DistFactor) {
updateData(prop);
@ -160,7 +154,7 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop)
}
else if (prop == &FaceColor) {
const App::Color& c = FaceColor.getValue();
pColor->rgb.setValue(c.r,c.g,c.b);
pMaterials->diffuseColor.setValue(c.r,c.g,c.b);
}
else if (prop == &FontSize) {
pFont->size = FontSize.getValue();
@ -170,45 +164,6 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop)
}
}
bool ViewProviderFemConstraint::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraint *constrDlg = qobject_cast<TaskDlgFemConstraint *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraint(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemConstraint::unsetEdit(int ModNum)
{
if (ModNum == ViewProvider::Default) {
@ -218,41 +173,13 @@ void ViewProviderFemConstraint::unsetEdit(int ModNum)
else {
ViewProviderDocumentObject::unsetEdit(ModNum);
}
if (oldDlg != NULL) {
Gui::Control().showDialog(oldDlg);
oldDlg = NULL;
}
}
std::vector<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);
}
void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject)
{
ViewProviderDocumentObject::attach(pcObject);
SoPickStyle* ps = new SoPickStyle();
ps->style = SoPickStyle::UNPICKABLE;
SoSeparator *faceSep = new SoSeparator();
faceSep->addChild(ps);
faceSep->addChild(pColor);
faceSep->addChild(pCoords);
faceSep->addChild(pFaces);
SoSeparator* sep = new SoSeparator();
sep->addChild(faceSep);
addDisplayMaskMode(sep, "Base");
}
/*
// Create a local coordinate system with the z-axis given in dir
void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x)
{
@ -299,521 +226,163 @@ void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x)
y = SbVec3f(y1, y2, y3);
x = y.cross(z);
}
*/
#define PLACEMENT_CHILDREN 2
#define FACETS 12
#define CONEPOINTS (FACETS + 1)
#define CONEFACETPOINTS (FACETS * 4 + FACETS + 1)
void createCone(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir,
const double height, const double radius, const bool update = false)
void ViewProviderFemConstraint::createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r)
{
SbVec3f x, y;
getLocalCoordinateSystem(dir, y, x);
point.set1Value(ipoints, base); // tip
SbVec3f midpoint(base + dir * height); // centre of the circle
for (int i = 0; i < FACETS; i++) {
float angle = 2 * M_PI / FACETS * i;
point.set1Value(ipoints + i + 1, midpoint + cos(angle) * x * radius + sin(angle) * y * radius);
}
if (update)
return;
int32_t faces[CONEFACETPOINTS];
int start_index = 1;
for (int f = 0; f < FACETS; f++) {
faces[f * 4] = ipoints; // tip of arrow
int idx = start_index;
faces[f * 4 + 1] = ipoints + idx;
idx++;
if (idx > FACETS) idx = 1; // Happens in the last iteration
faces[f * 4 + 2] = ipoints + idx;
faces[f * 4 + 3] = -1;
start_index++;
}
for (int f = 0; f < FACETS; f++)
faces[FACETS * 4 + f] = ipoints + f + 1;
faces[CONEFACETPOINTS - 1] = -1;
refs.setValues(ifaces, CONEFACETPOINTS, faces);
SoTranslation* trans = new SoTranslation();
trans->ref();
trans->translation.setValue(base);
sep->addChild(trans);
SoRotation* rot = new SoRotation();
rot->ref();
rot->rotation.setValue(r);
sep->addChild(rot);
}
#define CYLPOINTS (FACETS * 2)
#define CYLFACETPOINTS (FACETS * 5 + 2 * FACETS + 2)
void createCylinder(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir,
const double height, const double radius, const bool update = false)
void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r)
{
SbVec3f x, y;
getLocalCoordinateSystem(dir, y, x);
for (int i = 0; i < CYLPOINTS; i+=2) {
float angle = 2 * M_PI / FACETS * i/2;
point.set1Value(ipoints + i, base + cos(angle) * x * radius + sin(angle) * y * radius);
point.set1Value(ipoints + i + 1, base + dir * height + cos(angle) * x * radius + sin(angle) * y * radius);
}
if (update)
return;
int32_t faces[CYLFACETPOINTS];
int start_index = 0;
for (int f = 0; f < FACETS; f++) {
int idx = start_index;
faces[f * 5] = ipoints + idx;
idx++;
faces[f * 5 + 1] = ipoints + idx;
idx++;
if (idx >= CYLPOINTS) idx = 0; // Happens in the last iteration
faces[f * 5 + 3] = ipoints + idx;
idx++;
faces[f * 5 + 2] = ipoints + idx;
faces[f * 5 + 4] = -1;
start_index += 2;
}
for (int f = 0; f < FACETS; f++) {
faces[FACETS * 5 + f] = ipoints + 2 * f;
faces[FACETS * 5 + FACETS + f + 1] = ipoints + 1 + 2 * f;
}
faces[FACETS * 5 + FACETS] = -1;
faces[CYLFACETPOINTS - 1] = -1;
refs.setValues(ifaces, CYLFACETPOINTS, faces);
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
trans->translation.setValue(base);
SoRotation* rot = static_cast<SoRotation*>(sep->getChild(idx+1));
rot->rotation.setValue(r);
}
#define ARROWPOINTS (CONEPOINTS + CYLPOINTS)
#define ARROWFACETPOINTS (CONEFACETPOINTS + CYLFACETPOINTS)
#define CONE_CHILDREN 2
void createArrow(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir,
const double length, const double radius, const bool update = false)
void ViewProviderFemConstraint::createCone(SoSeparator* sep, const double height, const double radius)
{
createCone(point, refs, ipoints, ifaces, base, dir, radius, radius, update);
createCylinder(point, refs, ipoints + CONEPOINTS, ifaces + CONEFACETPOINTS, base + dir * radius, dir, length-radius, radius/3, update);
// Adjust cone so that the tip is on base
SoTranslation* trans = new SoTranslation();
trans->ref();
trans->translation.setValue(SbVec3f(0,-height/2,0));
sep->addChild(trans);
SoCone* cone = new SoCone();
cone->ref();
cone->height.setValue(height);
cone->bottomRadius.setValue(radius);
sep->addChild(cone);
}
#define BOXPOINTS 8
#define BOXFACEPOINTS 30
void createBox(SoMFVec3f& point, SoMFInt32& refs, const int ipoints, const int ifaces, const SbVec3f& base, const SbVec3f& dir,
const double width, const double length, const double height, const bool update = false)
SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius)
{
SbVec3f x, y;
getLocalCoordinateSystem(dir, y, x);
point.set1Value(ipoints, base + width/2 * y + length/2 * x);
point.set1Value(ipoints+1, base + width/2 * y - length/2 * x);
point.set1Value(ipoints+2, base - width/2 * y - length/2 * x);
point.set1Value(ipoints+3, base - width/2 * y + length/2 * x);
point.set1Value(ipoints+4, base + dir * height + width/2 * y + length/2 * x);
point.set1Value(ipoints+5, base + dir * height + width/2 * y - length/2 * x);
point.set1Value(ipoints+6, base + dir * height - width/2 * y - length/2 * x);
point.set1Value(ipoints+7, base + dir * height - width/2 * y + length/2 * x);
if (update)
return;
int32_t faces[BOXFACEPOINTS] = {
ipoints, ipoints+1, ipoints+2, ipoints+3, -1,
ipoints, ipoints+1, ipoints+5, ipoints+4, -1,
ipoints+1, ipoints+2, ipoints+6, ipoints+5, -1,
ipoints+2, ipoints+3, ipoints+7, ipoints+6, -1,
ipoints+3, ipoints, ipoints+4, ipoints+7, -1,
ipoints+4, ipoints+5, ipoints+6, ipoints+7, -1};
refs.setValues(ifaces, BOXFACEPOINTS, faces);
// Create a new cone node
SoSeparator* sep = new SoSeparator();
createCone(sep, height, radius);
return sep;
}
void ViewProviderFemConstraint::findCylinderData(SbVec3f& z, SbVec3f& y, SbVec3f& x, SbVec3f& p, double& radius, double& height) {
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(this->getObject());
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
if (Objects.empty())
return;
App::DocumentObject* obj = Objects[0];
Part::Feature* feat = static_cast<Part::Feature*>(obj);
TopoDS_Shape sh = feat->Shape.getShape().getSubShape(SubElements[0].c_str());
TopoDS_Face face = TopoDS::Face(sh);
BRepAdaptor_Surface surface(face);
gp_Cylinder cyl = surface.Cylinder();
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
height = start.Distance(end);
radius = cyl.Radius();
gp_Dir dirz = cyl.Axis().Direction();
z = SbVec3f(dirz.X(), dirz.Y(), dirz.Z());
gp_Dir diry = cyl.YAxis().Direction();
y = SbVec3f(diry.X(), diry.Y(), diry.Z());
gp_Dir dirx = cyl.XAxis().Direction();
x = SbVec3f(dirx.X(), dirx.Y(), dirx.Z());
if (pcConstraint->Location.getValue() == NULL) {
// Get a point in the middle of the cylindrical face.
gp_Pnt centre = cyl.Location();
SbVec3f base(centre.X(), centre.Y(), centre.Z());
p = base + z * height/2;
} else {
// Get the point specified by Location and Distance
App::DocumentObject* objLoc = pcConstraint->Location.getValue();
std::string subName = pcConstraint->Location.getSubValues().front();
Part::Feature* featLoc = static_cast<Part::Feature*>(objLoc);
TopoDS_Shape shloc = featLoc->Shape.getShape().getSubShape(subName.c_str());
// Get a plane from the Location reference
gp_Pln plane;
if (shloc.ShapeType() == TopAbs_FACE) {
BRepAdaptor_Surface surface(TopoDS::Face(shloc));
plane = surface.Plane();
} else {
BRepAdaptor_Curve curve(TopoDS::Edge(shloc));
gp_Lin line = curve.Line();
gp_Dir tang = line.Direction().Crossed(dirz);
gp_Dir norm = line.Direction().Crossed(tang);
plane = gp_Pln(line.Location(), norm);
}
// Translate the plane in direction of the cylinder (for positive values of Distance)
Handle_Geom_Plane pln = new Geom_Plane(plane);
GeomAPI_ProjectPointOnSurf proj(cyl.Location(), pln);
if (!proj.IsDone())
return;
gp_Pnt projPnt = proj.NearestPoint();
plane.Translate(gp_Vec(projPnt, cyl.Location()).Normalized().Multiplied(pcConstraint->Distance.getValue()));
Handle_Geom_Plane plnt = new Geom_Plane(plane);
// Intersect translated plane with cylinder axis
Handle_Geom_Curve crv = new Geom_Line(cyl.Axis());
GeomAPI_IntCS intersector(crv, plnt);
if (!intersector.IsDone())
return;
gp_Pnt inter = intersector.Point(1);
p.setValue(inter.X(), inter.Y(), inter.Z());
}
}
void ViewProviderFemConstraint::updateData(const App::Property* prop)
void ViewProviderFemConstraint::updateCone(const SoNode* node, const int idx, const double height, const double radius)
{
// Gets called whenever a property of the attached object changes
if (this->getObject() != NULL)
Base::Console().Error("%s: updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: updateData: %s\n", prop->getName());
Fem::Constraint* pcConstraint = static_cast<Fem::Constraint*>(this->getObject());
if (strcmp(prop->getName(),"References") == 0) {
const App::PropertyLinkSubList* pr = static_cast<const App::PropertyLinkSubList*>(prop);
std::vector<App::DocumentObject*> Objects = pr->getValues();
std::vector<std::string> SubElements = pr->getSubValues();
// Remove all arrows
pCoords->point.deleteValues(0, pCoords->point.getNum());
pFaces->coordIndex.deleteValues(0, pFaces->coordIndex.getNum());
if (Objects.empty()) {
Base::Console().Error(" updateData: No references\n");
Objects = pcConstraint->References.getValues();
SubElements = pcConstraint->References.getSubValues();
if (Objects.empty())
return;
}
Base::Console().Error(" updateData: Found %u references\n", Objects.size());
// Re-create all arrows
int type = pcConstraint->Type.getValue();
if ((type == 0) || (type == 1)) {
// Force on geometry
std::vector<gp_Pnt> points;
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()) {
Base::Console().Error(" updateData: Empty toposhape\n");
return;
}
sh = toposhape.getSubShape(SubElements[i].c_str());
if (sh.ShapeType() == TopAbs_VERTEX) {
const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
gp_Pnt p = BRep_Tool::Pnt(vertex);
points.push_back(p);
} else if (sh.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve curve(TopoDS::Edge(sh));
double fp = curve.FirstParameter();
double lp = curve.LastParameter();
GProp_GProps props;
BRepGProp::LinearProperties(sh, props);
double l = props.Mass();
int steps = round(l / 3); // TODO: Make number of steps depend on actual screen size of element!
double step = (lp - fp) / steps;
if (steps < 1) {
points.push_back(curve.Value(fp));
points.push_back(curve.Value(lp));
} else {
for (int i = 0; i < steps + 1; i++)
points.push_back(curve.Value(i * step));
}
} else if (sh.ShapeType() == TopAbs_FACE) {
TopoDS_Face face = TopoDS::Face(sh);
BRepAdaptor_Surface surface(face);
double ufp = surface.FirstUParameter();
double ulp = surface.LastUParameter();
double vfp = surface.FirstVParameter();
double vlp = surface.LastVParameter();
double ustep = (ulp - ufp) / 6.0;
double vstep = (vlp - vfp) / 6.0;
// TODO: How to find the distance between ufp and ulp to get the number of steps?
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 7; j++) {
gp_Pnt p = surface.Value(ufp + i * ustep, vfp + j * vstep);
BRepClass_FaceClassifier classifier(face, p, Precision::Confusion());
if (classifier.State() != TopAbs_OUT)
points.push_back(p);
}
}
}
}
// Get default direction (on first call to method)
if (arrowDirection == NULL) {
if (sh.ShapeType() == TopAbs_FACE) {
// Get face normal in center point
TopoDS_Face face = TopoDS::Face(sh);
BRepGProp_Face prop(face);
gp_Vec normal;
gp_Pnt center;
double u1,u2,v1,v2;
prop.Bounds(u1,u2,v1,v2);
prop.Normal((u1+u2)/2.0,(v1+v2)/2.0,center,normal);
normal.Normalize();
normalDirection->setValue(normal.X(), normal.Y(), normal.Z());
} // else use z axis
arrowDirection = new SbVec3f(*normalDirection);
}
if (type == 0) {
// Force on geometry
pCoords->point.setNum(ARROWPOINTS * points.size());
pFaces->coordIndex.setNum(ARROWFACETPOINTS * points.size());
int index = 0;
for (std::vector<gp_Pnt>::const_iterator p = points.begin(); p != points.end(); p++) {
SbVec3f v(p->X(), p->Y(), p->Z());
if (*arrowDirection != *normalDirection) // Turn arrow around
v = v + *normalDirection * 5.0;
createArrow(pCoords->point, pFaces->coordIndex,
index * ARROWPOINTS, index * ARROWFACETPOINTS,
v, *arrowDirection, 5.0, 1.0);
index++;
}
} else if (type == 1) {
// Fixed
pCoords->point.setNum((CONEPOINTS + BOXPOINTS) * points.size());
pFaces->coordIndex.setNum((CONEFACETPOINTS + BOXFACEPOINTS) * points.size());
int index = 0;
for (std::vector<gp_Pnt>::const_iterator p = points.begin(); p != points.end(); p++) {
SbVec3f v(p->X(), p->Y(), p->Z());
createCone(pCoords->point, pFaces->coordIndex,
index * (CONEPOINTS + BOXPOINTS), index * (CONEFACETPOINTS + BOXFACEPOINTS),
v, *normalDirection, 2.0, 1.0);
createBox(pCoords->point, pFaces->coordIndex,
index * (CONEPOINTS + BOXPOINTS) + CONEPOINTS, index * (CONEFACETPOINTS + BOXFACEPOINTS) + CONEFACETPOINTS,
v + *normalDirection * 2.0, *normalDirection, 2.0, 2.0, 0.5);
index++;
}
}
} else if ((type == 2) || (type == 3)) {
// Bearing. Note that only one face is allowed for this constraint
SbVec3f z, y, x, p;
double radius, height;
findCylinderData(z, y, x, p, radius, height);
p = p + y * radius;
pCoords->point.setNum(CONEPOINTS + BOXPOINTS);
pFaces->coordIndex.setNum(CONEFACETPOINTS + BOXFACEPOINTS);
if (type == 2)
// axial free
createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2.5, radius/4);
else
// axial fixed
createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2, radius/4);
createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10);
} else if ((type == 4) || (type == 5)) {
// Pulley, Gear
SbVec3f z, y, x, p;
double radius, height;
findCylinderData(z, y, x, p, radius, height);
double dia = pcConstraint->Diameter.getValue();
if (dia < Precision::Confusion())
dia = radius * 4;
double otherdia = pcConstraint->OtherDiameter.getValue();
if (otherdia < Precision::Confusion())
otherdia = radius * 2;
double centerdist = pcConstraint->CenterDistance.getValue();
if (fabs(centerdist) < Precision::Confusion())
centerdist = 500;
if (type == 4) {
// Pulley
pCoords->point.setNum(CYLPOINTS + 2 * ARROWPOINTS);
pFaces->coordIndex.setNum(CYLFACETPOINTS + 2 * ARROWFACETPOINTS);
createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia);
double angle = asin((dia - otherdia)/2/centerdist);
SbVec3f p1 = p + y * dia * cos(angle) + x * dia * sin(angle);
SbVec3f dir1 = x - y * sin(angle);
dir1.normalize();
p1 = p1 + dir1 * 2 * radius;
dir1.negate();
SbVec3f p2 = p - y * dia * cos(angle) + x * dia * sin(angle);
SbVec3f dir2 = x + y * sin(angle);
dir2.normalize();
p2 = p2 + dir2 * 2 * radius;
dir2.negate();
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, dir1, 2 * radius, radius/5);
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS+ARROWPOINTS, CYLFACETPOINTS+ARROWFACETPOINTS, p2, dir2, 2 * radius, radius/5);
} else if (type == 5) {
// Gear
pCoords->point.setNum(CYLPOINTS + ARROWPOINTS);
pFaces->coordIndex.setNum(CYLFACETPOINTS + ARROWFACETPOINTS);
createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia);
SbVec3f p1 = p + y * dia;
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, x, radius, radius/5);
}
}
} else if (strcmp(prop->getName(),"Direction") == 0) {
if (arrowDirection == NULL)
return;
const App::PropertyLinkSub* pr = static_cast<const App::PropertyLinkSub*>(prop);
App::DocumentObject* obj = pr->getValue();
std::vector<std::string> names = pr->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) {
gp_Dir dir = surface.Plane().Axis().Direction();
arrowDirection->setValue(dir.X(), dir.Y(), dir.Z());
} else {
return; // Not a planar face
}
} else if (sh.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve line(TopoDS::Edge(sh));
if (line.GetType() == GeomAbs_Line) {
gp_Dir dir = line.Line().Direction();
arrowDirection->setValue(dir.X(), dir.Y(), dir.Z());
} else {
return; // Not a linear edge
}
}
// TODO: Check whether direction points inside or outside of solid? But for which reference?
arrowDirection->normalize();
*normalDirection = *arrowDirection;
bool reversed = pcConstraint->Reversed.getValue();
if (reversed)
arrowDirection->negate();
// Re-orient all arrows
int numArrows = pCoords->point.getNum()/ARROWPOINTS;
for (int i = 0; i < numArrows; i++) {
// Note: for update=true the pFaces->coordIndex is not touched
SbVec3f p = pCoords->point[i * ARROWPOINTS];
if (reversed)
p = p + *normalDirection * 5.0;
createArrow(pCoords->point, pFaces->coordIndex,
i * ARROWPOINTS, 0,
p, *arrowDirection, 5.0, 1.0, true);
}
} else if (strcmp(prop->getName(),"Reversed") == 0) {
if (arrowDirection == NULL)
return;
bool reversed = static_cast<const App::PropertyBool*>(prop)->getValue();
bool isReversed = (*arrowDirection != *normalDirection);
if (reversed == isReversed)
return;
*arrowDirection = *normalDirection;
if (reversed)
arrowDirection->negate();
// Reverse all arrows
int numArrows = pCoords->point.getNum()/ARROWPOINTS;
for (int i = 0; i < numArrows; i++) {
createArrow(pCoords->point, pFaces->coordIndex,
i * ARROWPOINTS, 0,
pCoords->point[i * ARROWPOINTS], *arrowDirection, 5.0, 1.0, true);
}
} else if ((strcmp(prop->getName(),"Location") == 0) || (strcmp(prop->getName(),"Distance") == 0)) {
// Move bearing constraint
SbVec3f z, y, x, p;
double radius, height;
findCylinderData(z, y, x, p, radius, height);
int type = pcConstraint->Type.getValue();
if (type == 2) {
// axial free
createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2.5, radius/4, true);
createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10, true);
} else if (type == 3) {
// axial fixed
createCone(pCoords->point, pFaces->coordIndex, 0, 0, p, y, radius/2, radius/4, true);
createBox(pCoords->point, pFaces->coordIndex, CONEPOINTS, CONEFACETPOINTS, p + y * radius/2, y, radius, radius, radius/10, true);
} else if ((type == 4) || (type == 5)) {
createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, pcConstraint->Diameter.getValue(), true);
}
} else if ((strcmp(prop->getName(),"Diameter") == 0) || (strcmp(prop->getName(),"OtherDiameter") == 0) ||
(strcmp(prop->getName(),"CenterDistance") == 0)) {
// Update pulley/gear constraint
SbVec3f z, y, x, p;
double radius, height;
findCylinderData(z, y, x, p, radius, height);
double dia = pcConstraint->Diameter.getValue();
if (dia < Precision::Confusion())
dia = radius * 4;
double otherdia = pcConstraint->OtherDiameter.getValue();
if (otherdia < Precision::Confusion())
otherdia = radius * 2;
double centerdist = pcConstraint->CenterDistance.getValue();
if (fabs(centerdist) < Precision::Confusion())
centerdist = 500;
int type = pcConstraint->Type.getValue();
if (type == 4) {
// Pulley
createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia, true);
double angle = asin((dia - otherdia)/2/centerdist);
SbVec3f p1 = p + y * dia * cos(angle) + x * dia * sin(angle);
SbVec3f dir1 = x - y * sin(angle);
dir1.normalize();
p1 = p1 + dir1 * 2 * radius;
dir1.negate();
SbVec3f p2 = p - y * dia * cos(angle) + x * dia * sin(angle);
SbVec3f dir2 = x + y * sin(angle);
dir2.normalize();
p2 = p2 + dir2 * 2 * radius;
dir2.negate();
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, dir1, 2 * radius, radius/5, true);
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS+ARROWPOINTS, CYLFACETPOINTS+ARROWFACETPOINTS, p2, dir2, 2 * radius, radius/5, true);
} else if (type == 5) {
// Gear
createCylinder(pCoords->point, pFaces->coordIndex, 0, 0, p - z * height * 0.4, z, height * 0.8, dia, true);
SbVec3f p1 = p + y * dia;
createArrow(pCoords->point, pFaces->coordIndex, CYLPOINTS, CYLFACETPOINTS, p1, x, 2 * radius, radius/5, true);
}
}
ViewProviderDocumentObject::updateData(prop);
const SoSeparator* sep = static_cast<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);
}

View File

@ -33,14 +33,14 @@ class SoFontStyle;
class SoText2;
class SoBaseColor;
class SoTranslation;
class SoCoordinate3;
class SoIndexedLineSet;
class SoIndexedFaceSet;
class SoEventCallback;
class SoMarkerSet;
class SbRotation;
class SoMaterial;
namespace Gui {
class View3DInventorViewer;
namespace TaskView {
class TaskDialog;
}
}
namespace FemGui
@ -58,12 +58,13 @@ public:
// Display properties
App::PropertyColor TextColor;
App::PropertyColor FaceColor;
App::PropertyColor ShapeColor;
App::PropertyInteger FontSize;
App::PropertyFloat DistFactor;
App::PropertyBool Mirror;
void attach(App::DocumentObject *);
void updateData(const App::Property*);
virtual void updateData(const App::Property*) {}
std::vector<std::string> getDisplayModes(void) const;
void setDisplayMode(const char* ModeName);
@ -72,24 +73,37 @@ public:
protected:
void onChanged(const App::Property* prop);
virtual bool setEdit(int ModNum);
virtual bool setEdit(int ModNum) {}
virtual void unsetEdit(int ModNum);
static void createPlacement(SoSeparator* sep, const SbVec3f &base, const SbRotation &r);
static void updatePlacement(const SoSeparator* sep, const int idx, const SbVec3f &base, const SbRotation &r);
static void createCone(SoSeparator* sep, const double height, const double radius);
static SoSeparator* createCone(const double height, const double radius);
static void updateCone(const SoNode* node, const int idx, const double height, const double radius);
static void createCylinder(SoSeparator* sep, const double height, const double radius);
static SoSeparator* createCylinder(const double height, const double radius);
static void updateCylinder(const SoNode* node, const int idx, const double height, const double radius);
static void createCube(SoSeparator* sep, const double width, const double length, const double height);
static SoSeparator* createCube(const double width, const double length, const double height);
static void updateCube(const SoNode* node, const int idx, const double width, const double length, const double height);
static void createArrow(SoSeparator* sep, const double length, const double radius);
static SoSeparator* createArrow(const double length, const double radius);
static void updateArrow(const SoNode* node, const int idx, const double length, const double radius);
static void createFixed(SoSeparator* sep, const double height, const double width, const bool gap);
static SoSeparator* createFixed(const double height, const double width, const bool gap = false);
static void updateFixed(const SoNode* node, const int idx, const double height, const double width, const bool gap = false);
private:
SoFontStyle * pFont;
SoText2 * pLabel;
SoBaseColor * pColor;
SoBaseColor * pTextColor;
SoTranslation * pTranslation;
SoCoordinate3 * pCoords;
SoIndexedFaceSet * pFaces;
SoMaterial * pMaterials;
/// Direction pointing outside of the solid
SbVec3f * normalDirection;
/// Direction of the force
SbVec3f * arrowDirection;
protected:
SoSeparator * pShapeSep;
void findCylinderData(SbVec3f& z, SbVec3f& y, SbVec3f& x, SbVec3f& p, double& radius, double& height);
Gui::TaskView::TaskDialog *oldDlg;
};
} //namespace FemGui

View File

@ -0,0 +1,142 @@
/***************************************************************************
* 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 <Base/Console.h>
using namespace FemGui;
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintBearing, FemGui::ViewProviderFemConstraint)
ViewProviderFemConstraintBearing::ViewProviderFemConstraintBearing()
{
sPixmap = "view-femconstraintbearing";
}
ViewProviderFemConstraintBearing::~ViewProviderFemConstraintBearing()
{
}
bool ViewProviderFemConstraintBearing::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraintBearing *constrDlg = qobject_cast<TaskDlgFemConstraintBearing *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// Allow stacking of dialogs, for ShaftWizard application
// Note: If other features start to allow stacking, we need to check for oldDlg != NULL
oldDlg = dlg;
/*
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
*/
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraintBearing(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemConstraintBearing::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintBearing* pcConstraint = static_cast<Fem::ConstraintBearing*>(this->getObject());
if (this->getObject() != NULL)
Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName());
if (strcmp(prop->getName(),"BasePoint") == 0) {
// Remove and recreate the symbol
pShapeSep->removeAllChildren();
// This should always point outside of the cylinder
Base::Vector3f normal = pcConstraint->NormalDirection.getValue();
Base::Vector3f base = pcConstraint->BasePoint.getValue();
float radius = pcConstraint->Radius.getValue();
base = base + radius * normal;
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(normal.x, normal.y, normal.z);
SbRotation rot(SbVec3f(0,-1,0), dir);
createPlacement(pShapeSep, b, rot);
pShapeSep->addChild(createFixed(radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue()));
} else if (strcmp(prop->getName(),"AxialFree") == 0) {
if (pShapeSep->getNumChildren() > 0) {
// Change the symbol
Base::Vector3f normal = pcConstraint->NormalDirection.getValue();
Base::Vector3f base = pcConstraint->BasePoint.getValue();
float radius = pcConstraint->Radius.getValue();
base = base + radius * normal;
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(normal.x, normal.y, normal.z);
SbRotation rot(SbVec3f(0,-1,0), dir);
updatePlacement(pShapeSep, 0, b, rot);
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
updateFixed(sep, 0, radius/2, radius/2 * 1.5, pcConstraint->AxialFree.getValue());
}
}
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_VIEWPROVIDERFEMCONSTRAINTBEARING_H
#define GUI_VIEWPROVIDERFEMCONSTRAINTBEARING_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 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,147 @@
/***************************************************************************
* 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 = "view-femconstraintfixed";
}
ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed()
{
}
bool ViewProviderFemConstraintFixed::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraintFixed *constrDlg = qobject_cast<TaskDlgFemConstraintFixed *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// Allow stacking of dialogs, for ShaftWizard application
// Note: If other features start to allow stacking, we need to check for oldDlg != NULL
oldDlg = dlg;
/*
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
*/
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraintFixed(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
#define HEIGHT 4
#define WIDTH (1.5*HEIGHT)
void ViewProviderFemConstraintFixed::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
if (this->getObject() != NULL)
Base::Console().Error("%s: VPF updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: VPF updateData: %s\n", prop->getName());
Fem::ConstraintFixed* pcConstraint = static_cast<Fem::ConstraintFixed*>(this->getObject());
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
SoMultipleCopy* cp = new SoMultipleCopy();
cp->ref();
cp->matrix.setNum(0);
cp->addChild((SoNode*)createFixed(HEIGHT, WIDTH));
pShapeSep->addChild(cp);
}
if (strcmp(prop->getName(),"Points") == 0) {
// Note: Points and Normals are always updated together
const std::vector<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);
n++;
idx++;
}
}
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,196 @@
/***************************************************************************
* 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 = "view-femconstraintforce";
}
ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce()
{
}
bool ViewProviderFemConstraintForce::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraintForce *constrDlg = qobject_cast<TaskDlgFemConstraintForce *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// Allow stacking of dialogs, for ShaftWizard application
// Note: If other features start to allow stacking, we need to check for oldDlg != NULL
oldDlg = dlg;
/*
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
*/
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraintForce(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
#define ARROWLENGTH 9
#define ARROWHEADRADIUS (ARROWLENGTH/3)
void ViewProviderFemConstraintForce::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
if (this->getObject() != NULL)
Base::Console().Error("%s: VPF updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: VPF updateData: %s\n", prop->getName());
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(this->getObject());
/*
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
SoMultipleCopy* cp = new SoMultipleCopy();
cp->ref();
cp->matrix.setNum(0);
cp->addChild((SoNode*)createArrow(ARROWLENGTH, ARROWHEADRADIUS));
pShapeSep->addChild(cp);
}
*/
if (strcmp(prop->getName(),"Points") == 0) {
// Redraw all arrows
pShapeSep->removeAllChildren();
// This should always point outside of the solid
Base::Vector3f normal = pcConstraint->NormalDirection.getValue();
// Get default direction (on first call to method)
Base::Vector3f forceDirection = pcConstraint->DirectionVector.getValue();
if (forceDirection.Length() < Precision::Confusion())
forceDirection = normal;
SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z);
SbRotation rot(SbVec3f(0,1,0), dir);
const std::vector<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,154 @@
/***************************************************************************
* 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 "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 = "view-femconstraintgear";
}
ViewProviderFemConstraintGear::~ViewProviderFemConstraintGear()
{
}
bool ViewProviderFemConstraintGear::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraintGear *constrDlg = qobject_cast<TaskDlgFemConstraintGear *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// Allow stacking of dialogs, for ShaftWizard application
// Note: If other features start to allow stacking, we need to check for oldDlg != NULL
oldDlg = dlg;
/*
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
*/
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraintGear(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemConstraintGear::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintGear* pcConstraint = static_cast<Fem::ConstraintGear*>(this->getObject());
if (this->getObject() != NULL)
Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName());
if (strcmp(prop->getName(),"BasePoint") == 0) {
if (pcConstraint->Height.getValue() > Precision::Confusion()) {
// Remove and recreate the symbol
pShapeSep->removeAllChildren();
// This should always point outside of the cylinder
Base::Vector3f base = pcConstraint->BasePoint.getValue();
Base::Vector3f axis = pcConstraint->Axis.getValue();
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(axis.x, axis.y, axis.z);
SbRotation rot(SbVec3f(0,1,0), dir);
createPlacement(pShapeSep, b, rot);
pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2));
createPlacement(pShapeSep, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0)));
pShapeSep->addChild(createArrow(dia/2, dia/8));
}
} else if (strcmp(prop->getName(),"Diameter") == 0) {
if (pShapeSep->getNumChildren() > 0) {
// Change the symbol
Base::Vector3f base = pcConstraint->BasePoint.getValue();
Base::Vector3f axis = pcConstraint->Axis.getValue();
//float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
float radius = pcConstraint->Radius.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(axis.x, axis.y, axis.z);
SbRotation rot(SbVec3f(0,1,0), dir);
updatePlacement(pShapeSep, 0, b, rot);
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia/2);
updatePlacement(pShapeSep, 3, SbVec3f(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(1,0,0)));
sep = static_cast<SoSeparator*>(pShapeSep->getChild(5));
updateArrow(sep, 0, dia/2, 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_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,166 @@
/***************************************************************************
* 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 = "view-femconstraintpulley";
}
ViewProviderFemConstraintPulley::~ViewProviderFemConstraintPulley()
{
}
bool ViewProviderFemConstraintPulley::setEdit(int ModNum)
{
if (ModNum == ViewProvider::Default ) {
// When double-clicking on the item for this constraint the
// object unsets and sets its edit mode without closing
// the task panel
Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog();
TaskDlgFemConstraintPulley *constrDlg = qobject_cast<TaskDlgFemConstraintPulley *>(dlg);
if (constrDlg && constrDlg->getConstraintView() != this)
constrDlg = 0; // another constraint left open its task panel
if (dlg && !constrDlg) {
// Allow stacking of dialogs, for ShaftWizard application
// Note: If other features start to allow stacking, we need to check for oldDlg != NULL
oldDlg = dlg;
/*
QMessageBox msgBox;
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
Gui::Control().closeDialog();
else
return false;
*/
}
// clear the selection (convenience)
Gui::Selection().clearSelection();
// start the edit dialog
if (constrDlg)
Gui::Control().showDialog(constrDlg);
else
Gui::Control().showDialog(new TaskDlgFemConstraintPulley(this));
return true;
}
else {
return ViewProviderDocumentObject::setEdit(ModNum);
}
}
void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintPulley* pcConstraint = static_cast<Fem::ConstraintPulley*>(this->getObject());
if (this->getObject() != NULL)
Base::Console().Error("%s: VP updateData: %s\n", this->getObject()->getNameInDocument(), prop->getName());
else
Base::Console().Error("Anonymous: VP updateData: %s\n", prop->getName());
if (strcmp(prop->getName(),"BasePoint") == 0) {
if (pcConstraint->Height.getValue() > Precision::Confusion()) {
// Remove and recreate the symbol
pShapeSep->removeAllChildren();
// This should always point outside of the cylinder
Base::Vector3f base = pcConstraint->BasePoint.getValue();
Base::Vector3f axis = pcConstraint->Axis.getValue();
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float angle = pcConstraint->Angle.getValue();
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(axis.x, axis.y, axis.z);
SbRotation rot(SbVec3f(0,-1,0), dir);
createPlacement(pShapeSep, b, rot); // child 0 and 1
pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia/2)); // child 2
SoSeparator* sep = new SoSeparator();
createPlacement(sep, SbVec3f(dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(sin(angle),0,cos(angle))));
sep->addChild(createArrow(dia/2, dia/8));
pShapeSep->addChild(sep); // child 3
sep = new SoSeparator();
createPlacement(sep, SbVec3f(-dia/2,0,0), SbRotation(SbVec3f(0,1,0), SbVec3f(-sin(angle),0,cos(angle))));
sep->addChild(createArrow(dia/2, dia/8));
pShapeSep->addChild(sep); // child 4
}
} else if (strcmp(prop->getName(),"Angle") == 0) {
if (pShapeSep->getNumChildren() > 0) {
// Change the symbol
Base::Vector3f base = pcConstraint->BasePoint.getValue();
Base::Vector3f axis = pcConstraint->Axis.getValue();
float radius = pcConstraint->Radius.getValue();
float dia = pcConstraint->Diameter.getValue();
if (dia < 2 * radius)
dia = 2 * radius;
float angle = pcConstraint->Angle.getValue();
SbVec3f b(base.x, base.y, base.z);
SbVec3f dir(axis.x, axis.y, axis.z);
SbRotation rot(SbVec3f(0,-1,0), dir);
updatePlacement(pShapeSep, 0, b, rot);
const SoSeparator* sep = static_cast<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(0,0,dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,sin(angle))));
const SoSeparator* subsep = static_cast<SoSeparator*>(sep->getChild(2));
updateArrow(subsep, 0, dia/2, dia/8);
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
updatePlacement(sep, 0, SbVec3f(0,0,-dia/2), SbRotation(SbVec3f(0,1,0), SbVec3f(cos(angle),0,-sin(angle))));
subsep = static_cast<SoSeparator*>(sep->getChild(2));
updateArrow(subsep, 0, dia/2, 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

@ -57,7 +57,11 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
fem->setCommand("FEM");
*fem << "Fem_CreateFromShape"
<< "Fem_CreateNodesSet"
<< "Fem_Constraint";
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley";
return root;
}
@ -70,7 +74,11 @@ Gui::MenuItem* Workbench::setupMenuBar() const
fem->setCommand("&FEM");
*fem << "Fem_CreateFromShape"
<< "Fem_CreateNodesSet"
<< "Fem_Constraint";
<< "Fem_ConstraintFixed"
<< "Fem_ConstraintForce"
<< "Fem_ConstraintBearing"
<< "Fem_ConstraintGear"
<< "Fem_ConstraintPulley";
return root;
}

View File

@ -1,76 +0,0 @@
# PartDesign gui init module
# (c) 2003 Juergen Riegel
#
# Gathering all the information to start FreeCAD
# This is the second one of three init scripts, the third one
# runs when the gui is up
#***************************************************************************
#* (c) Juergen Riegel (juergen.riegel@web.de) 2002 *
#* *
#* This file is part of the FreeCAD CAx development system. *
#* *
#* This program is free software; you can redistribute it and/or modify *
#* it under the terms of the GNU General Public License (GPL) *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* *
#* FreeCAD is distributed in the hope that it will be useful, *
#* but WITHOUT ANY WARRANTY; without even the implied warranty of *
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
#* GNU Library General Public License for more details. *
#* *
#* You should have received a copy of the GNU Library General Public *
#* License along with FreeCAD; if not, write to the Free Software *
#* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
#* USA *
#* *
#* Juergen Riegel 2002 *
#***************************************************************************/
class PartDesignWorkbench ( Workbench ):
"PartDesign workbench object"
from WizardShaft import WizardShaft
Icon = """
/* XPM */
static char * partdesign_xpm[] = {
"16 16 9 1",
" c None",
". c #040006",
"+ c #070F38",
"@ c #002196",
"# c #0030F3",
"$ c #5A4D20",
"% c #858EB2",
"& c #DEB715",
"* c #BFB99D",
" & ........ ",
"&&&$..@@@@@@+...",
"&&&&$@#####@..@.",
"&&&&&$......@#@.",
"&&&&&&@@@+.###@.",
"$&&&&&&@#@.###@.",
".$&&&&&%#@.###@.",
".@*&&&*%#@.###@.",
".@#*&**%#@.###@.",
".@#@%%%.@@.###@.",
".@@@@@@@#@.###@.",
".@#######@.###@.",
".@#######@.##+. ",
".+@@@####@.@.. ",
" ......+++.. ",
" ... "};
"""
MenuText = "Part Design"
ToolTip = "Part Design workbench"
def Initialize(self):
# load the module
import PartDesignGui
import PartDesign
def GetClassName(self):
return "PartDesignGui::Workbench"
Gui.addWorkbench(PartDesignWorkbench())