Merge branch 'master' into PMP-smoothing-kkatrio

This commit is contained in:
Mael 2019-07-10 15:36:25 +02:00 committed by GitHub
commit 47c247ae72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
114 changed files with 1925 additions and 781 deletions

View File

@ -7,6 +7,9 @@ DO_IGNORE=FALSE
cd $1
if [ ! -f "$2/package_info/$2/dependencies" ];then
echo "No dependencies found for $2"
bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen
exit 1
fi
LIST_OF_FILES=$(git diff --name-only origin/master... |cut -d/ -f1 |uniq |sort)

View File

@ -195,7 +195,7 @@ namespace CGAL {
if(size() > 1)
return root_node()->bbox();
else
return AABB_traits().compute_bbox_object()(m_primitives.begin(),
return traits().compute_bbox_object()(m_primitives.begin(),
m_primitives.end());
}

View File

@ -408,7 +408,19 @@ public:
}
public:
static auto initialize_poly_0() {
Polynomial_2 poly_0;
return poly_0;
}
static Algebraic_curve_kernel_2& get_static_instance(){
// Useless reference to a `Polynomial_2` to force the creation
// of `CORE::MemoryPool<CORE::Bigfloat>` (and related type)
// before the static thread-local instance `ack_2_instance`.
// The issue is otherwise that the memory pool is created during
// the filling of the curves cache, and then destroyed too soon,
// before the destruction of `ack_2_instance`.
CGAL_STATIC_THREAD_LOCAL_VARIABLE(Polynomial_2, poly_0, initialize_poly_0());
CGAL_USE(poly_0);
// a default constructed ack_2 instance
CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(Algebraic_curve_kernel_2, ack_2_instance);
return ack_2_instance;

View File

@ -2534,7 +2534,7 @@ protected:
Polycurve_basic_traits_2;
/*! The polycurve traits (in case it has state). */
const Polycurve_basic_traits_2& m_poly_traits;
const Polycurve_basic_traits_2 m_poly_traits;
const Point_2& m_point;

View File

@ -385,26 +385,28 @@ bool is_valid_halfedge_graph(const Graph& g, bool verb = false)
bool valid = (1 != (num_h&1) && (2*num_e == num_h));
if(!valid)
{
verr << "number of halfedges is odd." << std::endl;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// All halfedges.
halfedges_size_type n = 0;
for(halfedge_descriptor begin : halfedges(g))
{
if(!valid)
break;
// Pointer integrity.
valid = valid && (next(begin, g) != boost::graph_traits<Graph>::null_halfedge());
valid = (next(begin, g) != boost::graph_traits<Graph>::null_halfedge());
valid = valid && (opposite(begin, g) != boost::graph_traits<Graph>::null_halfedge());
if(!valid)
{
verr << "halfedge " << n << " next / opposite halfedges are null." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// edge integrity
valid = valid && (halfedge(edge(begin, g), g) == begin);
valid = (halfedge(edge(begin, g), g) == begin);
// opposite integrity.
valid = valid && (opposite(begin, g) != begin);
@ -412,57 +414,64 @@ bool is_valid_halfedge_graph(const Graph& g, bool verb = false)
if(!valid)
{
verr << "halfedge " << n << " invalid halfedge opposite()." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// previous integrity.
valid = valid && (prev(next(begin, g), g) == begin);
valid = (prev(next(begin, g), g) == begin);
valid = valid && (next(prev(begin, g), g) == begin);
if(!valid)
{
verr << "halfedge " << n << " prev(next(hd)) != hd OR next(prev(hd)) != hd" << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// vertex integrity.
valid = valid && (target(begin, g) != boost::graph_traits<Graph>::null_vertex());
valid = (target(begin, g) != boost::graph_traits<Graph>::null_vertex());
if(!valid)
{
verr << "halfedge " << n << " target of halfedge is the null vertex." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
valid = valid && (target(begin, g) == target(opposite(next(begin, g), g), g));
valid = (target(begin, g) == target(opposite(next(begin, g), g), g));
if(!valid)
{
verr << "halfedge " << n << " target(hd) != source(next(hd))." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
++n;
}
if(valid && n != num_h)
valid = (n == num_h);
if(!valid)
{
verr << "counting halfedges failed." << std::endl;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// All vertices.
vertex_size_type v = 0;
n = 0;
for(vertex_descriptor vbegin : vertices(g))
{
if(!valid)
break;
// Pointer integrity.
if(halfedge(vbegin, g) != boost::graph_traits<Graph>::null_halfedge())
valid = valid && (target(halfedge(vbegin, g), g) == vbegin);
valid = (target(halfedge(vbegin, g), g) == vbegin);
else
valid = false;
if(!valid)
{
verr << "vertex " << v << " halfedge incident to vertex is the null halfedge." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// cycle-around-vertex test.
@ -474,49 +483,56 @@ bool is_valid_halfedge_graph(const Graph& g, bool verb = false)
{
++n;
h = opposite(next(h, g), g);
valid = valid && (n <= num_h && n!=0);
valid = (n <= num_h && n != 0);
if(!valid)
{
verr << "vertex " << v << " too many halfedges around vertex." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
}
while (valid && (h != ge));
while(h != ge);
}
if(!valid)
break;
++v;
}
if(valid && v != num_v)
valid = (v == num_v);
if(!valid)
{
verr << "counting vertices failed." << std::endl;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
if(valid && (n != num_h))
valid = (n == num_h);
if(!valid)
{
verr << "counting halfedges via vertices failed." << std::endl;
valid = valid && (v == num_v);
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
// All halfedges.
n = 0;
for(halfedge_descriptor i : halfedges(g))
{
// At least triangular facets and distinct geometry.
valid = valid && (next(i, g) != i);
valid = valid && (target(i, g) != target(opposite(i, g), g));
valid = (next(i, g) != i) && (target(i, g) != target(opposite(i, g), g));
if(!valid)
{
verr << "halfedge " << n << " pointer validity corrupted." << std::endl;
break;
verr << "Halfedge Graph Structure is NOT VALID." << std::endl;
return false;
}
++n;
}
valid = valid && (n == num_h);
if(n != num_h)
valid = (n == num_h);
if(!valid)
verr << "counting halfedges failed." << std::endl;
verr << "Halfedge Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
return valid;
@ -546,36 +562,35 @@ bool is_valid_face_graph(const Graph& g, bool verb = false)
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
typedef typename boost::graph_traits<Graph>::faces_size_type faces_size_type;
Verbose_ostream verr(verb);
std::size_t num_f(std::distance(boost::begin(faces(g)), boost::end(faces(g)))),
num_h(std::distance(boost::begin(halfedges(g)), boost::end(halfedges(g))));
faces_size_type f = 0;
std::size_t n = 0;
std::size_t hn = 0;
halfedges_size_type nb = 0;
//is valid halfedge_graph ?
bool valid = is_valid_halfedge_graph(g, verb);
if(!valid)
return false;
Verbose_ostream verr(verb);
// All faces.
faces_size_type f = 0;
std::size_t n = 0;
halfedges_size_type nb = 0;
for(face_descriptor fbegin : faces(g))
{
if(!valid)
break;
// Pointer integrity.
if(halfedge(fbegin, g) != boost::graph_traits<Graph>::null_halfedge())
valid = valid && (face(halfedge(fbegin, g), g) == fbegin);
valid = (face(halfedge(fbegin, g), g) == fbegin);
else
valid = false;
if(!valid)
{
verr << "face " << f << " halfedge incident to face is the null halfedge." << std::endl;
break;
verr << "Face Graph Structure is NOT VALID." << std::endl;
return false;
}
// cycle-around-face test.
@ -587,26 +602,28 @@ bool is_valid_face_graph(const Graph& g, bool verb = false)
{
++n;
h = next(h, g);
valid = valid && (n <= num_h && n != 0);
valid = (n <= num_h && n != 0);
if(!valid)
{
verr << "face " << f << " too many halfedges around face." << std::endl;
break;
verr << "Face Graph Structure is NOT VALID." << std::endl;
return false;
}
}
while(valid && (h != ge));
while(h != ge);
}
if(! valid)
break;
++f;
}
if(valid && f != num_f)
valid = (f == num_f);
if(!valid)
{
verr << "counting faces failed." << std::endl;
verr << "Face Graph Structure is NOT VALID." << std::endl;
return false;
}
std::size_t hn = 0;
for(halfedge_descriptor i : halfedges(g))
{
++hn;
@ -616,20 +633,28 @@ bool is_valid_face_graph(const Graph& g, bool verb = false)
++nb;
// face integrity.
valid = valid && (face(i, g) == face(next(i, g), g));
valid = (face(i, g) == face(next(i, g), g));
if(!valid)
{
verr << "halfedge " << hn << " face(hd) != face(next(hd))." << std::endl;
break;
verr << "Face Graph Structure is NOT VALID." << std::endl;
return false;
}
}
valid = (n + nb == num_h);
if(!valid)
{
verr << "sum border halfedges (2*nb) = " << 2 * nb << std::endl;
if(valid && n + nb != num_h)
verr << "counting halfedges via faces failed." << std::endl;
verr << "Face Graph Structure is NOT VALID." << std::endl;
return false;
}
valid = (f == num_f);
if(!valid)
verr << "counting faces failed." << std::endl;
valid = valid && (f == num_f);
valid = valid && (n + nb == num_h);
verr << "Face Graph Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
return valid;
@ -667,26 +692,27 @@ bool is_valid_polygon_mesh(const Mesh& g, bool verb = false)
// Distinct facets on each side of an halfedge.
for(halfedge_descriptor i : halfedges(g))
{
valid = valid && (face(i, g) != face(opposite(i, g), g));
valid = (face(i, g) != face(opposite(i, g), g));
if(!valid)
{
verr << "both incident facets are equal." << std::endl;
break;
verr << "Polygon Mesh Structure is NOT VALID." << std::endl;
return false;
}
valid = valid && (next(next(i, g), g) != i);
valid = (next(next(i, g), g) != i);
valid = valid && (target(i, g) != target(next(i, g), g));
valid = valid && (target(i, g) != target(next(next(i, g), g), g));
if(!valid)
{
verr << "incident facet is not at least a triangle." << std::endl;
break;
verr << "Polygon Mesh Structure is NOT VALID." << std::endl;
return false;
}
}
verr << "Polygon Mesh Structure is " << (valid ? "valid." : "NOT VALID.") << std::endl;
return valid;
verr << "Polygon Mesh Structure is valid." << std::endl;
return true;
}
/*!

View File

@ -46,15 +46,14 @@ MA 02110-1301, USA. */
#include <string>
#include <cstdio>
using namespace std;
namespace CORE {
CGAL_INLINE_FUNCTION
int
__gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
__gmp_istream_set_base (std::istream &i, char &c, bool &zero, bool &showbase)
{
int base;
using std::ios;
zero = showbase = false;
switch (i.flags() & ios::basefield)
@ -96,7 +95,7 @@ __gmp_istream_set_base (istream &i, char &c, bool &zero, bool &showbase)
CGAL_INLINE_FUNCTION
void
__gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
__gmp_istream_set_digits (std::string &s, std::istream &i, char &c, bool &ok, int base)
{
switch (base)
{
@ -131,13 +130,14 @@ __gmp_istream_set_digits (string &s, istream &i, char &c, bool &ok, int base)
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpz_ptr z)
io_read (istream &i, mpz_ptr z)
std::istream &
//operator>> (std::istream &i, mpz_ptr z)
io_read (std::istream &i, mpz_ptr z)
{
using namespace std;
int base;
char c = 0;
string s;
std::string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
@ -175,13 +175,14 @@ io_read (istream &i, mpz_ptr z)
}
CGAL_INLINE_FUNCTION
istream &
//operator>> (istream &i, mpq_ptr q)
io_read (istream &i, mpq_ptr q)
std::istream &
//operator>> (std::istream &i, mpq_ptr q)
io_read (std::istream &i, mpq_ptr q)
{
using namespace std;
int base;
char c = 0;
string s;
std::string s;
bool ok = false, zero, showbase;
i.get(c); // start reading
@ -253,9 +254,9 @@ io_read (istream &i, mpq_ptr q)
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpz_srcptr z)
io_write (ostream &o, mpz_srcptr z)
std::ostream&
//operator<< (std::ostream &o, mpz_srcptr z)
io_write (std::ostream &o, mpz_srcptr z)
{
char *str = new char [mpz_sizeinbase(z,10) + 2];
str = mpz_get_str(str, 10, z);
@ -265,9 +266,9 @@ io_write (ostream &o, mpz_srcptr z)
}
CGAL_INLINE_FUNCTION
ostream&
//operator<< (ostream &o, mpq_srcptr q)
io_write (ostream &o, mpq_srcptr q)
std::ostream&
//operator<< (std::ostream &o, mpq_srcptr q)
io_write (std::ostream &o, mpq_srcptr q)
{
// size according to GMP documentation
char *str = new char [mpz_sizeinbase(mpq_numref(q), 10) +

View File

@ -38,7 +38,7 @@
#include <CGAL/config.h>
#include <CGAL/tss.h>
#include <boost/config.hpp>
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC)
#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100
// Force the use of Boost.Thread with g++ and C++11, because of the PR66944
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66944
// See also CGAL PR #1888
@ -84,6 +84,10 @@ public:
::operator delete(blocks[i]);
}
}
// un-commenting the following line can help reproduce on Linux the
// assertion !blocks.empty() that is sometimes triggered with MSVC
// or AppleClang
// blocks.clear();
}
@ -92,10 +96,14 @@ public:
// Access the corresponding static global allocator.
static MemoryPool<T,nObjects>& global_allocator() {
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC)
#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100
if(memPool_ptr.get() == nullptr) {memPool_ptr.reset(new Self());}
Self& memPool = * memPool_ptr.get();
#endif
#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation
static thread_local Self memPool;
#else // not CGAL_HAS_THREADS
static Self memPool;
#endif // not CGAL_HAS_THREADS
return memPool;
}
@ -103,25 +111,15 @@ private:
Thunk* head; // next available block in the pool
std::vector<void*> blocks;
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC)
#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100
static boost::thread_specific_ptr<Self> memPool_ptr;
#elif defined(CGAL_HAS_THREADS) // use the C++11 implementation
static thread_local Self memPool;
#else // not CGAL_HAS_THREADS
static Self memPool;
#endif // not CGAL_HAS_THREADS
};
#if CGAL_STATIC_THREAD_LOCAL_USE_BOOST || (defined(CGAL_HAS_THREADS) && BOOST_GCC)
#if defined(CGAL_HAS_THREADS) && defined(BOOST_GCC) && BOOST_GCC < 90100
template <class T, int nObjects >
boost::thread_specific_ptr<MemoryPool<T, nObjects> >
MemoryPool<T, nObjects>::memPool_ptr;
#else // use C++11 or without CGAL_HAS_THREADS
template <class T, int nObjects >
# ifdef CGAL_HAS_THREADS
thread_local
# endif
MemoryPool<T, nObjects> MemoryPool<T, nObjects>::memPool;
#endif
template< class T, int nObjects >

View File

@ -65,7 +65,6 @@
#include <CGAL/tss.h>
namespace CORE {
using namespace std;
class Expr;
// ==================================================
// Typedefs
@ -117,25 +116,25 @@ public:
Polynomial(const Polynomial &);
Polynomial(const VecNT &);
Polynomial(int n, const char* s[]);
Polynomial(const string & s, char myX='x');
Polynomial(const std::string & s, char myX='x');
Polynomial(const char* s, char myX='x');
~Polynomial();
private:
void constructX(int n, Polynomial<NT>& P);
void constructFromString(string & s, char myX='x');
void constructFromString(std::string & s, char myX='x');
int getnumber(const char* c, int i, unsigned int len, Polynomial<NT> & P);
bool isint(char c);
int getint(const char* c, int i, unsigned int len, int & n);
int matchparen(const char* cstr, int start);
int getbasicterm(string & s, Polynomial<NT> & P);
int getterm(string & s, Polynomial<NT> & P);
int getbasicterm(std::string & s, Polynomial<NT> & P);
int getterm(std::string & s, Polynomial<NT> & P);
public:
//Returns a Polynomial corresponding to s, which is supposed to
//contain as place-holders the chars 'x' and 'y'.
Polynomial<NT> getpoly(string & s);
Polynomial<NT> getpoly(std::string & s);
// Assignment:
Polynomial & operator=(const Polynomial&);

View File

@ -131,21 +131,21 @@ Polynomial<NT>::Polynomial(int n, const char * s[]) {
// want to generalize this to BigFloat, etc.
//
template <class NT>
Polynomial<NT>::Polynomial(const string & s, char myX) {
string ss(s);
Polynomial<NT>::Polynomial(const std::string & s, char myX) {
std::string ss(s);
constructFromString(ss, myX);
}
template <class NT>
Polynomial<NT>::Polynomial(const char * s, char myX) {
string ss(s);
std::string ss(s);
constructFromString(ss, myX);
}
template <class NT>
void Polynomial<NT>::constructFromString(string & s, char myX) {
void Polynomial<NT>::constructFromString(std::string & s, char myX) {
if(myX != 'x' || myX != 'X'){
//Replace myX with 'x'.
string::size_type loc = s.find(myX, 0);
while(loc != string::npos){
std::string::size_type loc = s.find(myX, 0);
while(loc != std::string::npos){
s.replace(loc,1,1,'x');
loc = s.find(myX, loc+1);
}
@ -241,7 +241,7 @@ int Polynomial<NT>::matchparen(const char* cstr, int start){
template <class NT>
int Polynomial<NT>::getbasicterm(string & s, Polynomial<NT> & P){
int Polynomial<NT>::getbasicterm(std::string & s, Polynomial<NT> & P){
const char * cstr = s.c_str();
unsigned int len = s.length();
int i=0;
@ -254,7 +254,7 @@ int Polynomial<NT>::getbasicterm(string & s, Polynomial<NT> & P){
}else if(cstr[i] =='('){
int oldi = i;
i = matchparen(cstr, i);
string t = s.substr(oldi+1, i -oldi -1);
std::string t = s.substr(oldi+1, i -oldi -1);
P = getpoly(t);
}else{
#ifdef CGAL_CORE_TRACE
@ -272,7 +272,7 @@ int Polynomial<NT>::getbasicterm(string & s, Polynomial<NT> & P){
template <class NT>
int Polynomial<NT>::getterm(string & s, Polynomial<NT> & P){
int Polynomial<NT>::getterm(std::string & s, Polynomial<NT> & P){
unsigned int len = s.length();
if(len == 0){// Zero Polynomial
P=Polynomial<NT>();
@ -280,7 +280,7 @@ int Polynomial<NT>::getterm(string & s, Polynomial<NT> & P){
}
unsigned int ind, oind;
const char* cstr =s.c_str();
string t;
std::string t;
//P will be used to accumulate the product of basic terms.
ind = getbasicterm(s, P);
while(ind != len-1 && cstr[ind + 1]!='+' && cstr[ind + 1]!='-' ){
@ -304,11 +304,11 @@ int Polynomial<NT>::getterm(string & s, Polynomial<NT> & P){
}
template <class NT>
Polynomial<NT> Polynomial<NT>::getpoly(string & s){
Polynomial<NT> Polynomial<NT>::getpoly(std::string & s){
//Remove white spaces from the string
string::size_type cnt=s.find(' ',0);
while(cnt != string::npos){
std::string::size_type cnt=s.find(' ',0);
while(cnt != std::string::npos){
s.erase(cnt, 1);
cnt = s.find(' ', cnt);
}
@ -321,10 +321,10 @@ Polynomial<NT> Polynomial<NT>::getpoly(string & s){
//To handle the case when there is one '=' sign
//Suppose s is of the form s1 = s2. Then we assign s to
//s1 + (-1)(s2) and reset len
string::size_type loc;
if((loc=s.find('=',0)) != string::npos){
std::string::size_type loc;
if((loc=s.find('=',0)) != std::string::npos){
s.replace(loc,1,1,'+');
string s3 = "(-1)(";
std::string s3 = "(-1)(";
s.insert(loc+1, s3);
len = s.length();
s.insert(len, 1, ')');
@ -332,7 +332,7 @@ Polynomial<NT> Polynomial<NT>::getpoly(string & s){
len = s.length();
const char *cstr = s.c_str();
string t;
std::string t;
Polynomial<NT> P;
// P will be the polynomial in which we accumulate the
//sum and difference of the different terms.
@ -966,7 +966,7 @@ BigInt Polynomial<NT>::UpperBound() const {
lhsNeg.makeCeilExact();
/* compute B^{deg} */
if (rhs <= max(lhsPos,lhsNeg)) {
if (rhs <= (std::max)(lhsPos,lhsNeg)) {
B <<= 1;
rhs *= (BigInt(1)<<deg);
} else

View File

@ -155,6 +155,10 @@ public:
double vy() const { return image_ptr->vy; }
double vz() const { return image_ptr->vz; }
double tx() const { return image_ptr->tx; }
double ty() const { return image_ptr->ty; }
double tz() const { return image_ptr->tz; }
float value(const std::size_t i,
const std::size_t j,
const std::size_t k) const

View File

@ -69,6 +69,28 @@ public:
std::shared_ptr<std::vector<std::size_t> > neighbors;
/// \endcond
/// \cond SKIP_IN_MANUAL
class Point_idx_to_point_unary_function
{
public:
typedef std::size_t argument_type;
typedef typename ItemMap::reference result_type;
typedef boost::readable_property_map_tag category;
const ItemRange* m_range;
ItemMap m_item_map;
Point_idx_to_point_unary_function (const ItemRange* range, ItemMap item_map)
: m_range (range), m_item_map (item_map)
{ }
result_type operator() (const argument_type& arg) const
{
return get (m_item_map, *(m_range->begin() + arg));
}
};
/// \endcond
private:
const ItemRange* m_range;
ItemMap m_item_map;
@ -139,14 +161,12 @@ public:
*/
const CGAL::Bbox_3& bbox() const
{
auto transform = [&](const std::size_t& idx) -> typename ItemMap::reference
{
return get (m_item_map, *(m_range->begin() + idx));
};
if (m_bounding_box == CGAL::Bbox_3())
{
Point_idx_to_point_unary_function transform (m_range, m_item_map);
m_bounding_box = CGAL::bbox_3 (boost::make_transform_iterator (m_inliers->begin(), transform),
boost::make_transform_iterator (m_inliers->end(), transform));
}
return m_bounding_box;
}

View File

@ -295,7 +295,7 @@ We next list the libraries and essential 3rd party software
| Library | CMake Variable | Functionality | Dependencies |
| :-------- | :------------- | :------------ | :----------- |
| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers), Boost.Thread and Boost.System (library) for compilers not supporting the keywords `thread_local` and the class `std::mutex` |
| `%CGAL` | none | Main library | \sc{Gmp}, \sc{Mpfr}, \sc{Boost} (headers) |
| `CGAL_Core` | `WITH_CGAL_Core` | The CORE library for algebraic numbers.\cgalFootnote{CGAL_Core is not part of \cgal, but a custom version of the \sc{Core} library distributed by \cgal for the user convenience and it has it's own license.} | \sc{Gmp} and \sc{Mpfr} |
| `CGAL_ImageIO` | `WITH_CGAL_ImageIO` | Utilities to read and write image files | \sc{zlib}, \sc{Vtk}(optional) |
| `CGAL_Qt5` | `WITH_CGAL_Qt5` | `QGraphicsView` support for \sc{Qt}5-based demos | \sc{Qt}5 |
@ -388,27 +388,16 @@ The \sc{Boost} libraries are a set of portable C++ source libraries. Most of
\sc{Boost} libraries are header-only, but a few of them need to be compiled or
installed as binaries.
\cgal requires the \sc{Boost} libraries. In particular the header files
and the threading library (`Boost.Thread` and
`Boost.System` binaries). Version 1.48 (or higher) are needed
for compilers not supporting the keyword `thread_local` and the class `std::mutex` (This is supported for \gcc 4.8 and later when using the \cpp 11 standard, and for Visual C++ starting with 2015, that is VC14).
\cgal only requires the headers of the \sc{Boost} libraries, but some demos and examples depend on the binary library `Boost.Program_options`.
As an exception, because of a bug in the \gcc compiler about the \cpp 11
keyword `thread_local`, the `CGAL_Core` library always requires
`Boost.Thread` if the \gcc compiler is used.
On Windows, as auto-linking is used, you also need the binaries of
`Boost.Serialization` and `Boost.DateTime`, but the
dependency is artificial and used only at link-time: the \cgal libraries do
not depend on the DLL's of those two libraries.
In \cgal some demos and examples depend on `Boost.Program_options`.
the binary library `Boost.Thread` if the \gcc compiler version 9.0 or
earlier is used.
In case the \sc{Boost} libraries are not installed on your system already, you
can obtain them from <A HREF="https://www.boost.org/">`https://www.boost.org/`</A>. For Visual C++ you can download precompiled libraries
from <A HREF="https://sourceforge.net/projects/boost/files/boost-binaries/">`https://sourceforge.net/projects/boost/files/boost-binaries/`</A>.
For Visual C++ versions prior to 2015 `Boost.Thread` is required, so make sure to either install the precompiled
libraries for your compiler or build `libboost-thread` and `libboost-system`.
As on Windows there is no canonical directory for where to find
\sc{Boost}, we recommend that you define the environment variable

View File

@ -35,7 +35,7 @@
#include <vector>
#include <cstdlib>
#include <queue>
#include <boost/unordered_map.hpp>
#include <map>
namespace CGAL
{
@ -161,6 +161,9 @@ public:
m_flat_normal_buffer(flat_normal),
m_gouraud_normal_buffer(gouraud_normal),
m_bb(bbox),
m_zero_x(true),
m_zero_y(true),
m_zero_z(true),
m_face_started(false)
{}
@ -171,6 +174,10 @@ public:
if (m_index_buffer!=nullptr) { m_index_buffer->clear(); }
if (m_flat_normal_buffer!=nullptr) { m_flat_normal_buffer->clear(); }
if (m_gouraud_normal_buffer!=nullptr) { m_gouraud_normal_buffer->clear(); }
m_zero_x=true;
m_zero_y=true;
m_zero_z=true;
}
bool is_empty() const
@ -198,6 +205,15 @@ public:
bool has_gouraud_normal() const
{ return m_gouraud_normal_buffer!=nullptr; }
bool has_zero_x() const
{ return m_zero_x; }
bool has_zero_y() const
{ return m_zero_y; }
bool has_zero_z() const
{ return m_zero_z; }
// 1.1) Add a point, without color. Return the index of the added point.
template<typename KPoint>
std::size_t add_point(const KPoint& kp)
@ -210,6 +226,10 @@ public:
if (m_bb!=nullptr)
{ (*m_bb)=(*m_bb)+p.bbox(); }
if (m_zero_x && p.x()!=0) { m_zero_x=false; }
if (m_zero_y && p.y()!=0) { m_zero_y=false; }
if (m_zero_z && p.z()!=0) { m_zero_z=false; }
return m_pos_buffer->size()-3;
}
@ -605,8 +625,23 @@ protected:
{
P_traits cdt_traits(normal);
CDT cdt(cdt_traits);
bool with_vertex_normal=(m_vertex_normals_for_face.size()==m_points_of_face.size());
Local_point p1, p2;
// For each point of the face, store the list of adjacent points and the number of time
// the edge is found in the face. For an edge p1, p2, store edge min(p1,p2)->max(p1,p2)
std::map<Local_point, std::map<Local_point, unsigned int> > edges;
for (unsigned int i=0; i<m_points_of_face.size(); ++i)
{
p1=m_points_of_face[i];
p2=m_points_of_face[i==0?m_points_of_face.size()-1:i-1];
if (p2<p1) { std::swap(p1, p2); }
if (edges.count(p1)==0)
{ std::map<Local_point, unsigned int> m; m[p2]=1; edges[p1]=m; }
else if (edges[p1].count(p2)==0) { edges[p1][p2]=1; }
else { ++(edges[p1][p2]); }
}
// (1) We insert all the edges as contraint in the CDT.
typename CDT::Vertex_handle previous=nullptr, first=nullptr;
@ -625,12 +660,22 @@ protected:
{ vh->info().index=m_indices_of_points_of_face[i]; }
if(previous!=nullptr && previous!=vh)
{
p1=m_points_of_face[i]; p2=m_points_of_face[i-1];
if (p2<p1) { std::swap(p1, p2); }
if ((edges[p1][p2])%2==1) // odd number of time => constraint
{ cdt.insert_constraint(previous, vh); }
}
previous=vh;
}
if (previous!=nullptr && previous!=first)
{
p1=m_points_of_face[m_points_of_face.size()-1]; p2=m_points_of_face[0];
if (p2<p1) std::swap(p1, p2);
if ((edges[p1][p2])%2==1) // odd number of time => constraint
{ cdt.insert_constraint(previous, first); }
}
// (2) We mark all external triangles
// (2.1) We initialize is_external and is_process values
@ -783,6 +828,10 @@ protected:
CGAL::Bbox_3* m_bb;
bool m_zero_x; /// True iff all points have x==0
bool m_zero_y; /// True iff all points have y==0
bool m_zero_z; /// True iff all points have z==0
// Local variables, used when we started a new face.
bool m_face_started;
bool m_started_face_is_colored;

View File

@ -55,6 +55,7 @@
#include <CGAL/Buffer_for_vao.h>
#include <CGAL/Qt/CreateOpenGLContext.h>
#include <CGAL/Qt/constraint.h>
#include <CGAL/Random.h>
namespace CGAL
@ -253,6 +254,39 @@ public:
const CGAL::Bbox_3& bounding_box() const
{ return m_bounding_box; }
bool has_zero_x() const
{
return
m_buffer_for_mono_points.has_zero_x() &&
m_buffer_for_colored_points.has_zero_x() &&
m_buffer_for_mono_segments.has_zero_x() &&
m_buffer_for_colored_segments.has_zero_x() &&
m_buffer_for_mono_faces.has_zero_x() &&
m_buffer_for_colored_faces.has_zero_x();
}
bool has_zero_y() const
{
return
m_buffer_for_mono_points.has_zero_y() &&
m_buffer_for_colored_points.has_zero_y() &&
m_buffer_for_mono_segments.has_zero_y() &&
m_buffer_for_colored_segments.has_zero_y() &&
m_buffer_for_mono_faces.has_zero_y() &&
m_buffer_for_colored_faces.has_zero_y();
}
bool has_zero_z() const
{
return
m_buffer_for_mono_points.has_zero_z() &&
m_buffer_for_colored_points.has_zero_z() &&
m_buffer_for_mono_segments.has_zero_z() &&
m_buffer_for_colored_segments.has_zero_z() &&
m_buffer_for_mono_faces.has_zero_z() &&
m_buffer_for_colored_faces.has_zero_z();
}
template<typename KPoint>
void add_point(const KPoint& p)
{ m_buffer_for_mono_points.add_point(p); }
@ -732,6 +766,23 @@ protected:
rendering_program_face.release();
}
if (!is_empty() && (has_zero_x() || has_zero_y() || has_zero_z()))
{
camera()->setType(CGAL::qglviewer::Camera::ORTHOGRAPHIC);
// Camera Constraint:
constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS);
constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
double cx=0., cy=0., cz=0.;
if (has_zero_x()) { cx=1.; }
else if (has_zero_y()) { cy=1.; }
else { cz=1.; }
camera()->setViewDirection(CGAL::qglviewer::Vec(-cx,-cy,-cz));
constraint.setRotationConstraintDirection(CGAL::qglviewer::Vec(cx, cy, cz));
camera()->frame()->setConstraint(&constraint);
}
}
virtual void redraw()
@ -1001,6 +1052,9 @@ protected:
bool m_are_buffers_initialized;
CGAL::Bbox_3 m_bounding_box;
// CGAL::qglviewer::LocalConstraint constraint;
CGAL::qglviewer::WorldConstraint constraint;
// The following enum gives the indices of different elements of arrays vectors.
enum
{
@ -1062,32 +1116,10 @@ protected:
namespace CGAL
{
template<class T, class ColorFunctor>
void draw(const T&, const char*, bool, const ColorFunctor&)
{
std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined."
<<std::endl;
}
template<class T>
void draw(const T&, const char*, bool)
void draw(const T&, const char* ="", bool=false)
{
std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined."
<<std::endl;
}
template<class T>
void draw(const T&, const char*)
{
std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined."
<<std::endl;
}
template<class T>
void draw(const T&)
{
std::cerr<<"Impossible to draw because CGAL_USE_BASIC_VIEWER is not defined."
<<std::endl;
std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."<<std::endl;
}
} // End namespace CGAL

View File

@ -40,6 +40,13 @@ Release date: September 2019
for optional parameters is now removed (it was deprecated since
CGAL 4.12). The current (and now only) API uses ranges and Named
Parameters.
- Added the possibility to use the named parameter
`neighbor_radius` to use spherical neighbor queries instead of
K-nearest neighbors queries for the following functions:
`CGAL::bilateral_smooth_point_set()`,
`CGAL::jet_estimate_normals()`, `CGAL::jet_smooth_point_set()`,
`CGAL::mst_orient_normals()`, `CGAL::pca_estimate_normals()` and
`CGAL::remove_outliers()`.
### Polygon Mesh Processing
- Added the function `CGAL::Polygon_mesh_processing::centroid()`, which computes

View File

@ -31,7 +31,6 @@ CGAL packages, some are only needed for demos.
* Boost (>= 1.48)
Required for building CGAL and for applications using CGAL
Required compiled Boost library: Boost.Thread, Boost.System
Optional compiled Boost library: Boost.Program_options
http://www.boost.org/ or http://www.boostpro.com/products/free/
You need the former if you plan to compile the boost libraries yourself,

View File

@ -12,6 +12,9 @@ get_filename_component(CGAL_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(CGAL_HEADER_ONLY "@CGAL_HEADER_ONLY@" )
include(CMakeFindDependencyMacro)
find_dependency(Boost REQUIRED)
# The code for including exported targets is different from
# CGAL_Config_install.cmake. We do not have separate export files in
# an installed version and we need to make sure that we are not
@ -114,15 +117,6 @@ macro(check_cgal_component COMPONENT)
if ( "${CGAL_LIB}" STREQUAL "CGAL" )
set( CGAL_FOUND TRUE )
set( CHECK_CGAL_ERROR_TAIL "" )
get_property(CGAL_CGAL_is_imported TARGET CGAL::CGAL PROPERTY IMPORTED)
if(CGAL_CGAL_is_imported)
include("${CGAL_MODULES_DIR}/CGAL_SetupBoost.cmake")
get_property(CGAL_requires_Boost_libs
GLOBAL PROPERTY CGAL_requires_Boost_Thread)
if(CGAL_requires_Boost_libs AND TARGET Boost::thread)
set_property(TARGET CGAL::CGAL APPEND PROPERTY INTERFACE_LINK_LIBRARIES Boost::thread)
endif()
endif()
else( "${CGAL_LIB}" STREQUAL "CGAL" )
if ( WITH_${CGAL_LIB} )
if(TARGET CGAL::${CGAL_LIB})

View File

@ -12,6 +12,9 @@ get_filename_component(CGAL_CONFIG_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(CGAL_HEADER_ONLY "@CGAL_HEADER_ONLY@" )
include(CMakeFindDependencyMacro)
find_dependency(Boost REQUIRED)
# CGAL_DIR is the directory where this CGALConfig.cmake is installed
string(REPLACE "/@CGAL_INSTALL_CMAKE_DIR@" "" CGAL_INSTALL_PREFIX "${CGAL_CONFIG_DIR}")

View File

@ -290,13 +290,6 @@ if( NOT CGAL_MACROS_FILE_INCLUDED )
# To deal with imported targets of Qt5 and Boost, when CGAL
# targets are themselves imported by another project.
if(NOT CGAL_BUILDING_LIBS)
if (NOT MSVC AND "${component}" STREQUAL "Core")
# See the release notes of CGAL-4.10: CGAL_Core now requires
# Boost.Thread, with all compilers but MSVC.
find_package( Boost 1.48 REQUIRED thread system )
add_to_list( CGAL_3RD_PARTY_LIBRARIES ${Boost_LIBRARIES} )
endif()
if (${component} STREQUAL "Qt5")
find_package(Qt5 COMPONENTS OpenGL Gui Core Script ScriptTools QUIET)
endif()

View File

@ -17,38 +17,7 @@ set ( CGAL_Boost_Setup TRUE )
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake)
function(CGAL_detect_if_Boost_Thread_is_required)
get_property(PROPERTY_CGAL_requires_Boost_Thread_IS_SET
GLOBAL PROPERTY CGAL_requires_Boost_Thread SET)
if(PROPERTY_CGAL_requires_Boost_Thread_IS_SET)
get_property(CGAL_requires_Boost_libs
GLOBAL PROPERTY CGAL_requires_Boost_Thread)
else()
set ( CGAL_requires_Boost_libs TRUE )
if ( DEFINED MSVC_VERSION AND "${MSVC_VERSION}" GREATER 1800)
set ( CGAL_requires_Boost_libs FALSE )
else()
try_run( CGAL_test_cpp_version_RUN_RES CGAL_test_cpp_version_COMPILE_RES
"${CMAKE_BINARY_DIR}"
"${CGAL_MODULES_DIR}/config/support/CGAL_test_cpp_version.cpp"
RUN_OUTPUT_VARIABLE CGAL_cplusplus)
message(STATUS "__cplusplus is ${CGAL_cplusplus}")
if(NOT CGAL_test_cpp_version_RUN_RES)
set ( CGAL_requires_Boost_libs FALSE )
message(STATUS " --> Do not link with Boost.Thread")
endif()
endif()
endif()
set_property(GLOBAL PROPERTY CGAL_requires_Boost_Thread ${CGAL_requires_Boost_libs})
set(CGAL_requires_Boost_libs ${CGAL_requires_Boost_libs} PARENT_SCOPE)
endfunction(CGAL_detect_if_Boost_Thread_is_required)
CGAL_detect_if_Boost_Thread_is_required()
if (CGAL_requires_Boost_libs)
find_package( Boost 1.48 REQUIRED thread system )
else()
find_package( Boost 1.48 REQUIRED )
endif()
if(Boost_FOUND AND Boost_VERSION VERSION_LESS 1.70)
if(DEFINED Boost_DIR AND NOT Boost_DIR)
@ -94,9 +63,6 @@ function(use_CGAL_Boost_support target)
endif()
if(TARGET Boost::boost)
target_link_libraries(${target} ${keyword} Boost::boost)
if (CGAL_requires_Boost_libs)
target_link_libraries(${target} ${keyword} Boost::thread)
endif()
else()
target_include_directories(${target} SYSTEM ${keyword} ${Boost_INCLUDE_DIRS})
target_link_libraries(${target} ${keyword} ${Boost_LIBRARIES})

View File

@ -54,8 +54,8 @@ endif()
#
# See the release notes of CGAL-4.10: CGAL_Core now requires
# Boost.Thread, with GNU G++.
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
# Boost.Thread, with GNU G++ < 9.1.
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
include(${CMAKE_CURRENT_LIST_DIR}/CGAL_TweakFindBoost.cmake)
find_package( Boost 1.48 REQUIRED COMPONENTS thread system )
endif()
@ -73,7 +73,7 @@ function(CGAL_setup_CGAL_Core_dependencies target)
# See the release notes of CGAL-4.10: CGAL_Core now requires
# Boost.Thread, with GNU G++.
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU)
if (CMAKE_CXX_COMPILER_ID STREQUAL GNU AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1)
if(TARGET Boost::thread)
target_link_libraries( CGAL_Core ${keyword} Boost::thread)
else()

View File

@ -98,8 +98,25 @@ function(cgal_add_compilation_test exe_name)
COMMAND ${TIME_COMMAND} "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target "${exe_name}")
set_property(TEST "compilation_of__${exe_name}"
APPEND PROPERTY LABELS "${PROJECT_NAME}")
if(NOT TARGET cgal_check_build_system)
add_custom_target(cgal_check_build_system)
endif()
if(NOT TEST check_build_system)
add_test(NAME "check_build_system"
COMMAND "${CMAKE_COMMAND}" --build "${CMAKE_BINARY_DIR}" --target "cgal_check_build_system")
if(POLICY CMP0066) # cmake 3.7 or later
set_property(TEST "check_build_system"
PROPERTY FIXTURES_SETUP "check_build_system_SetupFixture")
endif()
endif()
if(POLICY CMP0066) # cmake 3.7 or later
set_property(TEST "compilation_of__${exe_name}"
APPEND PROPERTY FIXTURES_REQUIRED "check_build_system_SetupFixture")
endif()
endfunction(cgal_add_compilation_test)
option(CGAL_TEST_DRAW_FUNCTIONS "If set, the ctest command will not skip the tests of the draw functions.")
function(cgal_setup_test_properties test_name)
if(ARGC GREATER 1)
set(exe_name ${ARGV1})
@ -109,6 +126,11 @@ function(cgal_setup_test_properties test_name)
# message(STATUS " working dir: ${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TEST "${test_name}"
PROPERTY WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
if(NOT CGAL_TEST_DRAW_FUNCTIONS)
set_property(TEST "${test_name}"
APPEND PROPERTY ENVIRONMENT CGAL_TEST_SUITE=1)
endif()
if(exe_name)
set_property(TEST "${test_name}"
APPEND PROPERTY DEPENDS "compilation_of__${exe_name}")

View File

@ -22,46 +22,6 @@
#include <CGAL/config.h>
#if defined( CGAL_HAS_THREADS )
# ifdef CGAL_CAN_USE_CXX11_THREAD_LOCAL
//# pragma message ( "Use keyword thread_local" )
# else
//# pragma message ("Use thread_local from boost")
# define CGAL_USE_BOOST_THREAD
# include <boost/thread/tss.hpp>
# endif
# ifdef CGAL_USE_BOOST_THREAD
# define CGAL_STATIC_THREAD_LOCAL_USE_BOOST 1
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE());} \
TYPE& VAR = * VAR##_ptr.get()
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE(TYPE, VAR, ARG1) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1));} \
TYPE& VAR = * VAR##_ptr.get()
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_2(TYPE, VAR, ARG1, ARG2) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2));} \
TYPE& VAR = * VAR##_ptr.get()
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_3(TYPE, VAR, ARG1, ARG2, ARG3) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2,ARG3));} \
TYPE& VAR = * VAR##_ptr.get()
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_4(TYPE, VAR, ARG1, ARG2, ARG3, ARG4) \
static boost::thread_specific_ptr<TYPE> VAR##_ptr; \
if(VAR##_ptr.get() == nullptr) {VAR##_ptr.reset(new TYPE(ARG1,ARG2,ARG3,ARG4));} \
TYPE& VAR = * VAR##_ptr.get()
# else // not CGAL_USE_BOOST_THREAD, -> use C++11 thread_local
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) \
static thread_local TYPE VAR
@ -78,8 +38,6 @@
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_4(TYPE, VAR, ARG1, ARG2, ARG3, ARG4) \
static thread_local TYPE VAR(ARG1,ARG2,ARG3,ARG4)
# endif // not CGAL_USE_BOOST_THREAD
#else // not CGAL_HAS_THREADS
# define CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(TYPE, VAR) static TYPE VAR

View File

@ -58,7 +58,7 @@ void test();
int
main()
{
CGAL::force_ieee_double_precision();
CGAL::Set_ieee_double_precision double_precision_guard;
typedef CGAL::Cartesian<double> Clsdb;
typedef CGAL::Filtered_kernel<Clsdb> Clsd;

View File

@ -36,9 +36,6 @@ _test_cls_tetrahedron_3(const R& )
typedef typename R::RT RT;
typedef typename R::FT FT;
typename R::Tetrahedron_3 it;
CGAL::Tetrahedron_3<R> t0(it);
RT n0 = 0;
RT n1 = 12;
RT n2 = 16;
@ -60,6 +57,10 @@ _test_cls_tetrahedron_3(const R& )
CGAL::Point_3<R> ps1( n7, n0, n0, n5); // (3, 0, 0)
CGAL::Point_3<R> ps0( CGAL::ORIGIN ); // (0, 0, 0)
typename R::Tetrahedron_3 it0; // check the default-constructor
typename R::Tetrahedron_3 it(p1,p2,p3,p4);
CGAL::Tetrahedron_3<R> t0(it);
const CGAL::Tetrahedron_3<R> t1(p1,p2,p3,p4);
CGAL::Tetrahedron_3<R> t2(p2,p1,p3,p4);
CGAL::Tetrahedron_3<R> t3(ps0,ps1,ps2,ps3); // positive oriented

View File

@ -36,9 +36,6 @@ _test_cls_triangle_3(const R& )
typedef typename R::RT RT;
typedef typename R::FT FT;
typename R::Triangle_3 it;
CGAL::Triangle_3<R> t0(it);
RT n0 = 0;
RT n1 = 12;
RT n2 = 16;
@ -61,7 +58,10 @@ _test_cls_triangle_3(const R& )
CGAL::Point_3<R> ps2( n0, n7, n0, n5); // (0, 3, 0)
CGAL::Point_3<R> ps1( n7, n0, n0, n5); // (3, 0, 0)
typename R::Triangle_3 it; // test default-constructor
const CGAL::Triangle_3<R> t1(p1,p2,p3);
CGAL::Triangle_3<R> t0(t1);
CGAL::Triangle_3<R> t2(p4,p2,p3);
CGAL::Triangle_3<R> t3(ps1,ps2,ps3);
CGAL::Triangle_3<R> t4(ps2,ps1,ps3);

View File

@ -221,8 +221,8 @@ test_new_3(const R& rep)
typename R::Construct_tetrahedron_3 construct_tetrahedron
= rep.construct_tetrahedron_3_object();
Tetrahedron_3 th1;
Tetrahedron_3 th2 = construct_tetrahedron(p2,p3,p4,p5);
Tetrahedron_3 th0; // test default-constructor
Tetrahedron_3 th2 = construct_tetrahedron(p2,p3,p4,p5), th1 = th2;
typename R::Construct_iso_cuboid_3 construct_iso_cuboid
= rep.construct_iso_cuboid_3_object();

View File

@ -3,7 +3,7 @@ namespace CGAL {
/*!
\ingroup PkgDrawLinearCellComplex
Open a new window and draw `alcc`, a model of the `LinearCellComplex` concept. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
opens a new window and draws `alcc`, a model of the `LinearCellComplex` concept. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\tparam LCC a model of the `LinearCellComplex` concept.
\param alcc the linear cell complex to draw.

View File

@ -253,7 +253,7 @@ We can observe that the second run is faster than the first one. Indeed, updatin
\subsection Linear_cell_complexDraw Draw a Linear Cell Complex
\anchor ssecDrawLCC
A linear cell complex can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given linear cell complex. The function is blocking, that is the program continues as soon as the user closes the window.
A linear cell complex can be visualized by calling the \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink function as shown in the following example. This function opens a new window showing the given linear cell complex. A call to this function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Linear_cell_complex/draw_linear_cell_complex.cpp}

View File

@ -19,7 +19,7 @@
/// \defgroup PkgLinearCellComplexOperations Operations for Linear Cell Complex
/// \ingroup PkgLinearCellComplexRef
/*! Draw.
/*!
\code
#include <CGAL/draw_linear_cell_complex.h>
\endcode
@ -75,7 +75,7 @@
- `CGAL::compute_normal_of_cell_2<LCC>`
\cgalCRPSubsection{Draw a Linear Cell Complex}
- `CGAL::draw<LCC>`
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
*/

View File

@ -25,6 +25,7 @@
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Linear_cell_complex_base.h>
#include <CGAL/Random.h>
namespace CGAL
@ -372,16 +373,26 @@ protected:
const DrawingFunctorLCC& m_drawing_functor;
};
template<class LCC, class DrawingFunctorLCC>
void draw(const LCC& alcc,
const char* title,
bool nofill,
const DrawingFunctorLCC& drawing_functor)
// Specialization of draw function.
#define CGAL_LCC_TYPE CGAL::Linear_cell_complex_base \
<d_, ambient_dim, Traits_, Items_, Alloc_, Map, Refs, Storage_>
template < unsigned int d_, unsigned int ambient_dim,
class Traits_,
class Items_,
class Alloc_,
template<unsigned int,class,class,class,class>
class Map,
class Refs,
class Storage_>
void draw(const CGAL_LCC_TYPE& alcc,
const char* title="LCC for CMap Basic Viewer",
bool nofill=false)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
@ -389,30 +400,16 @@ void draw(const LCC& alcc,
int argc=1;
const char* argv[2]={"lccviewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleLCCViewerQt<LCC, DrawingFunctorLCC> mainwindow(app.activeWindow(),
&alcc,
title,
nofill,
drawing_functor);
DefaultDrawingFunctorLCC fcolor;
SimpleLCCViewerQt<CGAL_LCC_TYPE, DefaultDrawingFunctorLCC>
mainwindow(app.activeWindow(), &alcc, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
template<class LCC>
void draw(const LCC& alcc, const char* title, bool nofill)
{
DefaultDrawingFunctorLCC f;
draw(alcc, title, nofill, f);
}
template<class LCC>
void draw(const LCC& alcc, const char* title)
{ draw(alcc, title, false); }
template<class LCC>
void draw(const LCC& alcc)
{ draw(alcc, "Basic LCC Viewer"); }
// Todo a function taking a const DrawingFunctorLCC& drawing_functor as parameter
#undef CGAL_LCC_TYPE
} // End namespace CGAL

View File

@ -52,13 +52,16 @@ if ( CGAL_FOUND )
include( ${EIGEN3_USE_FILE} )
endif()
set(VTK_LIBS "")
find_package(VTK QUIET COMPONENTS vtkImagingGeneral vtkIOImage NO_MODULE)
if(VTK_FOUND)
if(VTK_USE_FILE)
include(${VTK_USE_FILE})
if ("${VTK_VERSION_MAJOR}" GREATER "5")
endif()
if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5)
message(STATUS "VTK found")
set( VTK_LIBS vtkImagingGeneral vtkIOImage )
if(TARGET VTK::IOImage)
set(VTK_LIBRARIES VTK::ImagingGeneral VTK::IOImage)
endif()
else()
message(STATUS "VTK version 6.0 or greater is required")
endif()
@ -87,9 +90,10 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "mesh_polyhedral_complex.cpp" )
create_single_source_cgal_program( "mesh_polyhedral_complex_sm.cpp" )
if( WITH_CGAL_ImageIO )
if( VTK_FOUND AND "${VTK_VERSION_MAJOR}" GREATER "5" )
if( VTK_FOUND AND ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5) )
add_executable ( mesh_3D_gray_vtk_image mesh_3D_gray_vtk_image.cpp )
target_link_libraries( mesh_3D_gray_vtk_image ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${VTK_LIBS})
target_link_libraries( mesh_3D_gray_vtk_image ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES} ${VTK_LIBRARIES})
cgal_add_test( mesh_3D_gray_vtk_image )
endif()
create_single_source_cgal_program( "mesh_3D_gray_image.cpp" )

View File

@ -283,7 +283,7 @@ typedef boost::variant<const std::vector<double>*, const std::vector<uint8_t>*,
template <class C3T3>
void output_to_vtu_with_attributes(std::ostream& os,
const C3T3& c3t3,
std::vector<std::pair<const char*, const Vtu_attributes> >&attributes,
std::vector<std::pair<const char*, Vtu_attributes> >&attributes,
IO::Mode mode = IO::BINARY)
{
//CGAL_assertion(attributes.size() == attribute_types.size());
@ -372,7 +372,7 @@ void output_to_vtu(std::ostream& os,
mids.push_back(v);
}
std::vector<std::pair<const char*, const Vtu_attributes > > atts;
std::vector<std::pair<const char*, Vtu_attributes > > atts;
Vtu_attributes v = &mids;
atts.push_back(std::make_pair("MeshDomain", v));
output_to_vtu_with_attributes(os, c3t3, atts, mode);

View File

@ -109,12 +109,12 @@ private:
/// Returns a box enclosing image \c im
Bbox_3 compute_bounding_box(const Image& im) const
{
return Bbox_3(-im.vx(),
-im.vy(),
-im.vz(),
double(im.xdim()+1)*im.vx(),
double(im.ydim()+1)*im.vy(),
double(im.zdim()+1)*im.vz());
return Bbox_3(-im.vx()+im.tx(),
-im.vy()+im.ty(),
-im.vz()+im.tz(),
double(im.xdim()+1)*im.vx()+im.tx(),
double(im.ydim()+1)*im.vy()+im.ty(),
double(im.zdim()+1)*im.vz()+im.tz());
}
}; // end class Labeled_image_mesh_domain_3

View File

@ -88,10 +88,10 @@ namespace internal {
/// Returns a box enclosing image \c im
inline Bbox_3 compute_bounding_box(const Image_3& im)
{
return Bbox_3(-1,-1,-1,
double(im.xdim())*im.vx()+1,
double(im.ydim())*im.vy()+1,
double(im.zdim())*im.vz()+1);
return Bbox_3(-1+im.tx(),-1+im.ty(),-1+im.tz(),
double(im.xdim())*im.vx()+im.tx()+1,
double(im.ydim())*im.vy()+im.ty()+1,
double(im.zdim())*im.vz()+im.tz()+1);
}
template <typename Image_values_to_subdom_indices>

View File

@ -41,13 +41,6 @@ struct Get_io_signature<std::pair<int, int> > {
}
}; // end Get_io_signature<std::pair<int, int> >
inline std::ostream& operator<<(std::ostream& out, const std::pair<int, int>& id) {
return out << id.first << " " << id.second;
}
inline std::istream& operator>>(std::istream& in, std::pair<int, int>& id) {
return in >> id.first >> id.second;
}
template <>
class Output_rep<std::pair<int, int> > : public IO_rep_is_specialized {
typedef std::pair<int, int> T;

View File

@ -59,15 +59,8 @@ private:
Word _wrd;
static const Matrix& gmap(const std::string& s)
{
typedef std::map<std::string, Matrix> M;
CGAL_STATIC_THREAD_LOCAL_VARIABLE_0(M, m);
if(m.empty()){
static auto initialize_gmap() {
std::map<std::string, Matrix> m;
std::vector<Matrix> g;
Matrix::generators(g);
@ -128,7 +121,30 @@ private:
m["7"] = g[D];
m["72"] = g[D]*g[C];
m["725"] = g[D]*g[C]*g[B];
{ // This block abuses `operator<<` of numbers, to a null stream.
// That ensures that the following memory pool are correctly
// initialized:
// - `CORE::MemoryPool<CORE::Realbase_for<long, 1024>`
// - `CORE::MemoryPool<CORE::Realbase_for<double, 1024>`
// - `CORE::MemoryPool<CORE::BigFloatRep, 1024>`
// - `CORE::MemoryPool<CORE::BigIntRep, 1024>`
// otherwise, there is an assertion during the destruction of
// static (or `thread_local`) objects
struct NullBuffer : public std::streambuf {
int overflow(int c) { return c; }
};
NullBuffer null_buffer;
std::ostream null_stream(&null_buffer);
for(auto& pair: m) null_stream << pair.second;
}
return m;
}
static const Matrix& gmap(const std::string& s)
{
typedef std::map<std::string, Matrix> M;
CGAL_STATIC_THREAD_LOCAL_VARIABLE(M, m, initialize_gmap());
return m[s];
}

View File

@ -1,6 +1,16 @@
/// \defgroup PkgPointSet3Ref 3D Point Set Reference
/*!
\code
#include <CGAL/draw_point_set_3.h>
\endcode
*/
/// \defgroup PkgDrawPointSet3D Draw a 3D Point Set
/// \ingroup PkgPointSet3Ref
/*!
\addtogroup PkgPointSet3Ref
\cgalPkgDescriptionBegin{3D Point Set, PkgPointSet3}
\cgalPkgPicture{point_set_3.png}
\cgalPkgSummaryBegin
@ -21,6 +31,9 @@
\cgalCRPSection{Class}
- `CGAL::Point_set_3<Point,Vector>`
\cgalCRPSection{Draw a 3D Point Set}
- \link PkgDrawPointSet3D CGAL::draw<PS>() \endlink
\defgroup PkgPointSet3IO Input/Output
\ingroup PkgPointSet3Ref

View File

@ -163,6 +163,18 @@ overload provided for `CGAL::Point_set_3`:
\cgalExample{Point_set_3/point_set_advanced.cpp}
\subsection Point_set_3_Draw Draw a Point Set
A 3D point set can be visualized by calling the \link PkgDrawPointSet3D CGAL::draw<PS>() \endlink function as shown in the following example. This function opens a new window showing the given point set. A call to this function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Point_set_3/draw_point_set_3.cpp}
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\cgalFigureBegin{fig_draw_point_set,draw_point_set.png}
Result of the run of the draw_point_set_3 program. A window shows the 3D points and allows to navigate through the 3D scene.
\cgalFigureEnd
\section Point_set_3_History History
This package has been created to fill the need for a practical data

View File

@ -5,4 +5,5 @@
\example Point_set_3/point_set_read_xyz.cpp
\example Point_set_3/point_set_read_ply.cpp
\example Point_set_3/point_set_advanced.cpp
\example Point_set_3/draw_point_set_3.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -7,7 +7,7 @@ project( Point_set_3_Examples )
# CGAL and its components
find_package( CGAL QUIET COMPONENTS )
find_package( CGAL QUIET COMPONENTS Qt5 )
if ( NOT CGAL_FOUND )
@ -16,6 +16,10 @@ if ( NOT CGAL_FOUND )
endif()
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
# Boost and its components
find_package( Boost REQUIRED )
@ -50,5 +54,7 @@ else()
create_single_source_cgal_program( "point_set_algo.cpp" )
endif()
create_single_source_cgal_program("draw_point_set_3.cpp" )
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_point_set_3 PUBLIC CGAL::CGAL_Qt5)
endif()

View File

@ -0,0 +1,29 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Point_set_3.h>
#include <CGAL/Point_set_3/IO.h>
#include <CGAL/draw_point_set_3.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::FT FT;
typedef Kernel::Point_3 Point;
typedef Kernel::Vector_3 Vector;
typedef CGAL::Point_set_3<Point> Point_set;
int main (int argc, char** argv)
{
std::ifstream f (argc > 1 ? argv[1] : "data/oni.xyz");
Point_set point_set;
// Reading input in XYZ format
if (!f || !CGAL::read_xyz_point_set (f, point_set))
{
std::cerr<<"Can't read input file "
<<(argc > 1 ? argv[1] : "data/oni.xyz")<< std::endl;
return EXIT_FAILURE;
}
CGAL::draw(point_set);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,127 @@
// Copyright (c) 2016 GeometryFactory Sarl (France).
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// 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 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_POINT_SET_3_H
#define CGAL_DRAW_POINT_SET_3_H
#include <CGAL/license/Point_set_3.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*!
\ingroup PkgDrawPointSet3D
opens a new window and draws `aps`, an instance of the `CGAL::Point_set_3` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\tparam PS an instance of the `CGAL::Point_set_3` class.
\param aps the point set to draw.
*/
template<class PS>
void draw(const PS& aps);
} /* namespace CGAL */
#endif
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Point_set_3.h>
#include <CGAL/Random.h>
namespace CGAL
{
// Viewer class for Point_set
template<class PointSet>
class SimplePointSetViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename PointSet::Point_map::value_type Point;
public:
/// Construct the viewer.
/// @param apointset the point set to view
/// @param title the title of the window
SimplePointSetViewerQt(QWidget* parent,
const PointSet& apointset, const char* title="") :
// First draw: vertices; no-edge, no-face; mono-color; no inverse normal
Base(parent, title, true, false, false, true, false),
pointset(apointset)
{
compute_elements();
}
protected:
void compute_vertex(const Point& p)
{
add_point(p);
// We can use add_point(p, c) with c a CGAL::Color to add a colored point
}
void compute_elements()
{
clear();
for (typename PointSet::const_iterator it=pointset.begin();
it!=pointset.end(); ++it)
{ compute_vertex(pointset.point(*it)); }
}
virtual void keyPressEvent(QKeyEvent *e)
{
// const ::Qt::KeyboardModifiers modifiers = e->modifiers();
Base::keyPressEvent(e);
}
protected:
const PointSet& pointset;
};
// Specialization of draw function.
template<class P, class V>
void draw(const Point_set_3<P, V>& apointset,
const char* title="Point_set_3 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"point_set_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePointSetViewerQt<Point_set_3<P, V> > mainwindow(app.activeWindow(),
apointset,
title);
mainwindow.show();
app.exec();
}
}
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POINT_SET_3_H

View File

@ -1,5 +1,6 @@
Algebraic_foundations
BGL
GraphicsView
Installation
Interval_support
Kernel_23

View File

@ -4,7 +4,6 @@ PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 2D Polygons"
EXAMPLE_PATH = ${CGAL_PACKAGE_DIR}/examples \
${CGAL_Stream_support_EXAMPLE_DIR}
EXTRACT_ALL = false
HIDE_UNDOC_MEMBERS = true
HIDE_UNDOC_CLASSES = true

View File

@ -6,6 +6,22 @@
/// \defgroup PkgPolygon2Functions Global Functions
/// \ingroup PkgPolygon2Ref
/*!
\code
#include <CGAL/draw_polygon_2.h>
\endcode
*/
/// \defgroup PkgDrawPolygon2 Draw a 2D Polygon
/// \ingroup PkgPolygon2Ref
/*!
\code
#include <CGAL/draw_polygon_with_holes_2.h>
\endcode
*/
/// \defgroup PkgDrawPolygonWithHoles2 Draw a 2D Polygon with Holes
/// \ingroup PkgPolygon2Ref
/*!
\addtogroup PkgPolygon2Ref
@ -53,5 +69,11 @@ The assertion flags for the polygons and polygon operations use
- `CGAL::right_vertex_2()`
- `CGAL::top_vertex_2()`
\cgalCRPSection{Draw a Polygon_2}
- \link PkgDrawPolygon2 CGAL::draw<P>() \endlink
\cgalCRPSection{Draw a Polygon_with_holes_2}
- \link PkgDrawPolygonWithHoles2 CGAL::draw<PH>() \endlink
*/

View File

@ -70,6 +70,18 @@ and 3D Linear Geometric %Kernel.
\cgalExample{Polygon/projected_polygon.cpp}
\subsection subsecPolygonDraw Draw a Polygon
A polygon can be visualized by calling the \link PkgDrawPolygon2 CGAL::draw<P>() \endlink function as shown in the following example. This function opens a new window showing the given polygon. A call to this function is blocking, that is the program continues as soon as the user closes the window (a version exists for polygon with holes, cf. \link PkgDrawPolygonWithHoles2 CGAL::draw<PH>() \endlink).
\cgalExample{Polygon/draw_polygon.cpp}
This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\cgalFigureBegin{fig_draw_polygon,draw_polygon.png}
Result of the run of the draw_polygon program. A window shows the polygon and allows to navigate through the scene.
\cgalFigureEnd
*/
\section secPolygonWithHole Polygons with Holes

View File

@ -4,4 +4,6 @@
\example Polygon/Polygon.cpp
\example Polygon/projected_polygon.cpp
\example Stream_support/Polygon_WKT.cpp
\example Polygon/draw_polygon.cpp
\example Polygon/draw_polygon_with_holes.cpp
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -6,7 +6,11 @@ cmake_minimum_required(VERSION 3.1...3.15)
project( Polygon_Examples )
find_package(CGAL QUIET)
find_package(CGAL QUIET COMPONENTS Qt5)
if(CGAL_Qt5_FOUND)
add_definitions(-DCGAL_USE_BASIC_VIEWER -DQT_NO_KEYWORDS)
endif()
if ( CGAL_FOUND )
@ -16,6 +20,11 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "${cppfile}" )
endforeach()
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_polygon PUBLIC CGAL::CGAL_Qt5)
target_link_libraries(draw_polygon_with_holes PUBLIC CGAL::CGAL_Qt5)
endif()
else()
message(STATUS "This program requires the CGAL library, and will not be compiled.")

View File

@ -0,0 +1,22 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_2.h>
#include <CGAL/draw_polygon_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Point_2<K> Point;
int main()
{
// create a polygon and put some points in it
Polygon_2 p;
p.push_back(Point(0,0));
p.push_back(Point(4,0));
p.push_back(Point(4,4));
p.push_back(Point(2,2));
p.push_back(Point(0,4));
CGAL::draw(p);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,37 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/draw_polygon_with_holes_2.h>
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Polygon_with_holes_2<K> Polygon_with_holes_2;
typedef CGAL::Polygon_2<K> Polygon_2;
typedef CGAL::Point_2<K> Point;
int main()
{
// create a polygon with three holes
Polygon_2 outer_polygon;
outer_polygon.push_back(Point(0,0)); outer_polygon.push_back(Point(9,0));
outer_polygon.push_back(Point(6,8)); outer_polygon.push_back(Point(5,3));
outer_polygon.push_back(Point(2,8)); outer_polygon.push_back(Point(0,8));
std::vector<Polygon_2> holes(3);
holes[0].push_back(Point(6,2)); holes[0].push_back(Point(7,1));
holes[0].push_back(Point(7,3)); holes[0].push_back(Point(6,3));
holes[0].push_back(Point(5,2));
holes[1].push_back(Point(2,1)); holes[1].push_back(Point(3,1));
holes[1].push_back(Point(3,3)); holes[1].push_back(Point(2,2));
holes[1].push_back(Point(1,2));
holes[2].push_back(Point(1,4)); holes[2].push_back(Point(2,4));
holes[2].push_back(Point(2,5)); holes[2].push_back(Point(3,5));
holes[2].push_back(Point(3,6)); holes[2].push_back(Point(1,6));
Polygon_with_holes_2 p(outer_polygon, holes.begin(), holes.end());
// And draw it.
CGAL::draw(p);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,148 @@
// Copyright (c) 1997
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_POLYGON_2_H
#define CGAL_DRAW_POLYGON_2_H
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*!
\ingroup PkgDrawPolygon2
opens a new window and draws `ap`, an instance of the `CGAL::Polygon_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\tparam P an instance of the `CGAL::Polygon_2` class.
\param ap the polygon to draw.
*/
template<class P>
void draw(const P& ap);
} /* namespace CGAL */
#endif
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Polygon_2.h>
#include <CGAL/Random.h>
namespace CGAL
{
// Viewer class for Polygon_2
template<class P2>
class SimplePolygon2ViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename P2::Point_2 Point;
public:
/// Construct the viewer.
/// @param ap2 the polygon to view
/// @param title the title of the window
SimplePolygon2ViewerQt(QWidget* parent, const P2& ap2,
const char* title="Basic Polygon_2 Viewer") :
// First draw: vertices; edges, faces; multi-color; no inverse normal
Base(parent, title, true, true, true, false, false),
p2(ap2)
{
compute_elements();
}
protected:
void compute_elements()
{
clear();
if (p2.is_empty()) return;
Point prev=p2.vertex(p2.size()-1);
CGAL::Color c(75,160,255);
face_begin(c);
for (typename P2::Vertex_const_iterator i=p2.vertices_begin();
i!=p2.vertices_end(); ++i)
{
add_point(*i); // Add vertex
add_segment(prev, *i); // Add segment with previous point
add_point_in_face(*i); // Add point in face
prev=*i;
}
face_end();
}
virtual void keyPressEvent(QKeyEvent *e)
{
// Test key pressed:
// const ::Qt::KeyboardModifiers modifiers = e->modifiers();
// if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... }
// Call: * compute_elements() if the model changed, followed by
// * redraw() if some viewing parameters changed that implies some
// modifications of the buffers
// (eg. type of normal, color/mono)
// * update() just to update the drawing
// Call the base method to process others/classicals key
Base::keyPressEvent(e);
}
protected:
const P2& p2;
};
// Specialization of draw function.
template<class T, class C>
void draw(const CGAL::Polygon_2<T, C>& ap2,
const char* title="Polygon_2 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"t2_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolygon2ViewerQt<CGAL::Polygon_2<T, C> >
mainwindow(app.activeWindow(), ap2, title);
mainwindow.show();
app.exec();
}
}
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POLYGON_2_H

View File

@ -0,0 +1,164 @@
// Copyright (c) 1997
// Utrecht University (The Netherlands),
// ETH Zurich (Switzerland),
// INRIA Sophia-Antipolis (France),
// Max-Planck-Institute Saarbruecken (Germany),
// and Tel-Aviv University (Israel). All rights reserved.
//
// This file is part of CGAL (www.cgal.org); you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; either version 3 of the License,
// or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0+
//
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_POLYGON_WITH_HOLES_2_H
#define CGAL_DRAW_POLYGON_WITH_HOLES_2_H
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef DOXYGEN_RUNNING
namespace CGAL {
/*!
\ingroup PkgDrawPolygonWithHoles2
opens a new window and draws `aph`, an instance of the `CGAL::Polygon_with_holes_2` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\tparam PH an instance of the `CGAL::Polygon_with_holes_2` class.
\param aph the polygon with holes to draw.
*/
template<class PH>
void draw(const PH& aph);
} /* namespace CGAL */
#endif
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Polygon_with_holes_2.h>
#include <CGAL/Random.h>
namespace CGAL
{
// Viewer class for Polygon_2
template<class P2>
class SimplePolygonWithHoles2ViewerQt : public Basic_viewer_qt
{
typedef Basic_viewer_qt Base;
typedef typename P2::General_polygon_2::Point_2 Point;
public:
/// Construct the viewer.
/// @param ap2 the polygon to view
/// @param title the title of the window
SimplePolygonWithHoles2ViewerQt(QWidget* parent, const P2& ap2,
const char* title="Basic Polygon_with_holes_2 Viewer") :
// First draw: vertices; edges, faces; multi-color; no inverse normal
Base(parent, title, true, true, true, false, false),
p2(ap2)
{
compute_elements();
}
protected:
void compute_one_loop_elements(const typename P2::General_polygon_2& p, bool hole)
{
if (hole)
{ add_point_in_face(p.vertex(p.size()-1)); }
typename P2::General_polygon_2::Vertex_const_iterator prev;
for (typename P2::General_polygon_2::Vertex_const_iterator i=p.vertices_begin();
i!=p.vertices_end(); ++i)
{
add_point(*i); // Add vertex
if (i!=p.vertices_begin())
{ add_segment(*prev, *i); } // Add segment with previous point
add_point_in_face(*i); // Add point in face
prev=i;
}
// Add the last segment between the last point and the first one
add_segment(*prev, *(p.vertices_begin()));
}
void compute_elements()
{
clear();
if (p2.outer_boundary().is_empty()) return;
CGAL::Color c(75,160,255);
face_begin(c);
compute_one_loop_elements(p2.outer_boundary(), false);
for (typename P2::Hole_const_iterator it=p2.holes_begin(); it!=p2.holes_end(); ++it)
{
compute_one_loop_elements(*it, true);
add_point_in_face(p2.outer_boundary().vertex(p2.outer_boundary().size()-1));
}
face_end();
}
virtual void keyPressEvent(QKeyEvent *e)
{
// Test key pressed:
// const ::Qt::KeyboardModifiers modifiers = e->modifiers();
// if ((e->key()==Qt::Key_PageUp) && (modifiers==Qt::NoButton)) { ... }
// Call: * compute_elements() if the model changed, followed by
// * redraw() if some viewing parameters changed that implies some
// modifications of the buffers
// (eg. type of normal, color/mono)
// * update() just to update the drawing
// Call the base method to process others/classicals key
Base::keyPressEvent(e);
}
protected:
const P2& p2;
};
// Specialization of draw function.
template<class T, class C>
void draw(const CGAL::Polygon_with_holes_2<T, C>& ap2,
const char* title="Polygon_with_holes_2 Basic Viewer")
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"t2_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolygonWithHoles2ViewerQt<CGAL::Polygon_with_holes_2<T, C> >
mainwindow(app.activeWindow(), ap2, title);
mainwindow.show();
app.exec();
}
}
} // End namespace CGAL
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_POLYGON_WITH_HOLES_2_H

View File

@ -1,5 +1,6 @@
Algebraic_foundations
Circulator
GraphicsView
Installation
Kernel_23
Number_types

View File

@ -362,6 +362,11 @@ add_executable ( CGAL_Classification Classification.cpp )
add_dependencies(CGAL_Classification Classification)
target_link_libraries( CGAL_Classification PRIVATE polyhedron_demo )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS CGAL_Classification )
add_executable ( CGAL_PMP PMP.cpp )
add_dependencies(CGAL_PMP PMP)
target_link_libraries( CGAL_PMP PRIVATE polyhedron_demo )
add_to_cached_list( CGAL_EXECUTABLE_TARGETS CGAL_PMP )
#
# Exporting
#

View File

@ -10,20 +10,9 @@
*/
int main(int argc, char **argv)
{
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(fmt);
QStringList keywords;
keywords << "Classification";
Polyhedron_demo app(argc, argv,
"Classification demo",
"CGAL Classification Demo",
keywords);
//We set the locale to avoid any trouble with VTK
std::setlocale(LC_ALL, "C");
QStringList() << "Classification");
return app.try_exec();
}

View File

@ -383,14 +383,38 @@ MainWindow::MainWindow(const QStringList &keywords, bool verbose, QWidget* paren
connect(ui->menuOperations, SIGNAL(aboutToShow()), this, SLOT(filterOperations()));
}
void addActionToMenu(QAction* action, QMenu* menu)
{
bool added = false;
for(QAction* it : menu->actions())
{
QString atxt = action->text().remove("&"),
btxt = it->text().remove("&");
int i = 0;
while(atxt[i] == btxt[i]
&& i < atxt.size()
&& i < btxt.size())
++i;
bool res = (atxt[i] < btxt[i]);
if (res)
{
menu->insertAction(it, action);
added = true;
break;
}
}
if(!added)
menu->addAction(action);
}
//Recursive function that do a pass over a menu and its sub-menus(etc.) and hide them when they are empty
void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here)
{
QList<QAction*> buffer;
Q_FOREACH(QAction* action, menu->actions())
buffer.append(action);
while(!buffer.isEmpty()){
while(!buffer.isEmpty()){
Q_FOREACH(QAction* action, buffer) {
if(QMenu* submenu = action->menu())
{
@ -407,14 +431,17 @@ void filterMenuOperations(QMenu* menu, QString filter, bool keep_from_here)
}
else
{
menu->addAction(submenu->menuAction());
//menu->addAction(submenu->menuAction());
addActionToMenu(submenu->menuAction(), menu);
}
}
filterMenuOperations(submenu, filter, keep);
action->setVisible(!(submenu->isEmpty()));
}
else if(action->text().contains(filter, Qt::CaseInsensitive)){
menu->addAction(action);
//menu->addAction(action);
addActionToMenu(action, menu);
}
buffer.removeAll(action);
}
@ -432,10 +459,13 @@ void MainWindow::filterOperations()
menu->removeAction(action);
}
}
Q_FOREACH(QAction* action, action_menu_map.keys())
{
action_menu_map[action]->addAction(action);
QMenu* menu = action_menu_map[action];
addActionToMenu(action, menu);
}
QString filter=operationSearchBar.text();
Q_FOREACH(const PluginNamePair& p, plugins) {
Q_FOREACH(QAction* action, p.first->actions()) {
@ -447,6 +477,7 @@ void MainWindow::filterOperations()
}
// do a pass over all menus in Operations and their sub-menus(etc.) and hide them when they are empty
filterMenuOperations(ui->menuOperations, filter, false);
operationSearchBar.setFocus();
}

View File

@ -10,20 +10,9 @@
*/
int main(int argc, char **argv)
{
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(fmt);
QStringList keywords;
keywords << "Mesh_3";
Polyhedron_demo app(argc, argv,
"Mesh_3 demo",
"CGAL Mesh_3 Demo",
keywords);
//We set the locale to avoid any trouble with VTK
std::setlocale(LC_ALL, "C");
QStringList() << "Mesh_3");
return app.try_exec();
}

View File

@ -0,0 +1,29 @@
#include "Polyhedron_demo.h"
#include <clocale>
#include <CGAL/Qt/resources.h>
#include <QSurfaceFormat>
/*!
* \brief Defines the entry point of the demo.
* Creates the application and sets a main window.
*/
int main(int argc, char **argv)
{
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(fmt);
QStringList keywords;
keywords << "PMP";
Polyhedron_demo app(argc, argv,
"PMP demo",
"CGAL Polygon Mesh Processing Demo",
keywords);
//We set the locale to avoid any trouble with VTK
std::setlocale(LC_ALL, "C");
return app.try_exec();
}

View File

@ -1073,7 +1073,7 @@ void Polyhedron_demo_cut_plugin::apply(Item* item, QMap< QObject*, Facets_tree*>
traits.set_shared_data(mesh, pmap); //Mandatory for SMesh. If not provided, mesh and PPmap are taken default, saying NULL in tree.traversal().
connect(item, SIGNAL(item_is_about_to_be_changed()),
this, SLOT(deleteTree()));
f_trees[item] = new Facets_tree(traits);
Facets_tree* new_tree = new Facets_tree(traits);
//filter facets to ignore degenerated ones
for(typename boost::graph_traits<Mesh>::face_iterator fit = faces(mesh).first,
@ -1085,10 +1085,10 @@ void Polyhedron_demo_cut_plugin::apply(Item* item, QMap< QObject*, Facets_tree*>
c(get(pmap, target(prev(halfedge(*fit, mesh), mesh), mesh)));
if(!CGAL::collinear(a,b,c))
f_trees[item]->insert(typename Facets_tree::Primitive(fit, mesh, pmap));
new_tree->insert(typename Facets_tree::Primitive(fit, mesh, pmap));
}
Scene_aabb_item* aabb_item = new Scene_aabb_item(*f_trees[item]);
Scene_aabb_item* aabb_item = new Scene_aabb_item(*new_tree);
f_trees[item] = new_tree;
aabb_item->setName(tr("AABB tree of %1").arg(item->name()));
aabb_item->setRenderingMode(Wireframe);
aabb_item->setColor(Qt::black);

View File

@ -10,7 +10,7 @@ target_link_libraries(io_implicit_function_plugin PUBLIC scene_implicit_function
polyhedron_demo_plugin(nef_io_plugin Nef_io_plugin KEYWORDS IO)
target_link_libraries(nef_io_plugin PUBLIC scene_nef_polyhedron_item)
polyhedron_demo_plugin(off_plugin OFF_io_plugin KEYWORDS IO Mesh_3 PointSetProcessing Classification)
polyhedron_demo_plugin(off_plugin OFF_io_plugin KEYWORDS IO Mesh_3 PointSetProcessing Classification PMP)
target_link_libraries(off_plugin PUBLIC scene_polygon_soup_item scene_points_with_normal_item scene_surface_mesh_item)
polyhedron_demo_plugin(off_to_nef_plugin OFF_to_nef_io_plugin KEYWORDS IO)
@ -19,11 +19,11 @@ target_link_libraries(off_to_nef_plugin PUBLIC scene_nef_polyhedron_item)
polyhedron_demo_plugin(polylines_io_plugin Polylines_io_plugin KEYWORDS IO Mesh_3)
target_link_libraries(polylines_io_plugin PUBLIC scene_polylines_item)
polyhedron_demo_plugin(stl_plugin STL_io_plugin KEYWORDS IO)
polyhedron_demo_plugin(stl_plugin STL_io_plugin KEYWORDS IO PMP)
target_link_libraries(stl_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item)
polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin KEYWORDS IO)
polyhedron_demo_plugin(surf_io_plugin Surf_io_plugin KEYWORDS IO PMP)
target_link_libraries(surf_io_plugin PUBLIC scene_surface_mesh_item)
polyhedron_demo_plugin(lcc_io_plugin lcc_io_plugin KEYWORDS IO)
@ -33,13 +33,17 @@ target_link_libraries(lcc_io_plugin PUBLIC scene_lcc_item)
find_package(VTK QUIET COMPONENTS
vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML vtkFiltersCore vtkFiltersSources)
if (VTK_FOUND)
if(VTK_USE_FILE)
include(${VTK_USE_FILE})
if ("${VTK_VERSION_MAJOR}" GREATER "5")
endif()
if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5)
if(TARGET VTK::CommonCore)
set(VTK_LIBRARIES VTK::CommonCore VTK::IOCore VTK::IOLegacy VTK::IOXML VTK::FiltersCore VTK::FiltersSources)
endif()
if(VTK_LIBRARIES)
polyhedron_demo_plugin(vtk_plugin VTK_io_plugin KEYWORDS IO Mesh_3)
target_link_libraries(vtk_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_c3t3_item scene_points_with_normal_item
vtkCommonCore vtkIOCore vtkIOLegacy vtkIOXML
vtkFiltersCore vtkFiltersSources)
${VTK_LIBRARIES})
else()
message(STATUS "NOTICE : the vtk IO plugin needs VTK libraries and will not be compiled.")
@ -61,7 +65,7 @@ if(has_cxx_rvalues LESS 0 OR has_cxx_variadic LESS 0)
else()
set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates)
polyhedron_demo_plugin(ply_plugin PLY_io_plugin KEYWORDS IO PointSetProcessing Classification)
polyhedron_demo_plugin(ply_plugin PLY_io_plugin KEYWORDS IO PointSetProcessing Classification PMP)
target_link_libraries(ply_plugin PUBLIC scene_points_with_normal_item scene_polygon_soup_item scene_surface_mesh_item scene_textured_item)
target_compile_features(ply_plugin PRIVATE ${needed_cxx_features})
@ -82,7 +86,7 @@ find_library(3MF_LIBRARIES NAMES 3MF DOC "Path to the lib3MF library")
if(3MF_LIBRARIES AND 3MF_INCLUDE_DIR)
include_directories(${3MF_INCLUDE_DIR})
polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO)
polyhedron_demo_plugin(3mf_io_plugin 3mf_io_plugin KEYWORDS IO PMP)
target_link_libraries(3mf_io_plugin PRIVATE scene_surface_mesh_item scene_points_with_normal_item scene_polylines_item ${3MF_LIBRARIES})
else()
message(STATUS "NOTICE : The 3mf_io_plugin requires the lib3MF library, and will not be compiled.")

View File

@ -11,15 +11,18 @@ polyhedron_demo_plugin(mesh_3_plugin Mesh_3_plugin
target_link_libraries(mesh_3_plugin PUBLIC scene_polygon_soup_item scene_polylines_item scene_implicit_function_item scene_image_item
scene_surface_mesh_item scene_c3t3_item ${OPENGL_gl_LIBRARY} )
set(VTK_LIBS "")
find_package(VTK QUIET COMPONENTS
vtkImagingGeneral vtkIOImage NO_MODULE)
if (VTK_FOUND)
if(VTK_USE_FILE)
include(${VTK_USE_FILE})
if ("${VTK_VERSION_MAJOR}" GREATER "5")
endif()
if ("${VTK_VERSION_MAJOR}" GREATER "5" OR VTK_VERSION VERSION_GREATER 5)
if(TARGET VTK::IOImage)
set(VTK_LIBRARIES VTK::IOImage)
endif()
if(VTK_LIBRARIES)
add_definitions(-DCGAL_USE_VTK)
set(VTK_LIBS vtkImagingGeneral vtkIOImage)
else()
message(STATUS "NOTICE : the DICOM files (.dcm) need VTK libraries to be open and will not be able to.")
endif()
@ -34,7 +37,7 @@ find_package(Boost QUIET OPTIONAL_COMPONENTS filesystem)
if(Boost_FILESYSTEM_FOUND)
qt5_wrap_ui( imgUI_FILES Image_res_dialog.ui raw_image.ui)
polyhedron_demo_plugin(io_image_plugin Io_image_plugin Volume_plane_intersection.cpp Raw_image_dialog.cpp ${imgUI_FILES} ${VOLUME_MOC_OUTFILES} KEYWORDS IO Mesh_3)
target_link_libraries(io_image_plugin PUBLIC scene_image_item ${VTK_LIBS} CGAL::CGAL_ImageIO)
target_link_libraries(io_image_plugin PUBLIC scene_image_item ${VTK_LIBRARIES} CGAL::CGAL_ImageIO)
if(TARGET Boost::filesystem)
target_link_libraries(io_image_plugin PUBLIC Boost::filesystem)
else()

View File

@ -462,7 +462,9 @@ void Mesh_3_plugin::mesh_3(const bool surface_only, const bool use_defaults)
if (!sm_items.empty())
{
QList<const SMesh*> polyhedrons;
if(!surface_only) {
sm_items.removeAll(bounding_sm_item);
}
std::transform(sm_items.begin(), sm_items.end(),
std::back_inserter(polyhedrons),
[](Scene_surface_mesh_item* item) {

View File

@ -113,7 +113,7 @@ public :
{
menu->addAction(action);
}
dock_widget = new GeneratorWidget("Basic Objets", mw);
dock_widget = new GeneratorWidget("Basic Objects", mw);
dock_widget->setVisible(false); // do not show at the beginning
addDockWidget(dock_widget);
connect(dock_widget->generateButton, &QAbstractButton::clicked,

View File

@ -12,11 +12,11 @@ if(EIGEN3_FOUND)
if("${EIGEN3_VERSION}" VERSION_GREATER "3.1.90")
qt5_wrap_ui( hole_fillingUI_FILES Hole_filling_widget.ui)
polyhedron_demo_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES})
polyhedron_demo_plugin(hole_filling_plugin Hole_filling_plugin ${hole_fillingUI_FILES} KEYWORDS PMP)
target_link_libraries(hole_filling_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_selection_item)
qt5_wrap_ui( fairingUI_FILES Fairing_widget.ui)
polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES})
polyhedron_demo_plugin(fairing_plugin Fairing_plugin ${fairingUI_FILES} KEYWORDS PMP)
target_link_libraries(fairing_plugin PUBLIC scene_selection_item)
polyhedron_demo_plugin(hole_filling_polyline_plugin Hole_filling_polyline_plugin )
@ -40,13 +40,14 @@ else(EIGEN3_FOUND)
endif()
qt5_wrap_ui( soupUI_FILES Repair_soup.ui )
polyhedron_demo_plugin(orient_soup_plugin Orient_soup_plugin ${soupUI_FILES} KEYWORDS Classification )
polyhedron_demo_plugin(orient_soup_plugin Orient_soup_plugin ${soupUI_FILES} KEYWORDS Classification PMP)
target_link_libraries(orient_soup_plugin PUBLIC scene_polygon_soup_item scene_surface_mesh_item scene_polylines_item scene_points_with_normal_item)
polyhedron_demo_plugin(inside_out_plugin Inside_out_plugin)
polyhedron_demo_plugin(inside_out_plugin Inside_out_plugin KEYWORDS PMP)
target_link_libraries(inside_out_plugin PUBLIC scene_surface_mesh_item scene_polygon_soup_item)
polyhedron_demo_plugin(join_and_split_plugin Join_and_split_polyhedra_plugin)
polyhedron_demo_plugin(join_and_split_plugin Join_and_split_polyhedra_plugin KEYWORDS PMP)
target_link_libraries(join_and_split_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
qt5_wrap_ui( point_inside_polyhedronUI_FILES Point_inside_polyhedron_widget.ui)
@ -57,57 +58,59 @@ qt5_wrap_ui( polyhedron_slicerUI_FILES Polyhedron_slicer_widget.ui)
polyhedron_demo_plugin(polyhedron_slicer_plugin Polyhedron_slicer_plugin ${polyhedron_slicerUI_FILES})
target_link_libraries(polyhedron_slicer_plugin PUBLIC scene_surface_mesh_item scene_basic_objects scene_polylines_item)
polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin)
polyhedron_demo_plugin(polyhedron_stitching_plugin Polyhedron_stitching_plugin KEYWORDS PMP)
target_link_libraries(polyhedron_stitching_plugin PUBLIC scene_surface_mesh_item scene_polylines_item)
qt5_wrap_ui( selectionUI_FILES Selection_widget.ui)
polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES} KEYWORDS PolygonMesh IO Classification Mesh_3)
polyhedron_demo_plugin(selection_plugin Selection_plugin ${selectionUI_FILES} KEYWORDS PMP IO Classification Mesh_3)
target_link_libraries(selection_plugin PUBLIC scene_selection_item scene_points_with_normal_item scene_polylines_item)
polyhedron_demo_plugin(self_intersection_plugin Self_intersection_plugin)
target_link_libraries(self_intersection_plugin PUBLIC scene_selection_item scene_surface_mesh_item)
#to keep it simple to compile
add_custom_target(self_intersection_plugin )
add_dependencies(self_intersection_plugin selection_plugin)
polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin)
polyhedron_demo_plugin(triangulate_facets_plugin Triangulate_facets_plugin KEYWORDS PMP)
target_link_libraries(triangulate_facets_plugin PUBLIC scene_surface_mesh_item)
polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin)
polyhedron_demo_plugin(corefinement_plugin Corefinement_plugin KEYWORDS PMP)
target_link_libraries(corefinement_plugin PUBLIC scene_surface_mesh_item)
polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin)
polyhedron_demo_plugin(surface_intersection_plugin Surface_intersection_plugin KEYWORDS PMP)
target_link_libraries(surface_intersection_plugin PUBLIC scene_surface_mesh_item scene_polylines_item scene_points_with_normal_item)
polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin)
polyhedron_demo_plugin(repair_polyhedron_plugin Repair_polyhedron_plugin KEYWORDS PMP)
target_link_libraries(repair_polyhedron_plugin PUBLIC scene_surface_mesh_item)
qt5_wrap_ui( isotropicRemeshingUI_FILES Isotropic_remeshing_dialog.ui)
polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin ${isotropicRemeshingUI_FILES})
polyhedron_demo_plugin(isotropic_remeshing_plugin Isotropic_remeshing_plugin ${isotropicRemeshingUI_FILES} KEYWORDS PMP)
target_link_libraries(isotropic_remeshing_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
if(TBB_FOUND)
CGAL_target_use_TBB(isotropic_remeshing_plugin)
endif()
polyhedron_demo_plugin(distance_plugin Distance_plugin)
polyhedron_demo_plugin(distance_plugin Distance_plugin KEYWORDS PMP)
target_link_libraries(distance_plugin PUBLIC scene_surface_mesh_item scene_color_ramp)
if(TBB_FOUND)
CGAL_target_use_TBB(distance_plugin)
endif()
polyhedron_demo_plugin(detect_sharp_edges_plugin Detect_sharp_edges_plugin KEYWORDS IO Mesh_3)
polyhedron_demo_plugin(detect_sharp_edges_plugin Detect_sharp_edges_plugin KEYWORDS IO Mesh_3 PMP)
target_link_libraries(detect_sharp_edges_plugin PUBLIC scene_surface_mesh_item)
qt5_wrap_ui( randomPerturbationUI_FILES Random_perturbation_dialog.ui)
polyhedron_demo_plugin(random_perturbation_plugin Random_perturbation_plugin ${randomPerturbationUI_FILES})
polyhedron_demo_plugin(random_perturbation_plugin Random_perturbation_plugin ${randomPerturbationUI_FILES} KEYWORDS PMP)
target_link_libraries(random_perturbation_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
polyhedron_demo_plugin(degenerated_faces_plugin Degenerated_faces_plugin)
polyhedron_demo_plugin(degenerated_faces_plugin Degenerated_faces_plugin KEYWORDS PMP)
target_link_libraries(degenerated_faces_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
qt5_wrap_ui( engravUI_FILES Engrave_dock_widget.ui )
polyhedron_demo_plugin(engrave_text_plugin Engrave_text_plugin ${engravUI_FILES})
target_link_libraries(engrave_text_plugin PUBLIC scene_surface_mesh_item scene_selection_item scene_polylines_item)
polyhedron_demo_plugin(extrude_plugin Extrude_plugin)
polyhedron_demo_plugin(extrude_plugin Extrude_plugin KEYWORDS PMP)
target_link_libraries(extrude_plugin PUBLIC scene_surface_mesh_item scene_selection_item)
# The smoothing plugin can still do some things, even if Ceres is not found

View File

@ -19,7 +19,7 @@ class Polyhedron_demo_corefinement_sm_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "corefinement_plugin.json")
enum bool_op {CRF_UNION, CRF_INTER, CRF_MINUS, CRF_MINUS_OP};

View File

@ -25,7 +25,7 @@ class Degenerated_faces_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "degenerated_faces_plugin.json")
public:

View File

@ -26,7 +26,7 @@ class Polyhedron_demo_detect_sharp_edges_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "detect_sharp_edges_plugin.json")
public:
void init(QMainWindow* mainWindow, Scene_interface* scene_interface, Messages_interface*) {

View File

@ -345,7 +345,7 @@ class DistancePlugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "distance_plugin.json")
typedef Kernel::Point_3 Point_3;
public:

View File

@ -316,7 +316,7 @@ class ExtrudePlugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "extrude_plugin.json")
public:
bool applicable(QAction* action) const Q_DECL_OVERRIDE

View File

@ -37,7 +37,7 @@ class Polyhedron_demo_fairing_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "fairing_plugin.json")
public:
bool applicable(QAction*) const {
return qobject_cast<Scene_facegraph_item*>(scene->item(scene->mainSelectionIndex()))

View File

@ -164,9 +164,9 @@ void removeViewer(Viewer_interface *viewer)
Scene_item_rendering_helper::removeViewer(viewer);
}
// filter events for selecting / activating holes with mouse input
bool eventFilter(QObject* target, QEvent *event)
bool eventFilter(QObject* , QEvent *event)
{
Viewer_interface* viewer = qobject_cast<Viewer_interface*>(target);
Viewer_interface* viewer = CGAL::Three::Three::activeViewer();
// This filter is both filtering events from 'viewer' and 'main window'
Mouse_keyboard_state old_state = state;
// key events
@ -262,7 +262,7 @@ private:
Face_graph& poly = *poly_item->polyhedron();
CGAL::QGLViewer* viewer = Three::mainViewer();
CGAL::QGLViewer* viewer = Three::currentViewer();
CGAL::qglviewer::Camera* camera = viewer->camera();
Polyline_data_list::const_iterator min_it;
@ -270,15 +270,6 @@ private:
Kernel::Point_2 xy(x,y);
for(Polyline_data_list::const_iterator it = polyline_data_list.begin(); it != polyline_data_list.end(); ++it)
{
#if 0
/* use center of polyline to measure distance - performance wise */
const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->position);
float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2);
if(dist < min_dist) {
min_dist = dist;
min_it = it;
}
#else
boost::property_map<Face_graph,CGAL::vertex_point_t>::type vpm = get(CGAL::vertex_point,poly);
/* use polyline points to measure distance - might hurt performance for large holes */
for(fg_halfedge_descriptor hf_around_facet : halfedges_around_face(it->halfedge,poly)){
@ -287,14 +278,12 @@ private:
const Point_3& p_2 = get(vpm,target(opposite(hf_around_facet,poly),poly));
const CGAL::qglviewer::Vec& pos_it_2 = camera->projectedCoordinatesOf(CGAL::qglviewer::Vec(p_2.x(), p_2.y(), p_2.z()));
Kernel::Segment_2 s(Kernel::Point_2(pos_it_1.x, pos_it_1.y), Kernel::Point_2(pos_it_2.x, pos_it_2.y));
double dist = CGAL::squared_distance(s, xy);
if(dist < min_dist) {
min_dist = dist;
min_it = it;
}
}
#endif
}
if(min_it == active_hole) {
@ -337,7 +326,7 @@ class Polyhedron_demo_hole_filling_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "hole_filling_plugin.json")
public:
bool applicable(QAction*) const { return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex())) ||
qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex())); }

View File

@ -15,7 +15,7 @@ class Polyhedron_demo_inside_out_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "inside_out_plugin.json")
public:

View File

@ -170,7 +170,7 @@ class Polyhedron_demo_isotropic_remeshing_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "isotropic_remeshing_plugin.json")
typedef boost::graph_traits<FaceGraph>::edge_descriptor edge_descriptor;
typedef boost::graph_traits<FaceGraph>::halfedge_descriptor halfedge_descriptor;

View File

@ -33,7 +33,7 @@ class Polyhedron_demo_join_and_split_polyhedra_plugin:
public Polyhedron_demo_plugin_helper
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "join_and_split_polyhedra_plugin.json")
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
QAction* actionJoinPolyhedra, *actionSplitPolyhedra, *actionColorConnectedComponents;
Messages_interface* msg_interface;

View File

@ -25,7 +25,7 @@ class Polyhedron_demo_orient_soup_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "orient_soup_plugin.json")
public:
void init(QMainWindow* mainWindow,

View File

@ -40,7 +40,7 @@ class Polyhedron_demo_polyhedron_stitching_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "polyhedron_stitching_plugin.json")
QAction* actionDetectBorders;
QAction* actionStitchBorders;

View File

@ -34,7 +34,7 @@ class Polyhedron_demo_random_perturbation_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "random_perturbation_plugin.json")
public:
void init(QMainWindow* mainWindow,

View File

@ -24,7 +24,7 @@ class Polyhedron_demo_repair_polyhedron_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "repair_polyhedron_plugin.json")
public:

View File

@ -25,6 +25,8 @@
#include <CGAL/Polygon_mesh_processing/border.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/shape_predicates.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <Scene.h>
typedef Scene_surface_mesh_item Scene_face_graph_item;
@ -125,17 +127,32 @@ public:
return res;
}
bool applicable(QAction*) const override {
bool applicable(QAction* action) const override {
if(action == actionSelfIntersection)
return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()));
else if(action == actionSelection)
return qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()))
|| qobject_cast<Scene_polyhedron_selection_item*>(scene->item(scene->mainSelectionIndex()));
return false;
}
void print_message(QString message) { CGAL::Three::Three::information(message); }
QList<QAction*> actions() const override { return QList<QAction*>() << actionSelection; }
QList<QAction*> actions() const override {
return QList<QAction*>() << actionSelection
<< actionSelfIntersection;
}
using Polyhedron_demo_io_plugin_interface::init;
virtual void init(QMainWindow* mainWindow, CGAL::Three::Scene_interface* scene_interface, Messages_interface* m) override{
mw = mainWindow;
scene = scene_interface;
messages = m;
actionSelfIntersection = new QAction(tr("Self-&Intersection Test"), mw);
actionSelfIntersection->setObjectName("actionSelfIntersection");
actionSelfIntersection->setProperty("subMenuName", "Polygon Mesh Processing");
connect(actionSelfIntersection, SIGNAL(triggered()), this, SLOT(on_actionSelfIntersection_triggered()));
actionSelection = new QAction(
QString("Surface Mesh Selection")
, mw);
@ -224,8 +241,10 @@ Q_SIGNALS:
void save_handleType();
void set_operation_mode(int);
void set_highlighting(bool);
public Q_SLOTS:
void on_actionSelfIntersection_triggered();
void connectItem(Scene_polyhedron_selection_item* new_item)
{
@ -1057,6 +1076,7 @@ void filter_operations()
private:
Messages_interface* messages;
QAction* actionSelection;
QAction *actionSelfIntersection;
QDockWidget* dock_widget;
Ui::Selection ui_widget;
@ -1068,6 +1088,102 @@ typedef boost::unordered_map<Scene_face_graph_item*, Scene_polyhedron_selection_
bool from_plugin;
}; // end Polyhedron_demo_selection_plugin
template<class Mesh>
bool selfIntersect(Mesh* mesh, std::vector<std::pair<typename boost::graph_traits<Mesh>::face_descriptor,typename boost::graph_traits<Mesh>::face_descriptor> > &faces)
{
if(!CGAL::is_triangle_mesh(*mesh))
{
CGAL::Three::Three::warning("%1 skipped because not triangulated.");
return false;
}
// compute self-intersections
CGAL::Polygon_mesh_processing::self_intersections
(*mesh, std::back_inserter(faces),
CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *mesh)));
std::cout << "ok (" << faces.size() << " triangle pair(s))" << std::endl;
return !faces.empty();
}
void Polyhedron_demo_selection_plugin::on_actionSelfIntersection_triggered()
{
typedef boost::graph_traits<Face_graph>::face_descriptor Face_descriptor;
typedef boost::graph_traits<Face_graph>::halfedge_descriptor halfedge_descriptor;
QApplication::setOverrideCursor(Qt::WaitCursor);
bool found = false;
std::vector<Scene_face_graph_item*> selected_polys;
Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices())
{
Scene_face_graph_item* poly_item =
qobject_cast<Scene_face_graph_item*>(scene->item(index));
if(poly_item)
{
selected_polys.push_back(poly_item);
}
}
Q_FOREACH(Scene_face_graph_item* poly_item, selected_polys)
{
Face_graph* mesh = poly_item->face_graph();
std::vector<std::pair<Face_descriptor, Face_descriptor> > faces;
// add intersecting triangles to a new Surface_mesh.
if(selfIntersect(mesh, faces))
{
Scene_polyhedron_selection_item* selection_item = nullptr;
bool should_add = true;
if(selection_item_map.find(poly_item) != selection_item_map.end())
{
QApplication::restoreOverrideCursor();
if(QMessageBox::question(mw, "Question", "Only one Selection Item can be associated to an item at once, "
"and one already exists. Would you like to replace it ? (If not, this item will be skipped.)")
== QMessageBox::Yes)
{
selection_item = selection_item_map.find(poly_item)->second;
selection_item->clear();
should_add = false;
}
else
continue;
}
else
{
selection_item = new Scene_polyhedron_selection_item(poly_item, mw);
}
QApplication::setOverrideCursor(Qt::WaitCursor);
//add the faces
for(std::vector<std::pair<Face_descriptor, Face_descriptor> >::iterator fb = faces.begin();
fb != faces.end(); ++fb) {
selection_item->selected_facets.insert(fb->first);
selection_item->selected_facets.insert(fb->second);
//add the edges
for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->first, *mesh), *mesh))
{
selection_item->selected_edges.insert(edge(he_circ, *mesh));
}
for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->second, *mesh), *mesh))
{
selection_item->selected_edges.insert(edge(he_circ, *mesh));
}
}
selection_item->invalidateOpenGLBuffers();
selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name()));
if(should_add)
connectItem(selection_item);
poly_item->setRenderingMode(Wireframe);
scene->itemChanged(poly_item);
selection_item->set_highlighting(false);
found = true;
}
}
QApplication::restoreOverrideCursor();
if(!found)
QMessageBox::information(mw, tr("No self intersection"),
tr("None of the selected surfaces self-intersect."));
}
//Q_EXPORT_PLUGIN2(Polyhedron_demo_selection_plugin, Polyhedron_demo_selection_plugin)
#include "Selection_plugin.moc"

View File

@ -1,138 +0,0 @@
#include <QApplication>
#include <QAction>
#include <QMessageBox>
#include <QMainWindow>
#include <CGAL/Three/Polyhedron_demo_plugin_interface.h>
#include <CGAL/intersections.h>
#include <CGAL/Bbox_3.h>
#include <CGAL/box_intersection_d.h>
#include <CGAL/Polygon_mesh_processing/self_intersections.h>
#include <CGAL/Make_triangle_soup.h>
#include "Kernel_type.h"
#include "Scene_polyhedron_selection_item.h"
#include "Scene_surface_mesh_item.h"
typedef Scene_surface_mesh_item Scene_face_graph_item;
typedef Scene_face_graph_item::Face_graph Face_graph;
typedef Kernel::Triangle_3 Triangle;
using namespace CGAL::Three;
class Polyhedron_demo_self_intersection_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")
public:
QList<QAction*> actions() const {
return _actions;
}
void init(QMainWindow* mainWindow,
Scene_interface* scene_interface,
Messages_interface*)
{
mw = mainWindow;
scene = scene_interface;
QAction *actionSelfIntersection = new QAction(tr("Self-&Intersection Test"), mw);
actionSelfIntersection->setProperty("subMenuName", "Polygon Mesh Processing");
connect(actionSelfIntersection, SIGNAL(triggered()), this, SLOT(on_actionSelfIntersection_triggered()));
_actions <<actionSelfIntersection;
}
bool applicable(QAction*) const {
return
qobject_cast<Scene_face_graph_item*>(scene->item(scene->mainSelectionIndex()));
}
public Q_SLOTS:
void on_actionSelfIntersection_triggered();
private:
QList<QAction*> _actions;
Scene_interface *scene;
QMainWindow *mw;
}; // end Polyhedron_demo_self_intersection_plugin
//pretty useless for now but could allow a huge factorization when a selection_item is
// available for SM_items
template<class Mesh>
bool selfIntersect(Mesh* mesh, std::vector<std::pair<typename boost::graph_traits<Mesh>::face_descriptor,typename boost::graph_traits<Mesh>::face_descriptor> > &faces)
{
if(!CGAL::is_triangle_mesh(*mesh))
{
CGAL::Three::Three::warning("%1 skipped because not triangulated.");
return false;
}
// compute self-intersections
CGAL::Polygon_mesh_processing::self_intersections
(*mesh, std::back_inserter(faces),
CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, *mesh)));
std::cout << "ok (" << faces.size() << " triangle pair(s))" << std::endl;
return !faces.empty();
}
void Polyhedron_demo_self_intersection_plugin::on_actionSelfIntersection_triggered()
{
typedef boost::graph_traits<Face_graph>::face_descriptor Face_descriptor;
typedef boost::graph_traits<Face_graph>::halfedge_descriptor halfedge_descriptor;
QApplication::setOverrideCursor(Qt::WaitCursor);
bool found = false;
std::vector<Scene_face_graph_item*> selected_polys;
Q_FOREACH(Scene_interface::Item_id index, scene->selectionIndices())
{
Scene_face_graph_item* poly_item =
qobject_cast<Scene_face_graph_item*>(scene->item(index));
if(poly_item)
{
selected_polys.push_back(poly_item);
}
}
Q_FOREACH(Scene_face_graph_item* poly_item, selected_polys)
{
Face_graph* mesh = poly_item->face_graph();
std::vector<std::pair<Face_descriptor, Face_descriptor> > faces;
// add intersecting triangles to a new Surface_mesh.
if(selfIntersect(mesh, faces))
{
//add the faces
Scene_polyhedron_selection_item* selection_item = new Scene_polyhedron_selection_item(poly_item, mw);
for(std::vector<std::pair<Face_descriptor, Face_descriptor> >::iterator fb = faces.begin();
fb != faces.end(); ++fb) {
selection_item->selected_facets.insert(fb->first);
selection_item->selected_facets.insert(fb->second);
//add the edges
for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->first, *mesh), *mesh))
{
selection_item->selected_edges.insert(edge(he_circ, *mesh));
}
for(halfedge_descriptor he_circ : halfedges_around_face( halfedge(fb->second, *mesh), *mesh))
{
selection_item->selected_edges.insert(edge(he_circ, *mesh));
}
}
selection_item->invalidateOpenGLBuffers();
selection_item->setName(tr("%1 (selection) (intersecting triangles)").arg(poly_item->name()));
poly_item->setRenderingMode(Wireframe);
scene->addItem(selection_item);
scene->itemChanged(poly_item);
scene->itemChanged(selection_item);
found = true;
}
}
QApplication::restoreOverrideCursor();
if(!found)
QMessageBox::information(mw, tr("No self intersection"),
tr("None of the selected surfaces self-intersect."));
}
#include "Self_intersection_plugin.moc"

View File

@ -32,7 +32,7 @@ class Polyhedron_demo_intersection_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "surface_intersection_plugin.json")
public:

View File

@ -14,7 +14,7 @@ class Polyhedron_demo_triangulate_facets_plugin :
{
Q_OBJECT
Q_INTERFACES(CGAL::Three::Polyhedron_demo_plugin_interface)
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0")
Q_PLUGIN_METADATA(IID "com.geometryfactory.PolyhedronDemo.PluginInterface/1.0" FILE "triangulate_facets_plugin.json")
public:

View File

@ -1,8 +1,4 @@
#include "Polyhedron_demo.h"
#include <clocale>
#include <CGAL/Qt/resources.h>
#include <QSurfaceFormat>
/*!
* \brief Defines the entry point of the demo.
@ -10,17 +6,8 @@
*/
int main(int argc, char **argv)
{
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(fmt);
Polyhedron_demo app(argc, argv,
"Polyhedron_3 demo",
"CGAL Polyhedron Demo");
//We set the locale to avoid any trouble with VTK
std::setlocale(LC_ALL, "C");
return app.try_exec();
}

View File

@ -8,6 +8,7 @@
#include <QCommandLineOption>
#include <QSurfaceFormat>
#include <QOpenGLContext>
#include <clocale>
struct Polyhedron_demo_impl {
@ -17,11 +18,34 @@ struct Polyhedron_demo_impl {
Polyhedron_demo_impl() : catch_exceptions(true) {}
}; // end struct Polyhedron_demo_impl
int& code_to_call_before_creation_of_QCoreApplication(int& i) {
QSurfaceFormat fmt;
fmt.setVersion(4, 3);
fmt.setRenderableType(QSurfaceFormat::OpenGL);
fmt.setProfile(QSurfaceFormat::CoreProfile);
fmt.setOption(QSurfaceFormat::DebugContext);
QSurfaceFormat::setDefaultFormat(fmt);
//for windows
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
#endif
//We set the locale to avoid any trouble with VTK
std::setlocale(LC_ALL, "C");
return i;
}
Polyhedron_demo::Polyhedron_demo(int& argc, char **argv,
QString application_name,
QString main_window_title,
QStringList input_keywords)
: QApplication(argc, argv)
: QApplication(code_to_call_before_creation_of_QCoreApplication(argc),
// This trick in the previous line ensure that code
// is called before the creation of the QApplication
// object.
argv)
, d_ptr_is_initialized(false)
, d_ptr(new Polyhedron_demo_impl)
{
@ -30,11 +54,6 @@ Polyhedron_demo::Polyhedron_demo(int& argc, char **argv,
std::cout.precision(17);
std::clog.precision(17);
//for windows
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
this->setAttribute(Qt::AA_UseDesktopOpenGL);
#endif
// Import resources from libCGAL (Qt5).
CGAL_QT_INIT_RESOURCES;

View File

@ -7,6 +7,7 @@
#include <CGAL/Three/Triangle_container.h>
#include <CGAL/Three/Edge_container.h>
#include <CGAL/Three/Point_container.h>
#include <CGAL/Three/Three.h>
#include <QObject>
#include <QApplication>
@ -25,6 +26,8 @@
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup.h>
#include <CGAL/Polygon_mesh_processing/orientation.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#define CGAL_PMP_REPAIR_POLYGON_SOUP_VERBOSE 1
#include <CGAL/Polygon_mesh_processing/repair_polygon_soup.h>
#include <CGAL/Polygon_2.h>
@ -41,11 +44,14 @@
#include <boost/accumulators/statistics/median.hpp>
#include <map>
#include <streambuf>
using namespace CGAL::Three;
typedef Viewer_interface Vi;
typedef Triangle_container Tc;
typedef Edge_container Ec;
typedef Point_container Pc;
struct Scene_polygon_soup_item_priv{
typedef Polygon_soup::Polygons::const_iterator Polygons_iterator;
@ -858,6 +864,8 @@ void Scene_polygon_soup_item::repair(bool erase_dup, bool req_same_orientation)
erase_all_duplicates(erase_dup)
.require_same_orientation(req_same_orientation));
QApplication::restoreOverrideCursor();
// CGAL::Three::Three::information(
}
CGAL::Three::Scene_item::Header_data Scene_polygon_soup_item::header() const

View File

@ -198,6 +198,10 @@ struct Scene_polyhedron_selection_item_priv{
};
QUndoStack stack;
CGAL::Face_filtered_graph<SMesh> *filtered_graph;
std::size_t num_faces;
std::size_t num_vertices;
std::size_t num_edges;
};
typedef Scene_polyhedron_selection_item_priv Priv;
@ -1121,6 +1125,7 @@ bool Scene_polyhedron_selection_item:: treat_selection(const std::set<fg_edge_de
halfedge(v2, *mesh),
*mesh);
}, this));
CGAL::Euler::join_face(halfedge(ed, *mesh), *mesh);
compute_normal_maps();
poly_item->invalidateOpenGLBuffers();
}
@ -2121,6 +2126,9 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa
{
this->poly_item = poly_item;
d->poly =poly_item->polyhedron();
d->num_faces = num_faces(*poly_item->polyhedron());
d->num_vertices = num_vertices(*poly_item->polyhedron());
d->num_edges = num_edges(*poly_item->polyhedron());
connect(poly_item, SIGNAL(item_is_about_to_be_changed()), this, SLOT(poly_item_changed()));
//parameters type must be of the same name here and there, so they must be hardcoded.
connect(&k_ring_selector, SIGNAL(selected(const std::set<fg_vertex_descriptor>&)), this,
@ -2148,6 +2156,29 @@ void Scene_polyhedron_selection_item::init(Scene_face_graph_item* poly_item, QMa
connect(&k_ring_selector,SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)), this, SIGNAL(isCurrentlySelected(Scene_facegraph_item_k_ring_selection*)));
k_ring_selector.init(poly_item, mw, Active_handle::VERTEX, -1);
connect(&k_ring_selector, SIGNAL(resetIsTreated()), this, SLOT(resetIsTreated()));
connect(poly_item, &Scene_surface_mesh_item::itemChanged, this, [this](){
std::size_t new_num_faces = num_faces(*this->poly_item->face_graph());
std::size_t new_num_vertices = num_vertices(*this->poly_item->face_graph());
std::size_t new_num_edges = num_edges(*this->poly_item->face_graph());
if(new_num_faces != d->num_faces)
{
selected_facets.clear();
d->num_faces = new_num_faces ;
}
if(new_num_vertices!= d->num_vertices)
{
selected_vertices.clear();
d->num_vertices = new_num_vertices ;
}
if(new_num_edges!= d->num_edges)
{
selected_edges.clear();
d->num_edges = new_num_edges ;
}
invalidateOpenGLBuffers();
redraw();
});
d->manipulated_frame = new ManipulatedFrame();
Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
v->installEventFilter(this);

View File

@ -2259,6 +2259,7 @@ void Scene_surface_mesh_item::computeElements()const
{
d->compute_elements(ALL);
setBuffersFilled(true);
const_cast<Scene_surface_mesh_item*>(this)->itemChanged();
}
void

View File

@ -3,7 +3,7 @@ namespace CGAL {
/*!
\ingroup PkgDrawPolyhedron
Open a new window and draw `apoly`, an instance of the `CGAL::Polyhedron_3` class. The function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
opens a new window and draws `apoly`, an instance of the `CGAL::Polyhedron_3` class. A call to this function is blocking, that is the program continues as soon as the user closes the window. This function requires CGAL_Qt5, and is only available if the flag CGAL_USE_BASIC_VIEWER is defined at compile time.
\tparam POLY an instance of the `CGAL::Polyhedron_3` class.
\param apoly the polyhedron to draw.

View File

@ -5,7 +5,7 @@
/// \defgroup PkgPolyhedronIOFunc I/O Functions
/// \ingroup PkgPolyhedronRef
/*! Draw.
/*!
\code
#include <CGAL/draw_polyhedron.h>
\endcode
@ -73,7 +73,7 @@ surface can be used without knowing the halfedge data structure.
- \link PkgPolyhedronIOFunc `read_off()` \endlink
\cgalCRPSection{Draw a Polyhedron 3}
- `CGAL::draw<POLY>`
- \link PkgDrawPolyhedron CGAL::draw<POLY>() \endlink
*/

View File

@ -278,7 +278,7 @@ are also marked in the program code.
\subsection PolyhedronDraw Draw a Polyhedron
\anchor ssecDrawPolyhedron
A polyhedron can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given polyhedron. The function is blocking, that is the program continues as soon as the user closes the window.
A polyhedron can be visualized by calling the \link PkgDrawPolyhedron CGAL::draw<POLY>() \endlink function as shown in the following example. This function opens a new window showing the given polyhedron. A call to this function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Polyhedron/draw_polyhedron.cpp}

View File

@ -26,6 +26,7 @@
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Random.h>
namespace CGAL
@ -195,16 +196,23 @@ protected:
const ColorFunctor& m_fcolor;
};
template<class Polyhedron, class ColorFunctor>
void draw(const Polyhedron& apoly,
const char* title,
bool nofill,
const ColorFunctor& fcolor)
// Specialization of draw function.
#define CGAL_POLY_TYPE CGAL::Polyhedron_3 \
<PolyhedronTraits_3, PolyhedronItems_3, T_HDS, Alloc>
template<class PolyhedronTraits_3,
class PolyhedronItems_3,
template < class T, class I, class A>
class T_HDS,
class Alloc>
void draw(const CGAL_POLY_TYPE& apoly,
const char* title="Polyhedron Basic Viewer",
bool nofill=false)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=false;
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
@ -212,27 +220,15 @@ void draw(const Polyhedron& apoly,
int argc=1;
const char* argv[2]={"polyhedron_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimplePolyhedronViewerQt<Polyhedron, ColorFunctor>
DefaultColorFunctorPolyhedron fcolor;
SimplePolyhedronViewerQt<CGAL_POLY_TYPE, DefaultColorFunctorPolyhedron>
mainwindow(app.activeWindow(), apoly, title, nofill, fcolor);
mainwindow.show();
app.exec();
}
}
template<class Polyhedron>
void draw(const Polyhedron& apoly, const char* title, bool nofill)
{
DefaultColorFunctorPolyhedron c;
draw(apoly, title, nofill, c);
}
template<class Polyhedron>
void draw(const Polyhedron& apoly, const char* title)
{ draw(apoly, title, false); }
template<class Polyhedron>
void draw(const Polyhedron& apoly)
{ draw(apoly, "Basic Polyhedron Viewer"); }
#undef CGAL_POLY_TYPE
} // End namespace CGAL

View File

@ -1857,9 +1857,11 @@ void test_rebind(const PT& /*traits*/){
typedef CGAL::LEDA_arithmetic_kernel AT;
typedef typename AT::Integer Integer;
typedef typename AT::Rational Rational;
const int dimension = 4;
const int dimension = 4; CGAL_USE(dimension);
typedef typename PT:: template Rebind<Integer,4>::Other PT_Integer_4;
CGAL_USE_TYPE(PT_Integer_4);
typedef typename PT:: template Rebind<Rational,4>::Other PT_Rational_4;
CGAL_USE_TYPE(PT_Rational_4);
CGAL_static_assertion((boost::is_same< typename PT_Integer_4::Innermost_coefficient_type,
Integer>::value));
CGAL_static_assertion((boost::is_same< typename PT_Rational_4::Innermost_coefficient_type,

View File

@ -1,6 +1,6 @@
/// \defgroup PkgSurface_mesh Surface Mesh Reference
/*! Draw.
/*!
\code
#include <CGAL/draw_surface_mesh.h>
\endcode
@ -39,7 +39,8 @@ and faces is much simpler and can be used at runtime and not at compile time.}
- `CGAL::Surface_mesh<P>`
\cgalCRPSection{Draw a Surface Mesh}
- `CGAL::draw<SM>`
- \link PkgDrawSurfaceMesh CGAL::draw<SM>() \endlink
*/

View File

@ -347,7 +347,7 @@ refering to the right vertices.
\section SurfaceMeshDraw Draw a Surface Mesh
\anchor ssecDrawSurfaceMesh
A surface mesh can be visualized by calling the `CGAL::draw()` function as shown in the following example. This function opens a new window showing the given surface mesh. The function is blocking, that is the program continues as soon as the user closes the window.
A surface mesh can be visualized by calling the \link PkgDrawSurfaceMesh CGAL::draw<SM>() \endlink as shown in the following example. This function opens a new window showing the given surface mesh. A call to this function is blocking, that is the program continues as soon as the user closes the window.
\cgalExample{Surface_mesh/draw_surface_mesh.cpp}

View File

@ -38,8 +38,10 @@ if ( CGAL_FOUND )
create_single_source_cgal_program( "sm_properties.cpp" )
create_single_source_cgal_program("draw_surface_mesh.cpp")
create_single_source_cgal_program("sm_draw_small_faces.cpp")
if(CGAL_Qt5_FOUND )
target_link_libraries(draw_surface_mesh PUBLIC CGAL::CGAL_Qt5)
target_link_libraries(sm_draw_small_faces PUBLIC CGAL::CGAL_Qt5)
endif()
else()

View File

@ -10,7 +10,7 @@ typedef CGAL::Surface_mesh<Point> Mesh;
int main(int argc, char* argv[])
{
Mesh sm1;
std::ifstream in1((argc>1)?argv[1]:"data/triangle.off");
std::ifstream in1((argc>1)?argv[1]:"data/elephant.off");
in1 >> sm1;
CGAL::draw(sm1);

View File

@ -0,0 +1,294 @@
// Copyright (c) 2018 GeometryFactory (France)
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org).
// 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 3 of the License, or (at your option) any later version.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $URL$
// $Id$
// SPDX-License-Identifier: GPL-3.0+
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
#ifndef CGAL_DRAW_SURFACE_MESH_SMALL_FACES_H
#define CGAL_DRAW_SURFACE_MESH_SMALL_FACES_H
#include <CGAL/license/Surface_mesh.h>
#include <CGAL/Qt/Basic_viewer_qt.h>
#ifdef CGAL_USE_BASIC_VIEWER
#include <CGAL/Surface_mesh.h>
#include <CGAL/Random.h>
template<class SM>
class SimpleSurfaceMeshWithSmallFacesViewerQt : public CGAL::Basic_viewer_qt
{
typedef CGAL::Basic_viewer_qt Base;
typedef typename SM::Point Point;
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
typedef typename SM::Vertex_index vertex_descriptor;
typedef typename SM::Face_index face_descriptor;
typedef typename SM::Edge_index edge_descriptor;
typedef typename SM::Halfedge_index halfedge_descriptor;
typedef typename Kernel::FT FT;
public:
/// Construct the viewer.
/// @param amesh the surface mesh to view
SimpleSurfaceMeshWithSmallFacesViewerQt(QWidget* parent,
SM& amesh) :
// First draw: no vertex; no edge, faces; multi-color; inverse normal
Base(parent, "Surface mesh viewer with small faces", false, false, true, false, false),
sm(amesh),
m_threshold(85),
m_draw_small_faces(true),
m_draw_big_faces(true)
{
// Add custom key description (see keyPressEvent).
setKeyDescription(Qt::Key_I, "Increment threshold for small faces");
setKeyDescription(Qt::Key_D, "Decrement threshold for small faces");
setKeyDescription(Qt::Key_S, "Draw small faces only , big faces only, both");
if (sm.faces().begin()!=sm.faces().end())
{
bool exist;
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, exist)=sm.template property_map<face_descriptor, FT>("f:size");
CGAL_assertion(exist);
m_min_size=faces_size[*(sm.faces().begin())];
m_max_size=m_min_size;
FT cur_size;
for (typename SM::Face_range::iterator f=sm.faces().begin(); f!=sm.faces().end(); ++f)
{
cur_size=faces_size[*f];
if (cur_size<m_min_size) m_min_size=cur_size;
if (cur_size>m_max_size) m_max_size=cur_size;
}
}
compute_elements();
}
protected:
void compute_face(face_descriptor fh)
{
// [Face creation]
bool issmall=false;
// Default color of faces
CGAL::Color c(75,160,255);
// Compare the size of the face with the % m_threshold
bool exist;
typename SM::template Property_map<face_descriptor, FT> faces_size;
boost::tie(faces_size, exist)=sm.template property_map<face_descriptor, FT>("f:size");
CGAL_assertion(exist);
// It it is smaller, color the face in red.
if (get(faces_size, fh)<m_min_size+((m_max_size-m_min_size)/(100-m_threshold)))
{
c=CGAL::Color(255,20,20);
issmall=true;
}
if ((issmall && !m_draw_small_faces) || (!issmall && !m_draw_big_faces))
{ return; }
// Add the color of the face, then all its points.
face_begin(c);
halfedge_descriptor hd=sm.halfedge(fh);
do
{
add_point_in_face(sm.point(sm.source(hd)), get_vertex_normal(hd));
hd=sm.next(hd);
}
while(hd!=sm.halfedge(fh));
face_end();
/// [Face creation]
}
// Copy from draw_surface_mesh.h
void compute_edge(edge_descriptor e)
{
/// [Edge creation]
add_segment(sm.point(sm.source(sm.halfedge(e))),
sm.point(sm.target(sm.halfedge(e))));
/// [Edge creation]
}
void compute_vertex(vertex_descriptor vh)
{
/// [Vertex creation]
add_point(sm.point(vh));
/// [Vertex creation]
}
void compute_elements()
{
clear();
for (typename SM::Face_range::iterator f=sm.faces().begin();
f!=sm.faces().end(); ++f)
{
if (*f!=boost::graph_traits<SM>::null_face())
{ compute_face(*f); }
}
for (typename SM::Edge_range::iterator e=sm.edges().begin();
e!=sm.edges().end(); ++e)
{ compute_edge(*e); }
for (typename SM::Vertex_range::iterator v=sm.vertices().begin();
v!=sm.vertices().end(); ++v)
{ compute_vertex(*v); }
}
// Call: * compute_elements() if the model changed, followed by
// * redraw() if some viewing parameters changed that implies some
// modifications of the buffers
// (eg. type of normal, color/mono)
// * update() just to update the drawing
virtual void keyPressEvent(QKeyEvent *e)
{
/// [Keypress]
const ::Qt::KeyboardModifiers modifiers = e->modifiers();
if ((e->key()==Qt::Key_I) && (modifiers==Qt::NoButton))
{
if (m_threshold<100) { ++m_threshold; }
displayMessage(QString("Threshold percent=%1%.").arg(m_threshold));
compute_elements();
redraw();
}
else if ((e->key()==Qt::Key_D) && (modifiers==Qt::NoButton))
{
if (m_threshold>0) { --m_threshold; }
displayMessage(QString("Threshold percent=%1%.").arg(m_threshold));
compute_elements();
redraw();
}
else if ((e->key()==Qt::Key_S) && (modifiers==Qt::NoButton))
{
QString msg;
if (m_draw_small_faces)
{
if (m_draw_big_faces)
{
m_draw_big_faces=false;
msg=QString("Draw small faces only.");
}
else
{
m_draw_big_faces=true; m_draw_small_faces=false;
msg=QString("Draw big faces only.");
}
}
else
{
assert(m_draw_big_faces);
m_draw_small_faces=true;
msg=QString("Draw small and big faces.");
}
displayMessage(msg);
compute_elements();
redraw();
}
else
{
// Call the base method to process others/classicals key
Base::keyPressEvent(e);
}
/// [Keypress]
}
protected:
typename Kernel::Vector_3 get_face_normal(halfedge_descriptor he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
halfedge_descriptor end=he;
unsigned int nb=0;
do
{
CGAL::internal::newell_single_step_3(sm.point(sm.source(he)),
sm.point(sm.target(he)), normal);
++nb;
he=sm.next(he);
}
while (he!=end);
assert(nb>0);
return (typename Kernel::Construct_scaled_vector_3()(normal, 1.0/nb));
}
typename Kernel::Vector_3 get_vertex_normal(halfedge_descriptor he)
{
typename Kernel::Vector_3 normal=CGAL::NULL_VECTOR;
halfedge_descriptor end=he;
do
{
if (!sm.is_border(he))
{
typename Kernel::Vector_3 n=get_face_normal(he);
normal=typename Kernel::Construct_sum_of_vectors_3()(normal, n);
}
he=sm.next(sm.opposite(he));
}
while (he!=end);
if (!typename Kernel::Equal_3()(normal, CGAL::NULL_VECTOR))
{ normal=(typename Kernel::Construct_scaled_vector_3()
(normal, 1.0/CGAL::sqrt(normal.squared_length()))); }
return normal;
}
protected:
SM& sm;
unsigned int m_threshold;
FT m_min_size, m_max_size;
bool m_draw_small_faces;
bool m_draw_big_faces;
};
template<class K>
void draw_surface_mesh_with_small_faces(CGAL::Surface_mesh<K>& amesh)
{
#if defined(CGAL_TEST_SUITE)
bool cgal_test_suite=true;
#else
bool cgal_test_suite=qEnvironmentVariableIsSet("CGAL_TEST_SUITE");
#endif
if (!cgal_test_suite)
{
int argc=1;
const char* argv[2]={"surface_mesh_viewer","\0"};
QApplication app(argc,const_cast<char**>(argv));
SimpleSurfaceMeshWithSmallFacesViewerQt<CGAL::Surface_mesh<K>>
mainwindow(app.activeWindow(), amesh);
mainwindow.show();
app.exec();
}
}
#else // CGAL_USE_BASIC_VIEWER
template<class K>
void draw_surface_mesh_with_small_faces(CGAL::Surface_mesh<K>&)
{
std::cerr<<"Impossible to draw, CGAL_USE_BASIC_VIEWER is not defined."<<std::endl;
}
#endif // CGAL_USE_BASIC_VIEWER
#endif // CGAL_DRAW_SURFACE_MESH_SMALL_FACES_H

Some files were not shown because too many files have changed in this diff Show More