CGAL::write_xyz_point_set precision and normal problem

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

CGAL::write_xyz_point_set precision and normal problem

williamlai3a
Hi All,

I am a newbie to CGAL, I am trying code from CGAL github master build
(v4.12) to do 3D point set processing.
I am using the following:
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;

However, in my original .xyz point cloud, I am having high precision like:
841293.765978 818818.600281 90.933151
841293.765000 818818.599880 90.906294
841293.764292 818818.599046 90.960005
841284.839693 818813.763807 90.725665
841284.822854 818813.767425 90.684145
841284.822320 818813.766970 90.696840
841284.821787 818813.766515 90.709534
841284.825319 818813.768227 90.721745

After processing normal, and I write back the points to a .xyz, the point
precision becomes:
841294 818819 90.9332 0 0 0
841294 818819 90.9063 0 0 0
841294 818819 90.96 0 0 0
841285 818814 90.7257 0 0 0
841285 818814 90.6841 0 0 0
841285 818814 90.6968 0 0 0
841285 818814 90.7095 0 0 0
841285 818814 90.7217 0 0 0

Problem 1:
Seems to me that the output is being trimmed to 6 significant figure.
Are there any ways to output much higher significant figure, say 12?

Problem 2:
In my normal reconstruction processing, I am trying to use the following:
// Computes average spacing.
    const unsigned int nb_neighbors = 6; // 1 ring
    FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(
                            point_sets,  // CGAL::Point_set_3<Point>
                            nb_neighbors,
                           
CGAL::parameters::point_map(point_sets.point_map())
                        );

        point_sets.add_normal_map();
        CGAL::vcm_estimate_normals(
            point_sets,
            CGAL::to_double(average_spacing)*20,
            CGAL::to_double(average_spacing),
            CGAL::parameters::point_map(point_sets.point_map()).
                              normal_map(point_sets.normal_map())
        );

        Point_set::iterator unoriented_points_begin =
        CGAL::mst_orient_normals(point_sets,
                                 nb_neighbors,
                               
CGAL::parameters::point_map(point_sets.point_map()).
                                                 
normal_map(point_sets.normal_map())
        );
        // Optional: delete points with an unoriented normal
        // if you plan to call a reconstruction algorithm that expects
oriented normals.
        point_sets.remove(unoriented_points_begin, point_sets.end());
        point_sets.collect_garbage();

As you can see from the above output, all normals are <0 0 0>
However, my point cloud contains a lot of planar surfaces with different
orientation.
Are there any things wrong with my code? Parameter problem? or I am doing in
a wrong concept way.

Thank you very much in advance for any suggestions and recommendation.

Best regards,
William



--
Sent from: http://cgal-discuss.949826.n4.nabble.com/

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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

Sebastien Loriot (GeometryFactory)
On 02/09/2018 03:41 AM, williamlai3a wrote:

> Hi All,
>
> I am a newbie to CGAL, I am trying code from CGAL github master build
> (v4.12) to do 3D point set processing.
> I am using the following:
> typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
> typedef Kernel::FT FT;
> typedef Kernel::Point_3 Point;
> typedef Kernel::Vector_3 Vector;
> typedef CGAL::Point_set_3<Point> Point_set;
>
> However, in my original .xyz point cloud, I am having high precision like:
> 841293.765978 818818.600281 90.933151
> 841293.765000 818818.599880 90.906294
> 841293.764292 818818.599046 90.960005
> 841284.839693 818813.763807 90.725665
> 841284.822854 818813.767425 90.684145
> 841284.822320 818813.766970 90.696840
> 841284.821787 818813.766515 90.709534
> 841284.825319 818813.768227 90.721745
>
> After processing normal, and I write back the points to a .xyz, the point
> precision becomes:
> 841294 818819 90.9332 0 0 0
> 841294 818819 90.9063 0 0 0
> 841294 818819 90.96 0 0 0
> 841285 818814 90.7257 0 0 0
> 841285 818814 90.6841 0 0 0
> 841285 818814 90.6968 0 0 0
> 841285 818814 90.7095 0 0 0
> 841285 818814 90.7217 0 0 0
>
> Problem 1:
> Seems to me that the output is being trimmed to 6 significant figure.
> Are there any ways to output much higher significant figure, say 12?
>

6 is the default precision of the stream. You can increase the precision
(the max being 17 if you want to guarantee that a value will be
identical to the one wrote when you read it).


Try something like:
std::ofstream output("out.xyz");
output << std::setprecision(17);


> Problem 2:
> In my normal reconstruction processing, I am trying to use the following:
> // Computes average spacing.
>      const unsigned int nb_neighbors = 6; // 1 ring
>      FT average_spacing = CGAL::compute_average_spacing<Concurrency_tag>(
>                              point_sets,  // CGAL::Point_set_3<Point>
>                              nb_neighbors,
>                            
> CGAL::parameters::point_map(point_sets.point_map())
>                          );
>
>          point_sets.add_normal_map();
>          CGAL::vcm_estimate_normals(
>              point_sets,
>              CGAL::to_double(average_spacing)*20,
>              CGAL::to_double(average_spacing),
>              CGAL::parameters::point_map(point_sets.point_map()).
>                                normal_map(point_sets.normal_map())
>          );
>
>          Point_set::iterator unoriented_points_begin =
>          CGAL::mst_orient_normals(point_sets,
>                                   nb_neighbors,
>                                  
> CGAL::parameters::point_map(point_sets.point_map()).
>                                                    
> normal_map(point_sets.normal_map())
>          );
>          // Optional: delete points with an unoriented normal
>          // if you plan to call a reconstruction algorithm that expects
> oriented normals.
>          point_sets.remove(unoriented_points_begin, point_sets.end());
>          point_sets.collect_garbage();
>
> As you can see from the above output, all normals are <0 0 0>
> However, my point cloud contains a lot of planar surfaces with different
> orientation.
> Are there any things wrong with my code? Parameter problem? or I am doing in
> a wrong concept way.
>

It has probably something to do with the parameters.
Did you try `jet_estimate_normals` that is easier to use?
https://doc.cgal.org/latest/Point_set_processing_3/group__PkgPointSetProcessingAlgorithms.html#ga2ab9546e4d0ef01bd8a26e748046b26a

Sebastien.

> Thank you very much in advance for any suggestions and recommendation.
>
> Best regards,
> William
>
>
>
> --
> Sent from: http://cgal-discuss.949826.n4.nabble.com/
>

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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

andreas.fabri


On 2/9/2018 8:22 AM, Sebastien Loriot (GeometryFactory) wrote:
> On 02/09/2018 03:41 AM, williamlai3a wrote:
>> Hi All,
>>
>> I am a newbie to CGAL, I am trying code from CGAL github master build
>> (v4.12) to do 3D point set processing.
>> I am using the following:

[snip]

>>
>> Problem 1:
>> Seems to me that the output is being trimmed to 6 significant figure.
>> Are there any ways to output much higher significant figure, say 12?
>>
>
> 6 is the default precision of the stream. You can increase the precision
> (the max being 17 if you want to guarantee that a value will be
> identical to the one wrote when you read it).
>
>
> Try something like:
> std::ofstream output("out.xyz");
> output << std::setprecision(17);

Sébastien,

I suggest that we add that line here:
examples/Point_set_processing_3/read_write_xyz_point_set_example.cpp

Best,

Andreas

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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

williamlai3a
In reply to this post by Sebastien Loriot (GeometryFactory)
Thanks for your kind suggestion.
I managed to change the normal estimation code to use jet_estimate_normals:

CGAL::jet_estimate_normals<Concurrency_tag>(
            point_sets,
            12,
            CGAL::parameters::point_map(point_sets.point_map()).
                              normal_map(point_sets.normal_map())
        );

However, it throws some unknown exception after long running on a large
model.
Any advise on what might happen?

Thanks.



--
Sent from: http://cgal-discuss.949826.n4.nabble.com/

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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

williamlai3a
I tried to run the code again, and deleted my try catch.
It shows the following error message:

terminate called after throwing an instance of 'CGAL::Assertion_exception'
  what():  CGAL ERROR: assertion violation!
Expr: parray_ != NULL
File:
/home/william/CGAL/Installation/lib/cmake/CGAL/../../../../Surface_mesh/include/CGAL/Surface_mesh/Properties.h
Line: 518
Aborted (core dumped)

No ideas on why jet_estimate_normals will call things in Surface_mesh

Please kindly advise.
Thanks.
William



--
Sent from: http://cgal-discuss.949826.n4.nabble.com/

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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

Simon Giraudot-2
Hello,

Le 12/02/2018 à 07:11, williamlai3a a écrit :

> I tried to run the code again, and deleted my try catch.
> It shows the following error message:
>
> terminate called after throwing an instance of 'CGAL::Assertion_exception'
>    what():  CGAL ERROR: assertion violation!
> Expr: parray_ != NULL
> File:
> /home/william/CGAL/Installation/lib/cmake/CGAL/../../../../Surface_mesh/include/CGAL/Surface_mesh/Properties.h
> Line: 518
> Aborted (core dumped)
Did you add the normal map (point_set.add_normal_map()) before calling
normal estimation? From your first mail, it seems that you did, but I
just want to check (as a missing normal map could lead to this error).

You're saying that it happens on large data sets after a long time: how
large is it? Is it possible that it exceeds the memory limits of your
computer? (How much RAM do you have?)
> No ideas on why jet_estimate_normals will call things in Surface_mesh
The class CGAL::Point_set_3 relies on some internal code that is from
the Surface_mesh package.

Best,

--
Simon Giraudot, PhD
R&D Engineer
GeometryFactory - http://geometryfactory.com/


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


Reply | Threaded
Open this post in threaded view
|

Re: CGAL::write_xyz_point_set precision and normal problem

williamlai3a
You are right!
Thank you so much!



--
Sent from: http://cgal-discuss.949826.n4.nabble.com/

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