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
53 #include <ObjectTypes/HexahedralMesh/HexahedralMesh.hh>
54 #endif
55
56 #ifdef ENABLE_BSPLINECURVE_SUPPORT
57 #include <ObjectTypes/BSplineCurve/BSplineCurve.hh>
58 #endif
59
60 #ifdef ENABLE_BSPLINESURFACE_SUPPORT
61 #include <ObjectTypes/BSplineSurface/BSplineSurface.hh>
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
83 void PrimitivesGeneratorPlugin::initializePlugin()
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
332 PluginFunctions::viewAll();
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
390 PluginFunctions::viewAll();
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
445 PluginFunctions::viewAll();
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)"));
491 PluginFunctions::viewAll();
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
537 PluginFunctions::viewAll();
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
688 PluginFunctions::viewAll();
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
827 PluginFunctions::viewAll();
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
876 PluginFunctions::viewAll();
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
931 PluginFunctions::viewAll();
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
1044 PluginFunctions::viewAll();
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
1104 PluginFunctions::viewAll();
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
1179 PluginFunctions::viewAll();
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
1215 PluginFunctions::viewAll();
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
1252 PluginFunctions::viewAll();
1253
1254 return id;
1255 }
1256 #endif
1257
LOGERR
Definition: LoggingInterface.hh:96
BSplineSurface.hh
WhatsThisGenerator
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
Definition: WhatsThisGenerator.hh:65
PrimitivesGeneratorPlugin::initializePlugin
void initializePlugin()
BaseInterface.
Definition: PrimitivesGenerator.cc:83
DATA_POLYHEDRAL_MESH
#define DATA_POLYHEDRAL_MESH
Definition: PolyhedralMesh.hh:54
DATA_TRIANGLE_MESH
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:60
OpenVolumeMesh
Definition: ColorAttrib.hh:53
DATA_POLY_MESH
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
UPDATE_ALL
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
PolyMeshObject
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
ACG::BSplineCurveT::add_control_point
void add_control_point(const Point &_cp)
add a control point
Definition: BSplineCurveT_impl.hh:149
RPC::callFunction
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Definition: RPCWrappers.cc:55
OpenMesh::PolyMeshT::Point
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
PluginFunctions::getObject
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Definition: PluginFunctions.cc:296
DATA_HEXAHEDRAL_MESH
#define DATA_HEXAHEDRAL_MESH
Definition: HexahedralMesh.hh:56
OpenMesh::VectorT
Definition: Vector11T.hh:83
ACG::BSplineSurfaceT::createKnots
void createKnots()
Creates interpolating knotvectors 0...0, 1, 2, ..., n...n.
Definition: BSplineSurfaceT_impl.hh:165
ACG::BSplineSurfaceT::add_vector_m
void add_vector_m(const std::vector< Point > &_control_polygon)
Adds a control point n-vector.
Definition: BSplineSurfaceT_impl.hh:187
Vector
ACG::Vec3d Vector
Standard Type for 3d Vector used for scripting.
Definition: DataTypes.hh:174
DATA_BSPLINE_SURFACE
#define DATA_BSPLINE_SURFACE
Definition: BSplineSurface.hh:67
ACG::SceneGraph::DrawModes::getDrawMode
const DrawMode & getDrawMode(const std::string &_name)
Get a custom DrawMode.
Definition: DrawModes.cc:807
HexahedralMesh.hh
DATA_BSPLINE_CURVE
#define DATA_BSPLINE_CURVE
Definition: BSplineCurve.hh:67
ACG::BSplineCurveT
Definition: BSplineCurveT.hh:82
ACG::BSplineSurfaceT
Definition: BSplineSurfaceT.hh:82
TriMeshObject
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:67
OpenMesh::PolyMeshT::add_vertex
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
VolumeMeshObject
Definition: VolumeMeshObject.hh:63
TetrahedralCuboidGenerator
Definition: TetrahedralCuboidGenerator.hh:75
BSplineCurveObject
Definition: BSplineCurveObject.hh:78
BSplineCurve.hh
VolumeMeshObject::mesh
MeshT * mesh()
return a pointer to the mesh
Definition: VolumeMeshObjectT_impl.hh:212
WhatsThisGenerator::setWhatsThis
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
Definition: WhatsThisGenerator.cc:89
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:434
ACG::Geometry::perpendicular
VectorT< Scalar, 3 > perpendicular(const VectorT< Scalar, 3 > &v)
find a vector that&#39;s perpendicular to _v
Definition: Algorithms.cc:1152
BSplineSurfaceObject
Definition: BSplineSurfaceObject.hh:80
PluginFunctions::viewAll
void viewAll(int _viewer)
View the whole scene.
Definition: PluginFunctions.cc:863
VolumeMeshObject::setName
void setName(QString _name)
Set the name of the Object.
Definition: VolumeMeshObjectT_impl.hh:187