diff --git a/pyTests/sfmData/test_landmark.py b/pyTests/sfmData/test_landmark.py index f776accd9f..6ba4e72e60 100644 --- a/pyTests/sfmData/test_landmark.py +++ b/pyTests/sfmData/test_landmark.py @@ -15,6 +15,7 @@ # - operator==(other) => DONE # - [inline] operator!=(other) => DONE # - Observations& getObservations() / Observations (stl::flat_map) not binded +# - MapObservation getMapObservations() ################## def test_landmark_default_constructor(): @@ -53,7 +54,25 @@ def test_landmark_compare(): # TODO: Update the describer type, the Vec3 or the image before comparing again -@pytest.mark.skip(reason="stl::flat_map not binded") def test_landmark_get_observations(): - """ Test creating Landmarks and retrieving their Observations. """ - assert True + """ Test creating a Landmark and retrieving its (empty) Observations. """ + landmark = av.Landmark() + observations = landmark.getMapObservations() + + # A default Landmark has no observations + assert len(observations) == 0, \ + "A default Landmark should have no observations" + + # Verify the observations container is iterable and dict-like + iterated_ids = [obs_id for obs_id in observations] + assert iterated_ids == [], \ + "Iterating over empty observations should yield no items" + + keys = observations.keys() + assert len(keys) == 0, "keys() on empty observations should return an empty list" + + values = observations.values() + assert len(values) == 0, "values() on empty observations should return an empty list" + + items = observations.items() + assert len(items) == 0, "items() on empty observations should return an empty list" diff --git a/pyTests/sfmData/test_sfmdata.py b/pyTests/sfmData/test_sfmdata.py index 18e6baa13f..8bfdd70317 100644 --- a/pyTests/sfmData/test_sfmdata.py +++ b/pyTests/sfmData/test_sfmdata.py @@ -83,6 +83,46 @@ def test_sfmdata_get_poses(): assert len(data.getPoses()) == len(poses) == 1, "The list of Poses should have been updated" +def test_sfmdata_iterate_poses(): + """ Test creating an SfMData object, filling it with Poses, and iterating over them. """ + data = av.SfMData() + poses = data.getPoses() + + pose_ids = [1, 2, 3, 4, 5] + for pose_id in pose_ids: + camera_pose = av.CameraPose() + poses[pose_id] = camera_pose + + assert len(poses) == len(pose_ids), "The list of Poses should contain all added Poses" + + # Test __iter__: iterating yields all pose IDs + iterated_ids = [pose_id for pose_id in poses] + assert sorted(iterated_ids) == sorted(pose_ids), \ + "Iterating over Poses should yield all pose IDs" + + # Test keys() + keys = poses.keys() + assert sorted(keys) == sorted(pose_ids), \ + "keys() should return all pose IDs" + + # Test values() + values = poses.values() + print(type(values)) + assert len(values) == len(pose_ids), \ + "values() should return one CameraPose per pose ID" + assert all(isinstance(v, av.CameraPose) for v in values), \ + "Each value returned by values() should be a CameraPose" + + # Test items() + items = poses.items() + assert len(items) == len(pose_ids), \ + "items() should return one (pose_id, CameraPose) pair per pose" + for pose_id, pose in items: + assert pose_id in pose_ids, "Each key from items() should be a valid pose ID" + assert isinstance(pose, av.CameraPose), \ + "Each value from items() should be a CameraPose" + + def test_sfmdata_get_rigs(): """ Test creating an empty SfMData object, retrieving and editing its Rigs. """ data = av.SfMData() diff --git a/src/aliceVision/sfmData/Landmark.i b/src/aliceVision/sfmData/Landmark.i index 1acb3979e7..5025daec3b 100644 --- a/src/aliceVision/sfmData/Landmark.i +++ b/src/aliceVision/sfmData/Landmark.i @@ -23,6 +23,9 @@ %ignore aliceVision::sfmData::Landmark::_X; %ignore aliceVision::sfmData::Landmark::_pointFetcher; +// getObservations() returns stl::flat_map which is not natively supported by SWIG. +// The correct way to access it in python is to use getMapObservations, returning MapObservations (std::map). + //Add new swig only C++ code %extend aliceVision::sfmData::Landmark { @@ -45,7 +48,7 @@ color.b() = value.z(); $self->setRgb(color); } - + // If the user asks for the rgb property // It is not a direct access to the rgb // variable but a getter/setter @@ -61,4 +64,4 @@ %{ #include -%} \ No newline at end of file +%} diff --git a/src/aliceVision/sfmData/SfMData.i b/src/aliceVision/sfmData/SfMData.i index 6e97191cb3..a87d6a77f6 100644 --- a/src/aliceVision/sfmData/SfMData.i +++ b/src/aliceVision/sfmData/SfMData.i @@ -114,5 +114,6 @@ SPMAP_EXTENSIONS(aliceVision::sfmData::CameraPose) %template(Rigs) std::map; %template(RotationPriors) std::vector; +%template(PosesVector) std::vector>; %template(ViewsVector) std::vector>; %template(ViewsVectorVector) std::vector>>;