00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <iostream>
00011 #include "../road/RoadTest.h"
00012
00013 #include "Qhull.h"
00014 #include "QhullError.h"
00015 #include "RboxPoints.h"
00016 #include "QhullFacetList.h"
00017
00018 using std::cout;
00019 using std::endl;
00020 using std::string;
00021
00022 namespace orgQhull {
00023
00026 class Qhull_test : public RoadTest
00027 {
00028 Q_OBJECT
00029
00030 #//Test slots
00031 private slots:
00032 void cleanup();
00033 void t_construct();
00034 void t_attribute();
00035 void t_message();
00036 void t_getSet();
00037 void t_getQh();
00038 void t_getValue();
00039 void t_foreach();
00040 void t_modify();
00041 };
00042
00043 void
00044 add_Qhull_test()
00045 {
00046 new Qhull_test();
00047 }
00048
00049
00050 void Qhull_test::
00051 cleanup()
00052 {
00053 UsingLibQhull::checkQhullMemoryEmpty();
00054 RoadTest::cleanup();
00055 }
00056
00057 void Qhull_test::
00058 t_construct()
00059 {
00060 {
00061 Qhull q;
00062 QCOMPARE(q.dimension(),0);
00063 QVERIFY(q.qhullQh()!=0);
00064 QVERIFY(q.runId()!=0);
00065 QCOMPARE(QString(q.qhullCommand()),QString(""));
00066 QCOMPARE(QString(q.rboxCommand()),QString(""));
00067 try{
00068 QCOMPARE(q.area(),0.0);
00069 QFAIL("area() did not fail.");
00070 }catch (const std::exception &e) {
00071 cout << "INFO : Caught " << e.what();
00072 }
00073 Qhull q2(q);
00074 QCOMPARE(q2.dimension(),0);
00075 q= q2;
00076 QCOMPARE(q.dimension(),0);
00077 }
00078 {
00079 RboxPoints rbox("10000");
00080 Qhull q(rbox, "QR0");
00081 QCOMPARE(q.dimension(),3);
00082 QVERIFY(q.volume() < 1.0);
00083 QVERIFY(q.volume() > 0.99);
00084 try{
00085 Qhull q2(q);
00086 QFAIL("Copy constructor did not fail for initialized Qhull.");
00087 }catch (const std::exception &e) {
00088 cout << "INFO : Caught " << e.what();
00089 }
00090 try{
00091 Qhull q3;
00092 q3= q;
00093 QFAIL("Copy assignment did not fail for initialized Qhull source.");
00094 }catch (const std::exception &e) {
00095 cout << "INFO : Caught " << e.what();
00096 }
00097 QCOMPARE(q.dimension(),3);
00098 try{
00099 Qhull q4;
00100 q= q4;
00101 QFAIL("Copy assignment did not fail for initialized Qhull destination.");
00102 }catch (const std::exception &e) {
00103 cout << "INFO : Caught " << e.what();
00104 }
00105 QCOMPARE(q.dimension(),3);
00106 }
00107 {
00108 double points[] = {
00109 0, 0,
00110 1, 0,
00111 1, 1
00112 };
00113 Qhull q("triangle", 2, 3, points, "");
00114 QCOMPARE(q.dimension(),2);
00115 QCOMPARE(q.facetCount(),3);
00116 QCOMPARE(q.vertexCount(),3);
00117 QCOMPARE(q.dimension(),2);
00118 QCOMPARE(q.area(), 2.0+sqrt(2.0));
00119 QCOMPARE(q.volume(), 0.5);
00120 }
00121 }
00122
00123 void Qhull_test::
00124 t_attribute()
00125 {
00126 RboxPoints rcube("c");
00127 {
00128 double normals[] = {
00129 0, -1, -0.5,
00130 -1, 0, -0.5,
00131 1, 0, -0.5,
00132 0, 1, -0.5
00133 };
00134 Qhull q;
00135 q.feasiblePoint << 0.0 << 0.0;
00136 Coordinates c(std::vector<double>(2, 0.0));
00137 QVERIFY(q.feasiblePoint==c);
00138 q.setOutputStream(&cout);
00139 q.runQhull("normals of square", 3, 4, normals, "H");
00140 QCOMPARE(q.facetList().count(), 4);
00141 cout << "Expecting summary of halfspace intersect\n";
00142 q.outputQhull();
00143 q.useOutputStream= false;
00144 cout << "Expecting no output from qh_fprintf() in Qhull.cpp\n";
00145 q.outputQhull();
00146 }
00147 }
00148
00150 void Qhull_test::
00151 t_message()
00152 {
00153 RboxPoints rcube("c");
00154 {
00155 Qhull q;
00156 QCOMPARE(q.qhullMessage(), string(""));
00157 QCOMPARE(q.qhullStatus(), qh_ERRnone);
00158 QVERIFY(!q.hasQhullMessage());
00159 try{
00160 q.runQhull(rcube, "Fd");
00161 QFAIL("runQhull Fd did not fail.");
00162 }catch (const std::exception &e) {
00163 const char *s= e.what();
00164 cout << "INFO : Caught " << s;
00165 QCOMPARE(QString::fromStdString(s).left(6), QString("QH6029"));
00166
00167 QVERIFY(!q.hasQhullMessage());
00168
00169
00170 q.clearQhullMessage();
00171 QVERIFY(!q.hasQhullMessage());
00172 }
00173 q.appendQhullMessage("Append 1");
00174 QVERIFY(q.hasQhullMessage());
00175 QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1"));
00176 q.appendQhullMessage("\nAppend 2\n");
00177 QCOMPARE(QString::fromStdString(q.qhullMessage()), QString("Append 1\nAppend 2\n"));
00178 q.clearQhullMessage();
00179 QVERIFY(!q.hasQhullMessage());
00180 QCOMPARE(QString::fromStdString(q.qhullMessage()), QString(""));
00181 }
00182 {
00183 cout << "INFO : Error stream without output stream\n";
00184 Qhull q;
00185 q.setErrorStream(&cout);
00186 q.setOutputStream(0);
00187 try{
00188 q.runQhull(rcube, "Fd");
00189 QFAIL("runQhull Fd did not fail.");
00190 }catch (const QhullError &e) {
00191 cout << "INFO : Caught " << e;
00192 QCOMPARE(e.errorCode(), 6029);
00193 }
00194
00195
00196
00197 q.clearQhullMessage();
00198 QVERIFY(!q.hasQhullMessage());
00199 }
00200 {
00201 cout << "INFO : Error output sent to output stream without error stream\n";
00202 Qhull q;
00203 q.setErrorStream(0);
00204 q.setOutputStream(&cout);
00205 try{
00206 q.runQhull(rcube, "Tz H0");
00207 QFAIL("runQhull TZ did not fail.");
00208 }catch (const std::exception &e) {
00209 const char *s= e.what();
00210 cout << "INFO : Caught " << s;
00211 QCOMPARE(QString::fromAscii(s).left(6), QString("QH6023"));
00212 }
00213
00214
00215
00216
00217 q.clearQhullMessage();
00218 QVERIFY(!q.hasQhullMessage());
00219 }
00220 {
00221 cout << "INFO : No error stream or output stream\n";
00222 Qhull q;
00223 q.setErrorStream(0);
00224 q.setOutputStream(0);
00225 try{
00226 q.runQhull(rcube, "Fd");
00227 QFAIL("outputQhull did not fail.");
00228 }catch (const std::exception &e) {
00229 const char *s= e.what();
00230 cout << "INFO : Caught " << s;
00231 QCOMPARE(QString::fromAscii(s).left(6), QString("QH6029"));
00232 }
00233
00234
00235
00236
00237 q.clearQhullMessage();
00238 QVERIFY(!q.hasQhullMessage());
00239 }
00240 }
00241
00242 void Qhull_test::
00243 t_getSet()
00244 {
00245 RboxPoints rcube("c");
00246 {
00247 Qhull q;
00248 QVERIFY(!q.initialized());
00249 q.runQhull(rcube, "s");
00250 QVERIFY(q.initialized());
00251 QCOMPARE(q.dimension(), 3);
00252 QhullPoint p= q.origin();
00253 QCOMPARE(p.dimension(), 3);
00254 QCOMPARE(p[0]+p[1]+p[2], 0.0);
00255 QVERIFY(q.runId()!=0);
00256 q.setErrorStream(&cout);
00257 q.outputQhull();
00258 }
00259 {
00260 Qhull q;
00261 q.runQhull(rcube, "");
00262 q.setOutputStream(&cout);
00263 q.outputQhull();
00264 }
00265
00266
00267 }
00268
00269 void Qhull_test::
00270 t_getQh()
00271 {
00272 RboxPoints rcube("c");
00273 {
00274 Qhull q;
00275 q.runQhull(rcube, "s");
00276 QCOMPARE(QString(q.qhullCommand()), QString("qhull s"));
00277 QCOMPARE(QString(q.rboxCommand()), QString("rbox \"c\""));
00278 QCOMPARE(q.facetCount(), 6);
00279 QCOMPARE(q.vertexCount(), 8);
00280
00281 QCOMPARE(q.qhullQh()->ALLpoints, 0u);
00282 QCOMPARE(q.qhullQh()->GOODpoint, 0);
00283 QCOMPARE(q.qhullQh()->IStracing, 0);
00284 QCOMPARE(q.qhullQh()->MAXcoplanar+1.0, 1.0);
00285 QCOMPARE(q.qhullQh()->MERGING, 1u);
00286 QCOMPARE(q.qhullQh()->input_dim, 3);
00287 QCOMPARE(QString(q.qhullQh()->qhull_options).left(8), QString(" run-id"));
00288 QCOMPARE(q.qhullQh()->run_id, q.runId());
00289 QCOMPARE(q.qhullQh()->num_facets, 6);
00290 QCOMPARE(q.qhullQh()->hasTriangulation, 0u);
00291 QCOMPARE(q.qhullQh()->max_outside - q.qhullQh()->min_vertex + 1.0, 1.0);
00292 QCOMPARE(*q.qhullQh()->gm_matrix+1.0, 1.0);
00293 }
00294 }
00295
00296 void Qhull_test::
00297 t_getValue()
00298 {
00299 RboxPoints rcube("c");
00300 {
00301 Qhull q;
00302 q.runQhull(rcube, "");
00303 QCOMPARE(q.area(), 6.0);
00304 QCOMPARE(q.volume(), 1.0);
00305 }
00306 }
00307
00308 void Qhull_test::
00309 t_foreach()
00310 {
00311 RboxPoints rcube("c");
00312 {
00313 Qhull q;
00314 QCOMPARE(q.beginFacet(),q.endFacet());
00315 QCOMPARE(q.beginVertex(),q.endVertex());
00316 q.runQhull(rcube, "");
00317 QCOMPARE(q.facetList().count(), 6);
00318
00319
00320
00321 QhullFacetList facets(q.beginFacet(), q.endFacet());
00322 QCOMPARE(facets.count(), 6);
00323 QCOMPARE(q.firstFacet(), q.beginFacet());
00324 QhullVertexList vertices(q.beginVertex(), q.endVertex());
00325 QCOMPARE(vertices.count(), 8);
00326 QCOMPARE(q.firstVertex(), q.beginVertex());
00327 QhullPoints ps= q.points();
00328 QCOMPARE(ps.count(), 8);
00329 QhullPointSet ps2= q.otherPoints();
00330 QCOMPARE(ps2.count(), 0);
00331
00332 QCOMPARE(q.facetCount(), 6);
00333 QCOMPARE(q.vertexCount(), 8);
00334 coordT *c= q.pointCoordinateBegin();
00335 QVERIFY(*c==0.5 || *c==-0.5);
00336 coordT *c3= q.pointCoordinateEnd();
00337 QVERIFY(c3[-1]==0.5 || c3[-1]==-0.5);
00338 QCOMPARE(c3-c, 8*3);
00339 QCOMPARE(q.vertexList().count(), 8);
00340 }
00341 }
00342
00343 void Qhull_test::
00344 t_modify()
00345 {
00346
00347 RboxPoints diamond("d");
00348 Qhull q(diamond, "o");
00349 q.setOutputStream(&cout);
00350 cout << "Expecting vertexList and facetList of a 3-d diamond.\n";
00351 q.outputQhull();
00352 cout << "Expecting normals of a 3-d diamond.\n";
00353 q.outputQhull("n");
00354
00355 }
00356
00357 }
00358
00359
00360 void qh_exit(int exitcode) {
00361 cout << "FAIL! : Qhull called qh_exit(). Qhull's error handling not available.\n.. See the corresponding Qhull:qhull_message or setErrorStream().\n";
00362 exit(exitcode);
00363 }
00364 void qh_free(void *mem) {
00365 free(mem);
00366 }
00367 void *qh_malloc(size_t size) {
00368 return malloc(size);
00369 }
00370
00371 #if 0
00372 template<> char * QTest::
00373 toString(const std::string &s)
00374 {
00375 QByteArray ba = s.c_str();
00376 return qstrdup(ba.data());
00377 }
00378 #endif
00379
00380 #include "moc/Qhull_test.moc"