Merge pull request #5461 from sloriot/PMP-decimation

Add coplanar decimation
This commit is contained in:
Laurent Rineau 2023-04-17 10:14:07 +02:00
commit 594682dde3
70 changed files with 60874 additions and 119 deletions

View File

@ -15,6 +15,7 @@
#include <CGAL/property_map.h>
#include <CGAL/boost/graph/iterator.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/value_type_traits.h>
#include <boost/iterator/function_output_iterator.hpp>
@ -222,7 +223,6 @@ namespace impl
{
put(map, pair.first, pair.second);
}
};
template<typename PMAP>
@ -237,6 +237,13 @@ namespace impl
}
}//end of impl
template <class PMAP>
struct value_type_traits<boost::function_output_iterator<impl::Output_iterator_functor<PMAP>>>
{
typedef std::pair<typename impl::Output_iterator_functor<PMAP>::input_t,
typename impl::Output_iterator_functor<PMAP>::output_t> type;
};
} // CGAL

View File

@ -10,6 +10,12 @@ Release date: June 2023
- **Breaking change**: The per package assertions, pre- and postconditions are no longer supported.
### [2D and 3D Linear Geometry Kernel](https://doc.cgal.org/5.6/Manual/packages.html#PkgKernel23)
- Added the functor
[`CompareAngle_3`](https://doc.cgal.org/5.6/Kernel_23/classKernel_1_1CompareAngle__3.html)
to the concept [`Kernel`](https://doc.cgal.org/5.6/Kernel_23/classKernel.html) to compare
an angle defined by three points to the cosinus of another angle.
### [Combinatorial Maps](https://doc.cgal.org/5.6/Manual/packages.html#PkgCombinatorialMaps) [Generalized Maps](https://doc.cgal.org/5.6/Manual/packages.html#PkgGeneralizedMaps) [Linear Cell Complex](https://doc.cgal.org/5.6/Manual/packages.html#PkgLinearCellComplex)
- Added a version that uses indices instead of handles as dart and attribute descriptors. As the indices are integers convertible from and to `std::size_t`, they can be used as index into vectors which store properties. To use the index version, `Use_index` must be defined and be equal to `CGAL::Tag_true` in the item class.
@ -34,6 +40,9 @@ CGAL tetrahedral Delaunay refinement algorithm.
- Added the function `CGAL::Polygon_mesh_processing::remove_almost_degenerate_faces()` to remove badly shaped triangles faces in a mesh.
- Added the functions `CGAL::Polygon_mesh_processing::remesh_planar_patches()` and
`CGAL::Polygon_mesh_processing::remesh_almost_coplanar_patches()` to retriangulate patches of coplanar faces in a mesh.
- Added a named parameter to `CGAL::Polygon_mesh_processing::smooth_shape()` to disable scaling to compensate volume loss.
### [3D Simplicial Mesh Data Structure](https://doc.cgal.org/5.6/Manual/packages.html#PkgSMDS3) (new package)
@ -181,7 +190,6 @@ Release date: June 2022
- Added the function [`invert_selection()`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html#aa428541ebbdd35f9a6e9a3ffd60178df) in the class [`Face_filtered_graph`](https://doc.cgal.org/5.5/BGL/structCGAL_1_1Face__filtered__graph.html), which toggles the selected status of a graph: selected faces are deselected, and unselected faces are selected.
[Release 5.4](https://github.com/CGAL/cgal/releases/tag/v5.4)
-----------

View File

@ -619,7 +619,19 @@ const CGAL::Point_3<Kernel>&r);
/// @}
/// \ingroup kernel_global_function
/*!
compares the angles \f$ \theta_1\f$ and \f$ \theta_2\f$, where
\f$ \theta_1\f$ is the angle in \f$ [0, \pi]\f$ of the triangle
\f$ (a, b, c)\f$ at the vertex `b`, and \f$ \theta_2\f$ is
the angle in \f$ [0, \pi]\f$ such that \f$ cos(\theta_2) = cosine\f$.
\pre `a!=b && c!=b`.
*/
template <typename Kernel>
Comparison_result compare_angle(const CGAL::Point_3<Kernel>& a,
const CGAL::Point_3<Kernel>& b,
const CGAL::Point_3<Kernel>& c,
const Kernel::FT& cosine);
/// \defgroup compare_dihedral_angle_grp CGAL::compare_dihedral_angle()
/// \ingroup kernel_global_function

View File

@ -739,6 +739,33 @@ public:
}; /* end Kernel::CompareAngleWithXAxis_2 */
/*!
\ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept
*/
class CompareAngle_3 {
public:
/// \name Operations
/// A model of this concept must provide:
/// @{
/*!
compares the angles \f$ \theta_1\f$ and \f$ \theta_2\f$, where
\f$ \theta_1\f$ is the angle in \f$ [0, \pi]\f$ of the triangle
\f$ (a, b, c)\f$ at the vertex `b`, and \f$ \theta_2\f$ is
the angle in \f$ [0, \pi]\f$ such that \f$ cos(\theta_2) = cosine\f$.
\pre `a!=b && c!=b`.
*/
Comparison_result operator()(const K::Point_3& a,
const K::Point_3& b,
const K::Point_3& c,
const K::FT& cosine);
};
/*!
\ingroup PkgKernel23ConceptsFunctionObjects
\cgalConcept

View File

@ -1468,6 +1468,11 @@ public:
*/
typedef unspecified_type Less_distance_to_point_3;
/*!
a model of `Kernel::CompareAngle_3`
*/
typedef unspecified_type Compare_angle_3;
/*!
a model of `Kernel::CompareDihedralAngle_3`
*/

View File

@ -160,6 +160,7 @@
- \link compare_signed_distance_to_line_grp `CGAL::compare_signed_distance_to_line()` \endlink
- \link compare_signed_distance_to_plane_grp `CGAL::compare_signed_distance_to_plane()` \endlink
- \link compare_slopes_grp `CGAL::compare_slopes()` \endlink
- `CGAL::compare_angle()`
- \link compare_dihedral_angle_grp `CGAL::compare_dihedral_angle()` \endlink
- \link compare_squared_distance_grp `CGAL::compare_squared_distance()` \endlink
- \link compare_squared_radius_grp `CGAL::compare_squared_radius()` \endlink

View File

@ -196,6 +196,49 @@ namespace CommonKernelFunctors {
{ return assign(t, o); }
};
template <typename K>
class Compare_angle_3
{
typedef typename K::Point_3 Point_3;
typedef typename K::Vector_3 Vector_3;
typedef typename K::FT FT;
public:
typedef typename K::Comparison_result result_type;
result_type
operator()(const Point_3& a, const Point_3& b, const Point_3& c,
const FT& cosine) const
{
typename K::Compute_scalar_product_3 scalar_product = K().compute_scalar_product_3_object();
typename K::Construct_vector_3 vector = K().construct_vector_3_object();
typename K::Compute_squared_length_3 sq_length = K().compute_squared_length_3_object();
const Vector_3 ba = vector(b, a);
const Vector_3 bc = vector(b, c);
typename K::FT sc_prod = scalar_product(ba, bc);
if (sc_prod >= 0)
{
if (cosine >= 0)
return CGAL::compare(CGAL::square(cosine)
* sq_length(ba)*sq_length(bc),
CGAL::square(sc_prod));
else
return SMALLER;
}
else
{
if (cosine >= 0)
return LARGER;
else
return CGAL::compare(CGAL::square(sc_prod),
CGAL::square(cosine)
* sq_length(ba)*sq_length(bc));
}
}
};
template <typename K>
class Compare_dihedral_angle_3
{

View File

@ -309,6 +309,15 @@ collinear_are_strictly_ordered_along_line(const Point_3<K> &p,
return internal::collinear_are_strictly_ordered_along_line(p, q, r, K());
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const Point_3<K>& a, const Point_3<K>& b, const Point_3<K>& c,
const typename K::FT& cosine)
{
return internal::compare_angle(a, b, c, cosine, K());
}
template < class K >
inline
typename K::Comparison_result

View File

@ -321,6 +321,17 @@ collinear_are_strictly_ordered_along_line(
return k.collinear_are_strictly_ordered_along_line_3_object()(p, q, r);
}
template < class K >
inline
typename K::Comparison_result
compare_angle(const typename K::Point_3& a,
const typename K::Point_3& b,
const typename K::Point_3& c,
const typename K::FT& cosine,
const K& k)
{
return k.compare_angle_3_object()(a, b, c, cosine);
}
template < class K >
inline

View File

@ -98,6 +98,8 @@ CGAL_Kernel_pred(Collinear_2,
collinear_2_object)
CGAL_Kernel_pred(Collinear_3,
collinear_3_object)
CGAL_Kernel_pred(Compare_angle_3,
compare_angle_3_object)
CGAL_Kernel_pred(Compare_angle_with_x_axis_2,
compare_angle_with_x_axis_2_object)
CGAL_Kernel_pred(Compare_dihedral_angle_3,

View File

@ -0,0 +1,39 @@
// Copyright (c) 2009 GeometryFactory (France)
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
//
// Author(s) : Laurent Rineau, Sebastien Loriot
//
template <class R>
bool
_test_compare_angle_3(const R& rep)
{
typedef typename R::Point_3 Point_3;
typedef typename R::FT FT;
typename R::Compare_angle_3 compare_angle
= rep.compare_angle_3_object();
for(int theta1 = -170; theta1 <= 180; theta1+= 10)
{
const double angle1 = CGAL_PI*theta1/180.;
Point_3 a(1, 0, 0);
Point_3 b(0, 0, 0);
Point_3 c((int)(std::cos(angle1)*1000), (int)(std::sin(angle1)*1000), 0);
for(int theta2 = -170; theta2 <= 180; theta2+= 10) {
if (theta1!=0 && theta1!=180 && abs(theta1)==abs(theta2)) continue;
const double angle2 = CGAL_PI*theta2/180.;
if ( CGAL::compare(abs(theta1), abs(theta2)) != CGAL::compare_angle(a, b, c, FT(std::cos(angle2))) )
return false;
if ( CGAL::compare(abs(theta1), abs(theta2)) != compare_angle(a, b, c, FT(std::cos(angle2))) )
return false;
} // end loop on theta2
} // end loop and theta1
return true;
}

View File

@ -22,6 +22,7 @@
#include <CGAL/intersections.h>
#include <CGAL/squared_distance_3.h>
#include <CGAL/_test_compare_dihedral_angle_3.h>
#include <CGAL/_test_compare_angle_3.h>
#include <CGAL/Has_member.h>
#include <CGAL/use.h>
@ -624,6 +625,10 @@ test_new_3(const R& rep)
bool tmp = _test_compare_dihedral_angle_3(rep);
assert(tmp);
}
{
bool tmp = _test_compare_angle_3(rep);
assert(tmp);
}
typename R::Compare_distance_3 compare_dist
= rep.compare_distance_3_object();

View File

@ -22,4 +22,7 @@ EXCLUDE_SYMBOLS += experimental
HTML_EXTRA_FILES = ${CGAL_PACKAGE_DOC_DIR}/fig/selfintersections.jpg \
${CGAL_PACKAGE_DOC_DIR}/fig/mesh_smoothing.png \
${CGAL_PACKAGE_DOC_DIR}/fig/shape_smoothing.png
${CGAL_PACKAGE_DOC_DIR}/fig/shape_smoothing.png \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_cheese.png \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_colors.png \
${CGAL_PACKAGE_DOC_DIR}/fig/decimate_rg_joint.png

View File

@ -113,6 +113,8 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
\cgalCRPSection{Meshing Functions}
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::isotropic_remeshing()` \endlink
- \link PMP_meshing_grp `CGAL::Polygon_mesh_processing::split_long_edges()` \endlink
- `CGAL::Polygon_mesh_processing::remesh_planar_patches()`
- `CGAL::Polygon_mesh_processing::remesh_almost_planar_patches()`
- `CGAL::Polygon_mesh_processing::refine()`
- `CGAL::Polygon_mesh_processing::fair()`
- `CGAL::Polygon_mesh_processing::triangulate_face()`
@ -237,6 +239,9 @@ The page \ref bgl_namedparameters "Named Parameters" describes their usage.
- `CGAL::Polygon_mesh_processing::sharp_edges_segmentation()`
- `CGAL::Polygon_mesh_processing::detect_sharp_edges()`
- `CGAL::Polygon_mesh_processing::detect_vertex_incident_patches()`
- `CGAL::Polygon_mesh_processing::region_growing_of_planes_on_faces()`
- `CGAL::Polygon_mesh_processing::detect_corners_of_regions()`
\cgalCRPSection{Miscellaneous}
- `CGAL::Polygon_mesh_slicer`

View File

@ -38,7 +38,7 @@ The page \ref bgl_namedparameters describes their usage.
\subsection PMPOutline Outline
The algorithms described in this manual are organized in sections:
- \ref PMPMeshing : meshing algorithms, including triangulation of non-triangulated
meshes, refinement, optimization by fairing, isotropic remeshing of triangulated surface meshes
meshes, refinement, optimization by fairing, remeshing of triangulated surface meshes
and smoothing algorithms.
- \ref Coref_section : methods to corefine triangle meshes and to compute
boolean operations out of corefined closed triangle meshes.
@ -152,6 +152,55 @@ An example of how to remesh a given triangulated surface mesh with the Delaunay
algorithm while preserving the detected sharp edges
is given in \ref Polygon_mesh_processing/delaunay_remeshing_example.cpp
\paragraph Decimate Remeshing of (Almost) Planar Patches
When many triangles are used to describe a planar region of a model, one might wish to simplify the mesh
in this region to use few elements, or even a single large polygonal face when the region makes up a simply connected patch.
This can be achieved using the function `CGAL::Polygon_mesh_processing::remesh_planar_patches()`.
This function performs the detection of the planar regions, using geometric predicates for coplanarity and
collinearity checks. If these tests are performed exactly, the planar regions can be unexpectedly small due to the
input in fact not being perfectly planar. To palliate this, it is possible to specify a threshold on the angle
between adjacent faces (resp. segments) such that they are considered coplanar (resp. collinear).
However, this tolerance threshold is only local and there is no global control, which can have undesired effects, such as in the classic example of a densely sampled circle arc where all points are eventually found
to be almost collinear). To circumvent this situation, we provide the function
`CGAL::Polygon_mesh_processing::remesh_almost_planar_patches()` , which expects the segmentation into
planar patches and corners to be provided by the user. Such segmentation can be obtained using the function
`CGAL::Polygon_mesh_processing::region_growing_of_planes_on_faces()`, which
uses the region growing algorithm to detect planar regions in a mesh with global and local criteria.
Similarly, the function `CGAL::Polygon_mesh_processing::detect_corners_of_regions()` can be used
to detect corner vertices on the border of the planar regions detected by running the region growing
algorithm on border segments of the patch.
\cgalFigureAnchor{decimate_cheese}
<center>
<table border=0>
<tr>
<td><img src="decimate_cheese.png" style="width:100%;"/></td>
<td><img src="decimate_colors.png" style="width:100%;"/></td>
</tr>
<tr align="center"><td>(a)</td><td>(b)</td></tr>
</table>
</center>
\cgalFigureCaptionBegin{decimate_cheese}
Remeshing of planar patches in two models: (a) planar patches in the cheese model are retriangulated
(b) the remeshed version of this model contains 14 vertices and
has not been retriangulated, the patch ids have been assigned to the input
and the output meshes, allowing an identical color scheme.
\cgalFigureCaptionEnd
\cgalFigureAnchor{decimate_rg_sphere}
<center>
<table border=0>
<tr>
<td><img src="decimate_rg_joint.png" style="width:100%;"/></td>
</tr>
</table>
</center>
\cgalFigureCaptionBegin{decimate_rg_sphere}
Remeshing of planar patches using region growing for the detection of planar patches.
From left to right: input mesh, remeshed version, remeshed version using the same angle threshold but larger approximation error.
\cgalFigureEnd
\subsubsection Smoothing
Smoothing of a triangulated mesh region can be achieved with algorithms that aim at either mesh smoothing or shape smoothing.

View File

@ -41,4 +41,6 @@
\example Polygon_mesh_processing/triangulate_faces_split_visitor_example.cpp
\example Polygon_mesh_processing/hausdorff_bounded_error_distance_example.cpp
\example Polygon_mesh_processing/cc_compatible_orientations.cpp
\example Polygon_mesh_processing/remesh_planar_patches.cpp
\example Polygon_mesh_processing/remesh_almost_planar_patches.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

View File

@ -19,6 +19,7 @@ create_single_source_cgal_program("point_inside_example.cpp")
create_single_source_cgal_program("triangulate_faces_example.cpp")
create_single_source_cgal_program("triangulate_faces_split_visitor_example.cpp")
create_single_source_cgal_program("connected_components_example.cpp")
create_single_source_cgal_program("remesh_planar_patches.cpp")
create_single_source_cgal_program( "face_filtered_graph_example.cpp")
create_single_source_cgal_program("orient_polygon_soup_example.cpp")
create_single_source_cgal_program("triangulate_polyline_example.cpp")
@ -70,6 +71,8 @@ if(TARGET CGAL::Eigen3_support)
target_link_libraries(mesh_smoothing_example PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("delaunay_remeshing_example.cpp")
target_link_libraries(delaunay_remeshing_example PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("remesh_almost_planar_patches.cpp")
target_link_libraries(remesh_almost_planar_patches PUBLIC CGAL::Eigen3_support)
else()
message(STATUS "NOTICE: Examples that use Eigen will not be compiled.")
endif()

View File

@ -0,0 +1,66 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/region_growing.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <CGAL/Polygon_mesh_processing/random_perturbation.h>
#include <boost/property_map/vector_property_map.hpp>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface_mesh;
namespace PMP = CGAL::Polygon_mesh_processing;
int main()
{
Surface_mesh sm;
CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/fandisk.off"), sm);
//apply a perturbation to input vertices so that points are no longer coplanar
PMP::random_perturbation(sm, 0.001);
// declare vectors to store mesh properties
std::vector<std::size_t> region_ids(num_faces(sm));
std::vector<std::size_t> corner_id_map(num_vertices(sm), -1); // corner status of vertices
std::vector<bool> ecm(num_edges(sm), false); // mark edges at the boundary of regions
boost::vector_property_map<CGAL::Epick::Vector_3> normal_map; // normal of the supporting planes of the regions detected
// detect planar regions in the mesh
std::size_t nb_regions =
PMP::region_growing_of_planes_on_faces(sm,
CGAL::make_random_access_property_map(region_ids),
CGAL::parameters::cosine_of_maximum_angle(0.98).
region_primitive_map(normal_map).
maximum_distance(0.011));
// detect corner vertices on the boundary of planar regions
std::size_t nb_corners =
PMP::detect_corners_of_regions(sm,
CGAL::make_random_access_property_map(region_ids),
nb_regions,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::parameters::cosine_of_maximum_angle(0.98).
maximum_distance(0.011).
edge_is_constrained_map(CGAL::make_random_access_property_map(ecm)));
// run the remeshing algorithm using filled properties
Surface_mesh out;
PMP::remesh_almost_planar_patches(sm,
out,
nb_regions, nb_corners,
CGAL::make_random_access_property_map(region_ids),
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map));
CGAL::IO::write_polygon_mesh("fandisk_remeshed.off", out);
return 0;
}

View File

@ -0,0 +1,49 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Polygon_mesh_processing/detect_features.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <iostream>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface_mesh;
namespace PMP = CGAL::Polygon_mesh_processing;
int main()
{
Surface_mesh sm;
CGAL::IO::read_polygon_mesh(CGAL::data_file_path("meshes/cube_quad.off"), sm);
// triangulate faces;
PMP::triangulate_faces(sm);
std::cout << "Input mesh has " << faces(sm).size() << " faces" << std::endl;
assert(faces(sm).size()==12);
Surface_mesh::Property_map<Surface_mesh::Edge_index, bool> ecm =
sm.add_property_map<Surface_mesh::Edge_index, bool>("ecm",false).first;
// detect sharp edges of the cube
PMP::detect_sharp_edges(sm, 60, ecm);
// create a remeshed version of the cube with many elements
PMP::isotropic_remeshing(faces(sm), 0.1, sm, CGAL::parameters::edge_is_constrained_map(ecm));
CGAL::IO::write_polygon_mesh("cube_remeshed.off", sm, CGAL::parameters::stream_precision(17));
assert(faces(sm).size()>100);
// decimate the mesh
Surface_mesh out;
PMP::remesh_planar_patches(sm, out);
CGAL::IO::write_polygon_mesh("cube_decimated.off", out, CGAL::parameters::stream_precision(17));
// we should be back to 12 faces
std::cout << "Output mesh has " << faces(out).size() << " faces" << std::endl;
assert(faces(out).size()==12);
return EXIT_SUCCESS;
}

View File

@ -384,10 +384,6 @@ namespace internal {
void split_long_edges(const EdgeRange& edge_range,
const double& high)
{
typedef boost::bimap<
boost::bimaps::set_of<halfedge_descriptor>,
boost::bimaps::multiset_of<double, std::greater<double> > > Boost_bimap;
typedef typename Boost_bimap::value_type long_edge;
#ifdef CGAL_PMP_REMESHING_VERBOSE
std::cout << "Split long edges (" << high << ")...";
@ -396,12 +392,17 @@ namespace internal {
double sq_high = high*high;
//collect long edges
Boost_bimap long_edges;
typedef std::pair<halfedge_descriptor, double> H_and_sql;
std::multiset< H_and_sql, std::function<bool(H_and_sql,H_and_sql)> >
long_edges(
[](const H_and_sql& p1, const H_and_sql& p2)
{ return p1.second > p2.second; }
);
for(edge_descriptor e : edge_range)
{
double sqlen = sqlength(e);
if (sqlen > sq_high)
long_edges.insert(long_edge(halfedge(e, mesh_), sqlen));
long_edges.emplace(halfedge(e, mesh_), sqlen);
}
//split long edges
@ -411,10 +412,10 @@ namespace internal {
while (!long_edges.empty())
{
//the edge with longest length
typename Boost_bimap::right_map::iterator eit = long_edges.right.begin();
halfedge_descriptor he = eit->second;
double sqlen = eit->first;
long_edges.right.erase(eit);
auto eit = long_edges.begin();
halfedge_descriptor he = eit->first;
double sqlen = eit->second;
long_edges.erase(eit);
//split edge
Point refinement_point = this->midpoint(he);
@ -438,8 +439,8 @@ namespace internal {
if (sqlen_new > sq_high)
{
//if it was more than twice the "long" threshold, insert them
long_edges.insert(long_edge(hnew, sqlen_new));
long_edges.insert(long_edge(next(hnew, mesh_), sqlen_new));
long_edges.emplace(hnew, sqlen_new);
long_edges.emplace(next(hnew, mesh_), sqlen_new);
}
//insert new edges to keep triangular faces, and update long_edges
@ -479,25 +480,26 @@ namespace internal {
//is split at its midpoint and the two adjacent triangles are bisected (2-4 split)"
void split_long_edges(const double& high)
{
typedef boost::bimap<
boost::bimaps::set_of<halfedge_descriptor>,
boost::bimaps::multiset_of<double, std::greater<double> > > Boost_bimap;
typedef typename Boost_bimap::value_type long_edge;
#ifdef CGAL_PMP_REMESHING_VERBOSE
std::cout << "Split long edges (" << high << ")..." << std::endl;
#endif
double sq_high = high*high;
//collect long edges
Boost_bimap long_edges;
typedef std::pair<halfedge_descriptor, double> H_and_sql;
std::multiset< H_and_sql, std::function<bool(H_and_sql,H_and_sql)> >
long_edges(
[](const H_and_sql& p1, const H_and_sql& p2)
{ return p1.second > p2.second; }
);
for(edge_descriptor e : edges(mesh_))
{
if (!is_split_allowed(e))
continue;
double sqlen = sqlength(e);
if(sqlen > sq_high)
long_edges.insert(long_edge(halfedge(e, mesh_), sqlen));
long_edges.emplace(halfedge(e, mesh_), sqlen);
}
//split long edges
@ -507,13 +509,13 @@ namespace internal {
while (!long_edges.empty())
{
//the edge with longest length
typename Boost_bimap::right_map::iterator eit = long_edges.right.begin();
halfedge_descriptor he = eit->second;
double sqlen = eit->first;
long_edges.right.erase(eit);
auto eit = long_edges.begin();
halfedge_descriptor he = eit->first;
double sqlen = eit->second;
long_edges.erase(eit);
#ifdef CGAL_PMP_REMESHING_VERBOSE_PROGRESS
std::cout << "\r\t(" << long_edges.left.size() << " long edges, ";
std::cout << "\r\t(" << long_edges.size() << " long edges, ";
std::cout << nb_splits << " splits)";
std::cout.flush();
#endif
@ -550,8 +552,8 @@ namespace internal {
if (sqlen_new > sq_high)
{
//if it was more than twice the "long" threshold, insert them
long_edges.insert(long_edge(hnew, sqlen_new));
long_edges.insert(long_edge(next(hnew, mesh_), sqlen_new));
long_edges.emplace(hnew, sqlen_new);
long_edges.emplace(next(hnew, mesh_), sqlen_new);
}
//insert new edges to keep triangular faces, and update long_edges
@ -573,7 +575,7 @@ namespace internal {
{
double sql = sqlength(hnew2);
if (sql > sq_high)
long_edges.insert(long_edge(hnew2, sql));
long_edges.emplace(hnew2, sql);
}
}
@ -596,7 +598,7 @@ namespace internal {
{
double sql = sqlength(hnew2);
if (sql > sq_high)
long_edges.insert(long_edge(hnew2, sql));
long_edges.emplace(hnew2, sql);
}
}
}

View File

@ -54,6 +54,18 @@ PM_Point convert_to_pm_point(const std::array<PS_FT, 3>& p)
return PM_Point(p[0], p[1], p[2]);
}
template <class OutputIterator, typename Value_type = typename value_type_traits<OutputIterator>::type>
struct Polygon_and_Point_id_helper
{
typedef std::remove_cv_t<std::remove_reference_t<typename Value_type::first_type>> type;
};
template <class OutputIterator>
struct Polygon_and_Point_id_helper<OutputIterator, void>
{
typedef std::size_t type;
};
template <typename PointRange,
typename PolygonRange,
typename PointMap = typename CGAL::GetPointMap<PointRange>::const_type>
@ -85,9 +97,11 @@ public:
const bool insert_isolated_vertices = true)
{
typedef typename boost::graph_traits<PolygonMesh>::vertex_descriptor vertex_descriptor;
typedef typename boost::property_traits<VertexPointMap>::value_type PM_Point;
typedef typename Polygon_and_Point_id_helper<V2V>::type Point_id;
typedef typename Polygon_and_Point_id_helper<F2F>::type Polygon_id;
reserve(pmesh, static_cast<typename boost::graph_traits<PolygonMesh>::vertices_size_type>(m_points.size()),
static_cast<typename boost::graph_traits<PolygonMesh>::edges_size_type>(2*m_polygons.size()),
static_cast<typename boost::graph_traits<PolygonMesh>::faces_size_type>(m_polygons.size()));
@ -106,7 +120,7 @@ public:
}
std::vector<vertex_descriptor> vertices(m_points.size());
for(std::size_t i = 0, end = m_points.size(); i < end; ++i)
for(Point_id i = 0, end = static_cast<Point_id>(m_points.size()); i < end; ++i)
{
if(!insert_isolated_vertices && !not_isolated.test(i))
continue;
@ -117,7 +131,7 @@ public:
*i2v++ = std::make_pair(i, vertices[i]);
}
for(std::size_t i = 0, end = m_polygons.size(); i < end; ++i)
for(Polygon_id i = 0, end = static_cast<Polygon_id>(m_polygons.size()); i < end; ++i)
{
const Polygon& polygon = m_polygons[i];
const std::size_t size = polygon.size();
@ -277,6 +291,20 @@ bool is_polygon_soup_a_polygon_mesh(const PolygonRange& polygons)
* \cgalParamDefault{`Emptyset_iterator`}
* \cgalParamNEnd
*
* \cgalParamNBegin{point_to_vertex_map}
* \cgalParamDescription{a property map associating each soup point of `points` to a vertex of `out`.}
* \cgalParamType{a class model of `ReadablePropertyMap` with an integer type as key type and
* `boost::graph_traits<PolygonMesh>::%vertex_descriptor` as value type.}
* \cgalParamDefault{unused}
* \cgalParamNEnd
*
* \cgalParamNBegin{polygon_to_face_map}
* \cgalParamDescription{a property map associating each soup polygon of `polygons` to a face of `out`}
* \cgalParamType{a class model of `ReadablePropertyMap` with an integer type as key type and
* `boost::graph_traits<PolygonMesh>::%face_descriptor` as value type.}
* \cgalParamDefault{unused}
* \cgalParamNEnd
*
* \cgalNamedParamsEnd
*
* @param np_pm an optional sequence of \ref bgl_namedparameters "Named Parameters" among the ones listed below
@ -321,9 +349,16 @@ void polygon_soup_to_polygon_mesh(const PointRange& points,
internal::PS_to_PM_converter<PointRange, PolygonRange, Point_map> converter(points, polygons, pm);
converter(out, vpm,
choose_parameter(get_parameter(np_ps, internal_np::point_to_vertex_output_iterator),
impl::make_functor(get_parameter(np_ps, internal_np::vertex_to_vertex_map))),
impl::make_functor(get_parameter(np_ps, internal_np::point_to_vertex_map))),
choose_parameter(get_parameter(np_ps, internal_np::polygon_to_face_output_iterator),
impl::make_functor(get_parameter(np_ps, internal_np::face_to_face_map))));
impl::make_functor(get_parameter(np_ps, internal_np::polygon_to_face_map))));
CGAL_static_assertion_msg(
(parameters::is_default_parameter<NamedParameters_PS,internal_np::vertex_to_vertex_map_t>::value),
"Named parameter vertex_to_vertex_map was renamed point_to_vertex_map");
CGAL_static_assertion_msg(
(parameters::is_default_parameter<NamedParameters_PS,internal_np::face_to_face_map_t>::value),
"Named parameter face_to_face_map was renamed polygon_to_face_map");
}
} // namespace Polygon_mesh_processing

View File

@ -79,6 +79,8 @@ if(TARGET CGAL::Eigen3_support)
target_link_libraries(test_shape_smoothing PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("delaunay_remeshing_test.cpp")
target_link_libraries(delaunay_remeshing_test PUBLIC CGAL::Eigen3_support)
create_single_source_cgal_program("test_decimation_of_planar_patches.cpp")
target_link_libraries(test_decimation_of_planar_patches PUBLIC CGAL::Eigen3_support)
else()
message(STATUS "NOTICE: Tests that use the Eigen library will not be compiled.")
endif()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
OFF
38 72 0
-1.5425534248352051 2.0011272430419922 2.1056604385375977
-2.4678716659545898 1.843524694442749 1.0478570461273193
-2.3172659873962402 1.3054063320159912 1.9416441917419434
-2.2937459945678711 2.210951566696167 2.7315070629119873
-2.4685182571411133 1.9557313919067383 2.6072971820831299
-2.6432909965515137 1.7005102634429932 2.4830870628356934
-2.0433511734008789 2.1410109996795654 2.5228936672210693
-2.718266487121582 1.9134653806686401 1.2564704418182373
-1.6762199401855469 2.2038135528564453 1.8772693872451782
-2.9517297744750977 1.6479761600494385 2.1304864883422852
-2.5676684379577637 1.3753491640090942 2.1502640247344971
-1.7929482460021973 2.0710680484771729 2.3142738342285156
-1.7173261642456055 1.7459070682525635 1.9814505577087402
-1.9435539245605469 2.6091864109039307 1.4204866886138916
-1.8920989036560059 1.4906859397888184 1.8572404384613037
-2.3342046737670898 1.6408385038375854 1.2762479782104492
-2.642967700958252 1.6444073915481567 1.7033674716949463
-2.0052127838134766 1.9223260879516602 1.576758861541748
-2.1183261871337891 2.353966236114502 1.2962768077850342
-2.5813088417053223 2.3312678337097168 1.5470952987670898
-2.4443511962890625 2.7490699291229248 1.8377199172973633
-2.6947460174560547 2.8190107345581055 2.0463333129882812
-2.066871166229248 1.2354656457901001 1.7330307960510254
-2.2005376815795898 1.4381518363952637 1.5046396255493164
-3.2190637588500977 2.0533490180969238 1.673703670501709
-2.8180632591247559 1.4452899694442749 2.358877420425415
-2.8695182800292969 2.5637903213500977 1.9221234321594238
-2.4274125099182129 2.4136378765106201 2.5031161308288574
-2.118649959564209 2.4100689888000488 2.0759971141815186
-2.7564048767089844 2.132150411605835 2.2026054859161377
-3.0853967666625977 1.8506628274917603 1.9020946025848389
-2.5610795021057129 2.6163244247436523 2.2747242450714111
-2.2930994033813477 2.0987448692321777 1.1720666885375977
-2.1939487457275391 2.6791272163391113 1.6291000843048096
-1.8098869323730469 2.4065003395080566 1.6488776206970215
-2.9686689376831055 1.9834082126617432 1.465090274810791
-2.1803088188171387 1.7232086658477783 2.2322690486907959
-3.0442914962768555 2.3085691928863525 1.7979133129119873
3 8 11 0
3 8 12 17
3 32 15 1
3 13 18 33
3 36 10 2
3 2 10 16
3 4 6 3
3 25 10 5
3 9 5 29
3 5 4 29
3 7 1 15
3 32 1 7
3 28 6 11
3 20 31 28
3 32 7 19
3 36 14 12
3 8 28 11
3 16 10 9
3 28 27 6
3 12 11 36
3 0 11 12
3 35 16 30
3 13 34 18
3 12 14 17
3 15 17 23
3 15 23 16
3 7 15 16
3 3 6 27
3 3 27 4
3 17 18 34
3 5 10 36
3 22 2 23
3 19 18 32
3 26 20 19
3 23 2 16
3 21 20 26
3 31 20 21
3 31 21 26
3 5 36 4
3 22 14 2
3 14 22 23
3 30 37 24
3 12 8 0
3 9 10 25
3 35 24 37
3 13 33 34
3 30 24 35
3 14 36 2
3 29 31 26
3 4 27 29
3 34 33 28
3 28 33 20
3 29 37 30
3 25 5 9
3 9 29 30
3 30 16 9
3 31 27 28
3 29 27 31
3 35 37 19
3 23 17 14
3 15 32 17
3 19 20 33
3 34 8 17
3 28 8 34
3 7 16 35
3 7 35 19
3 36 6 4
3 11 6 36
3 18 19 33
3 37 26 19
3 26 37 29
3 32 18 17

View File

@ -0,0 +1,114 @@
OFF
38 72 0
3.5397257804870605 0.50155007839202881 0.71940517425537109
2.6144077777862549 0.34394717216491699 -0.33839845657348633
2.7891786098480225 0.59916532039642334 -0.21418976783752441
2.3258743286132812 0.63257288932800293 0.81634986400604248
2.6379303932189941 1.2494919300079346 0.4514625072479248
2.6137626171112061 0.45615625381469727 1.2210431098937988
2.5211987495422363 1.1167490482330322 0.88846683502197266
3.2893285751342773 0.57149136066436768 0.92802047729492188
2.8883283138275146 1.1795504093170166 0.24284648895263672
2.7885334491729736 0.71137428283691406 1.3452516794204712
2.5146126747131348 -0.12422895431518555 0.76400661468505859
2.2642157077789307 -0.054287552833557129 0.97262191772460938
1.863215446472168 0.5537714958190918 0.28744816780090332
2.0379862785339355 0.80898964405059814 0.41165685653686523
3.1901788711547852 -0.0088937282562255859 0.47098398208618164
2.7480731010437012 0.14126282930374146 -0.11000943183898926
3.4060602188110352 0.70423442125320435 0.49101614952087402
2.5009703636169434 0.83169031143188477 0.16083979606628418
2.2127623558044434 1.0642153024673462 0.53586924076080322
2.6548681259155273 0.9140586256980896 1.1168627738952637
3.1387255191802979 1.1096091270446777 0.034231185913085938
2.1136126518249512 0.48383009433746338 0.078832864761352539
2.3875331878662109 1.319433331489563 0.66007781028747559
2.9076576232910156 0.21673417091369629 0.83656430244445801
1.9968808889389038 0.35108715295791626 0.51583719253540039
3.0763490200042725 0.41475355625152588 0.1923222541809082
2.9639546871185303 0.85439109802246094 -0.089977264404296875
2.8817424774169922 -0.061427593231201172 0.11838626861572266
3.0154080390930176 -0.26411187648773193 0.34677529335021973
2.7650105953216553 -0.19417047500610352 0.55539059638977051
3.2723908424377441 0.9069247841835022 0.26262021064758301
2.4503841400146484 0.13884997367858887 0.31381893157958984
2.9636294841766357 0.9104917049407959 0.68974149227142334
3.0389304161071777 0.6414330005645752 1.1366362571716309
2.3640105724334717 0.41388857364654541 -0.12978315353393555
2.1305503845214844 0.14839679002761841 0.74423301219940186
2.4389865398406982 0.20093059539794922 1.0968306064605713
3.364954948425293 0.24633204936981201 0.59519648551940918
3 15 34 1
3 0 7 37
3 16 7 0
3 0 37 16
3 31 24 21
3 17 8 26
3 10 29 23
3 31 29 10
3 2 15 1
3 19 6 3
3 32 6 19
3 17 4 8
3 5 3 36
3 6 18 3
3 23 37 7
3 30 8 32
3 33 19 9
3 11 10 36
3 35 10 11
3 11 36 35
3 12 24 13
3 21 24 12
3 12 13 21
3 3 18 13
3 34 17 2
3 23 29 14
3 32 7 16
3 15 25 27
3 30 32 16
3 3 35 36
3 29 31 27
3 13 18 17
3 9 19 5
3 9 5 33
3 20 30 26
3 8 30 20
3 20 26 8
3 34 21 17
3 6 4 22
3 33 5 23
3 13 24 3
3 17 26 2
3 32 4 6
3 2 26 25
3 14 28 27
3 29 28 14
3 27 28 29
3 22 4 18
3 22 18 6
3 30 25 26
3 31 15 27
3 33 7 32
3 34 31 21
3 10 35 31
3 35 24 31
3 25 16 37
3 17 18 4
3 32 8 4
3 1 34 2
3 25 30 16
3 25 14 27
3 23 5 36
3 10 23 36
3 19 33 32
3 17 21 13
3 25 37 14
3 24 35 3
3 15 31 34
3 37 23 14
3 7 33 23
3 2 25 15
3 19 3 5

View File

@ -0,0 +1,171 @@
OFF
57 110 0
3.3128511905670166 1.4770362377166748 1.7178813219070435
2.9636294841766357 0.9104917049407959 0.68974149227142334
2.5211987495422363 1.1167490482330322 0.88846683502197266
2.5623040199279785 1.5746514797210693 0.7842864990234375
4.0646886825561523 1.1550029516220093 -0.4674065113067627
2.7885334491729736 0.71137428283691406 1.3452516794204712
2.9633042812347412 0.96659243106842041 1.4694602489471436
3.7945542335510254 1.3824794292449951 -0.10743498802185059
3.408212423324585 0.99434208869934082 1.2337028980255127
4.0640435218811035 1.2672119140625 1.0920348167419434
4.3144383430480957 1.1972712278366089 0.88342142105102539
3.1380801200866699 1.2218180894851685 1.5936727523803711
4.1638407707214355 1.7353873252868652 -0.010372161865234375
4.8152356147766113 1.0573877096176147 0.46618819236755371
3.1791858673095703 1.679720401763916 1.4894924163818359
4.352576732635498 0.97858625650405884 -0.062713623046875
4.2559938430786133 1.4854962825775146 0.37342500686645508
3.9134383201599121 1.8053302764892578 0.19824743270874023
2.6548681259155273 0.9140586256980896 1.1168627738952637
2.7370800971984863 1.8298771381378174 0.90849888324737549
4.0235834121704102 0.69710057973861694 -0.36322617530822754
2.9118509292602539 2.0850951671600342 1.0327074527740479
2.3875331878662109 1.319433331489563 0.66007781028747559
3.2723908424377441 0.9069247841835022 0.26262021064758301
4.5479011535644531 1.4627623558044434 0.0094034671783447266
4.4142355918884277 1.6654467582702637 -0.21898555755615234
4.2394647598266602 1.4102286100387573 -0.34319424629211426
4.157252311706543 0.49441021680831909 -0.13483047485351562
4.2909178733825684 0.29172587394714355 0.093558549880981445
4.4656887054443359 0.54694390296936035 0.21776723861694336
3.4126460552215576 1.9452122449874878 0.61547625064849854
3.1622481346130371 2.0151538848876953 0.82409214973449707
3.38912034034729 1.0396684408187866 -0.17438220977783203
3.0072121620178223 1.6024011373519897 0.54852914810180664
2.8883283138275146 1.1795504093170166 0.24284648895263672
3.2893285751342773 0.57149136066436768 0.92802047729492188
3.0389304161071777 0.6414330005645752 1.1366362571716309
4.5648407936096191 1.1273283958435059 0.67480158805847168
4.195554256439209 0.77442049980163574 0.57773876190185547
3.4060602188110352 0.70423442125320435 0.49101614952087402
3.7901206016540527 0.4316093921661377 0.51079177856445312
3.7148218154907227 0.70066744089126587 0.063894748687744141
3.6395230293273926 0.96972554922103882 -0.38300180435180664
3.7174763679504395 1.6378555297851562 0.81809937953948975
3.5397257804870605 0.50155007839202881 0.71940517425537109
2.6379303932189941 1.2494919300079346 0.4514625072479248
3.8899178504943848 0.89978492259979248 -0.59161520004272461
4.6815700531005859 1.2600719928741455 0.23779916763305664
4.6404647827148438 0.8021695613861084 0.3419795036315918
3.1387255191802979 1.1096091270446777 0.034231185913085938
3.0455164909362793 1.8824107646942139 1.2610964775085449
3.5632481575012207 1.4070948362350464 1.5092660188674927
3.8136463165283203 1.3371531963348389 1.3006501197814941
4.0405230522155762 0.36166656017303467 0.30217194557189941
3.4710955619812012 1.6569856405258179 1.1254680156707764
2.8501920700073242 1.3982347249984741 1.1889796257019043
3.6630432605743408 1.8752709627151489 0.4068608283996582
3 44 35 39
3 0 51 14
3 11 51 0
3 11 0 14
3 3 2 55
3 18 2 1
3 22 2 3
3 20 46 4
3 1 34 23
3 5 18 36
3 6 18 5
3 6 5 36
3 12 7 17
3 12 17 16
3 24 12 16
3 11 8 51
3 29 27 15
3 9 43 52
3 10 43 9
3 52 8 9
3 6 8 11
3 39 35 1
3 12 26 7
3 39 1 23
3 47 37 13
3 19 50 21
3 4 7 26
3 19 55 50
3 55 11 14
3 29 15 48
3 16 10 37
3 33 45 3
3 43 16 17
3 55 2 18
3 53 41 27
3 33 19 31
3 20 15 27
3 20 27 41
3 3 19 33
3 55 19 3
3 49 23 34
3 31 19 21
3 21 50 31
3 22 45 2
3 3 45 22
3 41 39 23
3 25 24 26
3 12 24 25
3 25 26 12
3 38 37 10
3 2 45 1
3 4 26 15
3 28 53 27
3 29 53 28
3 28 27 29
3 16 37 47
3 54 43 30
3 30 33 31
3 31 54 30
3 49 32 23
3 49 34 33
3 36 35 8
3 1 35 36
3 37 48 13
3 8 44 9
3 48 38 29
3 8 35 44
3 6 36 8
3 48 37 38
3 39 40 44
3 24 16 47
3 32 42 41
3 56 30 43
3 38 9 44
3 45 34 1
3 33 34 45
3 40 39 41
3 46 42 4
3 42 32 7
3 24 47 15
3 13 48 47
3 20 42 46
3 53 40 41
3 7 32 49
3 7 49 56
3 31 50 54
3 50 14 54
3 51 54 14
3 55 14 50
3 8 52 51
3 10 9 38
3 56 33 30
3 53 38 40
3 1 36 18
3 56 49 33
3 42 7 4
3 43 54 52
3 20 41 42
3 55 6 11
3 17 7 56
3 23 32 41
3 43 10 16
3 15 20 4
3 26 24 15
3 48 15 47
3 44 40 38
3 29 38 53
3 6 55 18
3 51 52 54
3 56 43 17

View File

@ -0,0 +1,213 @@
OFF
71 138 0
-1.3677825927734375 2.2563455104827881 2.2298691272735596
-2.1802701950073242 3.0913705825805664 3.4464244842529297
-2.2822113037109375 2.8249242305755615 4.1373443603515625
-1.2788395881652832 2.8395814895629883 2.695408821105957
-3.0684585571289062 1.515230655670166 2.5674910545349121
-2.6432909965515137 1.7005102634429932 2.4830870628356934
-2.5676684379577637 1.3753491640090942 2.1502640247344971
-2.4685182571411133 1.9557313919067383 2.6072971820831299
-2.3584427833557129 0.97177004814147949 2.6851232051849365
-1.7186203002929688 1.9703198671340942 5.1003313064575195
-2.5206203460693359 3.1864378452301025 3.7299833297729492
-1.7929482460021973 2.0710680484771729 2.3142738342285156
-1.6410198211669922 2.4823627471923828 2.5903611183166504
-2.6165375709533691 2.3563733100891113 3.8931472301483154
-1.0182356834411621 2.7667891979217529 2.4782900810241699
-0.86400508880615234 2.5329205989837646 2.7418184280395508
-3.1484746932983398 1.7375944852828979 3.462127685546875
-1.8920989036560059 1.4906859397888184 1.8572404384613037
-1.7173261642456055 1.7459070682525635 1.9814505577087402
-0.46300315856933594 1.9248586893081665 3.4269955158233643
-2.9409670829772949 1.9158768653869629 2.8484303951263428
-2.1803088188171387 1.7232086658477783 2.2322690486907959
-2.8180632591247559 1.4452899694442749 2.358877420425415
-2.3172659873962402 1.3054063320159912 1.9416441917419434
-0.21623563766479492 1.5506713390350342 3.8486378192901611
-1.5425534248352051 2.0011272430419922 2.1056604385375977
-1.9537248611450195 2.579941987991333 2.8599698543548584
-1.4801898002624512 0.999869704246521 4.0995607376098633
-0.71703314781188965 1.6905548572540283 4.2658710479736328
-0.91532588005065918 0.52978909015655518 3.3517982959747314
-2.5816426277160645 0.82760387659072876 3.2954068183898926
-1.2648711204528809 0.019347667694091797 3.1033785343170166
-1.7656683921813965 0.15923118591308594 3.5206117630004883
-1.2178230285644531 1.8304363489151001 4.6830978393554688
-2.436521053314209 2.5928385257720947 3.1539731025695801
-2.7581782341003418 2.8395316600799561 3.5611522197723389
-1.9126405715942383 1.0015970468521118 1.9965589046478271
-3.0140233039855957 0.81318360567092896 3.933429479598999
-2.066871166229248 1.2354656457901001 1.7330307960510254
-2.7672557830810547 0.43899619579315186 4.355072021484375
-3.5692558288574219 1.6551141738891602 2.9847240447998047
-1.8192925453186035 2.703794002532959 3.7348763942718506
-3.3873605728149414 1.9207360744476318 3.1139960289001465
-3.4150252342224121 1.4212455749511719 3.2482523918151855
-3.0005402565002441 1.2597334384918213 2.9969079494476318
-2.0148792266845703 2.4195537567138672 4.5941247940063477
-2.0433511734008789 2.1410109996795654 2.5228936672210693
-1.18631911277771 2.592656135559082 3.072596549987793
-1.119194507598877 2.1355414390563965 2.5687465667724609
-0.67892789840698242 2.2522778511047363 3.0580527782440186
-2.2664585113525391 0.29911267757415771 3.9378387928009033
-2.727027416229248 2.242955207824707 3.0134880542755127
-1.1930065155029297 2.5115711688995361 2.354081392288208
-1.5116386413574219 0.3935350775718689 2.6817362308502197
-3.3188605308532715 1.5851733684539795 2.7761104106903076
-2.7535190582275391 1.8265565633773804 3.9063596725463867
-2.4177103042602539 0.94943761825561523 4.6034917831420898
-1.3535199165344238 2.436643123626709 3.6284284591674805
-2.0681672096252441 1.4598760604858398 4.8519101142883301
-1.7275633811950684 0.72095417976379395 2.312793493270874
-2.2937459945678711 2.210951566696167 2.7315070629119873
-3.1915493011474609 2.2066793441772461 3.2531578540802002
-2.9818205833435059 2.5129463672637939 3.4022109508514404
-3.2299480438232422 1.140602707862854 3.5644867420196533
-0.56578254699707031 1.0402275323867798 3.6002168655395508
-1.2428500652313232 1.1113617420196533 2.7636961936950684
-1.5593795776367188 2.9179425239562988 2.9291374683380127
-1.6152782440185547 1.331046462059021 2.2430253028869629
-1.1374824047088623 1.7621533870697021 2.6719796657562256
-1.8598566055297852 3.0018720626831055 3.1794760227203369
-2.2797942161560059 1.0937072038650513 2.3239080905914307
3 11 0 25
3 35 10 1
3 42 16 61
3 61 20 42
3 1 2 41
3 12 3 52
3 15 3 47
3 20 5 4
3 23 6 21
3 31 29 32
3 60 46 7
3 22 70 8
3 22 6 70
3 5 6 22
3 58 33 9
3 34 69 26
3 5 20 7
3 2 1 10
3 35 2 10
3 44 43 54
3 46 12 11
3 45 13 55
3 3 15 14
3 14 15 52
3 52 3 14
3 16 63 55
3 18 17 21
3 67 17 18
3 49 19 68
3 42 43 16
3 37 39 56
3 20 54 42
3 21 11 18
3 4 22 44
3 70 6 23
3 13 2 35
3 58 27 33
3 28 64 24
3 18 11 25
3 18 25 67
3 66 12 26
3 28 27 64
3 0 12 52
3 66 3 12
3 59 8 70
3 55 61 16
3 49 57 19
3 57 33 28
3 56 50 27
3 51 20 61
3 32 29 27
3 8 30 44
3 29 53 65
3 29 31 53
3 58 56 27
3 21 6 5
3 66 47 3
3 8 32 30
3 9 33 45
3 1 69 34
3 17 67 36
3 7 21 5
3 62 13 35
3 62 35 34
3 36 23 38
3 30 50 37
3 38 17 36
3 23 17 38
3 56 39 50
3 50 39 37
3 54 43 40
3 1 41 69
3 40 43 42
3 43 63 16
3 44 63 43
3 58 9 45
3 45 2 13
3 41 2 45
3 46 26 12
3 49 15 47
3 40 42 54
3 49 47 57
3 24 64 19
3 19 28 24
3 23 21 17
3 15 49 48
3 31 32 53
3 0 11 12
3 28 33 27
3 48 49 68
3 27 50 32
3 19 57 28
3 4 5 22
3 7 20 51
3 52 48 0
3 65 53 59
3 4 44 54
3 37 56 55
3 41 45 57
3 57 45 33
3 58 55 56
3 55 13 62
3 64 68 19
3 36 67 59
3 4 54 20
3 51 34 60
3 62 51 61
3 55 62 61
3 25 48 68
3 53 32 8
3 53 8 59
3 25 0 48
3 45 55 58
3 63 37 55
3 67 25 68
3 7 46 21
3 51 62 34
3 30 37 63
3 21 46 11
3 22 8 44
3 50 30 32
3 26 60 34
3 34 35 1
3 29 65 64
3 60 26 46
3 60 7 51
3 52 15 48
3 57 47 66
3 67 65 59
3 67 68 65
3 63 44 30
3 26 69 66
3 69 57 66
3 69 41 57
3 59 70 36
3 36 70 23
3 65 68 64
3 29 64 27

View File

@ -0,0 +1,246 @@
OFF
82 160 0
3.0558681488037109 0.30599963665008545 1.8020365238189697
3.8656063079833984 -0.085526466369628906 1.4671635627746582
4.0150866508483887 0.32877802848815918 1.7473554611206055
5.2177524566650391 -0.46321010589599609 0.34063982963562012
4.3774218559265137 0.94689667224884033 1.3092564344406128
4.3899240493774414 0.68013536930084229 1.8397932052612305
4.9923949241638184 -0.40026283264160156 0.52839374542236328
4.691159725189209 0.13993620872497559 1.1840934753417969
4.8152356147766113 1.0573877096176147 0.46618819236755371
4.7670373916625977 -0.33731555938720703 0.71614789962768555
4.6152820587158203 0.61718809604644775 1.6520392894744873
2.7885334491729736 0.71137428283691406 1.3452516794204712
3.7138512134552002 0.86897718906402588 2.4030551910400391
5.0656304359436035 0.98744702339172363 0.25757479667663574
5.5209474563598633 0.55406481027603149 0.50740349292755127
4.7508416175842285 0.82979440689086914 1.024443507194519
5.8337626457214355 0.44218873977661133 0.29712653160095215
5.200221061706543 0.7059246301651001 0.64665389060974121
5.2913551330566406 0.42834627628326416 1.0887775421142578
3.0389304161071777 0.6414330005645752 1.1366362571716309
5.5047693252563477 0.16070300340652466 -0.0033862590789794922
4.6759033203125 -0.059737205505371094 0.27402424812316895
4.3144383430480957 1.1972712278366089 0.88342142105102539
3.408212423324585 0.99434208869934082 1.2337028980255127
2.9633042812347412 0.96659243106842041 1.4694602489471436
5.443110466003418 -0.52615737915039062 0.15288591384887695
5.0659971237182617 0.49129354953765869 1.276531457901001
3.1895334720611572 0.10331535339355469 2.0304255485534668
2.9221987724304199 0.5086899995803833 1.5736407041549683
5.7926568984985352 -0.01571357250213623 0.4013068675994873
3.3128511905670166 1.4770362377166748 1.7178813219070435
3.9005718231201172 0.17780786752700806 0.87687802314758301
3.3643043041229248 0.35853338241577148 2.1546342372894287
5.3160333633422852 0.91750407218933105 0.048954963684082031
5.5664281845092773 0.84756338596343994 -0.15965843200683594
3.4465165138244629 1.2743518352508545 1.9462703466415405
5.9674282073974609 0.23950445652008057 0.52551555633544922
5.742070198059082 0.3024517297744751 0.71326947212219238
5.5167126655578613 0.36539900302886963 0.90102338790893555
5.0421104431152344 0.08190155029296875 -0.5322880744934082
5.2168807983398438 0.33711957931518555 -0.40807938575744629
3.5397257804870605 0.50155007839202881 0.71940517425537109
3.7901206016540527 0.4316093921661377 0.51079177856445312
3.6402487754821777 -0.022579193115234375 1.6549174785614014
4.5648407936096191 1.1273283958435059 0.67480158805847168
5.7000932693481445 0.64487910270690918 0.068730592727661133
4.0405230522155762 0.36166656017303467 0.30217194557189941
4.0909643173217773 -0.14847373962402344 1.279409646987915
5.3094449043273926 -0.32347309589385986 -0.075503110885620117
4.9966297149658203 -0.21159696578979492 0.13477373123168945
3.5390803813934326 0.61375910043716431 2.2788465023040771
5.3916568756103516 0.59234535694122314 -0.28386712074279785
4.0798654556274414 1.010907769203186 1.5964139699935913
3.8136463165283203 1.3371531963348389 1.3006501197814941
5.1418747901916504 0.014041662216186523 0.80858564376831055
4.5416793823242188 -0.2743682861328125 0.90390181541442871
5.1757755279541016 -0.12078273296356201 -0.30389904975891113
3.2893285751342773 0.57149136066436768 0.92802047729492188
4.6404647827148438 0.8021695613861084 0.3419795036315918
5.6178808212280273 -0.27093935012817383 0.27709460258483887
4.4656887054443359 0.54694390296936035 0.21776723861694336
3.8533940315246582 1.0198484659194946 1.8967046737670898
4.1645665168762207 0.74308264255523682 2.0275471210479736
3.1380801200866699 1.2218180894851685 1.5936727523803711
4.0640435218811035 1.2672119140625 1.0920348167419434
4.840639591217041 0.55424082279205322 1.4642853736877441
5.4737510681152344 0.028314352035522461 0.62702035903930664
4.2909178733825684 0.29172587394714355 0.093558549880981445
4.5413126945495605 0.22178506851196289 -0.11505484580993652
4.2265238761901855 0.064132571220397949 0.65181386470794678
3.5491154193878174 0.25499922037124634 1.2127940654754639
4.316321849822998 -0.21142101287841797 1.0916557312011719
3.5632481575012207 1.4070948362350464 1.5092660188674927
4.195554256439209 0.77442049980163574 0.57773876190185547
3.6832141876220703 0.31450438499450684 1.9289175271987915
3.2511923313140869 0.79017573595046997 1.8741533756256104
4.9286727905273438 0.56964457035064697 -0.033050060272216797
3.5801858901977539 1.0716614723205566 2.174666166305542
4.7917156219482422 0.15184223651885986 -0.32367467880249023
3.9392087459564209 0.80602991580963135 2.2153012752532959
3.414891242980957 0.040368080139160156 1.8426716327667236
3.3290765285491943 0.25418663024902344 1.524074912071228
3 28 0 75
3 81 0 28
3 1 2 43
3 6 49 3
3 15 22 4
3 30 72 63
3 5 2 10
3 9 6 54
3 15 26 18
3 18 26 7
3 8 44 15
3 47 31 71
3 71 7 47
3 9 69 21
3 4 5 10
3 19 11 24
3 77 12 79
3 50 12 77
3 79 12 50
3 64 52 4
3 17 33 13
3 3 48 25
3 13 76 58
3 52 5 4
3 72 23 63
3 13 33 76
3 16 14 37
3 14 45 33
3 17 8 15
3 45 14 16
3 17 18 38
3 38 18 54
3 38 54 66
3 28 19 81
3 59 48 20
3 6 9 21
3 10 47 7
3 16 29 20
3 60 58 76
3 49 21 78
3 64 4 22
3 64 23 53
3 63 23 24
3 75 63 24
3 59 3 25
3 31 1 70
3 44 22 15
3 78 76 40
3 17 14 33
3 65 7 26
3 26 15 65
3 27 32 0
3 80 32 27
3 27 0 80
3 28 11 19
3 24 11 28
3 13 58 8
3 17 13 8
3 33 51 76
3 59 20 29
3 35 72 30
3 31 69 71
3 50 75 32
3 33 34 51
3 35 61 72
3 36 29 16
3 37 29 36
3 37 36 16
3 17 38 14
3 39 40 56
3 40 51 20
3 76 51 40
3 41 42 31
3 65 10 7
3 38 66 37
3 38 37 14
3 1 43 70
3 22 44 73
3 5 52 62
3 33 45 34
3 67 46 60
3 48 59 25
3 31 70 41
3 31 47 1
3 48 56 20
3 49 56 48
3 69 46 67
3 55 9 7
3 49 48 3
3 80 0 81
3 74 79 50
3 70 57 41
3 45 20 51
3 52 53 61
3 60 68 67
3 7 9 54
3 69 9 55
3 52 61 62
3 49 6 21
3 78 39 56
3 40 39 78
3 23 57 19
3 8 58 44
3 59 66 3
3 62 2 5
3 64 41 23
3 60 73 58
3 40 20 56
3 41 57 23
3 10 2 47
3 77 79 61
3 2 62 74
3 23 19 24
3 57 70 19
3 73 44 58
3 35 30 63
3 41 64 73
3 2 1 47
3 65 4 10
3 65 15 4
3 16 20 45
3 75 24 28
3 56 49 78
3 53 52 64
3 45 51 34
3 66 6 3
3 21 69 67
3 21 67 68
3 42 46 69
3 81 19 70
3 7 71 55
3 50 77 75
3 17 15 18
3 72 53 23
3 61 53 72
3 73 64 22
3 42 73 46
3 32 75 0
3 74 32 80
3 2 74 43
3 75 35 63
3 74 50 32
3 68 60 76
3 75 77 35
3 68 76 78
3 21 68 78
3 69 55 71
3 61 79 62
3 62 79 74
3 73 42 41
3 46 73 60
3 66 29 37
3 66 59 29
3 66 54 6
3 35 77 61
3 43 74 80
3 80 81 43
3 43 81 70
3 54 18 7
3 31 42 69

View File

@ -0,0 +1,258 @@
OFF
86 168 0
1.7636244297027588 3.7739925384521484 3.2035260200500488
2.5089099407196045 3.029773473739624 5.0258541107177734
3.0859766006469727 2.4525222778320312 2.7163577079772949
2.8186419010162354 2.8578970432281494 2.2595727443695068
2.9523112773895264 2.6552066802978516 2.4879686832427979
4.0112943649291992 2.6101250648498535 3.7741611003875732
1.8509267568588257 2.4667961597442627 4.4248356819152832
1.1825919151306152 3.4802298545837402 3.2828769683837891
1.5321388244628906 3.9906735420227051 3.5312979221343994
1.3573627471923828 3.735447883605957 3.4070854187011719
1.7069096565246582 4.2458915710449219 3.6555066108703613
1.840575098991394 4.0432071685791016 3.8838956356048584
2.9588992595672607 3.8961837291717529 2.6124267578125
3.209294319152832 3.8262429237365723 2.403813362121582
3.0345234870910645 3.5710251331329346 2.2796049118041992
1.9742443561553955 3.8405168056488037 4.1122913360595703
3.009706974029541 2.8898899555206299 4.6086211204528809
1.984592080116272 2.2641119956970215 4.6532249450683594
2.2349870204925537 2.1941711902618408 4.4446110725402832
2.3752443790435791 3.2324576377868652 4.7974653244018555
3.5789151191711426 2.4854092597961426 3.2969968318939209
2.3341391086578369 2.7745556831359863 4.9016456604003906
2.1593630313873291 2.5193300247192383 4.7774333953857422
2.526820182800293 2.5260300636291504 3.3520922660827637
3.8365235328674316 2.3549070358276367 3.6499524116516113
2.6671512126922607 3.209723949432373 4.433443546295166
1.703233003616333 3.1106529235839844 3.3096849918365479
1.432986855506897 3.4102892875671387 3.074263334274292
2.5267350673675537 2.8806309700012207 2.6235945224761963
3.054966926574707 3.4559760093688965 3.3817710876464844
2.5745716094970703 3.7045795917510986 3.5469036102294922
2.3983871936798096 3.6393728256225586 3.9287924766540527
2.4853894710540771 2.1242284774780273 4.2359914779663086
1.9573045969009399 4.1759510040283203 3.4468929767608643
3.2196419239044189 2.2498378753662109 2.9447464942932129
2.1079096794128418 3.6378324031829834 4.3406801223754883
3.6617474555969238 2.0996813774108887 3.5257401466369629
3.4869766235351562 1.8444633483886719 3.401531457901001
2.0403156280517578 2.8848550319671631 4.5119953155517578
2.9663355350494385 2.2140402793884277 3.3747231960296631
3.2601022720336914 2.8199493885040283 4.4000077247619629
2.1287035942077637 2.4480090141296387 4.0725860595703125
3.0510528087615967 3.6462926864624023 2.9962241649627686
3.760899543762207 2.6800656318664551 3.9827744960784912
2.8727421760559082 2.4720897674560547 4.3180027008056641
2.8597474098205566 3.3157992362976074 2.1553924083709717
3.1030998229980469 3.1317973136901855 2.5091733932495117
2.4345815181732178 3.1305220127105713 2.2397971153259277
2.6849765777587891 3.0605812072753906 2.0311837196350098
3.4906532764434814 2.9797019958496094 3.7473530769348145
1.3162573575973511 3.2775454521179199 3.5112659931182861
2.5656247138977051 2.5578744411468506 4.5738735198974609
1.8404836654663086 2.8830921649932861 3.584144115447998
3.8776290416717529 2.8128094673156738 3.5457720756530762
3.5104970932006836 2.7500085830688477 4.1913943290710449
2.1031477451324463 2.6443707942962646 3.7050697803497314
2.2415752410888672 3.4351482391357422 4.5690693855285645
3.3429596424102783 3.6235587596893311 2.6322023868560791
3.4766290187835693 3.4208683967590332 2.8605983257293701
2.7593047618865967 2.9598329067230225 4.8172407150268555
2.0693492889404297 2.9099621772766113 3.2069017887115479
1.9337842464447021 3.2704055309295654 2.6570303440093994
2.4198434352874756 2.378488302230835 3.8057780265808105
3.6102943420410156 3.2181839942932129 3.0889873504638672
3.4149701595306396 2.7340078353881836 3.0168702602386475
1.6007152795791626 3.5514457225799561 3.7608664035797119
2.7084968090057373 3.9661264419555664 2.8210465908050537
2.2200078964233398 3.8877522945404053 3.6694266796112061
1.6833891868591309 3.3403463363647461 2.8656437397003174
3.35331130027771 2.0471477508544922 3.1731424331665039
3.4349298477172852 2.3589587211608887 3.8885822296142578
2.9861793518066406 1.984346866607666 3.8187646865844727
2.6329295635223389 3.5750765800476074 2.5182344913482666
2.1841790676116943 3.2004647254943848 2.4484169483184814
3.2365818023681641 1.914404034614563 3.6101448535919189
2.8007354736328125 3.3616344928741455 3.9333415031433105
2.2077069282531738 4.1060080528259277 3.2382733821868896
3.7439596652984619 3.0154998302459717 3.3173761367797852
1.4499266147613525 3.0748550891876221 3.739661693572998
1.7172573804855347 2.6694865226745605 4.1964397430419922
2.7357842922210693 2.0542874336242676 4.0273780822753906
2.4581019878387451 4.0360674858093262 3.0296599864959717
2.0707418918609619 3.6882078647613525 2.9476549625396729
2.7561142444610596 3.7390527725219727 3.2206258773803711
1.5835920572280884 2.8721709251403809 3.9680507183074951
1.9398711919784546 3.1935017108917236 4.2879552841186523
3 6 22 38
3 29 49 63
3 2 23 28
3 33 76 0
3 1 59 19
3 64 34 2
3 2 34 39
3 26 60 52
3 71 44 80
3 46 4 3
3 24 53 5
3 5 53 43
3 43 24 5
3 18 6 41
3 44 70 54
3 50 9 7
3 7 9 27
3 27 50 7
3 20 53 24
3 8 0 9
3 8 9 65
3 10 11 33
3 13 12 57
3 14 12 13
3 15 11 65
3 0 27 9
3 2 39 23
3 16 40 25
3 17 22 6
3 18 22 17
3 17 6 18
3 1 19 21
3 64 20 34
3 21 22 51
3 62 55 23
3 2 28 4
3 41 32 18
3 29 58 42
3 67 15 31
3 24 70 36
3 20 24 36
3 25 75 31
3 50 27 26
3 73 28 61
3 67 76 33
3 68 27 0
3 26 27 68
3 30 75 29
3 31 30 67
3 32 44 51
3 10 33 8
3 8 11 10
3 14 57 46
3 62 41 55
3 34 69 39
3 56 31 35
3 36 74 37
3 36 37 69
3 6 38 79
3 71 62 39
3 20 64 77
3 40 44 54
3 54 49 40
3 35 31 15
3 35 15 85
3 72 66 12
3 79 55 41
3 3 28 47
3 83 29 42
3 70 24 43
3 16 51 44
3 45 72 14
3 45 14 46
3 48 47 45
3 3 47 48
3 48 45 3
3 49 77 63
3 82 73 61
3 14 13 57
3 78 65 50
3 77 64 63
3 32 51 18
3 81 30 83
3 78 26 52
3 71 80 62
3 43 53 49
3 43 49 54
3 54 70 43
3 21 59 1
3 60 23 55
3 19 25 56
3 56 38 19
3 46 64 4
3 65 9 50
3 57 42 58
3 46 57 58
3 72 12 14
3 19 59 25
3 28 23 60
3 60 26 68
3 59 21 51
3 59 51 16
3 2 4 64
3 61 60 68
3 41 62 32
3 23 39 62
3 30 76 67
3 55 84 52
3 63 58 29
3 64 58 63
3 65 11 8
3 85 15 65
3 37 74 69
3 12 66 42
3 25 59 16
3 11 15 67
3 49 29 75
3 4 28 3
3 50 26 78
3 56 35 85
3 38 21 19
3 21 38 22
3 66 72 82
3 30 29 83
3 82 61 68
3 69 20 36
3 70 71 74
3 47 73 72
3 28 73 47
3 74 39 69
3 30 81 76
3 49 75 40
3 0 76 82
3 20 77 53
3 31 56 25
3 56 85 38
3 20 69 34
3 72 73 82
3 31 75 30
3 85 65 78
3 68 0 82
3 36 70 74
3 41 6 79
3 84 55 79
3 64 46 58
3 49 53 77
3 71 70 44
3 52 60 55
3 62 80 32
3 32 80 44
3 25 40 75
3 66 82 81
3 51 22 18
3 81 82 76
3 45 46 3
3 57 12 42
3 81 83 66
3 28 60 61
3 72 45 47
3 74 71 39
3 52 84 78
3 84 85 78
3 67 33 11
3 44 40 16
3 33 0 8
3 79 38 85
3 85 84 79
3 83 42 66

View File

@ -0,0 +1,315 @@
OFF
105 206 0
3.1777701377868652 -0.44245564937591553 1.5529642105102539
4.2831711769104004 -1.114276647567749 0.30981612205505371
2.9221987724304199 0.5086899995803833 1.5736407041549683
4.3675537109375 -0.64179539680480957 -0.77974843978881836
5.9269676208496094 -0.33060705661773682 -0.92974567413330078
5.2177524566650391 -0.46321010589599609 0.34063982963562012
3.9436547756195068 -0.55960845947265625 1.000760555267334
4.1421966552734375 -0.57884824275970459 -0.5919945240020752
5.6935052871704102 -0.59609818458557129 -0.055727720260620117
5.4388504028320312 -1.4370827674865723 -0.65302348136901855
4.8937244415283203 -0.81869900226593018 0.21479892730712891
5.54290771484375 -0.057981967926025391 -0.94952106475830078
2.9076576232910156 0.21673417091369629 0.83656430244445801
3.364954948425293 0.24633204936981201 0.59519648551940918
2.7322597503662109 0.025431156158447266 1.5076801776885986
2.397881031036377 -0.25697183609008789 1.2010109424591064
2.8094565868377686 -0.50518798828125 1.1319161653518677
4.7454395294189453 -1.2433981895446777 -0.075317144393920898
3.1274881362915039 -0.79146921634674072 1.2726593017578125
2.2642157077789307 -0.054287552833557129 0.97262191772460938
2.4389865398406982 0.20093059539794922 1.0968306064605713
4.0909643173217773 -0.14847373962402344 1.279409646987915
3.8656063079833984 -0.085526466369628906 1.4671635627746582
4.2358798980712891 -0.10285103321075439 -0.22439837455749512
5.2925052642822266 0.011960744857788086 -0.74090170860290527
4.7670373916625977 -0.33731555938720703 0.71614789962768555
2.5146126747131348 -0.12422895431518555 0.76400661468505859
4.8182697296142578 -0.76769018173217773 -1.1552565097808838
4.9966297149658203 -0.21159696578979492 0.13477373123168945
4.7917156219482422 0.15184223651885986 -0.32367467880249023
3.2407655715942383 -0.32705914974212646 0.15902137756347656
3.1895334720611572 0.10331535339355469 2.0304255485534668
3.0558681488037109 0.30599963665008545 1.8020365238189697
4.9720802307128906 -0.3470611572265625 -0.87198662757873535
4.5413126945495605 0.22178506851196289 -0.11505484580993652
2.7885334491729736 0.71137428283691406 1.3452516794204712
2.8399865627288818 -0.40712833404541016 1.7820045948028564
3.4919171333312988 -0.43520689010620117 1.3755416870117188
5.1766414642333984 -0.51870644092559814 -1.1440339088439941
4.9765739440917969 -1.3079590797424316 -0.2678837776184082
2.7650105953216553 -0.19417047500610352 0.55539059638977051
4.316321849822998 -0.21142101287841797 1.0916557312011719
4.2265238761901855 0.064132571220397949 0.65181386470794678
4.9923949241638184 -0.40026283264160156 0.52839374542236328
5.2077159881591797 -1.3725218772888184 -0.46045684814453125
4.514305591583252 -1.1788372993469238 0.11724972724914551
3.0389304161071777 0.6414330005645752 1.1366362571716309
4.5416793823242188 -0.2743682861328125 0.90390181541442871
3.9005718231201172 0.17780786752700806 0.87687802314758301
5.5748271942138672 -1.1120054721832275 -0.44411396980285645
3.466123104095459 -0.39000630378723145 -0.028732538223266602
3.5491154193878174 0.25499922037124634 1.2127940654754639
5.3575758934020996 -0.95263171195983887 -0.17553043365478516
3.5090847015380859 -0.052921772003173828 0.2452704906463623
4.0023097991943359 -0.78489339351654053 0.028208255767822266
4.4537153244018555 -0.9118340015411377 -0.34612107276916504
5.443110466003418 -0.52615737915039062 0.15288591384887695
3.5397257804870605 0.50155007839202881 0.71940517425537109
5.3094449043273926 -0.32347309589385986 -0.075503110885620117
5.1757755279541016 -0.12078273296356201 -0.30389904975891113
3.5044949054718018 -0.64327847957611084 0.43768715858459473
3.0154080390930176 -0.26411187648773193 0.34677529335021973
5.9439077377319336 -0.66604089736938477 -0.26434707641601562
4.2909178733825684 0.29172587394714355 0.093558549880981445
3.0400538444519043 -0.51592600345611572 0.82951295375823975
3.5897607803344727 -0.92059195041656494 0.88752269744873047
3.8208949565887451 -0.9851527214050293 0.69495606422424316
3.414891242980957 0.040368080139160156 1.8426716327667236
6.1943025588989258 -0.73598170280456543 -0.4729607105255127
3.3586239814758301 -0.85603046417236328 1.0800912380218506
3.9168386459350586 -0.51590096950531006 -0.40424060821533203
5.6118040084838867 -0.32813858985900879 -0.49135804176330566
5.0421104431152344 0.08190155029296875 -0.5322880744934082
4.90521240234375 -1.0389144420623779 -0.72029304504394531
4.0520291328430176 -1.0497136116027832 0.50238943099975586
3.1901788711547852 -0.0088937282562255859 0.47098398208618164
3.2893285751342773 0.57149136066436768 0.92802047729492188
2.531550407409668 -0.45966219902038574 1.4294068813323975
2.6652157306671143 -0.6623464822769165 1.6577959060668945
3.0147626399993896 -0.15190267562866211 1.9062168598175049
5.4437556266784668 -0.6383664608001709 -1.4065556526184082
5.2689847946166992 -0.8935847282409668 -1.530764102935791
5.4026498794555664 -1.096268892288208 -1.302375316619873
5.7933025360107422 -0.12792277336120605 -1.1581346988677979
3.8452918529510498 -0.032324790954589844 0.06678318977355957
2.6137626171112061 0.45615625381469727 1.2210431098937988
5.6699848175048828 -1.5016436576843262 -0.84559035301208496
4.6759033203125 -0.059737205505371094 0.27402424812316895
5.6185317039489746 -0.38314080238342285 -1.2823433876037598
3.7901206016540527 0.4316093921661377 0.51079177856445312
4.0405230522155762 0.36166656017303467 0.30217194557189941
3.3290765285491943 0.25418663024902344 1.524074912071228
4.3952722549438477 -0.68418610095977783 0.62589359283447266
3.6914811134338379 -0.45295369625091553 -0.21648669242858887
6.0606374740600586 -0.53329741954803467 -0.70134973526000977
5.7316436767578125 -0.81478309631347656 -1.0018625259399414
5.8447556495666504 -1.2464253902435303 -0.72138166427612305
6.0195317268371582 -0.99119973182678223 -0.59716939926147461
2.8963515758514404 -0.72690773010253906 1.4652278423309326
4.5929117202758789 -0.7047426700592041 -0.96750235557556152
4.5196189880371094 -0.22371625900268555 -0.49771952629089355
5.5363197326660156 -1.298959493637085 -1.073979377746582
5.2065134048461914 -1.1747376918792725 -0.86516213417053223
5.0436267852783203 -0.83063721656799316 -1.3430101871490479
3.6402487754821777 -0.022579193115234375 1.6549174785614014
3 36 0 79
3 1 45 10
3 54 45 1
3 2 32 91
3 3 99 55
3 4 88 83
3 13 76 57
3 5 28 43
3 5 43 10
3 6 41 21
3 7 3 55
3 36 14 77
3 12 40 26
3 52 49 8
3 86 9 101
3 10 52 56
3 24 59 71
3 38 33 11
3 41 48 21
3 87 42 25
3 76 13 12
3 77 14 15
3 16 77 15
3 54 7 55
3 10 45 17
3 8 71 58
3 18 16 64
3 14 2 85
3 20 26 19
3 56 58 5
3 5 10 56
3 22 6 21
3 61 60 64
3 63 34 23
3 24 33 72
3 59 24 72
3 91 46 2
3 87 25 43
3 19 26 15
3 73 27 102
3 29 87 28
3 75 40 12
3 60 30 50
3 51 22 48
3 67 32 31
3 53 30 75
3 33 100 72
3 34 29 100
3 46 35 2
3 0 36 98
3 18 37 0
3 80 38 88
3 80 88 95
3 52 17 39
3 16 26 40
3 41 42 48
3 10 43 92
3 79 32 14
3 44 9 49
3 64 65 69
3 30 60 61
3 61 75 30
3 46 85 35
3 55 17 45
3 12 85 46
3 79 14 36
3 47 41 92
3 102 44 73
3 89 13 57
3 48 89 57
3 97 95 94
3 49 62 8
3 33 27 99
3 19 15 20
3 97 62 49
3 53 84 50
3 54 50 93
3 51 104 22
3 60 50 54
3 52 44 49
3 84 53 89
3 39 17 55
3 74 60 54
3 73 39 55
3 8 58 56
3 57 51 48
3 22 21 48
3 66 74 92
3 60 74 66
3 58 59 28
3 65 64 60
3 75 61 40
3 71 8 62
3 63 90 42
3 84 90 63
3 35 85 2
3 80 103 38
3 64 40 61
3 5 58 28
3 93 50 84
3 65 66 6
3 91 32 67
3 104 37 22
3 62 97 68
3 68 97 94
3 94 62 68
3 57 76 51
3 64 69 18
3 65 6 69
3 71 11 24
3 24 11 33
3 70 23 7
3 7 54 70
3 47 25 42
3 92 25 47
3 37 6 22
3 64 16 40
3 11 71 4
3 87 43 28
3 59 72 29
3 73 99 27
3 92 43 25
3 32 2 14
3 71 59 58
3 74 1 92
3 18 0 98
3 75 13 53
3 8 56 52
3 46 51 76
3 78 77 98
3 36 77 78
3 36 78 98
3 50 30 53
3 79 31 32
3 67 31 79
3 71 62 94
3 29 28 59
3 72 100 29
3 82 81 80
3 82 103 81
3 55 45 54
3 83 11 4
3 6 37 69
3 63 42 87
3 84 23 93
3 14 85 20
3 86 96 9
3 60 66 65
3 34 63 87
3 96 86 101
3 83 88 11
3 1 10 92
3 80 81 103
3 42 90 89
3 89 90 84
3 51 46 91
3 53 13 89
3 66 92 6
3 14 20 15
3 20 85 12
3 39 73 44
3 10 17 52
3 20 12 26
3 52 39 44
3 100 7 23
3 100 23 34
3 16 15 26
3 9 44 102
3 55 99 73
3 92 41 6
3 69 37 18
3 54 93 70
3 38 27 33
3 38 103 27
3 93 23 70
3 1 74 54
3 29 34 87
3 41 47 42
3 84 63 23
3 4 71 94
3 4 94 95
3 96 49 9
3 104 0 37
3 97 96 95
3 95 96 101
3 97 49 96
3 101 82 95
3 82 80 95
3 4 95 88
3 75 12 13
3 12 46 76
3 98 16 18
3 98 77 16
3 33 99 100
3 7 100 3
3 101 102 82
3 9 102 101
3 102 27 103
3 82 102 103
3 104 67 0
3 0 67 79
3 88 38 11
3 104 91 67
3 51 91 104
3 99 3 100
3 42 89 48

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,210 @@
OFF 71 138 0
1 4 0
1 4.33333 0
1.33333 4 0
2 5.54692 0
1.54692 6 0
2 6 0
0.720377 6 0
0.346918 6 0
0.46167 6 0.445685
0.478292 5.49745 0
2 5.37496 0.578061
2 6 0.594537
1.49745 4.47829 0
1.66667 4 0
2 4.34692 0
2 4.46167 0.445685
2 4 0.384615
0 5.33333 0
0.333333 5 0
0 4.33333 0
0.5 4.5 0
0 4.66667 0
0 4.66667 2
0 4 2
0.666667 4 2
1 5 0
0.666667 5 0
1 4.66667 0
0 5 0
0 4.75956 0.695771
0 4.5 0.405669
1.33333 6 2
2 6 2
2 5.33333 2
1.37496 5.45178 0
1.50867 4.9024 0
2 5.12038 0
0 5.49745 0.476818
0 5.66667 0
0 6 0.384615
2 6 1.2612
0.902401 6 0.854344
1.37496 6 0.578061
2 4 0
0 6 0.846154
0.666667 4 0
0.333333 4 0
0.5 4 0.472405
2 4 0.846154
1.24044 4 0.695771
2 4 1.38462
0 6 1.38462
0.666667 6 2
0 6 2
1.00906 4.99094 2
2 4 2
2 4.66667 2
1.33333 4 2
2 4.72038 0
0 4 0.846154
2 4.9024 0.854344
0 5.33333 2
0.902401 5.50867 0
0 5.27892 1.11208
0.721084 4 1.11208
0 4 1.38462
0 4 0.384615
1.12038 6 0
0 4 0
0 6 0
1.49745 4 0.40533
3 0 1 2
3 3 4 5
3 6 7 8
3 7 6 9
3 10 3 11
3 13 12 14
3 15 16 14
3 17 9 18
3 20 19 21
3 22 23 24
3 26 25 27
3 29 28 30
3 30 28 21
3 28 18 21
3 32 31 33
3 35 34 36
3 26 18 9
3 5 11 3
3 5 4 11
3 38 37 39
3 1 27 12
3 41 40 42
3 43 14 16
3 13 43 16
3 43 13 14
3 41 8 44
3 20 45 46
3 45 47 46
3 49 48 50
3 8 7 39
3 52 51 53
3 7 9 38
3 45 20 1
3 37 17 28
3 19 30 21
3 4 42 11
3 33 31 54
3 55 56 57
3 0 45 1
3 47 45 0
3 35 58 12
3 57 56 54
3 13 2 12
3 12 58 14
3 30 59 29
3 8 41 6
3 50 48 60
3 56 60 33
3 54 52 61
3 6 62 9
3 54 22 24
3 37 29 63
3 64 24 65
3 65 24 23
3 54 31 52
3 18 20 21
3 14 58 15
3 63 29 22
3 40 32 33
3 34 3 36
3 66 46 47
3 18 26 20
3 4 67 42
3 34 67 4
3 68 66 19
3 51 63 61
3 66 68 46
3 68 19 46
3 61 52 53
3 51 61 53
3 69 38 39
3 36 3 10
3 7 69 39
3 8 39 44
3 39 37 44
3 40 31 32
3 42 40 11
3 40 10 11
3 12 27 35
3 15 48 16
3 38 69 7
3 60 48 15
3 50 55 57
3 55 50 56
3 46 19 20
3 70 16 48
3 65 23 22
3 12 2 1
3 54 56 33
3 49 70 48
3 22 54 61
3 56 50 60
3 28 17 18
3 62 26 9
3 2 13 70
3 59 64 65
3 38 17 37
3 41 51 52
3 60 10 40
3 33 60 40
3 52 31 41
3 67 41 42
3 50 57 49
3 59 66 47
3 9 17 38
3 25 62 34
3 6 67 62
3 6 41 67
3 49 0 70
3 29 65 22
3 59 65 29
3 70 0 2
3 31 40 41
3 41 44 51
3 49 47 0
3 20 26 27
3 34 62 67
3 44 63 51
3 1 20 27
3 37 28 29
3 22 61 63
3 34 35 25
3 3 34 4
3 57 24 64
3 27 25 35
3 62 25 26
3 70 13 16
3 58 60 15
3 59 47 64
3 64 47 49
3 63 44 37
3 58 35 36
3 58 36 60
3 60 36 10
3 66 59 30
3 19 66 30
3 57 64 49
3 54 24 57

View File

@ -0,0 +1,111 @@
OFF 38 72 0
1 4 0
1 4 -0.333333
1 4.33333 0
0.5 4 -0.5
0.666667 4 0
0 4 -1
0.333333 4 -1
0 4 -0.666667
1 4 -1
1 4.33333 -1
0.666667 4 -1
0 4.33333 0
0.5 4.5 0
0 4.66667 0
0 4.5 -0.5
1 5 0
0.666667 5 0
1 4.66667 0
0 5 0
0.333333 5 0
0 5 -0.333333
0.5 5 -0.5
0 4.33333 -1
1 4.5 -0.5
1 4.66667 -1
1 5 -0.666667
0.5 4.5 -1
0.333333 4 0
1 5 -0.333333
0 4.66667 -1
0 5 -0.666667
1 4 -0.666667
0 4 -0.333333
0 4 0
0.666667 5 -1
1 5 -1
0 5 -1
0.333333 5 -1
3 0 1 2
3 3 1 4
3 5 6 7
3 9 8 10
3 11 12 13
3 14 11 13
3 15 16 17
3 19 18 13
3 21 20 19
3 21 19 16
3 7 22 5
3 22 6 5
3 2 23 17
3 23 24 25
3 26 6 22
3 4 12 27
3 2 1 23
3 20 14 13
3 17 23 28
3 12 4 2
3 4 0 2
3 30 29 14
3 10 8 31
3 3 4 27
3 32 7 3
3 14 7 32
3 14 22 7
3 28 15 17
3 16 15 28
3 31 3 10
3 12 19 13
3 32 33 11
3 6 26 10
3 26 34 24
3 14 32 11
3 34 35 24
3 35 25 24
3 34 25 35
3 16 19 12
3 11 33 27
3 32 27 33
3 36 30 37
3 0 4 1
3 18 20 13
3 37 29 36
3 31 8 9
3 29 30 36
3 11 27 12
3 34 21 25
3 21 16 28
3 23 31 9
3 24 23 9
3 30 21 37
3 20 18 19
3 30 20 21
3 20 30 14
3 23 25 28
3 25 21 28
3 26 29 37
3 27 32 3
3 3 7 6
3 9 26 24
3 3 31 1
3 31 23 1
3 29 22 14
3 26 22 29
3 16 12 17
3 12 2 17
3 9 10 26
3 26 37 34
3 21 34 37
3 3 6 10

View File

@ -0,0 +1,255 @@
OFF 86 168 0
4.45187 3 2.54813
4 3 2.66667
4.33333 3 3
5 1 2
5 1.65029 1.83333
5 1.45187 2.54813
4 1 2
4 1.45187 1.45187
4 1.83333 2.16667
5 2.66667 1
4.5 2.57551 1
5 2.33333 1
5 3 3
5 3 2.66667
5 2.66667 3
4.5 1 2.16667
4 1 2.33333
4 1.45187 2.54813
4 2.56905 1.83333
4 2.54813 1.45187
4 2.16667 1.65029
4 1.66667 3
4 2 3
4.5 2.16667 3
4 1 1.33333
4.45187 1 1.45187
4 1 1.66667
5 1 3
4.66667 1 3
5 1 2.66667
5 1.33333 3
4 2.56694 2.54813
4 2.66667 3
5 1.66667 3
4.54813 1.45187 3
4 3 1
4 3 1.33333
4.33333 3 1
4 2.66667 1
4.5 1 2.57551
4.66667 3 1
4.45187 3 1.45187
5 3 1
5 3 1.33333
5 1 1
5 1 1.33333
5 1.33333 1
4.66667 1 1
5 3 1.66667
5 2.54813 2.54813
5 2.33333 3
5 2 3
4 3 3
4.66667 3 3
4.5 2.57551 3
4 2.16667 2.52434
4 2.39733 2.16667
4 2.33333 3
5 1.45187 1.45187
5 1 1.66667
5 2.54813 1.43306
5 2.52434 1.83333
4.33333 1 3
5 2.16667 2.16667
4 1.66667 1
4 2 1
4 2.33333 1
5 2.16667 1.60267
4 1 2.66667
5 3 2
5 3 2.33333
4 1 3
4 1.33333 3
4 3 2.33333
5 1 2.33333
4.55204 3 2.16667
4.54813 1.45187 1
5 1.66667 1
4 1.33333 1
5 1.83333 1.43095
4.33333 1 1
4 1 1
4.5 2.16667 1
4 3 1.66667
5 2 1
4 3 2
3 0 1 2
3 3 4 5
3 7 6 8
3 10 9 11
3 13 12 14
3 6 15 16
3 17 6 16
3 18 19 20
3 22 21 23
3 24 25 26
3 27 28 29
3 30 27 29
3 27 30 28
3 31 32 1
3 33 23 34
3 35 36 37
3 38 35 37
3 35 38 36
3 28 39 29
3 37 40 10
3 41 40 37
3 9 42 43
3 45 44 46
3 44 47 46
3 41 48 43
3 37 10 38
3 8 6 17
3 49 50 51
3 1 52 2
3 52 32 2
3 32 52 1
3 53 12 13
3 16 15 39
3 54 53 2
3 8 55 56
3 26 6 7
3 32 31 57
3 58 4 59
3 61 60 48
3 62 28 34
3 62 39 28
3 61 49 63
3 19 36 38
3 65 64 7
3 9 60 11
3 10 66 38
3 66 19 38
3 4 67 63
3 60 61 67
3 54 57 23
3 40 42 9
3 42 40 43
3 25 47 45
3 56 55 31
3 17 16 68
3 69 70 61
3 71 62 72
3 68 62 71
3 73 1 0
3 17 21 55
3 74 39 15
3 33 51 23
3 51 33 5
3 48 69 61
3 75 69 48
3 46 76 77
3 31 73 56
3 78 24 7
3 58 79 4
3 30 34 28
3 23 50 54
3 47 80 76
3 25 80 47
3 80 81 78
3 81 24 78
3 24 81 80
3 3 5 74
3 65 82 64
3 45 47 44
3 36 83 41
3 3 74 15
3 32 57 54
3 79 84 67
3 18 83 19
3 55 21 22
3 5 30 29
3 33 30 5
3 30 33 34
3 12 53 14
3 56 20 8
3 70 13 49
3 13 70 0
3 26 25 15
3 36 41 37
3 59 45 58
3 59 25 45
3 47 76 46
3 49 13 14
3 20 7 8
3 66 20 19
3 54 14 53
3 50 14 54
3 15 6 26
3 66 65 20
3 57 31 55
3 55 8 17
3 60 67 11
3 18 56 85
3 4 3 59
3 3 15 59
3 40 41 43
3 41 75 48
3 68 71 72
3 58 46 77
3 50 49 14
3 60 43 48
3 63 5 4
3 24 26 7
3 83 36 19
3 75 70 69
3 13 0 53
3 2 53 0
3 82 77 76
3 79 67 4
3 66 82 65
3 62 68 39
3 72 34 21
3 76 78 64
3 78 7 64
3 68 72 17
3 11 67 84
3 51 5 63
3 82 10 11
3 29 39 74
3 49 61 70
3 0 70 75
3 16 39 68
3 82 76 64
3 67 61 63
3 83 75 41
3 82 66 10
3 72 62 34
3 73 31 1
3 73 85 56
3 59 15 25
3 74 5 29
3 23 21 34
3 56 18 20
3 57 55 22
3 23 57 22
3 63 49 51
3 84 77 82
3 32 54 2
3 11 84 82
3 24 80 25
3 58 45 46
3 77 84 79
3 65 7 20
3 78 76 80
3 17 72 21
3 83 18 85
3 83 85 75
3 43 60 9
3 50 23 51
3 40 9 10
3 75 73 0
3 73 75 85
3 77 79 58

View File

@ -0,0 +1,111 @@
OFF 38 72 0
1 -1 1
1 -1 1.33333
1 -0.666667 1
2 -1 2
1.66667 -1 2
2 -0.666667 2
2 -1 1.66667
1 -0.511633 1.50582
1 -0.333333 1
1 0 1.33333
1.66667 -1 1
1.5 -0.5 1
2 -0.666667 1
1 -0.333333 2
1.49418 -0.511633 2
1 -0.666667 2
1.33333 -1 1
2 0 1.66667
1.5 0 1.5
2 0 1.33333
2 -0.5 1.5
2 -0.333333 1
1.33333 0 2
1.66667 0 2
1.66667 0 1
2 -1 1.33333
2 -0.333333 2
2 0 2
1 0 2
1 0 1.66667
1 0 1
1.33333 0 1
1.33333 -1 2
1 -1 1.66667
1.49418 -1 1.50582
2 -1 1
2 0 1
1 -1 2
3 0 1 2
3 4 3 5
3 3 6 5
3 6 3 4
3 8 7 9
3 10 11 12
3 14 13 15
3 13 7 15
3 0 16 1
3 18 17 19
3 17 20 19
3 12 11 21
3 22 23 18
3 18 19 24
3 5 14 4
3 20 25 12
3 27 26 17
3 22 28 13
3 28 29 13
3 29 28 22
3 31 30 9
3 30 8 9
3 8 30 31
3 31 18 24
3 16 2 11
3 32 14 15
3 6 20 5
3 33 1 34
3 6 25 20
3 22 18 29
3 33 15 7
3 11 31 24
3 23 27 17
3 26 27 23
3 10 35 25
3 35 12 25
3 12 35 10
3 11 2 8
3 36 19 21
3 14 26 23
3 18 31 9
3 16 11 10
3 19 20 21
3 34 16 10
3 33 32 37
3 32 15 37
3 15 33 37
3 24 36 21
3 19 36 24
3 10 25 34
3 33 7 1
3 20 26 5
3 8 2 7
3 7 13 29
3 7 29 9
3 4 34 6
3 21 11 24
3 21 20 12
3 16 0 2
3 6 34 25
3 33 34 32
3 22 14 23
3 22 13 14
3 20 17 26
3 31 11 8
3 32 34 4
3 18 9 29
3 2 1 7
3 32 4 14
3 14 5 26
3 1 16 34
3 23 17 18

View File

@ -0,0 +1,168 @@
OFF 57 110 0
2 -1 2
2 -1 1.66667
2 -0.666667 2
3 0 1.66667
3 0 2
3 -0.333333 2
2.66667 0 2
2.33333 0 1
2.5 0 1.5
2 0 1.33333
2 0 1.66667
2 -0.5 1.5
2 0 1
2.33333 -2 1
2 -2 1.33333
2 -2 1
2 -1 1.33333
2 -0.666667 1
2 -0.333333 2
2 0 2
2.33333 0 2
3 -1.66667 1
3 -1.33333 1
2.5 -1.52406 1
3 -1.54813 1.45187
3 -2 1.33333
2.5 -0.475937 2
2.33333 -2 2
2.5 -2 1.5
2 -2 1.66667
3 -1 2
3 -0.666667 2
3 -0.833333 1.44796
3 -1.33333 2
2.66667 -2 1
3 -2 1.66667
3 -2 2
3 -1.66667 2
2.66667 0 1
3 0 1
3 0 1.33333
2.66667 -2 2
2.5 -0.475937 1
2 -0.333333 1
2 -1.66667 2
2 -1.5 1.5
3 -0.333333 1
2 -1 1
3 -2 1
2.5 -1.52406 2
2 -2 2
3 -0.451874 1.54813
3 -0.666667 1
2 -1.33333 1
2 -1.33333 2
2 -1.66667 1
3 -1 1
3 1 0 2
3 3 4 5
3 4 6 5
3 3 6 4
3 8 7 9
3 11 10 9
3 7 12 9
3 13 14 15
3 16 11 17
3 18 19 10
3 19 20 10
3 18 20 19
3 22 21 23
3 24 21 22
3 24 25 21
3 5 6 26
3 28 27 29
3 31 30 32
3 30 33 32
3 30 31 26
3 6 20 26
3 11 1 2
3 23 21 34
3 16 1 11
3 36 35 37
3 39 38 40
3 34 13 23
3 40 38 8
3 3 8 6
3 41 27 28
3 37 24 33
3 7 42 43
3 22 32 24
3 10 8 9
3 29 44 45
3 46 42 38
3 29 14 28
3 45 14 29
3 42 7 38
3 7 8 38
3 17 47 16
3 39 46 38
3 46 39 40
3 9 12 43
3 12 7 43
3 16 45 1
3 34 48 25
3 48 21 25
3 21 48 34
3 33 49 37
3 11 9 43
3 28 13 34
3 29 50 44
3 50 27 44
3 27 50 29
3 35 24 37
3 52 51 32
3 46 52 42
3 52 46 51
3 16 47 53
3 42 47 17
3 26 18 2
3 18 11 2
3 36 37 41
3 30 26 0
3 27 41 49
3 0 26 2
3 26 20 18
3 49 41 37
3 0 1 54
3 35 25 24
3 45 53 55
3 32 56 52
3 0 49 30
3 11 43 17
3 43 42 17
3 45 54 1
3 13 15 55
3 23 55 53
3 28 25 35
3 35 36 41
3 15 14 55
3 45 44 54
3 47 23 53
3 56 23 47
3 51 46 40
3 51 40 3
3 3 5 51
3 40 8 3
3 5 26 31
3 49 33 30
3 52 56 42
3 54 44 49
3 10 11 18
3 42 56 47
3 13 55 23
3 31 32 51
3 55 14 45
3 6 8 20
3 56 22 23
3 45 16 53
3 24 32 33
3 13 28 14
3 28 34 25
3 35 41 28
3 49 0 54
3 44 27 49
3 10 20 8
3 51 5 31
3 22 56 32

View File

@ -0,0 +1,243 @@
OFF 82 160 0
2.5 0 2.5
2 0 2.33333
2 0 2.66667
2 -0.390065 2.61728
2 -0.6 3
2 -0.9 3
2.5 -0.75 3
2 -2.7 3
2 -2.4 3
2 -2.60994 2.61728
3 -1.65 2.49507
3 -1.16667 2.46927
3 -1.33333 2
2.66667 0 2
3 0 2
3 -0.333333 2
3 -1.2 3
3 -0.9 3
2 -2.1 3
2.5 -2.25 3
3 -2.1 3
3 -1.8 3
2.5 -1.65 3
3 -2 2
3 -1.66667 2
2 -1.5 3
2 -1.2 3
2 -1.24044 2.44945
2 -2.25 2.49174
2 -1.65 2.49507
2.33333 0 2
2 -0.333333 2
2 0 2
3 -0.3 3
3 0 2.66667
3 0 3
2.66667 0 3
3 -1 2
3 -0.75 2.50778
3 -2.25 2.49174
3 -2.33333 2
3 -2.66667 2
2 -3 3
2 -3 2.66667
2.66667 -2 2
2.5 -2.5 2
2.5 -0.475937 2
3 -3 2.66667
3 -2.7 3
3 -2.60994 2.61728
3 -3 2.33333
3 -2.4 3
2.61728 -2.60994 3
2.5 -3 2.5
2.33333 -3 3
2.66667 -3 3
2.33333 -2 2
2 -2.66667 2
3 -0.666667 2
2 -0.75 2.49174
2.33333 -3 2
3 -1.5 3
2 0 3
2.33333 0 3
2 -0.3 3
2.66667 -3 2
3 0 2.33333
3 -3 2
3 -0.390065 2.61728
3 -3 3
2 -3 2.33333
2 -3 2
2 -1 2
2 -1.33333 2
2.5 -1.52406 2
3 -0.6 3
2 -2 2
2 -1.66667 2
2 -1.8 3
2.38272 -0.390065 3
2 -0.666667 2
2 -2.33333 2
3 0 1 2
3 1 3 2
3 4 5 6
3 7 8 9
3 11 10 12
3 13 14 15
3 16 17 6
3 19 18 8
3 20 10 21
3 22 20 21
3 10 23 24
3 25 26 27
3 26 25 22
3 28 18 29
3 16 11 17
3 30 31 32
3 33 34 35
3 34 36 35
3 36 33 35
3 11 37 38
3 40 39 41
3 42 7 43
3 44 40 45
3 11 38 17
3 13 15 46
3 45 40 41
3 48 47 49
3 41 49 50
3 10 39 23
3 47 50 49
3 51 39 20
3 19 51 20
3 52 51 19
3 3 1 31
3 53 54 43
3 28 8 18
3 22 16 26
3 53 47 55
3 45 56 44
3 57 9 28
3 12 37 11
3 58 37 46
3 30 13 46
3 30 0 13
3 42 54 7
3 59 27 5
3 10 24 12
3 60 57 45
3 41 39 49
3 21 61 22
3 61 21 10
3 2 62 63
3 62 64 63
3 64 62 2
3 31 1 32
3 1 30 32
3 23 40 44
3 23 39 40
3 45 41 65
3 55 54 53
3 14 66 15
3 25 27 29
3 63 36 0
3 65 41 67
3 15 66 68
3 47 69 55
3 69 48 55
3 47 48 69
3 49 39 51
3 70 71 60
3 53 60 65
3 60 45 65
3 27 72 73
3 22 61 16
3 48 51 52
3 49 51 48
3 59 5 4
3 74 12 24
3 75 17 38
3 67 41 50
3 56 76 77
3 42 43 54
3 72 27 59
3 5 27 26
3 53 43 70
3 43 9 70
3 76 29 77
3 22 78 18
3 7 9 43
3 3 64 2
3 36 79 33
3 72 59 80
3 65 50 53
3 68 38 58
3 76 56 81
3 19 22 18
3 78 29 18
3 75 38 68
3 28 9 8
3 70 57 71
3 57 60 71
3 31 46 80
3 24 23 44
3 7 54 52
3 17 75 6
3 46 37 72
3 44 56 74
3 70 60 53
3 46 72 80
3 26 16 6
3 68 34 33
3 79 6 75
3 30 46 31
3 31 80 59
3 44 74 24
3 13 66 14
3 74 72 37
3 26 6 5
3 16 61 11
3 11 61 10
3 50 47 53
3 1 0 30
3 57 70 9
3 37 58 38
3 67 50 65
3 7 52 8
3 76 28 29
3 81 28 76
3 29 73 77
3 59 3 31
3 78 22 25
3 0 36 34
3 20 39 10
3 46 15 58
3 15 68 58
3 12 74 37
3 77 73 74
3 2 63 0
3 64 79 63
3 4 6 79
3 13 0 66
3 63 79 36
3 45 81 56
3 66 0 34
3 57 81 45
3 57 28 81
3 25 29 78
3 75 68 33
3 79 75 33
3 72 74 73
3 56 77 74
3 48 52 55
3 55 52 54
3 8 52 19
3 68 66 34
3 64 4 79
3 4 64 3
3 59 4 3
3 22 19 20
3 29 27 73

View File

@ -0,0 +1,312 @@
OFF 105 206 0
1.33333 0 3
1.66667 0 3
1.39804 -0.404497 3
1 -2.15385 3
1.51103 -2.60994 3
1 -2.46154 3
1 -2.05 2.49414
2 -0.390065 2.61728
2 0 2.33333
2 0 2.66667
1 -2.8 2
1 -2.65 2.49586
1 -3.1 2
2 -4 2.33333
2 -4 2
1.66667 -4 2
2 -1 2
1.66667 -1 2
2 -0.666667 2
2 -2.7 3
2 -2.4 3
2 -2.60994 2.61728
2 -1.2 3
1.50414 -1.35 3
2 -1.5 3
1 -2.5 2
1 0 2.66667
1.50582 0 2.50582
1 -0.333333 2
1.49418 -0.511633 2
1 -0.666667 2
2 -3.33333 3
1.50624 -3.23077 3
1.39804 -3.5955 3
1 -4 3
1 -4 2.66667
1 -3.69231 3
2 -3 3
2 -3.33333 2
2 -3.48837 2.50582
2 -3 2.33333
2 -3.66667 2
1.38272 -3.60994 2
1.50826 -3.25 2
2 -1.24044 2.44945
2 -2.1 3
2 -2.25 2.49174
2 -1.65 2.49507
1 0 2.33333
1 -0.404497 2.60196
1 -2.76923 3
2 -3 2.66667
1 -0.615385 3
1 -0.769231 2.49376
1.66667 0 2
1 0 2
1.33333 0 2
2 -0.9 3
1 -1 2
1 -1.39006 2.48897
1.55055 -2.24044 2
2 -2 2
2 -2.33333 2
2 -3 2
2 -0.333333 2
1 -3.25 2.49781
1 -3.5955 2.60196
1 -3.4 2
2 -2.66667 2
1.33333 -1 2
1 -1.6 2
1 -1.3 2
2 -0.75 2.49174
2 0 3
2 -0.3 3
1.38272 -1.39006 2
1.50493 -2.65 2
2 0 2
1 -0.307692 3
1.50219 -0.75 3
1.33333 -4 2
1.5 -4 2.5
1 -3.07692 3
1.50586 -1.95 3
1 -3.38462 3
1 -0.923077 3
1 -1.23077 3
2 -1.8 3
2 -1.33333 2
1.66667 -4 3
2 -4 2.66667
2 -3.66667 3
1.50826 -1.75 2
1 -1.9 2
2 -0.6 3
1 -1.84615 3
1 -1.53846 3
2 -1.66667 2
1 -3.7 2
2 -4 3
1 -2.2 2
1 0 3
1 -4 2.33333
1 -4 2
1.33333 -4 3
3 1 0 2
3 4 3 5
3 3 6 5
3 7 8 9
3 11 10 12
3 14 13 15
3 16 17 18
3 20 19 21
3 4 19 20
3 22 23 24
3 11 25 10
3 26 0 27
3 28 29 30
3 31 32 33
3 35 34 36
3 37 4 32
3 39 38 40
3 41 42 43
3 22 24 44
3 45 46 47
3 29 18 17
3 48 26 27
3 48 49 26
3 11 6 25
3 50 4 5
3 51 31 39
3 53 52 49
3 54 27 8
3 55 56 28
3 19 37 51
3 37 19 4
3 22 57 23
3 53 58 59
3 60 61 62
3 63 38 43
3 63 40 38
3 8 7 64
3 20 46 45
3 48 55 28
3 66 65 67
3 21 68 46
3 29 69 30
3 70 59 71
3 44 72 57
3 73 74 9
3 69 75 71
3 63 43 76
3 76 62 68
3 8 64 77
3 78 2 0
3 2 52 79
3 15 80 42
3 81 80 15
3 82 32 50
3 30 49 28
3 44 24 47
3 83 4 20
3 27 1 9
3 33 84 36
3 85 53 86
3 58 71 59
3 71 58 69
3 77 64 54
3 5 11 50
3 64 29 54
3 0 1 27
3 83 87 24
3 65 66 84
3 16 88 17
3 16 44 88
3 90 89 81
3 31 33 91
3 12 43 67
3 56 55 48
3 33 89 91
3 70 75 92
3 93 6 70
3 57 72 94
3 6 59 70
3 33 32 84
3 88 92 75
3 11 82 50
3 6 95 59
3 11 65 82
3 37 31 51
3 44 16 72
3 44 57 22
3 83 96 95
3 96 59 95
3 21 51 40
3 59 86 53
3 30 69 58
3 91 39 31
3 47 61 97
3 61 92 97
3 8 77 54
3 42 80 98
3 58 53 30
3 21 19 51
3 92 93 70
3 23 86 96
3 74 7 9
3 57 94 79
3 99 91 89
3 90 99 89
3 99 90 91
3 72 16 18
3 52 53 85
3 85 86 23
3 38 39 41
3 43 38 41
3 25 100 60
3 100 25 6
3 47 87 45
3 87 83 45
3 57 79 23
3 30 53 49
3 13 41 39
3 21 46 20
3 68 40 63
3 67 65 12
3 45 83 20
3 27 9 8
3 51 39 40
3 83 95 3
3 78 52 2
3 75 69 17
3 32 31 37
3 18 64 72
3 78 101 26
3 101 0 26
3 78 0 101
3 75 70 71
3 9 1 73
3 1 74 73
3 90 39 91
3 40 68 21
3 68 63 76
3 80 102 103
3 103 102 98
3 6 11 5
3 13 14 41
3 85 23 79
3 46 61 47
3 93 92 60
3 56 27 54
3 36 34 104
3 86 59 96
3 46 62 61
3 35 104 34
3 41 14 15
3 83 3 4
3 98 80 103
3 88 47 97
3 92 88 97
3 7 72 64
3 88 75 17
3 23 96 83
3 48 27 56
3 29 56 54
3 84 82 65
3 32 4 50
3 28 56 29
3 84 32 82
3 60 76 25
3 62 76 60
3 28 49 48
3 66 36 84
3 65 11 12
3 23 83 24
3 52 85 79
3 100 6 93
3 43 42 67
3 67 42 98
3 100 93 60
3 6 3 95
3 46 68 62
3 47 24 87
3 60 92 61
3 90 13 39
3 81 13 90
3 36 104 33
3 79 94 2
3 81 89 104
3 35 81 104
3 104 89 33
3 81 35 102
3 81 102 80
3 15 13 81
3 17 69 29
3 18 29 64
3 52 78 49
3 49 78 26
3 76 43 12
3 10 25 76
3 102 35 66
3 35 36 66
3 98 66 67
3 98 102 66
3 2 94 74
3 1 2 74
3 41 15 42
3 74 94 7
3 94 72 7
3 76 12 10
3 44 47 88

View File

@ -0,0 +1,463 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#ifdef USE_POLYHEDRON
#include <CGAL/Polyhedron_3.h>
#else
#include <CGAL/Surface_mesh.h>
#endif
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/region_growing.h>
#include <CGAL/Polygon_mesh_processing/manifoldness.h>
#include <CGAL/Polygon_mesh_processing/transform.h>
#include <CGAL/Polygon_mesh_processing/detect_features.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/subdivision_method_3.h>
#include <iostream>
#include <fstream>
#include <sstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
#ifdef USE_POLYHEDRON
typedef CGAL::Polyhedron_3<Kernel> Surface_mesh;
#else
typedef Kernel::Point_3 Point_3;
typedef CGAL::Surface_mesh<Kernel::Point_3> Surface_mesh;
#endif
namespace PMP = CGAL::Polygon_mesh_processing;
void approximate_remeshing(Surface_mesh& sm, double cos_th, double frechet)
{
std::vector<std::size_t> region_ids(num_faces(sm));
std::vector<std::size_t> corner_id_map(num_vertices(sm), -1); // corner status of vertices
std::vector<bool> ecm(num_edges(sm), false); // mark edges at the boundary of regions
boost::vector_property_map<CGAL::Epick::Vector_3> normal_map; // normal of the supporting planes of the regions detected
// detect planar regions in the mesh
std::size_t nb_regions =
PMP::region_growing_of_planes_on_faces(sm,
CGAL::make_random_access_property_map(region_ids),
CGAL::parameters::cosine_of_maximum_angle(cos_th).
region_primitive_map(normal_map).
maximum_distance(frechet));
// detect corner vertices on the boundary of planar regions
std::size_t nb_corners =
PMP::detect_corners_of_regions(sm,
CGAL::make_random_access_property_map(region_ids),
nb_regions,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::parameters::cosine_of_maximum_angle(cos_th).
maximum_distance(frechet).
edge_is_constrained_map(CGAL::make_random_access_property_map(ecm)));
// run the remeshing algorithm using filled properties
Surface_mesh out;
PMP::remesh_almost_planar_patches(sm,
sm,
nb_regions, nb_corners,
CGAL::make_random_access_property_map(region_ids),
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map),
CGAL::parameters::visitor([](Surface_mesh& sm){sm.clear_without_removing_property_maps ();}));
}
int main()
{
CGAL::Aff_transformation_3<Kernel> rot( 0.914409, 0.0707007,-0.39857 , 0,
-0.34672 , 0.644949 ,-0.681048, 0,
0.208907, 0.760948 , 0.61426 , 0);
// testing decimate function
bool OK = true;
const int nb_meshes=4;
for (int i=1; i<=nb_meshes; ++i)
{
std::cout << "handling decimation of data/decimation/m" << i << ".off\n";
std::stringstream ss;
ss << "data/decimation/m" << i << ".off";
Surface_mesh sm;
std::ifstream in(ss.str().c_str());
in >> sm;
// call the decimation function
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out);
ss=std::stringstream();
ss << "out" << i << ".off";
std::ofstream out(ss.str().c_str());
out << sm_out;
std::cout << " output written to out" << i << ".off\n";
assert(CGAL::is_valid_polygon_mesh(sm_out));
}
// test on cheese
{
std::cout << "handling decimation of data/cheese.off\n";
Surface_mesh sm;
std::ifstream(CGAL::data_file_path("meshes/cheese.off")) >> sm;
auto ecm = sm.add_property_map<Surface_mesh::Edge_index, bool>("ecm", false).first;
PMP::detect_sharp_edges(sm, 60, ecm);
PMP::isotropic_remeshing(faces(sm), 0.004, sm, CGAL::parameters::edge_is_constrained_map(ecm));
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out);
std::ofstream("cheese_out.off") << sm_out;
assert(CGAL::is_valid_polygon_mesh(sm_out));
PMP::transform(rot, sm);
approximate_remeshing(sm, 0.98, 1e-2);
std::ofstream("cheese_out_rg.off") << sm;
assert(CGAL::is_valid_polygon_mesh(sm));
}
// testing border non-manifold vertex: not working for now, test kept
/*
// in case we find a solution
{
std::cout << "testing handling of non-manifold patches\n";
Surface_mesh sm;
std::ifstream("data/decimation/m1.off") >> sm;
auto f1 = *std::next(faces(sm).begin(), 594);
auto f2 = *std::next(faces(sm).begin(), 2378);
CGAL::Euler::remove_face(halfedge(f1, sm), sm);
CGAL::Euler::remove_face(halfedge(f2, sm), sm);
if (!PMP::remesh_planar_patches(sm))
{
OK=false;
std::cerr << "ERROR: decimate failed to remesh some patches\n";
}
std::ofstream("nm_m1.off") << std::setprecision(17) << sm;
assert(CGAL::is_valid_polygon_mesh(sm));
}
*/
// test duplicated vertex
{
std::cout << "testing handling of duplicated non-manifold vertex\n";
Surface_mesh sm;
std::ifstream("data/decimation/m1.off") >> sm;
auto f1 = *std::next(faces(sm).begin(), 594);
auto f2 = *std::next(faces(sm).begin(), 2378);
CGAL::Euler::remove_face(halfedge(f1, sm), sm);
CGAL::Euler::remove_face(halfedge(f2, sm), sm);
PMP::duplicate_non_manifold_vertices(sm);
std::size_t nbv_before = vertices(sm).size();
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out);
assert(vertices(sm_out).size()<nbv_before);
std::ofstream("nmd_m1.off") << std::setprecision(17) << sm_out;
assert(CGAL::is_valid_polygon_mesh(sm_out));
}
// test duplicated vertex at patch interface
{
std::cout << "testing handling of duplicated non-manifold vertex at patch interface\n";
Surface_mesh sm;
std::ifstream("data/decimation/m1.off") >> sm;
auto f1 = *std::next(faces(sm).begin(), 244);
auto f2 = *std::next(faces(sm).begin(), 2279);
CGAL::Euler::remove_face(halfedge(f1, sm), sm);
CGAL::Euler::remove_face(halfedge(f2, sm), sm);
PMP::duplicate_non_manifold_vertices(sm);
std::size_t nbv_before = vertices(sm).size();
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out);
assert(vertices(sm_out).size()<nbv_before);
std::ofstream("nmdi_m1.off") << std::setprecision(17) << sm_out;
assert(CGAL::is_valid_polygon_mesh(sm_out));
}
assert(OK);
// testing decimate function with almost coplanar/collinear tests
for (int i=1; i<=nb_meshes; ++i)
{
std::cout << "handling decimation of transformed data/decimation/m" << i << ".off (approximate coplanar/collinear)\n";
std::stringstream ss;
ss << "data/decimation/m" << i << ".off";
Surface_mesh sm;
std::ifstream in(ss.str().c_str());
in >> sm;
PMP::transform(rot, sm);
// call the decimation function
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out, CGAL::parameters::cosine_of_maximum_angle(0.99));
ss=std::stringstream();
ss << "out_a" << i << ".off";
std::ofstream out(ss.str().c_str());
out << sm_out;
std::cout << " output written to out_a" << i << ".off\n";
assert(CGAL::is_valid_polygon_mesh(sm_out));
}
//testing decimation of meshes, preserving common interface
const int nb_meshes_range=9;
std::vector<Surface_mesh> meshes(nb_meshes_range);
for (int i=1; i<=nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "data/decimation/range/m" << i << ".off";
std::ifstream in(ss.str().c_str());
in >> meshes[i-1];
}
std::cout << "decimate a range of meshes with common interfaces\n";
if (!PMP::decimate_meshes_with_common_interfaces(meshes))
{
OK=false;
std::cerr << "ERROR: decimate failed to remesh some patches\n";
}
std::cout << " output written to";
for (int i=0; i<nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "out_r" << i+1 << ".off";
std::ofstream out(ss.str().c_str());
out << meshes[i];
std::cout << " out_r" << i+1 << ".off";
}
std::cout << "\n";
for (int i=0; i<nb_meshes_range; ++i)
assert(CGAL::is_valid_polygon_mesh(meshes[i]));
//testing decimation of meshes, preserving common interface and a patch that fails to simplify at the interface
meshes.clear();
meshes.resize(nb_meshes_range);
for (int i=1; i<=nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "data/decimation/range/m" << i << ".off";
std::ifstream in(ss.str().c_str());
in >> meshes[i-1];
}
auto f1 = *std::next(faces(meshes[4]).begin(), 1);
auto f2 = *std::next(faces(meshes[4]).begin(), 109);
CGAL::Euler::remove_face(halfedge(f1, meshes[4]), meshes[4]);
CGAL::Euler::remove_face(halfedge(f2, meshes[4]), meshes[4]);
PMP::duplicate_non_manifold_vertices(meshes[4]);
f1 = *std::next(faces(meshes[0]).begin(), 322);
f2 = *std::next(faces(meshes[0]).begin(), 963);
CGAL::Euler::remove_face(halfedge(f1, meshes[0]), meshes[0]);
CGAL::Euler::remove_face(halfedge(f2, meshes[0]), meshes[0]);
PMP::duplicate_non_manifold_vertices(meshes[0]);
f1 = *std::next(faces(meshes[8]).begin(), 23);
f2 = *std::next(faces(meshes[8]).begin(), 164);
CGAL::Euler::remove_face(halfedge(f1, meshes[8]), meshes[8]);
CGAL::Euler::remove_face(halfedge(f2, meshes[8]), meshes[8]);
PMP::duplicate_non_manifold_vertices(meshes[8]);
std::cout << "decimate a range of meshes with common interfaces and issue at the interface\n";
if (!PMP::decimate_meshes_with_common_interfaces(meshes))
std::cerr << "decimate failed to remesh some patches (expected)\n";
std::cout << " output written to";
for (int i=0; i<nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "out_fi_r" << i+1 << ".off";
std::ofstream out(ss.str().c_str());
out << meshes[i];
std::cout << " out_fi_r" << i+1 << ".off";
}
std::cout << "\n";
for (int i=0; i<nb_meshes_range; ++i)
assert(CGAL::is_valid_polygon_mesh(meshes[i]));
//testing decimation of meshes, preserving common interface with almost coplanar/collinear tests
meshes.clear();
meshes.resize(nb_meshes_range);
for (int i=1; i<=nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "data/decimation/range/am" << i << ".off";
std::ifstream in(ss.str().c_str());
in >> meshes[i-1];
}
std::cout << "decimate a range of meshes with common interfaces (approximate coplanar/collinear)\n";
if (!PMP::decimate_meshes_with_common_interfaces(meshes, -0.99))
{
OK=false;
std::cerr << "ERROR: decimate failed to remesh some patches\n";
}
std::cout << " output written to";
for (int i=0; i<nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "out_ar" << i+1 << ".off";
std::ofstream out(ss.str().c_str());
out << meshes[i];
std::cout << " out_ar" << i+1 << ".off";
}
std::cout << "\n";
for (int i=0; i<nb_meshes_range; ++i)
assert(CGAL::is_valid_polygon_mesh(meshes[i]));
// test face/vertex maps
{
std::cout << "check face patch ids\n";
std::cout << " face map alone\n";
Surface_mesh in, out;
std::ifstream(CGAL::data_file_path("meshes/cube-meshed.off")) >> in;
assert(vertices(in).size()!=0);
auto fmap_in = in.add_property_map<Surface_mesh::Face_index, std::size_t>("f:pid").first;
auto fmap_out = out.add_property_map<Surface_mesh::Face_index, std::size_t>("f:pid").first;
auto vmap_in = in.add_property_map<Surface_mesh::Vertex_index, std::size_t>("v:pid").first;
auto vmap_out = out.add_property_map<Surface_mesh::Vertex_index, std::size_t>("v:pid").first;
PMP::remesh_planar_patches(in, out,
CGAL::parameters::face_patch_map(fmap_in),
CGAL::parameters::face_patch_map(fmap_out));
auto get_id = [](Surface_mesh::Face_index f, Surface_mesh& sm)
{
auto h = halfedge(f, sm);
Point_3 p=sm.point(source(h, sm)), q=sm.point(target(h, sm)), r=sm.point(target(next(h, sm), sm));
if (p.x()==-1 && q.x()==-1 && r.x()==-1) return 0;
if (p.x()== 1 && q.x()== 1 && r.x()== 1) return 1;
if (p.y()==-1 && q.y()==-1 && r.y()==-1) return 2;
if (p.y()== 1 && q.y()== 1 && r.y()== 1) return 3;
if (p.z()==-1 && q.z()==-1 && r.z()==-1) return 4;
assert(p.z()==1 && q.z()==1 && r.z()==1);
return 5;
};
std::array<std::size_t, 6> pids; // xi, Xi, yi, Yi, zi, Zi;
for (auto f : faces(out)) pids[get_id(f, out)]=get(fmap_out, f);
for (auto f : faces(in)) assert(pids[get_id(f, in)]==get(fmap_in, f));
//------------------------------------------------------
std::cout << " face and vertex maps\n";
out.clear_without_removing_property_maps();
PMP::remesh_planar_patches(in, out,
CGAL::parameters::face_patch_map(fmap_in).vertex_corner_map(vmap_in),
CGAL::parameters::face_patch_map(fmap_out).vertex_corner_map(vmap_out));
auto check_corner_ids = [&]()
{
std::vector<Point_3> id2pt(vertices(out).size());
for (auto v : vertices(out))
id2pt[get(vmap_out, v)]=out.point(v);
for (auto v : vertices(in))
{
if (!( get(vmap_in, v)==std::size_t(-1) || id2pt[get(vmap_in, v)]==in.point(v) ))
std::cout << get(vmap_in, v) << " vs " << std::size_t(-1) << " vs " << std::size_t(-2) << "\n";
assert( get(vmap_in, v)==std::size_t(-1) || id2pt[get(vmap_in, v)]==in.point(v) );
}
};
check_corner_ids();
for (auto f : faces(out)) pids[get_id(f, out)]=get(fmap_out, f);
for (auto f : faces(in)) assert(pids[get_id(f, in)]==get(fmap_in, f));
//------------------------------------------------------
std::cout << " vertex map alone\n";
out.clear_without_removing_property_maps();
PMP::remesh_planar_patches(in, out,
CGAL::parameters::vertex_corner_map(vmap_in),
CGAL::parameters::vertex_corner_map(vmap_out));
check_corner_ids();
//------------------------------------------------------
std::cout << " no simplification face+vertex maps\n";
out.clear_without_removing_property_maps();
in.clear_without_removing_property_maps();
std::ifstream(CGAL::data_file_path("meshes/sphere.off")) >> in;
assert(vertices(in).size()!=0);
PMP::remesh_planar_patches(in, out,
CGAL::parameters::face_patch_map(fmap_in).vertex_corner_map(vmap_in),
CGAL::parameters::face_patch_map(fmap_out).vertex_corner_map(vmap_out));
check_corner_ids();
std::map<std::array<Point_3, 3>, std::size_t> pids_map;
auto get_pt_sorted_array = [](Surface_mesh::Face_index f, Surface_mesh& sm)
{
auto h = halfedge(f, sm);
std::array<Point_3, 3> pts = CGAL::make_array(sm.point(source(h, sm)),
sm.point(target(h, sm)),
sm.point(target(next(h, sm), sm)));
std::sort(pts.begin(), pts.end());
return pts;
};
for (auto f : faces(out)) pids_map[get_pt_sorted_array(f, out)]=get(fmap_out, f);
for (auto f : faces(in)) assert(pids_map[get_pt_sorted_array(f, in)]==get(fmap_in, f));
}
#if 0 // tests to be re-enable when using region growing with common interface
// testing decimation of meshes, preserving common interface with almost coplanar/collinear tests using PCA
std::cout << "decimate a range of meshes with common interfaces (approximate coplanar/collinear with PCA)\n";
if (!PMP::decimate_meshes_with_common_interfaces_and_pca_for_coplanarity(meshes, 0.99, -0.99))
std::cerr << "ERROR: decimate failed to remesh some patches\n";
std::cout << " output written to";
for (int i=0; i<nb_meshes_range; ++i)
{
std::stringstream ss;
ss << "out_ar_pca" << i+1 << ".off";
std::ofstream out(ss.str().c_str());
out << meshes[i];
std::cout << " out_ar_pca" << i+1 << ".off";
}
std::cout << "\n";
for (int i=0; i<nb_meshes_range; ++i)
assert(CGAL::is_valid_polygon_mesh(meshes[i]));
#endif
// testing decimate function with almost coplanar/collinear tests using RG
for (int i=1; i<=nb_meshes; ++i)
{
std::cout << "handling decimation of transformed data/decimation/m" << i << ".off (approximate coplanar/collinear with RG)\n";
std::stringstream ss;
ss << "data/decimation/m" << i << ".off";
Surface_mesh sm;
std::ifstream in(ss.str().c_str());
in >> sm;
PMP::transform(rot, sm);
// call the decimation function
approximate_remeshing(sm, 0.98, 1e-2);
ss=std::stringstream();
ss << "out_a_rg" << i << ".off";
std::ofstream out(ss.str().c_str());
out << sm;
std::cout << " output written to out_a_rg" << i << ".off\n";
assert(CGAL::is_valid_polygon_mesh(sm));
}
// two examples that fails with approximate but works with RG
//PCA first
{
Surface_mesh sm;
std::cout << "decimate of refined data/decimation/sphere.off using RG\n";
std::ifstream(CGAL::data_file_path("meshes/sphere.off")) >> sm;
CGAL::Subdivision_method_3::Sqrt3_subdivision(sm,
CGAL::parameters::number_of_iterations(3));
approximate_remeshing(sm, 0.98, 1e-2);
std::ofstream out("sphere_rg.off");
out << sm;
std::cout << "output written to sphere_rg.off\n";
assert(CGAL::is_valid_polygon_mesh(sm));
}
// Approximation then
{
Surface_mesh sm;
std::ifstream(CGAL::data_file_path("meshes/sphere.off")) >> sm;
CGAL::Subdivision_method_3::Sqrt3_subdivision(sm,
CGAL::parameters::number_of_iterations(3));
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out, CGAL::parameters::cosine_of_maximum_angle(0.99));
}
{
Surface_mesh sm;
std::cout << "decimate of data/decimation/sphere_selection.off using approximate predicates\n";
std::ifstream in("data/decimation/sphere_selection.off");
in >> sm;
Surface_mesh sm_out;
PMP::remesh_planar_patches(sm, sm_out, CGAL::parameters::cosine_of_maximum_angle(0.99));
std::ofstream out("sphere_selection_app.off");
out << sm_out;
std::cout << "output written to sphere_selection_app.off\n";
assert(CGAL::is_valid_polygon_mesh(sm_out));
}
assert(OK);
return 0 ;
}

View File

@ -33,32 +33,37 @@ if(TARGET CGAL::Eigen3_support)
scene_mcf_item
demo_framework
CGAL::Eigen3_support)
# The smoothing plugin can still do some things, even if Ceres is not found
qt5_wrap_ui( smoothingUI_FILES Smoothing_plugin.ui Smoothing_tangential_relaxation.ui)
polyhedron_demo_plugin(smoothing_plugin Smoothing_plugin ${smoothingUI_FILES})
target_link_libraries(smoothing_plugin PUBLIC scene_surface_mesh_item scene_selection_item CGAL::Eigen3_support)
find_package(Ceres QUIET)
include(CGAL_Ceres_support)
if(TARGET CGAL::Ceres_support)
target_link_libraries(smoothing_plugin PUBLIC CGAL::Ceres_support)
endif()
# The smoothing plugin can still do some things, even if Ceres is not found
qt5_wrap_ui( smoothingUI_FILES Smoothing_plugin.ui Smoothing_tangential_relaxation.ui)
polyhedron_demo_plugin(smoothing_plugin Smoothing_plugin ${smoothingUI_FILES})
target_link_libraries(smoothing_plugin PUBLIC scene_surface_mesh_item scene_selection_item CGAL::Eigen3_support)
find_package(Ceres QUIET)
include(CGAL_Ceres_support)
if(TARGET CGAL::Ceres_support)
target_link_libraries(smoothing_plugin PUBLIC CGAL::Ceres_support)
endif()
set_package_properties(
Ceres PROPERTIES
DESCRIPTION "A large scale non-linear optimization library."
PURPOSE "Can be used as a solver in the smoothing plugin.")
target_link_libraries(extrude_plugin PUBLIC CGAL::Eigen3_support)
set_package_properties(
Ceres PROPERTIES
DESCRIPTION "A large scale non-linear optimization library."
PURPOSE "Can be used as a solver in the smoothing plugin.")
target_link_libraries(extrude_plugin PUBLIC CGAL::Eigen3_support)
if(BUILD_TESTING AND NOT CMAKE_VS_MSBUILD_COMMAND)
set_tests_properties(
compilation_of__extrude_plugin
compilation_of__fairing_plugin
PROPERTIES RESOURCE_LOCK Selection_test_resources)
set_tests_properties(
compilation_of__hole_filling_plugin
compilation_of__smoothing_plugin
PROPERTIES RESOURCE_LOCK Selection_test_resources)
endif()
qt5_wrap_ui(remeshPlanarPatchesUI_FILES Remesh_planar_patches_dialog.ui)
polyhedron_demo_plugin(remesh_planar_patches_plugin Remesh_planar_patches_plugin
${remeshPlanarPatchesUI_FILES} KEYWORDS PMP)
target_link_libraries(remesh_planar_patches_plugin PUBLIC scene_surface_mesh_item CGAL::Eigen3_support)
if(BUILD_TESTING AND NOT CMAKE_VS_MSBUILD_COMMAND)
set_tests_properties(
compilation_of__extrude_plugin
compilation_of__fairing_plugin
PROPERTIES RESOURCE_LOCK Selection_test_resources)
set_tests_properties(
compilation_of__hole_filling_plugin
compilation_of__smoothing_plugin
PROPERTIES RESOURCE_LOCK Selection_test_resources)
endif()
else()
message(STATUS "NOTICE: The hole filling and fairing plugins require Eigen 3.2 (or higher) and will not be available.")
endif()
@ -160,6 +165,7 @@ if(BUILD_TESTING AND NOT CMAKE_VS_MSBUILD_COMMAND)
compilation_of__selection_plugin
compilation_of__triangulate_facets_plugin
compilation_of__isotropic_remeshing_plugin
compilation_of__remesh_planar_patches_plugin
compilation_of__random_perturbation_plugin
compilation_of__engrave_text_plugin
compilation_of__degenerated_faces_plugin

View File

@ -0,0 +1,216 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Remesh_planar_patches_dialog</class>
<widget class="QDialog" name="Remesh_planar_patches_dialog">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>262</width>
<height>285</height>
</rect>
</property>
<property name="windowTitle">
<string>Remesh planar patches parameters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Parameters</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="cos_label">
<property name="text">
<string>Cosinus Threshold</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="DoubleEdit" name="cos_dspinbox">
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string>1</string>
</property>
<property name="placeholderText">
<string>0.00</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="dist_label">
<property name="text">
<string>Frechet Distance</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="DoubleEdit" name="dist_dspinbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="inputMethodHints">
<set>Qt::ImhNone</set>
</property>
<property name="inputMask">
<string/>
</property>
<property name="text">
<string>1</string>
</property>
<property name="placeholderText">
<string>0.00</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="notriangulation_checkbox">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Do not triangulate patches</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="use_region_growing_checkbox">
<property name="text">
<string>Use region growing of planes</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="postprocess_regions_checkbox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Post-process regions</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="create_new_item_checkbox">
<property name="text">
<string>Create new item</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>DoubleEdit</class>
<extends>QLineEdit</extends>
<header>CGAL_double_edit.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>cos_dspinbox</tabstop>
<tabstop>notriangulation_checkbox</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Remesh_planar_patches_dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>397</x>
<y>333</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>195</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Remesh_planar_patches_dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>397</x>
<y>333</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>195</y>
</hint>
</hints>
</connection>
<connection>
<sender>use_region_growing_checkbox</sender>
<signal>toggled(bool)</signal>
<receiver>postprocess_regions_checkbox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>143</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>143</x>
<y>245</y>
</hint>
</hints>
</connection>
<connection>
<sender>use_region_growing_checkbox</sender>
<signal>toggled(bool)</signal>
<receiver>dist_dspinbox</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>143</x>
<y>214</y>
</hint>
<hint type="destinationlabel">
<x>203</x>
<y>135</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,327 @@
#include <QtCore/qglobal.h>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include "Scene_surface_mesh_item.h"
#include <CGAL/iterator.h>
#include <CGAL/Polygon_mesh_processing/remesh_planar_patches.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <CGAL/Polygon_mesh_processing/region_growing.h>
#include <CGAL/utility.h>
#include <CGAL/property_map.h>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/vector_property_map.hpp>
#include <QElapsedTimer>
#include <QAction>
#include <QMainWindow>
#include <QApplication>
#include <QString>
#include <QDialog>
#include <QtPlugin>
#include <QMessageBox>
#include <vector>
#include <algorithm>
#include <queue>
#include <sstream>
#include <cmath>
#include <unordered_set>
#include "ui_Remesh_planar_patches_dialog.h"
namespace PMP = CGAL::Polygon_mesh_processing;
template <class SM>
struct Mesh_map
{
typedef SM value_type;
typedef SM& reference;
typedef Scene_surface_mesh_item* key_type;
typedef boost::lvalue_property_map_tag category;
SM& operator[](Scene_surface_mesh_item* poly_item) const
{
return *poly_item->polyhedron();
}
};
using namespace CGAL::Three;
class Polyhedron_demo_remesh_planar_patches_plugin :
public QObject,
public Polyhedron_demo_plugin_interface
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "isotropic_remeshing_plugin.json")
typedef Scene_surface_mesh_item::Face_graph Mesh;
typedef boost::graph_traits<Mesh>::face_descriptor face_descriptor;
typedef boost::graph_traits<Mesh>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor halfedge_descriptor;
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface*)
{
this->scene = scene_interface;
this->mw = mainWindow;
actionRemeshPlanarPatches_ = new QAction("Remesh Planar Patches", mw);
actionRemeshPlanarPatches_->setProperty("subMenuName", "Polygon Mesh Processing");
if (actionRemeshPlanarPatches_) {
connect(actionRemeshPlanarPatches_, SIGNAL(triggered()),
this, SLOT(remeshing()));
}
}
QList<QAction*> actions() const {
return QList<QAction*>() << actionRemeshPlanarPatches_;
}
bool applicable(QAction*) const
{
if (scene->selectionIndices().size() == 1)
return qobject_cast<Scene_surface_mesh_item*>(scene->item(scene->mainSelectionIndex()));
Q_FOREACH(int index, scene->selectionIndices())
{
if (qobject_cast<Scene_surface_mesh_item*>(scene->item(index)))
return true;
}
return false;
}
public Q_SLOTS:
void remeshing()
{
if (scene->selectionIndices().size() > 1)
{
// Create dialog box
QDialog dialog(mw);
ui.setupUi(&dialog);
connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
ui.create_new_item_checkbox->setEnabled(false);
ui.use_region_growing_checkbox->setEnabled(false);
// Get values
int i = dialog.exec();
if (i == QDialog::Rejected)
{
std::cout << "Remeshing aborted" << std::endl;
return;
}
bool do_not_triangulate_faces = ui.notriangulation_checkbox->isChecked();
double cos_threshold = ui.cos_dspinbox->value();
std::vector<Scene_surface_mesh_item*> meshes;
for(int index : scene->selectionIndices())
{
Scene_surface_mesh_item* poly_item =
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
if (poly_item != nullptr)
meshes.push_back(poly_item);
}
PMP::decimate_meshes_with_common_interfaces(meshes, -cos_threshold, Mesh_map<Mesh>(), do_not_triangulate_faces);
for (Scene_surface_mesh_item* poly_item : meshes)
{
poly_item->invalidateOpenGLBuffers();
Q_EMIT poly_item->itemChanged();
}
return;
}
const Scene_interface::Item_id index = scene->mainSelectionIndex();
Scene_surface_mesh_item* poly_item =
qobject_cast<Scene_surface_mesh_item*>(scene->item(index));
if (poly_item)
{
// Create dialog box
QDialog dialog(mw);
ui.setupUi(&dialog);
connect(ui.buttonBox, SIGNAL(accepted()), &dialog, SLOT(accept()));
connect(ui.buttonBox, SIGNAL(rejected()), &dialog, SLOT(reject()));
// Get values
int i = dialog.exec();
if (i == QDialog::Rejected)
{
std::cout << "Remeshing aborted" << std::endl;
return;
}
bool do_not_triangulate_faces = ui.notriangulation_checkbox->isChecked();
bool create_new_item = ui.create_new_item_checkbox->isChecked();
double cos_threshold = ui.cos_dspinbox->value();
// wait cursor
QApplication::setOverrideCursor(Qt::WaitCursor);
QElapsedTimer time;
time.start();
Mesh& pmesh = *poly_item->polyhedron();
if (!CGAL::is_triangle_mesh(pmesh))
{
QApplication::restoreOverrideCursor();
if (QMessageBox::Ok ==
QMessageBox::question(mw, tr("Error - Triangulate Faces?"),
tr("The input mesh is not a triangulated surface mesh.\n"
"Do you wish to triangulate faces first, or cancel remeshing ?"),
(QMessageBox::Ok | QMessageBox::Cancel), QMessageBox::Ok))
{
QApplication::setOverrideCursor(Qt::WaitCursor);
PMP::triangulate_faces(pmesh);
}
else
{
return;
}
}
if (ui.use_region_growing_checkbox->isChecked())
{
typedef boost::property_map<Mesh, CGAL::face_patch_id_t<int> >::type Patch_id_pmap;
Patch_id_pmap in_fpmap = get(CGAL::face_patch_id_t<int>(), pmesh);
std::vector<std::size_t> corner_id_map(num_vertices(pmesh), -1);
std::vector<bool> ecm(num_edges(pmesh), false);
boost::vector_property_map<CGAL::Epick::Vector_3> normal_map;
std::size_t nb_regions =
PMP::region_growing_of_planes_on_faces(pmesh,
in_fpmap,
CGAL::parameters::cosine_of_maximum_angle(cos_threshold).
region_primitive_map(normal_map).
maximum_distance(ui.dist_dspinbox->value()).
postprocess_regions(ui.postprocess_regions_checkbox->isChecked()));
std::size_t nb_corners =
PMP::detect_corners_of_regions(pmesh,
in_fpmap,
nb_regions,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::parameters::cosine_of_maximum_angle(cos_threshold).
maximum_distance(ui.dist_dspinbox->value()).
edge_is_constrained_map(CGAL::make_random_access_property_map(ecm)));
if (create_new_item)
{
Scene_surface_mesh_item* new_item=new Scene_surface_mesh_item();
Mesh& out = *new_item->polyhedron();
Patch_id_pmap out_fpmap = get(CGAL::face_patch_id_t<int>(), out);
//TODO: use the return type
PMP::remesh_almost_planar_patches(pmesh,
out,
nb_regions, nb_corners,
in_fpmap,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map),
CGAL::parameters::do_not_triangulate_faces(do_not_triangulate_faces).face_patch_map(out_fpmap));
new_item->setName(tr("%1_remeshed").arg(poly_item->name()));
scene->setSelectedItem( scene->addItem(new_item) );
poly_item->setItemIsMulticolor(true);
poly_item->computeItemColorVectorAutomatically(true);
poly_item->invalidateOpenGLBuffers();
Q_EMIT poly_item->itemChanged();
new_item->setItemIsMulticolor(true);
new_item->computeItemColorVectorAutomatically(false);
new_item->color_vector()=poly_item->color_vector(); // colors are not deterministic
new_item->invalidateOpenGLBuffers();
Q_EMIT new_item->itemChanged();
}
else
{
PMP::remesh_almost_planar_patches(pmesh,
pmesh,
nb_regions, nb_corners,
in_fpmap,
CGAL::make_random_access_property_map(corner_id_map),
CGAL::make_random_access_property_map(ecm),
CGAL::parameters::patch_normal_map(normal_map),
CGAL::parameters::visitor([](Mesh& pmesh){pmesh.clear_without_removing_property_maps ();})
.do_not_triangulate_faces(do_not_triangulate_faces));
pmesh.remove_property_map<Mesh::Face_index, int>(in_fpmap);
poly_item->invalidateOpenGLBuffers();
Q_EMIT poly_item->itemChanged();
}
}
else
{
if (create_new_item)
{
typedef boost::property_map<Mesh, CGAL::face_patch_id_t<int> >::type Patch_id_pmap;
Scene_surface_mesh_item* new_item=new Scene_surface_mesh_item();
Mesh& out = *new_item->polyhedron();
Patch_id_pmap in_fpmap = get(CGAL::face_patch_id_t<int>(), pmesh);
Patch_id_pmap out_fpmap = get(CGAL::face_patch_id_t<int>(), out);
PMP::remesh_planar_patches(pmesh,
out,
CGAL::parameters::cosine_of_maximum_angle(cos_threshold)
.face_patch_map(in_fpmap),
CGAL::parameters::face_patch_map(out_fpmap)
.do_not_triangulate_faces(do_not_triangulate_faces));
new_item->setName(tr("%1_remeshed").arg(poly_item->name()));
scene->setSelectedItem( scene->addItem(new_item) );
poly_item->setItemIsMulticolor(true);
poly_item->computeItemColorVectorAutomatically(true);
poly_item->invalidateOpenGLBuffers();
Q_EMIT poly_item->itemChanged();
new_item->setItemIsMulticolor(true);
new_item->computeItemColorVectorAutomatically(false);
new_item->color_vector()=poly_item->color_vector(); // colors are not deterministic
new_item->invalidateOpenGLBuffers();
Q_EMIT new_item->itemChanged();
}
else
{
PMP::remesh_planar_patches(pmesh,
pmesh,
CGAL::parameters::cosine_of_maximum_angle(cos_threshold),
CGAL::parameters::visitor([](Mesh& pmesh){pmesh.clear_without_removing_property_maps ();})
.do_not_triangulate_faces(do_not_triangulate_faces));
poly_item->invalidateOpenGLBuffers();
Q_EMIT poly_item->itemChanged();
}
}
std::cout << "ok (" << time.elapsed() << " ms)" << std::endl;
// default cursor
QApplication::restoreOverrideCursor();
}
}
private:
Scene_interface *scene;
QMainWindow* mw;
QAction* actionRemeshPlanarPatches_;
Ui::Remesh_planar_patches_dialog ui;
}; // end Polyhedron_demo_remesh_planar_patches_plugin
#include "Remesh_planar_patches_plugin.moc"

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>495</width>
<height>552</height>
<width>501</width>
<height>615</height>
</rect>
</property>
<property name="windowTitle">
@ -236,6 +236,9 @@
</item>
<item>
<widget class="DoubleEdit" name="m_probability_field">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -457,5 +460,21 @@
</hint>
</hints>
</connection>
<connection>
<sender>ransac</sender>
<signal>toggled(bool)</signal>
<receiver>m_probability_field</receiver>
<slot>setEnabled(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>64</x>
<y>87</y>
</hint>
<hint type="destinationlabel">
<x>366</x>
<y>370</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -37,6 +37,8 @@ CGAL_add_named_parameter(halfedge_to_halfedge_output_iterator_t, halfedge_to_hal
CGAL_add_named_parameter(face_to_face_output_iterator_t, face_to_face_output_iterator, face_to_face_output_iterator)
CGAL_add_named_parameter(point_to_vertex_output_iterator_t, point_to_vertex_output_iterator, point_to_vertex_output_iterator)
CGAL_add_named_parameter(polygon_to_face_output_iterator_t, polygon_to_face_output_iterator, polygon_to_face_output_iterator)
CGAL_add_named_parameter(point_to_vertex_map_t, point_to_vertex_map, point_to_vertex_map)
CGAL_add_named_parameter(polygon_to_face_map_t, polygon_to_face_map, polygon_to_face_map)
CGAL_add_named_parameter(vertex_to_vertex_map_t, vertex_to_vertex_map, vertex_to_vertex_map)
CGAL_add_named_parameter(halfedge_to_halfedge_map_t, halfedge_to_halfedge_map, halfedge_to_halfedge_map)
@ -68,6 +70,7 @@ CGAL_add_named_parameter(vertex_incident_patches_t, vertex_incident_patches, ver
CGAL_add_named_parameter(density_control_factor_t, density_control_factor, density_control_factor)
CGAL_add_named_parameter(use_delaunay_triangulation_t, use_delaunay_triangulation, use_delaunay_triangulation)
CGAL_add_named_parameter(do_not_use_cubic_algorithm_t, do_not_use_cubic_algorithm, do_not_use_cubic_algorithm)
CGAL_add_named_parameter(do_not_triangulate_faces_t, do_not_triangulate_faces, do_not_triangulate_faces)
CGAL_add_named_parameter(use_2d_constrained_delaunay_triangulation_t, use_2d_constrained_delaunay_triangulation, use_2d_constrained_delaunay_triangulation)
CGAL_add_named_parameter(fairing_continuity_t, fairing_continuity, fairing_continuity)
CGAL_add_named_parameter(sparse_linear_solver_t, sparse_linear_solver, sparse_linear_solver)
@ -147,6 +150,10 @@ CGAL_add_named_parameter(mesh_facet_distance_t, mesh_facet_distance, mesh_facet_
CGAL_add_named_parameter(mesh_facet_topology_t, mesh_facet_topology, mesh_facet_topology)
CGAL_add_named_parameter(polyline_constraints_t, polyline_constraints, polyline_constraints)
CGAL_add_named_parameter(do_scale_t, do_scale, do_scale)
CGAL_add_named_parameter(vertex_corner_map_t, vertex_corner_map, vertex_corner_map)
CGAL_add_named_parameter(patch_normal_map_t, patch_normal_map, patch_normal_map)
CGAL_add_named_parameter(region_primitive_map_t, region_primitive_map, region_primitive_map)
CGAL_add_named_parameter(postprocess_regions_t, postprocess_regions, postprocess_regions)
// List of named parameters that we use in the package 'Surface Mesh Simplification'
CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost)
@ -259,7 +266,7 @@ CGAL_add_named_parameter(minimum_region_size_t, minimum_region_size, minimum_reg
CGAL_add_named_parameter(sphere_radius_t, sphere_radius, sphere_radius)
CGAL_add_named_parameter(k_neighbors_t, k_neighbors, k_neighbors)
CGAL_add_named_parameter(item_map_t, item_map, item_map)
CGAL_add_named_parameter(cosine_of_maxium_angle_t, cosine_of_maxium_angle, cosine_of_maxium_angle)
CGAL_add_named_parameter(cosine_of_maximum_angle_t, cosine_of_maximum_angle, cosine_of_maximum_angle)
CGAL_add_named_parameter(minimum_radius_t, minimum_radius, minimum_radius)
CGAL_add_named_parameter(maximum_radius_t, maximum_radius, maximum_radius)

View File

@ -25,6 +25,32 @@
namespace CGAL {
namespace Polygon_mesh_processing {
namespace internal
{
template <class GT, class Pair>
void fill_region_primitive_map(const std::vector<Pair>&, internal_np::Param_not_found) {}
template <class GT, class Pair, class RegionMap>
void fill_plane_or_vector_map(const std::vector<Pair>& normals, RegionMap region_map, typename GT::Vector_3)
{
for (std::size_t i = 0 ; i<normals.size(); ++i)
put(region_map, i, normals[i].first.orthogonal_vector());
}
template <class GT, class Pair, class RegionMap>
void fill_plane_or_vector_map(const std::vector<Pair>& normals, RegionMap region_map, typename GT::Plane_3)
{
for (std::size_t i = 0 ; i<normals.size(); ++i)
put(region_map, i, normals[i].first);
}
template <class GT, class Pair, class RegionMap>
void fill_region_primitive_map(const std::vector<Pair>& normals, RegionMap region_map)
{
fill_plane_or_vector_map<GT>(normals, region_map, typename boost::property_traits<RegionMap>::value_type());
}
}
/*!
\ingroup PkgPolygonMeshProcessingRef
\brief applies a region growing algorithm to fit planes on faces of a mesh.
@ -53,10 +79,15 @@ namespace Polygon_mesh_processing {
such that they are considered part of the same region}
\cgalParamType{`GeomTraits::FT` with `GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{25 degrees}
\cgalParamExtra{this parameter and `cosine_of_maxium_angle` are exclusive}
\cgalParamExtra{this parameter and `cosine_of_maximum_angle` are exclusive}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamDescription{The maximum angle, given as a cosine, between the normal of the supporting planes of adjacent faces
\cgalParamNBegin{postprocess_regions}
\cgalParamDescription{Apply a post-processing step to the output of the region growing algorithm.}
\cgalParamType{`bool`}
\cgalParamDefault{false}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{The maximum angle, given as a cosine, between the normals of the supporting planes of adjacent faces
such that they are considered part of the same region}
\cgalParamType{`GeomTraits::FT` with `GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{`cos(25 * PI / 180)`}
@ -81,6 +112,14 @@ namespace Polygon_mesh_processing {
\cgalParamDefault{a \cgal Kernel deduced from the point type, using `CGAL::Kernel_traits`}
\cgalParamExtra{The geometric traits class must be compatible with the vertex point type.}
\cgalParamNEnd
\cgalParamNBegin{region_primitive_map}
\cgalParamDescription{a property map filled by this function and that will contain for each region
the plane (or only its orthognonal vector) estimated that approximates it.}
\cgalParamType{a class model of `WritablePropertyMap` with the value type of `RegionMap` as key and
`GeomTraits::Plane_3` or `GeomTraits::Vector_3` as value type,
`GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{None}
\cgalParamNEnd
\cgalNamedParamsEnd
*/
template<typename PolygonMesh,
@ -113,9 +152,72 @@ region_growing_of_planes_on_faces(const PolygonMesh& mesh,
std::vector<typename Region_growing::Primitive_and_region> regions;
Region_growing region_growing(
faces(mesh), sorting.ordered(), neighbor_query, region_type, region_map);
region_growing.detect(CGAL::Emptyset_iterator());
return region_growing.number_of_regions_detected();
typedef typename boost::graph_traits<PolygonMesh>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<PolygonMesh>::halfedge_descriptor halfedge_descriptor;
std::vector<std::pair<typename Traits::Plane_3, std::vector<face_descriptor> > > tmp;
region_growing.detect(std::back_inserter(tmp));
if (choose_parameter(get_parameter(np, internal_np::postprocess_regions), false))
{
// first try for a post-processing: look at regions made of one face and check if a
// larger region contains its 3 vertices and if so assigned it to it.
typedef typename boost::property_traits<RegionMap>::value_type Id;
for (std::size_t i=0; i<tmp.size(); ++i)
{
if (tmp[i].second.size() == 1)
{
face_descriptor f0=tmp[i].second[0];
std::map<Id, int> vertex_incidence;
halfedge_descriptor h0 = halfedge(f0, mesh);
for (int k=0; k<3; ++k)
{
std::set<Id> ids_for_v;
for (halfedge_descriptor h : halfedges_around_target(h0, mesh))
{
if (!is_border(h, mesh))
{
Id id = get(region_map, face(h, mesh));
if (std::size_t(id)!=i)
ids_for_v.insert(id);
}
}
h0=next(h0, mesh);
for (Id id : ids_for_v)
vertex_incidence.insert(std::make_pair(id, 0)).first->second+=1;
}
std::set<Id> candidates;
for (const std::pair<const Id, int>& p : vertex_incidence)
{
if (p.second == 3)
candidates.insert(p.first);
}
if (candidates.size() == 1)
{
Id new_id = *candidates.begin();
put(region_map, f0, new_id);
tmp[new_id].second.push_back(f0);
tmp[i].second.clear();
}
}
}
auto last = std::remove_if(tmp.begin(), tmp.end(),
[](const std::pair<typename Traits::Plane_3, std::vector<face_descriptor>>& p)
{return p.second.empty();});
tmp.erase(last, tmp.end());
//update region map
for (std::size_t i=0; i<tmp.size(); ++i)
{
for (face_descriptor f : tmp[i].second)
put(region_map, f, i);
}
}
internal::fill_region_primitive_map<Traits>(tmp, parameters::get_parameter(np, internal_np::region_primitive_map));
return tmp.size();
}
/*!
@ -125,7 +227,7 @@ region_growing_of_planes_on_faces(const PolygonMesh& mesh,
More precisely, a corner on the boundary of a region is a vertex that is either shared by at least three regions (two if it is also a vertex on the boundary of the mesh), or that is incident to two segments edges assigned to different lines.
See Section \ref Shape_detection_RegionGrowing for more details on the method.
@tparam PolygonMesh a model of `FaceListGraph` and `EdgeListGaph`
@tparam PolygonMesh a model of `FaceListGraph` and `EdgeListGraph`
@tparam RegionMap a model of `ReadablePropertyMap` with `boost::graph_traits<PolygonMesh>::%face_descriptor` as key type and `std::size_t` as value type.
@tparam CornerIdMap a model of `WritablePropertyMap` with `boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and `std::size_t` as value type.
@tparam NamedParameters a sequence of \ref bgl_namedparameters "Named Parameters"
@ -146,21 +248,23 @@ region_growing_of_planes_on_faces(const PolygonMesh& mesh,
\cgalParamType{a class model of `ReadWritePropertyMap` with `boost::graph_traits<PolygonMesh>::%edge_descriptor`
as key type and `bool` as value type}
\cgalParamDefault{Unused if not provided}
\cgalParamExtra{The value for each edge must be initialized to `false`.}
\cgalParamNEnd
\cgalParamNBegin{maximum_distance}
\cgalParamDescription{the maximum distance from a point to a line such that it is considered part of the region of the line}
\cgalParamDescription{the maximum distance from a segment to a line such that it is considered part of the region of the line}
\cgalParamType{`GeomTraits::FT` with `GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{1}
\cgalParamExtra{this parameter and `cosine_of_maxium_angle` are exclusive}
\cgalParamNEnd
\cgalParamNBegin{maximum_angle}
\cgalParamDescription{the maximum angle in degrees between two adjacent segments
such that they are considered part of the same region}
\cgalParamType{`GeomTraits::FT` with `GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{25 degrees}
\cgalParamExtra{this parameter and `cosine_of_maximum_angle` are exclusive}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamDescription{The maximum angle, given as a cosine, between two adjacent segments
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{The maximum angle, given as a cosine, for the smallest angle
between the supporting line of a segment and an adjacent segment
such that they are considered part of the same region}
\cgalParamType{`GeomTraits::FT` with `GeomTraits` being the type of the parameter `geom_traits`}
\cgalParamDefault{`cos(25 * PI / 180)`}
@ -205,7 +309,7 @@ detect_corners_of_regions(
using face_descriptor = typename Graph_traits::face_descriptor;
using vertex_descriptor = typename Graph_traits::vertex_descriptor;
using Default_ecm = typename boost::template property_map<PolygonMesh, CGAL::dynamic_edge_property_t<bool> >::type;
using Default_ecm = typename boost::template property_map<PolygonMesh, CGAL::dynamic_edge_property_t<bool> >::const_type;
using Ecm = typename internal_np::Lookup_named_param_def <
internal_np::edge_is_constrained_t,
NamedParameters,
@ -213,8 +317,12 @@ detect_corners_of_regions(
> ::type;
Default_ecm dynamic_ecm;
if(!(is_default_parameter<NamedParameters, internal_np::edge_is_constrained_t>::value))
if(is_default_parameter<NamedParameters, internal_np::edge_is_constrained_t>::value)
{
dynamic_ecm = get(CGAL::dynamic_edge_property_t<bool>(), mesh);
for (edge_descriptor e : edges(mesh))
put(dynamic_ecm, e, false);
}
Ecm ecm = choose_parameter(get_parameter(np, internal_np::edge_is_constrained), dynamic_ecm);
using Polyline_graph = CGAL::Shape_detection::Polygon_mesh::Polyline_graph<PolygonMesh>;
@ -270,7 +378,7 @@ detect_corners_of_regions(
RG_lines rg_lines(
segment_range, pgraph, line_region);
std::vector< std::pair<typename Line_region::Primitive, std::vector<edge_descriptor> > > subregions;
std::vector< std::pair<typename Line_region::Primitive, std::vector<edge_descriptor> > > subregions; // TODO dump into pmap lines
rg_lines.detect(std::back_inserter(subregions));
#ifdef CGAL_DEBUG_DETECT_CORNERS_OF_REGIONS

View File

@ -129,7 +129,7 @@ namespace Point_set {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamType{`GeomTraits::FT`}
@ -168,7 +168,7 @@ namespace Point_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
\pre `minimum_radius >= 0`
\pre `maximum_radius >= minimum_radius`
@ -198,7 +198,7 @@ namespace Point_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;

View File

@ -128,7 +128,7 @@ namespace Point_set {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamType{`GeomTraits::FT`}
@ -167,7 +167,7 @@ namespace Point_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
\pre `minimum_radius >= 0`
\pre `maximum_radius >= minimum_radius`
@ -197,7 +197,7 @@ namespace Point_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;

View File

@ -118,7 +118,7 @@ namespace Point_set {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamType{`GeomTraits::FT`}
@ -145,7 +145,7 @@ namespace Point_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
*/
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
@ -174,7 +174,7 @@ namespace Point_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;
}

View File

@ -119,7 +119,7 @@ namespace Point_set {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamType{`GeomTraits::FT`}
@ -146,7 +146,7 @@ namespace Point_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
*/
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
@ -175,7 +175,7 @@ namespace Point_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;
}

View File

@ -118,7 +118,7 @@ namespace Point_set {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamType{`GeomTraits::FT`}
@ -157,7 +157,7 @@ namespace Point_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
\pre `minimum_radius >= 0`
\pre `maximum_radius >= minimum_radius`
@ -187,7 +187,7 @@ namespace Point_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;

View File

@ -118,9 +118,8 @@ namespace Polygon_mesh {
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cosine value `cos(maximum_angle * PI / 180)` to be used instead of the parameter `maximum_angle()`}
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{`cos(25 * PI / 180)`}
\cgalParamNEnd
@ -143,7 +142,7 @@ namespace Polygon_mesh {
\pre `faces(tmesh).size() > 0`
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
*/
template<typename CGAL_NP_TEMPLATE_PARAMETERS>
@ -176,7 +175,7 @@ namespace Polygon_mesh {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;
}

View File

@ -358,13 +358,12 @@ namespace internal {
*/
template<typename PrimitiveAndRegionOutputIterator = Emptyset_iterator>
PrimitiveAndRegionOutputIterator detect(PrimitiveAndRegionOutputIterator region_out = PrimitiveAndRegionOutputIterator()) {
// clear(); TODO: this is not valid to comment this clear()
// clear(); TODO: this is not valid to comment this clear()
m_visited_map.clear(); // tmp replacement for the line above
Region region;
m_nb_regions = 0;
// Grow regions.
for (auto it = m_seed_range.begin(); it != m_seed_range.end(); it++) {
const Item seed = *it;
@ -376,9 +375,11 @@ namespace internal {
// Check global conditions.
if (!is_success || !m_region_type.is_valid_region(region)) {
revert(region);
} else {
*(region_out++) = std::pair<typename RegionType::Primitive, Region>(m_region_type.primitive(), region);
}
else {
fill_region_map(m_nb_regions++, region);
if (!std::is_same<PrimitiveAndRegionOutputIterator, Emptyset_iterator>::value)
*region_out++ = std::make_pair(m_region_type.primitive(), std::move(region));
}
}
}
@ -391,8 +392,7 @@ namespace internal {
\return Property map that maps each iterator of the input range to a region index.
*/
const Region_map &region_map() {
const Region_map& region_map() {
return m_region_map;
}
@ -470,6 +470,7 @@ namespace internal {
Neighbor_query& m_neighbor_query;
Region_type& m_region_type;
Region_map m_region_map;
std::vector<Item> m_seed_range;
std::size_t m_nb_regions = 0;

View File

@ -123,14 +123,12 @@ namespace Segment_set {
\cgalParamDefault{1}
\cgalParamNEnd
\cgalParamNBegin{maximum_angle}
\cgalParamDescription{the maximum angle in degrees between
the direction of a segment and the direction of a line}
\cgalParamDescription{the maximum angle in degrees between the direction of a segment and the direction of a line}
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{25 degrees}
\cgalParamNEnd
\cgalParamNBegin{cosine_of_maxium_angle}
\cgalParamDescription{the cos value computed as `cos(maximum_angle * PI / 180)`,
this parameter can be used instead of the `maximum_angle`}
\cgalParamNBegin{cosine_of_maximum_angle}
\cgalParamDescription{the cosine value `cos(maximum_angle * PI / 180)` to be used instead of the parameter `maximum_angle()`}
\cgalParamType{`GeomTraits::FT`}
\cgalParamDefault{`cos(25 * PI / 180)`}
\cgalParamNEnd
@ -152,7 +150,7 @@ namespace Segment_set {
\pre `maximum_distance >= 0`
\pre `maximum_angle >= 0 && maximum_angle <= 90`
\pre `cosine_of_maxium_angle >= 0 && cosine_of_maxium_angle <= 1`
\pre `cosine_of_maximum_angle >= 0 && cosine_of_maximum_angle <= 1`
\pre `minimum_region_size > 0`
*/
template<typename NamedParameters = parameters::Default_named_parameters>
@ -182,7 +180,7 @@ namespace Segment_set {
const FT default_cos_value = static_cast<FT>(std::cos(CGAL::to_double(
(max_angle * static_cast<FT>(CGAL_PI)) / FT(180))));
const FT cos_value = parameters::choose_parameter(
parameters::get_parameter(np, internal_np::cosine_of_maxium_angle), default_cos_value);
parameters::get_parameter(np, internal_np::cosine_of_maximum_angle), default_cos_value);
CGAL_precondition(cos_value >= FT(0) && cos_value <= FT(1));
m_cos_value_threshold = cos_value;
}

View File

@ -35,7 +35,7 @@ bool test_region_growing_on_polygon_mesh(int argc, char *argv[]) {
// Default parameter values.
const FT distance_threshold = FT(1);
const FT angle_threshold = FT(45);
const std::size_t min_region_size = 5;
const std::size_t min_region_size = 1;
// Load data.
std::ifstream in(argc > 1 ? argv[1] : CGAL::data_file_path("meshes/building.off"));
@ -68,13 +68,19 @@ bool test_region_growing_on_polygon_mesh(int argc, char *argv[]) {
std::vector<typename Region_growing::Primitive_and_region> regions;
region_growing.detect(std::back_inserter(regions));
assert(regions.size() == 416);
assert(regions.size() == 1077);
for (const auto& region : regions)
assert(region_type.is_valid_region(region.second));
auto map = region_growing.region_map();
for (auto fit : face_range) {
std::size_t id = get(region_growing.region_map(), fit);
assert(id != std::size_t(-1));
}
std::vector<typename Region_growing::Item> unassigned_faces;
region_growing.unassigned_items(face_range, std::back_inserter(unassigned_faces));
assert(unassigned_faces.size() == 1006);
assert(unassigned_faces.size() == 0);
return true;
}

View File

@ -122,7 +122,7 @@ void test_copied_point_cloud (const Point_set& original_points, std::size_t nb)
RG_region rg_region (
CGAL::parameters::
maximum_distance(parameters.epsilon).
cosine_of_maxium_angle(parameters.normal_threshold).
cosine_of_maximum_angle(parameters.normal_threshold).
minimum_region_size(parameters.min_points));
Region_growing region_growing (points, rg_query, rg_region);
std::size_t nb_detected = 0;

View File

@ -358,10 +358,8 @@ private:
it = indices.begin(), end = indices.end();
it != end; ++it) {
v_hint = insert(points[*it], hint);
if(v_hint!=Vertex_handle()) {
v_hint->info()=infos[*it];
hint=v_hint->face();
}
v_hint->info()=infos[*it];
hint=v_hint->face();
}
return this->number_of_vertices() - n;