Developer Documentation
PrimitivesGenerator.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 #include <cstdlib>
44 
45 #include "PrimitivesGenerator.hh"
46 #include <OpenFlipper/BasePlugin/WhatsThisGenerator.hh>
47 
48 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
49 #include "TetrahedralCuboidGenerator.hh"
50 #endif
51 
52 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
54 #endif
55 
56 #ifdef ENABLE_BSPLINECURVE_SUPPORT
58 #endif
59 
60 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
62 #endif
63 
64 PrimitivesGeneratorPlugin::PrimitivesGeneratorPlugin() :
65  triMesh_(0),
66  polyMesh_(0),
67  slices_(50),
68  stacks_(50),
69  primitivesMenu_(0)
70 {
71 
72 }
73 
74 PrimitivesGeneratorPlugin::~PrimitivesGeneratorPlugin()
75 {
76 
77  if ( OpenFlipper::Options::gui()) {
78  delete primitivesMenu_;
79  }
80 
81 }
82 
84 {
85  emit setSlotDescription("addCube(Vector,double)",
86  tr("Generates a poly mesh of cube (ObjectId is returned)"),
87  QString("Position,Length").split(","),
88  QString("Center position,Length of each edge").split(","));
89 
90  emit setSlotDescription("addTetrahedron(Vector,double)",
91  tr("Generates a tetrahedron (ObjectId is returned)"),
92  QString("Position,Length").split(","),
93  QString("Center position,Length of each edge").split(","));
94 
95  emit setSlotDescription("addIcosahedron(Vector,double)",
96  tr("Generates an icosahedron (ObjectId is returned)"),
97  QString("Position,Length").split(","),
98  QString("Center position,Length of each edge").split(","));
99 
100  emit setSlotDescription("addPyramid(Vector,double)",
101  tr("Generates a pyramid (ObjectId is returned)"),
102  QString("Position,Length").split(","),
103  QString("Center position,Length of each edge").split(","));
104 
105  emit setSlotDescription("addOctahedron(Vector,double)",
106  tr("Generates an octahedron (ObjectId is returned)"),
107  QString("Position,Length").split(","),
108  QString("Center position,Length of each edge").split(","));
109 
110  emit setSlotDescription("addDodecahedron(Vector,double)",
111  tr("Generates a dodecahedron (ObjectId is returned)"),
112  QString("Position,Length").split(","),
113  QString("Center position,Length of each edge").split(","));
114 
115  emit setSlotDescription("addSphere(Vector,double)",
116  tr("Generates a triangulated sphere with all vertical lines connected to the poles (ObjectId is returned)"),
117  QString("Position, Radius").split(","),
118  QString("Center position,Radius").split(","));
119 
120  emit setSlotDescription("addSubdivisionSphere(Vector,double)",
121  tr("Generates a triangulated sphere by subdivision without poles. (ObjectId is returned)"),
122  QString("Position, Radius").split(","),
123  QString("Center position,Radius").split(","));
124 
125  emit setSlotDescription("addTriangulatedCube(Vector,double)",
126  tr("Generates a triangular mesh of cube (ObjectId is returned)"),
127  QString("Position,Length").split(","),
128  QString("Center position,Length of each edge").split(","));
129 
130  emit setSlotDescription("addTriangulatedCylinder(Vector,Vector,double,double)",
131  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 #ifdef ENABLE_BSPLINECURVE_SUPPORT
136  emit setSlotDescription("addRandomBSplineCurve(Vector,int)",
137  tr("Generates a random B-spline curve (ObjectId is returned)"),
138  QString("Position,Count").split(","),
139  QString("Center position,Number of control points").split(","));
140 #endif
141 
142 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
143  emit setSlotDescription("addRandomBSplineSurface(Vector,int)",
144  tr("Generates a random B-spline surface (ObjectId is returned)"),
145  QString("Position,Count").split(","),
146  QString("Center position,Number of control points").split(","));
147 #endif
148 
149 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
150  emit setSlotDescription("addTetrahedralCube(Vector,double)",
151  tr("Generates a tetrahedral mesh of a cube (ObjectId is returned)"),
152  QString("Position,Length").split(","),
153  QString("Center position,Length of each edge").split(","));
154 
155  emit setSlotDescription("addTetrahedralCuboid(Vector,Vector,uint,uint,uint)",
156  tr("Generates a tetrahedral mesh of a cuboid (ObjectId is returned)"),
157  QString("Position,Lengths,Count,Count,Count").split(","),
158  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(","));
159 #endif
160 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
161  emit setSlotDescription("addHexahedralCube(Vector,double)",
162  tr("Generates a hexahedral mesh of a cube (ObjectId is returned)"),
163  QString("Position,Length").split(","),
164  QString("Center position,Length of each edge").split(","));
165 #endif
166 
167 }
168 
169 void PrimitivesGeneratorPlugin::pluginsInitialized() {
170 
171  if ( OpenFlipper::Options::gui()) {
172 
173  emit getMenubarMenu(tr("&Primitives"), primitivesMenu_, true );
174 
175  WhatsThisGenerator whatsThisGen("PrimitivesGenerator");
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  action = primitivesMenu_->addAction("Cube (Triangle Mesh)" ,this,SLOT(addTriangulatedCube()));
183  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
184  whatsThisGen.setWhatsThis(action,tr("Create a Cube."),"Cube");
185 
186  action = primitivesMenu_->addAction("Dodecahedron" ,this,SLOT(addDodecahedron()));
187  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_dodecahedron.png"));
188  whatsThisGen.setWhatsThis(action,tr("Create a Dodecahedron."), "Dodecahedron");
189 
190  action = primitivesMenu_->addAction("Icosahedron" ,this,SLOT(addIcosahedron()));
191  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_icosahedron.png"));
192  whatsThisGen.setWhatsThis(action,tr("Create a Icosahedron.","Icosahedron"));
193 
194  action = primitivesMenu_->addAction("Octahedron" ,this,SLOT(addOctahedron()));
195  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_octahedron.png"));
196  whatsThisGen.setWhatsThis(action,tr("Create an Octahedron."),"Octahedron");
197 
198  action = primitivesMenu_->addAction("Pyramid" ,this,SLOT(addPyramid()));
199  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_pyramid.png"));
200  whatsThisGen.setWhatsThis(action,tr("Create a Pyramid."),"Pyramid");
201 
202  action = primitivesMenu_->addAction("Cylinder (Triangle Mesh)" ,this,SLOT(addTriangulatedCylinder()));
203  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cylinder.png"));
204 
205  action = primitivesMenu_->addAction("Sphere (Poles,Triangle Mesh)",this,SLOT(addSphere()));
206  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_sphere.png"));
207  whatsThisGen.setWhatsThis(action,tr("Create a Sphere. All vertical lines connect to poles) "),"Sphere");
208 
209  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");
212 
213  action = primitivesMenu_->addAction("Tetrahedron",this,SLOT(addTetrahedron()));
214  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_tetrahedron.png"));
215  whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedron."),"Tetrahedron");
216 
217 #ifdef ENABLE_BSPLINECURVE_SUPPORT
218  action = primitivesMenu_->addAction("Random B-spline curve",this,SLOT(addRandomBSplineCurve()));
219  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr() + OpenFlipper::Options::dirSeparator() + "bspline_curve.png"));
220  whatsThisGen.setWhatsThis(action, tr("Create a random B-spline curve."), "B-spline curve");
221 #endif
222 
223 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
224  action = primitivesMenu_->addAction("Random B-spline surface",this,SLOT(addRandomBSplineSurface()));
225  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"bspline_surface.png"));
226  whatsThisGen.setWhatsThis(action,tr("Create a random B-spline surface."),"B-spline surface");
227 #endif
228 
229 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
230  action = primitivesMenu_->addAction("Cube (Tetrahedral Mesh)" ,this,SLOT(addTetrahedralCube()));
231  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
232  whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedral Cube."), "Cube");
233 
234  action = primitivesMenu_->addAction("Cuboid (Tetrahedral Mesh)" ,this,SLOT(addTetrahedralCuboid()));
235  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
236  whatsThisGen.setWhatsThis(action,tr("Create a Tetrahedral Cuboid."), "Cuboid");
237 #endif
238 
239 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
240  action = primitivesMenu_->addAction("Cube (Hexahedral Mesh)" ,this,SLOT(addHexahedralCube()));
241  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"primitive_cube.png"));
242  whatsThisGen.setWhatsThis(action,tr("Create a Hexahedral Cube."), "Cube");
243 
244 #endif
245  }
246 }
247 
248 
249 int PrimitivesGeneratorPlugin::addTriMesh() {
250  int objectId = -1;
251 
252  emit addEmptyObject( DATA_TRIANGLE_MESH, objectId );
253 
254  TriMeshObject* object;
255  if ( !PluginFunctions::getObject(objectId,object) ) {
256  emit log(LOGERR,"Unable to create new Object");
257  return -1;
258  }
259 
260  return objectId;
261 }
262 
263 int PrimitivesGeneratorPlugin::addPolyMesh() {
264  int objectId = -1;
265 
266  emit addEmptyObject( DATA_POLY_MESH, objectId );
267 
268  PolyMeshObject* object;
269  if ( !PluginFunctions::getObject(objectId,object) ) {
270  emit log(LOGERR,"Unable to create new Object");
271  return -1;
272  }
273 
274  return objectId;
275 }
276 
277 
278 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
279 int PrimitivesGeneratorPlugin::addPolyhedralMesh() {
280  int objectId = -1;
281 
282  emit addEmptyObject( DATA_POLYHEDRAL_MESH, objectId );
283 
284  PolyhedralMeshObject* object;
285  if (!PluginFunctions::getObject(objectId, object) ) {
286  emit log(LOGERR, "Unable to create new PolyhedralMesh object");
287  return -1;
288  }
289 
290  return objectId;
291 }
292 #endif
293 
294 
295 int PrimitivesGeneratorPlugin::addTetrahedron(const Vector& _position, const double _length) {
296 
297  int newObject = addTriMesh();
298 
299  TriMeshObject* object;
300  if ( !PluginFunctions::getObject(newObject,object) ) {
301  emit log(LOGERR,"Unable to create new Object");
302  return -1;
303  } else {
304 
305  object->setName( "Tetrahedron " + QString::number(newObject) );
306 
307  triMesh_ = object->mesh();
308 
309  triMesh_->clear();
310 
311  // Add 4 vertices
312  vhandles_.resize(4);
313 
314  const double halfSize = 0.5*_length;
315 
316  vhandles_[0] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize, halfSize)+_position);
317  vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfSize, halfSize, halfSize)+_position);
318  vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfSize, halfSize, -halfSize)+_position);
319  vhandles_[3] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize, -halfSize)+_position);
320 
321  // Add 4 faces
322  add_face(0,1,2);
323  add_face(0,2,3);
324  add_face(2,1,3);
325  add_face(3,1,0);
326 
327  triMesh_->update_normals();
328 
329  emit updatedObject(newObject,UPDATE_ALL);
330  emit createBackup(newObject, "Original Object");
331 
333 
334  return newObject;
335  }
336 
337  return -1;
338 }
339 
340 int PrimitivesGeneratorPlugin::addTriangulatedCube(const Vector& _position,const double _length) {
341  int newObject = addTriMesh();
342 
343  TriMeshObject* object;
344  if ( !PluginFunctions::getObject(newObject,object) ) {
345  emit log(LOGERR,"Unable to create new Object");
346  return -1;
347  } else {
348 
349  object->setName( "Cube " + QString::number(newObject) );
350 
351  triMesh_ = object->mesh();
352 
353  triMesh_->clear();
354 
355  // Add 8 vertices
356  vhandles_.resize(8);
357 
358  const double halfSize = 0.5*_length;
359 
360  vhandles_[0] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize, halfSize)+_position);
361  vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfSize, halfSize, halfSize)+_position);
362  vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfSize, halfSize, halfSize)+_position);
363  vhandles_[3] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize, halfSize)+_position);
364  vhandles_[4] = triMesh_->add_vertex(TriMesh::Point( halfSize, -halfSize,-halfSize)+_position);
365  vhandles_[5] = triMesh_->add_vertex(TriMesh::Point( halfSize, halfSize,-halfSize)+_position);
366  vhandles_[6] = triMesh_->add_vertex(TriMesh::Point(-halfSize, halfSize,-halfSize)+_position);
367  vhandles_[7] = triMesh_->add_vertex(TriMesh::Point(-halfSize, -halfSize,-halfSize)+_position);
368 
369 
370  // Add 12 faces
371  add_face(0,1,2);
372  add_face(0,2,3);
373  add_face(0,5,1);
374  add_face(5,0,4);
375  add_face(4,0,7);
376  add_face(7,0,3);
377 
378  add_face(7,3,6);
379  add_face(6,3,2);
380  add_face(6,2,5);
381  add_face(5,2,1);
382  add_face(6,5,4);
383  add_face(6,4,7);
384 
385  triMesh_->update_normals();
386 
387  emit updatedObject(newObject,UPDATE_ALL);
388  emit createBackup(newObject, "Original Object");
389 
391 
392  return newObject;
393  }
394 
395  return -1;
396 }
397 
398 int PrimitivesGeneratorPlugin::addCube(const Vector& _position,const double _length) {
399  int newObject = addPolyMesh();
400 
401  PolyMeshObject* object;
402  if ( !PluginFunctions::getObject(newObject,object) ) {
403  emit log(LOGERR,"Unable to create new Object");
404  return -1;
405  } else {
406 
407  object->setName( "Cube " + QString::number(newObject) );
408 
409  polyMesh_ = object->mesh();
410  polyMesh_->clear();
411 
412  // Add 8 vertices
413  vhandles_.resize(8);
414 
415  const double halfSize = 0.5*_length;
416  // 6------5
417  // /| /|
418  // 2------1 |
419  // | | | |
420  // | 7----|-4
421  // |/ |/
422  // 3------0
423  vhandles_[0] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, -halfSize, halfSize)+_position);
424  vhandles_[1] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, halfSize, halfSize)+_position);
425  vhandles_[2] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, halfSize, halfSize)+_position);
426  vhandles_[3] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, -halfSize, halfSize)+_position);
427  vhandles_[4] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, -halfSize,-halfSize)+_position);
428  vhandles_[5] = polyMesh_->add_vertex(PolyMesh::Point( halfSize, halfSize,-halfSize)+_position);
429  vhandles_[6] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, halfSize,-halfSize)+_position);
430  vhandles_[7] = polyMesh_->add_vertex(PolyMesh::Point(-halfSize, -halfSize,-halfSize)+_position);
431 
432  // Add faces
433  add_face(0,1,2,3);
434  add_face(0,4,5,1);
435  add_face(4,7,6,5);
436  add_face(7,3,2,6);
437  add_face(1,5,6,2);
438  add_face(0,3,7,4);
439 
440  polyMesh_->update_normals();
441 
442  emit updatedObject(newObject,UPDATE_ALL);
443  emit createBackup(newObject, "Original Object");
444 
446 
447  return newObject;
448  }
449 
450  return -1;
451 }
452 
453 //========================================================================
454 // Tetrahedral cube
455 //========================================================================
456 
457 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
458 
459 int PrimitivesGeneratorPlugin::addTetrahedralCube(const Vector& _position, const double _length)
460 {
461  return addTetrahedralCuboid(_position, Vector(_length, _length, _length), 1, 1, 1);
462 }
463 
464 #endif
465 
466 //========================================================================
467 // Tetrahedral Cuboid
468 //========================================================================
469 
470 #ifdef ENABLE_POLYHEDRALMESH_SUPPORT
471 
472 int PrimitivesGeneratorPlugin::addTetrahedralCuboid(const Vector& _position,
473  const Vector& _length, const unsigned int n_x, const unsigned int n_y, const unsigned int n_z)
474 {
475 
476  int object_id = addPolyhedralMesh();
477  PolyhedralMeshObject* object;
478 
479  if (!PluginFunctions::getObject(object_id, object)) {
480  return -1;
481  }
482 
483  object->setName("Cuboid " + QString::number(object_id));
484 
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  object->setObjectDrawMode(ACG::SceneGraph::DrawModes::getDrawMode("Cells (flat shaded)"));
492 
493  return object_id;
494 }
495 
496 #endif
497 
498 //========================================================================
499 // Hexahedral Cube & Cuboid
500 //========================================================================
501 
502 #ifdef ENABLE_HEXAHEDRALMESH_SUPPORT
503 
504 int PrimitivesGeneratorPlugin::addHexahedralCube(const Vector& _position, const double _length)
505 {
506  int object_id;
507  emit addEmptyObject( DATA_HEXAHEDRAL_MESH, object_id);
508 
509  HexahedralMeshObject* object;
510  if (!PluginFunctions::getObject(object_id, object) ) {
511  emit log(LOGERR, "Unable to create new HexahedralMesh object");
512  return -1;
513  }
514  object->setName( "HexCube " + QString::number(object_id) );
515 
516  auto mesh = object->mesh();
517  namespace OVM = OpenVolumeMesh;
518  std::vector<OVM::VertexHandle> vertices(8);
519 
520  const double halfSize = 0.5*_length;
521  vertices[0] = mesh->add_vertex(Vector(-halfSize, -halfSize, halfSize)+_position);
522  vertices[1] = mesh->add_vertex(Vector( halfSize, -halfSize, halfSize)+_position);
523  vertices[2] = mesh->add_vertex(Vector( halfSize, halfSize, halfSize)+_position);
524  vertices[3] = mesh->add_vertex(Vector(-halfSize, halfSize, halfSize)+_position);
525  vertices[4] = mesh->add_vertex(Vector(-halfSize, -halfSize,-halfSize)+_position);
526  vertices[5] = mesh->add_vertex(Vector(-halfSize, halfSize,-halfSize)+_position);
527  vertices[6] = mesh->add_vertex(Vector( halfSize, halfSize,-halfSize)+_position);
528  vertices[7] = mesh->add_vertex(Vector( halfSize, -halfSize,-halfSize)+_position);
529 
530  mesh->add_cell(vertices);
531 
532  emit updatedObject(object_id, UPDATE_ALL);
533  emit createBackup(object_id, "Original Object");
534 
535  object->setObjectDrawMode(ACG::SceneGraph::DrawModes::getDrawMode("Cells (flat shaded)"));
536 
538 
539  return object_id;
540 }
541 
542 #endif
543 
544 //========================================================================
545 // Cylinder
546 //========================================================================
547 
548 
549 ACG::Vec3d PrimitivesGeneratorPlugin::positionOnCylinder(const int _sliceNumber,
550  const int _stackNumber,
551  const Vector _position,
552  const Vector _axis,
553  const double _radius,
554  const double _height)
555 {
556  ACG::Vec3d position;
557 
558  const ACG::Vec3d right = (ACG::Geometry::perpendicular(_axis)).normalized();
559  const ACG::Vec3d left = (cross( _axis, right)).normalized();
560 
561  double beta = ((2.0 * M_PI) / double(slices_)) * double(_sliceNumber);
562 
563  if ( _sliceNumber == 0 && _stackNumber == 0) {
564  position[0] = 0.0;
565  position[1] = 0.0;
566  position[2] = _height;
567  } else if ( _sliceNumber == slices_ && _stackNumber == stacks_ ) {
568  position[0] = 0.0;
569  position[1] = 0.0;
570  position[2] = 0.0;
571  } else {
572  position[0] = sin(beta) * _radius;
573  position[1] = cos(beta) * _radius;
574  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  return position;
580 }
581 
582 int PrimitivesGeneratorPlugin::addTriangulatedCylinder(const Vector& _position,const Vector& _axis,const double _radius,const double _height,const bool _top,const bool _bottom ) {
583 
584  // TODO: Generate texture coordinates for cylinder (Glu compatible)
585  int newObject = addTriMesh();
586 
587  TriMeshObject* object;
588  if (!PluginFunctions::getObject(newObject, object)) {
589  emit log(LOGERR, "Unable to create new Object");
590  return -1;
591  } else {
592 
593  object->setName( "Cylinder " + QString::number(newObject) );
594 
595  triMesh_ = object->mesh();
596 
597  triMesh_->clear();
598 
599  //triMesh_->request_vertex_texcoords2D();
600 
601  TriMesh::VertexHandle vh;
602  TriMesh::VertexHandle top = triMesh_->add_vertex(positionOnCylinder(0, 0,_position,_axis,_radius,_height));
603  //triMesh_->set_texcoord2D(vh, texCoordOnSphere(0, 0));
604 
605  for (int st = 1; st < stacks_; ++st) {
606  for (int sl = 0; sl < slices_; ++sl) {
607  vh = triMesh_->add_vertex(positionOnCylinder(sl, st,_position,_axis,_radius,_height));
608  //triMesh_->set_texcoord2D(vh, texCoordOnSphere(sl, st));
609  }
610  }
611 
612  TriMesh::VertexHandle bottom = triMesh_->add_vertex(positionOnCylinder(slices_, stacks_,_position,_axis,_radius,_height));
613  //triMesh_->set_texcoord2D(vh, texCoordOnSphere(slices_, stacks_));
614 
615  std::vector<TriMesh::VertexHandle> vhandles;
616 
617  // Add top triangle fan ( Vertex index is shifted by one for the first slice )
618  if ( _top ) {
619  for (int sl = 1; sl < slices_ + 1; ++sl) {
620 
621  vhandles.clear();
622 
623  vhandles.push_back(triMesh_->vertex_handle(sl));
624  vhandles.push_back(triMesh_->vertex_handle(0));
625  vhandles.push_back(triMesh_->vertex_handle(1 * 1 + (sl % slices_)));
626 
627  triMesh_->add_face(vhandles);
628  }
629  } else {
630  triMesh_->delete_vertex(top);
631  }
632 
633  for (int st = 0; st < stacks_ - 2; ++st) {
634 
635  // Move around one slice
636  for (int sl = 0; sl < slices_; ++sl) {
637 
638  // Offset 1 because of singular vertex
639  unsigned int startTop = 1 + slices_ * st;
640  unsigned int startBottom = 1 + slices_ * (st + 1);
641 
642  vhandles.clear();
643 
644  vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
645  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
646  vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
647 
648  triMesh_->add_face(vhandles);
649 
650  vhandles.clear();
651 
652  vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
653  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
654  vhandles.push_back(triMesh_->vertex_handle(startBottom + ((sl + 1) % slices_)));
655 
656  triMesh_->add_face(vhandles);
657  }
658 
659  }
660 
661  const int startTop = 1 + (stacks_ - 2) * slices_;
662  const int bottomVertex = 1 + (stacks_ - 1) * slices_;
663 
664  // Add bottom triangle fan
665  if ( _bottom) {
666  for (int sl = 0; sl < slices_; ++sl) {
667 
668  vhandles.clear();
669 
670  vhandles.push_back(triMesh_->vertex_handle(bottomVertex));
671  vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
672  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
673 
674  triMesh_->add_face(vhandles);
675  }
676  } else {
677  triMesh_->delete_vertex(bottom);
678  }
679 
680  // Cleanup if bottom or top vertex is missing
681  triMesh_->garbage_collection();
682 
683  triMesh_->update_normals();
684 
685  emit updatedObject(newObject,UPDATE_ALL);
686  emit createBackup(newObject, "Original Object");
687 
689 
690  return object->id();
691  }
692 
693 }
694 
695 
696 //========================================================================
697 // Sphere
698 //========================================================================
699 
700 
701 ACG::Vec3d PrimitivesGeneratorPlugin::positionOnSphere(int _sliceNumber, int _stackNumber, double _radius, const Vector& _position)
702 {
703  ACG::Vec3d position;
704 
705  double alpha = (M_PI / double(stacks_)) * double(_stackNumber);
706  double beta = ((2.0 * M_PI) / double(slices_)) * double(_sliceNumber);
707 
708  double ringRadius = sin(alpha);
709  position[0] = sin(beta) * ringRadius * _radius;
710  position[1] = cos(beta) * ringRadius * _radius;
711  position[2] = cos(alpha)* _radius;
712 
713  return _position+position;
714 }
715 
716 //------------------------------------------------------------------------
717 
718 ACG::Vec2f PrimitivesGeneratorPlugin::texCoordOnSphere(int _sliceNumber, int _stackNumber)
719 {
720  ACG::Vec2f texCoord;
721 
722  double alpha = (M_PI / double(stacks_)) * double(_stackNumber);
723  texCoord[0] = double(_sliceNumber) / double(slices_);
724  texCoord[1] = 0.5 * (cos(alpha) + 1.0);
725 
726  return texCoord;
727 }
728 
729 
730 //------------------------------------------------------------------------
731 
732 int PrimitivesGeneratorPlugin::addSphere(const Vector& _position, const double _radius)
733 {
734  int newObject = addTriMesh();
735 
736  TriMeshObject* object;
737  if (!PluginFunctions::getObject(newObject, object)) {
738  emit log(LOGERR, "Unable to create new Object");
739  return -1;
740  } else {
741 
742  object->setName( "Sphere " + QString::number(newObject) );
743 
744  triMesh_ = object->mesh();
745 
746  triMesh_->clear();
747 
748  triMesh_->request_vertex_texcoords2D();
749 
750  TriMesh::VertexHandle vh;
751 
752  vh = triMesh_->add_vertex(positionOnSphere(0, 0, _radius,_position));
753  triMesh_->set_texcoord2D(vh, texCoordOnSphere(0, 0));
754 
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  triMesh_->set_texcoord2D(vh, texCoordOnSphere(sl, st));
759  }
760  }
761 
762  vh = triMesh_->add_vertex(positionOnSphere(slices_, stacks_, _radius,_position));
763  triMesh_->set_texcoord2D(vh, texCoordOnSphere(slices_, stacks_));
764 
765  std::vector<TriMesh::VertexHandle> vhandles;
766 
767  // Add top triangle fan ( Vertex index is shifted by one for the first slice )
768  for (int sl = 1; sl < slices_ + 1; ++sl) {
769 
770  vhandles.clear();
771 
772  vhandles.push_back(triMesh_->vertex_handle(sl));
773  vhandles.push_back(triMesh_->vertex_handle(0));
774  vhandles.push_back(triMesh_->vertex_handle(1 * 1 + (sl % slices_)));
775 
776  triMesh_->add_face(vhandles);
777  }
778 
779  for (int st = 0; st < stacks_ - 2; ++st) {
780 
781  // Move around one slice
782  for (int sl = 0; sl < slices_; ++sl) {
783 
784  // Offset 1 because of singular vertex
785  unsigned int startTop = 1 + slices_ * st;
786  unsigned int startBottom = 1 + slices_ * (st + 1);
787 
788  vhandles.clear();
789 
790  vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
791  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
792  vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
793 
794  triMesh_->add_face(vhandles);
795 
796  vhandles.clear();
797 
798  vhandles.push_back(triMesh_->vertex_handle(startBottom + sl));
799  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
800  vhandles.push_back(triMesh_->vertex_handle(startBottom + ((sl + 1) % slices_)));
801 
802  triMesh_->add_face(vhandles);
803  }
804 
805  }
806 
807  const int startTop = 1 + (stacks_ - 2) * slices_;
808  const int bottomVertex = 1 + (stacks_ - 1) * slices_;
809 
810  // Add bottom triangle fan
811  for (int sl = 0; sl < slices_; ++sl) {
812 
813  vhandles.clear();
814 
815  vhandles.push_back(triMesh_->vertex_handle(bottomVertex));
816  vhandles.push_back(triMesh_->vertex_handle(startTop + sl));
817  vhandles.push_back(triMesh_->vertex_handle(startTop + ((sl + 1) % slices_)));
818 
819  triMesh_->add_face(vhandles);
820  }
821 
822  triMesh_->update_normals();
823 
824  emit updatedObject(newObject,UPDATE_ALL);
825  emit createBackup(newObject, "Original Object");
826 
828 
829  return object->id();
830  }
831 
832 
833 }
834 
835 //------------------------------------------------------------------------
836 
837 int PrimitivesGeneratorPlugin::addSubdivisionSphere(const Vector& _position, const double _radius)
838 {
839 
840  // Create the underlying octahedron
841  int newObject = addTriMesh();
842 
843  TriMeshObject* object;
844  if (!PluginFunctions::getObject(newObject, object)) {
845  emit log(LOGERR, "Unable to create new Object");
846  return -1;
847  } else {
848  object->setName( "Sphere " + QString::number(newObject) );
849 
850  triMesh_ = object->mesh();
851  constructOctahedron(_position, _radius);
852 
853  // Number of subdivision iterations for the sphere
854  const size_t subdivisionSteps = 4;
855 
856  for (size_t i = 0 ; i < subdivisionSteps; ++i) {
857 
858  // Call the subdivision algorithm
859  RPC::callFunction("subdivider", "subdivide", newObject, QString("loop"), 1, false);
860 
861  // Reposition vertices onto sphere
862  for (TriMesh::VertexIter v_it = triMesh_->vertices_begin(); v_it != triMesh_->vertices_end(); ++v_it) {
863  TriMesh::Point p = triMesh_->point(*v_it);
864  p -= _position;
865  p = _radius * p.normalize() + _position;
866  triMesh_->set_point(*v_it, p);
867  }
868  }
869 
870  // Make sure that the normals are fine
871  triMesh_->update_normals();
872 
873  emit updatedObject(newObject, UPDATE_ALL);
874  emit createBackup(newObject, "Original Object");
875 
877 
878  return newObject;
879 
880  }
881 
882 
883 }
884 
885 
886 //========================================================================
887 // Pyramid
888 //========================================================================
889 
890 int PrimitivesGeneratorPlugin::addPyramid(const Vector& _position,const double _length) {
891  int newObject = addTriMesh();
892 
893  TriMeshObject* object;
894  if ( !PluginFunctions::getObject(newObject,object) ) {
895  emit log(LOGERR,"Unable to create new Object");
896  return -1;
897  } else {
898 
899  object->setName( "Pyramid " + QString::number(newObject) );
900 
901  triMesh_ = object->mesh();
902 
903  triMesh_->clear();
904 
905  // Add 5 vertices
906  vhandles_.resize(5);
907 
908  const double halfLength = 0.5*_length;
909 
910  vhandles_[0] = triMesh_->add_vertex(TriMesh::Point( halfLength, -halfLength, 0.0)+_position);
911  vhandles_[1] = triMesh_->add_vertex(TriMesh::Point( halfLength, halfLength, 0.0)+_position);
912  vhandles_[2] = triMesh_->add_vertex(TriMesh::Point(-halfLength, halfLength, 0.0)+_position);
913  vhandles_[3] = triMesh_->add_vertex(TriMesh::Point(-halfLength, -halfLength, 0.0)+_position);
914 
915  vhandles_[4] = triMesh_->add_vertex(TriMesh::Point(0.0, 0.0, sqrt(2.0)*halfLength));
916 
917  // Add 6 faces
918  add_face(2,1,0);
919  add_face(3,2,0);
920  add_face(4,0,1);
921 
922  add_face(3,0,4);
923  add_face(4,2,3);
924  add_face(1,2,4);
925 
926  triMesh_->update_normals();
927 
928  emit updatedObject(newObject,UPDATE_ALL);
929  emit createBackup(newObject, "Original Object");
930 
932 
933  return newObject;
934  }
935 
936  return -1;
937 }
938 
939 void PrimitivesGeneratorPlugin::add_face(int _vh1 , int _vh2, int _vh3) {
940  triMesh_->add_face(
941  static_cast<TriMesh::VertexHandle>(_vh1),
942  static_cast<TriMesh::VertexHandle>(_vh2),
943  static_cast<TriMesh::VertexHandle>(_vh3)
944  );
945 }
946 
947 void PrimitivesGeneratorPlugin::add_face(int _vh1, int _vh2, int _vh3, int _vh4)
948 {
949  polyMesh_->add_face(
950  static_cast<PolyMesh::VertexHandle>(_vh1),
951  static_cast<PolyMesh::VertexHandle>(_vh2),
952  static_cast<PolyMesh::VertexHandle>(_vh3),
953  static_cast<PolyMesh::VertexHandle>(_vh4)
954  );
955 }
956 
957 void PrimitivesGeneratorPlugin::add_face( int _vh1 , int _vh2, int _vh3, int _vh4 , int _vh5 ) {
958  std::vector<PolyMesh::VertexHandle> vhandles;
959 
960  vhandles.push_back(vphandles_[_vh1]);
961  vhandles.push_back(vphandles_[_vh2]);
962  vhandles.push_back(vphandles_[_vh3]);
963  vhandles.push_back(vphandles_[_vh4]);
964  vhandles.push_back(vphandles_[_vh5]);
965 
966  polyMesh_->add_face(vhandles);
967 }
968 
969 int PrimitivesGeneratorPlugin::addIcosahedron(const Vector& _position,const double _length) {
970  int newObject = addTriMesh();
971 
972  TriMeshObject* object;
973  if ( !PluginFunctions::getObject(newObject,object) ) {
974  emit log(LOGERR,"Unable to create new Object");
975  return -1;
976  } else {
977 
978  object->setName( "Icosahedron " + QString::number(newObject) );
979 
980  triMesh_ = object->mesh();
981 
982  triMesh_->clear();
983 
984  // Add 12 vertices
985  vhandles_.resize(12);
986 
987  const double phi = 0.5 * (1.0 + sqrt(5.0));
988  //double norm = 1.0 / sqrt(1.0 + phi*phi);
989  const double norm = 1.0;
990  const double halfLength = 0.5*_length;
991 
992  vhandles_[0 ] = triMesh_->add_vertex(norm * TriMesh::Point( 0.0 , -halfLength , -phi )+_position);
993  vhandles_[1 ] = triMesh_->add_vertex(norm * TriMesh::Point( 0.0 , halfLength , -phi )+_position);
994  vhandles_[2 ] = triMesh_->add_vertex(norm * TriMesh::Point( 0.0 , halfLength , phi )+_position);
995  vhandles_[3 ] = triMesh_->add_vertex(norm * TriMesh::Point( 0.0 , -halfLength , phi )+_position);
996 
997  vhandles_[4 ] = triMesh_->add_vertex(norm * TriMesh::Point( -halfLength , -phi , 0.0 )+_position);
998  vhandles_[5 ] = triMesh_->add_vertex(norm * TriMesh::Point( halfLength , -phi , 0.0 )+_position);
999  vhandles_[6 ] = triMesh_->add_vertex(norm * TriMesh::Point( halfLength , phi , 0.0 )+_position);
1000  vhandles_[7 ] = triMesh_->add_vertex(norm * TriMesh::Point( -halfLength , phi , 0.0 )+_position);
1001 
1002  vhandles_[8 ] = triMesh_->add_vertex(norm * TriMesh::Point( -phi , 0.0 , -halfLength )+_position);
1003  vhandles_[9 ] = triMesh_->add_vertex(norm * TriMesh::Point( -phi , 0.0 , halfLength )+_position);
1004  vhandles_[10] = triMesh_->add_vertex(norm * TriMesh::Point( phi , 0.0 , halfLength )+_position);
1005  vhandles_[11] = triMesh_->add_vertex(norm * TriMesh::Point( phi , 0.0 , -halfLength )+_position);
1006 
1007 
1008  // Add 20 faces
1009  add_face(2,6,7);
1010  add_face(7,6,1);
1011 
1012  add_face(11,0,1);
1013  add_face(0, 8,1);
1014 
1015  add_face(4,9,8);
1016  add_face(8,9,7);
1017 
1018  add_face(9,3,2);
1019  add_face(10,2,3);
1020 
1021  add_face(5,11,10);
1022  add_face(11,6,10);
1023 
1024  add_face(0,5,4);
1025  add_face(5,3,4);
1026 
1027  // Upper block
1028  add_face(6,2,10);
1029  add_face(6,11,1);
1030  add_face(1,8,7);
1031  add_face(9,2,7);
1032 
1033  // Lower block
1034  add_face(3,5,10);
1035  add_face(0,11,5);
1036  add_face(3,9,4);
1037  add_face(0,4,8);
1038 
1039  triMesh_->update_normals();
1040 
1041  emit updatedObject(newObject,UPDATE_ALL);
1042  emit createBackup(newObject, "Original Object");
1043 
1045 
1046  return newObject;
1047  }
1048 
1049  return -1;
1050 }
1051 
1052 void PrimitivesGeneratorPlugin::constructOctahedron(const Vector& _position, const double _length)
1053 {
1054  triMesh_->clear();
1055 
1056  // Add 6 vertices
1057  vhandles_.resize(6);
1058 
1059  const double sqrtLength = sqrt(_length);
1060 
1061  vhandles_[0 ] = triMesh_->add_vertex(TriMesh::Point(-sqrtLength, 0.0, 0.0)+_position);
1062  vhandles_[1 ] = triMesh_->add_vertex(TriMesh::Point( 0.0, -sqrtLength, 0.0)+_position);
1063  vhandles_[2 ] = triMesh_->add_vertex(TriMesh::Point( sqrtLength, 0.0, 0.0)+_position);
1064  vhandles_[3 ] = triMesh_->add_vertex(TriMesh::Point( 0.0, sqrtLength, 0.0)+_position);
1065 
1066  vhandles_[4 ] = triMesh_->add_vertex(TriMesh::Point( 0.0, 0.0, sqrtLength)+_position);
1067  vhandles_[5 ] = triMesh_->add_vertex(TriMesh::Point( 0.0, 0.0, -sqrtLength)+_position);
1068 
1069 
1070  // Add 8 faces
1071  add_face(0,1,4);
1072  add_face(1,2,4);
1073 
1074  add_face(2,3,4);
1075  add_face(0,4,3);
1076 
1077  add_face(5,1,0);
1078  add_face(5,2,1);
1079 
1080  add_face(5,3,2);
1081  add_face(5,0,3);
1082 
1083  triMesh_->update_normals();
1084 }
1085 
1086 int PrimitivesGeneratorPlugin::addOctahedron(const Vector& _position,const double _length) {
1087  int newObject = addTriMesh();
1088 
1089  TriMeshObject* object;
1090  if ( !PluginFunctions::getObject(newObject,object) ) {
1091  emit log(LOGERR,"Unable to create new Object");
1092  return -1;
1093  } else {
1094 
1095  object->setName( "Octahedron " + QString::number(newObject) );
1096 
1097  triMesh_ = object->mesh();
1098 
1099  constructOctahedron(_position, _length);
1100 
1101  emit updatedObject(newObject,UPDATE_ALL);
1102  emit createBackup(newObject, "Original Object");
1103 
1105 
1106  return newObject;
1107  }
1108 
1109  return -1;
1110 }
1111 
1112 int PrimitivesGeneratorPlugin::addDodecahedron(const Vector& _position,const double _length) {
1113  int newObject = addPolyMesh();
1114 
1115  PolyMeshObject* object;
1116  if ( !PluginFunctions::getObject(newObject,object) ) {
1117  emit log(LOGERR,"Unable to create new Object");
1118  return -1;
1119  } else {
1120 
1121  object->setName( "Dodecahedron " + QString::number(newObject) );
1122 
1123  polyMesh_ = object->mesh();
1124 
1125  polyMesh_->clear();
1126 
1127  // Add 20 vertices
1128  vphandles_.resize(20);
1129 
1130  const double phi = (1.0 + sqrt(5.0)) / 2.0;
1131  const double halfLength = 0.5*_length;
1132 
1133 
1134  vphandles_[0 ] = polyMesh_->add_vertex(TriMesh::Point( halfLength , halfLength , halfLength )+_position);
1135  vphandles_[1 ] = polyMesh_->add_vertex(TriMesh::Point( halfLength , halfLength ,-halfLength )+_position);
1136  vphandles_[2 ] = polyMesh_->add_vertex(TriMesh::Point( halfLength , -halfLength , halfLength )+_position);
1137  vphandles_[3 ] = polyMesh_->add_vertex(TriMesh::Point( halfLength , -halfLength ,-halfLength )+_position);
1138  vphandles_[4 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , halfLength , halfLength )+_position);
1139  vphandles_[5 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , halfLength ,-halfLength )+_position);
1140  vphandles_[6 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , -halfLength , halfLength )+_position);
1141  vphandles_[7 ] = polyMesh_->add_vertex(TriMesh::Point( -halfLength , -halfLength ,-halfLength )+_position);
1142 
1143  vphandles_[8 ] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , halfLength / phi , phi )+_position);
1144  vphandles_[9 ] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , halfLength / phi , -phi )+_position);
1145  vphandles_[10] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , -halfLength / phi , phi )+_position);
1146  vphandles_[11] = polyMesh_->add_vertex(TriMesh::Point( 0.0 , -halfLength / phi , -phi )+_position);
1147 
1148  vphandles_[12] = polyMesh_->add_vertex(TriMesh::Point( halfLength / phi , phi, 0.0)+_position);
1149  vphandles_[13] = polyMesh_->add_vertex(TriMesh::Point( halfLength / phi , -phi, 0.0)+_position);
1150  vphandles_[14] = polyMesh_->add_vertex(TriMesh::Point( -halfLength / phi , phi, 0.0)+_position);
1151  vphandles_[15] = polyMesh_->add_vertex(TriMesh::Point( -halfLength / phi , -phi, 0.0)+_position);
1152 
1153  vphandles_[16] = polyMesh_->add_vertex(TriMesh::Point( phi , 0.0 , halfLength / phi)+_position);
1154  vphandles_[17] = polyMesh_->add_vertex(TriMesh::Point( phi , 0.0 ,-halfLength / phi)+_position);
1155  vphandles_[18] = polyMesh_->add_vertex(TriMesh::Point( -phi , 0.0 , halfLength / phi)+_position);
1156  vphandles_[19] = polyMesh_->add_vertex(TriMesh::Point( -phi , 0.0 ,-halfLength / phi)+_position);
1157 
1158  // Add 12 faces
1159  add_face(14, 5,19,18, 4);
1160  add_face( 5, 9,11, 7,19);
1161  add_face( 6,15,13, 2,10);
1162  add_face(12, 0,16,17, 1);
1163 
1164  add_face( 0, 8,10, 2,16);
1165  add_face(16, 2,13, 3,17);
1166  add_face( 3,13,15, 7,11);
1167  add_face( 7,15, 6,18,19);
1168 
1169  add_face( 4,18, 6,10, 8);
1170  add_face( 4, 8, 0,12,14);
1171  add_face(14,12, 1, 9, 5);
1172  add_face( 9, 1,17, 3,11);
1173 
1174  polyMesh_->update_normals();
1175 
1176  emit updatedObject(newObject,UPDATE_ALL);
1177  emit createBackup(newObject, "Original Object");
1178 
1180 
1181  return newObject;
1182  }
1183 
1184  return -1;
1185 }
1186 
1187 #ifdef ENABLE_BSPLINECURVE_SUPPORT
1188 int PrimitivesGeneratorPlugin::addRandomBSplineCurve(const Vector& _position, int nDiv)
1189 {
1190  int id = -1;
1191  emit addEmptyObject(DATA_BSPLINE_CURVE, id);
1192  if (id == -1) {
1193  return -1;
1194  }
1195 
1196  BSplineCurveObject *object = NULL;
1197  if (!PluginFunctions::getObject(id, object)) {
1198  return -1;
1199  }
1200 
1201  BSplineCurve *curve = object->splineCurve();
1202 
1203  curve->autocompute_knotvector(true);
1204  for (int i = 0; i < nDiv; ++i) {
1205  double x = _position[0] + i - nDiv / 2.0;
1206 
1207  double r = (2.0 * std::rand()) / RAND_MAX - 1.0;
1208  BSplineCurve::Point cp(x, _position[1] + r, _position[2]);
1209  curve->add_control_point(cp);
1210  }
1211 
1212  emit updatedObject(id, UPDATE_ALL);
1213  emit createBackup(id, "Original Object");
1214 
1216 
1217  return id;
1218 }
1219 #endif
1220 
1221 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
1222 int PrimitivesGeneratorPlugin::addRandomBSplineSurface(const Vector& _position, int nDiv)
1223 {
1224  int id = -1;
1225  emit addEmptyObject(DATA_BSPLINE_SURFACE, id);
1226  if (id == -1) {
1227  return -1;
1228  }
1229 
1230  BSplineSurfaceObject *object = NULL;
1231  if (!PluginFunctions::getObject(id, object)) {
1232  return -1;
1233  }
1234 
1235  BSplineSurface *surf = object->splineSurface();
1236  typedef BSplineSurface::Point Point;
1237  std::vector<Point> cp(nDiv);
1238 
1239  for (int i = 0; i < nDiv; ++i) {
1240  double x = _position[0] + i - nDiv / 2.0;
1241  for (int j = 0; j < nDiv; ++j) {
1242  double y = _position[1] + j - nDiv / 2.0;
1243  cp[j] = Point(x, y, _position[2] + (2.0 * std::rand()) / RAND_MAX - 1);
1244  }
1245  surf->add_vector_m(cp);
1246  }
1247  surf->createKnots();
1248 
1249  emit updatedObject(id, UPDATE_ALL);
1250  emit createBackup(id, "Original Object");
1251 
1253 
1254  return id;
1255 }
1256 #endif
1257 
void add_vector_m(const std::vector< Point > &_control_polygon)
Adds a control point n-vector.
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void initializePlugin()
BaseInterface.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
void createKnots()
Creates interpolating knotvectors 0...0, 1, 2, ..., n...n.
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
VertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
const DrawMode & getDrawMode(const std::string &_name)
Get a custom DrawMode.
Definition: DrawModes.cc:807
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:429
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Definition: RPCWrappers.cc:55
void add_control_point(const Point &_cp)
add a control point
void setName(QString _name)
Set the name of the Object.
VectorT< Scalar, 3 > perpendicular(const VectorT< Scalar, 3 > &v)
find a vector that&#39;s perpendicular to _v
Definition: Algorithms.cc:1152
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
#define DATA_BSPLINE_SURFACE
#define DATA_HEXAHEDRAL_MESH
void viewAll(int _viewer)
View the whole scene.
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
#define DATA_POLYHEDRAL_MESH
ACG::Vec3d Vector
Standard Type for 3d Vector used for scripting.
Definition: DataTypes.hh:174
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
MeshT * mesh()
return a pointer to the mesh
#define DATA_BSPLINE_CURVE
Definition: BSplineCurve.hh:67
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
void setWhatsThis(QAction *_action, const QString &_msg, const QString &_ref="", const QString &_site="index.html") const
sets a whatsThis Message plus link to the doc for the given QAction