I'm using the CGAL library in a a Visual Studio project.
I'm trying to create a polygon_set_2 composed of polygons with holes. I run into an exception when creating the polygon_set_2 even when just using simple polygons.
Typedefs:
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::Point_2 CGALPoint;
typedef CGAL::Polygon_2<K> CGALInnerPolygon;
typedef CGAL::Polygon_set_2<K> CGALMultiPolygon;
Problem code:
CGALInnerPolygon cgalpoly;
cgalpoly.push_back(CGALPoint(0, 0));
cgalpoly.push_back(CGALPoint(1, 1));
cgalpoly.push_back(CGALPoint(1, 0));
CGALMultiPolygon multipolygon;
multipolygon.insert(cgalpoly);
I get an exception on the insert call. Output for the exception is:
Exception thrown at 0x75112CF2 in XXX.exe: Microsoft C++ exception: CGAL::Precondition_exception at memory location 0x00191AF0
It was actually a combination of two things. First the polygon points much be counterclockwise as sloriot mentioned. To fix for this in the general case the following code was added:
if (cgalpoly.is_clockwise_oriented())
{
cgalpoly.reverse_orientation();
}
Secondly, the the Polygon_set_2 must use an exact construction kernel:
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
Related
Im trying to simplify 3d polylines using CGAL::Simplify, is a terrain so the elevation does not matter for the simplification but I need to carry them because I need them on simplified polylines. The polylines can be open or closed (polygon).
The problem occurs when I try to call PS::simplify with 3d points. I checked and it work ok with 2d points. The funny is that it accept 3d points for parameters begin and end of the polyline but do not accept for the back_inserter parameter.
Is there any version of simplify that work completely with 3d points or I´m missing something?
on the code:
PS::simplify(P1.begin(), P1.end(), CostSquare(), Stop(0.5), std::back_inserter(Result),Closed);
Templates and parametes definitions:
namespace PS = CGAL::Polyline_simplification_2;
typedef CGAL::Exact_predicates_exact_constructions_kernel Epic;
typedef CGAL::Projection_traits_xy_3<Epic> K;
typedef CGAL::Polygon_2<K> Polygon_2;
Polygon_2_2 P1;
std::deque<Point_2> Result;
typedef K::Point_2 Point_2;
Thank you
Carlos A. Rabelo
My question is similar to this one but part of the (useful) given answer isn't compatible with compiling GLSL for vulkan based on OpenGL ES ESSL 3.10.
In order to use a separate section of the push constant memory in the vertex shader and the fragment shader, the suggested solution is to use layout(offset = #) before the first member of the push constant structure.
Attempting to do this in GLSL ES 310 code leads to the error "'offset on block member': not supported with this profile: es".
Is there a supported way to declare such an offset that is compatible with es?
The only workaround I've found is to declare a bunch of dummy variables in the fragment shader. When I do so, I get validation layer errors if I don't declare the full range of the fragment shader's push constant buffer in VkPipelineLayoutCreateInfo. After fixing that, I get validation layer warnings about "vkCreatePipelineLayout() call has push constants with overlapping ranges".
Obviously I can ignore warnings, but if there's a tidier solution, then that would be much more preferable.
Simple example, this compiles successfully with VulkanSDK\1.0.13.0\Bin\glslangValidator.exe:
#version 430
#extension GL_ARB_enhanced_layouts: enable
layout(std140, push_constant) uniform PushConstants
{
layout(offset=64) mat4 matWorldViewProj;
} ubuf;
layout(location = 0) in vec4 i_Position;
void main() {
gl_Position = ubuf.matWorldViewProj * i_Position;
}
Whereas this does not:
#version 310 es
#extension GL_ARB_enhanced_layouts: enable
layout(std140, push_constant) uniform PushConstants
{
layout(offset=64) mat4 matWorldViewProj;
} ubuf;
layout(location = 0) in vec4 i_Position;
void main() {
gl_Position = ubuf.matWorldViewProj * i_Position;
}
Converting all my 310 ES shader code to 430 would solve my problem, but that wouldn't be ideal. GL_ARB_enhanced_layouts doesn't apply to 310 ES code, so my question is not about why it doesn't work, but rather, do I have any options in ES to achieve the same goal?
I would consider this an error in the GLSL compiler.
What's happening is this. There are some things which compiling GLSL for Vulkan adds to the language, as defined by KHR_vulkan_glsl. The push_constant layout, for example, is explicitly added to GLSL syntax.
However, there are certain things which it does not add to the language. Important to your use case is the ability to apply offsets to members of uniform blocks. Oh yes, KHR_vulkan_glsl uses that information when building the shader's block layout. But the grammar that allows you to say layout(offset=#) is defined by GLSL, not by KHR_vulkan_glsl.
And that grammar is not a part of any version of GLSL-ES. Nor is it provided by any ES extension I am aware of. So you can't use it.
I would say that the reference compiler should, when compiling a shader for Vulkan, either fail to compile any GLSL-ES-based version, or silently ignore any version and extension declarations, and just assume desktop GLSL 4.50.
As for what you can do about it... nothing. Short of hacking that solution into the compiler yourself, your primary solution is to write your code against versions of desktop OpenGL. Like 4.50.
If you compile SPIR-V for Vulkan there is a "VULKAN" define set in your shaders (see GL_KHR_VULKAN_glsl), so you could do something like this:
#ifdef VULKAN
layout(push_constant) uniform pushConstants {
vec4 (offset = 12) pos;
} pushConstBlock;
#else
// GLES stuff
#endif
I am having an issue that is probably due to the mismatch between the precision of a double and the infinite precision given in CGAL, but I cannot seem to solve it, and do not see anyway to set a tolerance.
I input a set of points (initially the locations are doubles).
When the points are aligned horizontally on the upper part (and only happens there) I sometimes (not always) get an issue of too many triangles (with a really small area, almost 0) being generated: see image
(*notice in the upper section, how there is a line that seems to be thicker than the rest, because there are at least 3 triangles there).
This is what I am doing in my code, I tried to set the kernel to handle the imprecision of doubles:
typedef CGAL::Simple_cartesian<double> CK;
typedef CGAL::Filtered_kernel<CK> K;
//typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef K::FT FT;
typedef K::Point_2 Point;
typedef K::Segment_2 Segment;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Triangulation_vertex_base_with_info_2<unsigned long, K> Vb2;
typedef CGAL::Triangulation_data_structure_2<Vb2,Fb> Tds2;
typedef CGAL::Delaunay_triangulation_2<K,Tds2> Delaunay;
std::vector<std::vector<long> > Geometry::delaunay(std::vector<double> xs,std::vector<double> ys){
std::vector<Point> points;
std::vector<unsigned long> indices;
points.resize(xs.size());
indices.resize(xs.size());
for(long i=0;i<xs.size();i++){
indices[i]=i;
points[i]=Point(xs[i],ys[i]);
}
std::vector<long> idAs;
std::vector<long> idBs;
Delaunay dt;
dt.insert( boost::make_zip_iterator(boost::make_tuple( points.begin(),indices.begin() )),boost::make_zip_iterator(boost::make_tuple( points.end(),indices.end() ) ) );
for(Delaunay::Finite_edges_iterator it = dt.finite_edges_begin(); it != dt.finite_edges_end(); ++it)
{
Delaunay::Edge e=*it;
long i1= e.first->vertex( (e.second+1)%3 )->info();
long i2= e.first->vertex( (e.second+2)%3 )->info();
idAs.push_back(i1);
idBs.push_back(i2);
}
std::vector<std::vector<long> > result;
result.resize(2);
result[0]=(idAs);
result[1]=(idBs);
return result;
}
I am completely new to CGAL, and this code is something that I have been able to put together after a lot of looking up in web pages in the last 2 days. So if there is something else that might be improved, please, do not hesitate to mention it, the sintaxis of CGAL is not really straightforward.
*the code works perfectly for random points, and 70% of the times even for points that are aligned, but the other 30% worries me.
THE QUESTION IS, how can I set a tolerance, so CGAL does not generate triangles on top of points that are almost almost aligned??, or is there a better kernel for this? (as you see I tried also the Exact_predicates_inexact_constructions_kernel, but it is even worst).
I'm trying to do the aggregate insertion of x-monotone polylines, but I get the following error:
terminate called after throwing an instance of 'CGAL::Precondition_exception'
what(): CGAL ERROR: precondition violation!
Expr: i != INVALID_INDEX
File: /home/vladimir/lib-cgal/include/CGAL/Arr_polycurve_basic_traits_2.h
Line: 727
And have no clue why it happens. Do I miss something? Is my input wrong? Or is it a bug? Here is a code snippet resulting in this behavior:
#include <vector>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/Arr_segment_traits_2.h>
#include <CGAL/Arr_polyline_traits_2.h>
#include <CGAL/Arrangement_2.h>
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef Kernel::Point_2 Point_2;
typedef CGAL::Arr_segment_traits_2<Kernel> Segment_traits_2;
typedef CGAL::Arr_polyline_traits_2<Segment_traits_2> Geom_traits_2;
typedef CGAL::Arrangement_2<Geom_traits_2> Arrangement_2;
int main()
{
Arrangement_2 arr;
std::vector<Geom_traits_2::X_monotone_curve_2> segments;
{
auto ctor = arr.geometry_traits()->construct_x_monotone_curve_2_object();
typedef std::vector<Point_2> Line;
std::vector<Line> lines = {
{{0,0}, {8,0}},
{{2,0}, {7,0}},
{{4,2}, {6,3}},
{{1,1}, {3,0}, {5,0}},
};
for (auto &line: lines) {
segments.push_back(ctor(line.begin(), line.end()));
}
}
insert(arr, segments.begin(), segments.end());
return 0;
}
CGAL version I'm using is 4.7, but I have tried it with 4.5.2 and the lates git version (81d638341) with the same result.
The lines are intersecting, but that should be fine as I understand. I have observed that changing {{1,1}, {3,0}, {5,0}} to {{2,1}, {3,0}, {5,0}} results in no error. And splitting {{1,1}, {3,0}, {5,0}} into two segments {{1,1}, {3,0}}, {{3,0}, {5,0}} results in no error as well.
I have also noticed another thread (link) with similar problem which was fixed, but I don't see this fix in the version 4.7. Probably it's fixed somewhere else in the code, or perhaps this fix got lost somehow.? Anyway, it looks like it's not related to my problem, but one never knows.
I was able to reproduce the problem and at first glance it looks like a bug. We are looking into it, but for now you have 2 options to work around the problem:
1. Use incremental insertion. The incremental insertion is based on a completely different algorithm.
2. Break each polyline into segments and construct an arrangement of segments instead of an arrangement of polylines. I've tested it with the minimal example that produces the problem you provided (that you, by the way for that) and it works fine.
BW, the link you mentioned is unrelated.
I'm trying to do some 3D boolean operations with CGAL. I have successfully converted my polyhedra to nef polyhedra. However, when ever I try doing a simple union, I get an assertion fail on line 286 of SM_overlayer.h:
CGAL error: assertion violation!
Expression : G.mark(v1,0)==G.mark(v2,0)&& G.mark(v1,1)==G.mark(v2,1)
File : ./CGAL/include/CGAL/Nef_S2/SM_overlayer.h
Line : 287
I tried searching the documentation for "mark". Apparently it is a template argument on the Nef_polyhedron_3" that defaults to bool. However the documentation also says it is not implemented and that you shouldn't mess with it. I am a bit confused why there is even an assertion on some unimplemented feature. I tried simply commenting out the assertion, but it simply goes on to fail at a later point.
I am using the following kernel and typedefs as it was the only example I could find that allowed doubles in the construction of the meshes.
typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel;
typedef CGAL::Nef_polyhedron_3<Kernel> Nef_polyhedron;
typedef CGAL::Polyhedron_3<Kernel> Polyhedron;
I used CGAL 4.6.3 installed with the exe installer. I have also tried the 4.7 beta and I get the same exception(at line 300 instead though).
Related github issue: https://github.com/CGAL/cgal/issues/353
EDIT: The issue turned out to be with the meshes. The meshes I were using had self intersections. Thus, even though is_valid, is_closed and is_triangular returned true, the mesh was in valid for conversion to a nef polyhedron. From CGAL 4.7. The Polygon mesh processing package has been introduced which contains this which can be used to check for self intersections.