Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] Assertion failed when try to access a Point_set_3 property map

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] Assertion failed when try to access a Point_set_3 property map


Chronological Thread 
  • From: Sebastien Loriot <>
  • To:
  • Subject: Re: [cgal-discuss] Assertion failed when try to access a Point_set_3 property map
  • Date: Tue, 23 Nov 2021 19:00:44 +0100
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=Pass ; spf=None
  • Ironport-data: A9a23:aJUMuakcfADxQMZiUoplklDo5gztJ0RdPkR7XQ2eYbTBsI5bp2FSmDMWDGyCM63cNGekc9x3YYqw905Vu8TRy99iHgdq3Hw8FHgiRejtVY3IdB+oV8+xBpSeFxw/t512huEtnanYd1eEzvuWGuWn/SYUOZ2gHOKmUbedYHspHmeIdQ944f5ds75h6mJXqYPha++9kYuaT/z3YDdJ6RYsWo4nw/7rRCdUgRjHkGhwUmrSyhx8lAS2e3E9VPrzLEwqRpfyatE88uWSH44vwFwll1418SvBCvv9+lr6WkgDQ7qXMATXz3QLAu6thR9NoiF02aE+XBYeQR0P2nPZwpYrkIUL6MXYpQQBZsUgnMwGVx5CEiZie6hC0LDCKHm798eUyiUqdlOxn6U+VxBnVWEf0r8vXTsmGeYjADsCZxTGi+Oty6+gUcF3l8E7JY/qOpkeszdu11nk4VwOVciWGeOV8YYNhHFokpobRbCENptAfWE6NFKdd0IaE0kzI5casOeMp3DZTyd8llOwsfNvtjGLiFdluFT2GN/ce9jPSMkM20jF/yTJ+GP2BhxcP9uaoQdpO0mE3ofn9R4XkqpJfFF5yhJrvLFX7mkaCRlTWFfi5Pfk0wixXNVQL0FS8S0rxUT33CRHUfGlNyBUYlbd1vLfZzaUO+I/4QCJjKHT5m51w0AaGyVZZoVOWNAeHFQXO5zgoz8tLTNqubyRD3ma8994aBva1Tc9dQc/WMPPcefJDxQPbm3+YtIjg+uPyJKIs+A=
  • Ironport-hdrordr: A9a23:4miXtqyN+dfkXpUQM+owKrPwJb1zdoMgy1knxilNoHtuA66lfqGV7ZcmPHrP4gr5N0tMpTntAsa9qBDnlaKdg7NxAV7KZmCP01dAR7sN0WKN+VHd86qVzJ856U/nGZIObOHNMQ==
  • Ironport-phdr: A9a23:yrjT8xd1seJOYYhpJdJpBM/XlGM+qNnLVj580XLHo4xHfqnrxZn+JkuXvawr0AWQG9mFoKsc1aL/iOPJYSQ4+5GPsXQPItRndiQuroEopTEmG9OPEkbhLfTnPGQQFcVGU0J5rTngaRAGUMnxaEfPrXKs8DUcBgvwNRZvJuTyB4Xek9m72/q99pHNfglEnjWwbLJ9IBmrsQnct9QdjJd/JKo21hbHuGZDdf5MxWNvK1KTnhL86dm18ZV+7SleuO8v+tBZX6nicKs2UbJXDDI9M2Ao/8LrrgXMTRGO5nQHTGoblAdDDhXf4xH7WpfxtTb6tvZ41SKHM8D6Uaw4VDK/5KhsVRHolTwHNyYn/27Llsx+gqVboBe7qBx+xY7ffYWZOfV6c6/Ye94RWGhPUdtLVyFZH42ycYUPAeoCM+hWoYbyqFkBogexCwS3GOPiySVFimPq0aA00eksFxzN0gw6H9IJtXTZtMj7O7kJXu+v16nI0TTDYO1Q2Tzg7obIdQohofCLXbJsbMHczlIvFwfCjlWKqIzlOC+V2v4Is2if9OdgWuevhHQmqwF1uDSg2sAsiozQi48T11vL+jl3zpwvKt2kVE50f8SkEJ1IuiyVKYZ7X98uTm5otSg1ybAKp4C3cSYExpkjyBPTd/OJf5aW7x/hSuqdPyl1iWx4dL+iiRi+7FasxvHgW8S63ltHqDdOnNfLtnAIzRPT686HR+Ny/kegxTaP1x3T5fpeLU8okqrbLoYtwrE3lpoUvkTDGjH5lF/qg6+Rc0Uo4umo6+L9YrXnvJCQLYF0ihv4P68zmcK/Gfw1PhYSU2Wf4+ix173u8VfnTLlWjfA6iKnUvI3CKckYpaO1GRFZ3psn5hqlETuqzsoUkWMaIF9GZh6KiZXiNUvUL/DiF/i/hkyhkDd1yPDCOb3sGpDNIWLCkLflZLpy9VNTxBcqwdBR559YF6sNIP30Wk/2u9zYCgE2PxaozObgDdVxzoIeWWSRDa+FKK7er0OE6+Y1L+SPZIIZoijxJ+Qm6vL0jXI1hEcRfayz0psWbHC4EO5mI0KcYXf0mdcBFWAKvhA/TOztlF2OSztTZ3KpUqIz4zE0EoOmDYPZSo+xh7yB2T+3HodKaWBeFlCMDXDoep2YVPcDci2SJtZtnSEFVbi6V4AhyAqutBThxrp8LuvU/zUYuoj52Nh04e3TjxAy+iZuA8STyWHeB1xyhX4CEj8qwLhk8ws60UaGyaE+gvpCFNUV6ekOSRY/LZebzup0DJf5VQvFO9uIU127Wc71PDcqU9gNzs8SNkZhB8253FeExDuvG7ZTlrqRBZVy/LibxGn0P886ynDI0+4qgFAiB8dOLma7nbUsyw+GDIHAlwCVlr2haL8H9C/L7maKi2SU729CVwslaqjPVGsDZ0bQ5fD+/ELFU/f6ErAgKApG1YiHLoNFb9ToiRNNQ/K1a4eWWH64h2rlXUXA/biLdoe/JzR1NMr1B00NkgRV9nGDZ1FW7sKJrGfXDTgoHlXqMRuEGQhWrXq6Sgo5w1jPYRA4kbWy/RERiLqXTPZBhto5

You should not iterate on a range and remove elements at the same time.
Put elements to be removed in a std::vector and remove them after the
main loop over all elements. Removing an element may invalidate its
iterator for any container.

Something like that:
for ( auto it = cloud.begin(); it != cloud.end(); ++it )
{
if ( c_size <= size_limit ) to_remove.push_back(*it);
}
for(auto i : to_remove)
cloud.remove(i);

Best,

Sebastien.


On 11/18/21 4:18 PM, Yaoyu Hu ( via cgal-discuss Mailing List) wrote:
Hi,

I am trying to clean the points of a Point_set_3 by removing small clusters of points.

The way I did it is first computing the clusters by CGAL::cluster_point_set() and saving the cluster indices to a property map with the name "cluster". Then I count the number of points in each cluster. Finally, the points belonging to a cluster that has a small cluster size are removed by issuing the remove() function ( followed by collect_garbage() after all remove() calls).

The problem is when I iterate through the Point_set_3 point cloud and send the de-referenced iterator value to the property map, the property map throws an exception triggered by a CGAL::assertion_fail(). The following is the code I use to do the small cluster removal. And I also create a gist if that is more convenient.

https://gist.github.com/huyaoyu/ea9919a1ff6e4c4b49d55020998d1e46 <https://gist.github.com/huyaoyu/ea9919a1ff6e4c4b49d55020998d1e46>

=== Code begins. ===

template < typename Iterable_t >
static std::map<int, int>
compute_cluster_size(const Iterable_t& cluster_map) {
    std::map<int, int> cluster_size;

    for ( const auto& idx : cluster_map ) {
        if ( cluster_size.find(idx) == cluster_size.end() ) {
            // New idx.
            cluster_size[idx] = 1;
        } else {
            // Existing cluster.
            cluster_size[idx]++;
        }
    }

    return cluster_size;
}

// sr::PointSet_t is CGAL::Point_set_3.
void sr::compute_and_remove_small_clusters(
    sr::PointSet_t& cloud,
    double avg_spacing,
    int size_limit,
    std::ostream& os ) {
    sr::PointSet_t::Property_map<int> cluster_map;

    // Reset or create a new property map.
    if ( cloud.has_property_map<int>("cluster") ) {
        boost::tie( cluster_map, boost::tuples::ignore ) =
            cloud.property_map<int>("cluster");

        cloud.remove_property_map(cluster_map);
    }

    bool success = false;
    boost::tie( cluster_map, success ) =
        cloud.add_property_map<int>("cluster", -1);

    if ( !success ) {
        os << "Cannot add cluster property map. \n";
        return;
    }

    // Clustering.
    CGAL::Real_timer rt; rt.start();
    std::size_t n_clusters =
        CGAL::cluster_point_set(
            cloud,
            cluster_map,
            cloud.parameters().neighbor_radius(avg_spacing)
        );
    rt.stop();
    os << "Find " << n_clusters << " clusters in " << rt.time() << " seoncds. \n";

    // Compute the cluster size.
    std::map<int, int> cluster_size = compute_cluster_size( cluster_map );

    // Remove small clusters.
    for ( auto it = cloud.begin(); it != cloud.end(); ++it ) {
        // Get the cluster index.
        const auto c_idx = cluster_map[*it];

        // Get the cluster size.
        const auto c_size = cluster_size[c_idx];

        if ( c_size <= size_limit ) cloud.remove(it);
    }

    cloud.collect_garbage();
}

=== Code ends. ===

In the above code, the line *const auto c_idx = cluster_map[*it];* triggers the assertion failure in *CGAL::Property_array<int>::operator[]()*.

I am assuming that *cluster_map* has all the points in the point cloud as the key and as long as the iterator *it* comes from the point cloud, **it* should be a valid key for *cluster_map*.

The assertion failure does not always get triggered. Most of my point clouds are OK. Only some point clouds trigger this error. I have uploaded one sample point cloud that causes this error to my Google Drive for your reference.
https://drive.google.com/file/d/1rfQP0mo7pj84YgAX1CZtorr6IMpsslyo/view?usp=sharing <https://drive.google.com/file/d/1rfQP0mo7pj84YgAX1CZtorr6IMpsslyo/view?usp=sharing>

Please help me. Any suggestions are appreciated. Thank you!

Yaoyu


--
You are currently subscribed to cgal-discuss.
To unsubscribe or access the archives, go to
https://sympa.inria.fr/sympa/info/cgal-discuss




Archive powered by MHonArc 2.6.19+.

Top of Page