Fem: Update constraint transform
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -366,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)",
|
||||
|
||||
120
src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv
Normal file
120
src/Mod/Fem/Gui/Resources/symbols/ConstraintTransform.iv
Normal file
@@ -0,0 +1,120 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
|
||||
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/>
|
||||
|
||||
@@ -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