Skip to content

Commit 2e2aef8

Browse files
committed
Fem: Improve constraint contact - partial fixes FreeCAD#11653
1 parent 1a1d101 commit 2e2aef8

11 files changed

+296
-96
lines changed

src/Mod/Fem/App/FemConstraintContact.cpp

+51-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,31 @@ PROPERTY_SOURCE(Fem::ConstraintContact, Fem::Constraint)
3333
ConstraintContact::ConstraintContact()
3434
{
3535
/*Note: Initialise parameters here*/
36-
ADD_PROPERTY(Slope, (0.0));
37-
ADD_PROPERTY(Friction, (0.0));
38-
/* */
36+
ADD_PROPERTY_TYPE(Slope,
37+
(0.0),
38+
"ConstraintContact",
39+
App::PropertyType(App::Prop_None),
40+
"Contact stiffness");
41+
ADD_PROPERTY_TYPE(Adjust,
42+
(0.0),
43+
"ConstraintContact",
44+
App::PropertyType(App::Prop_None),
45+
"Node clearance adjustment limit");
46+
ADD_PROPERTY_TYPE(Friction,
47+
(false),
48+
"ConstraintContact",
49+
App::PropertyType(App::Prop_None),
50+
"Enable friction interaction");
51+
ADD_PROPERTY_TYPE(FrictionCoefficient,
52+
(0.0),
53+
"ConstraintContact",
54+
App::PropertyType(App::Prop_None),
55+
"Friction coefficient");
56+
ADD_PROPERTY_TYPE(StickSlope,
57+
(0.0),
58+
"ConstraintContact",
59+
App::PropertyType(App::Prop_None),
60+
"Stick slope");
3961

4062
ADD_PROPERTY_TYPE(Points,
4163
(Base::Vector3d()),
@@ -47,6 +69,7 @@ ConstraintContact::ConstraintContact()
4769
"ConstraintContact",
4870
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
4971
"Normals where symbols are drawn");
72+
/* */
5073
Points.setValues(std::vector<Base::Vector3d>());
5174
Normals.setValues(std::vector<Base::Vector3d>());
5275
}
@@ -77,3 +100,28 @@ void ConstraintContact::onChanged(const App::Property* prop)
77100
}
78101
}
79102
}
103+
104+
void ConstraintContact::handleChangedPropertyType(Base::XMLReader& reader,
105+
const char* typeName,
106+
App::Property* prop)
107+
{
108+
if (prop == &Slope && strcmp(typeName, "App::PropertyFloat") == 0) {
109+
App::PropertyFloat oldSlope;
110+
oldSlope.Restore(reader);
111+
// old slope value stored as MPa/mm equivalent to 1e3 kg/(mm^2*s^2)
112+
Slope.setValue(oldSlope.getValue() * 1000);
113+
114+
// stick slope internally generated as slope/10
115+
StickSlope.setValue(Slope.getValue() / 10);
116+
}
117+
else if (prop == &Friction && strcmp(typeName, "App::PropertyFloat") == 0) {
118+
App::PropertyFloat oldFriction;
119+
oldFriction.Restore(reader);
120+
FrictionCoefficient.setValue(oldFriction.getValue());
121+
122+
Friction.setValue(oldFriction.getValue() > 0 ? true : false);
123+
}
124+
else {
125+
Constraint::handleChangedPropertyType(reader, typeName, prop);
126+
}
127+
}

src/Mod/Fem/App/FemConstraintContact.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@ class FemExport ConstraintContact: public Fem::Constraint
5050
* This is only the definitions of the variables
5151
******/
5252
// ex.
53-
App::PropertyFloat Slope;
54-
App::PropertyFloat Friction;
53+
App::PropertyStiffnessDensity Slope;
54+
App::PropertyLength Adjust;
55+
App::PropertyBool Friction;
56+
App::PropertyFloat FrictionCoefficient;
57+
App::PropertyStiffnessDensity StickSlope;
5558

5659
// etc
5760
/* */
@@ -64,6 +67,9 @@ class FemExport ConstraintContact: public Fem::Constraint
6467

6568
protected:
6669
void onChanged(const App::Property* prop) override;
70+
void handleChangedPropertyType(Base::XMLReader& reader,
71+
const char* typeName,
72+
App::Property* prop) override;
6773
};
6874

6975
} // namespace Fem

src/Mod/Fem/Gui/Command.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -250,10 +250,19 @@ void CmdFemConstraintContact::activated(int)
250250
"App.activeDocument().addObject(\"Fem::ConstraintContact\",\"%s\")",
251251
FeatName.c_str());
252252
doCommand(Doc,
253-
"App.activeDocument().%s.Slope = 1000000.00",
253+
"App.activeDocument().%s.Slope = \"1e6 GPa/m\"",
254254
FeatName.c_str()); // OvG: set default not equal to 0
255255
doCommand(Doc,
256-
"App.activeDocument().%s.Friction = 0.0",
256+
"App.activeDocument().%s.Adjust = 0.0",
257+
FeatName.c_str()); // OvG: set default equal to 0
258+
doCommand(Doc,
259+
"App.activeDocument().%s.Friction = False",
260+
FeatName.c_str()); // OvG: set default equal to 0
261+
doCommand(Doc,
262+
"App.activeDocument().%s.FrictionCoefficient = 0.0",
263+
FeatName.c_str()); // OvG: set default equal to 0
264+
doCommand(Doc,
265+
"App.activeDocument().%s.StickSlope = \"1e4 GPa/m\"",
257266
FeatName.c_str()); // OvG: set default not equal to 0
258267
doCommand(Doc,
259268
"App.activeDocument().%s.Scale = 1",

src/Mod/Fem/Gui/TaskFemConstraintContact.cpp

+75-16
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,36 @@ TaskFemConstraintContact::TaskFemConstraintContact(ViewProviderFemConstraintCont
9191

9292
std::vector<App::DocumentObject*> Objects = pcConstraint->References.getValues();
9393
std::vector<std::string> SubElements = pcConstraint->References.getSubValues();
94-
double slope = pcConstraint->Slope.getValue();
95-
double friction = pcConstraint->Friction.getValue();
9694

97-
// Fill data into dialog elements
98-
ui->spSlope->setMinimum(1.0);
99-
ui->spSlope->setValue(slope);
100-
ui->spFriction->setValue(friction);
95+
bool friction = pcConstraint->Friction.getValue();
10196

97+
// Fill data into dialog elements
98+
ui->spbSlope->setUnit(pcConstraint->Slope.getUnit());
99+
ui->spbSlope->setMinimum(0);
100+
ui->spbSlope->setMaximum(FLOAT_MAX);
101+
ui->spbSlope->setValue(pcConstraint->Slope.getQuantityValue());
102+
ui->spbSlope->bind(pcConstraint->Slope);
103+
104+
ui->spbAdjust->setUnit(pcConstraint->Adjust.getUnit());
105+
ui->spbAdjust->setMinimum(0);
106+
ui->spbAdjust->setMaximum(FLOAT_MAX);
107+
ui->spbAdjust->setValue(pcConstraint->Adjust.getQuantityValue());
108+
ui->spbAdjust->bind(pcConstraint->Adjust);
109+
110+
ui->ckbFriction->setChecked(friction);
111+
112+
ui->spbFrictionCoeff->setMinimum(0);
113+
ui->spbFrictionCoeff->setMaximum(FLOAT_MAX);
114+
ui->spbFrictionCoeff->setValue(pcConstraint->FrictionCoefficient.getValue());
115+
ui->spbFrictionCoeff->setEnabled(friction);
116+
ui->spbFrictionCoeff->bind(pcConstraint->FrictionCoefficient);
117+
118+
ui->spbStickSlope->setUnit(pcConstraint->StickSlope.getUnit());
119+
ui->spbStickSlope->setMinimum(0);
120+
ui->spbStickSlope->setMaximum(FLOAT_MAX);
121+
ui->spbStickSlope->setValue(pcConstraint->StickSlope.getQuantityValue());
122+
ui->spbStickSlope->setEnabled(friction);
123+
ui->spbStickSlope->bind(pcConstraint->StickSlope);
102124
/* */
103125

104126
ui->lw_referencesMaster->clear();
@@ -136,6 +158,11 @@ TaskFemConstraintContact::TaskFemConstraintContact(ViewProviderFemConstraintCont
136158
this,
137159
&TaskFemConstraintContact::removeFromSelectionMaster);
138160

161+
connect(ui->ckbFriction,
162+
&QCheckBox::toggled,
163+
this,
164+
&TaskFemConstraintContact::onFrictionChanged);
165+
139166
updateUI();
140167
}
141168

@@ -428,6 +455,12 @@ void TaskFemConstraintContact::onReferenceDeletedMaster()
428455
TaskFemConstraintContact::removeFromSelectionMaster();
429456
}
430457

458+
void TaskFemConstraintContact::onFrictionChanged(bool state)
459+
{
460+
ui->spbFrictionCoeff->setEnabled(state);
461+
ui->spbStickSlope->setEnabled(state);
462+
}
463+
431464
const std::string TaskFemConstraintContact::getReferences() const
432465
{
433466
int rowsSlave = ui->lw_referencesSlave->model()->rowCount();
@@ -443,15 +476,29 @@ const std::string TaskFemConstraintContact::getReferences() const
443476
return TaskFemConstraint::getReferences(items);
444477
}
445478

446-
/* Note: */
447-
double TaskFemConstraintContact::get_Slope() const
479+
const std::string TaskFemConstraintContact::getSlope() const
480+
{
481+
return ui->spbSlope->value().getSafeUserString().toStdString();
482+
}
483+
484+
const std::string TaskFemConstraintContact::getAdjust() const
485+
{
486+
return ui->spbAdjust->value().getSafeUserString().toStdString();
487+
}
488+
489+
bool TaskFemConstraintContact::getFriction() const
490+
{
491+
return ui->ckbFriction->isChecked();
492+
}
493+
494+
double TaskFemConstraintContact::getFrictionCoeff() const
448495
{
449-
return ui->spSlope->rawValue();
496+
return ui->spbFrictionCoeff->value();
450497
}
451498

452-
double TaskFemConstraintContact::get_Friction() const
499+
const std::string TaskFemConstraintContact::getStickSlope() const
453500
{
454-
return ui->spFriction->value();
501+
return ui->spbStickSlope->value().getSafeUserString().toStdString();
455502
}
456503

457504
void TaskFemConstraintContact::changeEvent(QEvent*)
@@ -478,7 +525,7 @@ void TaskDlgFemConstraintContact::open()
478525
// a transaction is already open at creation time of the panel
479526
if (!Gui::Command::hasPendingCommand()) {
480527
QString msg = QObject::tr("Contact constraint");
481-
Gui::Command::openCommand((const char*)msg.toUtf8());
528+
Gui::Command::openCommand(static_cast<const char*>(msg.toUtf8()));
482529
ConstraintView->setVisible(true);
483530
Gui::Command::runCommand(
484531
Gui::Command::Doc,
@@ -497,13 +544,25 @@ bool TaskDlgFemConstraintContact::accept()
497544

498545
try {
499546
Gui::Command::doCommand(Gui::Command::Doc,
500-
"App.ActiveDocument.%s.Slope = %f",
547+
"App.ActiveDocument.%s.Slope = \"%s\"",
548+
name.c_str(),
549+
parameterContact->getSlope().c_str());
550+
Gui::Command::doCommand(Gui::Command::Doc,
551+
"App.ActiveDocument.%s.Adjust = \"%s\"",
552+
name.c_str(),
553+
parameterContact->getAdjust().c_str());
554+
Gui::Command::doCommand(Gui::Command::Doc,
555+
"App.ActiveDocument.%s.Friction = %s",
556+
name.c_str(),
557+
parameterContact->getFriction() ? "True" : "False");
558+
Gui::Command::doCommand(Gui::Command::Doc,
559+
"App.ActiveDocument.%s.FrictionCoefficient = %f",
501560
name.c_str(),
502-
parameterContact->get_Slope());
561+
parameterContact->getFrictionCoeff());
503562
Gui::Command::doCommand(Gui::Command::Doc,
504-
"App.ActiveDocument.%s.Friction = %f",
563+
"App.ActiveDocument.%s.StickSlope = \"%s\"",
505564
name.c_str(),
506-
parameterContact->get_Friction());
565+
parameterContact->getStickSlope().c_str());
507566
std::string scale = parameterContact->getScale(); // OvG: determine modified scale
508567
Gui::Command::doCommand(Gui::Command::Doc,
509568
"App.ActiveDocument.%s.Scale = %s",

src/Mod/Fem/Gui/TaskFemConstraintContact.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,11 @@ class TaskFemConstraintContact: public TaskFemConstraint
4646
QWidget* parent = nullptr);
4747
~TaskFemConstraintContact() override;
4848
const std::string getReferences() const override;
49-
double get_Slope() const;
50-
double get_Friction() const;
49+
const std::string getAdjust() const;
50+
const std::string getSlope() const;
51+
bool getFriction() const;
52+
const std::string getStickSlope() const;
53+
double getFrictionCoeff() const;
5154

5255
private Q_SLOTS:
5356
void onReferenceDeletedSlave();
@@ -56,12 +59,12 @@ private Q_SLOTS:
5659
void removeFromSelectionSlave();
5760
void addToSelectionMaster();
5861
void removeFromSelectionMaster();
62+
void onFrictionChanged(bool);
5963

6064
protected:
6165
void changeEvent(QEvent* e) override;
6266

6367
private:
64-
// void onSelectionChanged(const Gui::SelectionChanges& msg);
6568
void updateUI();
6669
std::unique_ptr<Ui_TaskFemConstraintContact> ui;
6770
};

0 commit comments

Comments
 (0)