Merge pull request #14353 from marioalexis84/fem-constraint_transform
Fem: Cleanup ViewProviderFemConstraint and update constraint transform
This commit is contained in:
@@ -147,18 +147,6 @@ float Constraint::getScaleFactor() const
|
||||
return Scale.getValue() * sizeFactor;
|
||||
}
|
||||
|
||||
void setSubShapeLocation(const Part::Feature* feat, TopoDS_Shape& sh)
|
||||
{
|
||||
// subshape placement is not necessarily the same as the
|
||||
// feature placement.
|
||||
Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation());
|
||||
Base::Placement shPla {matrix};
|
||||
Base::Placement featlPlaInv = feat->Placement.getValue().inverse();
|
||||
Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla;
|
||||
|
||||
sh.Location(Part::Tools::fromPlacement(shGlobalPla));
|
||||
}
|
||||
|
||||
constexpr int CONSTRAINTSTEPLIMIT = 50;
|
||||
|
||||
void Constraint::onChanged(const App::Property* prop)
|
||||
@@ -177,26 +165,20 @@ void Constraint::onChanged(const App::Property* prop)
|
||||
for (std::size_t 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.getShape().IsNull()) {
|
||||
sh = toposhape.getSubShape(SubElements[i].c_str(), !execute);
|
||||
|
||||
if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) {
|
||||
setSubShapeLocation(feat, sh);
|
||||
|
||||
// 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...
|
||||
break;
|
||||
}
|
||||
sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), !execute);
|
||||
if (!sh.IsNull() && 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...
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,22 +256,15 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
|
||||
TopoDS_Shape sh;
|
||||
|
||||
for (std::size_t i = 0; i < Objects.size(); i++) {
|
||||
App::DocumentObject* obj = Objects[i];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sh = toposhape.getSubShape(SubElements[i].c_str(), true);
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(Objects[i]);
|
||||
sh = Tools::getFeatureSubShape(feat, SubElements[i].c_str(), true);
|
||||
if (sh.IsNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setSubShapeLocation(feat, sh);
|
||||
// Scale by bounding box of the object
|
||||
Bnd_Box box;
|
||||
BRepBndLib::Add(toposhape.getShape(), box);
|
||||
BRepBndLib::Add(feat->Shape.getShape().getShape(), box);
|
||||
double l = sqrt(box.SquareExtent() / 3.0);
|
||||
*scale = this->calcSizeFactor(l);
|
||||
|
||||
@@ -471,40 +446,6 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Constraint::getCylinder(double& radius,
|
||||
double& height,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis) const
|
||||
{
|
||||
std::vector<App::DocumentObject*> Objects = References.getValues();
|
||||
std::vector<std::string> SubElements = References.getSubValues();
|
||||
if (Objects.empty()) {
|
||||
return false;
|
||||
}
|
||||
App::DocumentObject* obj = Objects[0];
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(obj);
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return false;
|
||||
}
|
||||
TopoDS_Shape sh = toposhape.getSubShape(SubElements[0].c_str());
|
||||
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
gp_Cylinder cyl = surface.Cylinder();
|
||||
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
|
||||
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
|
||||
height = start.Distance(end);
|
||||
radius = cyl.Radius();
|
||||
|
||||
gp_Pnt b = cyl.Location();
|
||||
base = Base::Vector3d(b.X(), b.Y(), b.Z());
|
||||
gp_Dir dir = cyl.Axis().Direction();
|
||||
axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Base::Vector3d Constraint::getBasePoint(const Base::Vector3d& base,
|
||||
const Base::Vector3d& axis,
|
||||
const App::PropertyLinkSub& location,
|
||||
|
||||
@@ -198,16 +198,6 @@ protected:
|
||||
std::vector<Base::Vector3d>& normals,
|
||||
double* scale) const;
|
||||
|
||||
/**
|
||||
* @brief Extract properties of cylindrical face.
|
||||
*
|
||||
* @note
|
||||
* This method is very specific and doesn't require access to member
|
||||
* variables. It should be rewritten at a different place.
|
||||
*/
|
||||
bool
|
||||
getCylinder(double& radius, double& height, Base::Vector3d& base, Base::Vector3d& axis) const;
|
||||
|
||||
/**
|
||||
* @brief Calculate point of cylindrical face where to render widget.
|
||||
*
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "FemConstraintBearing.h"
|
||||
|
||||
#include "FemTools.h"
|
||||
|
||||
using namespace Fem;
|
||||
|
||||
@@ -74,9 +74,17 @@ void ConstraintBearing::onChanged(const App::Property* prop)
|
||||
|
||||
if (prop == &References) {
|
||||
// Find data of cylinder
|
||||
std::vector<App::DocumentObject*> ref = References.getValues();
|
||||
std::vector<std::string> subRef = References.getSubValues();
|
||||
if (ref.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(ref.front());
|
||||
TopoDS_Shape sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true);
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!getCylinder(radius, height, base, axis)) {
|
||||
if (!Tools::getCylinderParams(sh, base, axis, height, radius)) {
|
||||
return;
|
||||
}
|
||||
Radius.setValue(radius);
|
||||
@@ -113,12 +121,19 @@ void ConstraintBearing::onChanged(const App::Property* prop)
|
||||
}
|
||||
}
|
||||
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!getCylinder(radius, height, base, axis)) {
|
||||
std::vector<App::DocumentObject*> ref = References.getValues();
|
||||
std::vector<std::string> subRef = References.getSubValues();
|
||||
if (ref.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
feat = static_cast<Part::Feature*>(ref.front());
|
||||
sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true);
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!Tools::getCylinderParams(sh, base, axis, height, radius)) {
|
||||
return;
|
||||
}
|
||||
base = getBasePoint(base + axis * height / 2, axis, Location, Dist.getValue());
|
||||
BasePoint.setValue(base);
|
||||
BasePoint.touch();
|
||||
}
|
||||
|
||||
@@ -23,8 +23,10 @@
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#include "FemConstraintTransform.h"
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
|
||||
#include "FemConstraintTransform.h"
|
||||
#include "FemTools.h"
|
||||
|
||||
using namespace Fem;
|
||||
|
||||
@@ -34,9 +36,11 @@ static const char* TransformTypes[] = {"Cylindrical", "Rectangular", nullptr};
|
||||
|
||||
ConstraintTransform::ConstraintTransform()
|
||||
{
|
||||
ADD_PROPERTY(X_rot, (0.0));
|
||||
ADD_PROPERTY(Y_rot, (0.0));
|
||||
ADD_PROPERTY(Z_rot, (0.0));
|
||||
ADD_PROPERTY_TYPE(Rotation,
|
||||
(Base::Rotation(0.0, 0.0, 0.0, 1.0)),
|
||||
"ConstraintTransform",
|
||||
App::Prop_Output,
|
||||
"Rectangular system transform");
|
||||
ADD_PROPERTY_TYPE(TransformType,
|
||||
(1),
|
||||
"ConstraintTransform",
|
||||
@@ -78,54 +82,141 @@ const char* ConstraintTransform::getViewProviderName() const
|
||||
return "FemGui::ViewProviderFemConstraintTransform";
|
||||
}
|
||||
|
||||
void ConstraintTransform::handleChangedPropertyType(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
App::Property* prop)
|
||||
{
|
||||
// properties _rot had App::PropertyFloat and were changed to App::PropertyAngle
|
||||
if (prop == &X_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat X_rotProperty;
|
||||
X_rotProperty.Restore(reader);
|
||||
X_rot.setValue(X_rotProperty.getValue());
|
||||
}
|
||||
else if (prop == &Y_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat Y_rotProperty;
|
||||
Y_rotProperty.Restore(reader);
|
||||
Y_rot.setValue(Y_rotProperty.getValue());
|
||||
}
|
||||
else if (prop == &Z_rot && strcmp(TypeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat Z_rotProperty;
|
||||
Z_rotProperty.Restore(reader);
|
||||
Z_rot.setValue(Z_rotProperty.getValue());
|
||||
}
|
||||
else {
|
||||
Constraint::handleChangedPropertyType(reader, TypeName, prop);
|
||||
}
|
||||
}
|
||||
|
||||
void ConstraintTransform::onChanged(const App::Property* prop)
|
||||
{
|
||||
Constraint::onChanged(prop);
|
||||
|
||||
if (prop == &References) {
|
||||
std::vector<Base::Vector3d> points;
|
||||
std::vector<Base::Vector3d> normals;
|
||||
double scale = 1; // OvG: Enforce use of scale
|
||||
if (getPoints(points, normals, &scale)) {
|
||||
std::string transform_type = TransformType.getValueAsString();
|
||||
if (transform_type == "Cylindrical") {
|
||||
// Find data of cylinder
|
||||
double radius, height;
|
||||
Base::Vector3d base, axis;
|
||||
if (!getCylinder(radius, height, base, axis)) {
|
||||
return;
|
||||
}
|
||||
Axis.setValue(axis);
|
||||
// Update base point
|
||||
base = base + axis * height / 2;
|
||||
BasePoint.setValue(base);
|
||||
BasePoint.touch(); // This triggers ViewProvider::updateData()
|
||||
std::string transform_type = TransformType.getValueAsString();
|
||||
if (transform_type == "Cylindrical") {
|
||||
// Extract geometry from References
|
||||
std::vector<App::DocumentObject*> ref = References.getValues();
|
||||
std::vector<std::string> subRef = References.getSubValues();
|
||||
if (ref.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Part::Feature* feat = static_cast<Part::Feature*>(ref.front());
|
||||
TopoDS_Shape sh = Tools::getFeatureSubShape(feat, subRef.front().c_str(), true);
|
||||
|
||||
Base::Vector3d axis, base;
|
||||
double height, radius;
|
||||
if (!Tools::getCylinderParams(sh, base, axis, height, radius)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BasePoint.setValue(base);
|
||||
Axis.setValue(axis);
|
||||
}
|
||||
}
|
||||
|
||||
Constraint::onChanged(prop);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Base::Rotation anglesToRotation(double xAngle, double yAngle, double zAngle)
|
||||
{
|
||||
static Base::Vector3d a(1, 0, 0);
|
||||
static Base::Vector3d b(0, 1, 0);
|
||||
static int count = 0;
|
||||
double xRad = xAngle * D_PI / 180.0;
|
||||
double yRad = yAngle * D_PI / 180.0;
|
||||
double zRad = zAngle * D_PI / 180.0;
|
||||
if (xAngle != 0) {
|
||||
a[1] = 0;
|
||||
a[2] = 0;
|
||||
b[1] = std::cos(xRad);
|
||||
b[2] = -std::sin(xRad);
|
||||
}
|
||||
if (yAngle != 0) {
|
||||
a[0] = std::cos(yRad);
|
||||
a[2] = std::sin(yRad);
|
||||
b[0] = 0;
|
||||
b[2] = 0;
|
||||
}
|
||||
if (zAngle != 0) {
|
||||
a[0] = std::cos(zRad);
|
||||
a[1] = -std::sin(zRad);
|
||||
b[0] = 0;
|
||||
b[1] = 0;
|
||||
}
|
||||
|
||||
++count;
|
||||
count %= 3;
|
||||
if (!count) {
|
||||
Base::Vector3d X = a.Normalize();
|
||||
Base::Vector3d Y = b.Normalize();
|
||||
Base::Vector3d Z = X.Cross(Y);
|
||||
Z.Normalize();
|
||||
Y = Z.Cross(X);
|
||||
|
||||
a.x = 1;
|
||||
a.y = 0;
|
||||
a.z = 0;
|
||||
b.x = 0;
|
||||
b.y = 1;
|
||||
b.z = 0;
|
||||
|
||||
Base::Matrix4D m;
|
||||
m.setCol(0, X);
|
||||
m.setCol(1, Y);
|
||||
m.setCol(2, Z);
|
||||
|
||||
return Base::Rotation(m);
|
||||
}
|
||||
return Base::Rotation();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
void ConstraintTransform::handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* typeName,
|
||||
const char* propName)
|
||||
{
|
||||
if (strcmp(propName, "X_rot") == 0) {
|
||||
double xAngle;
|
||||
if (strcmp(typeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat X_rotProperty;
|
||||
X_rotProperty.Restore(reader);
|
||||
xAngle = X_rotProperty.getValue();
|
||||
}
|
||||
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
|
||||
App::PropertyAngle X_rotProperty;
|
||||
X_rotProperty.Restore(reader);
|
||||
xAngle = X_rotProperty.getValue();
|
||||
}
|
||||
anglesToRotation(xAngle, 0, 0);
|
||||
}
|
||||
else if (strcmp(propName, "Y_rot") == 0) {
|
||||
double yAngle;
|
||||
if (strcmp(typeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat Y_rotProperty;
|
||||
Y_rotProperty.Restore(reader);
|
||||
yAngle = Y_rotProperty.getValue();
|
||||
}
|
||||
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
|
||||
App::PropertyAngle Y_rotProperty;
|
||||
Y_rotProperty.Restore(reader);
|
||||
yAngle = Y_rotProperty.getValue();
|
||||
}
|
||||
anglesToRotation(0, yAngle, 0);
|
||||
}
|
||||
else if (strcmp(propName, "Z_rot") == 0) {
|
||||
double zAngle;
|
||||
if (strcmp(typeName, "App::PropertyFloat") == 0) {
|
||||
App::PropertyFloat Z_rotProperty;
|
||||
Z_rotProperty.Restore(reader);
|
||||
zAngle = Z_rotProperty.getValue();
|
||||
}
|
||||
else if (strcmp(typeName, "App::PropertyAngle") == 0) {
|
||||
App::PropertyAngle Z_rotProperty;
|
||||
Z_rotProperty.Restore(reader);
|
||||
zAngle = Z_rotProperty.getValue();
|
||||
}
|
||||
Rotation.setValue(anglesToRotation(0, 0, zAngle));
|
||||
}
|
||||
else {
|
||||
Constraint::handleChangedPropertyName(reader, typeName, propName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,12 +42,9 @@ public:
|
||||
App::PropertyLinkList NameDispl;
|
||||
App::PropertyVector BasePoint;
|
||||
App::PropertyVector Axis;
|
||||
App::PropertyAngle X_rot;
|
||||
App::PropertyAngle Y_rot;
|
||||
App::PropertyAngle Z_rot;
|
||||
|
||||
App::PropertyRotation Rotation;
|
||||
App::PropertyEnumeration TransformType;
|
||||
// etc
|
||||
/* */
|
||||
|
||||
/// recalculate the object
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
@@ -56,9 +53,9 @@ public:
|
||||
const char* getViewProviderName() const override;
|
||||
|
||||
protected:
|
||||
void handleChangedPropertyType(Base::XMLReader& reader,
|
||||
const char* TypeName,
|
||||
App::Property* prop) override;
|
||||
void handleChangedPropertyName(Base::XMLReader& reader,
|
||||
const char* typeName,
|
||||
const char* propName) override;
|
||||
void onChanged(const App::Property* prop) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -27,16 +27,19 @@
|
||||
|
||||
#include <BRepAdaptor_Curve.hxx>
|
||||
#include <BRepAdaptor_Surface.hxx>
|
||||
#include <GeomAPI_ProjectPointOnCurve.hxx>
|
||||
#include <Geom_BSplineCurve.hxx>
|
||||
#include <Geom_BSplineSurface.hxx>
|
||||
#include <Geom_BezierCurve.hxx>
|
||||
#include <Geom_BezierSurface.hxx>
|
||||
#include <Geom_Line.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <TColgp_Array2OfPnt.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Edge.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Cylinder.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Lin.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
@@ -44,6 +47,8 @@
|
||||
#endif
|
||||
|
||||
#include <App/Application.h>
|
||||
#include <Mod/Part/App/PartFeature.h>
|
||||
#include <Mod/Part/App/Tools.h>
|
||||
|
||||
#include "FemTools.h"
|
||||
|
||||
@@ -322,3 +327,74 @@ std::string Fem::Tools::checkIfBinaryExists(std::string prefSection,
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
Base::Placement Fem::Tools::getSubShapeGlobalLocation(const Part::Feature* feat,
|
||||
const TopoDS_Shape& sh)
|
||||
{
|
||||
Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation());
|
||||
Base::Placement shPla {matrix};
|
||||
Base::Placement featlPlaInv = feat->Placement.getValue().inverse();
|
||||
Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla;
|
||||
|
||||
return shGlobalPla;
|
||||
}
|
||||
|
||||
void Fem::Tools::setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh)
|
||||
{
|
||||
Base::Placement pla = getSubShapeGlobalLocation(feat, sh);
|
||||
sh.Location(Part::Tools::fromPlacement(pla));
|
||||
}
|
||||
|
||||
|
||||
TopoDS_Shape
|
||||
Fem::Tools::getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent)
|
||||
{
|
||||
TopoDS_Shape sh;
|
||||
const Part::TopoShape& toposhape = feat->Shape.getShape();
|
||||
if (toposhape.isNull()) {
|
||||
return sh;
|
||||
}
|
||||
|
||||
sh = toposhape.getSubShape(subName, silent);
|
||||
if (sh.IsNull()) {
|
||||
return sh;
|
||||
}
|
||||
|
||||
setSubShapeGlobalLocation(feat, sh);
|
||||
|
||||
return sh;
|
||||
}
|
||||
|
||||
bool Fem::Tools::getCylinderParams(const TopoDS_Shape& sh,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis,
|
||||
double& height,
|
||||
double& radius)
|
||||
{
|
||||
TopoDS_Face face = TopoDS::Face(sh);
|
||||
BRepAdaptor_Surface surface(face);
|
||||
if (!(surface.GetType() == GeomAbs_Cylinder)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Cylinder cyl = surface.Cylinder();
|
||||
gp_Pnt start = surface.Value(surface.FirstUParameter(), surface.FirstVParameter());
|
||||
gp_Pnt end = surface.Value(surface.FirstUParameter(), surface.LastVParameter());
|
||||
|
||||
Handle(Geom_Curve) handle = new Geom_Line(cyl.Axis());
|
||||
GeomAPI_ProjectPointOnCurve proj(start, handle);
|
||||
gp_XYZ startProj = proj.NearestPoint().XYZ();
|
||||
proj.Perform(end);
|
||||
gp_XYZ endProj = proj.NearestPoint().XYZ();
|
||||
|
||||
gp_XYZ ax(endProj - startProj);
|
||||
gp_XYZ center = (startProj + endProj) / 2.0;
|
||||
gp_Dir dir(ax);
|
||||
|
||||
height = ax.Modulus();
|
||||
radius = cyl.Radius();
|
||||
base = Base::Vector3d(center.X(), center.Y(), center.Z());
|
||||
axis = Base::Vector3d(dir.X(), dir.Y(), dir.Z());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -24,14 +24,22 @@
|
||||
#ifndef FEM_TOOLS_H
|
||||
#define FEM_TOOLS_H
|
||||
|
||||
#include <Base/Placement.h>
|
||||
#include <Base/Vector3D.h>
|
||||
#include <Mod/Fem/FemGlobal.h>
|
||||
#include <gp_XYZ.hxx>
|
||||
#include <TopoDS_Shape.hxx>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class TopoDS_Edge;
|
||||
class TopoDS_Face;
|
||||
|
||||
namespace Part
|
||||
{
|
||||
|
||||
class Feature;
|
||||
|
||||
}
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
@@ -75,6 +83,27 @@ public:
|
||||
static std::string checkIfBinaryExists(std::string prefSection,
|
||||
std::string prefBinaryPath,
|
||||
std::string prefBinaryName);
|
||||
|
||||
/*!
|
||||
Subshape placement is not necessarily the same as the
|
||||
feature placement
|
||||
*/
|
||||
static Base::Placement getSubShapeGlobalLocation(const Part::Feature* feat,
|
||||
const TopoDS_Shape& sh);
|
||||
static void setSubShapeGlobalLocation(const Part::Feature* feat, TopoDS_Shape& sh);
|
||||
/*!
|
||||
Get subshape from Part Feature. The subShape is returned with global location
|
||||
*/
|
||||
static TopoDS_Shape
|
||||
getFeatureSubShape(const Part::Feature* feat, const char* subName, bool silent);
|
||||
/*!
|
||||
Get cylinder parameters. Base is located at the center of the cylinder
|
||||
*/
|
||||
static bool getCylinderParams(const TopoDS_Shape& sh,
|
||||
Base::Vector3d& base,
|
||||
Base::Vector3d& axis,
|
||||
double& height,
|
||||
double& radius);
|
||||
};
|
||||
|
||||
} // namespace Fem
|
||||
|
||||
@@ -305,6 +305,8 @@ SET(FemGui_SRCS_Module
|
||||
ActiveAnalysisObserver.cpp
|
||||
ActiveAnalysisObserver.h
|
||||
Command.cpp
|
||||
FemGuiTools.cpp
|
||||
FemGuiTools.h
|
||||
FemSettings.cpp
|
||||
FemSettings.h
|
||||
Resources/Fem.qrc
|
||||
@@ -364,6 +366,7 @@ SET(FemGuiSymbol_IV
|
||||
Resources/symbols/ConstraintSectionPrint.iv
|
||||
Resources/symbols/ConstraintSpring.iv
|
||||
Resources/symbols/ConstraintTemperature.iv
|
||||
Resources/symbols/ConstraintTransform.iv
|
||||
Resources/symbols/ConstraintTie.iv
|
||||
)
|
||||
|
||||
|
||||
@@ -1002,9 +1002,6 @@ void CmdFemConstraintTransform::activated(int)
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().addObject(\"Fem::ConstraintTransform\",\"%s\")",
|
||||
FeatName.c_str());
|
||||
doCommand(Doc, "App.activeDocument().%s.X_rot = 0.0", FeatName.c_str());
|
||||
doCommand(Doc, "App.activeDocument().%s.Y_rot = 0.0", FeatName.c_str());
|
||||
doCommand(Doc, "App.activeDocument().%s.Z_rot = 0.0", FeatName.c_str());
|
||||
doCommand(Doc, "App.activeDocument().%s.Scale = 1", FeatName.c_str());
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().%s.addObject(App.activeDocument().%s)",
|
||||
|
||||
206
src/Mod/Fem/Gui/FemGuiTools.cpp
Normal file
206
src/Mod/Fem/Gui/FemGuiTools.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/***************************************************************************
|
||||
* 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 <Inventor/nodes/SoCone.h>
|
||||
#include <Inventor/nodes/SoCube.h>
|
||||
#include <Inventor/nodes/SoCylinder.h>
|
||||
#include <Inventor/nodes/SoTranslation.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoRotation.h>
|
||||
#endif
|
||||
|
||||
#include "FemGuiTools.h"
|
||||
|
||||
|
||||
namespace FemGui::GuiTools
|
||||
{
|
||||
|
||||
#define PLACEMENT_CHILDREN 2
|
||||
#define CONE_CHILDREN 2
|
||||
|
||||
void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r)
|
||||
{
|
||||
SoTranslation* trans = new SoTranslation();
|
||||
trans->translation.setValue(base);
|
||||
sep->addChild(trans);
|
||||
SoRotation* rot = new SoRotation();
|
||||
rot->rotation.setValue(r);
|
||||
sep->addChild(rot);
|
||||
}
|
||||
|
||||
void updatePlacement(const SoSeparator* sep,
|
||||
const int idx,
|
||||
const SbVec3f& base,
|
||||
const SbRotation& r)
|
||||
{
|
||||
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
|
||||
trans->translation.setValue(base);
|
||||
SoRotation* rot = static_cast<SoRotation*>(sep->getChild(idx + 1));
|
||||
rot->rotation.setValue(r);
|
||||
}
|
||||
|
||||
void createCone(SoSeparator* sep, const double height, const double radius)
|
||||
{
|
||||
// Adjust cone so that the tip is on base
|
||||
SoTranslation* trans = new SoTranslation();
|
||||
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
|
||||
sep->addChild(trans);
|
||||
SoCone* cone = new SoCone();
|
||||
cone->height.setValue(height);
|
||||
cone->bottomRadius.setValue(radius);
|
||||
sep->addChild(cone);
|
||||
}
|
||||
|
||||
SoSeparator* createCone(const double height, const double radius)
|
||||
{
|
||||
// Create a new cone node
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createCone(sep, height, radius);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void updateCone(const SoNode* node, const int idx, const double height, const double radius)
|
||||
{
|
||||
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
|
||||
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
|
||||
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
|
||||
SoCone* cone = static_cast<SoCone*>(sep->getChild(idx + 1));
|
||||
cone->height.setValue(height);
|
||||
cone->bottomRadius.setValue(radius);
|
||||
}
|
||||
|
||||
void createCylinder(SoSeparator* sep, const double height, const double radius)
|
||||
{
|
||||
SoCylinder* cyl = new SoCylinder();
|
||||
cyl->height.setValue(height);
|
||||
cyl->radius.setValue(radius);
|
||||
sep->addChild(cyl);
|
||||
}
|
||||
|
||||
SoSeparator* createCylinder(const double height, const double radius)
|
||||
{
|
||||
// Create a new cylinder node
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createCylinder(sep, height, radius);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void 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);
|
||||
}
|
||||
|
||||
void createCube(SoSeparator* sep, const double width, const double length, const double height)
|
||||
{
|
||||
SoCube* cube = new SoCube();
|
||||
cube->width.setValue(width);
|
||||
cube->depth.setValue(length);
|
||||
cube->height.setValue(height);
|
||||
sep->addChild(cube);
|
||||
}
|
||||
|
||||
SoSeparator* createCube(const double width, const double length, const double height)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createCube(sep, width, length, height);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void 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);
|
||||
}
|
||||
|
||||
void 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* createArrow(const double length, const double radius)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createArrow(sep, length, radius);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void 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);
|
||||
}
|
||||
|
||||
void 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* createFixed(const double height, const double width, const bool gap)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createFixed(sep, height, width, gap);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void 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);
|
||||
}
|
||||
|
||||
} // namespace FemGui::GuiTools
|
||||
74
src/Mod/Fem/Gui/FemGuiTools.h
Normal file
74
src/Mod/Fem/Gui/FemGuiTools.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer *
|
||||
* <jrheinlaender@users.sourceforge.net> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FEM_GUI_TOOLS_H
|
||||
#define FEM_GUI_TOOLS_H
|
||||
|
||||
#include <Inventor/SbVec3f.h>
|
||||
#include <Inventor/SbRotation.h>
|
||||
|
||||
|
||||
class SoNode;
|
||||
class SoSeparator;
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
namespace GuiTools
|
||||
{
|
||||
|
||||
void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r);
|
||||
void updatePlacement(const SoSeparator* sep,
|
||||
const int idx,
|
||||
const SbVec3f& base,
|
||||
const SbRotation& r);
|
||||
void createCone(SoSeparator* sep, const double height, const double radius);
|
||||
SoSeparator* createCone(const double height, const double radius);
|
||||
void updateCone(const SoNode* node, const int idx, const double height, const double radius);
|
||||
void createCylinder(SoSeparator* sep, const double height, const double radius);
|
||||
SoSeparator* createCylinder(const double height, const double radius);
|
||||
void updateCylinder(const SoNode* node, const int idx, const double height, const double radius);
|
||||
void createCube(SoSeparator* sep, const double width, const double length, const double height);
|
||||
SoSeparator* createCube(const double width, const double length, const double height);
|
||||
void updateCube(const SoNode* node,
|
||||
const int idx,
|
||||
const double width,
|
||||
const double length,
|
||||
const double height);
|
||||
void createArrow(SoSeparator* sep, const double length, const double radius);
|
||||
SoSeparator* createArrow(const double length, const double radius);
|
||||
void updateArrow(const SoNode* node, const int idx, const double length, const double radius);
|
||||
void createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false);
|
||||
SoSeparator* createFixed(const double height, const double width, const bool gap = false);
|
||||
void updateFixed(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
|
||||
} // namespace GuiTools
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
|
||||
#endif // FEM_GUI_TOOLS_H
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
|
||||
143
src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv
Normal file
143
src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv
Normal file
@@ -0,0 +1,143 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
#/***************************************************************************
|
||||
# * Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
# * *
|
||||
# * This file is part of FreeCAD. *
|
||||
# * *
|
||||
# * FreeCAD is free software: you can redistribute it and/or modify it *
|
||||
# * under the terms of the GNU Lesser General Public License as *
|
||||
# * published by the Free Software Foundation, either version 2.1 of the *
|
||||
# * License, or (at your option) any later version. *
|
||||
# * *
|
||||
# * 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 *
|
||||
# * Lesser General Public License for more details. *
|
||||
# * *
|
||||
# * You should have received a copy of the GNU Lesser General Public *
|
||||
# * License along with FreeCAD. If not, see *
|
||||
# * <https://www.gnu.org/licenses/>. *
|
||||
# * *
|
||||
# **************************************************************************
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
Separator {
|
||||
DEF REC_TRANSFORM Switch {
|
||||
Separator {
|
||||
|
||||
BaseColor {
|
||||
rgb 0.0 1.0 0.0
|
||||
|
||||
}
|
||||
DEF AXIS Separator {
|
||||
|
||||
Translation {
|
||||
translation 0 2.5 0
|
||||
|
||||
}
|
||||
Cone {
|
||||
bottomRadius 0.4
|
||||
height 1.0
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 -1.5 0
|
||||
|
||||
}
|
||||
Cylinder {
|
||||
radius 0.15
|
||||
height 2.0
|
||||
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
|
||||
BaseColor {
|
||||
rgb 1.0 0.0 0.0
|
||||
|
||||
}
|
||||
Rotation {
|
||||
rotation 0 0 1 -1.5707964
|
||||
|
||||
}
|
||||
USE AXIS
|
||||
}
|
||||
|
||||
Separator {
|
||||
|
||||
BaseColor {
|
||||
rgb 0.0 0.0 1.0
|
||||
|
||||
}
|
||||
Rotation {
|
||||
rotation 1 0 0 1.5707964
|
||||
|
||||
}
|
||||
USE AXIS
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
|
||||
BaseColor {
|
||||
rgb 1.0 0.0 0.0
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 2.5 0
|
||||
|
||||
}
|
||||
Cone {
|
||||
bottomRadius 0.4
|
||||
height 1.0
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 -1.5 0
|
||||
|
||||
}
|
||||
Cylinder {
|
||||
radius 0.15
|
||||
height 2.0
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
|
||||
Switch {
|
||||
|
||||
Separator {
|
||||
|
||||
BaseColor {
|
||||
rgb 0.0 0.0 1.0
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 12.0 0
|
||||
|
||||
}
|
||||
Cone {
|
||||
bottomRadius 0.4
|
||||
height 1.0
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 -12.5 0
|
||||
|
||||
}
|
||||
Cylinder {
|
||||
radius 0.15
|
||||
height 24.0
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,18 +88,22 @@ TaskFemConstraintTransform::TaskFemConstraintTransform(
|
||||
connect(ui->rb_rect, &QRadioButton::clicked, this, &TaskFemConstraintTransform::Rect);
|
||||
connect(ui->rb_cylin, &QRadioButton::clicked, this, &TaskFemConstraintTransform::Cyl);
|
||||
|
||||
connect(ui->sp_X,
|
||||
connect(ui->spb_rot_axis_x,
|
||||
qOverload<double>(&DoubleSpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::xAxisChanged);
|
||||
connect(ui->spb_rot_axis_y,
|
||||
qOverload<double>(&DoubleSpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::yAxisChanged);
|
||||
connect(ui->spb_rot_axis_z,
|
||||
qOverload<double>(&DoubleSpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::zAxisChanged);
|
||||
connect(ui->qsb_rot_angle,
|
||||
qOverload<double>(&QuantitySpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::x_Changed);
|
||||
connect(ui->sp_Y,
|
||||
qOverload<double>(&QuantitySpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::y_Changed);
|
||||
connect(ui->sp_Z,
|
||||
qOverload<double>(&QuantitySpinBox::valueChanged),
|
||||
this,
|
||||
&TaskFemConstraintTransform::z_Changed);
|
||||
&TaskFemConstraintTransform::angleChanged);
|
||||
|
||||
// Get the feature data
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
@@ -109,9 +113,33 @@ TaskFemConstraintTransform::TaskFemConstraintTransform(
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
|
||||
// Fill data into dialog elements
|
||||
ui->sp_X->setValue(pcConstraint->X_rot.getQuantityValue());
|
||||
ui->sp_Y->setValue(pcConstraint->Y_rot.getQuantityValue());
|
||||
ui->sp_Z->setValue(pcConstraint->Z_rot.getQuantityValue());
|
||||
Base::Vector3d axis;
|
||||
double angle;
|
||||
pcConstraint->Rotation.getValue().getValue(axis, angle);
|
||||
ui->spb_rot_axis_x->setValue(axis.x);
|
||||
ui->spb_rot_axis_y->setValue(axis.y);
|
||||
ui->spb_rot_axis_z->setValue(axis.z);
|
||||
Base::Quantity rotAngle(angle, QString::fromUtf8("rad"));
|
||||
ui->qsb_rot_angle->setValue(rotAngle.getValueAs(Base::Quantity::Degree));
|
||||
|
||||
ui->spb_rot_axis_x->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.x")));
|
||||
ui->spb_rot_axis_y->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.y")));
|
||||
ui->spb_rot_axis_z->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Axis.z")));
|
||||
ui->qsb_rot_angle->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("Rotation.Angle")));
|
||||
|
||||
ui->spb_rot_axis_x->setMinimum(-FLOAT_MAX);
|
||||
ui->spb_rot_axis_x->setMaximum(FLOAT_MAX);
|
||||
ui->spb_rot_axis_y->setMinimum(-FLOAT_MAX);
|
||||
ui->spb_rot_axis_y->setMaximum(FLOAT_MAX);
|
||||
ui->spb_rot_axis_z->setMinimum(-FLOAT_MAX);
|
||||
ui->spb_rot_axis_z->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_rot_angle->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_rot_angle->setMaximum(FLOAT_MAX);
|
||||
|
||||
std::string transform_type = pcConstraint->TransformType.getValueAsString();
|
||||
if (transform_type == "Rectangular") {
|
||||
ui->sw_transform->setCurrentIndex(0);
|
||||
@@ -167,11 +195,6 @@ TaskFemConstraintTransform::TaskFemConstraintTransform(
|
||||
this,
|
||||
&TaskFemConstraintTransform::removeFromSelection);
|
||||
|
||||
// Bind input fields to properties
|
||||
ui->sp_X->bind(pcConstraint->X_rot);
|
||||
ui->sp_Y->bind(pcConstraint->Y_rot);
|
||||
ui->sp_Z->bind(pcConstraint->Z_rot);
|
||||
|
||||
updateUI();
|
||||
|
||||
if ((p == 0) && (!Objects.empty())) {
|
||||
@@ -199,43 +222,40 @@ void TaskFemConstraintTransform::updateUI()
|
||||
}
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::x_Changed(int i)
|
||||
void TaskFemConstraintTransform::xAxisChanged(double x)
|
||||
{
|
||||
(void)x;
|
||||
Base::Rotation rot = getRotation();
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
static_cast<Fem::ConstraintTransform*>(ConstraintView->getObject());
|
||||
double x = i;
|
||||
pcConstraint->X_rot.setValue(x);
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.X_rot = %f", name.c_str(), x);
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
pcConstraint->Rotation.setValue(rot);
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::y_Changed(int i)
|
||||
void TaskFemConstraintTransform::yAxisChanged(double y)
|
||||
{
|
||||
(void)y;
|
||||
Base::Rotation rot = getRotation();
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
static_cast<Fem::ConstraintTransform*>(ConstraintView->getObject());
|
||||
double y = i;
|
||||
pcConstraint->Y_rot.setValue(y);
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Y_rot = %f", name.c_str(), y);
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
pcConstraint->Rotation.setValue(rot);
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::z_Changed(int i)
|
||||
void TaskFemConstraintTransform::zAxisChanged(double z)
|
||||
{
|
||||
(void)z;
|
||||
Base::Rotation rot = getRotation();
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
static_cast<Fem::ConstraintTransform*>(ConstraintView->getObject());
|
||||
double z = i;
|
||||
pcConstraint->Z_rot.setValue(z);
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Doc, "App.ActiveDocument.%s.Z_rot = %f", name.c_str(), z);
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
pcConstraint->Rotation.setValue(rot);
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::angleChanged(double a)
|
||||
{
|
||||
(void)a;
|
||||
Base::Rotation rot = getRotation();
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
static_cast<Fem::ConstraintTransform*>(ConstraintView->getObject());
|
||||
pcConstraint->Rotation.setValue(rot);
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::Rect()
|
||||
@@ -258,9 +278,6 @@ void TaskFemConstraintTransform::Rect()
|
||||
void TaskFemConstraintTransform::Cyl()
|
||||
{
|
||||
ui->sw_transform->setCurrentIndex(1);
|
||||
ui->sp_X->setValue(0);
|
||||
ui->sp_Y->setValue(0);
|
||||
ui->sp_Z->setValue(0);
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.TransformType = %s",
|
||||
@@ -391,35 +408,15 @@ void TaskFemConstraintTransform::addToSelection()
|
||||
updateUI();
|
||||
if (ui->rb_rect->isChecked()) {
|
||||
Base::Vector3d normal = pcConstraint->NormalDirection.getValue();
|
||||
double n = normal.x;
|
||||
double m = normal.y;
|
||||
double l = normal.z;
|
||||
// about Z-axis
|
||||
double about_z;
|
||||
double mag_norm_z = sqrt(n * n + m * m); // normal vector mapped onto XY plane
|
||||
if (mag_norm_z == 0) {
|
||||
about_z = 0;
|
||||
}
|
||||
else {
|
||||
about_z = (-1 * (acos(m / mag_norm_z) * 180 / M_PI) + 180);
|
||||
}
|
||||
if (n > 0) {
|
||||
about_z = about_z * (-1);
|
||||
}
|
||||
// rotation to ZY plane
|
||||
double m_p = n * sin(about_z * M_PI / 180) + m * cos(about_z * M_PI / 180);
|
||||
double l_p = l;
|
||||
// about X-axis
|
||||
double about_x;
|
||||
double mag_norm_x = sqrt(m_p * m_p + l_p * l_p);
|
||||
if (mag_norm_x == 0) {
|
||||
about_x = 0;
|
||||
}
|
||||
else {
|
||||
about_x = -(acos(l_p / mag_norm_x) * 180 / M_PI); // rotation to the Z axis
|
||||
}
|
||||
ui->sp_X->setValue(round(about_x));
|
||||
ui->sp_Z->setValue(round(about_z));
|
||||
Base::Rotation rot(Base::Vector3d(0, 0, 1), normal);
|
||||
Base::Vector3d axis;
|
||||
double angle;
|
||||
rot.getValue(axis, angle);
|
||||
ui->spb_rot_axis_x->setValue(axis.x);
|
||||
ui->spb_rot_axis_y->setValue(axis.y);
|
||||
ui->spb_rot_axis_z->setValue(axis.z);
|
||||
Base::Quantity rotAngle(angle, QString::fromUtf8("rad"));
|
||||
ui->qsb_rot_angle->setValue(rotAngle.getValueAs(Base::Quantity::Degree));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,9 +472,10 @@ void TaskFemConstraintTransform::removeFromSelection()
|
||||
}
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
updateUI();
|
||||
ui->sp_X->setValue(0);
|
||||
ui->sp_Y->setValue(0);
|
||||
ui->sp_Z->setValue(0);
|
||||
ui->spb_rot_axis_x->setValue(0);
|
||||
ui->spb_rot_axis_y->setValue(0);
|
||||
ui->spb_rot_axis_z->setValue(1);
|
||||
ui->qsb_rot_angle->setValue(0);
|
||||
}
|
||||
|
||||
const std::string TaskFemConstraintTransform::getReferences() const
|
||||
@@ -490,6 +488,16 @@ const std::string TaskFemConstraintTransform::getReferences() const
|
||||
return TaskFemConstraint::getReferences(items);
|
||||
}
|
||||
|
||||
Base::Rotation TaskFemConstraintTransform::getRotation() const
|
||||
{
|
||||
double x = ui->spb_rot_axis_x->value();
|
||||
double y = ui->spb_rot_axis_y->value();
|
||||
double z = ui->spb_rot_axis_z->value();
|
||||
double angle = ui->qsb_rot_angle->value().getValueAs(Base::Quantity::Radian);
|
||||
|
||||
return Base::Rotation(Base::Vector3d(x, y, z), angle);
|
||||
}
|
||||
|
||||
void TaskFemConstraintTransform::onReferenceDeleted()
|
||||
{
|
||||
TaskFemConstraintTransform::removeFromSelection();
|
||||
@@ -535,19 +543,6 @@ else:\n\
|
||||
+ showConstr + ".NameDispl = []\n";
|
||||
}
|
||||
|
||||
std::string TaskFemConstraintTransform::get_X_rot() const
|
||||
{
|
||||
return ui->sp_X->value().getSafeUserString().toStdString();
|
||||
}
|
||||
std::string TaskFemConstraintTransform::get_Y_rot() const
|
||||
{
|
||||
return ui->sp_Y->value().getSafeUserString().toStdString();
|
||||
}
|
||||
std::string TaskFemConstraintTransform::get_Z_rot() const
|
||||
{
|
||||
return ui->sp_Z->value().getSafeUserString().toStdString();
|
||||
}
|
||||
|
||||
std::string TaskFemConstraintTransform::get_transform_type() const
|
||||
{
|
||||
std::string transform;
|
||||
@@ -607,27 +602,29 @@ bool TaskDlgFemConstraintTransform::accept()
|
||||
static_cast<const TaskFemConstraintTransform*>(parameter);
|
||||
|
||||
try {
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.X_rot = \"%s\"",
|
||||
name.c_str(),
|
||||
parameters->get_X_rot().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Y_rot = \"%s\"",
|
||||
name.c_str(),
|
||||
parameters->get_Y_rot().c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Z_rot = \"%s\"",
|
||||
name.c_str(),
|
||||
parameters->get_Z_rot().c_str());
|
||||
Base::Rotation rot = parameters->getRotation();
|
||||
Base::Vector3d axis;
|
||||
double angle;
|
||||
rot.getValue(axis, angle);
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Rotation = App.Rotation(App.Vector(%f,% f, %f), Radian=%f)",
|
||||
name.c_str(),
|
||||
axis.x,
|
||||
axis.y,
|
||||
axis.z,
|
||||
angle);
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.TransformType = %s",
|
||||
name.c_str(),
|
||||
parameters->get_transform_type().c_str());
|
||||
std::string scale = parameters->getScale(); // OvG: determine modified scale
|
||||
|
||||
std::string scale = parameters->getScale();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Scale = %s",
|
||||
name.c_str(),
|
||||
scale.c_str()); // OvG: implement modified scale
|
||||
scale.c_str());
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what()));
|
||||
|
||||
@@ -47,9 +47,7 @@ public:
|
||||
QWidget* parent = nullptr);
|
||||
~TaskFemConstraintTransform() override;
|
||||
const std::string getReferences() const override;
|
||||
std::string get_X_rot() const;
|
||||
std::string get_Y_rot() const;
|
||||
std::string get_Z_rot() const;
|
||||
Base::Rotation getRotation() const;
|
||||
std::string get_transform_type() const;
|
||||
static std::string getSurfaceReferences(const std::string showConstr);
|
||||
|
||||
@@ -59,9 +57,10 @@ private Q_SLOTS:
|
||||
void Cyl();
|
||||
void addToSelection();
|
||||
void removeFromSelection();
|
||||
void x_Changed(int x);
|
||||
void y_Changed(int y);
|
||||
void z_Changed(int z);
|
||||
void xAxisChanged(double x);
|
||||
void yAxisChanged(double y);
|
||||
void zAxisChanged(double z);
|
||||
void angleChanged(double a);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* e) override;
|
||||
|
||||
@@ -105,76 +105,84 @@
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Rotation about X-Axis</string>
|
||||
<widget class="QGroupBox" name="groupBox_0">
|
||||
<property name="title">
|
||||
<string>System Rotation</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="horizontalLayout_7">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::DoubleSpinBox" name="spb_rot_axis_x">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.10000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::QuantitySpinBox" name="sp_X">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">deg</string>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::DoubleSpinBox" name="spb_rot_axis_y">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
<property name="singleStep">
|
||||
<double>0.10000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_8">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Rotation about Y-Axis</string>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::DoubleSpinBox" name="spb_rot_axis_z">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.10000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::QuantitySpinBox" name="sp_Y">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">deg</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Rotation about Z-Axis</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::QuantitySpinBox" name="sp_Z">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">deg</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lb_angle">
|
||||
<property name="text">
|
||||
<string>Angle:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_rot_angle">
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">deg</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
@@ -222,6 +230,11 @@
|
||||
<extends>QWidget</extends>
|
||||
<header>Gui/QuantitySpinBox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>Gui::DoubleSpinBox</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>Gui/SpinBox.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer *
|
||||
* <jrheinlaender@users.sourceforge.net> *
|
||||
* Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
@@ -24,17 +25,12 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <Inventor/nodes/SoCone.h>
|
||||
#include <Inventor/nodes/SoCube.h>
|
||||
#include <Inventor/nodes/SoCylinder.h>
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/nodes/SoMultipleCopy.h>
|
||||
#include <Inventor/nodes/SoPickStyle.h>
|
||||
#include <Inventor/nodes/SoRotation.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <Inventor/nodes/SoShapeHints.h>
|
||||
#include <Inventor/nodes/SoTransform.h>
|
||||
#include <Inventor/nodes/SoTranslation.h>
|
||||
#include <QAction>
|
||||
#include <QDockWidget>
|
||||
#include <QMenu>
|
||||
@@ -318,348 +314,7 @@ PyObject* ViewProviderFemConstraint::getPyObject()
|
||||
pyViewObject->IncRef();
|
||||
return pyViewObject;
|
||||
}
|
||||
/*
|
||||
// Create a local coordinate system with the z-axis given in dir
|
||||
void getLocalCoordinateSystem(const SbVec3f& z, SbVec3f& y, SbVec3f& x)
|
||||
{
|
||||
// Find the y axis in an arbitrary direction, normal to z
|
||||
// Conditions:
|
||||
// y1 * z1 + y2 * z2 + y3 * z3 = |y| |z| cos(90°) = 0
|
||||
// |y| = sqrt(y1^2 + y2^2 + y3^2) = 1
|
||||
float z1, z2, z3;
|
||||
z.getValue(z1, z2, z3);
|
||||
float y1, y2, y3;
|
||||
if (fabs(z1) > Precision::Confusion()) {
|
||||
// Choose: y3 = 0
|
||||
// Solution:
|
||||
// y1 * z1 + y2 * z2 = 0
|
||||
// y1 = - z2/z1 y2
|
||||
// sqrt(z2^2/z1^2 y2^2 + y2^2) = 1
|
||||
// y2^2 ( 1 + z2^2/z1^2)) = +-1 -> choose +1 otherwise no solution
|
||||
// y2 = +- sqrt(1 / (1 + z2^2/z1^2))
|
||||
y3 = 0;
|
||||
y2 = sqrt(1 / (1 + z2*z2 / (z1*z1)));
|
||||
y1 = -z2/z1 * y2;
|
||||
// Note: result might be (0, 1, 0)
|
||||
} else if (fabs(z2) > Precision::Confusion()) {
|
||||
// Given: z1 = 0
|
||||
// Choose: y1 = 0
|
||||
// Solution:
|
||||
// y2 * z2 + y3 * z3 = 0
|
||||
// y2 = - z3/z2 y3
|
||||
// sqrt(z3^2/z2^2 y3^3 + y3^2) = 1
|
||||
// y3^2 (1 + z3^2/z2^2)) = +1
|
||||
// y3 = +- sqrt(1 / (1 + z3^2/z2^2))
|
||||
y1 = 0;
|
||||
y3 = sqrt(1 / (1 + z3*z3 / (z2*z2)));
|
||||
y2 = -z3/z2 * y3;
|
||||
// Note: result might be (0, 0, 1)
|
||||
} else if (fabs(z3) > Precision::Confusion()) {
|
||||
// Given: z1 = z2 = 0
|
||||
// Choose the remaining possible axis
|
||||
y1 = 1;
|
||||
y2 = 0;
|
||||
y3 = 0;
|
||||
}
|
||||
|
||||
y = SbVec3f(y1, y2, y3);
|
||||
x = y.cross(z);
|
||||
}
|
||||
*/
|
||||
#define PLACEMENT_CHILDREN 2
|
||||
|
||||
void ViewProviderFemConstraint::createPlacement(SoSeparator* sep,
|
||||
const SbVec3f& base,
|
||||
const SbRotation& r)
|
||||
{
|
||||
SoTranslation* trans = new SoTranslation();
|
||||
trans->translation.setValue(base);
|
||||
sep->addChild(trans);
|
||||
SoRotation* rot = new SoRotation();
|
||||
rot->rotation.setValue(r);
|
||||
sep->addChild(rot);
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::updatePlacement(const SoSeparator* sep,
|
||||
const int idx,
|
||||
const SbVec3f& base,
|
||||
const SbRotation& r)
|
||||
{
|
||||
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
|
||||
trans->translation.setValue(base);
|
||||
SoRotation* rot = static_cast<SoRotation*>(sep->getChild(idx + 1));
|
||||
rot->rotation.setValue(r);
|
||||
}
|
||||
|
||||
#define CONE_CHILDREN 2
|
||||
|
||||
void ViewProviderFemConstraint::createCone(SoSeparator* sep,
|
||||
const double height,
|
||||
const double radius)
|
||||
{
|
||||
// Adjust cone so that the tip is on base
|
||||
SoTranslation* trans = new SoTranslation();
|
||||
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
|
||||
sep->addChild(trans);
|
||||
SoCone* cone = new SoCone();
|
||||
cone->height.setValue(height);
|
||||
cone->bottomRadius.setValue(radius);
|
||||
sep->addChild(cone);
|
||||
}
|
||||
|
||||
SoSeparator* ViewProviderFemConstraint::createCone(const double height, const double radius)
|
||||
{
|
||||
// Create a new cone node
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createCone(sep, height, radius);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::updateCone(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double radius)
|
||||
{
|
||||
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
|
||||
SoTranslation* trans = static_cast<SoTranslation*>(sep->getChild(idx));
|
||||
trans->translation.setValue(SbVec3f(0, -height / 2, 0));
|
||||
SoCone* cone = static_cast<SoCone*>(sep->getChild(idx + 1));
|
||||
cone->height.setValue(height);
|
||||
cone->bottomRadius.setValue(radius);
|
||||
}
|
||||
|
||||
#define CYLINDER_CHILDREN 1
|
||||
|
||||
void ViewProviderFemConstraint::createCylinder(SoSeparator* sep,
|
||||
const double height,
|
||||
const double radius)
|
||||
{
|
||||
SoCylinder* cyl = new SoCylinder();
|
||||
cyl->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->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 SPRING_CHILDREN (CUBE_CHILDREN + PLACEMENT_CHILDREN + CYLINDER_CHILDREN)
|
||||
|
||||
void ViewProviderFemConstraint::createSpring(SoSeparator* sep,
|
||||
const double length,
|
||||
const double width)
|
||||
{
|
||||
createCube(sep, width, width, length / 2);
|
||||
createPlacement(sep, SbVec3f(0, -length / 2, 0), SbRotation());
|
||||
createCylinder(sep, length / 2, width / 4);
|
||||
}
|
||||
|
||||
SoSeparator* ViewProviderFemConstraint::createSpring(const double length, const double width)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createSpring(sep, length, width);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::updateSpring(const SoNode* node,
|
||||
const int idx,
|
||||
const double length,
|
||||
const double width)
|
||||
{
|
||||
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
|
||||
updateCube(sep, idx, width, width, length / 2);
|
||||
updatePlacement(sep, idx + CUBE_CHILDREN, SbVec3f(0, -length / 2, 0), SbRotation());
|
||||
updateCylinder(sep, idx + CUBE_CHILDREN + PLACEMENT_CHILDREN, length / 2, width / 4);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::createDisplacement(SoSeparator* sep,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap)
|
||||
{
|
||||
createCone(sep, height, width);
|
||||
createPlacement(sep,
|
||||
SbVec3f(0, -(height) / 2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0),
|
||||
SbRotation());
|
||||
}
|
||||
|
||||
SoSeparator* ViewProviderFemConstraint::createDisplacement(const double height,
|
||||
const double width,
|
||||
const bool gap)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createDisplacement(sep, height, width, gap);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::updateDisplacement(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);
|
||||
updatePlacement(sep,
|
||||
idx + CONE_CHILDREN,
|
||||
SbVec3f(0, -(height) / 2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0),
|
||||
SbRotation());
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::createRotation(SoSeparator* sep,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap)
|
||||
{
|
||||
createCylinder(sep, width / 2, height / 2);
|
||||
createPlacement(sep,
|
||||
SbVec3f(0, -(height)*2 - width / 8 - (gap ? 1.0 : 0.1) * width / 8, 0),
|
||||
SbRotation());
|
||||
}
|
||||
|
||||
SoSeparator*
|
||||
ViewProviderFemConstraint::createRotation(const double height, const double width, const bool gap)
|
||||
{
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createRotation(sep, height, width, gap);
|
||||
return sep;
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::updateRotation(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap)
|
||||
{
|
||||
const SoSeparator* sep = static_cast<const SoSeparator*>(node);
|
||||
updateCylinder(sep, idx, height / 2, width / 2);
|
||||
updatePlacement(sep,
|
||||
idx + CYLINDER_CHILDREN,
|
||||
SbVec3f(0, -(height)*2 - width / 8 - (gap ? 1.0 : 0.0) * width / 8, 0),
|
||||
SbRotation());
|
||||
}
|
||||
|
||||
QObject* ViewProviderFemConstraint::findChildByName(const QObject* parent, const QString& name)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2013 Jan Rheinländer *
|
||||
* <jrheinlaender@users.sourceforge.net> *
|
||||
* Copyright (c) 2024 Mario Passaglia <mpassaglia[at]cbc.uba.ar> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
@@ -98,67 +99,6 @@ protected:
|
||||
transformSymbol(const Base::Vector3d& point, const Base::Vector3d& normal, SbMatrix& mat) const;
|
||||
virtual void transformExtraSymbol() const;
|
||||
|
||||
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 createSpring(SoSeparator* sep, const double length, const double width);
|
||||
static SoSeparator* createSpring(const double length, const double width);
|
||||
static void
|
||||
updateSpring(const SoNode* node, const int idx, const double length, const double width);
|
||||
static void
|
||||
createFixed(SoSeparator* sep, const double height, const double width, const bool gap = false);
|
||||
static SoSeparator*
|
||||
createFixed(const double height, const double width, const bool gap = false);
|
||||
static void updateFixed(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
static void createDisplacement(SoSeparator* sep,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
static SoSeparator*
|
||||
createDisplacement(const double height, const double width, const bool gap = false);
|
||||
static void updateDisplacement(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
static void createRotation(SoSeparator* sep,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
static SoSeparator*
|
||||
createRotation(const double height, const double width, const bool gap = false);
|
||||
static void updateRotation(const SoNode* node,
|
||||
const int idx,
|
||||
const double height,
|
||||
const double width,
|
||||
const bool gap = false);
|
||||
|
||||
private:
|
||||
bool rotateSymbol;
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#endif
|
||||
|
||||
#include "Gui/Control.h"
|
||||
#include "FemGuiTools.h"
|
||||
#include "TaskFemConstraintBearing.h"
|
||||
#include "ViewProviderFemConstraintBearing.h"
|
||||
#include <Base/Console.h>
|
||||
@@ -131,9 +132,10 @@ void ViewProviderFemConstraintBearing::updateData(const App::Property* prop)
|
||||
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()));
|
||||
GuiTools::createPlacement(pShapeSep, b, rot);
|
||||
pShapeSep->addChild(GuiTools::createFixed(radius / 2,
|
||||
radius / 2 * 1.5,
|
||||
pcConstraint->AxialFree.getValue()));
|
||||
}
|
||||
else if (prop == &pcConstraint->AxialFree) {
|
||||
if (pShapeSep->getNumChildren() > 0) {
|
||||
@@ -147,9 +149,13 @@ void ViewProviderFemConstraintBearing::updateData(const App::Property* prop)
|
||||
SbVec3f dir(normal.x, normal.y, normal.z);
|
||||
SbRotation rot(SbVec3f(0, -1, 0), dir);
|
||||
|
||||
updatePlacement(pShapeSep, 0, b, rot);
|
||||
GuiTools::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());
|
||||
GuiTools::updateFixed(sep,
|
||||
0,
|
||||
radius / 2,
|
||||
radius / 2 * 1.5,
|
||||
pcConstraint->AxialFree.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "Gui/Control.h"
|
||||
#include <Mod/Fem/App/FemConstraintFluidBoundary.h>
|
||||
|
||||
#include "FemGuiTools.h"
|
||||
#include "TaskFemConstraintFluidBoundary.h"
|
||||
#include "ViewProviderFemConstraintFluidBoundary.h"
|
||||
|
||||
@@ -157,7 +158,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro
|
||||
if (pShapeSep->getNumChildren() == 0) {
|
||||
// Set up the nodes
|
||||
cp->matrix.setNum(0);
|
||||
cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling
|
||||
cp->addChild(
|
||||
(SoNode*)GuiTools::createArrow(scaledlength, scaledheadradius)); // OvG: Scaling
|
||||
pShapeSep->addChild(cp);
|
||||
}
|
||||
#endif
|
||||
@@ -199,8 +201,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro
|
||||
idx++;
|
||||
#else
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createPlacement(sep, base, rot);
|
||||
createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling
|
||||
GuiTools::createPlacement(sep, base, rot);
|
||||
GuiTools::createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
#endif
|
||||
}
|
||||
@@ -243,8 +245,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro
|
||||
matrices[idx] = m;
|
||||
#else
|
||||
SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(idx));
|
||||
updatePlacement(sep, 0, base, rot);
|
||||
updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling
|
||||
GuiTools::updatePlacement(sep, 0, base, rot);
|
||||
GuiTools::updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling
|
||||
#endif
|
||||
idx++;
|
||||
}
|
||||
@@ -261,7 +263,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro
|
||||
if (pShapeSep->getNumChildren() == 0) {
|
||||
// Set up the nodes
|
||||
cp->matrix.setNum(0);
|
||||
cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); // OvG: Scaling
|
||||
cp->addChild(
|
||||
(SoNode*)GuiTools::createFixed(scaledheight, scaledwidth)); // OvG: Scaling
|
||||
pShapeSep->addChild(cp);
|
||||
}
|
||||
#endif
|
||||
@@ -295,8 +298,8 @@ void ViewProviderFemConstraintFluidBoundary::updateData(const App::Property* pro
|
||||
idx++;
|
||||
#else
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createPlacement(sep, base, rot);
|
||||
createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling
|
||||
GuiTools::createPlacement(sep, base, rot);
|
||||
GuiTools::createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
#endif
|
||||
n++;
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <Base/Console.h>
|
||||
#include <Mod/Fem/App/FemConstraintGear.h>
|
||||
|
||||
#include "FemGuiTools.h"
|
||||
#include "TaskFemConstraintGear.h"
|
||||
#include "ViewProviderFemConstraintGear.h"
|
||||
|
||||
@@ -139,12 +140,13 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop)
|
||||
// Base::Console().Error("DirectionVector: %f, %f, %f\n", direction.x, direction.y,
|
||||
// direction.z);
|
||||
|
||||
createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax));
|
||||
pShapeSep->addChild(createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2));
|
||||
createPlacement(pShapeSep,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
pShapeSep->addChild(createArrow(dia / 2, dia / 8));
|
||||
GuiTools::createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax));
|
||||
pShapeSep->addChild(
|
||||
GuiTools::createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2));
|
||||
GuiTools::createPlacement(pShapeSep,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
pShapeSep->addChild(GuiTools::createArrow(dia / 2, dia / 8));
|
||||
}
|
||||
}
|
||||
else if (prop == &pcConstraint->Diameter) {
|
||||
@@ -166,13 +168,13 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop)
|
||||
SbVec3f dir(direction.x, direction.y, direction.z);
|
||||
|
||||
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
|
||||
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2);
|
||||
updatePlacement(pShapeSep,
|
||||
3,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
GuiTools::updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2);
|
||||
GuiTools::updatePlacement(pShapeSep,
|
||||
3,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
sep = static_cast<SoSeparator*>(pShapeSep->getChild(5));
|
||||
updateArrow(sep, 0, dia / 2, dia / 8);
|
||||
GuiTools::updateArrow(sep, 0, dia / 2, dia / 8);
|
||||
}
|
||||
}
|
||||
else if ((prop == &pcConstraint->DirectionVector) || (prop == &pcConstraint->ForceAngle)) {
|
||||
@@ -203,10 +205,10 @@ void ViewProviderFemConstraintGear::updateData(const App::Property* prop)
|
||||
directions!)
|
||||
*/
|
||||
|
||||
updatePlacement(pShapeSep,
|
||||
3,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
GuiTools::updatePlacement(pShapeSep,
|
||||
3,
|
||||
SbVec3f(dia / 2 * sin(angle), 0, dia / 2 * cos(angle)),
|
||||
SbRotation(ax, dir));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#endif
|
||||
|
||||
#include "Gui/Control.h"
|
||||
#include "FemGuiTools.h"
|
||||
#include "TaskFemConstraintPulley.h"
|
||||
#include "ViewProviderFemConstraintPulley.h"
|
||||
#include <Mod/Fem/App/FemConstraintPulley.h>
|
||||
@@ -138,32 +139,34 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
|
||||
SbVec3f b(base.x, base.y, base.z);
|
||||
SbVec3f ax(axis.x, axis.y, axis.z);
|
||||
|
||||
createPlacement(pShapeSep, b, SbRotation(SbVec3f(0, 1, 0), ax)); // child 0 and 1
|
||||
pShapeSep->addChild(
|
||||
createCylinder(pcConstraint->Height.getValue() * 0.8, dia / 2)); // child 2
|
||||
GuiTools::createPlacement(pShapeSep,
|
||||
b,
|
||||
SbRotation(SbVec3f(0, 1, 0), ax)); // child 0 and 1
|
||||
pShapeSep->addChild(GuiTools::createCylinder(pcConstraint->Height.getValue() * 0.8,
|
||||
dia / 2)); // child 2
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
createPlacement(sep,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation());
|
||||
sep->addChild(createArrow(dia / 8 + dia / 2 * rat1, dia / 8));
|
||||
GuiTools::createPlacement(sep,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
GuiTools::createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation());
|
||||
sep->addChild(GuiTools::createArrow(dia / 8 + dia / 2 * rat1, dia / 8));
|
||||
pShapeSep->addChild(sep); // child 3
|
||||
sep = new SoSeparator();
|
||||
createPlacement(sep,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation());
|
||||
sep->addChild(createArrow(dia / 8 + dia / 2 * rat2, dia / 8));
|
||||
GuiTools::createPlacement(sep,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
GuiTools::createPlacement(sep, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation());
|
||||
sep->addChild(GuiTools::createArrow(dia / 8 + dia / 2 * rat2, dia / 8));
|
||||
pShapeSep->addChild(sep); // child 4
|
||||
}
|
||||
}
|
||||
@@ -186,33 +189,39 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
|
||||
}
|
||||
|
||||
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(2));
|
||||
updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2);
|
||||
GuiTools::updateCylinder(sep, 0, pcConstraint->Height.getValue() * 0.8, dia / 2);
|
||||
sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
|
||||
updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation());
|
||||
GuiTools::updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
GuiTools::updatePlacement(sep,
|
||||
2,
|
||||
SbVec3f(0, dia / 8 + dia / 2 * rat1, 0),
|
||||
SbRotation());
|
||||
const SoSeparator* subsep = static_cast<SoSeparator*>(sep->getChild(4));
|
||||
updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8);
|
||||
GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8);
|
||||
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
|
||||
updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation());
|
||||
GuiTools::updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
GuiTools::updatePlacement(sep,
|
||||
2,
|
||||
SbVec3f(0, dia / 8 + dia / 2 * rat2, 0),
|
||||
SbRotation());
|
||||
subsep = static_cast<SoSeparator*>(sep->getChild(4));
|
||||
updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8);
|
||||
GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8);
|
||||
}
|
||||
}
|
||||
else if ((prop == &pcConstraint->ForceAngle) || (prop == &pcConstraint->BeltAngle)) {
|
||||
@@ -226,25 +235,25 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
|
||||
double beltAngle = pcConstraint->BeltAngle.getValue();
|
||||
|
||||
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
|
||||
updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
GuiTools::updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(dia / 2 * sin(forceAngle + beltAngle),
|
||||
0,
|
||||
dia / 2 * cos(forceAngle + beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(sin(forceAngle + beltAngle + M_PI_2),
|
||||
0,
|
||||
cos(forceAngle + beltAngle + M_PI_2))));
|
||||
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
|
||||
updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
GuiTools::updatePlacement(sep,
|
||||
0,
|
||||
SbVec3f(-dia / 2 * sin(forceAngle - beltAngle),
|
||||
0,
|
||||
-dia / 2 * cos(forceAngle - beltAngle)),
|
||||
SbRotation(SbVec3f(0, 1, 0),
|
||||
SbVec3f(-sin(forceAngle - beltAngle - M_PI_2),
|
||||
0,
|
||||
-cos(forceAngle - beltAngle - M_PI_2))));
|
||||
}
|
||||
}
|
||||
else if ((prop == &pcConstraint->BeltForce1) || (prop == &pcConstraint->BeltForce2)) {
|
||||
@@ -263,13 +272,19 @@ void ViewProviderFemConstraintPulley::updateData(const App::Property* prop)
|
||||
}
|
||||
|
||||
const SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(3));
|
||||
updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat1, 0), SbRotation());
|
||||
GuiTools::updatePlacement(sep,
|
||||
2,
|
||||
SbVec3f(0, dia / 8 + dia / 2 * rat1, 0),
|
||||
SbRotation());
|
||||
const SoSeparator* subsep = static_cast<SoSeparator*>(sep->getChild(4));
|
||||
updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8);
|
||||
GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat1, dia / 8);
|
||||
sep = static_cast<SoSeparator*>(pShapeSep->getChild(4));
|
||||
updatePlacement(sep, 2, SbVec3f(0, dia / 8 + dia / 2 * rat2, 0), SbRotation());
|
||||
GuiTools::updatePlacement(sep,
|
||||
2,
|
||||
SbVec3f(0, dia / 8 + dia / 2 * rat2, 0),
|
||||
SbRotation());
|
||||
subsep = static_cast<SoSeparator*>(sep->getChild(4));
|
||||
updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8);
|
||||
GuiTools::updateArrow(subsep, 0, dia / 8 + dia / 2 * rat2, dia / 8);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,10 +27,12 @@
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
#include <Inventor/SbMatrix.h>
|
||||
#include <Inventor/SbRotation.h>
|
||||
#include <Inventor/nodes/SoMaterial.h>
|
||||
#include <Inventor/SbVec3f.h>
|
||||
#include <Inventor/nodes/SoSeparator.h>
|
||||
#include <cmath>
|
||||
#include <Inventor/nodes/SoSwitch.h>
|
||||
#include <Inventor/nodes/SoTransform.h>
|
||||
#endif
|
||||
|
||||
#include "Mod/Fem/App/FemConstraintTransform.h"
|
||||
@@ -46,6 +48,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintTransform, FemGui::ViewProvider
|
||||
ViewProviderFemConstraintTransform::ViewProviderFemConstraintTransform()
|
||||
{
|
||||
sPixmap = "FEM_ConstraintTransform";
|
||||
loadSymbol((resourceSymbolDir + "ConstraintTransform.iv").c_str());
|
||||
}
|
||||
|
||||
ViewProviderFemConstraintTransform::~ViewProviderFemConstraintTransform() = default;
|
||||
@@ -91,215 +94,82 @@ bool ViewProviderFemConstraintTransform::setEdit(int ModNum)
|
||||
}
|
||||
}
|
||||
|
||||
#define HEIGHTAXIS (20)
|
||||
#define RADIUSAXIS (0.8)
|
||||
#define ARROWLENGTH (3)
|
||||
#define ARROWHEADRADIUS (ARROWLENGTH / 3)
|
||||
#define LENGTHDISC (0.25)
|
||||
#define RADIUSDISC (0.8)
|
||||
|
||||
void ViewProviderFemConstraintTransform::updateData(const App::Property* prop)
|
||||
{
|
||||
// Gets called whenever a property of the attached object changes
|
||||
Fem::ConstraintTransform* pcConstraint =
|
||||
static_cast<Fem::ConstraintTransform*>(this->getObject());
|
||||
float scaledradiusaxis =
|
||||
RADIUSAXIS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
|
||||
float scaledheightaxis = HEIGHTAXIS * pcConstraint->Scale.getValue();
|
||||
float scaledheadradiusA =
|
||||
ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
|
||||
float scaledlengthA = ARROWLENGTH * pcConstraint->Scale.getValue();
|
||||
std::string transform_type = pcConstraint->TransformType.getValueAsString();
|
||||
if (transform_type == "Rectangular") {
|
||||
auto obj = static_cast<Fem::ConstraintTransform*>(this->getObject());
|
||||
|
||||
if (prop == &pcConstraint->Points) {
|
||||
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
|
||||
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
|
||||
if (points.size() != normals.size()) {
|
||||
return;
|
||||
if (prop == &obj->Rotation) {
|
||||
updateSymbol();
|
||||
}
|
||||
else if (prop == &obj->TransformType || prop == &obj->References) {
|
||||
std::string transType = obj->TransformType.getValueAsString();
|
||||
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(0));
|
||||
auto swExtra = static_cast<SoSwitch*>(getExtraSymbolSeparator()->getChild(0));
|
||||
|
||||
if (transType == "Rectangular") {
|
||||
sw->whichChild.setValue(0);
|
||||
swExtra->whichChild.setValue(-1);
|
||||
}
|
||||
else if (transType == "Cylindrical") {
|
||||
sw->whichChild.setValue(1);
|
||||
if (obj->References.getSize()) {
|
||||
swExtra->whichChild.setValue(0);
|
||||
}
|
||||
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
|
||||
|
||||
// Points and Normals are always updated together
|
||||
Gui::coinRemoveAllChildren(pShapeSep);
|
||||
|
||||
for (const auto& point : points) {
|
||||
SbVec3f base(point.x, point.y, point.z);
|
||||
SbVec3f basex(point.x, point.y, point.z);
|
||||
SbVec3f basey(point.x, point.y, point.z);
|
||||
|
||||
double x_axis_x = 1;
|
||||
double x_axis_y = 0;
|
||||
double x_axis_z = 0;
|
||||
|
||||
double y_axis_x = 0;
|
||||
double y_axis_y = 1;
|
||||
double y_axis_z = 0;
|
||||
|
||||
double z_axis_x = 0;
|
||||
double z_axis_y = 0;
|
||||
double z_axis_z = 1;
|
||||
|
||||
double rot_x = (pcConstraint->X_rot.getValue() * (M_PI / 180));
|
||||
double rot_y = (pcConstraint->Y_rot.getValue() * (M_PI / 180));
|
||||
double rot_z = (pcConstraint->Z_rot.getValue() * (M_PI / 180));
|
||||
|
||||
double x_axis_x_p;
|
||||
double x_axis_y_p;
|
||||
double x_axis_z_p;
|
||||
|
||||
double y_axis_x_p;
|
||||
double y_axis_y_p;
|
||||
double y_axis_z_p;
|
||||
|
||||
double z_axis_x_p;
|
||||
double z_axis_y_p;
|
||||
double z_axis_z_p;
|
||||
|
||||
if (rot_x != 0) {
|
||||
x_axis_z_p = x_axis_z * cos(rot_x) - x_axis_y * sin(rot_x);
|
||||
x_axis_y_p = x_axis_y * cos(rot_x) + x_axis_z * sin(rot_x);
|
||||
x_axis_z = x_axis_z_p;
|
||||
x_axis_y = x_axis_y_p;
|
||||
|
||||
y_axis_z_p = y_axis_z * cos(rot_x) - y_axis_y * sin(rot_x);
|
||||
y_axis_y_p = y_axis_y * cos(rot_x) + y_axis_z * sin(rot_x);
|
||||
y_axis_z = y_axis_z_p;
|
||||
y_axis_y = y_axis_y_p;
|
||||
|
||||
z_axis_z_p = z_axis_z * cos(rot_x) - z_axis_y * sin(rot_x);
|
||||
z_axis_y_p = z_axis_y * cos(rot_x) + z_axis_z * sin(rot_x);
|
||||
z_axis_z = z_axis_z_p;
|
||||
z_axis_y = z_axis_y_p;
|
||||
}
|
||||
if (rot_y != 0) {
|
||||
x_axis_z_p = x_axis_z * cos(rot_y) + x_axis_x * sin(rot_y);
|
||||
x_axis_x_p = x_axis_x * cos(rot_y) - x_axis_z * sin(rot_y);
|
||||
x_axis_z = x_axis_z_p;
|
||||
x_axis_x = x_axis_x_p;
|
||||
|
||||
y_axis_z_p = y_axis_z * cos(rot_y) + y_axis_x * sin(rot_y);
|
||||
y_axis_x_p = y_axis_x * cos(rot_y) - y_axis_z * sin(rot_y);
|
||||
y_axis_z = y_axis_z_p;
|
||||
y_axis_x = y_axis_x_p;
|
||||
|
||||
z_axis_z_p = z_axis_z * cos(rot_y) + z_axis_x * sin(rot_y);
|
||||
z_axis_x_p = z_axis_x * cos(rot_y) - z_axis_z * sin(rot_y);
|
||||
z_axis_z = z_axis_z_p;
|
||||
z_axis_x = z_axis_x_p;
|
||||
}
|
||||
if (rot_z != 0) {
|
||||
x_axis_x_p = x_axis_x * cos(rot_z) + x_axis_y * sin(rot_z);
|
||||
x_axis_y_p = x_axis_y * cos(rot_z) - x_axis_x * sin(rot_z);
|
||||
x_axis_x = x_axis_x_p;
|
||||
x_axis_y = x_axis_y_p;
|
||||
|
||||
y_axis_x_p = y_axis_x * cos(rot_z) + y_axis_y * sin(rot_z);
|
||||
y_axis_y_p = y_axis_y * cos(rot_z) - y_axis_x * sin(rot_z);
|
||||
y_axis_x = y_axis_x_p;
|
||||
y_axis_y = y_axis_y_p;
|
||||
|
||||
z_axis_x_p = z_axis_x * cos(rot_z) + z_axis_y * sin(rot_z);
|
||||
z_axis_y_p = z_axis_y * cos(rot_z) - z_axis_x * sin(rot_z);
|
||||
z_axis_x = z_axis_x_p;
|
||||
z_axis_y = z_axis_y_p;
|
||||
}
|
||||
|
||||
SbVec3f dirz(z_axis_x, z_axis_y, z_axis_z);
|
||||
SbRotation rot(SbVec3f(0, 1, 0), dirz);
|
||||
|
||||
SbVec3f dirx(x_axis_x, x_axis_y, x_axis_z);
|
||||
SbRotation rotx(SbVec3f(0, 1, 0), dirx);
|
||||
|
||||
SbVec3f diry(y_axis_x, y_axis_y, y_axis_z);
|
||||
SbRotation roty(SbVec3f(0, 1, 0), diry);
|
||||
|
||||
base = base + dirz * scaledlengthA * 0.75f;
|
||||
basex = basex + dirx * scaledlengthA * 0.65f;
|
||||
basey = basey + diry * scaledlengthA * 0.65f;
|
||||
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
|
||||
SoMaterial* myMaterial = new SoMaterial;
|
||||
myMaterial->diffuseColor.set1Value(0, SbColor(0, 0, 1)); // RGB
|
||||
sep->addChild(myMaterial);
|
||||
|
||||
createPlacement(sep, base, rot);
|
||||
createArrow(sep, scaledlengthA * 0.75, scaledheadradiusA * 0.9); // OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
|
||||
SoSeparator* sepx = new SoSeparator();
|
||||
|
||||
SoMaterial* myMaterialx = new SoMaterial;
|
||||
myMaterialx->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB
|
||||
sepx->addChild(myMaterialx);
|
||||
|
||||
createPlacement(sepx, basex, rotx);
|
||||
createArrow(sepx, scaledlengthA * 0.65, scaledheadradiusA * 0.65); // OvG: Scaling
|
||||
pShapeSep->addChild(sepx);
|
||||
|
||||
SoSeparator* sepy = new SoSeparator();
|
||||
|
||||
SoMaterial* myMaterialy = new SoMaterial;
|
||||
myMaterialy->diffuseColor.set1Value(0, SbColor(0, 1, 0)); // RGB
|
||||
sepy->addChild(myMaterialy);
|
||||
|
||||
createPlacement(sepy, basey, roty);
|
||||
createArrow(sepy, scaledlengthA * 0.65, scaledheadradiusA * 0.65); // OvG: Scaling
|
||||
pShapeSep->addChild(sepy);
|
||||
|
||||
n++;
|
||||
else {
|
||||
swExtra->whichChild.setValue(-1);
|
||||
}
|
||||
}
|
||||
updateSymbol();
|
||||
}
|
||||
else if (transform_type == "Cylindrical") {
|
||||
|
||||
// Points and Normals are always updated together
|
||||
Gui::coinRemoveAllChildren(pShapeSep);
|
||||
|
||||
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
|
||||
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
|
||||
|
||||
if (points.size() != normals.size()) {
|
||||
return;
|
||||
}
|
||||
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
|
||||
|
||||
if (!points.empty()) {
|
||||
Base::Vector3d base = pcConstraint->BasePoint.getValue();
|
||||
Base::Vector3d axis = pcConstraint->Axis.getValue();
|
||||
|
||||
SbVec3f b(base.x, base.y, base.z);
|
||||
SbVec3f ax(axis.x, axis.y, axis.z);
|
||||
SbRotation rots(SbVec3f(0, -1, 0), ax);
|
||||
|
||||
b = b - ax * scaledheightaxis / 2;
|
||||
SoSeparator* sepAx = new SoSeparator();
|
||||
SoMaterial* myMaterial = new SoMaterial;
|
||||
myMaterial->diffuseColor.set1Value(0, SbColor(0, 0, 1)); // RGB
|
||||
sepAx->addChild(myMaterial);
|
||||
createPlacement(sepAx, b, rots);
|
||||
createArrow(sepAx, scaledheightaxis, scaledradiusaxis);
|
||||
pShapeSep->addChild(sepAx);
|
||||
}
|
||||
|
||||
for (const auto& point : points) {
|
||||
SbVec3f base(point.x, point.y, point.z);
|
||||
SbVec3f dir(n->x, n->y, n->z);
|
||||
base = base + dir * scaledlengthA; // OvG: Scaling
|
||||
SbRotation rot(SbVec3f(0, 1, 0), dir);
|
||||
|
||||
SoSeparator* sep = new SoSeparator();
|
||||
SoMaterial* myMaterials = new SoMaterial;
|
||||
myMaterials->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB
|
||||
sep->addChild(myMaterials);
|
||||
createPlacement(sep, base, rot);
|
||||
createArrow(sep, scaledlengthA, scaledheadradiusA); // OvG: Scaling
|
||||
pShapeSep->addChild(sep);
|
||||
n++;
|
||||
}
|
||||
else if (prop == &obj->BasePoint || prop == &obj->Axis) {
|
||||
updateSymbol();
|
||||
}
|
||||
|
||||
// Gets called whenever a property of the attached object changes
|
||||
ViewProviderFemConstraint::updateData(prop);
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraintTransform::transformSymbol(const Base::Vector3d& point,
|
||||
const Base::Vector3d& normal,
|
||||
SbMatrix& mat) const
|
||||
{
|
||||
auto obj = static_cast<const Fem::ConstraintTransform*>(this->getObject());
|
||||
|
||||
std::string transType = obj->TransformType.getValueAsString();
|
||||
if (transType == "Rectangular") {
|
||||
Base::Rotation rot = obj->Rotation.getValue();
|
||||
Base::Vector3d axis;
|
||||
double angle;
|
||||
rot.getValue(axis, angle);
|
||||
float s = obj->getScaleFactor();
|
||||
|
||||
mat.setTransform(SbVec3f(point.x, point.y, point.z),
|
||||
SbRotation(SbVec3f(axis.x, axis.y, axis.z), angle),
|
||||
SbVec3f(s, s, s));
|
||||
}
|
||||
else if (transType == "Cylindrical") {
|
||||
float s = obj->getScaleFactor();
|
||||
|
||||
mat.setTransform(SbVec3f(point.x, point.y, point.z),
|
||||
SbRotation(SbVec3f(0, 1, 0), SbVec3f(normal.x, normal.y, normal.z)),
|
||||
SbVec3f(s, s, s));
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraintTransform::transformExtraSymbol() const
|
||||
{
|
||||
auto obj = static_cast<const Fem::ConstraintTransform*>(this->getObject());
|
||||
std::string transType = obj->TransformType.getValueAsString();
|
||||
if (transType == "Cylindrical") {
|
||||
SoTransform* trans = getExtraSymbolTransform();
|
||||
Base::Vector3d point = obj->BasePoint.getValue();
|
||||
Base::Vector3d axis = obj->Axis.getValue();
|
||||
float s = obj->getScaleFactor();
|
||||
|
||||
SbMatrix mat;
|
||||
mat.setTransform(SbVec3f(point.x, point.y, point.z),
|
||||
SbRotation(SbVec3f(0, 1, 0), SbVec3f(axis.x, axis.y, axis.z)),
|
||||
SbVec3f(s, s, s));
|
||||
|
||||
trans->setMatrix(mat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,10 @@ public:
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
void transformSymbol(const Base::Vector3d& point,
|
||||
const Base::Vector3d& normal,
|
||||
SbMatrix& mat) const override;
|
||||
void transformExtraSymbol() const override;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
@@ -160,17 +160,11 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
con_transform1 = ObjectsFem.makeConstraintTransform(doc, name="FemConstraintTransform1")
|
||||
con_transform1.References = [(geom_obj, "Face4")]
|
||||
con_transform1.TransformType = "Cylindrical"
|
||||
con_transform1.X_rot = 0.0
|
||||
con_transform1.Y_rot = 0.0
|
||||
con_transform1.Z_rot = 0.0
|
||||
analysis.addObject(con_transform1)
|
||||
|
||||
con_transform2 = ObjectsFem.makeConstraintTransform(doc, name="FemConstraintTransform2")
|
||||
con_transform2.References = [(geom_obj, "Face5")]
|
||||
con_transform2.TransformType = "Cylindrical"
|
||||
con_transform2.X_rot = 0.0
|
||||
con_transform2.Y_rot = 0.0
|
||||
con_transform2.Z_rot = 0.0
|
||||
analysis.addObject(con_transform2)
|
||||
|
||||
# mesh
|
||||
|
||||
@@ -156,9 +156,6 @@ def setup(doc=None, solvertype="ccxtools"):
|
||||
con_transform = ObjectsFem.makeConstraintTransform(doc, name="ConstraintTransform")
|
||||
con_transform.References = [(geom_obj, "Face1")]
|
||||
con_transform.TransformType = "Cylindrical"
|
||||
con_transform.X_rot = 0.0
|
||||
con_transform.Y_rot = 0.0
|
||||
con_transform.Z_rot = 0.0
|
||||
analysis.addObject(con_transform)
|
||||
|
||||
# mesh
|
||||
|
||||
@@ -26,6 +26,8 @@ __author__ = "Bernd Hahnebach"
|
||||
__url__ = "https://www.freecad.org"
|
||||
|
||||
|
||||
import FreeCAD
|
||||
|
||||
from femtools import geomtools
|
||||
|
||||
|
||||
@@ -75,11 +77,15 @@ def write_constraint(f, femobj, trans_obj, ccxwriter):
|
||||
if trans_obj.TransformType == "Rectangular":
|
||||
trans_name = "Rect"
|
||||
trans_type = "R"
|
||||
coords = geomtools.get_rectangular_coords(trans_obj)
|
||||
x = trans_obj.Rotation * FreeCAD.Vector(1, 0, 0)
|
||||
y = trans_obj.Rotation * FreeCAD.Vector(0, 1, 0)
|
||||
coords = list(x) + list(y)
|
||||
elif trans_obj.TransformType == "Cylindrical":
|
||||
trans_name = "Cylin"
|
||||
trans_type = "C"
|
||||
coords = geomtools.get_cylindrical_coords(trans_obj)
|
||||
base = trans_obj.BasePoint
|
||||
axis = trans_obj.Axis
|
||||
coords = list(base) + list(base + axis)
|
||||
f.write("*TRANSFORM, NSET={}{}, TYPE={}\n".format(
|
||||
trans_name,
|
||||
trans_obj.Name,
|
||||
|
||||
@@ -3635,10 +3635,10 @@ Evolumes
|
||||
** Transform Constraints
|
||||
** FemConstraintTransform1
|
||||
*TRANSFORM, NSET=CylinFemConstraintTransform1, TYPE=C
|
||||
10,27,10,10,7,10
|
||||
10,5,10,10,6,10
|
||||
** FemConstraintTransform2
|
||||
*TRANSFORM, NSET=CylinFemConstraintTransform2, TYPE=C
|
||||
190,27,10,190,7,10
|
||||
190,5,10,190,6,10
|
||||
|
||||
***********************************************************
|
||||
** At least one step is needed to run an CalculiX analysis of FreeCAD
|
||||
|
||||
@@ -10979,7 +10979,7 @@ Evolumes
|
||||
** Transform Constraints
|
||||
** ConstraintTransform
|
||||
*TRANSFORM, NSET=CylinConstraintTransform, TYPE=C
|
||||
0,0,-35,0,0,-15
|
||||
0,0,25,0,0,24
|
||||
|
||||
***********************************************************
|
||||
** At least one step is needed to run an CalculiX analysis of FreeCAD
|
||||
|
||||
@@ -187,52 +187,3 @@ def get_element(
|
||||
return part.Shape.Solids[index] # Solid
|
||||
else:
|
||||
return part.Shape.getElement(element) # Face, Edge, Vertex
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
def get_rectangular_coords(
|
||||
obj
|
||||
):
|
||||
from math import cos, sin, radians
|
||||
A = [1, 0, 0]
|
||||
B = [0, 1, 0]
|
||||
a_x = A[0]
|
||||
a_y = A[1]
|
||||
a_z = A[2]
|
||||
b_x = B[0]
|
||||
b_y = B[1]
|
||||
b_z = B[2]
|
||||
x_rot = radians(obj.X_rot)
|
||||
y_rot = radians(obj.Y_rot)
|
||||
z_rot = radians(obj.Z_rot)
|
||||
if obj.X_rot != 0:
|
||||
a_y = A[1] * cos(x_rot) + A[2] * sin(x_rot)
|
||||
a_z = A[2] * cos(x_rot) - A[1] * sin(x_rot)
|
||||
b_y = B[1] * cos(x_rot) + B[2] * sin(x_rot)
|
||||
b_z = B[2] * cos(x_rot) - B[1] * sin(x_rot)
|
||||
if obj.Y_rot != 0:
|
||||
a_x = A[0] * cos(y_rot) - A[2] * sin(y_rot)
|
||||
a_z = A[2] * cos(y_rot) + A[0] * sin(y_rot)
|
||||
b_x = B[0] * cos(y_rot) - B[2] * sin(y_rot)
|
||||
b_z = B[2] * cos(y_rot) + B[0] * sin(z_rot)
|
||||
if obj.Z_rot != 0:
|
||||
a_x = A[0] * cos(z_rot) + A[1] * sin(z_rot)
|
||||
a_y = A[1] * cos(z_rot) - A[0] * sin(z_rot)
|
||||
b_x = B[0] * cos(z_rot) + B[1] * sin(z_rot)
|
||||
b_y = B[1] * cos(z_rot) - B[0] * sin(z_rot)
|
||||
return (a_x, a_y, a_z, b_x, b_y, b_z)
|
||||
|
||||
|
||||
# ************************************************************************************************
|
||||
def get_cylindrical_coords(
|
||||
obj
|
||||
):
|
||||
vec = obj.Axis
|
||||
base = obj.BasePoint
|
||||
a_x = base[0] + 10 * vec[0]
|
||||
a_y = base[1] + 10 * vec[1]
|
||||
a_z = base[2] + 10 * vec[2]
|
||||
b_x = base[0] - 10 * vec[0]
|
||||
b_y = base[1] - 10 * vec[1]
|
||||
b_z = base[2] - 10 * vec[2]
|
||||
return (a_x, a_y, a_z, b_x, b_y, b_z)
|
||||
|
||||
Reference in New Issue
Block a user