GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
__delaunayn__.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2000-2017 Kai Habel
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 /*
24  16. July 2000 - Kai Habel: first release
25 
26  25. September 2002 - Changes by Rafael Laboissiere <rafael@laboissiere.net>
27 
28  * Added Qbb option to normalize the input and avoid crashes in Octave.
29  * delaunayn accepts now a second (optional) argument that must be a string
30  containing extra options to the qhull command.
31  * Fixed doc string. The dimension of the result matrix is [m, dim+1], and
32  not [n, dim-1].
33 
34  6. June 2006: Changes by Alexander Barth <abarth@marine.usf.edu>
35 
36  * triangulate non-simplicial facets
37  * allow options to be specified as cell array of strings
38  * change the default options (for compatibility with matlab)
39 */
40 
41 #if defined (HAVE_CONFIG_H)
42 # include "config.h"
43 #endif
44 
45 #include <iostream>
46 #include <string>
47 
48 #include "oct-locbuf.h"
49 
50 #include "Cell.h"
51 #include "defun-dld.h"
52 #include "error.h"
53 #include "errwarn.h"
54 #include "ovl.h"
55 #include "unwind-prot.h"
56 
57 #if defined (HAVE_QHULL)
58 
59 # include "oct-qhull.h"
60 
61 # if defined (NEED_QHULL_VERSION)
62 char qh_version[] = "__delaunayn__.oct 2007-08-21";
63 # endif
64 
65 static void
66 close_fcn (FILE *f)
67 {
68  std::fclose (f);
69 }
70 
71 static bool
73 {
74  if (sizeof (octave_idx_type) > sizeof (int))
75  {
76  int maxval = std::numeric_limits<int>::max ();
77 
78  if (dim > maxval || n > maxval)
79  error ("%s: dimension too large for Qhull", who);
80  }
81 
82  return true;
83 }
84 
85 #endif
86 
87 DEFUN_DLD (__delaunayn__, args, ,
88  doc: /* -*- texinfo -*-
89 @deftypefn {} {@var{T} =} __delaunayn__ (@var{pts})
90 @deftypefnx {} {@var{T} =} __delaunayn__ (@var{pts}, @var{options})
91 Undocumented internal function.
92 @end deftypefn */)
93 
94 {
95 #if defined (HAVE_QHULL)
96 
97  int nargin = args.length ();
98 
99  if (nargin < 1 || nargin > 2)
100  print_usage ();
101 
103 
104  retval(0) = 0.0;
105 
106  Matrix p (args(0).matrix_value ());
107  const octave_idx_type dim = p.columns ();
108  const octave_idx_type n = p.rows ();
109 
110  if (! octave_qhull_dims_ok (dim, n, "__delaynayn__"))
111  return retval;
112 
113  // Default options
115  if (dim <= 3)
116  options = "Qt Qbb Qc Qz";
117  else
118  options = "Qt Qbb Qc Qx";
119 
120  if (nargin == 2)
121  {
122  if (args(1).is_string ())
123  options = args(1).string_value ();
124  else if (args(1).is_empty ())
125  ; // Use default options
126  else if (args(1).is_cellstr ())
127  {
128  options = "";
129  Array<std::string> tmp = args(1).cellstr_value ();
130 
131  for (octave_idx_type i = 0; i < tmp.numel (); i++)
132  options += tmp(i) + " ";
133  }
134  else
135  error ("__delaunayn__: OPTIONS argument must be a string, cell array of strings, or empty");
136  }
137 
138  if (n > dim + 1)
139  {
140  p = p.transpose ();
141  double *pt_array = p.fortran_vec ();
142  boolT ismalloc = false;
143 
144  // Qhull flags argument is not const char*
145  OCTAVE_LOCAL_BUFFER (char, flags, 9 + options.length ());
146 
147  sprintf (flags, "qhull d %s", options.c_str ());
148 
150 
151  // Replace the outfile pointer with stdout for debugging information.
152 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
153  FILE *outfile = std::fopen ("NUL", "w");
154 #else
155  FILE *outfile = std::fopen ("/dev/null", "w");
156 #endif
157  FILE *errfile = stderr;
158 
159  if (! outfile)
160  error ("__delaunayn__: unable to create temporary file for output");
161 
162  frame.add_fcn (close_fcn, outfile);
163 
164  int exitcode = qh_new_qhull (dim, n, pt_array,
165  ismalloc, flags, outfile, errfile);
166  if (exitcode)
167  error ("__delaunayn__: qhull failed");
168 
169  // triangulate non-simplicial facets
170  qh_triangulate ();
171 
172  facetT *facet;
173  vertexT *vertex, **vertexp;
174  octave_idx_type nf = 0;
175  octave_idx_type i = 0;
176 
177  FORALLfacets
178  {
179  if (! facet->upperdelaunay)
180  nf++;
181 
182  // Double check. Non-simplicial facets will cause segfault below
183  if (! facet->simplicial)
184  error ("__delaunayn__: Qhull returned non-simplicial facets -- try delaunayn with different options");
185  }
186 
187  if (! exitcode)
188  {
189  Matrix simpl (nf, dim+1);
190 
191  FORALLfacets
192  {
193  if (! facet->upperdelaunay)
194  {
195  octave_idx_type j = 0;
196 
197  FOREACHvertex_ (facet->vertices)
198  {
199  simpl(i, j++) = 1 + qh_pointid(vertex->point);
200  }
201  i++;
202  }
203  }
204 
205  retval(0) = simpl;
206  }
207 
208  // Free memory from Qhull
209  qh_freeqhull (! qh_ALL);
210 
211  int curlong, totlong;
212  qh_memfreeshort (&curlong, &totlong);
213 
214  if (curlong || totlong)
215  warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
216  totlong, curlong);
217  }
218  else if (n == dim + 1)
219  {
220  // one should check if nx points span a simplex
221  // I will look at this later.
222  RowVector vec (n);
223  for (octave_idx_type i = 0; i < n; i++)
224  vec(i) = i + 1.0;
225 
226  retval(0) = vec;
227  }
228 
229  return retval;
230 
231 #else
232 
233  octave_unused_parameter (args);
234 
235  err_disabled_feature ("__delaunayn__", "Qhull");
236 
237 #endif
238 }
239 
240 /*
241 ## No test needed for internal helper function.
242 %!assert (1)
243 */
OCTINTERP_API void print_usage(void)
Definition: defun.cc:52
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_REAL const F77_REAL F77_REAL &F77_RET_T const F77_DBLE const F77_DBLE F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T F77_DBLE &F77_RET_T F77_REAL &F77_RET_T F77_REAL &F77_RET_T F77_DBLE &F77_RET_T const F77_DBLE F77_DBLE &F77_RET_T const F77_REAL F77_REAL &F77_RET_T F77_REAL F77_REAL &F77_RET_T F77_DBLE F77_DBLE &F77_RET_T const F77_DBLE const F77_DBLE * f
fclose(in)
void error(const char *fmt,...)
Definition: error.cc:570
octave_idx_type rows(void) const
Definition: Array.h:401
JNIEnv void * args
Definition: ov-java.cc:67
static void close_fcn(FILE *f)
int nargin
Definition: graphics.cc:10115
double tmp
Definition: data.cc:6300
octave_value retval
Definition: data.cc:6294
Matrix transpose(void) const
Definition: dMatrix.h:129
Definition: dMatrix.h:37
void warning(const char *fmt,...)
Definition: error.cc:788
octave::unwind_protect frame
Definition: graphics.cc:11584
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:228
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
p
Definition: lu.cc:138
OCTAVE_EXPORT octave_value_list only variables visible in the local scope are displayed The following are valid options
Definition: variables.cc:1859
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition: oct-locbuf.h:200
static bool octave_qhull_dims_ok(octave_idx_type dim, octave_idx_type n, const char *who)
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Definition: defun-dld.h:45
const T * fortran_vec(void) const
Definition: Array.h:584
void err_disabled_feature(const std::string &fcn, const std::string &feature, const std::string &pkg)
Definition: errwarn.cc:50
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
octave_idx_type columns(void) const
Definition: Array.h:410