Skip to Content.
Sympa Menu

cgal-discuss - Re: [cgal-discuss] Check if region contains point

Subject: CGAL users discussion list

List archive

Re: [cgal-discuss] Check if region contains point


Chronological Thread 
  • From: Claus Volko <>
  • To:
  • Subject: Re: [cgal-discuss] Check if region contains point
  • Date: Thu, 14 Sep 2023 11:37:23 +0200
  • Authentication-results: mail2-smtp-roc.national.inria.fr; spf=None ; spf=Pass ; spf=None
  • Ironport-data: A9a23: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 OPrk67G2+20Z7igyPPJ6z+KznO4zJLetXMaSuDM
  • Ironport-hdrordr: A9a23:HsMrva51XCfKzeR4SAPXwPHXdLJyesId70hD6qkRc20tTiX8ra qTdZsgpHrJYVoqKRMdcJW7Scq9qBDnlKKdg7NhWYtKNTOO0ACVxcNZjbcKqAeQfBEWmNQts5 uIsJITNDQzNzVHZArBjzVQ2uxP/OW6
  • Ironport-phdr: A9a23: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 x8yzAB5ZLZ1nAo=
  • Ironport-sdr: 6502d46a_6etuGZOzDvtMkgSHjGMXuGuJQFac8u7ekoOkXtMOCfTAzSK imWmOXYT+nxIVdEYejBphrUIoKkKWJPtoiQue3g==

Yes, I am doing region growing on a mesh. In the end I would like to check which region intersects with a given line (orthogonal to the xz plane).

I can send you code that is ready to be built. I've attached a file to this email.

The effect of this code should be a ply file in which all regions are black except the one that contains the given point. This last region will be red.

I've already tested the code a bit and it does seem to work, but my tests are not finished yet.

Am Do., 14. Sept. 2023 um 11:32 Uhr schrieb Sebastien Loriot <>:
It is hard to understand what you are trying to do.
If you want to get help, you should post a minimal example showing what
you want to achieve.

Yesterday I thought you were doing region growing on a point set but now
it seems to be on a mesh.

Best,

Sebastien.

On 9/14/23 08:30, Claus Volko ( via cgal-discuss
Mailing List) wrote:
> I've got it now. It is perhaps not the most elegant piece of code but it
> seems to work fine:
>
>    std::list<int> listRegions = {};
>
>    for (std::size_t i = 0; i < regions.size(); i++)
>    {
>        Region_growing::Primitive_and_region region = regions[i];
>        Line_3* l = new Line_3(Point_3(0, -1, 0), Point_3(0, +1, 0));
>        auto intersection =
> boost::get<Point_3>(&*CGAL::intersection(region.first, *l));
>
>        if (intersection && region.first.has_on(*intersection))
>        {
>            auto x11 =
> region.second.front()->halfedge()->vertex()->point().x();
>            auto z11 =
> region.second.front()->halfedge()->vertex()->point().z();
>            auto x12 =
> region.second.front()->halfedge()->next()->vertex()->point().x();
>            auto z12 =
> region.second.front()->halfedge()->next()->vertex()->point().z();
>            auto x13 =
> region.second.front()->halfedge()->next()->next()->vertex()->point().x();
>            auto z13 =
> region.second.front()->halfedge()->next()->next()->vertex()->point().z();
>            auto x1a = x11 < x12 ? x11 < x13 ? x11 : x13 : x12 < x13 ?
> x12 : x13;
>            auto z1a = z11 < z12 ? z11 < z13 ? z11 : z13 : z12 < z13 ?
> z12 : z13;
>            auto x1b = x11 > x12 ? x11 > x13 ? x11 : x13 : x12 > x13 ?
> x12 : x13;
>            auto z1b = z11 > z12 ? z11 > z13 ? z11 : z13 : z12 > z13 ?
> z12 : z13;
>
>            if (intersection->x() > x1a && intersection->x() < x1b &&
> intersection->z() > z1a && intersection->z() < z1b)
>            {
>                std::cout << "Region " << i << " has point on it : " <<
> region.first << " at " << *intersection << std::endl;
>                listRegions.push_back(i);
>            }
>        }
>    }
>
> Am Do., 14. Sept. 2023 um 07:28 Uhr schrieb Claus Volko
> < <mailto:>>:
>
>     I tried coloring the regions with intersections red. The result
>     looked strange. That's why I don't think the code I posted does its job.
>
>     Am Mi., 13. Sept. 2023 um 12:41 Uhr schrieb Claus Volko
>     < <mailto:>>:
>
>         I'm now trying this:
>
>            for (std::size_t i = 0; i < regions.size(); i++)
>            {
>                Region_growing::Primitive_and_region region = regions[i];
>                Line_3* l = new Line_3(Point_3(0, -1, 0), Point_3(0, +1, 0));
>                auto intersection =
>         boost::get<Point_3>(&*CGAL::intersection(region.first, *l));
>
>                if (intersection && region.first.has_on(*intersection))
>         std::cout << "Region has point on it: " << region.first << " at"
>         << *intersection << std::endl;
>            }
>
>         It returns fewer incidences of intersection, but I'm still not
>         sure if it does what it should.
>
>         Am Mi., 13. Sept. 2023 um 11:39 Uhr schrieb Claus Volko
>         < <mailto:>>:
>
>             I've realized the way I did it was not correct because it
>             searched for the intersection of the plane with the line,
>             which always returns a point. But I actually want to check
>             for intersection with the finite region.
>
>             However, I've not understood how region_map() would help me
>             in my endeavour. Could you perhaps point me to an example?
>
>             Thank you!
>
>             Am Mi., 13. Sept. 2023 um 11:03 Uhr schrieb Sebastien Loriot
>             < <mailto:>>:
>
>                 region_map()
>
>                 https://doc.cgal.org/latest/Shape_detection/classCGAL_1_1Shape__detection_1_1Region__growing.html#a60adecff409f4025585c64cd3bd70110 <https://doc.cgal.org/latest/Shape_detection/classCGAL_1_1Shape__detection_1_1Region__growing.html#a60adecff409f4025585c64cd3bd70110>
>
>                 Provides a property map associating indicating the
>                 region index for each
>                 input element. The key of the map depends on your
>                 instantiation. But
>                 everything should be documented in the documentation of
>                 your model.
>
>                 Best,
>
>                 Sebastien.
>
>                 On 9/13/23 09:56, Claus Volko (
>                 <mailto:> via cgal-discuss
>                 Mailing List) wrote:
>                  > OK, it seems I've found it out myself by now:
>                  >
>                  >    for (Region_growing::Primitive_and_region region :
>                 regions)
>                  >    {
>                  >        Line_3* l = new Line_3(Point_3(0, -10, 0),
>                 Point_3(0, +10, 0));
>                  >
>                  >        if (CGAL::intersection(region.first, *l))
>                  >        {
>                  >            std::cout << "Region has point on it" <<
>                 std::endl;
>                  >            break;
>                  >        }
>                  >    }
>                  >
>                  > Am Mi., 13. Sept. 2023 um 09:39 Uhr schrieb Claus Volko
>                  > < <mailto:>
>                 <mailto: <mailto:>>>:
>                  >
>                  >     OK, I've realized by now that the code I posted
>                 was not wrong but
>                  >     that what I really need is to check if a line
>                 intersects with a
>                  >     region, as I don't know the y coordinate of the
>                 point I'm looking
>                  >     for. How can that be done?
>                  >
>                  >     Am Mi., 13. Sept. 2023 um 07:04 Uhr schrieb Claus
>                 Volko
>                  >     < <mailto:>
>                 <mailto: <mailto:>>>:
>                  >
>                  >         I would like to find the region that contains
>                 a given point
>                  >         after using the region growing algorithm for
>                 shape detection. I
>                  >         tried this code but it does not seem to work:
>                  >
>                  >            for (Region_growing::Primitive_and_region
>                 region : regions)
>                  >            {
>                  >                Point_3 *point = new Point_3(0, 0, 0);
>                  >                if (region.first.has_on(*point))
>                  >                    std::cout << "Region has zero
>                 point on it" << std::endl;
>                  >            }
>                  >
>                  >         Also, if I found a region, how can I access
>                 the information
>                  >         about the boundaries of the region?
>                  >
>                  >         --
>                  >         Dipl.-Ing. Dr. Claus D. Volko, BSc
>                  > http://www.cdvolko.net/ <http://www.cdvolko.net/>
>                 <http://www.cdvolko.net/ <http://www.cdvolko.net/>>
>                  >
>                  >
>                  >
>                  >
>                  >
>                  >     --
>                  >     Dipl.-Ing. Dr. Claus D. Volko, BSc
>                  > http://www.cdvolko.net/ <http://www.cdvolko.net/>
>                 <http://www.cdvolko.net/ <http://www.cdvolko.net/>>
>                  >
>                  >
>                  >
>                  >
>                  >
>                  > --
>                  > Dipl.-Ing. Dr. Claus D. Volko, BSc
>                  > http://www.cdvolko.net/ <http://www.cdvolko.net/>
>                 <http://www.cdvolko.net/ <http://www.cdvolko.net/>>
>                  >
>                  >
>                  >
>                  >
>                  > --
>                  > You are currently subscribed to cgal-discuss.
>                  > To unsubscribe or access the archives, go to
>                  > https://sympa.inria.fr/sympa/info/cgal-discuss
>                 <https://sympa.inria.fr/sympa/info/cgal-discuss>
>                  >
>
>                 --
>                 You are currently subscribed to cgal-discuss.
>                 To unsubscribe or access the archives, go to
>                 https://sympa.inria.fr/sympa/info/cgal-discuss
>                 <https://sympa.inria.fr/sympa/info/cgal-discuss>
>
>
>
>
>             --
>             Dipl.-Ing. Dr. Claus D. Volko, BSc
>             http://www.cdvolko.net/ <http://www.cdvolko.net/>
>
>
>
>
>
>         --
>         Dipl.-Ing. Dr. Claus D. Volko, BSc
>         http://www.cdvolko.net/ <http://www.cdvolko.net/>
>
>
>
>
>
>     --
>     Dipl.-Ing. Dr. Claus D. Volko, BSc
>     http://www.cdvolko.net/ <http://www.cdvolko.net/>
>
>
>
>
>
> --
> Dipl.-Ing. Dr. Claus D. Volko, BSc
> http://www.cdvolko.net/ <http://www.cdvolko.net/>
>
>
>
>
> --
> You are currently subscribed to cgal-discuss.
> To unsubscribe or access the archives, go to
> https://sympa.inria.fr/sympa/info/cgal-discuss
>

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




--
Dipl.-Ing. Dr. Claus D. Volko, BSc
http://www.cdvolko.net/



#define USE_POLYHEDRON

#include <CGAL/Polygon_mesh_processing/clip.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Shape_detection/Region_growing/Region_growing.h>
#include <CGAL/Shape_detection/Region_growing/Polygon_mesh.h>
#include <CGAL/boost/graph/IO/polygon_mesh_io.h>
#include "include/utils.h"
#include <CGAL/Polygon_mesh_processing/IO/polygon_mesh_io.h>
#include <boost/optional/optional_io.hpp>

// Typedefs.
/*
namespace PMP = CGAL::Polygon_mesh_processing;
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef CGAL::Surface_mesh<Point> Surface_mesh;
*/

using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;
using FT = typename Kernel::FT;
using Point_3 = typename Kernel::Point_3;
using Line_3 = typename Kernel::Line_3;

#ifdef USE_POLYHEDRON
using Polygon_mesh = CGAL::Polyhedron_3<Kernel>;
#else
using Polygon_mesh = CGAL::Surface_mesh<Point_3>;
#endif

using Neighbor_query =
CGAL::Shape_detection::Polygon_mesh::One_ring_neighbor_query<Polygon_mesh>;
using Region_type =
CGAL::Shape_detection::Polygon_mesh::Least_squares_plane_fit_region<Kernel,
Polygon_mesh>;
using Sorting =
CGAL::Shape_detection::Polygon_mesh::Least_squares_plane_fit_sorting<Kernel,
Polygon_mesh, Neighbor_query>;
using Region_growing = CGAL::Shape_detection::Region_growing<Neighbor_query,
Region_type>;

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Surface_mesh<K::Point_3> Mesh;
typedef boost::graph_traits<Mesh>::vertex_descriptor
vertex_descriptor;
typedef boost::graph_traits<Mesh>::halfedge_descriptor
halfedge_descriptor;

// extract vertices which are at most k (inclusive)
// far from vertex v in the graph of edges
void extract_k_ring(Polygon_mesh::Vertex_handle v,
int k,
std::vector<Polygon_mesh::Vertex_handle>& qv)
{
std::map<Polygon_mesh::Vertex_handle, int> D;
qv.push_back(v);
D[v] = 0;
std::size_t current_index = 0;
int dist_v;
while (current_index < qv.size() && (dist_v = D[qv[current_index]]) < k)
{
v = qv[current_index++];
Polygon_mesh::Halfedge_around_vertex_circulator e(v->vertex_begin()),
e_end(e);
do {
Polygon_mesh::Vertex_handle new_v = e->opposite()->vertex();
if (D.insert(std::make_pair(new_v, dist_v + 1)).second)
qv.push_back(new_v);
} while (++e != e_end);
}
}

template<typename Polygon_mesh, typename Region>
void save_polygon_mesh_regions(
Polygon_mesh& polygon_mesh,
const Region& regions,
const std::string fullpath,
std::list<int> listRegions) {

using Color = CGAL::IO::Color;
srand(static_cast<unsigned int>(time(NULL)));

using Face_property_color = CGAL::dynamic_face_property_t<Color>;
using Face_color_map = typename boost::property_map<Polygon_mesh,
Face_property_color>::type;
Face_color_map face_color = get(Face_property_color(), polygon_mesh);

// Iterate through all regions.
std::ofstream out(fullpath);
for (std::size_t i = 0; i < regions.size(); i++)
{
Region_growing::Primitive_and_region region = regions[i];

/*
// Generate a random color.
Color color(
static_cast<unsigned char>(rand() % 256),
static_cast<unsigned char>(rand() % 256),
static_cast<unsigned char>(rand() % 256));
*/

Color color(0, 0, 0, 0);

if (std::find(listRegions.begin(), listRegions.end(), i) !=
listRegions.end())
{
color = Color(255, 0, 0, 255);
// std::cout << "Region " << i << " is red." << std::endl;
}

// Iterate through all region items.
for (const auto& item : region.second) {
put(face_color, item, color);
}
}
CGAL::IO::write_PLY(out, polygon_mesh,
CGAL::parameters::face_color_map(face_color));
}

int main(int argc, char *argv[]) {

// Load data either from a local folder or a user-provided file.
const bool is_default_input = argc > 1 ? false : true;
const std::string filename = is_default_input ?
CGAL::data_file_path("meshes/building.off") : argv[1];
std::ifstream in(filename);
CGAL::IO::set_ascii_mode(in);

Polygon_mesh polygon_mesh;
if (!CGAL::Polygon_mesh_processing::IO::read_polygon_mesh(filename,
polygon_mesh)) {
std::cerr << "ERROR: cannot read the input file!" << std::endl;
return EXIT_FAILURE;
}

for (auto f : faces(polygon_mesh))
{
auto w = CGAL::Polygon_mesh_processing::compute_face_normal(f,
polygon_mesh);
if (abs(w.y()) < .5)
{
CGAL::Euler::remove_face(f->halfedge(), polygon_mesh);
}
}

for (auto f1 : faces(polygon_mesh))
{
for (auto f2 : faces(polygon_mesh))
{
if (f1 == f2) continue;

if (f1->plane().point().y() == f2->plane().point().y())
{
auto x11 = f1->halfedge()->vertex()->point().x();
auto z11 = f1->halfedge()->vertex()->point().z();
auto x12 = f1->halfedge()->next()->vertex()->point().x();
auto z12 = f1->halfedge()->next()->vertex()->point().z();
auto x13 =
f1->halfedge()->next()->next()->vertex()->point().x();
auto z13 =
f1->halfedge()->next()->next()->vertex()->point().z();
auto x1a = x11 < x12 ? x11 < x13 ? x11 : x13 : x12 < x13 ? x12
: x13;
auto z1a = z11 < z12 ? z11 < z13 ? z11 : z13 : z12 < z13 ? z12
: z13;
auto x1b = x11 > x12 ? x11 > x13 ? x11 : x13 : x12 > x13 ? x12
: x13;
auto z1b = z11 > z12 ? z11 > z13 ? z11 : z13 : z12 > z13 ? z12
: z13;

auto x21 = f2->halfedge()->vertex()->point().x();
auto z21 = f2->halfedge()->vertex()->point().z();
auto x22 = f2->halfedge()->next()->vertex()->point().x();
auto z22 = f2->halfedge()->next()->vertex()->point().z();
auto x23 =
f2->halfedge()->next()->next()->vertex()->point().x();
auto z23 =
f2->halfedge()->next()->next()->vertex()->point().z();
auto x2a = x21 < x22 ? x21 < x23 ? x21 : x23 : x22 < x23 ? x22
: x23;
auto z2a = z21 < z22 ? z21 < z23 ? z21 : z23 : z22 < z23 ? z22
: z23;
auto x2b = x21 > x22 ? x21 > x23 ? x21 : x23 : x22 > x23 ? x22
: x23;
auto z2b = z21 > z22 ? z21 > z23 ? z21 : z23 : z22 > z23 ? z22
: z23;

if (x2a > x1a && x2b < x1b && z2a > z1a && z2b < z1b)
CGAL::Euler::remove_face(f2->halfedge(), polygon_mesh);
}
}
}

for (Polygon_mesh::Vertex_iterator v1 = polygon_mesh.vertices_begin(); v1
!= polygon_mesh.vertices_end(); v1++)
{
for (Polygon_mesh::Vertex_iterator v2 = polygon_mesh.vertices_begin();
v2 != polygon_mesh.vertices_end(); v2++)
{
if (v1 == v2) continue;
if ((abs(v1->point().x() - v2->point().x()) < .01)
&& (abs(v1->point().y() - v2->point().y()) < .01)
&& (abs(v1->point().z() - v2->point().z()) < .01))
{
//std::cout << "merging vertices " << v1->point() << " and " <<
v2->point() << std::endl;
v2->point() = v1->point();
}
}
}

std::cout << "Before stitching : " << std::endl;
std::cout << "\t Number of vertices :\t" <<
polygon_mesh.size_of_vertices() << std::endl;
std::cout << "\t Number of halfedges :\t" <<
polygon_mesh.size_of_halfedges() << std::endl;
std::cout << "\t Number of facets :\t" << polygon_mesh.size_of_facets()
<< std::endl;

CGAL::Polygon_mesh_processing::stitch_borders(polygon_mesh);

std::cout << "Stitching done : " << std::endl;
std::cout << "\t Number of vertices :\t" <<
polygon_mesh.size_of_vertices() << std::endl;
std::cout << "\t Number of halfedges :\t" <<
polygon_mesh.size_of_halfedges() << std::endl;
std::cout << "\t Number of facets :\t" << polygon_mesh.size_of_facets()
<< std::endl;


/*
std::vector<Polygon_mesh::Facet_handle> new_facets;
std::vector<Polygon_mesh::Vertex_handle> new_vertices;
CGAL::Polygon_mesh_processing::refine(polygon_mesh, faces(polygon_mesh),
std::back_inserter(new_facets),
std::back_inserter(new_vertices),
CGAL::parameters::density_control_factor(2.));

int vertexCount = 0;
for (Polygon_mesh::Vertex_iterator v = polygon_mesh.vertices_begin(); v !=
polygon_mesh.vertices_end(); v++)
{
vertexCount++;
}
std::vector<Polygon_mesh::Vertex_handle> region1;
std::vector<Polygon_mesh::Vertex_handle> region2;
int i = 0;
for (Polygon_mesh::Vertex_iterator v = polygon_mesh.vertices_begin(); v !=
polygon_mesh.vertices_end(); v++, i++)
{
if (i < vertexCount / 2)
region1.push_back(v);
else
region2.push_back(v);
}
CGAL::Polygon_mesh_processing::fair(polygon_mesh, region1);
CGAL::Polygon_mesh_processing::fair(polygon_mesh, region2);


std::cout << "Before stitching : " << std::endl;
std::cout << "\t Number of vertices :\t" <<
polygon_mesh.size_of_vertices() << std::endl;
std::cout << "\t Number of halfedges :\t" <<
polygon_mesh.size_of_halfedges() << std::endl;
std::cout << "\t Number of facets :\t" << polygon_mesh.size_of_facets()
<< std::endl;

CGAL::Polygon_mesh_processing::stitch_borders(polygon_mesh);
CGAL::Polygon_mesh_processing::stitch_borders(polygon_mesh);
CGAL::Polygon_mesh_processing::stitch_borders(polygon_mesh);
CGAL::Polygon_mesh_processing::stitch_borders(polygon_mesh);

std::cout << "Stitching done : " << std::endl;
std::cout << "\t Number of vertices :\t" <<
polygon_mesh.size_of_vertices() << std::endl;
std::cout << "\t Number of halfedges :\t" <<
polygon_mesh.size_of_halfedges() << std::endl;
std::cout << "\t Number of facets :\t" << polygon_mesh.size_of_facets()
<< std::endl;
*/

const auto& face_range = faces(polygon_mesh);
std::cout << "* number of input faces: " << face_range.size() << std::endl;
assert(!is_default_input || face_range.size() == 32245);

// Testing the usage of clip and copy_face_graph (Claus Volko)
#ifdef USE_POLYHEDRON
/*
const Kernel::Plane_3& plane = Kernel::Plane_3(CGAL::Point_3<Kernel>(0, 0,
0),
CGAL::Point_3<Kernel>(0, 1, 0),
CGAL::Point_3<Kernel>(1, 1, 0));
CGAL::Polygon_mesh_processing::clip(polygon_mesh, plane,
CGAL::parameters::default_values());

CGAL::Surface_mesh<Point_3> surface_mesh;
copy_face_graph(polygon_mesh, surface_mesh);
*/
#endif

// Default parameter values for the data file building.off.
/*
const FT max_distance = FT(1);
const FT max_angle = FT(45);
const std::size_t min_region_size = 5;
*/
const FT max_distance = FT(1);
const FT max_angle = FT(45);
const std::size_t min_region_size = 1;

// Create instances of the classes Neighbor_query and Region_type.
Neighbor_query neighbor_query(polygon_mesh);

Region_type region_type(
polygon_mesh,
CGAL::parameters::
maximum_distance(max_distance).
maximum_angle(max_angle).
minimum_region_size(min_region_size));

// Sort face indices.
Sorting sorting(
polygon_mesh, neighbor_query);
sorting.sort();

// Create an instance of the region growing class.
Region_growing region_growing(
face_range, sorting.ordered(), neighbor_query, region_type);

// Run the algorithm.
std::vector<typename Region_growing::Primitive_and_region> regions;
region_growing.detect(std::back_inserter(regions));
std::cout << "* number of found planes: " << regions.size() << std::endl;
assert(!is_default_input || regions.size() == 365);


std::list<int> listRegions = {};

for (std::size_t i = 0; i < regions.size(); i++)
{
Region_growing::Primitive_and_region region = regions[i];
Line_3* l = new Line_3(Point_3(0, -1, 0), Point_3(0, +1, 0));
auto intersection =
boost::get<Point_3>(&*CGAL::intersection(region.first, *l));

if (intersection && region.first.has_on(*intersection))
{
auto x11 = region.second.front()->halfedge()->vertex()->point().x();
auto z11 = region.second.front()->halfedge()->vertex()->point().z();
auto x12 =
region.second.front()->halfedge()->next()->vertex()->point().x();
auto z12 =
region.second.front()->halfedge()->next()->vertex()->point().z();
auto x13 =
region.second.front()->halfedge()->next()->next()->vertex()->point().x();
auto z13 =
region.second.front()->halfedge()->next()->next()->vertex()->point().z();
auto x1a = x11 < x12 ? x11 < x13 ? x11 : x13 : x12 < x13 ? x12 :
x13;
auto z1a = z11 < z12 ? z11 < z13 ? z11 : z13 : z12 < z13 ? z12 :
z13;
auto x1b = x11 > x12 ? x11 > x13 ? x11 : x13 : x12 > x13 ? x12 :
x13;
auto z1b = z11 > z12 ? z11 > z13 ? z11 : z13 : z12 > z13 ? z12 :
z13;

if (intersection->x() > x1a && intersection->x() < x1b &&
intersection->z() > z1a && intersection->z() < z1b)
{
std::cout << "Region " << i << " has point on it : " <<
region.first << " at " << *intersection << std::endl;
listRegions.push_back(i);
}
}
}


const Region_growing::Region_map& map = region_growing.region_map();

for (std::size_t i = 0; i < regions.size(); i++)
for (auto& item : regions[i].second) {
if (i != get(map, item)) {
std::cout << "Region map incorrect" << std::endl;
}
}

std::vector<typename Region_growing::Item> unassigned;
region_growing.unassigned_items(face_range, std::back_inserter(unassigned));

for (auto& item : unassigned) {
if (std::size_t(-1) != get(map, item)) {
std::cout << "Region map for unassigned incorrect" << std::endl;
}
}

// Save regions to a file.
const std::string fullpath = (argc > 2 ? argv[2] :
"planes_polygon_mesh.ply");
save_polygon_mesh_regions(polygon_mesh, regions, fullpath, listRegions);
//utils::save_polygon_mesh_regions(polygon_mesh, regions, fullpath);

return EXIT_SUCCESS;
}



Archive powered by MHonArc 2.6.19+.

Top of Page