Merge pull request #13900 from marioalexis84/fem-constraint_rigid_body
Fem: Add constraint rigid body
This commit is contained in:
@@ -2027,6 +2027,7 @@ void Application::initTypes()
|
||||
App::PropertyMagneticFluxDensity ::init();
|
||||
App::PropertyMagnetization ::init();
|
||||
App::PropertyMass ::init();
|
||||
App::PropertyMoment ::init();
|
||||
App::PropertyPressure ::init();
|
||||
App::PropertyPower ::init();
|
||||
App::PropertyShearModulus ::init();
|
||||
|
||||
@@ -555,6 +555,17 @@ PropertyMass::PropertyMass()
|
||||
setUnit(Base::Unit::Mass);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// PropertyMoment
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TYPESYSTEM_SOURCE(App::PropertyMoment, App::PropertyQuantity)
|
||||
|
||||
PropertyMoment::PropertyMoment()
|
||||
{
|
||||
setUnit(Base::Unit::Moment);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// PropertyPressure
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
@@ -540,6 +540,19 @@ public:
|
||||
~PropertyMass() override = default;
|
||||
};
|
||||
|
||||
/** Moment property
|
||||
* This is a property for representing moment. It is basically a float
|
||||
* property. On the Gui it has a quantity like N*m.
|
||||
*/
|
||||
class AppExport PropertyMoment: public PropertyQuantity
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
PropertyMoment();
|
||||
~PropertyMoment() override = default;
|
||||
};
|
||||
|
||||
/** Pressure property
|
||||
* This is a property for representing pressure. It basically a float
|
||||
* property. On the Gui it has a quantity like Pa.
|
||||
|
||||
@@ -623,6 +623,9 @@ QString Unit::getTypeString() const
|
||||
if (*this == Unit::YoungsModulus) {
|
||||
return QString::fromLatin1("YoungsModulus");
|
||||
}
|
||||
if (*this == Unit::Moment) {
|
||||
return QString::fromLatin1("Moment");
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -664,6 +667,7 @@ const Unit Unit::MagneticFieldStrength (-1,0,0,1);
|
||||
const Unit Unit::MagneticFlux (2,1,-2,-1);
|
||||
const Unit Unit::MagneticFluxDensity (0,1,-2,-1);
|
||||
const Unit Unit::Magnetization (-1,0,0,1);
|
||||
const Unit Unit::Moment (2, 1, -2);
|
||||
const Unit Unit::Pressure (-1,1,-2);
|
||||
const Unit Unit::Power (2, 1, -3);
|
||||
const Unit Unit::ShearModulus (-1,1,-2);
|
||||
|
||||
@@ -155,6 +155,7 @@ public:
|
||||
static const Unit Force;
|
||||
static const Unit Work;
|
||||
static const Unit Power;
|
||||
static const Unit Moment;
|
||||
|
||||
static const Unit SpecificEnergy;
|
||||
static const Unit ThermalConductivity;
|
||||
|
||||
@@ -272,6 +272,24 @@ UnitsSchemaInternal::schemaTranslate(const Quantity& quant, double& factor, QStr
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
// else if (unit == Unit::Moment) {
|
||||
// if (UnitValue < 1e6) {
|
||||
// unitString = QString::fromLatin1("mNm");
|
||||
// factor = 1e3;
|
||||
// }
|
||||
// else if (UnitValue < 1e9) {
|
||||
// unitString = QString::fromLatin1("Nm");
|
||||
// factor = 1e6;
|
||||
// }
|
||||
// else if (UnitValue < 1e12) {
|
||||
// unitString = QString::fromLatin1("kNm");
|
||||
// factor = 1e9;
|
||||
// }
|
||||
// else {
|
||||
// unitString = QString::fromLatin1("MNm");
|
||||
// factor = 1e12;
|
||||
// }
|
||||
// }
|
||||
else if (unit == Unit::Power) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = QString::fromLatin1("mW");
|
||||
|
||||
@@ -261,6 +261,24 @@ QString UnitsSchemaMKS::schemaTranslate(const Quantity& quant, double& factor, Q
|
||||
factor = 1e9;
|
||||
}
|
||||
}
|
||||
// else if (unit == Unit::Moment) {
|
||||
// if (UnitValue < 1e6) {
|
||||
// unitString = QString::fromLatin1("mNm");
|
||||
// factor = 1e3;
|
||||
// }
|
||||
// else if (UnitValue < 1e9) {
|
||||
// unitString = QString::fromLatin1("Nm");
|
||||
// factor = 1e6;
|
||||
// }
|
||||
// else if (UnitValue < 1e12) {
|
||||
// unitString = QString::fromLatin1("kNm");
|
||||
// factor = 1e9;
|
||||
// }
|
||||
// else {
|
||||
// unitString = QString::fromLatin1("MNm");
|
||||
// factor = 1e12;
|
||||
// }
|
||||
// }
|
||||
else if (unit == Unit::Power) {
|
||||
if (UnitValue < 1e6) {
|
||||
unitString = QString::fromLatin1("mW");
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "FemConstraintPlaneRotation.h"
|
||||
#include "FemConstraintPressure.h"
|
||||
#include "FemConstraintPulley.h"
|
||||
#include "FemConstraintRigidBody.h"
|
||||
#include "FemConstraintSpring.h"
|
||||
#include "FemConstraintTemperature.h"
|
||||
#include "FemConstraintTransform.h"
|
||||
@@ -142,6 +143,7 @@ PyMOD_INIT_FUNC(Fem)
|
||||
Fem::ConstraintContact ::init();
|
||||
Fem::ConstraintDisplacement ::init();
|
||||
Fem::ConstraintFixed ::init();
|
||||
Fem::ConstraintRigidBody ::init();
|
||||
Fem::ConstraintFluidBoundary ::init();
|
||||
Fem::ConstraintForce ::init();
|
||||
Fem::ConstraintGear ::init();
|
||||
|
||||
@@ -148,6 +148,8 @@ SET(FemConstraints_SRCS
|
||||
FemConstraintBearing.cpp
|
||||
FemConstraintFixed.cpp
|
||||
FemConstraintFixed.h
|
||||
FemConstraintRigidBody.cpp
|
||||
FemConstraintRigidBody.h
|
||||
FemConstraintForce.cpp
|
||||
FemConstraintForce.h
|
||||
FemConstraintFluidBoundary.cpp
|
||||
|
||||
128
src/Mod/Fem/App/FemConstraintRigidBody.cpp
Normal file
128
src/Mod/Fem/App/FemConstraintRigidBody.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
#include "FemConstraintRigidBody.h"
|
||||
|
||||
|
||||
using namespace Fem;
|
||||
|
||||
PROPERTY_SOURCE(Fem::ConstraintRigidBody, Fem::Constraint)
|
||||
|
||||
const char* ConstraintRigidBody::boundaryModeEnum[] = {"Free", "Constraint", "Load", nullptr};
|
||||
|
||||
ConstraintRigidBody::ConstraintRigidBody()
|
||||
{
|
||||
ADD_PROPERTY_TYPE(ReferenceNode,
|
||||
(0.0, 0.0, 0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Reference node position");
|
||||
ADD_PROPERTY_TYPE(Displacement,
|
||||
(0.0, 0.0, 0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Reference node displacement");
|
||||
ADD_PROPERTY_TYPE(Rotation,
|
||||
(Base::Rotation(0.0, 0.0, 0.0, 1.0)),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Reference node rotation");
|
||||
ADD_PROPERTY_TYPE(ForceX,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied force in X direction");
|
||||
ADD_PROPERTY_TYPE(ForceY,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied force in Y direction");
|
||||
ADD_PROPERTY_TYPE(ForceZ,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied force in Z direction");
|
||||
ADD_PROPERTY_TYPE(MomentX,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied moment in X direction");
|
||||
ADD_PROPERTY_TYPE(MomentY,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied moment in Y direction");
|
||||
ADD_PROPERTY_TYPE(MomentZ,
|
||||
(0.0),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Applied moment in Z direction");
|
||||
ADD_PROPERTY_TYPE(TranslationalModeX,
|
||||
("Free"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"X-direction displacement/force mode");
|
||||
ADD_PROPERTY_TYPE(TranslationalModeY,
|
||||
("Free"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Y-direction displacement/force mode");
|
||||
ADD_PROPERTY_TYPE(TranslationalModeZ,
|
||||
("Free"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Z-direction displacement/force mode");
|
||||
ADD_PROPERTY_TYPE(RotationalModeX,
|
||||
("None"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"X-direction rotation/moment mode");
|
||||
ADD_PROPERTY_TYPE(RotationalModeY,
|
||||
("None"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Y-direction rotation/moment mode");
|
||||
ADD_PROPERTY_TYPE(RotationalModeZ,
|
||||
("None"),
|
||||
"ConstraintRigidBody",
|
||||
App::Prop_Output,
|
||||
"Z-direction rotation/moment mode");
|
||||
|
||||
TranslationalModeX.setEnums(boundaryModeEnum);
|
||||
TranslationalModeY.setEnums(boundaryModeEnum);
|
||||
TranslationalModeZ.setEnums(boundaryModeEnum);
|
||||
RotationalModeX.setEnums(boundaryModeEnum);
|
||||
RotationalModeY.setEnums(boundaryModeEnum);
|
||||
RotationalModeZ.setEnums(boundaryModeEnum);
|
||||
}
|
||||
|
||||
App::DocumentObjectExecReturn* ConstraintRigidBody::execute()
|
||||
{
|
||||
return Constraint::execute();
|
||||
}
|
||||
|
||||
void ConstraintRigidBody::onChanged(const App::Property* prop)
|
||||
{
|
||||
Constraint::onChanged(prop);
|
||||
}
|
||||
76
src/Mod/Fem/App/FemConstraintRigidBody.h
Normal file
76
src/Mod/Fem/App/FemConstraintRigidBody.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* 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_CONSTRAINTRIGIDBODY_H
|
||||
#define FEM_CONSTRAINTRIGIDBODY_H
|
||||
|
||||
#include "FemConstraint.h"
|
||||
|
||||
|
||||
namespace Fem
|
||||
{
|
||||
|
||||
class FemExport ConstraintRigidBody: public Fem::Constraint
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(Fem::ConstraintRigidBody);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
ConstraintRigidBody();
|
||||
|
||||
// Rigid Body parameters
|
||||
App::PropertyPosition ReferenceNode;
|
||||
App::PropertyPosition Displacement;
|
||||
App::PropertyRotation Rotation;
|
||||
App::PropertyForce ForceX;
|
||||
App::PropertyForce ForceY;
|
||||
App::PropertyForce ForceZ;
|
||||
App::PropertyMoment MomentX;
|
||||
App::PropertyMoment MomentY;
|
||||
App::PropertyMoment MomentZ;
|
||||
App::PropertyEnumeration TranslationalModeX;
|
||||
App::PropertyEnumeration TranslationalModeY;
|
||||
App::PropertyEnumeration TranslationalModeZ;
|
||||
App::PropertyEnumeration RotationalModeX;
|
||||
App::PropertyEnumeration RotationalModeY;
|
||||
App::PropertyEnumeration RotationalModeZ;
|
||||
|
||||
/// recalculate the object
|
||||
App::DocumentObjectExecReturn* execute() override;
|
||||
|
||||
/// returns the type name of the ViewProvider
|
||||
const char* getViewProviderName() const override
|
||||
{
|
||||
return "FemGui::ViewProviderFemConstraintRigidBody";
|
||||
}
|
||||
|
||||
protected:
|
||||
void onChanged(const App::Property* prop) override;
|
||||
|
||||
private:
|
||||
static const char* boundaryModeEnum[];
|
||||
};
|
||||
|
||||
} // namespace Fem
|
||||
|
||||
|
||||
#endif // FEM_CONSTRAINTRIGIDBODY_H
|
||||
@@ -231,6 +231,8 @@ SET(FemSolverCalculix_SRCS
|
||||
femsolver/calculix/write_constraint_initialtemperature.py
|
||||
femsolver/calculix/write_constraint_planerotation.py
|
||||
femsolver/calculix/write_constraint_pressure.py
|
||||
femsolver/calculix/write_constraint_rigidbody.py
|
||||
femsolver/calculix/write_constraint_rigidbody_step.py
|
||||
femsolver/calculix/write_constraint_sectionprint.py
|
||||
femsolver/calculix/write_constraint_selfweight.py
|
||||
femsolver/calculix/write_constraint_temperature.py
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "ViewProviderFemConstraintContact.h"
|
||||
#include "ViewProviderFemConstraintDisplacement.h"
|
||||
#include "ViewProviderFemConstraintFixed.h"
|
||||
#include "ViewProviderFemConstraintRigidBody.h"
|
||||
#include "ViewProviderFemConstraintForce.h"
|
||||
#include "ViewProviderFemConstraintFluidBoundary.h"
|
||||
#include "ViewProviderFemConstraintGear.h"
|
||||
@@ -120,6 +121,7 @@ PyMOD_INIT_FUNC(FemGui)
|
||||
FemGui::ViewProviderFemConstraintContact ::init();
|
||||
FemGui::ViewProviderFemConstraintDisplacement ::init();
|
||||
FemGui::ViewProviderFemConstraintFixed ::init();
|
||||
FemGui::ViewProviderFemConstraintRigidBody ::init();
|
||||
FemGui::ViewProviderFemConstraintFluidBoundary ::init();
|
||||
FemGui::ViewProviderFemConstraintForce ::init();
|
||||
FemGui::ViewProviderFemConstraintGear ::init();
|
||||
|
||||
@@ -63,6 +63,7 @@ set(FemGui_UIC_SRCS
|
||||
TaskFemConstraint.ui
|
||||
TaskFemConstraintBearing.ui
|
||||
TaskFemConstraintFixed.ui
|
||||
TaskFemConstraintRigidBody.ui
|
||||
TaskFemConstraintForce.ui
|
||||
TaskFemConstraintFluidBoundary.ui
|
||||
TaskFemConstraintPressure.ui
|
||||
@@ -134,6 +135,9 @@ SET(FemGui_DLG_SRCS
|
||||
TaskFemConstraintFixed.ui
|
||||
TaskFemConstraintFixed.cpp
|
||||
TaskFemConstraintFixed.h
|
||||
TaskFemConstraintRigidBody.ui
|
||||
TaskFemConstraintRigidBody.cpp
|
||||
TaskFemConstraintRigidBody.h
|
||||
TaskFemConstraintForce.ui
|
||||
TaskFemConstraintForce.cpp
|
||||
TaskFemConstraintForce.h
|
||||
@@ -210,6 +214,8 @@ SET(FemGui_SRCS_ViewProvider
|
||||
ViewProviderFemConstraintBearing.h
|
||||
ViewProviderFemConstraintFixed.cpp
|
||||
ViewProviderFemConstraintFixed.h
|
||||
ViewProviderFemConstraintRigidBody.cpp
|
||||
ViewProviderFemConstraintRigidBody.h
|
||||
ViewProviderFemConstraintForce.cpp
|
||||
ViewProviderFemConstraintForce.h
|
||||
ViewProviderFemConstraintFluidBoundary.cpp
|
||||
@@ -354,6 +360,7 @@ SET(FemGuiSymbol_IV
|
||||
Resources/symbols/ConstraintHeatFlux.iv
|
||||
Resources/symbols/ConstraintPlaneRotation.iv
|
||||
Resources/symbols/ConstraintPressure.iv
|
||||
Resources/symbols/ConstraintRigidBody.iv
|
||||
Resources/symbols/ConstraintSpring.iv
|
||||
Resources/symbols/ConstraintTemperature.iv
|
||||
Resources/symbols/ConstraintTie.iv
|
||||
|
||||
@@ -387,6 +387,58 @@ bool CmdFemConstraintFixed::isActive()
|
||||
}
|
||||
|
||||
|
||||
//================================================================================================
|
||||
DEF_STD_CMD_A(CmdFemConstraintRigidBody)
|
||||
|
||||
CmdFemConstraintRigidBody::CmdFemConstraintRigidBody()
|
||||
: Command("FEM_ConstraintRigidBody")
|
||||
{
|
||||
sAppModule = "Fem";
|
||||
sGroup = QT_TR_NOOP("Fem");
|
||||
sMenuText = QT_TR_NOOP("Constraint rigid body");
|
||||
sToolTipText = QT_TR_NOOP("Creates a FEM constraint for a rigid body");
|
||||
sWhatsThis = "FEM_ConstraintRigidBody";
|
||||
sStatusTip = sToolTipText;
|
||||
sPixmap = "FEM_ConstraintRigidBody";
|
||||
}
|
||||
|
||||
void CmdFemConstraintRigidBody::activated(int)
|
||||
{
|
||||
Fem::FemAnalysis* Analysis;
|
||||
|
||||
if (getConstraintPrerequisits(&Analysis)) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string FeatName = getUniqueObjectName("ConstraintRigidBody");
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Make FEM constraint fixed geometry"));
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().addObject(\"Fem::ConstraintRigidBody\",\"%s\")",
|
||||
FeatName.c_str());
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().%s.Scale = 1",
|
||||
FeatName.c_str()); // OvG: set initial scale to 1
|
||||
doCommand(Doc,
|
||||
"App.activeDocument().%s.addObject(App.activeDocument().%s)",
|
||||
Analysis->getNameInDocument(),
|
||||
FeatName.c_str());
|
||||
|
||||
doCommand(Doc,
|
||||
"%s",
|
||||
gethideMeshShowPartStr(FeatName).c_str()); // OvG: Hide meshes and show parts
|
||||
|
||||
updateActive();
|
||||
|
||||
doCommand(Gui, "Gui.activeDocument().setEdit('%s')", FeatName.c_str());
|
||||
}
|
||||
|
||||
bool CmdFemConstraintRigidBody::isActive()
|
||||
{
|
||||
return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject();
|
||||
}
|
||||
|
||||
|
||||
//================================================================================================
|
||||
DEF_STD_CMD_A(CmdFemConstraintFluidBoundary)
|
||||
|
||||
@@ -2625,6 +2677,7 @@ void CreateFemCommands()
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintContact());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintDisplacement());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintFixed());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintRigidBody());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintFluidBoundary());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintForce());
|
||||
rcCmdMgr.addCommand(new CmdFemConstraintGear());
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
<file>icons/FEM_ConstraintPlaneRotation.svg</file>
|
||||
<file>icons/FEM_ConstraintPressure.svg</file>
|
||||
<file>icons/FEM_ConstraintPulley.svg</file>
|
||||
<file>icons/FEM_ConstraintRigidBody.svg</file>
|
||||
<file>icons/FEM_ConstraintSectionPrint.svg</file>
|
||||
<file>icons/FEM_ConstraintSelfWeight.svg</file>
|
||||
<file>icons/FEM_ConstraintSpring.svg</file>
|
||||
|
||||
300
src/Mod/Fem/Gui/Resources/icons/FEM_ConstraintRigidBody.svg
Normal file
300
src/Mod/Fem/Gui/Resources/icons/FEM_ConstraintRigidBody.svg
Normal file
@@ -0,0 +1,300 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="64px"
|
||||
height="64px"
|
||||
id="svg2860"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="1.2.2 (732a01da63, 2022-12-09)"
|
||||
sodipodi:docname="Rigid body icon 2.svg"
|
||||
inkscape:output_extension="org.inkscape.output.svg.inkscape"
|
||||
version="1.1"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs2862">
|
||||
<linearGradient
|
||||
id="linearGradient3377">
|
||||
<stop
|
||||
id="stop3379"
|
||||
offset="0"
|
||||
style="stop-color:#faff2b;stop-opacity:1;" />
|
||||
<stop
|
||||
id="stop3381"
|
||||
offset="1"
|
||||
style="stop-color:#ffaa00;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<inkscape:perspective
|
||||
sodipodi:type="inkscape:persp3d"
|
||||
inkscape:vp_x="0 : 32 : 1"
|
||||
inkscape:vp_y="0 : 1000 : 0"
|
||||
inkscape:vp_z="64 : 32 : 1"
|
||||
inkscape:persp3d-origin="32 : 21.333333 : 1"
|
||||
id="perspective2868" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3851-7-2"
|
||||
id="linearGradient3367"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-19.999999,-5.9999984)"
|
||||
spreadMethod="reflect"
|
||||
x1="-11"
|
||||
y1="26"
|
||||
x2="-18"
|
||||
y2="14" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3851-7-2">
|
||||
<stop
|
||||
style="stop-color:#c4a000;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3853-9-4" />
|
||||
<stop
|
||||
style="stop-color:#fce94f;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3855-8-4" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3838-1"
|
||||
id="linearGradient3371"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="2802.9631"
|
||||
y1="538.36249"
|
||||
x2="2859.7263"
|
||||
y2="786.05646" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3838-1">
|
||||
<stop
|
||||
style="stop-color:#34e0e2;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3840-2" />
|
||||
<stop
|
||||
style="stop-color:#06989a;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3842-0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3859-3-8"
|
||||
id="linearGradient3369"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="32.557789"
|
||||
y1="32.917992"
|
||||
x2="26.30212"
|
||||
y2="12.206754" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3859-3-8">
|
||||
<stop
|
||||
style="stop-color:#edd400;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3861-1-7" />
|
||||
<stop
|
||||
style="stop-color:#fce94f;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3863-2-4" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="9.03125"
|
||||
inkscape:cx="-0.88581315"
|
||||
inkscape:cy="34.435986"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:document-units="px"
|
||||
inkscape:grid-bbox="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-global="true"
|
||||
inkscape:snap-bbox="true"
|
||||
inkscape:snap-nodes="true"
|
||||
inkscape:object-nodes="true"
|
||||
inkscape:snap-grids="false"
|
||||
inkscape:object-paths="false"
|
||||
inkscape:snap-intersection-paths="true"
|
||||
inkscape:snap-smooth-nodes="true"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showguides="false">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid3077"
|
||||
empspacing="2"
|
||||
visible="true"
|
||||
enabled="true"
|
||||
snapvisiblegridlinesonly="true" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata2865">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>[vdwalts]</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:date>2016-08-01</dc:date>
|
||||
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
|
||||
<dc:publisher>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:identifier>FreeCAD/src/Mod/</dc:identifier>
|
||||
<dc:rights>
|
||||
<cc:Agent>
|
||||
<dc:title>FreeCAD LGPL2+</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:rights>
|
||||
<cc:license>https://www.gnu.org/copyleft/lesser.html</cc:license>
|
||||
<dc:contributor>
|
||||
<cc:Agent>
|
||||
<dc:title>[agryson] Alexander Gryson</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:contributor>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer">
|
||||
<g
|
||||
id="g3350"
|
||||
transform="matrix(1.2132401,0,0,1.2243031,94.541045,3.2214691)">
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3063-1"
|
||||
d="M -60.49828,12.297578 -44.276817,1.6539792 c 11.343458,-4.6432832 24.728769,13.2093768 12.401376,22.2560528 l -15.695501,9.840822 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:#edd400;fill-opacity:1;fill-rule:nonzero;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3063-3-0"
|
||||
d="M -61.579091,15.205413 -45.631684,4.7575543 c 10.364771,-7.6968104 23.945833,10.6256217 12.009914,17.8715007 l -15.695501,9.840823 z"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3367);fill-opacity:1;fill-rule:nonzero;stroke:#fce94f;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3875-5-7"
|
||||
d="m -51.199941,6 c 11.999989,-0.9999991 18.571392,11.000001 14.571396,20.999994"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3895-60"
|
||||
d="M -51.999998,13 -35.000001,2.000001"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3895-6-1"
|
||||
d="M -44.000006,21.999999 -27.000008,11.000001"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#302b00;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<g
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:url(#linearGradient3371);fill-opacity:1;fill-rule:nonzero;stroke:#042a2a;stroke-width:15.059;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
transform="matrix(0.92148168,0.21647657,-0.04656812,0.97752701,-67.128334,5.0954655)"
|
||||
id="g3031-0">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3011-2"
|
||||
d="m 44,22 c 0,6.627417 -5.372583,12 -12,12 -6.627417,0 -12,-5.372583 -12,-12 0,-6.627417 5.372583,-12 12,-12 6.627417,0 12,5.372583 12,12 z"
|
||||
style="fill:#ef2929;stroke:#a40000;stroke-width:2.09559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
transform="translate(-17,-7)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3011-3-5"
|
||||
d="m 44,22 c 0,6.627417 -5.372583,12 -12,12 -6.627417,0 -12,-5.372583 -12,-12 0,-6.627417 5.372583,-12 12,-12 6.627417,0 12,5.372583 12,12 z"
|
||||
style="fill:url(#linearGradient3369);fill-opacity:1;stroke:#ef2929;stroke-width:2.5147;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
transform="matrix(0.83333334,0,0,0.83333333,-11.666667,-3.3333333)" />
|
||||
</g>
|
||||
<g
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#042a2a;stroke-width:15.059;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
|
||||
transform="matrix(0.92148168,0.21647657,-0.04656812,0.97752701,-67.195852,5.0728652)"
|
||||
id="g3031-3">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3011-5"
|
||||
d="m 44,22 c 0,6.627417 -5.372583,12 -12,12 -6.627417,0 -12,-5.372583 -12,-12 0,-6.627417 5.372583,-12 12,-12 6.627417,0 12,5.372583 12,12 z"
|
||||
style="fill:none;stroke:#a40000;stroke-width:2.09559;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
|
||||
transform="translate(-17,-7)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3011-3-6"
|
||||
d="m 44,22 c 0,6.627417 -5.372583,12 -12,12 -6.627417,0 -12,-5.372583 -12,-12 0,-6.627417 5.372583,-12 12,-12 6.627417,0 12,5.372583 12,12 z"
|
||||
style="fill:none;stroke:#ef2929;stroke-width:2.5147;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4"
|
||||
transform="matrix(0.83333334,0,0,0.83333333,-11.666667,-3.3333333)" />
|
||||
</g>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3867-1"
|
||||
d="M -50.999999,12 V 34.999991"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a40000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3869-9"
|
||||
d="M -58.000006,12 V 32.99999"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a40000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3871-7"
|
||||
d="m -64,16 20.999994,6.999998"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a40000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3873-1"
|
||||
d="m -64.999999,22.999998 20.999993,6.999993"
|
||||
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:54.2152px;font-family:Arial;-inkscape-font-specification:Arial;display:inline;overflow:visible;visibility:visible;fill:none;stroke:#a40000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;stroke:#008800;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 16.715031,24.075792 6.472382,54.966195 39.936147,39.616646"
|
||||
id="path1766"
|
||||
sodipodi:nodetypes="ccc" />
|
||||
<path
|
||||
style="fill:#008800;fill-opacity:1;stroke:#008900;stroke-width:2.19669;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path2789"
|
||||
sodipodi:type="arc"
|
||||
sodipodi:cx="5.4048667"
|
||||
sodipodi:cy="56.144741"
|
||||
sodipodi:rx="3.6746972"
|
||||
sodipodi:ry="3.3471732"
|
||||
sodipodi:start="0"
|
||||
sodipodi:end="6.1171338"
|
||||
sodipodi:arc-type="slice"
|
||||
d="M 9.0795639,56.144741 A 3.6746972,3.3471732 0 0 1 5.5573701,59.489031 3.6746972,3.3471732 0 0 1 1.7428276,56.422323 3.6746972,3.3471732 0 0 1 4.948407,52.823491 3.6746972,3.3471732 0 0 1 9.0290188,55.591489 L 5.4048667,56.144741 Z" />
|
||||
<path
|
||||
style="fill:none;stroke:#008900;stroke-width:4.28125;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 11.053259,50.370761 29.542791,29.937553"
|
||||
id="path555"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
32
src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv
Normal file
32
src/Mod/Fem/Gui/Resources/symbols/ConstraintRigidBody.iv
Normal file
@@ -0,0 +1,32 @@
|
||||
#Inventor V2.1 ascii
|
||||
|
||||
|
||||
Separator {
|
||||
|
||||
Separator {
|
||||
|
||||
Translation {
|
||||
translation 0 2.5 0
|
||||
}
|
||||
Sphere {
|
||||
radius 0.5
|
||||
|
||||
}
|
||||
Translation {
|
||||
translation 0 -1.25 0
|
||||
|
||||
}
|
||||
Cylinder {
|
||||
radius 0.25
|
||||
height 2.5
|
||||
|
||||
}
|
||||
}
|
||||
Separator {
|
||||
|
||||
Sphere {
|
||||
radius 0.25
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
747
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.cpp
Normal file
747
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.cpp
Normal file
@@ -0,0 +1,747 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* 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 <QAction>
|
||||
#include <QMessageBox>
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
#include <App/Document.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/SelectionObject.h>
|
||||
#include <Mod/Fem/App/FemConstraintRigidBody.h>
|
||||
|
||||
#include "TaskFemConstraintRigidBody.h"
|
||||
#include "ui_TaskFemConstraintRigidBody.h"
|
||||
|
||||
|
||||
using namespace FemGui;
|
||||
using namespace Gui;
|
||||
|
||||
/* TRANSLATOR FemGui::TaskFemConstraintRigidBody */
|
||||
|
||||
TaskFemConstraintRigidBody::TaskFemConstraintRigidBody(
|
||||
ViewProviderFemConstraintRigidBody* ConstraintView,
|
||||
QWidget* parent)
|
||||
: TaskFemConstraintOnBoundary(ConstraintView, parent, "FEM_ConstraintRigidBody")
|
||||
{ // Note change "RigidBody" in line above to new constraint name
|
||||
proxy = new QWidget(this);
|
||||
ui = new Ui_TaskFemConstraintRigidBody();
|
||||
ui->setupUi(proxy);
|
||||
QMetaObject::connectSlotsByName(this);
|
||||
|
||||
// create a context menu for the listview of the references
|
||||
createDeleteAction(ui->lw_references);
|
||||
deleteAction->connect(deleteAction,
|
||||
&QAction::triggered,
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onReferenceDeleted);
|
||||
|
||||
connect(ui->lw_references,
|
||||
&QListWidget::currentItemChanged,
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::setSelection);
|
||||
connect(ui->lw_references,
|
||||
&QListWidget::itemClicked,
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::setSelection);
|
||||
connect(ui->cb_x_trans_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onTransModeXChanged);
|
||||
connect(ui->cb_y_trans_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onTransModeYChanged);
|
||||
connect(ui->cb_z_trans_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onTransModeZChanged);
|
||||
connect(ui->cb_x_rot_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onRotModeXChanged);
|
||||
connect(ui->cb_y_rot_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onRotModeYChanged);
|
||||
connect(ui->cb_z_rot_mode,
|
||||
qOverload<int>(&QComboBox::activated),
|
||||
this,
|
||||
&TaskFemConstraintRigidBody::onRotModeZChanged);
|
||||
|
||||
this->groupLayout()->addWidget(proxy);
|
||||
|
||||
/* Note: */
|
||||
// Get the feature data
|
||||
auto pcConstraint = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject());
|
||||
|
||||
const Base::Vector3d& refNode = pcConstraint->ReferenceNode.getValue();
|
||||
const Base::Vector3d& disp = pcConstraint->Displacement.getValue();
|
||||
Base::Vector3d rotDir;
|
||||
double rotAngleRad;
|
||||
pcConstraint->Rotation.getValue().getValue(rotDir, rotAngleRad);
|
||||
Base::Quantity rotAngle(rotAngleRad, QString::fromUtf8("rad"));
|
||||
Base::Quantity forceX = pcConstraint->ForceX.getQuantityValue();
|
||||
Base::Quantity forceY = pcConstraint->ForceY.getQuantityValue();
|
||||
Base::Quantity forceZ = pcConstraint->ForceZ.getQuantityValue();
|
||||
Base::Quantity momentX = pcConstraint->MomentX.getQuantityValue();
|
||||
Base::Quantity momentY = pcConstraint->MomentY.getQuantityValue();
|
||||
Base::Quantity momentZ = pcConstraint->MomentZ.getQuantityValue();
|
||||
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
|
||||
// Fill data into dialog elements
|
||||
ui->qsb_ref_node_x->setValue(refNode.x);
|
||||
ui->qsb_ref_node_y->setValue(refNode.y);
|
||||
ui->qsb_ref_node_z->setValue(refNode.z);
|
||||
ui->qsb_ref_node_x->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("ReferenceNode.x")));
|
||||
ui->qsb_ref_node_y->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("ReferenceNode.y")));
|
||||
ui->qsb_ref_node_z->bind(
|
||||
App::ObjectIdentifier::parse(pcConstraint, std::string("ReferenceNode.z")));
|
||||
ui->qsb_ref_node_x->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_ref_node_x->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_ref_node_y->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_ref_node_y->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_ref_node_z->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_ref_node_z->setMaximum(FLOAT_MAX);
|
||||
|
||||
ui->qsb_disp_x->setValue(disp.x);
|
||||
ui->qsb_disp_y->setValue(disp.y);
|
||||
ui->qsb_disp_z->setValue(disp.z);
|
||||
ui->qsb_disp_x->bind(App::ObjectIdentifier::parse(pcConstraint, std::string("Displacement.x")));
|
||||
ui->qsb_disp_y->bind(App::ObjectIdentifier::parse(pcConstraint, std::string("Displacement.y")));
|
||||
ui->qsb_disp_z->bind(App::ObjectIdentifier::parse(pcConstraint, std::string("Displacement.z")));
|
||||
ui->qsb_disp_x->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_disp_x->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_disp_y->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_disp_y->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_disp_z->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_disp_z->setMaximum(FLOAT_MAX);
|
||||
|
||||
ui->spb_rot_axis_x->setValue(rotDir.x);
|
||||
ui->spb_rot_axis_y->setValue(rotDir.y);
|
||||
ui->spb_rot_axis_z->setValue(rotDir.z);
|
||||
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);
|
||||
|
||||
ui->qsb_force_x->setValue(forceX);
|
||||
ui->qsb_force_y->setValue(forceY);
|
||||
ui->qsb_force_z->setValue(forceZ);
|
||||
ui->qsb_force_x->bind(pcConstraint->ForceX);
|
||||
ui->qsb_force_y->bind(pcConstraint->ForceY);
|
||||
ui->qsb_force_z->bind(pcConstraint->ForceZ);
|
||||
ui->qsb_force_x->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_force_x->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_force_y->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_force_y->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_force_z->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_force_z->setMaximum(FLOAT_MAX);
|
||||
|
||||
ui->qsb_moment_x->setValue(momentX);
|
||||
ui->qsb_moment_y->setValue(momentY);
|
||||
ui->qsb_moment_z->setValue(momentZ);
|
||||
ui->qsb_moment_x->bind(pcConstraint->MomentX);
|
||||
ui->qsb_moment_y->bind(pcConstraint->MomentY);
|
||||
ui->qsb_moment_z->bind(pcConstraint->MomentZ);
|
||||
ui->qsb_moment_x->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_moment_x->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_moment_y->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_moment_y->setMaximum(FLOAT_MAX);
|
||||
ui->qsb_moment_z->setMinimum(-FLOAT_MAX);
|
||||
ui->qsb_moment_z->setMaximum(FLOAT_MAX);
|
||||
|
||||
QStringList modeList;
|
||||
|
||||
App::PropertyEnumeration* transMode = &pcConstraint->TranslationalModeX;
|
||||
for (auto item : transMode->getEnumVector()) {
|
||||
modeList << QString::fromUtf8(item.c_str());
|
||||
}
|
||||
ui->cb_x_trans_mode->addItems(modeList);
|
||||
ui->cb_y_trans_mode->addItems(modeList);
|
||||
ui->cb_z_trans_mode->addItems(modeList);
|
||||
ui->cb_x_trans_mode->setCurrentIndex(pcConstraint->TranslationalModeX.getValue());
|
||||
ui->cb_y_trans_mode->setCurrentIndex(pcConstraint->TranslationalModeY.getValue());
|
||||
ui->cb_z_trans_mode->setCurrentIndex(pcConstraint->TranslationalModeZ.getValue());
|
||||
|
||||
modeList.clear();
|
||||
App::PropertyEnumeration* rotMode = &pcConstraint->RotationalModeX;
|
||||
for (auto item : rotMode->getEnumVector()) {
|
||||
modeList << QString::fromUtf8(item.c_str());
|
||||
}
|
||||
ui->cb_x_rot_mode->addItems(modeList);
|
||||
ui->cb_y_rot_mode->addItems(modeList);
|
||||
ui->cb_z_rot_mode->addItems(modeList);
|
||||
ui->cb_x_rot_mode->setCurrentIndex(pcConstraint->RotationalModeX.getValue());
|
||||
ui->cb_y_rot_mode->setCurrentIndex(pcConstraint->RotationalModeY.getValue());
|
||||
ui->cb_z_rot_mode->setCurrentIndex(pcConstraint->RotationalModeZ.getValue());
|
||||
|
||||
onTransModeXChanged(pcConstraint->TranslationalModeX.getValue());
|
||||
onTransModeYChanged(pcConstraint->TranslationalModeY.getValue());
|
||||
onTransModeZChanged(pcConstraint->TranslationalModeZ.getValue());
|
||||
onRotModeXChanged(pcConstraint->RotationalModeX.getValue());
|
||||
onRotModeYChanged(pcConstraint->RotationalModeY.getValue());
|
||||
onRotModeZChanged(pcConstraint->RotationalModeZ.getValue());
|
||||
|
||||
ui->lw_references->clear();
|
||||
for (std::size_t i = 0; i < Objects.size(); i++) {
|
||||
ui->lw_references->addItem(makeRefText(Objects[i], SubElements[i]));
|
||||
}
|
||||
if (!Objects.empty()) {
|
||||
ui->lw_references->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
// Selection buttons
|
||||
buttonGroup->addButton(ui->btnAdd, (int)SelectionChangeModes::refAdd);
|
||||
buttonGroup->addButton(ui->btnRemove, (int)SelectionChangeModes::refRemove);
|
||||
|
||||
updateUI();
|
||||
}
|
||||
|
||||
TaskFemConstraintRigidBody::~TaskFemConstraintRigidBody()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::updateUI()
|
||||
{
|
||||
if (ui->lw_references->model()->rowCount() == 0) {
|
||||
// Go into reference selection mode if no reference has been selected yet
|
||||
onButtonReference(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::addToSelection()
|
||||
{
|
||||
std::vector<Gui::SelectionObject> selection =
|
||||
Gui::Selection().getSelectionEx(); // gets vector of selected objects of active document
|
||||
if (selection.empty()) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!"));
|
||||
return;
|
||||
}
|
||||
Fem::ConstraintRigidBody* pcConstraint =
|
||||
static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject());
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
|
||||
for (std::vector<Gui::SelectionObject>::iterator it = selection.begin(); it != selection.end();
|
||||
++it) { // for every selected object
|
||||
if (!it->isObjectTypeOf(Part::Feature::getClassTypeId())) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
|
||||
return;
|
||||
}
|
||||
std::vector<std::string> subNames = it->getSubNames();
|
||||
App::DocumentObject* obj =
|
||||
ConstraintView->getObject()->getDocument()->getObject(it->getFeatName());
|
||||
for (size_t subIt = 0; subIt < (subNames.size());
|
||||
++subIt) { // for every selected sub element
|
||||
bool addMe = true;
|
||||
for (std::vector<std::string>::iterator itr =
|
||||
std::find(SubElements.begin(), SubElements.end(), subNames[subIt]);
|
||||
itr != SubElements.end();
|
||||
itr = std::find(++itr,
|
||||
SubElements.end(),
|
||||
subNames[subIt])) { // for every sub element in selection that
|
||||
// matches one in old list
|
||||
if (obj
|
||||
== Objects[std::distance(
|
||||
SubElements.begin(),
|
||||
itr)]) { // if selected sub element's object equals the one in old list
|
||||
// then it was added before so don't add
|
||||
addMe = false;
|
||||
}
|
||||
}
|
||||
// limit constraint such that only vertexes or faces or edges can be used depending on
|
||||
// what was selected first
|
||||
std::string searchStr;
|
||||
if (subNames[subIt].find("Vertex") != std::string::npos) {
|
||||
searchStr = "Vertex";
|
||||
}
|
||||
else if (subNames[subIt].find("Edge") != std::string::npos) {
|
||||
searchStr = "Edge";
|
||||
}
|
||||
else {
|
||||
searchStr = "Face";
|
||||
}
|
||||
for (size_t iStr = 0; iStr < (SubElements.size()); ++iStr) {
|
||||
if (SubElements[iStr].find(searchStr) == std::string::npos) {
|
||||
QString msg = tr(
|
||||
"Only one type of selection (vertex,face or edge) per constraint allowed!");
|
||||
QMessageBox::warning(this, tr("Selection error"), msg);
|
||||
addMe = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (addMe) {
|
||||
QSignalBlocker block(ui->lw_references);
|
||||
Objects.push_back(obj);
|
||||
SubElements.push_back(subNames[subIt]);
|
||||
ui->lw_references->addItem(makeRefText(obj, subNames[subIt]));
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update UI
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::removeFromSelection()
|
||||
{
|
||||
std::vector<Gui::SelectionObject> selection =
|
||||
Gui::Selection().getSelectionEx(); // gets vector of selected objects of active document
|
||||
if (selection.empty()) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!"));
|
||||
return;
|
||||
}
|
||||
Fem::ConstraintRigidBody* pcConstraint =
|
||||
static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject());
|
||||
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
|
||||
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
|
||||
std::vector<size_t> itemsToDel;
|
||||
for (std::vector<Gui::SelectionObject>::iterator it = selection.begin(); it != selection.end();
|
||||
++it) { // for every selected object
|
||||
if (!it->isObjectTypeOf(Part::Feature::getClassTypeId())) {
|
||||
QMessageBox::warning(this, tr("Selection error"), tr("Selected object is not a part!"));
|
||||
return;
|
||||
}
|
||||
const std::vector<std::string>& subNames = it->getSubNames();
|
||||
App::DocumentObject* obj = it->getObject();
|
||||
|
||||
for (size_t subIt = 0; subIt < (subNames.size());
|
||||
++subIt) { // for every selected sub element
|
||||
for (std::vector<std::string>::iterator itr =
|
||||
std::find(SubElements.begin(), SubElements.end(), subNames[subIt]);
|
||||
itr != SubElements.end();
|
||||
itr = std::find(++itr,
|
||||
SubElements.end(),
|
||||
subNames[subIt])) { // for every sub element in selection that
|
||||
// matches one in old list
|
||||
if (obj
|
||||
== Objects[std::distance(
|
||||
SubElements.begin(),
|
||||
itr)]) { // if selected sub element's object equals the one in old list
|
||||
// then it was added before so mark for deletion
|
||||
itemsToDel.push_back(std::distance(SubElements.begin(), itr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::sort(itemsToDel.begin(), itemsToDel.end());
|
||||
while (!itemsToDel.empty()) {
|
||||
Objects.erase(Objects.begin() + itemsToDel.back());
|
||||
SubElements.erase(SubElements.begin() + itemsToDel.back());
|
||||
itemsToDel.pop_back();
|
||||
}
|
||||
// Update UI
|
||||
{
|
||||
QSignalBlocker block(ui->lw_references);
|
||||
ui->lw_references->clear();
|
||||
for (unsigned int j = 0; j < Objects.size(); j++) {
|
||||
ui->lw_references->addItem(makeRefText(Objects[j], SubElements[j]));
|
||||
}
|
||||
}
|
||||
pcConstraint->References.setValues(Objects, SubElements);
|
||||
updateUI();
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::onReferenceDeleted()
|
||||
{
|
||||
TaskFemConstraintRigidBody::removeFromSelection();
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::onRotModeXChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->RotationalModeX.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->spb_rot_axis_x->setEnabled(false);
|
||||
ui->qsb_moment_x->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->spb_rot_axis_x->setEnabled(true);
|
||||
ui->qsb_moment_x->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->spb_rot_axis_x->setEnabled(false);
|
||||
ui->qsb_moment_x->setEnabled(true);
|
||||
}
|
||||
}
|
||||
void TaskFemConstraintRigidBody::onRotModeYChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->RotationalModeY.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->spb_rot_axis_y->setEnabled(false);
|
||||
ui->qsb_moment_y->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->spb_rot_axis_y->setEnabled(true);
|
||||
ui->qsb_moment_y->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->spb_rot_axis_y->setEnabled(false);
|
||||
ui->qsb_moment_y->setEnabled(true);
|
||||
}
|
||||
}
|
||||
void TaskFemConstraintRigidBody::onRotModeZChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->RotationalModeZ.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->spb_rot_axis_z->setEnabled(false);
|
||||
ui->qsb_moment_z->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->spb_rot_axis_z->setEnabled(true);
|
||||
ui->qsb_moment_z->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->spb_rot_axis_z->setEnabled(false);
|
||||
ui->qsb_moment_z->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::onTransModeXChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->TranslationalModeX.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->qsb_disp_x->setEnabled(false);
|
||||
ui->qsb_force_x->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->qsb_disp_x->setEnabled(true);
|
||||
ui->qsb_force_x->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->qsb_disp_x->setEnabled(false);
|
||||
ui->qsb_force_x->setEnabled(true);
|
||||
}
|
||||
}
|
||||
void TaskFemConstraintRigidBody::onTransModeYChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->TranslationalModeY.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->qsb_disp_y->setEnabled(false);
|
||||
ui->qsb_force_y->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->qsb_disp_y->setEnabled(true);
|
||||
ui->qsb_force_y->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->qsb_disp_y->setEnabled(false);
|
||||
ui->qsb_force_y->setEnabled(true);
|
||||
}
|
||||
}
|
||||
void TaskFemConstraintRigidBody::onTransModeZChanged(int item)
|
||||
{
|
||||
const char* val = static_cast<Fem::ConstraintRigidBody*>(ConstraintView->getObject())
|
||||
->TranslationalModeZ.getEnumVector()[item]
|
||||
.c_str();
|
||||
|
||||
if (strcmp(val, "Free") == 0) {
|
||||
ui->qsb_disp_z->setEnabled(false);
|
||||
ui->qsb_force_z->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Constraint") == 0) {
|
||||
ui->qsb_disp_z->setEnabled(true);
|
||||
ui->qsb_force_z->setEnabled(false);
|
||||
}
|
||||
else if (strcmp(val, "Load") == 0) {
|
||||
ui->qsb_disp_z->setEnabled(false);
|
||||
ui->qsb_force_z->setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const std::string TaskFemConstraintRigidBody::getReferences() const
|
||||
{
|
||||
int rows = ui->lw_references->model()->rowCount();
|
||||
std::vector<std::string> items;
|
||||
for (int r = 0; r < rows; r++) {
|
||||
items.push_back(ui->lw_references->item(r)->text().toStdString());
|
||||
}
|
||||
return TaskFemConstraint::getReferences(items);
|
||||
}
|
||||
|
||||
Base::Vector3d TaskFemConstraintRigidBody::getReferenceNode() const
|
||||
{
|
||||
double x = ui->qsb_ref_node_x->rawValue();
|
||||
double y = ui->qsb_ref_node_y->rawValue();
|
||||
double z = ui->qsb_ref_node_z->rawValue();
|
||||
|
||||
return Base::Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
Base::Vector3d TaskFemConstraintRigidBody::getDisplacement() const
|
||||
{
|
||||
double x = ui->qsb_disp_x->rawValue();
|
||||
double y = ui->qsb_disp_y->rawValue();
|
||||
double z = ui->qsb_disp_z->rawValue();
|
||||
|
||||
return Base::Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
Base::Rotation TaskFemConstraintRigidBody::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);
|
||||
}
|
||||
|
||||
std::vector<std::string> TaskFemConstraintRigidBody::getForce() const
|
||||
{
|
||||
std::string x = ui->qsb_force_x->value().getSafeUserString().toStdString();
|
||||
std::string y = ui->qsb_force_y->value().getSafeUserString().toStdString();
|
||||
std::string z = ui->qsb_force_z->value().getSafeUserString().toStdString();
|
||||
|
||||
return {x, y, z};
|
||||
}
|
||||
|
||||
std::vector<std::string> TaskFemConstraintRigidBody::getMoment() const
|
||||
{
|
||||
std::string x = ui->qsb_moment_x->value().getSafeUserString().toStdString();
|
||||
std::string y = ui->qsb_moment_y->value().getSafeUserString().toStdString();
|
||||
std::string z = ui->qsb_moment_z->value().getSafeUserString().toStdString();
|
||||
|
||||
return std::vector<std::string>({x, y, z});
|
||||
}
|
||||
|
||||
std::vector<std::string> TaskFemConstraintRigidBody::getTranslationalMode() const
|
||||
{
|
||||
std::vector<std::string> transModes(3);
|
||||
transModes[0] = ui->cb_x_trans_mode->currentText().toStdString();
|
||||
transModes[1] = ui->cb_y_trans_mode->currentText().toStdString();
|
||||
transModes[2] = ui->cb_z_trans_mode->currentText().toStdString();
|
||||
|
||||
return transModes;
|
||||
}
|
||||
|
||||
std::vector<std::string> TaskFemConstraintRigidBody::getRotationalMode() const
|
||||
{
|
||||
std::vector<std::string> rotModes(3);
|
||||
rotModes[0] = ui->cb_x_rot_mode->currentText().toStdString();
|
||||
rotModes[1] = ui->cb_y_rot_mode->currentText().toStdString();
|
||||
rotModes[2] = ui->cb_z_rot_mode->currentText().toStdString();
|
||||
|
||||
return rotModes;
|
||||
}
|
||||
|
||||
bool TaskFemConstraintRigidBody::event(QEvent* e)
|
||||
{
|
||||
return TaskFemConstraint::KeyEvent(e);
|
||||
}
|
||||
|
||||
void TaskFemConstraintRigidBody::changeEvent(QEvent*)
|
||||
{}
|
||||
|
||||
void TaskFemConstraintRigidBody::clearButtons(const SelectionChangeModes notThis)
|
||||
{
|
||||
if (notThis != SelectionChangeModes::refAdd) {
|
||||
ui->btnAdd->setChecked(false);
|
||||
}
|
||||
if (notThis != SelectionChangeModes::refRemove) {
|
||||
ui->btnRemove->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// TaskDialog
|
||||
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
TaskDlgFemConstraintRigidBody::TaskDlgFemConstraintRigidBody(
|
||||
ViewProviderFemConstraintRigidBody* ConstraintView)
|
||||
{
|
||||
this->ConstraintView = ConstraintView;
|
||||
assert(ConstraintView);
|
||||
this->parameter = new TaskFemConstraintRigidBody(ConstraintView);
|
||||
|
||||
Content.push_back(parameter);
|
||||
}
|
||||
|
||||
//==== calls from the TaskView ===============================================================
|
||||
|
||||
void TaskDlgFemConstraintRigidBody::open()
|
||||
{
|
||||
// a transaction is already open at creation time of the panel
|
||||
if (!Gui::Command::hasPendingCommand()) {
|
||||
QString msg = QObject::tr("Constraint RigidBody");
|
||||
Gui::Command::openCommand((const char*)msg.toUtf8());
|
||||
ConstraintView->setVisible(true);
|
||||
Gui::Command::doCommand(
|
||||
Gui::Command::Doc,
|
||||
ViewProviderFemConstraint::gethideMeshShowPartStr(
|
||||
(static_cast<Fem::Constraint*>(ConstraintView->getObject()))->getNameInDocument())
|
||||
.c_str()); // OvG: Hide meshes and show parts
|
||||
}
|
||||
}
|
||||
|
||||
bool TaskDlgFemConstraintRigidBody::accept()
|
||||
{
|
||||
std::string name = ConstraintView->getObject()->getNameInDocument();
|
||||
const TaskFemConstraintRigidBody* parameters =
|
||||
static_cast<const TaskFemConstraintRigidBody*>(parameter);
|
||||
try {
|
||||
Base::Vector3d ref = parameters->getReferenceNode();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.ReferenceNode = App.Vector(%f, %f, %f)",
|
||||
name.c_str(),
|
||||
ref.x,
|
||||
ref.y,
|
||||
ref.z);
|
||||
|
||||
Base::Vector3d disp = parameters->getDisplacement();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Displacement = App.Vector(%f, %f, %f)",
|
||||
name.c_str(),
|
||||
disp.x,
|
||||
disp.y,
|
||||
disp.z);
|
||||
|
||||
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);
|
||||
|
||||
auto force = parameters->getForce();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.ForceX = \"%s\"",
|
||||
name.c_str(),
|
||||
force[0].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.ForceY = \"%s\"",
|
||||
name.c_str(),
|
||||
force[1].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.ForceZ = \"%s\"",
|
||||
name.c_str(),
|
||||
force[2].c_str());
|
||||
|
||||
auto moment = parameters->getMoment();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.MomentX = \"%s\"",
|
||||
name.c_str(),
|
||||
moment[0].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.MomentY = \"%s\"",
|
||||
name.c_str(),
|
||||
moment[1].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.MomentZ = \"%s\"",
|
||||
name.c_str(),
|
||||
moment[2].c_str());
|
||||
|
||||
auto transModes = parameters->getTranslationalMode();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.TranslationalModeX = \"%s\"",
|
||||
name.c_str(),
|
||||
transModes[0].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.TranslationalModeY = \"%s\"",
|
||||
name.c_str(),
|
||||
transModes[1].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.TranslationalModeZ = \"%s\"",
|
||||
name.c_str(),
|
||||
transModes[2].c_str());
|
||||
|
||||
auto rotModes = parameters->getRotationalMode();
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.RotationalModeX = \"%s\"",
|
||||
name.c_str(),
|
||||
rotModes[0].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.RotationalModeY = \"%s\"",
|
||||
name.c_str(),
|
||||
rotModes[1].c_str());
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.RotationalModeZ = \"%s\"",
|
||||
name.c_str(),
|
||||
rotModes[2].c_str());
|
||||
|
||||
Gui::Command::doCommand(Gui::Command::Doc,
|
||||
"App.ActiveDocument.%s.Scale = %s",
|
||||
name.c_str(),
|
||||
parameters->getScale().c_str());
|
||||
}
|
||||
catch (const Base::Exception& e) {
|
||||
QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what()));
|
||||
return false;
|
||||
}
|
||||
return TaskDlgFemConstraint::accept();
|
||||
}
|
||||
|
||||
bool TaskDlgFemConstraintRigidBody::reject()
|
||||
{
|
||||
Gui::Command::abortCommand();
|
||||
Gui::Command::doCommand(Gui::Command::Gui, "Gui.activeDocument().resetEdit()");
|
||||
Gui::Command::updateActive();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "moc_TaskFemConstraintRigidBody.cpp"
|
||||
88
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.h
Normal file
88
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef GUI_TASKVIEW_TaskFemConstraintRigidBody_H
|
||||
#define GUI_TASKVIEW_TaskFemConstraintRigidBody_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "TaskFemConstraintOnBoundary.h"
|
||||
#include "ViewProviderFemConstraintRigidBody.h"
|
||||
|
||||
|
||||
class Ui_TaskFemConstraintRigidBody;
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
class TaskFemConstraintRigidBody: public TaskFemConstraintOnBoundary
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskFemConstraintRigidBody(ViewProviderFemConstraintRigidBody* ConstraintView,
|
||||
QWidget* parent = nullptr);
|
||||
~TaskFemConstraintRigidBody() override;
|
||||
|
||||
const std::string getReferences() const override;
|
||||
Base::Vector3d getReferenceNode() const;
|
||||
Base::Vector3d getDisplacement() const;
|
||||
Base::Rotation getRotation() const;
|
||||
std::vector<std::string> getForce() const;
|
||||
std::vector<std::string> getMoment() const;
|
||||
std::vector<std::string> getTranslationalMode() const;
|
||||
std::vector<std::string> getRotationalMode() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onReferenceDeleted();
|
||||
void addToSelection() override;
|
||||
void removeFromSelection() override;
|
||||
void onTransModeXChanged(int);
|
||||
void onTransModeYChanged(int);
|
||||
void onTransModeZChanged(int);
|
||||
void onRotModeXChanged(int);
|
||||
void onRotModeYChanged(int);
|
||||
void onRotModeZChanged(int);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* e) override;
|
||||
void changeEvent(QEvent* e) override;
|
||||
void clearButtons(const SelectionChangeModes notThis) override;
|
||||
|
||||
private:
|
||||
void updateUI();
|
||||
Ui_TaskFemConstraintRigidBody* ui;
|
||||
};
|
||||
|
||||
class TaskDlgFemConstraintRigidBody: public TaskDlgFemConstraint
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TaskDlgFemConstraintRigidBody(ViewProviderFemConstraintRigidBody* ConstraintView);
|
||||
void open() override;
|
||||
bool accept() override;
|
||||
bool reject() override;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
#endif // GUI_TASKVIEW_TaskFemConstraintRigidBody_H
|
||||
615
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.ui
Normal file
615
src/Mod/Fem/Gui/TaskFemConstraintRigidBody.ui
Normal file
@@ -0,0 +1,615 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TaskFemConstraintRigidBody</class>
|
||||
<widget class="QWidget" name="TaskFemConstraintRigidBody">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>296</width>
|
||||
<height>587</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="lbl_info">
|
||||
<property name="text">
|
||||
<string>Select multiple face(s), click Add or Remove</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="hLayout1">
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnAdd">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Add</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="btnRemove">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Remove</string>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="lw_references"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_ref_mode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Reference Node</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_ref_node">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_ref_node_x">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_ref_node_x">
|
||||
<property name="singleStep">
|
||||
<double>1.0</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000000000.0</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>0.0</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_ref_node_y">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_ref_node_y">
|
||||
<property name="singleStep">
|
||||
<double>1.0</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000000000.0</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>0.0</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_ref_node_z">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_ref_node_z">
|
||||
<property name="singleStep">
|
||||
<double>1.0</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>1000000000.0</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
<property name="value" stdset="0">
|
||||
<double>0.0</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_trans_parameter">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Translational Mode</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_trans_mode">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_x_mode">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_y_mode">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_z_mode">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cb_x_trans_mode"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cb_y_trans_mode"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cb_z_trans_mode"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_trans_disp">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Displacement</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_trans_disp">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_x_disp">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_y_disp">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_z_disp">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_disp_x">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_disp_y">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_disp_z">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">mm</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_trans_force">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Force</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_trans_force">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_x_force">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_y_force">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_trans_z_force">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_force_x">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_force_y">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_force_z">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer1">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_rot_mode">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Rotational Mode</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_rot_mode">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_x_mode">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_y_mode">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_z_mode">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="cb_x_rot_mode"/>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QComboBox" name="cb_y_rot_mode"/>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="cb_z_rot_mode"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_rot_rot">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Rotation</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_rot_rot">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_x_axis">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_y_axis">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_z_axis">
|
||||
<property name="text">
|
||||
<string>Z:</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 row="1" column="1">
|
||||
<widget class="Gui::DoubleSpinBox" name="spb_rot_axis_y">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.100000000000000</double>
|
||||
</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.100000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_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="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">deg</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gpb_rot_moment">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Moment</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="f_layout_rot_moment">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_x_moment">
|
||||
<property name="text">
|
||||
<string>X:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_y_moment">
|
||||
<property name="text">
|
||||
<string>Y:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="lbl_rot_z_rot">
|
||||
<property name="text">
|
||||
<string>Z:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_moment_x">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N*m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_moment_y">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N*m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="Gui::QuantitySpinBox" name="qsb_moment_z">
|
||||
<property name="keyboardTracking">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>1.00000000000000</double>
|
||||
</property>
|
||||
<property name="unit" stdset="0">
|
||||
<string notr="true">N*m</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>Gui::QuantitySpinBox</class>
|
||||
<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/>
|
||||
</ui>
|
||||
@@ -33,6 +33,7 @@
|
||||
#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>
|
||||
@@ -61,6 +62,7 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
|
||||
: rotateSymbol(true)
|
||||
, pSymbol(nullptr)
|
||||
, pExtraSymbol(nullptr)
|
||||
, pExtraTrans(nullptr)
|
||||
, ivFile(nullptr)
|
||||
, wizardWidget(nullptr)
|
||||
, wizardSubLayout(nullptr)
|
||||
@@ -70,6 +72,8 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
|
||||
pShapeSep->ref();
|
||||
pMultCopy = new SoMultipleCopy();
|
||||
pMultCopy->ref();
|
||||
pExtraTrans = new SoTransform();
|
||||
pExtraTrans->ref();
|
||||
|
||||
ShapeAppearance.setDiffuseColor(1.0f, 0.0f, 0.2f);
|
||||
ShapeAppearance.setSpecularColor(0.0f, 0.0f, 0.0f);
|
||||
@@ -80,6 +84,7 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
|
||||
ViewProviderFemConstraint::~ViewProviderFemConstraint()
|
||||
{
|
||||
pMultCopy->unref();
|
||||
pExtraTrans->unref();
|
||||
pShapeSep->unref();
|
||||
}
|
||||
|
||||
@@ -129,6 +134,7 @@ void ViewProviderFemConstraint::loadSymbol(const char* fileName)
|
||||
if (nodes->getNumChildren() == 2) {
|
||||
pExtraSymbol = dynamic_cast<SoSeparator*>(nodes->getChild(1));
|
||||
if (pExtraSymbol) {
|
||||
pShapeSep->addChild(pExtraTrans);
|
||||
pShapeSep->addChild(pExtraSymbol);
|
||||
}
|
||||
}
|
||||
@@ -221,6 +227,8 @@ void ViewProviderFemConstraint::updateSymbol()
|
||||
}
|
||||
|
||||
pMultCopy->matrix.finishEditing();
|
||||
|
||||
transformExtraSymbol();
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::transformSymbol(const Base::Vector3d& point,
|
||||
@@ -239,6 +247,17 @@ void ViewProviderFemConstraint::transformSymbol(const Base::Vector3d& point,
|
||||
mat.setTransform(tra, rot, scale);
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraint::transformExtraSymbol() const
|
||||
{
|
||||
if (pExtraTrans) {
|
||||
auto obj = static_cast<const Fem::Constraint*>(this->getObject());
|
||||
float s = obj->getScaleFactor();
|
||||
SbMatrix mat;
|
||||
mat.setScale(s);
|
||||
pExtraTrans->setMatrix(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// OvG: Visibility automation show parts and hide meshes on activation of a constraint
|
||||
std::string ViewProviderFemConstraint::gethideMeshShowPartStr(const std::string showConstr)
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
class SbRotation;
|
||||
class SoMultipleCopy;
|
||||
class SoTransform;
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
@@ -68,6 +69,7 @@ public:
|
||||
|
||||
SoSeparator* getSymbolSeparator() const;
|
||||
SoSeparator* getExtraSymbolSeparator() const;
|
||||
SoTransform* getExtraSymbolTransform() const;
|
||||
// Apply rotation on copies of the constraint symbol
|
||||
void setRotateSymbol(bool rotate);
|
||||
bool getRotateSymbol() const;
|
||||
@@ -94,6 +96,7 @@ protected:
|
||||
void updateSymbol();
|
||||
virtual void
|
||||
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,
|
||||
@@ -163,6 +166,7 @@ protected:
|
||||
SoSeparator* pShapeSep;
|
||||
SoSeparator* pSymbol;
|
||||
SoSeparator* pExtraSymbol;
|
||||
SoTransform* pExtraTrans;
|
||||
SoMultipleCopy* pMultCopy;
|
||||
const char* ivFile;
|
||||
|
||||
@@ -190,6 +194,11 @@ inline SoSeparator* ViewProviderFemConstraint::getExtraSymbolSeparator() const
|
||||
return pExtraSymbol;
|
||||
}
|
||||
|
||||
inline SoTransform* ViewProviderFemConstraint::getExtraSymbolTransform() const
|
||||
{
|
||||
return pExtraTrans;
|
||||
}
|
||||
|
||||
inline bool ViewProviderFemConstraint::getRotateSymbol() const
|
||||
{
|
||||
return rotateSymbol;
|
||||
|
||||
138
src/Mod/Fem/Gui/ViewProviderFemConstraintRigidBody.cpp
Normal file
138
src/Mod/Fem/Gui/ViewProviderFemConstraintRigidBody.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* 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 <QMessageBox>
|
||||
#include <Inventor/nodes/SoTransform.h>
|
||||
#endif
|
||||
|
||||
#include "Gui/Control.h"
|
||||
#include <Mod/Fem/App/FemConstraintRigidBody.h>
|
||||
|
||||
#include "TaskFemConstraintRigidBody.h"
|
||||
#include "ViewProviderFemConstraintRigidBody.h"
|
||||
|
||||
|
||||
using namespace FemGui;
|
||||
|
||||
PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintRigidBody,
|
||||
FemGui::ViewProviderFemConstraintOnBoundary)
|
||||
|
||||
|
||||
ViewProviderFemConstraintRigidBody::ViewProviderFemConstraintRigidBody()
|
||||
{
|
||||
sPixmap = "FEM_ConstraintRigidBody";
|
||||
loadSymbol((resourceSymbolDir + "ConstraintRigidBody.iv").c_str());
|
||||
ShapeAppearance.setDiffuseColor(0.0f, 0.5f, 0.0f);
|
||||
}
|
||||
|
||||
ViewProviderFemConstraintRigidBody::~ViewProviderFemConstraintRigidBody() = default;
|
||||
|
||||
bool ViewProviderFemConstraintRigidBody::setEdit(int ModNum)
|
||||
{
|
||||
if (ModNum == ViewProvider::Default) {
|
||||
// When double-clicking on the item for this constraint the
|
||||
// object unsets and sets its edit mode without closing
|
||||
// the task panel
|
||||
Gui::TaskView::TaskDialog* dlg = Gui::Control().activeDialog();
|
||||
TaskDlgFemConstraintRigidBody* constrDlg =
|
||||
qobject_cast<TaskDlgFemConstraintRigidBody*>(dlg);
|
||||
if (constrDlg && constrDlg->getConstraintView() != this) {
|
||||
constrDlg = nullptr; // another constraint left open its task panel
|
||||
}
|
||||
if (dlg && !constrDlg) {
|
||||
// This case will occur in the ShaftWizard application
|
||||
checkForWizard();
|
||||
if (!wizardWidget || !wizardSubLayout) {
|
||||
// No shaft wizard is running
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText(QObject::tr("A dialog is already open in the task panel"));
|
||||
msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?"));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::Yes);
|
||||
int ret = msgBox.exec();
|
||||
if (ret == QMessageBox::Yes) {
|
||||
Gui::Control().reject();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (constraintDialog) {
|
||||
// Another FemConstraint* dialog is already open inside the Shaft Wizard
|
||||
// Ignore the request to open another dialog
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
constraintDialog = new TaskFemConstraintRigidBody(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// clear the selection (convenience)
|
||||
Gui::Selection().clearSelection();
|
||||
|
||||
// start the edit dialog
|
||||
if (constrDlg) {
|
||||
Gui::Control().showDialog(constrDlg);
|
||||
}
|
||||
else {
|
||||
Gui::Control().showDialog(new TaskDlgFemConstraintRigidBody(this));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return ViewProviderDocumentObject::setEdit(ModNum); // clazy:exclude=skipped-base-method
|
||||
}
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraintRigidBody::updateData(const App::Property* prop)
|
||||
{
|
||||
auto obj = static_cast<Fem::ConstraintRigidBody*>(this->getObject());
|
||||
|
||||
if (prop == &obj->ReferenceNode) {
|
||||
updateSymbol();
|
||||
}
|
||||
|
||||
ViewProviderFemConstraint::updateData(prop);
|
||||
}
|
||||
|
||||
void ViewProviderFemConstraintRigidBody::transformExtraSymbol() const
|
||||
{
|
||||
SoTransform* symTrans = getExtraSymbolTransform();
|
||||
if (symTrans) {
|
||||
auto obj = static_cast<const Fem::ConstraintRigidBody*>(this->getObject());
|
||||
float s = obj->getScaleFactor();
|
||||
const Base::Vector3d& refNode = obj->ReferenceNode.getValue();
|
||||
SbVec3f tra(refNode.x, refNode.y, refNode.z);
|
||||
SbVec3f sca(s, s, s);
|
||||
SbRotation rot(SbVec3f(0, 0, 1), 0);
|
||||
|
||||
SbMatrix mat;
|
||||
mat.setTransform(tra, rot, sca);
|
||||
|
||||
symTrans->setMatrix(mat);
|
||||
}
|
||||
}
|
||||
53
src/Mod/Fem/Gui/ViewProviderFemConstraintRigidBody.h
Normal file
53
src/Mod/Fem/Gui/ViewProviderFemConstraintRigidBody.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
* *
|
||||
* This file is part of the FreeCAD CAx development system. *
|
||||
* *
|
||||
* This library is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU Library General Public *
|
||||
* License as published by the Free Software Foundation; either *
|
||||
* version 2 of the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This library is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU Library General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Library General Public *
|
||||
* License along with this library; see the file COPYING.LIB. If not, *
|
||||
* write to the Free Software Foundation, Inc., 59 Temple Place, *
|
||||
* Suite 330, Boston, MA 02111-1307, USA *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTRIGIDBODY_H
|
||||
#define GUI_VIEWPROVIDERFEMCONSTRAINTRIGIDBODY_H
|
||||
|
||||
#include "ViewProviderFemConstraintOnBoundary.h"
|
||||
|
||||
namespace FemGui
|
||||
{
|
||||
|
||||
class FemGuiExport ViewProviderFemConstraintRigidBody
|
||||
: public FemGui::ViewProviderFemConstraintOnBoundary
|
||||
{
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(FemGui::ViewProviderFemConstraintRigidBody);
|
||||
|
||||
public:
|
||||
/// Constructor
|
||||
ViewProviderFemConstraintRigidBody();
|
||||
~ViewProviderFemConstraintRigidBody() override;
|
||||
|
||||
void updateData(const App::Property*) override;
|
||||
|
||||
protected:
|
||||
bool setEdit(int ModNum) override;
|
||||
|
||||
void transformExtraSymbol() const override;
|
||||
};
|
||||
|
||||
} // namespace FemGui
|
||||
|
||||
|
||||
#endif // GUI_VIEWPROVIDERFEMCONSTRAINTRIGIDBODY_H
|
||||
@@ -132,6 +132,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const
|
||||
Gui::ToolBarItem* mech = new Gui::ToolBarItem(root);
|
||||
mech->setCommand("Mechanical boundary conditions and loads");
|
||||
*mech << "FEM_ConstraintFixed"
|
||||
<< "FEM_ConstraintRigidBody"
|
||||
<< "FEM_ConstraintDisplacement"
|
||||
<< "FEM_ConstraintContact"
|
||||
<< "FEM_ConstraintTie"
|
||||
@@ -263,6 +264,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const
|
||||
Gui::MenuItem* mech = new Gui::MenuItem;
|
||||
mech->setCommand("&Mechanical boundary conditions and loads");
|
||||
*mech << "FEM_ConstraintFixed"
|
||||
<< "FEM_ConstraintRigidBody"
|
||||
<< "FEM_ConstraintDisplacement"
|
||||
<< "FEM_ConstraintContact"
|
||||
<< "FEM_ConstraintTie"
|
||||
|
||||
@@ -173,6 +173,16 @@ def makeConstraintFixed(
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintRigidBody(
|
||||
doc,
|
||||
name="ConstraintRigidBody"
|
||||
):
|
||||
"""makeConstraintRigidBody(document, [name]):
|
||||
makes a Fem ConstraintRigidBody object"""
|
||||
obj = doc.addObject("Fem::ConstraintRigidBody", name)
|
||||
return obj
|
||||
|
||||
|
||||
def makeConstraintFlowVelocity(
|
||||
doc,
|
||||
name="ConstraintFlowVelocity"
|
||||
|
||||
@@ -139,6 +139,7 @@ class MeshSetsGetter():
|
||||
# constraints node sets getter
|
||||
self.get_constraints_fixed_nodes()
|
||||
self.get_constraints_displacement_nodes()
|
||||
self.get_constraints_rigidbody_nodes()
|
||||
self.get_constraints_planerotation_nodes()
|
||||
|
||||
# constraints surface sets getter
|
||||
@@ -205,6 +206,21 @@ class MeshSetsGetter():
|
||||
femobj["NodesSolid"] = set(nds_solid)
|
||||
femobj["NodesFaceEdge"] = set(nds_faceedge)
|
||||
|
||||
def get_constraints_rigidbody_nodes(self):
|
||||
if not self.member.cons_rigidbody:
|
||||
return
|
||||
# get nodes
|
||||
for femobj in self.member.cons_rigidbody:
|
||||
# femobj --> dict, FreeCAD document object is femobj["Object"]
|
||||
print_obj_info(femobj["Object"])
|
||||
femobj["Nodes"] = meshtools.get_femnodes_by_femobj_with_references(
|
||||
self.femmesh,
|
||||
femobj
|
||||
)
|
||||
# add nodes to constraint_conflict_nodes, needed by constraint plane rotation
|
||||
for node in femobj["Nodes"]:
|
||||
self.constraint_conflict_nodes.append(node)
|
||||
|
||||
def get_constraints_displacement_nodes(self):
|
||||
if not self.member.cons_displacement:
|
||||
return
|
||||
|
||||
79
src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py
Normal file
79
src/Mod/Fem/femsolver/calculix/write_constraint_rigidbody.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program 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 program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD FEM calculix constraint rigid body"
|
||||
__author__ = "Ajinkya Dahale"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
def get_analysis_types():
|
||||
return "all" # write for all analysis types
|
||||
|
||||
|
||||
def get_sets_name():
|
||||
return "constraints_rigidbody_node_sets"
|
||||
|
||||
|
||||
def get_constraint_title():
|
||||
return "Rigid Body Constraints"
|
||||
|
||||
|
||||
def get_before_write_meshdata_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_after_write_meshdata_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_before_write_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_after_write_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def write_meshdata_constraint(f, femobj, rb_obj, ccxwriter):
|
||||
|
||||
f.write("*NSET,NSET=" + rb_obj.Name + "\n")
|
||||
for n in femobj["Nodes"]:
|
||||
f.write("{},\n".format(n))
|
||||
|
||||
|
||||
def write_constraint(f, femobj, rb_obj, ccxwriter):
|
||||
|
||||
rb_obj_idx = ccxwriter.analysis.Group.index(rb_obj)
|
||||
node_count = ccxwriter.mesh_object.FemMesh.NodeCount
|
||||
# factor 2 is to prevent conflict with other rigid body constraint
|
||||
ref_node_idx = node_count + 2*rb_obj_idx + 1
|
||||
rot_node_idx = node_count + 2*rb_obj_idx + 2
|
||||
|
||||
f.write("*NODE\n")
|
||||
f.write("{},{},{},{}\n".format(ref_node_idx, *rb_obj.ReferenceNode))
|
||||
f.write("{},{},{},{}\n".format(rot_node_idx, *rb_obj.ReferenceNode))
|
||||
|
||||
kw_line = "*RIGID BODY, NSET={}, REF NODE={}, ROT NODE={}".format(rb_obj.Name, ref_node_idx, rot_node_idx)
|
||||
|
||||
f.write(kw_line + "\n")
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2022 Ajinkya Dahale <dahale.a.p@gmail.com> *
|
||||
# * *
|
||||
# * This file is part of the FreeCAD CAx development system. *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program 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 program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD FEM calculix constraint rigid body"
|
||||
__author__ = "Ajinkya Dahale"
|
||||
__url__ = "https://www.freecadweb.org"
|
||||
|
||||
|
||||
import FreeCAD
|
||||
|
||||
|
||||
def get_analysis_types():
|
||||
return "all" # write for all analysis types
|
||||
|
||||
|
||||
def get_sets_name():
|
||||
return "constraints_rigidbody_node_sets"
|
||||
|
||||
|
||||
def get_constraint_title():
|
||||
return "Rigid Body Constraints"
|
||||
|
||||
|
||||
def get_before_write_meshdata_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_after_write_meshdata_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_before_write_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def get_after_write_constraint():
|
||||
return ""
|
||||
|
||||
|
||||
def write_constraint(f, femobj, rb_obj, ccxwriter):
|
||||
|
||||
rb_obj_idx = ccxwriter.analysis.Group.index(rb_obj)
|
||||
node_count = ccxwriter.mesh_object.FemMesh.NodeCount
|
||||
# factor 2 is to prevent conflict with other rigid body constraint
|
||||
ref_node_idx = node_count + 2*rb_obj_idx + 1
|
||||
rot_node_idx = node_count + 2*rb_obj_idx + 2
|
||||
|
||||
def write_mode(mode, node, dof, constraint, load):
|
||||
if mode == "Constraint":
|
||||
f.write("*BOUNDARY\n")
|
||||
f.write("{},{},{},{:.13G}\n".format(node, dof, dof, constraint))
|
||||
elif mode == "Load":
|
||||
f.write("*CLOAD\n")
|
||||
f.write("{},{},{:.13G}\n".format(node, dof, load))
|
||||
|
||||
mode = [rb_obj.TranslationalModeX, rb_obj.TranslationalModeY, rb_obj.TranslationalModeZ]
|
||||
constraint = rb_obj.Displacement
|
||||
load = [rb_obj.ForceX, rb_obj.ForceY, rb_obj.ForceZ]
|
||||
|
||||
for i in range(3):
|
||||
write_mode(mode[i], ref_node_idx, i + 1, constraint[i], load[i].getValueAs("N").Value)
|
||||
|
||||
|
||||
mode = [rb_obj.RotationalModeX, rb_obj.RotationalModeY, rb_obj.RotationalModeZ]
|
||||
load = [rb_obj.MomentX,rb_obj.MomentY, rb_obj.MomentZ]
|
||||
|
||||
# write rotation components according to rotational mode
|
||||
rot = rb_obj.Rotation
|
||||
proj_axis = [rot.Axis[i] if mode[i] == "Constraint" else 0 for i in range(3)]
|
||||
# proj_axis could be null
|
||||
try:
|
||||
constraint = FreeCAD.Vector(proj_axis).normalize() * rot.Angle
|
||||
except:
|
||||
constraint = FreeCAD.Vector(0, 0, 0)
|
||||
|
||||
for i in range(3):
|
||||
write_mode(mode[i], rot_node_idx, i + 1, constraint[i], load[i].getValueAs("N*mm").Value)
|
||||
|
||||
|
||||
f.write("\n")
|
||||
@@ -45,6 +45,8 @@ from . import write_constraint_heatflux as con_heatflux
|
||||
from . import write_constraint_initialtemperature as con_itemp
|
||||
from . import write_constraint_planerotation as con_planerotation
|
||||
from . import write_constraint_pressure as con_pressure
|
||||
from . import write_constraint_rigidbody as con_rigidbody
|
||||
from . import write_constraint_rigidbody_step as con_rigidbody_step
|
||||
from . import write_constraint_sectionprint as con_sectionprint
|
||||
from . import write_constraint_selfweight as con_selfweight
|
||||
from . import write_constraint_temperature as con_temperature
|
||||
@@ -161,6 +163,7 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
|
||||
# node sets
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_fixed, con_fixed)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_rigidbody, con_rigidbody)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_displacement, con_displacement)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_planerotation, con_planerotation)
|
||||
self.write_constraints_meshsets(inpfile, self.member.cons_transform, con_transform)
|
||||
@@ -181,12 +184,14 @@ class FemInputWriterCcx(writerbase.FemInputWriter):
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_contact, con_contact)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_tie, con_tie)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_transform, con_transform)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_rigidbody, con_rigidbody)
|
||||
|
||||
# step equation
|
||||
write_step_equation.write_step_equation(inpfile, self)
|
||||
|
||||
# constraints dependent from steps
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_fixed, con_fixed)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_rigidbody_step, con_rigidbody_step)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_displacement, con_displacement)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_sectionprint, con_sectionprint)
|
||||
self.write_constraints_propdata(inpfile, self.member.cons_selfweight, con_selfweight)
|
||||
|
||||
@@ -189,6 +189,10 @@ class TestObjectType(unittest.TestCase):
|
||||
"Fem::ConstraintFixed",
|
||||
type_of_obj(ObjectsFem.makeConstraintFixed(doc))
|
||||
)
|
||||
self.assertEqual(
|
||||
"Fem::ConstraintRigidBody",
|
||||
type_of_obj(ObjectsFem.makeConstraintRigidBody(doc))
|
||||
)
|
||||
self.assertEqual(
|
||||
"Fem::ConstraintFlowVelocity",
|
||||
type_of_obj(ObjectsFem.makeConstraintFlowVelocity(doc))
|
||||
@@ -434,6 +438,10 @@ class TestObjectType(unittest.TestCase):
|
||||
ObjectsFem.makeConstraintFixed(doc),
|
||||
"Fem::ConstraintFixed"
|
||||
))
|
||||
self.assertTrue(is_of_type(
|
||||
ObjectsFem.makeConstraintRigidBody(doc),
|
||||
"Fem::ConstraintRigidBody"
|
||||
))
|
||||
self.assertTrue(is_of_type(
|
||||
ObjectsFem.makeConstraintFlowVelocity(doc),
|
||||
"Fem::ConstraintFlowVelocity"
|
||||
@@ -778,6 +786,21 @@ class TestObjectType(unittest.TestCase):
|
||||
"Fem::ConstraintFixed"
|
||||
))
|
||||
|
||||
# ConstraintRigidBody
|
||||
constraint_rigidbody = ObjectsFem.makeConstraintRigidBody(doc)
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_rigidbody,
|
||||
"App::DocumentObject"
|
||||
))
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_rigidbody,
|
||||
"Fem::Constraint"
|
||||
))
|
||||
self.assertTrue(is_derived_from(
|
||||
constraint_rigidbody,
|
||||
"Fem::ConstraintRigidBody"
|
||||
))
|
||||
|
||||
# ConstraintFlowVelocity
|
||||
constraint_flow_velocity = ObjectsFem.makeConstraintFlowVelocity(doc)
|
||||
self.assertTrue(is_derived_from(
|
||||
@@ -1573,6 +1596,10 @@ class TestObjectType(unittest.TestCase):
|
||||
ObjectsFem.makeConstraintFixed(
|
||||
doc).isDerivedFrom("Fem::ConstraintFixed")
|
||||
)
|
||||
self.assertTrue(
|
||||
ObjectsFem.makeConstraintRigidBody(
|
||||
doc).isDerivedFrom("Fem::ConstraintRigidBody")
|
||||
)
|
||||
self.assertTrue(
|
||||
ObjectsFem.makeConstraintFlowVelocity(
|
||||
doc).isDerivedFrom("Fem::ConstraintPython")
|
||||
@@ -1844,6 +1871,7 @@ def create_all_fem_objects_doc(
|
||||
analysis.addObject(ObjectsFem.makeConstraintDisplacement(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintElectrostaticPotential(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintFixed(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintRigidBody(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintFlowVelocity(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintFluidBoundary(doc))
|
||||
analysis.addObject(ObjectsFem.makeConstraintSpring(doc))
|
||||
|
||||
@@ -207,6 +207,10 @@ class AnalysisMember():
|
||||
list of fixed constraints from the analysis.
|
||||
[{"Object":fixed_obj, "NodeSupports":bool}, {}, ...]
|
||||
|
||||
constraints_rigidbody : list of dictionaries
|
||||
list of displacements for the analysis.
|
||||
[{"Object":rigidbody_obj, "xxxxxxxx":value}, {}, ...]
|
||||
|
||||
constraints_force : list of dictionaries
|
||||
list of force constraints from the analysis.
|
||||
[{"Object":force_obj, "NodeLoad":value}, {}, ...
|
||||
@@ -294,6 +298,12 @@ class AnalysisMember():
|
||||
self.cons_fixed = self.get_several_member(
|
||||
"Fem::ConstraintFixed"
|
||||
)
|
||||
self.cons_rigidbody = self.get_several_member(
|
||||
"Fem::ConstraintRigidBody"
|
||||
)
|
||||
self.cons_rigidbody_step = self.get_several_member(
|
||||
"Fem::ConstraintRigidBody"
|
||||
)
|
||||
self.cons_force = self.get_several_member(
|
||||
"Fem::ConstraintForce"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user