mirror of
git://projects.qi-hardware.com/cae-tools.git
synced 2025-01-03 21:10:15 +02:00
poly2d/: add triangulation (untested)
This commit is contained in:
parent
7aaaf8671f
commit
f93e93ca89
@ -1,8 +1,8 @@
|
||||
#
|
||||
# Makefile - Makefile of libpoly2d
|
||||
#
|
||||
# Written 2012 by Werner Almesberger
|
||||
# Copyright 2012 by Werner Almesberger
|
||||
# Written 2012, 2013 by Werner Almesberger
|
||||
# Copyright 2012, 2013 by Werner Almesberger
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -18,7 +18,8 @@ LIB = libpoly2d.a
|
||||
OBJS = v2d_intersect.o v2d_line_distance.o \
|
||||
p2d_area.o p2d_area_holes.o \
|
||||
p2d_attrib.o p2d_contains_point.o p2d_contains_poly.o \
|
||||
p2d_copy.o p2d_free.o p2d_gnuplot.o p2d_make.o p2d_offset.o p2d_hsort.o
|
||||
p2d_copy.o p2d_free.o p2d_gnuplot.o p2d_make.o p2d_offset.o \
|
||||
p2d_hsort.o f2d_tri_holes.o f2d_tri.o
|
||||
|
||||
CFLAGS_WARN = -Wall -Wshadow -Wmissing-prototypes \
|
||||
-Wmissing-declarations -Wno-format-zero-length
|
||||
|
42
poly2d/f2d_tri.c
Normal file
42
poly2d/f2d_tri.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* f2d_tri.c - Triangulate a set of nested polygons
|
||||
*
|
||||
* Written 2013 by Werner Almesberger
|
||||
* Copyright 2013 Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include "poly2d.h"
|
||||
#include "p2d_hsort.h"
|
||||
|
||||
|
||||
static void recurse_area(struct p2d_hier *t, struct f2d ***last)
|
||||
{
|
||||
const struct p2d *p, *h;
|
||||
|
||||
for (p = &t->p; p; p = p->next) {
|
||||
h = &p2d_to_hier(p)->holes->p;
|
||||
f2d_tri_holes_append(p, h, last);
|
||||
while (h) {
|
||||
recurse_area(p2d_to_hier(h)->holes, last);
|
||||
h = h->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct f2d *f2d_tri(const struct p2d *p)
|
||||
{
|
||||
struct p2d_hier *t;
|
||||
struct f2d *res = NULL, **last = &res;
|
||||
|
||||
t = p2d_hsort(p);
|
||||
recurse_area(t, &last);
|
||||
p2d_hier_free(t);
|
||||
return res;
|
||||
}
|
245
poly2d/f2d_tri_holes.cpp
Normal file
245
poly2d/f2d_tri_holes.cpp
Normal file
@ -0,0 +1,245 @@
|
||||
/*
|
||||
* f2d_tri_holes.cpp - Triangulate a polygon with holes
|
||||
*
|
||||
* Written 2013 by Werner Almesberger
|
||||
* Copyright 2013 by Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* References:
|
||||
* http://www.cgal.org/Manual/latest/doc_html/cgal_manual/Triangulation_2/
|
||||
* Chapter_main.html#Subsection_37.8.2
|
||||
* http://www.cgal.org/Manual/latest/examples/Triangulation_2/
|
||||
* polygon_triangulation.cpp
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "poly2d.h"
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* @@@ Prevent spurious aborts with
|
||||
*
|
||||
* terminate called after throwing an instance of 'CGAL::Precondition_exception'
|
||||
* what(): CGAL ERROR: precondition violation!
|
||||
* Expr: is_simple_2(first, last, traits)
|
||||
* File: /usr/include/CGAL/Polygon_2/Polygon_2_algorithms_impl.h
|
||||
* Line: 420
|
||||
*
|
||||
* Note that we also need to check the polygons for simplicity in recurse_area,
|
||||
* or this may still lead to assertion failures.
|
||||
*/
|
||||
|
||||
#define CGAL_POLYGON_NO_PRECONDITIONS
|
||||
#endif
|
||||
|
||||
#include "cgal_helper.h"
|
||||
|
||||
//#include <vector>
|
||||
//#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/Triangulation_face_base_with_info_2.h>
|
||||
#include <CGAL/Polygon_2.h>
|
||||
|
||||
|
||||
struct FaceInfo2 {
|
||||
FaceInfo2(){}
|
||||
int nesting_level;
|
||||
|
||||
bool in_domain(void)
|
||||
{
|
||||
return nesting_level % 2 == 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef CGAL::Triangulation_vertex_base_2<K> Vb;
|
||||
typedef CGAL::Triangulation_face_base_with_info_2<FaceInfo2, K> Fbb;
|
||||
typedef CGAL::Constrained_triangulation_face_base_2<K, Fbb> Fb;
|
||||
typedef CGAL::Triangulation_data_structure_2<Vb, Fb> TDS;
|
||||
typedef CGAL::Exact_predicates_tag Itag;
|
||||
typedef CGAL::Constrained_Delaunay_triangulation_2<K, TDS, Itag> CDT;
|
||||
typedef CDT::Point Point;
|
||||
typedef CGAL::Polygon_2<K> Polygon_2;
|
||||
|
||||
|
||||
#if 0
|
||||
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes;
|
||||
|
||||
typedef boost::shared_ptr<Polygon_with_holes> PolygonPtr;
|
||||
|
||||
typedef std::vector<PolygonPtr> PolygonPtrVector;
|
||||
|
||||
struct p2d *res = NULL, **last = &res, *np;
|
||||
|
||||
|
||||
static void append_poly(Polygon_2 poly, struct p2d ***last)
|
||||
{
|
||||
**last = P2_to_p2d(poly);
|
||||
*last = &(**last)->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* ----- Mark domains ------------------------------------------------------ */
|
||||
|
||||
|
||||
static void mark_domains(CDT &ct, CDT::Face_handle start, int index,
|
||||
std::list<CDT::Edge> &border)
|
||||
{
|
||||
std::list<CDT::Face_handle> queue;
|
||||
|
||||
if (start->info().nesting_level != -1)
|
||||
return;
|
||||
|
||||
queue.push_back(start);
|
||||
while (!queue.empty()) {
|
||||
CDT::Face_handle fh = queue.front();
|
||||
|
||||
queue.pop_front();
|
||||
if (fh->info().nesting_level == -1){
|
||||
fh->info().nesting_level = index;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
CDT::Edge e(fh, i);
|
||||
CDT::Face_handle n = fh->neighbor(i);
|
||||
if (n->info().nesting_level == -1) {
|
||||
if (ct.is_constrained(e))
|
||||
border.push_back(e);
|
||||
else
|
||||
queue.push_back(n);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void mark_domains(CDT &cdt)
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for (CDT::All_faces_iterator it = cdt.all_faces_begin();
|
||||
it != cdt.all_faces_end(); ++it)
|
||||
it->info().nesting_level = -1;
|
||||
|
||||
std::list<CDT::Edge> border;
|
||||
mark_domains(cdt, cdt.infinite_face(), index++, border);
|
||||
while(!border.empty()) {
|
||||
CDT::Edge e = border.front();
|
||||
|
||||
border.pop_front();
|
||||
CDT::Face_handle n = e.first->neighbor(e.second);
|
||||
if (n->info().nesting_level == -1)
|
||||
mark_domains(cdt, n, e.first->info().nesting_level+1,
|
||||
border);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ----- Inser polygon ----------------------------------------------------- */
|
||||
|
||||
|
||||
void insert_polygon(CDT &cdt, const Polygon_2 &polygon)
|
||||
{
|
||||
if (polygon.is_empty())
|
||||
return;
|
||||
CDT::Vertex_handle v_prev =
|
||||
cdt.insert(*CGAL::cpp0x::prev(polygon.vertices_end()));
|
||||
for (Polygon_2::Vertex_iterator vit = polygon.vertices_begin();
|
||||
vit != polygon.vertices_end(); ++vit) {
|
||||
CDT::Vertex_handle vh = cdt.insert(*vit);
|
||||
|
||||
cdt.insert_constraint(vh, v_prev);
|
||||
v_prev = vh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const struct v2d *find_point(const struct p2d *p, double x, double y)
|
||||
{
|
||||
const struct v2d *v;
|
||||
|
||||
for (v = p->v; v; v = v->next)
|
||||
if (v->x == x && v->y == y)
|
||||
break;
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
static struct f2d *make_face(CDT::Finite_faces_iterator fit,
|
||||
const struct p2d *p, const struct p2d *holes)
|
||||
{
|
||||
struct f2d *f;
|
||||
const struct p2d *h;
|
||||
int i;
|
||||
|
||||
f = alloc_type(struct f2d);
|
||||
for (i = 0; i != 3; i++) {
|
||||
Point point = fit->vertex(i)->point();
|
||||
const struct v2d *m;
|
||||
|
||||
m = find_point(p, point.x(), point.y());
|
||||
if (m) {
|
||||
f->v[i] = m;
|
||||
f->p[i] = p;
|
||||
continue;
|
||||
}
|
||||
for (h = holes; h; h = h->next) {
|
||||
m = find_point(h, point.x(), point.y());
|
||||
if (!m)
|
||||
continue;
|
||||
f->v[i] = m;
|
||||
f->p[i] = h;
|
||||
break;
|
||||
}
|
||||
assert(m);
|
||||
}
|
||||
f->next = NULL;
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
void tri_holes_append(const struct p2d *p, const struct p2d *holes,
|
||||
struct f2d ***last)
|
||||
{
|
||||
CDT cdt;
|
||||
const struct p2d *h;
|
||||
struct f2d *f;
|
||||
|
||||
insert_polygon(cdt, p2d_to_P2(p, 0));
|
||||
for (h = holes; h; h = h->next) {
|
||||
assert(p2d_is_closed(h));
|
||||
insert_polygon(cdt, p2d_to_P2(h, 0));
|
||||
}
|
||||
mark_domains(cdt);
|
||||
|
||||
for (CDT::Finite_faces_iterator fit = cdt.finite_faces_begin();
|
||||
fit != cdt.finite_faces_end(); ++fit)
|
||||
if (fit->info().in_domain()) {
|
||||
f = make_face(fit, p, holes);
|
||||
**last = f;
|
||||
*last = &f->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern "C" struct f2d *f2d_tri_holes(const struct p2d *p,
|
||||
const struct p2d *holes)
|
||||
{
|
||||
struct f2d *res = NULL, **last = &res;
|
||||
|
||||
tri_holes_append(p, holes, &last);
|
||||
return res;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* poly2d.h - The public face of the 2D Polygon library
|
||||
*
|
||||
* Written 2012 by Werner Almesberger
|
||||
* Copyright 2012 Werner Almesberger
|
||||
* Written 2012, 2013 by Werner Almesberger
|
||||
* Copyright 2012, 2013 Werner Almesberger
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -29,6 +29,12 @@ struct p2d {
|
||||
struct p2d *next;
|
||||
};
|
||||
|
||||
struct f2d {
|
||||
const struct v2d *v[3]; /* vertices forming the face */
|
||||
const struct p2d *p[3]; /* polygons vertices belong to */
|
||||
struct f2d *next;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* forall_v2d* need -std=gnu99
|
||||
@ -161,6 +167,11 @@ struct p2d *p2d_area_holes(const struct p2d *p, const struct p2d *holes,
|
||||
double first, double next);
|
||||
struct p2d *p2d_area(const struct p2d *p, double first, double next);
|
||||
|
||||
void f2d_tri_holes_append(const struct p2d *p, const struct p2d *holes,
|
||||
struct f2d ***last);
|
||||
struct f2d *f2d_tri_holes(const struct p2d *p, const struct p2d *holes);
|
||||
struct f2d *f2d_tri(const struct p2d *p);
|
||||
|
||||
struct p2d *p2d_read_gnuplot(FILE *file);
|
||||
int p2d_write_gnuplot(FILE *file, const struct p2d *p);
|
||||
int p2d_write_gnuplot_all(FILE *file, const struct p2d *p);
|
||||
|
Loading…
Reference in New Issue
Block a user