PrimitivesGenerator.cc 44.1 KB
Newer Older
1 2 3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
39 40 41 42
*                                                                            *
\*===========================================================================*/


43 44
#include <cstdlib>

45
#include "PrimitivesGenerator.hh"
46
#include <OpenFlipper/BasePlugin/WhatsThisGenerator.hh>
47

48
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
49 50
#include "TetrahedralCuboidGenerator.hh"
#endif
51

52 53 54 55
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
#include <ObjectTypes/HexahedralMesh/HexahedralMesh.hh>
#endif

56 57 58 59
#ifdef ENABLE_BSPLINECURVE_SUPPORT
#include <ObjectTypes/BSplineCurve/BSplineCurve.hh>
#endif

60 61 62 63
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
#include <ObjectTypes/BSplineSurface/BSplineSurface.hh>
#endif

Jan Möbius's avatar
Jan Möbius committed
64 65
PrimitivesGeneratorPlugin::PrimitivesGeneratorPlugin() :
        triMesh_(0),
66 67
        polyMesh_(0),
        slices_(50),
68 69
        stacks_(50),
        primitivesMenu_(0)
Jan Möbius's avatar
Jan Möbius committed
70 71 72 73 74 75 76
{

}

PrimitivesGeneratorPlugin::~PrimitivesGeneratorPlugin()
{

77 78 79 80
  if ( OpenFlipper::Options::gui()) {
    delete primitivesMenu_;
  }

Jan Möbius's avatar
Jan Möbius committed
81 82
}

83 84
void PrimitivesGeneratorPlugin::initializePlugin()
{
85 86 87 88 89
  emit setSlotDescription("addCube(Vector,double)",
                          tr("Generates a poly mesh of cube (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

90
  emit setSlotDescription("addTetrahedron(Vector,double)",
91 92 93 94
                          tr("Generates a tetrahedron (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

95
  emit setSlotDescription("addIcosahedron(Vector,double)",
96 97 98 99
                          tr("Generates an icosahedron (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

100
  emit setSlotDescription("addPyramid(Vector,double)",
101 102 103 104
                          tr("Generates a pyramid (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

105
  emit setSlotDescription("addOctahedron(Vector,double)",
106 107 108 109
                          tr("Generates an octahedron (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

110
  emit setSlotDescription("addDodecahedron(Vector,double)",
111 112 113 114
                          tr("Generates a dodecahedron (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

115 116
  emit setSlotDescription("addSphere(Vector,double)",
                          tr("Generates a triangulated sphere with all vertical lines connected to the poles (ObjectId is returned)"),
117 118 119
                          QString("Position, Radius").split(","),
                          QString("Center position,Radius").split(","));

120 121 122 123 124 125
  emit setSlotDescription("addSubdivisionSphere(Vector,double)",
                          tr("Generates a triangulated sphere by subdivision without poles. (ObjectId is returned)"),
                          QString("Position, Radius").split(","),
                          QString("Center position,Radius").split(","));

  emit setSlotDescription("addTriangulatedCube(Vector,double)",
126
                          tr("Generates a triangular mesh of cube (ObjectId is returned)"),
127 128 129
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

130 131
  emit setSlotDescription("addTriangulatedCylinder(Vector,Vector,double,double)",
                          tr("Generates a triangulated cylinder (ObjectId is returned)")  ,
132
                          QString("Position,Axis,Radius,Height,Top,Bottom").split(","),
133
                          QString("Bottom center vertex position,Center axis,radius,height,add top vertex,add bottom vertex").split(","));
134

135 136 137 138 139 140 141
#ifdef ENABLE_BSPLINECURVE_SUPPORT
  emit setSlotDescription("addRandomBSplineCurve(Vector,int)",
    tr("Generates a random B-spline curve (ObjectId is returned)"),
    QString("Position,Count").split(","),
    QString("Center position,Number of control points").split(","));
#endif

142 143 144 145 146 147 148
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
  emit setSlotDescription("addRandomBSplineSurface(Vector,int)",
                          tr("Generates a random B-spline surface (ObjectId is returned)"),
                          QString("Position,Count").split(","),
                          QString("Center position,Number of control points").split(","));
#endif

149
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
150 151 152 153 154 155 156 157 158 159
  emit setSlotDescription("addTetrahedralCube(Vector,double)",
                          tr("Generates a tetrahedral mesh of a cube (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));

  emit setSlotDescription("addTetrahedralCuboid(Vector,Vector,uint,uint,uint)",
                          tr("Generates a tetrahedral mesh of a cuboid (ObjectId is returned)"),
                          QString("Position,Lengths,Count,Count,Count").split(","),
                          QString("Center position,Length of each side,Number of units in x-axis,Number of units in y-axis,Number of units in z-axis").split(","));
#endif
160 161 162 163 164 165
#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
  emit setSlotDescription("addHexahedralCube(Vector,double)",
                          tr("Generates a hexahedral mesh of a cube (ObjectId is returned)"),
                          QString("Position,Length").split(","),
                          QString("Center position,Length of each edge").split(","));
#endif
166

167 168 169 170
}

void PrimitivesGeneratorPlugin::pluginsInitialized() {

Jan Möbius's avatar
Jan Möbius committed
171
  if ( OpenFlipper::Options::gui()) {
172

173
    emit getMenubarMenu(tr("&Primitives"), primitivesMenu_, true );
174

175
    WhatsThisGenerator whatsThisGen("PrimitivesGenerator");
Matthias Möller's avatar
Matthias Möller committed
176
    QAction* action;
177

178
    action = primitivesMenu_->addAction("Cube (Poly Mesh)"       ,this,SLOT(addCube()));
179
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
180
    whatsThisGen.setWhatsThis(action,tr("Create a Cube."),"Cube");
181

182 183
    action = primitivesMenu_->addAction("Cube (Triangle Mesh)"       ,this,SLOT(addTriangulatedCube()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
184
    whatsThisGen.setWhatsThis(action,tr("Create a Cube."),"Cube");
185

186 187
    action = primitivesMenu_->addAction("Dodecahedron"               ,this,SLOT(addDodecahedron()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_dodecahedron.png"));
188
    whatsThisGen.setWhatsThis(action,tr("Create a Dodecahedron."), "Dodecahedron");
189

190 191
    action = primitivesMenu_->addAction("Icosahedron"                ,this,SLOT(addIcosahedron()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_icosahedron.png"));
192
    whatsThisGen.setWhatsThis(action,tr("Create a Icosahedron.","Icosahedron"));
193

194 195
    action = primitivesMenu_->addAction("Octahedron"                  ,this,SLOT(addOctahedron()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_octahedron.png"));
196
    whatsThisGen.setWhatsThis(action,tr("Create an Octahedron."),"Octahedron");
Jan Möbius's avatar
Jan Möbius committed
197

198 199
    action = primitivesMenu_->addAction("Pyramid"                    ,this,SLOT(addPyramid()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_pyramid.png"));
200
    whatsThisGen.setWhatsThis(action,tr("Create a Pyramid."),"Pyramid");
Jan Möbius's avatar
Jan Möbius committed
201

202 203
    action = primitivesMenu_->addAction("Cylinder (Triangle Mesh)"       ,this,SLOT(addTriangulatedCylinder()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cylinder.png"));
204

205 206 207 208 209
    action = primitivesMenu_->addAction("Sphere (Poles,Triangle Mesh)",this,SLOT(addSphere()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_sphere.png"));
    whatsThisGen.setWhatsThis(action,tr("Create a Sphere. All vertical lines connect to poles) "),"Sphere");

    action = primitivesMenu_->addAction("Sphere (Subdivision,Triangle Mesh)",this,SLOT(addSubdivisionSphere()));
210
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_sphere.png"));
211
    whatsThisGen.setWhatsThis(action,tr("Create a Sphere. No poles due to Subdivision) "),"Sphere");
Jan Möbius's avatar
Jan Möbius committed
212

213 214
    action = primitivesMenu_->addAction("Tetrahedron",this,SLOT(addTetrahedron()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_tetrahedron.png"));
215
    whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedron."),"Tetrahedron");
216

217 218
#ifdef ENABLE_BSPLINECURVE_SUPPORT
    action = primitivesMenu_->addAction("Random B-spline curve",this,SLOT(addRandomBSplineCurve()));
Christopher Tenter's avatar
Christopher Tenter committed
219 220
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "bspline_curve.png"));
    whatsThisGen.setWhatsThis(action, tr("Create a random B-spline curve."), "B-spline curve");
221 222
#endif

223 224
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
    action = primitivesMenu_->addAction("Random B-spline surface",this,SLOT(addRandomBSplineSurface()));
225
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"bspline_surface.png"));
226 227 228
    whatsThisGen.setWhatsThis(action,tr("Create a random B-spline surface."),"B-spline surface");
#endif

229
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
230 231 232 233 234 235 236
    action = primitivesMenu_->addAction("Cube (Tetrahedral Mesh)"    ,this,SLOT(addTetrahedralCube()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
    whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedral Cube."), "Cube");

    action = primitivesMenu_->addAction("Cuboid (Tetrahedral Mesh)"  ,this,SLOT(addTetrahedralCuboid()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
    whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedral Cuboid."), "Cuboid");
237 238 239 240 241 242 243
#endif

#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
    action = primitivesMenu_->addAction("Cube (Hexahedral Mesh)"    ,this,SLOT(addHexahedralCube()));
    action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
    whatsThisGen.setWhatsThis(action,tr("Create a Hexahedral Cube."), "Cube");

244 245
#endif
  }
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
}


int PrimitivesGeneratorPlugin::addTriMesh() {
  int objectId = -1;

  emit addEmptyObject( DATA_TRIANGLE_MESH, objectId );

  TriMeshObject* object;
  if ( !PluginFunctions::getObject(objectId,object) ) {
    emit log(LOGERR,"Unable to create new Object");
    return -1;
  }

  return objectId;
}

Jan Möbius's avatar
Jan Möbius committed
263 264 265 266 267 268 269 270 271 272 273 274 275 276
int PrimitivesGeneratorPlugin::addPolyMesh() {
  int objectId = -1;

  emit addEmptyObject( DATA_POLY_MESH, objectId );

  PolyMeshObject* object;
  if ( !PluginFunctions::getObject(objectId,object) ) {
    emit log(LOGERR,"Unable to create new Object");
    return -1;
  }

  return objectId;
}

277

278
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
int PrimitivesGeneratorPlugin::addPolyhedralMesh() {
    int objectId = -1;

    emit addEmptyObject( DATA_POLYHEDRAL_MESH, objectId );

    PolyhedralMeshObject* object;
    if (!PluginFunctions::getObject(objectId, object) ) {
        emit log(LOGERR, "Unable to create new PolyhedralMesh object");
        return -1;
    }

    return objectId;
}
#endif

294

295
int PrimitivesGeneratorPlugin::addTetrahedron(const Vector& _position, const double _length) {
296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313

  int newObject = addTriMesh();

  TriMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
        emit log(LOGERR,"Unable to create new Object");
        return -1;
  } else {

    object->setName( "Tetrahedron " + QString::number(newObject) );

    triMesh_ =  object->mesh();

    triMesh_->clear();

    // Add 4 vertices
    vhandles_.resize(4);

314
    const double halfSize = 0.5*_length;
Jan Möbius's avatar
Jan Möbius committed
315

316 317 318 319
    vhandles_[0] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize,  halfSize)+_position);
    vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfSize,  halfSize,  halfSize)+_position);
    vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfSize,  halfSize, -halfSize)+_position);
    vhandles_[3] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize, -halfSize)+_position);
320 321 322 323 324 325 326 327 328 329

    // Add 4 faces
    add_face(0,1,2);
    add_face(0,2,3);
    add_face(2,1,3);
    add_face(3,1,0);

    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
330
    emit createBackup(newObject, "Original Object");
331

332 333
    PluginFunctions::viewAll();

334 335 336 337 338 339
    return newObject;
  }

  return -1;
}

340
int PrimitivesGeneratorPlugin::addTriangulatedCube(const Vector& _position,const double _length) {
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
  int newObject = addTriMesh();

  TriMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
        emit log(LOGERR,"Unable to create new Object");
        return -1;
  } else {

    object->setName( "Cube " + QString::number(newObject) );

    triMesh_ =  object->mesh();

    triMesh_->clear();

    // Add 8 vertices
    vhandles_.resize(8);

358
    const double halfSize = 0.5*_length;
Jan Möbius's avatar
Jan Möbius committed
359

360 361 362 363 364 365 366 367
    vhandles_[0] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize, halfSize)+_position);
    vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfSize,  halfSize, halfSize)+_position);
    vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfSize,  halfSize, halfSize)+_position);
    vhandles_[3] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize, halfSize)+_position);
    vhandles_[4] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize,-halfSize)+_position);
    vhandles_[5] = triMesh_->add_vertex(TriMesh::Point( halfSize,  halfSize,-halfSize)+_position);
    vhandles_[6] = triMesh_->add_vertex(TriMesh::Point(-halfSize,  halfSize,-halfSize)+_position);
    vhandles_[7] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize,-halfSize)+_position);
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387


    // Add 12 faces
    add_face(0,1,2);
    add_face(0,2,3);
    add_face(0,5,1);
    add_face(5,0,4);
    add_face(4,0,7);
    add_face(7,0,3);

    add_face(7,3,6);
    add_face(6,3,2);
    add_face(6,2,5);
    add_face(5,2,1);
    add_face(6,5,4);
    add_face(6,4,7);

    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
388
    emit createBackup(newObject, "Original Object");
389

390 391
    PluginFunctions::viewAll();

392 393 394 395 396 397
    return newObject;
  }

  return -1;
}

398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
int PrimitivesGeneratorPlugin::addCube(const Vector& _position,const double _length) {
  int newObject = addPolyMesh();

  PolyMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
        emit log(LOGERR,"Unable to create new Object");
        return -1;
  } else {

    object->setName( "Cube " + QString::number(newObject) );

    polyMesh_ =  object->mesh();
    polyMesh_->clear();

    // Add 8 vertices
    vhandles_.resize(8);

    const double halfSize = 0.5*_length;
    //   6------5
    //  /|     /|
    // 2------1 |
    // | |    | |
    // | 7----|-4
    // |/     |/
    // 3------0
    vhandles_[0] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, -halfSize, halfSize)+_position);
    vhandles_[1] = polyMesh_->add_vertex(PolyMesh::Point( halfSize,  halfSize, halfSize)+_position);
    vhandles_[2] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize,  halfSize, halfSize)+_position);
    vhandles_[3] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, -halfSize, halfSize)+_position);
    vhandles_[4] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, -halfSize,-halfSize)+_position);
    vhandles_[5] = polyMesh_->add_vertex(PolyMesh::Point( halfSize,  halfSize,-halfSize)+_position);
    vhandles_[6] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize,  halfSize,-halfSize)+_position);
    vhandles_[7] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, -halfSize,-halfSize)+_position);

    // Add faces
    add_face(0,1,2,3);
    add_face(0,4,5,1);
    add_face(4,7,6,5);
    add_face(7,3,2,6);
    add_face(1,5,6,2);
    add_face(0,3,7,4);

    polyMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
    emit createBackup(newObject, "Original Object");

    PluginFunctions::viewAll();

    return newObject;
  }

  return -1;
}

453 454 455 456
//========================================================================
// Tetrahedral cube
//========================================================================

457
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
458 459 460 461 462 463 464 465 466 467 468 469

int PrimitivesGeneratorPlugin::addTetrahedralCube(const Vector& _position, const double _length)
{
    return addTetrahedralCuboid(_position, Vector(_length, _length, _length), 1, 1, 1);
}

#endif

//========================================================================
// Tetrahedral Cuboid
//========================================================================

470
#ifdef ENABLE_POLYHEDRALMESH_SUPPORT
471 472 473 474 475 476 477 478 479 480 481 482 483 484

int PrimitivesGeneratorPlugin::addTetrahedralCuboid(const Vector& _position,
        const Vector& _length, const unsigned int  n_x, const unsigned int  n_y, const unsigned int  n_z)
{

    int object_id = addPolyhedralMesh();
    PolyhedralMeshObject* object;

    if (!PluginFunctions::getObject(object_id, object)) {
        return -1;
    }

    object->setName("Cuboid " + QString::number(object_id));

485
    TetrahedralCuboidGenerator gen(*(object->mesh()), _position, _length, n_x, n_y, n_z);
486 487

    emit updatedObject(object_id, UPDATE_ALL);
488
    emit createBackup(object_id, "Original Object");
489 490 491 492 493 494 495 496 497

    object->setObjectDrawMode(ACG::SceneGraph::DrawModes::getDrawMode("Cells (flat shaded)"));
    PluginFunctions::viewAll();

    return object_id;
}

#endif

498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543
//========================================================================
// Hexahedral Cube & Cuboid
//========================================================================

#ifdef ENABLE_HEXAHEDRALMESH_SUPPORT

int PrimitivesGeneratorPlugin::addHexahedralCube(const Vector& _position, const double _length)
{
    int object_id;
    emit addEmptyObject( DATA_HEXAHEDRAL_MESH, object_id);

    HexahedralMeshObject* object;
    if (!PluginFunctions::getObject(object_id, object) ) {
        emit log(LOGERR, "Unable to create new HexahedralMesh object");
        return -1;
    }
    object->setName( "HexCube " + QString::number(object_id) );

    auto mesh =  object->mesh();
    namespace OVM = OpenVolumeMesh;
    std::vector<OVM::VertexHandle> vertices(8);

    const double halfSize = 0.5*_length;
    vertices[0] = mesh->add_vertex(Vector(-halfSize, -halfSize, halfSize)+_position);
    vertices[1] = mesh->add_vertex(Vector( halfSize, -halfSize, halfSize)+_position);
    vertices[2] = mesh->add_vertex(Vector( halfSize,  halfSize, halfSize)+_position);
    vertices[3] = mesh->add_vertex(Vector(-halfSize,  halfSize, halfSize)+_position);
    vertices[4] = mesh->add_vertex(Vector(-halfSize, -halfSize,-halfSize)+_position);
    vertices[5] = mesh->add_vertex(Vector(-halfSize,  halfSize,-halfSize)+_position);
    vertices[6] = mesh->add_vertex(Vector( halfSize,  halfSize,-halfSize)+_position);
    vertices[7] = mesh->add_vertex(Vector( halfSize, -halfSize,-halfSize)+_position);

    mesh->add_cell(vertices);

    emit updatedObject(object_id, UPDATE_ALL);
    emit createBackup(object_id, "Original Object");

    object->setObjectDrawMode(ACG::SceneGraph::DrawModes::getDrawMode("Cells (flat shaded)"));

    PluginFunctions::viewAll();

    return object_id;
}

#endif

544 545 546 547 548
//========================================================================
// Cylinder
//========================================================================


549 550 551 552 553 554
ACG::Vec3d PrimitivesGeneratorPlugin::positionOnCylinder(const int _sliceNumber,
                                                         const int _stackNumber,
                                                         const Vector _position,
                                                         const Vector _axis,
                                                         const double _radius,
                                                         const double _height)
555 556 557
{
  ACG::Vec3d position;

558 559
  const ACG::Vec3d right = (ACG::Geometry::perpendicular(_axis)).normalized();
  const ACG::Vec3d left  = (cross( _axis, right)).normalized();
560 561 562 563 564 565

  double beta = ((2.0 * M_PI) / double(slices_)) * double(_sliceNumber);

  if ( _sliceNumber == 0 &&  _stackNumber == 0) {
    position[0] = 0.0;
    position[1] = 0.0;
566
    position[2] = _height;
567 568 569 570 571
  } else  if ( _sliceNumber == slices_ &&  _stackNumber == stacks_ ) {
    position[0] = 0.0;
    position[1] = 0.0;
    position[2] = 0.0;
  } else {
572 573 574
    position[0] = sin(beta) * _radius;
    position[1] = cos(beta) * _radius;
    position[2] = _height * double(stacks_ - _stackNumber -1 ) / double(stacks_-2);
575 576
  }

577
  position = _position + position[0] * right + position[1] * left + position[2] * _axis ;
578

579 580 581
  return position;
}

582
int PrimitivesGeneratorPlugin::addTriangulatedCylinder(const Vector& _position,const Vector& _axis,const double _radius,const double _height,const bool _top,const bool   _bottom ) {
583

Jan Möbius's avatar
Jan Möbius committed
584
  // TODO: Generate texture coordinates for cylinder (Glu compatible)
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
  int newObject = addTriMesh();

  TriMeshObject* object;
  if (!PluginFunctions::getObject(newObject, object)) {
    emit log(LOGERR, "Unable to create new Object");
    return -1;
  } else {

    object->setName( "Cylinder " + QString::number(newObject) );

    triMesh_ = object->mesh();

    triMesh_->clear();

    //triMesh_->request_vertex_texcoords2D();

    TriMesh::VertexHandle vh;
602
    TriMesh::VertexHandle top = triMesh_->add_vertex(positionOnCylinder(0, 0,_position,_axis,_radius,_height));
603 604 605 606
    //triMesh_->set_texcoord2D(vh, texCoordOnSphere(0, 0));

    for (int st = 1; st < stacks_; ++st) {
      for (int sl = 0; sl < slices_; ++sl) {
607
        vh = triMesh_->add_vertex(positionOnCylinder(sl, st,_position,_axis,_radius,_height));
608 609 610 611
        //triMesh_->set_texcoord2D(vh, texCoordOnSphere(sl, st));
      }
    }

612
    TriMesh::VertexHandle bottom = triMesh_->add_vertex(positionOnCylinder(slices_, stacks_,_position,_axis,_radius,_height));
613 614 615 616 617
    //triMesh_->set_texcoord2D(vh, texCoordOnSphere(slices_, stacks_));

    std::vector<TriMesh::VertexHandle> vhandles;

    // Add top triangle fan ( Vertex index is shifted by one for the first slice )
618 619
    if ( _top ) {
      for (int sl = 1; sl < slices_ + 1; ++sl) {
620

621
        vhandles.clear();
622

623 624 625
        vhandles.push_back(triMesh_->vertex_handle(sl));
        vhandles.push_back(triMesh_->vertex_handle(0));
        vhandles.push_back(triMesh_->vertex_handle(1 * 1 + (sl % slices_)));
626

627 628 629 630
        triMesh_->add_face(vhandles);
      }
    } else {
      triMesh_->delete_vertex(top);
631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
    }

    for (int st = 0; st < stacks_ - 2; ++st) {

      // Move around one slice
      for (int sl = 0; sl < slices_; ++sl) {

        // Offset 1 because of singular vertex
        unsigned int startTop = 1 + slices_ * st;
        unsigned int startBottom = 1 + slices_ * (st + 1);

        vhandles.clear();

        vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
        vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
        vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));

        triMesh_->add_face(vhandles);

        vhandles.clear();

        vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
        vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
        vhandles.push_back(triMesh_->vertex_handle(startBottom + ((sl + 1) % slices_)));

        triMesh_->add_face(vhandles);
      }

    }

    const int startTop     = 1 + (stacks_ - 2) * slices_;
    const int bottomVertex = 1 + (stacks_ - 1) * slices_;

    // Add bottom triangle fan
665 666
    if ( _bottom) {
      for (int sl = 0; sl < slices_; ++sl) {
667

668
        vhandles.clear();
669

670 671 672
        vhandles.push_back(triMesh_->vertex_handle(bottomVertex));
        vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
        vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
673

674 675 676 677
        triMesh_->add_face(vhandles);
      }
    } else {
      triMesh_->delete_vertex(bottom);
678 679
    }

680 681 682
    // Cleanup if bottom or top vertex is missing
    triMesh_->garbage_collection();

683 684 685
    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
686
    emit createBackup(newObject, "Original Object");
687

688 689
    PluginFunctions::viewAll();

690 691 692 693 694 695
    return object->id();
  }

}


696 697 698 699 700
//========================================================================
// Sphere
//========================================================================


701
ACG::Vec3d PrimitivesGeneratorPlugin::positionOnSphere(int _sliceNumber, int _stackNumber, double _radius, const Vector& _position)
702 703 704 705 706 707 708
{
  ACG::Vec3d position;

  double alpha = (M_PI / double(stacks_)) * double(_stackNumber);
  double beta = ((2.0 * M_PI) / double(slices_)) * double(_sliceNumber);

  double ringRadius = sin(alpha);
709 710 711
  position[0] = sin(beta) * ringRadius * _radius;
  position[1] = cos(beta) * ringRadius * _radius;
  position[2] = cos(alpha)* _radius;
712

713
  return _position+position;
714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
}

//------------------------------------------------------------------------

ACG::Vec2f PrimitivesGeneratorPlugin::texCoordOnSphere(int _sliceNumber, int _stackNumber)
{
  ACG::Vec2f texCoord;

  double alpha = (M_PI / double(stacks_)) * double(_stackNumber);
  texCoord[0] = double(_sliceNumber) / double(slices_);
  texCoord[1] = 0.5 * (cos(alpha) + 1.0);

  return texCoord;
}

729

730 731
//------------------------------------------------------------------------

732 733
int PrimitivesGeneratorPlugin::addSphere(const Vector& _position, const double _radius)
{
734 735 736 737 738 739 740 741
  int newObject = addTriMesh();

  TriMeshObject* object;
  if (!PluginFunctions::getObject(newObject, object)) {
    emit log(LOGERR, "Unable to create new Object");
    return -1;
  } else {

Jan Möbius's avatar
Jan Möbius committed
742 743
    object->setName( "Sphere " + QString::number(newObject) );

744
    triMesh_ = object->mesh();
Jan Möbius's avatar
Jan Möbius committed
745 746 747

    triMesh_->clear();

748 749 750 751
    triMesh_->request_vertex_texcoords2D();

    TriMesh::VertexHandle vh;

752
    vh = triMesh_->add_vertex(positionOnSphere(0, 0, _radius,_position));
753 754
    triMesh_->set_texcoord2D(vh, texCoordOnSphere(0, 0));

755
    for (int st = 1; st < stacks_; ++st) {
756
      for (int sl = 0; sl < slices_; ++sl) {
757
        vh = triMesh_->add_vertex(positionOnSphere(sl, st, _radius,_position));
758 759 760 761
        triMesh_->set_texcoord2D(vh, texCoordOnSphere(sl, st));
      }
    }

762
    vh = triMesh_->add_vertex(positionOnSphere(slices_, stacks_, _radius,_position));
763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
    triMesh_->set_texcoord2D(vh, texCoordOnSphere(slices_, stacks_));

    std::vector<TriMesh::VertexHandle> vhandles;

    // Add top triangle fan ( Vertex index is shifted by one for the first slice )
    for (int sl = 1; sl < slices_ + 1; ++sl) {

      vhandles.clear();

      vhandles.push_back(triMesh_->vertex_handle(sl));
      vhandles.push_back(triMesh_->vertex_handle(0));
      vhandles.push_back(triMesh_->vertex_handle(1 * 1 + (sl % slices_)));

      triMesh_->add_face(vhandles);
    }

779
    for (int st = 0; st < stacks_ - 2; ++st) {
780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806

      // Move around one slice
      for (int sl = 0; sl < slices_; ++sl) {

        // Offset 1 because of singular vertex
        unsigned int startTop = 1 + slices_ * st;
        unsigned int startBottom = 1 + slices_ * (st + 1);

        vhandles.clear();

        vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
        vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
        vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));

        triMesh_->add_face(vhandles);

        vhandles.clear();

        vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
        vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
        vhandles.push_back(triMesh_->vertex_handle(startBottom + ((sl + 1) % slices_)));

        triMesh_->add_face(vhandles);
      }

    }

807 808
    const int startTop     = 1 + (stacks_ - 2) * slices_;
    const int bottomVertex = 1 + (stacks_ - 1) * slices_;
809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824

    // Add bottom triangle fan
    for (int sl = 0; sl < slices_; ++sl) {

      vhandles.clear();

      vhandles.push_back(triMesh_->vertex_handle(bottomVertex));
      vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
      vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));

      triMesh_->add_face(vhandles);
    }

    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
825
    emit createBackup(newObject, "Original Object");
826

827 828
    PluginFunctions::viewAll();

829 830 831 832
    return object->id();
  }


833 834 835 836 837 838 839 840
}

//------------------------------------------------------------------------

int PrimitivesGeneratorPlugin::addSubdivisionSphere(const Vector& _position, const double _radius)
{

  // Create the underlying octahedron
841
  int newObject = addTriMesh();
842 843 844 845 846 847 848 849 850

  TriMeshObject* object;
  if (!PluginFunctions::getObject(newObject, object)) {
    emit log(LOGERR, "Unable to create new Object");
    return -1;
  } else {
    object->setName( "Sphere " + QString::number(newObject) );

    triMesh_ = object->mesh();
851
    constructOctahedron(_position, _radius);
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873

    // Number of subdivision iterations for the sphere
    const size_t subdivisionSteps = 4;

    for (size_t i = 0 ; i < subdivisionSteps; ++i) {

      // Call the subdivision algorithm
      RPC::callFunction("subdivider", "subdivide", newObject, QString("loop"), 1, false);

      // Reposition vertices onto sphere
      for (TriMesh::VertexIter v_it = triMesh_->vertices_begin(); v_it != triMesh_->vertices_end(); ++v_it) {
        TriMesh::Point p = triMesh_->point(*v_it);
        p -= _position;
        p = _radius * p.normalize() + _position;
        triMesh_->set_point(*v_it, p);
      }
    }

    // Make sure that the normals are fine
    triMesh_->update_normals();

    emit updatedObject(newObject, UPDATE_ALL);
874
    emit createBackup(newObject, "Original Object");
875 876 877 878 879 880 881 882

    PluginFunctions::viewAll();

    return newObject;

  }


883 884
}

885 886 887 888 889

//========================================================================
// Pyramid
//========================================================================

890
int PrimitivesGeneratorPlugin::addPyramid(const Vector& _position,const double _length) {
891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907
  int newObject = addTriMesh();

  TriMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
        emit log(LOGERR,"Unable to create new Object");
        return -1;
  } else {

    object->setName( "Pyramid " + QString::number(newObject) );

    triMesh_ =  object->mesh();

    triMesh_->clear();

    // Add 5 vertices
    vhandles_.resize(5);

908
    const double halfLength   = 0.5*_length;
Jan Möbius's avatar
Jan Möbius committed
909

910 911 912 913
    vhandles_[0] = triMesh_->add_vertex(TriMesh::Point( halfLength, -halfLength, 0.0)+_position);
    vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfLength,  halfLength, 0.0)+_position);
    vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfLength,  halfLength, 0.0)+_position);
    vhandles_[3] = triMesh_->add_vertex(TriMesh::Point(-halfLength, -halfLength, 0.0)+_position);
Jan Möbius's avatar
Jan Möbius committed
914

915
    vhandles_[4] = triMesh_->add_vertex(TriMesh::Point(0.0, 0.0, sqrt(2.0)*halfLength));
916 917 918 919 920 921 922 923 924 925 926 927 928

    // Add 6 faces
    add_face(2,1,0);
    add_face(3,2,0);
    add_face(4,0,1);

    add_face(3,0,4);
    add_face(4,2,3);
    add_face(1,2,4);

    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
929
    emit createBackup(newObject, "Original Object");
930

931 932
    PluginFunctions::viewAll();

933 934 935 936 937 938
    return newObject;
  }

  return -1;
}

939 940 941 942 943 944 945
void PrimitivesGeneratorPlugin::add_face(int _vh1 , int _vh2, int _vh3) {
  triMesh_->add_face(
    static_cast<TriMesh::VertexHandle>(_vh1),
    static_cast<TriMesh::VertexHandle>(_vh2),
    static_cast<TriMesh::VertexHandle>(_vh3)
  );
}
946

947 948 949 950 951 952 953 954
void PrimitivesGeneratorPlugin::add_face(int _vh1, int _vh2, int _vh3, int _vh4)
{
  polyMesh_->add_face(
    static_cast<PolyMesh::VertexHandle>(_vh1),
    static_cast<PolyMesh::VertexHandle>(_vh2),
    static_cast<PolyMesh::VertexHandle>(_vh3),
    static_cast<PolyMesh::VertexHandle>(_vh4)
  );
955 956
}

Jan Möbius's avatar
Jan Möbius committed
957 958 959 960 961 962 963 964 965 966 967 968
void PrimitivesGeneratorPlugin::add_face( int _vh1 , int _vh2, int _vh3, int _vh4 , int _vh5 ) {
  std::vector<PolyMesh::VertexHandle> vhandles;

  vhandles.push_back(vphandles_[_vh1]);
  vhandles.push_back(vphandles_[_vh2]);
  vhandles.push_back(vphandles_[_vh3]);
  vhandles.push_back(vphandles_[_vh4]);
  vhandles.push_back(vphandles_[_vh5]);

  polyMesh_->add_face(vhandles);
}

969
int PrimitivesGeneratorPlugin::addIcosahedron(const Vector& _position,const double _length) {
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986
  int newObject = addTriMesh();

  TriMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
        emit log(LOGERR,"Unable to create new Object");
        return -1;
  } else {

    object->setName( "Icosahedron " + QString::number(newObject) );

    triMesh_ =  object->mesh();

    triMesh_->clear();

    // Add 12 vertices
    vhandles_.resize(12);

987
    const double phi  = 0.5 * (1.0 + sqrt(5.0));
988
    //double norm = 1.0 / sqrt(1.0 + phi*phi);
989 990
    const double norm = 1.0;
    const double halfLength = 0.5*_length;
991

992 993 994 995
    vhandles_[0 ] = triMesh_->add_vertex(norm * TriMesh::Point(  0.0 ,  -halfLength , -phi )+_position);
    vhandles_[1 ] = triMesh_->add_vertex(norm * TriMesh::Point(  0.0 ,   halfLength , -phi )+_position);
    vhandles_[2 ] = triMesh_->add_vertex(norm * TriMesh::Point(  0.0 ,   halfLength ,  phi )+_position);
    vhandles_[3 ] = triMesh_->add_vertex(norm * TriMesh::Point(  0.0 ,  -halfLength ,  phi )+_position);
996

997 998 999 1000
    vhandles_[4 ] = triMesh_->add_vertex(norm * TriMesh::Point( -halfLength , -phi ,  0.0  )+_position);
    vhandles_[5 ] = triMesh_->add_vertex(norm * TriMesh::Point(  halfLength , -phi ,  0.0  )+_position);
    vhandles_[6 ] = triMesh_->add_vertex(norm * TriMesh::Point(  halfLength ,  phi ,  0.0  )+_position);
    vhandles_[7 ] = triMesh_->add_vertex(norm * TriMesh::Point( -halfLength ,  phi ,  0.0  )+_position);
1001

1002 1003 1004 1005
    vhandles_[8 ] = triMesh_->add_vertex(norm * TriMesh::Point( -phi ,  0.0 , -halfLength  )+_position);
    vhandles_[9 ] = triMesh_->add_vertex(norm * TriMesh::Point( -phi ,  0.0 ,  halfLength  )+_position);
    vhandles_[10] = triMesh_->add_vertex(norm * TriMesh::Point(  phi ,  0.0 ,  halfLength  )+_position);
    vhandles_[11] = triMesh_->add_vertex(norm * TriMesh::Point(  phi ,  0.0 , -halfLength  )+_position);
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041


    // Add 20 faces
    add_face(2,6,7);
    add_face(7,6,1);

    add_face(11,0,1);
    add_face(0, 8,1);

    add_face(4,9,8);
    add_face(8,9,7);

    add_face(9,3,2);
    add_face(10,2,3);

    add_face(5,11,10);
    add_face(11,6,10);

    add_face(0,5,4);
    add_face(5,3,4);

    // Upper block
    add_face(6,2,10);
    add_face(6,11,1);
    add_face(1,8,7);
    add_face(9,2,7);

    // Lower block
    add_face(3,5,10);
    add_face(0,11,5);
    add_face(3,9,4);
    add_face(0,4,8);

    triMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
1042
    emit createBackup(newObject, "Original Object");
1043

1044 1045
    PluginFunctions::viewAll();

1046 1047 1048 1049 1050 1051
    return newObject;
  }

  return -1;
}

1052 1053 1054
void PrimitivesGeneratorPlugin::constructOctahedron(const Vector& _position, const double _length)
{
  triMesh_->clear();
Jan Möbius's avatar
Jan Möbius committed
1055

1056 1057
  // Add 6 vertices
  vhandles_.resize(6);
Jan Möbius's avatar
Jan Möbius committed
1058

1059
  const double sqrtLength = sqrt(_length);
Jan Möbius's avatar
Jan Möbius committed
1060

1061 1062 1063 1064
  vhandles_[0 ] = triMesh_->add_vertex(TriMesh::Point(-sqrtLength,   0.0,   0.0)+_position);
  vhandles_[1 ] = triMesh_->add_vertex(TriMesh::Point(  0.0, -sqrtLength,   0.0)+_position);
  vhandles_[2 ] = triMesh_->add_vertex(TriMesh::Point( sqrtLength,   0.0,   0.0)+_position);
  vhandles_[3 ] = triMesh_->add_vertex(TriMesh::Point(  0.0,  sqrtLength,   0.0)+_position);
Jan Möbius's avatar
Jan Möbius committed
1065

1066 1067
  vhandles_[4 ] = triMesh_->add_vertex(TriMesh::Point(  0.0,   0.0,  sqrtLength)+_position);
  vhandles_[5 ] = triMesh_->add_vertex(TriMesh::Point(  0.0,   0.0, -sqrtLength)+_position);
Jan Möbius's avatar
Jan Möbius committed
1068 1069


1070 1071 1072
  // Add 8 faces
  add_face(0,1,4);
  add_face(1,2,4);
Jan Möbius's avatar
Jan Möbius committed
1073

1074 1075
  add_face(2,3,4);
  add_face(0,4,3);
Jan Möbius's avatar
Jan Möbius committed
1076

1077 1078
  add_face(5,1,0);
  add_face(5,2,1);
Jan Möbius's avatar
Jan Möbius committed
1079

1080 1081
  add_face(5,3,2);
  add_face(5,0,3);
Jan Möbius's avatar
Jan Möbius committed
1082

1083 1084
  triMesh_->update_normals();
}
Jan Möbius's avatar
Jan Möbius committed
1085

1086 1087
int PrimitivesGeneratorPlugin::addOctahedron(const Vector& _position,const double _length) {
  int newObject = addTriMesh();
1088

1089 1090 1091 1092 1093
  TriMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
    emit log(LOGERR,"Unable to create new Object");
    return -1;
  } else {
Jan Möbius's avatar
Jan Möbius committed
1094

1095
    object->setName( "Octahedron " + QString::number(newObject) );
Jan Möbius's avatar
Jan Möbius committed
1096

1097 1098 1099
    triMesh_ =  object->mesh();

    constructOctahedron(_position, _length);
Jan Möbius's avatar
Jan Möbius committed
1100 1101

    emit updatedObject(newObject,UPDATE_ALL);
1102
    emit createBackup(newObject, "Original Object");
Jan Möbius's avatar
Jan Möbius committed
1103

1104 1105
    PluginFunctions::viewAll();

Jan Möbius's avatar
Jan Möbius committed
1106 1107 1108 1109 1110 1111
    return newObject;
  }

  return -1;
}

1112
int PrimitivesGeneratorPlugin::addDodecahedron(const Vector& _position,const double _length) {
Jan Möbius's avatar
Jan Möbius committed
1113 1114 1115 1116 1117 1118 1119 1120
  int newObject = addPolyMesh();

  PolyMeshObject* object;
  if ( !PluginFunctions::getObject(newObject,object) ) {
    emit log(LOGERR,"Unable to create new Object");
    return -1;
  } else {

Jan Möbius's avatar
Jan Möbius committed
1121
    object->setName( "Dodecahedron " + QString::number(newObject) );
Jan Möbius's avatar
Jan Möbius committed
1122 1123 1124 1125 1126 1127 1128 1129

    polyMesh_ =  object->mesh();

    polyMesh_->clear();

    // Add 20 vertices
    vphandles_.resize(20);

1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156
    const double phi = (1.0 + sqrt(5.0)) / 2.0;
    const double halfLength = 0.5*_length;


    vphandles_[0 ] = polyMesh_->add_vertex(TriMesh::Point(  halfLength ,  halfLength , halfLength )+_position);
    vphandles_[1 ] = polyMesh_->add_vertex(TriMesh::Point(  halfLength ,  halfLength ,-halfLength )+_position);
    vphandles_[2 ] = polyMesh_->add_vertex(TriMesh::Point(  halfLength , -halfLength , halfLength )+_position);
    vphandles_[3 ] = polyMesh_->add_vertex(TriMesh::Point(  halfLength , -halfLength ,-halfLength )+_position);
    vphandles_[4 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength ,  halfLength , halfLength )+_position);
    vphandles_[5 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength ,  halfLength ,-halfLength )+_position);
    vphandles_[6 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , -halfLength , halfLength )+_position);
    vphandles_[7 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , -halfLength ,-halfLength )+_position);

    vphandles_[8 ] = polyMesh_->add_vertex(TriMesh::Point( 0.0 ,  halfLength / phi ,  phi )+_position);
    vphandles_[9 ] = polyMesh_->add_vertex(TriMesh::Point( 0.0 ,  halfLength / phi , -phi )+_position);
    vphandles_[10] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , -halfLength / phi ,  phi )+_position);
    vphandles_[11] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , -halfLength / phi , -phi )+_position);

    vphandles_[12] = polyMesh_->add_vertex(TriMesh::Point(  halfLength / phi ,  phi, 0.0)+_position);
    vphandles_[13] = polyMesh_->add_vertex(TriMesh::Point(  halfLength / phi , -phi, 0.0)+_position);
    vphandles_[14] = polyMesh_->add_vertex(TriMesh::Point( -halfLength / phi ,  phi, 0.0)+_position);
    vphandles_[15] = polyMesh_->add_vertex(TriMesh::Point( -halfLength / phi , -phi, 0.0)+_position);

    vphandles_[16] = polyMesh_->add_vertex(TriMesh::Point(  phi , 0.0 , halfLength / phi)+_position);
    vphandles_[17] = polyMesh_->add_vertex(TriMesh::Point(  phi , 0.0 ,-halfLength / phi)+_position);
    vphandles_[18] = polyMesh_->add_vertex(TriMesh::Point( -phi , 0.0 , halfLength / phi)+_position);
    vphandles_[19] = polyMesh_->add_vertex(TriMesh::Point( -phi , 0.0 ,-halfLength / phi)+_position);
Jan Möbius's avatar
Jan Möbius committed
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176

    // Add 12 faces
    add_face(14, 5,19,18, 4);
    add_face( 5, 9,11, 7,19);
    add_face( 6,15,13, 2,10);
    add_face(12, 0,16,17, 1);

    add_face( 0, 8,10, 2,16);
    add_face(16, 2,13, 3,17);
    add_face( 3,13,15, 7,11);
    add_face( 7,15, 6,18,19);

    add_face( 4,18, 6,10, 8);
    add_face( 4, 8, 0,12,14);
    add_face(14,12, 1, 9, 5);
    add_face( 9, 1,17, 3,11);

    polyMesh_->update_normals();

    emit updatedObject(newObject,UPDATE_ALL);
1177
    emit createBackup(newObject, "Original Object");
Jan Möbius's avatar
Jan Möbius committed
1178

1179 1180
    PluginFunctions::viewAll();

Jan Möbius's avatar
Jan Möbius committed
1181 1182 1183 1184 1185
    return newObject;
  }

  return -1;
}
1186

1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220
#ifdef ENABLE_BSPLINECURVE_SUPPORT
int PrimitivesGeneratorPlugin::addRandomBSplineCurve(const Vector& _position, int nDiv)
{
  int id = -1;
  emit addEmptyObject(DATA_BSPLINE_CURVE, id);
  if (id == -1) {
    return -1;
  }

  BSplineCurveObject *object = NULL;
  if (!PluginFunctions::getObject(id, object)) {
    return -1;
  }

  BSplineCurve *curve = object->splineCurve();

  curve->autocompute_knotvector(true);
  for (int i = 0; i < nDiv; ++i) {
    double x = _position[0] + i - nDiv / 2.0;

    double r = (2.0 * std::rand()) / RAND_MAX - 1.0;
    BSplineCurve::Point cp(x, _position[1] + r, _position[2]);
    curve->add_control_point(cp);
  }

  emit updatedObject(id, UPDATE_ALL);
  emit createBackup(id, "Original Object");

  PluginFunctions::viewAll();

  return id;
}
#endif

1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249
#ifdef ENABLE_BSPLINESURFACE_SUPPORT
int PrimitivesGeneratorPlugin::addRandomBSplineSurface(const Vector& _position, int nDiv)
{
    int id = -1;
    emit addEmptyObject(DATA_BSPLINE_SURFACE, id);
    if (id == -1) {
        return -1;
	}

    BSplineSurfaceObject *object = NULL;
    if (!PluginFunctions::getObject(id, object)) {
        return -1;
	}

    BSplineSurface *surf = object->splineSurface();
    typedef BSplineSurface::Point Point;
    std::vector<Point> cp(nDiv);

    for (int i = 0; i < nDiv; ++i) {
        double x = _position[0] + i - nDiv / 2.0;
        for (int j = 0; j < nDiv; ++j) {
            double y = _position[1] + j - nDiv / 2.0;
            cp[j] = Point(x, y, _position[2] + (2.0 * std::rand()) / RAND_MAX - 1);
        }
        surf->add_vector_m(cp);
    }
    surf->createKnots();

    emit updatedObject(id, UPDATE_ALL);
1250 1251
    emit createBackup(id, "Original Object");

1252 1253 1254 1255 1256
    PluginFunctions::viewAll();

    return id;
}
#endif
1257