Skip to content

Commit 1b55e66

Browse files
committed
Fem: Update constraint symbols when moving reference shape - fixes FreeCAD#6093
1 parent e012d6b commit 1b55e66

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/Mod/Fem/App/FemConstraint.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,19 @@
5555
#endif
5656
#endif
5757

58+
#include <App/Document.h>
5859
#include <App/DocumentObjectPy.h>
5960
#include <App/FeaturePythonPyImp.h>
6061
#include <App/OriginFeature.h>
6162
#include <Mod/Part/App/PartFeature.h>
63+
#include <Mod/Part/App/Tools.h>
6264

6365
#include "FemConstraint.h"
6466
#include "FemTools.h"
6567

6668

6769
using namespace Fem;
70+
namespace sp = std::placeholders;
6871

6972
#if OCC_VERSION_HEX >= 0x070600
7073
using Adaptor3d_HSurface = Adaptor3d_Surface;
@@ -140,6 +143,18 @@ int Constraint::calcDrawScaleFactor() const
140143
return 1;
141144
}
142145

146+
void setSubShapeLocation(const Part::Feature* feat, TopoDS_Shape& sh)
147+
{
148+
// subshape placement is not necessarily the same as the
149+
// feature placement.
150+
Base::Matrix4D matrix = Part::TopoShape::convert(sh.Location().Transformation());
151+
Base::Placement shPla {matrix};
152+
Base::Placement featlPlaInv = feat->Placement.getValue().inverse();
153+
Base::Placement shGlobalPla = feat->globalPlacement() * featlPlaInv * shPla;
154+
155+
sh.Location(Part::Tools::fromPlacement(shGlobalPla));
156+
}
157+
143158
constexpr int CONSTRAINTSTEPLIMIT = 50;
144159

145160
void Constraint::onChanged(const App::Property* prop)
@@ -163,6 +178,8 @@ void Constraint::onChanged(const App::Property* prop)
163178
sh = toposhape.getSubShape(SubElements[i].c_str(), !execute);
164179

165180
if (!sh.IsNull() && sh.ShapeType() == TopAbs_FACE) {
181+
setSubShapeLocation(feat, sh);
182+
166183
// Get face normal in center point
167184
TopoDS_Face face = TopoDS::Face(sh);
168185
BRepGProp_Face props(face);
@@ -193,6 +210,37 @@ void Constraint::onChanged(const App::Property* prop)
193210
App::DocumentObject::onChanged(prop);
194211
}
195212

213+
void Constraint::slotChangedObject(const App::DocumentObject& obj, const App::Property& prop)
214+
{
215+
if (obj.isDerivedFrom<App::GeoFeature>()
216+
&& (prop.isDerivedFrom<App::PropertyPlacement>() || obj.isRemoving())) {
217+
auto values = References.getValues();
218+
for (const auto ref : values) {
219+
auto v = ref->getInListEx(true);
220+
if ((&obj == ref) || (std::find(v.begin(), v.end(), &obj) != v.end())) {
221+
this->touch();
222+
return;
223+
}
224+
}
225+
}
226+
}
227+
228+
void Constraint::onSettingDocument()
229+
{
230+
App::Document* doc = getDocument();
231+
if (doc) {
232+
connDocChangedObject = doc->signalChangedObject.connect(
233+
std::bind(&Constraint::slotChangedObject, this, sp::_1, sp::_2));
234+
}
235+
236+
App::DocumentObject::onSettingDocument();
237+
}
238+
239+
void Constraint::unsetupObject()
240+
{
241+
connDocChangedObject.disconnect();
242+
}
243+
196244
void Constraint::onDocumentRestored()
197245
{
198246
// This seems to be the only way to make the ViewProvider display the constraint
@@ -223,6 +271,8 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
223271
return false;
224272
}
225273

274+
setSubShapeLocation(feat, sh);
275+
226276
if (sh.ShapeType() == TopAbs_VERTEX) {
227277
const TopoDS_Vertex& vertex = TopoDS::Vertex(sh);
228278
gp_Pnt p = BRep_Tool::Pnt(vertex);

src/Mod/Fem/App/FemConstraint.h

+6
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ class FemExport Constraint: public App::DocumentObject
179179
* of FemConstraint.
180180
*/
181181
void onDocumentRestored() override;
182+
void onSettingDocument() override;
183+
void unsetupObject() override;
182184

183185
/**
184186
* @brief Returns data based on References relevant for rendering widgets.
@@ -247,6 +249,10 @@ class FemExport Constraint: public App::DocumentObject
247249
* variables. It should be rewritten at a different place.
248250
*/
249251
const Base::Vector3d getDirection(const App::PropertyLinkSub& direction);
252+
253+
private:
254+
void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop);
255+
boost::signals2::connection connDocChangedObject;
250256
};
251257

252258
using ConstraintPython = App::FeaturePythonT<Constraint>;

0 commit comments

Comments
 (0)