Skip to content

Commit 8b6c5eb

Browse files
PR-FIX-ISSUE-313 (#316)
1 parent e0a8a3e commit 8b6c5eb

3 files changed

Lines changed: 42 additions & 12 deletions

File tree

Plugin/src/SofaPython3/DataHelper.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -247,9 +247,9 @@ py::slice toSlice(const py::object& o)
247247
}
248248

249249

250-
std::map<void*, py::array>& getObjectCache()
250+
std::map<void*, std::pair<int, py::array>>& getObjectCache()
251251
{
252-
static std::map<void*, py::array> s_objectcache {} ;
252+
static std::map<void*, std::pair<int, py::array>> s_objectcache {} ;
253253
return s_objectcache;
254254
}
255255

@@ -324,7 +324,7 @@ py::buffer_info toBufferInfo(BaseData& m)
324324
// TODO add nfo.Text()
325325
/* } else if(nfo.Text()) { */
326326
/* format = py::format_descriptor<char>::value; */
327-
/* } */
327+
/* } */
328328
}
329329
else {
330330
throw py::type_error("Invalid type");
@@ -426,25 +426,26 @@ py::array resetArrayFor(BaseData* d)
426426
py::array a(pybind11::dtype(ninfo), ninfo.shape,
427427
ninfo.strides, ninfo.ptr, capsule);
428428

429-
memcache[d] = a;
429+
memcache[d] = std::make_pair(d->getCounter(), a);
430430
return a;
431431
}
432432

433433
py::array getPythonArrayFor(BaseData* d)
434434
{
435435
auto& memcache = getObjectCache();
436-
if(d->isDirty() || memcache.find(d) == memcache.end())
436+
auto mementry = memcache.find(d);
437+
if(d->isDirty() || mementry == memcache.end() || std::get<0>(mementry->second) != d->getCounter())
437438
{
438439
auto capsule = py::capsule(new Base::SPtr(d->getOwner()), [](void*p){ delete static_cast<Base::SPtr*>(p); } );
439440

440441
py::buffer_info ninfo = toBufferInfo(*d);
441442
py::array a(pybind11::dtype(ninfo), ninfo.shape,
442443
ninfo.strides, ninfo.ptr, capsule);
443444

444-
memcache[d] = a;
445+
memcache[d] = std::make_pair(d->getCounter(), a);
445446
return a;
446447
}
447-
return memcache[d];
448+
return std::get<1>(memcache[d]);
448449
}
449450

450451

Plugin/src/SofaPython3/DataHelper.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ SOFAPYTHON3_API pybind11::slice toSlice(const pybind11::object& o);
193193
SOFAPYTHON3_API std::string getPathTo(Base* b);
194194
SOFAPYTHON3_API const char* getFormat(const AbstractTypeInfo& nfo);
195195

196-
SOFAPYTHON3_API std::map<void*, pybind11::array>& getObjectCache();
196+
SOFAPYTHON3_API std::map<void*, std::pair<int, pybind11::array>>& getObjectCache();
197197
SOFAPYTHON3_API void trimCache();
198198

199199
SOFAPYTHON3_API bool hasArrayFor(BaseData* d);

bindings/Sofa/tests/Core/BaseData.py

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ def test_UnknowAttribute(self):
207207
self.assertRaises(AttributeError, (lambda aa: aa.unvalid), p)
208208

209209
# @unittest.skip # no reason needed
210-
211210
def test_DataArray2DOperation(self):
212211
root = create_scene("rootNode")
213212
v = numpy.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
@@ -248,6 +247,36 @@ def t(c):
248247
c[0] = 1.0
249248
self.assertRaises(ValueError, (lambda c: t(c)), color)
250249

250+
def test_DataAsContainerNumpyArray_testIsDirtyOnDoubleAccess_(self):
251+
root = create_scene("rootNode")
252+
253+
root.addObject("PointSetTopologyContainer", points=[[0, 0, 0], [1, 0, 0]])
254+
modifier = root.addObject("PointSetTopologyModifier")
255+
mo = root.addObject("MechanicalObject")
256+
Sofa.Simulation.init(root)
257+
258+
modifier.addPoints(10, True)
259+
self.assertEqual(len(mo.position), 12)
260+
261+
modifier.addPoints(10, True)
262+
self.assertEqual(len(mo.position), 22)
263+
264+
def test_DataAsContainerNumpyArray_testIsDirtyOnDoubleWriteAccess_(self):
265+
root = create_scene("rootNode")
266+
267+
root.addObject("PointSetTopologyContainer", points=[[0, 0, 0], [1, 0, 0]])
268+
modifier = root.addObject("PointSetTopologyModifier")
269+
mo = root.addObject("MechanicalObject")
270+
Sofa.Simulation.init(root)
271+
272+
modifier.addPoints(10, True)
273+
with mo.position.writeable() as w:
274+
self.assertEqual(len(w), 12)
275+
276+
modifier.addPoints(10, True)
277+
with mo.position.writeable() as w:
278+
self.assertEqual(len(w), 22)
279+
251280
def test_DataAsContainerNumpyArray_(self):
252281
root = create_scene("rootNode")
253282
v = numpy.array([[0, 0, 0], [1, 1, 1], [2, 2, 2], [3, 3, 3]])
@@ -319,10 +348,10 @@ def test_linkpath_between_two_scenes(self):
319348
root1 = create_scene("root1")
320349
root1.addChild("child1")
321350
root2 = create_scene("root2")
322-
root2.addChild("child2)
351+
root2.addChild("child2")
323352
root1.child1.addObject("MechanicalObject", name="dofs1", position=[[1.0,2.0,3.0]])
324-
root2.chdil2.addObject("MechanicalObject", name="dofs2", position=root1.child1.dofs1.position.linkpath)
325-
self.assertEqual(root2.dofs2.position.getParent().name, "dofs1")
353+
root2.child2.addObject("MechanicalObject", name="dofs2", position=root1.child1.dofs1.position.linkpath)
354+
self.assertEqual(str(root2.child2.dofs2.position.getParent().linkpath), "@/child1/dofs1.position")
326355

327356
def test_set_value_from_string(self):
328357
n = create_scene("rootNode")

0 commit comments

Comments
 (0)