Subject: CGAL users discussion list
List archive
- 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
--
#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;
}
- [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Sebastien Loriot, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/14/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/14/2023
- Re: [cgal-discuss] Check if region contains point, Sebastien Loriot, 09/14/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/14/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/15/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/14/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Sebastien Loriot, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
- Re: [cgal-discuss] Check if region contains point, Claus Volko, 09/13/2023
Archive powered by MHonArc 2.6.19+.