comparison src/dldfcn/__delaunayn__.cc @ 15076:000587f92082

rename src/DLD-FUNCTIONS directory to src/dldfcn * src/dldfcn: Rename from src/DLD-FUNCTIONS. * autogen.sh, src/Makefile.am, src/dldfcn/config-module.awk, src/dldfcn/config-module.sh: Change all uses of DLD-FUNCTIONS to be dldfcn. Change all uses of DLD_FUNCTIONS to be DLDFCN.
author John W. Eaton <jwe@octave.org>
date Tue, 31 Jul 2012 21:57:58 -0400
parents src/DLD-FUNCTIONS/__delaunayn__.cc@460a3c6d8bf1
children
comparison
equal deleted inserted replaced
15075:b62b0b85369c 15076:000587f92082
1 /*
2
3 Copyright (C) 2000-2012 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 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 #include <iostream>
46 #include <string>
47
48 #include "Cell.h"
49 #include "defun-dld.h"
50 #include "error.h"
51 #include "oct-obj.h"
52 #include "unwind-prot.h"
53
54 #if defined (HAVE_QHULL)
55 # include "oct-qhull.h"
56 # if defined (NEED_QHULL_VERSION)
57 char qh_version[] = "__delaunayn__.oct 2007-08-21";
58 # endif
59 #endif
60
61 static void
62 close_fcn (FILE *f)
63 {
64 gnulib::fclose (f);
65 }
66
67 DEFUN_DLD (__delaunayn__, args, ,
68 "-*- texinfo -*-\n\
69 @deftypefn {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts})\n\
70 @deftypefnx {Loadable Function} {@var{T} =} __delaunayn__ (@var{pts}, @var{options})\n\
71 Undocumented internal function.\n\
72 @end deftypefn")
73
74 {
75 octave_value_list retval;
76
77 #if defined (HAVE_QHULL)
78
79 retval(0) = 0.0;
80
81 int nargin = args.length ();
82 if (nargin < 1 || nargin > 2)
83 {
84 print_usage ();
85 return retval;
86 }
87
88 Matrix p (args(0).matrix_value ());
89 const octave_idx_type dim = p.columns ();
90 const octave_idx_type n = p.rows ();
91
92 // Default options
93 std::string options;
94 if (dim <= 3)
95 options = "Qt Qbb Qc Qz";
96 else
97 options = "Qt Qbb Qc Qx";
98
99 if (nargin == 2)
100 {
101 if (args(1).is_string ())
102 options = args(1).string_value ();
103 else if (args(1).is_empty ())
104 ; // Use default options
105 else if (args(1).is_cellstr ())
106 {
107 options = "";
108 Array<std::string> tmp = args(1).cellstr_value ();
109
110 for (octave_idx_type i = 0; i < tmp.numel (); i++)
111 options += tmp(i) + " ";
112 }
113 else
114 {
115 error ("__delaunayn__: OPTIONS argument must be a string, cell array of strings, or empty");
116 return retval;
117 }
118 }
119
120 if (n > dim + 1)
121 {
122 p = p.transpose ();
123 double *pt_array = p.fortran_vec ();
124 boolT ismalloc = false;
125
126 // Qhull flags argument is not const char*
127 OCTAVE_LOCAL_BUFFER (char, flags, 9 + options.length ());
128
129 sprintf (flags, "qhull d %s", options.c_str ());
130
131 unwind_protect frame;
132
133 // Replace the outfile pointer with stdout for debugging information.
134 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
135 FILE *outfile = gnulib::fopen ("NUL", "w");
136 #else
137 FILE *outfile = gnulib::fopen ("/dev/null", "w");
138 #endif
139 FILE *errfile = stderr;
140
141 if (outfile)
142 frame.add_fcn (close_fcn, outfile);
143 else
144 {
145 error ("__delaunayn__: unable to create temporary file for output");
146 return retval;
147 }
148
149 int exitcode = qh_new_qhull (dim, n, pt_array,
150 ismalloc, flags, outfile, errfile);
151 if (! exitcode)
152 {
153 // triangulate non-simplicial facets
154 qh_triangulate ();
155
156 facetT *facet;
157 vertexT *vertex, **vertexp;
158 octave_idx_type nf = 0, i = 0;
159
160 FORALLfacets
161 {
162 if (! facet->upperdelaunay)
163 nf++;
164
165 // Double check. Non-simplicial facets will cause segfault below
166 if (! facet->simplicial)
167 {
168 error ("__delaunayn__: Qhull returned non-simplicial facets -- try delaunayn with different options");
169 exitcode = 1;
170 break;
171 }
172 }
173
174 if (! exitcode)
175 {
176 Matrix simpl (nf, dim+1);
177
178 FORALLfacets
179 {
180 if (! facet->upperdelaunay)
181 {
182 octave_idx_type j = 0;
183
184 FOREACHvertex_ (facet->vertices)
185 {
186 simpl(i, j++) = 1 + qh_pointid(vertex->point);
187 }
188 i++;
189 }
190 }
191
192 retval(0) = simpl;
193 }
194 }
195 else
196 error ("__delaunayn__: qhull failed");
197
198 // Free memory from Qhull
199 qh_freeqhull (! qh_ALL);
200
201 int curlong, totlong;
202 qh_memfreeshort (&curlong, &totlong);
203
204 if (curlong || totlong)
205 warning ("__delaunay__: did not free %d bytes of long memory (%d pieces)",
206 totlong, curlong);
207 }
208 else if (n == dim + 1)
209 {
210 // one should check if nx points span a simplex
211 // I will look at this later.
212 RowVector vec (n);
213 for (octave_idx_type i = 0; i < n; i++)
214 vec(i) = i + 1.0;
215
216 retval(0) = vec;
217 }
218
219 #else
220 error ("__delaunayn__: not available in this version of Octave");
221 #endif
222
223 return retval;
224 }
225
226 /*
227 ## No test needed for internal helper function.
228 %!assert (1)
229 */