Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] How to read a PLY with properties as Point_set_3

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] How to read a PLY with properties as Point_set_3


Chronological Thread 
  • From: Yaoyu Hu <>
  • To:
  • Subject: Re: [cgal-discuss] How to read a PLY with properties as Point_set_3
  • Date: Fri, 22 Oct 2021 22:43:50 -0400
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=Pass ; spf=None
  • Ironport-data: A9a23:WKlIdKPs+QozWSjvrR3IlsFynXyQoLVcMsFnjC/WdQaw1mwr1GdUnWZLCDuAMvvcZ2GmfY1yPNu1oUgH65HSv4NqS1BcGVNFHysb85KdbTi6Bh6tZH3KdpWroHqKXqzyU/GYRCwPZiKa9kjF3oTJ9yEmjPjQHOCkU4YoBwgoLeNaYHd54f5cs7Vh6mJYqYDR7zKl4bsekeWHULOW82Ic3lYv1k62gEgHUMIeF98vlgdWifhj5DcynpSOZX4VDfnZw3DQGuG4EgMmLtsvwo1V/kuBl/ssItask7K+f0FTB7COYU6BjX1ZX6XkiR9HzsAw+vxjZbxMNAEN02XPw4wZJNZl7fRcTS8pI7zFn/UACkgITQlxOKRH/PnMJn3XXcm7kB2fLCGEL/JGVRlqZ+X04N1fCm5H8bkUKSsGcwuYr/mnxaqyDOhqnMUqasfxVL7zEFl0lWSDS6kyGMWbBf3ev4oAmm1h15laRqOGIZcNNm9GcjDrZjljOnM2AbQChsOWh1zrKmUN8xbM/b5fD3P7yQVw1P3gPIOQdIDWA8pSmUmcqyTN+GGRP/3TD/THoRLtz55mrranceLHtIMu+HmQ8/drhBieyjVWBkFKE1S8pva9hwi1XNc3x4k8ksYxhfBayaBpZoCVs96ETLqssRsVWt4WGOo/gO1I4rSB+B6XXwDoURYYAOHLd6YKqfgC2VqAntevDjtq2FFQYRpx6Z/MxQ6P1eMpwaPuqMPKocbpIzUunW3rsi/ycw==
  • Ironport-hdrordr: A9a23:kCLm46EG6EY2iAVppLqFF5HXdLJyesId70hD6qkRc20qTiX2rbHfoB12726DtN8xYgBUpTniAtjwfZqjz+8I3WERVY3SLzUO0VHAROoD0WKF+UypJ8SUzJ8j6U4PSdk2NPTASXBQt4LRwSWTMfoMqePozImYwc/y4kwoZyBHQYNNwm5CZjqzIwlfYzRnP6MQMN64yvVqglObGEg/X4CSO0Qsdcnmi/r30LXbRXc9dmUawTjLoBft1bL/Ch2Vw1MkXztD+rs69HitqX2M2oyT996A91vg8QbonvNrseqk6uIGKeqpougzBVzX+2WVTbUkfpuplBVwm8uX1RIBtuXqnn4bTr1OwkKUW0eagTyo/CHF/F8Vmhvf4G7dpVPChIjVaBcbNOZ7tetiHyfx2g4FlPFYlIxx91LxjfBq5Gv77VPADqPzJmNXv3vxmlAarKo4qUB5bOIlGdlshL1ax2YQKrsmMQ7AgbpXctVGPYXnyNF6XWjyVQG9goF7q+bcJkgbL1O9YGRHkO24+Rp7sRlCoHcw9Ygkjm0c+JZ4ZJxN6Y3/Q9lVvYALcug3VZ5QQNoob6KMexbwfS4=
  • Ironport-phdr: A9a23:eZ9CoxOtwdlb7uY/ZFQl6nYjChdPi9zP1u491JMrhvp0f7i5+Ny6ZQqDv60r1gWYFtiLo9t/yMPu+5j6XmIB5ZvT+FsjS7drEyE/tMMNggY7C9SEA0CoZNTjbig9AdgQHAQ9pyLzPkdaAtvxaEPPqXOu8zESBg//NQ1oLejpB4Lelcu62/6u95HJfQlEmj6wbbxyIRi1sA7cqtQYjYx+J6gr1xDHuGFIe+NYxWNpIVKcgRPx7dqu8ZBg7ipdpesv+9ZPXqvmcas4S6dYDCk9PGAu+MLrrxjDQhCR6XYaT24bjwBHAwnB7BH9Q5fxri73vfdz1SWGIcH7S60/VDK/5KlpVRDokj8KODE38G7VisJ+gqFVrg+/qRNj2IPbep2ZOeBkc6/BYd8XR2xMVdtRWSxbBYO8apMCAOgbMuZfr4j9ukYFoxmjBQKxA+7vyiJIh3/s0q090+UhDBzK0QgjEt8Pq3nUo9D1O70TUeCx1qXH0TLDb/ZP1Dr79YPHfQwvr+uWUrJsbcre11MvFwXdg1iNp4HoPzOb2+YCvWWY4edtWuCih3AnpgxwoTWhxsMhhpfLi48RyV3J6CR0zYkpKNCmVEN1b8CpHYdTui2ENoZ7RN4pTW9vuCY/0LIGuJi7cTAUx5Qj2RHfbuKIc46U4h75UuaeOzJ4i2x9dLK+gRay60mgxffmWsm6ylZHqDdOnNrUtn0VyRDf9syKRuF+80qhwzqDyRzf5+JeLU07mqfWLYMqzKQqmZoJq0vDGzf7mEXog6+ScUUp4u2o5P7mYrXiv5OTKZJ7hhznPqQglcGyDv40MgcJX2ic9uS80KPs8VflT7VNi/06iqjZsJbEKsQHvqO1HRNZ34I55xu8DzqqysoUkWUEIV5fdx+KgJDlO1TUL/D5Cfe/jU6skDBux/3ePr3hH5XMIWLEkLbhYLZx9kpRxQkywN1E6JJUD6sOIPP3WkPrqNPYCRo5PxSuw+n7ENV9yp8eWWWXD6CFP6Pdq1uI6vsyLOmNf48apCv9K+M+5/P1ln84mVodfbGz0pcNaXC4GO5mI0SDbnb2jNcBCzRCgwwlUea/iEGeSSUBIDGpTqck73c6DpinBMHNXMe2kbmZ1WC6GJNRIWtJA1TJHXbzfJifQKQxbjmPKO99lzhRVaS9U5Rzkla1pQriwvxmKPDV82sWr9X4xd1t7qrSkx81sjd7BsDY32CWRHxvhTA1QSQr1pxysVAoykufybMqxLtDBNlL7rVIVB07PNjS1athGtXqU0XAeNmOD12pS9HjDTAqRc8q2IwyZBN2FNymyxzCxCG3GKQ9lrqRBZVy/LiP8WL2IpNMwnHXyeEBkhFyQtZePGq3m/cup1b7CIvAkkHfnKGvI/dPlBXR/XuOmDLd9HpTVxR9BP2ttZE3Y0LXqZH06hqHQePyT7sgNQRFxIiJLa4YMrUBaH1JQf7iPJLVZGfjww9Y6j6Hw7qNaMzhfGBPhU3g

I sort of figured it out.

I should use CGAL::Point_set_3::point_push_map() and CGAL::Point_set_3::normal_push_map() as described in the documentation. 
Also, although Point_set_3 provides the functions for handling normal vectors, the normal map is not automatically created by default. add_normal_map() should be called before reading the PLY. 

The following code works.

=== Code begins. ===

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_t;
typedef Kernel_t::Point_3  Point_t;
typedef Kernel_t::Vector_3 Vector_t;
typedef std::array< unsigned char, 3 > Color_t;

typedef CGAL::Point_set_3<Point_t> PointSet_t;

PointSet_t read_ply_as_point_set( const std::string& fn ) {
    std::ifstream ifs(fn, std::ios::binary);
    if (!ifs) {
        std::stringstream ss;
        ss << "Cannot open " << fn << " for reading. ";
        throw std::runtime_error( ss.str() );
    }

    PointSet_t point_set;

    // Normal map.
    point_set.add_normal_map();

    // Default color.
    const Color_t color_black { { 0, 0, 0 } };

    // The color map.
    PS_ColorMap_t color;
    bool success = false;
    boost::tie( color, success ) =
        point_set.add_property_map<Color_t>("color", color_black);
    assert (success);

    if ( !CGAL::read_PLY_with_properties(
            ifs,
            point_set.index_back_inserter(),
            CGAL::make_ply_point_reader( point_set.point_push_map()  ),
            CGAL::make_ply_normal_reader( point_set.normal_push_map()  ),
            std::make_tuple( color, CGAL::Construct_array(), 
                             CGAL::PLY_property<unsigned char>("red"),
                             CGAL::PLY_property<unsigned char>("green"),
                             CGAL::PLY_property<unsigned char>("blue") ) ) ) {
        ifs.close();
        std::stringstream ss;
        ss << "Read from PLY file " << fn << " failed. ";
        throw std::runtime_error( ss.str() );
    }

    ifs.close();

    return point_set;
}

=== Code ends. ===

Thank you for the help!

Yaoyu

On Thu, Oct 21, 2021 at 3:38 AM Yaoyu Hu <> wrote:
Thank you Andreas for the suggestion. The problem persists after adding the std::ios::binary argument. 

Oh, I forgot to mention that I am on Ubuntu 20.04.

I still have the impression that I might have messed up in using the property maps. 

I tried to debug what is wrong with gdb and I got the following error and a backtrace. I simplify it such that only the filename and line number are preserved. And also, I tried to list the relevant lines at some backtrace points.

=== Debug info. ===
terminate called after throwing an instance of 'CGAL::Assertion_exception'
  what():  CGAL ERROR: assertion violation!
Expr: _idx < data_.size()
File: /home/yaoyu/Libraries/CGAL/cgal/Surface_mesh/include/CGAL/Surface_mesh/Properties.h
Line: 193

#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007ffff7642859 in __GI_abort () at abort.c:79
#2  0x00007ffff7a17911 in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#3  0x00007ffff7a2338c in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6
#4  0x00007ffff7a233f7 in std::terminate() () from /lib/x86_64-linux-gnu/libstdc++.so.6
#5  0x00007ffff7a236a9 in __cxa_throw () from /lib/x86_64-linux-gnu/libstdc++.so.6
#6  /home/yaoyu/Libraries/CGAL/cgal/STL_Extension/include/CGAL/assertions_impl.h:170
#7  /home/yaoyu/Libraries/CGAL/cgal/Surface_mesh/include/CGAL/Surface_mesh/Properties.h:193
190    /// Access the i'th element. No range check is performed!
191    reference operator[](std::size_t _idx)
192    {
193        CGAL_assertion( _idx < data_.size() );
194        return data_[_idx];
195    }

#8  /home/yaoyu/Libraries/CGAL/cgal/Surface_mesh/include/CGAL/Surface_mesh/Properties.h:587
583    /// Access the property associated with the key \c i.
584    reference operator[](const I& i) const
585    {
586      CGAL_assertion(parray_ != nullptr);
587      return (*parray_)[i];
588    }
589
590    iterator begin() { return parray_->begin(); }
591    iterator end() { return parray_->end(); }

#9  /usr/include/boost/property_map/property_map.hpp:311
307  template <class PropertyMap, class Reference, class K, class V>
308  inline void
309  put(const put_get_helper<Reference, PropertyMap>& pa, K k, const V& v)
310  {
311    static_cast<const PropertyMap&>(pa)[k] = v;
312  }
313
314  //=========================================================================
315  // Adapter to turn a RandomAccessIterator into a property map

#10 /home/yaoyu/Libraries/CGAL/cgal/Stream_support/include/CGAL/IO/PLY/PLY_reader.h:670
665  typedef typename boost::property_traits<PropertyMap>::value_type PmapValueType;
666
667  std::tuple<T...> values;
668  Filler<sizeof...(T)-1>::fill(element, values, current);
669  PmapValueType new_value = call_functor<PmapValueType>(std::get<1>(current), values);
670  put(std::get<0>(current), new_element, new_value);
671
672  process_properties(element, new_element, std::forward<NextPropertyBinder>(next),
673                     std::forward<PropertyMapBinders>(properties)...);

#11 /home/yaoyu/Libraries/CGAL/cgal/Point_set_processing_3/include/CGAL/IO/read_ply_points.h:177
172      }
173
174      if(element.name() == "vertex" || element.name() == "vertices")
175      {
176        OutputValueType new_element;
177        IO::internal::process_properties(element, new_element, std::forward<PropertyHandler>(properties)...);
178        *(output ++) = new_element;
179      }
180    }
181  }

#12 /home/yaoyu/Libraries/CGAL/cgal/Point_set_processing_3/include/CGAL/IO/read_ply_points.h:196
191                              OutputIterator output,
192                              PropertyHandler&& ... properties)
193 {
194  typedef typename value_type_traits<OutputIterator>::type OutputValueType;
195
196  return read_PLY_with_properties<OutputValueType>(is, output, std::forward<PropertyHandler>(properties)...);
197 }
198
199 /// \endcond

=== End of debug info. ===

Thank you!

On Thu, Oct 21, 2021 at 2:10 AM Andreas Fabri <> wrote:

Hello,

At least on Windows if you read a binary ply file you must open the stream in binary mode.

Can you try    std::ifstream ifs(fn, std::ios::binary);

Best,

Andreas

On 10/21/2021 1:20 AM, Yaoyu Hu ( via cgal-discuss Mailing List) wrote:
Hi,

I am trying to read a binary PLY file as CGAL::Point_set_3 but I can't get it right.

I am using CGAL 5.3.

I suppose there is not a dedicated example showing how to read a PLY file as Point_set_3 that has properties. For my PLY file, there are point normal and color stored. The code I tried to read it as CGAL::Point_set_3 is as follows:

=== Code begins. ===

typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel_t;
typedef Kernel_t::Point_3  Point_t;
typedef Kernel_t::Vector_3 Vector_t;
typedef std::array< unsigned char, 3 > Color_t;

typedef CGAL::Point_set_3<Point_t> PointSet_t;
typedef PointSet_t::Point_map PS_PointMap_t;
typedef PointSet_t::Vector_map PS_NormalMap_t;
typedef PointSet_t::Property_map<Color_t> PS_ColorMap_t;

PointSet_t sr::read_ply_as_point_set( const std::string& fn ) {
    std::ifstream ifs(fn);

    PointSet_t point_set;

    // Default color.
    const Color_t color_black { { 0, 0, 0 } };

    // The color map.
    PS_ColorMap_t color;
    bool success = false;
    boost::tie( color, success ) =
        point_set.add_property_map<Color_t>("color", color_black);
    assert (success);

    // Read PLY.
    CGAL::read_PLY_with_properties(
            ifs,
            point_set.index_back_inserter(),
            CGAL::make_ply_point_reader( PS_PointMap_t() ),
            CGAL::make_ply_normal_reader( PS_NormalMap_t() ),
            std::make_tuple( PS_ColorMap_t(), CGAL::Construct_array(), 
                             CGAL::PLY_property<unsigned char>("red"),
                             CGAL::PLY_property<unsigned char>("green"),
                             CGAL::PLY_property<unsigned char>("blue") ) ) )

    return point_set;
}

=== Code ends. ===

The codes that I am not sure about are the lines of CGAL::make_ply_point_reader() and CGAL::make_ply_normal_reader(), they are probably wrong but I don't know how to get it right.

Thanks!

Yaoyu


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

-- 
Andreas Fabri, PhD
Chief Officer, GeometryFactory
Editor, The CGAL Project

--
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