Developer Documentation

TypePolyhedralMesh.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 "TypePolyhedralMesh.hh"
44 #include <ObjectTypes/Plane/Plane.hh>
45 #include <OpenFlipper/common/GlobalOptions.hh>
46 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
47
48 #include <QMenu>
49 #include <QInputDialog>
50 #include <QFormLayout>
51 #include <QLabel>
52
53 TypePolyhedralMeshPlugin::TypePolyhedralMeshPlugin() :
54 render_switch_(NULL),
55 translucency_factor_action_(NULL),
56 optionsWidget_(NULL),
57 scalingFactorSpinBox_(NULL),
58 translucencyFactorSpinBox_(NULL),
59 renderBoundaryCheckBox_(NULL),
60 scalingFactorSettingName_(name() + QString("/CellScalingFactor")),
61 translucencyFactorSettingName_(name() + QString("/TranslucencyFactor")),
62 renderBoundarySettingName_(name() + QString("/RenderBoundaryOnly"))
63 {
64 }
65
66 bool TypePolyhedralMeshPlugin::registerType() {
67
68 addDataType("PolyhedralMesh", tr("Polyhedral Volume Mesh"));
69 setTypeIcon("PolyhedralMesh", "PolyVolMeshType.png");
70 return true;
71 }
72
73 //----------------------------------------------------------------------------
74
75 void TypePolyhedralMeshPlugin::pluginsInitialized() {
76
77 if(OpenFlipper::Options::nogui()) return;
78
79 emit registerKey(Qt::Key_F8, Qt::ShiftModifier, "Set scaling of cell shrinkage");
80
81 QMenu* menu = new QMenu("Polyhedral Mesh Options");
82
83 // scaling action in context menu
84 QAction* act_scale_cells = new QAction(tr("Scale cells (Shift-F8)"), this);
85 act_scale_cells->setStatusTip(tr("Scale cells (Shift-F8)"));
86 connect(act_scale_cells, SIGNAL( triggered() ), this, SLOT( slot_change_shrinkage() ));
87 menu->addAction(act_scale_cells);
88
89 // Change rendering
90 render_switch_ = new QAction(tr("Render Boundary Only"), this);
91 render_switch_->setStatusTip(tr("Render Boundary Only"));
92 render_switch_->setCheckable(true);
93 render_switch_->setChecked(OpenFlipperSettings().value(renderBoundarySettingName_, false).toBool());
94 connect(render_switch_, SIGNAL( triggered() ), this, SLOT( switchRendering() ));
95 menu->addAction(render_switch_);
96
97 translucency_factor_action_ = new QAction(tr("Set Translucency Factor"), this);
98 translucency_factor_action_->setStatusTip(tr("Set Translucency Factor"));
99 translucency_factor_action_->setCheckable(false);
100 connect(translucency_factor_action_, SIGNAL( triggered() ), this, SLOT( setTranslucencyFactor() ));
101 menu->addAction(translucency_factor_action_);
102
103 emit addContextMenuItem(menu->menuAction(), DATA_POLYHEDRAL_MESH, CONTEXTOBJECTMENU);
104 }
105
106 //----------------------------------------------------------------------------
107
108 int TypePolyhedralMeshPlugin::addEmpty() {
109
110
111 // new object data struct
112 PolyhedralMeshObject* object = new PolyhedralMeshObject(DATA_POLYHEDRAL_MESH);
113
114 if ( OpenFlipperSettings().value("Core/File/AllTarget",false).toBool() )
115 object->target(true);
116 else {
117
118 // Only the first object in the scene will be target
119 if ( PluginFunctions::objectCount() == 1 )
120 object->target(true);
121
122 // If no target is available, we set the new object as target
123 if (PluginFunctions::targetCount() == 0 )
124 object->target(true);
125 }
126
127 QString name = QString(tr("New PolyHedral Mesh %1.ovm").arg( object->id() ));
128
129 // call the local function to update names
130 QFileInfo f(name);
131 object->setName(f.fileName());
132
133 // enable backface culling
134 object->materialNode()->applyProperties(ACG::SceneGraph::MaterialNode::All);
135
136 // set the default colors
137 const QColor color = OpenFlipper::Options::defaultColor();
138 const ACG::Vec4f default_color(color.redF(), color.greenF(), color.blueF(), color.alphaF());
139 object->materialNode()->set_color(default_color);
140
141 // Set rendering props
142 if(OpenFlipper::Options::gui())
143 {
144 object->meshNode()->set_scaling(OpenFlipperSettings().value(scalingFactorSettingName_, 0.8).toDouble());
145 object->meshNode()->set_translucency_factor(OpenFlipperSettings().value(translucencyFactorSettingName_, 0.1f).toFloat());
146 object->update();
147
148 object->show();
149 }
150
151
152 // emit log(LOGINFO, object->getObjectinfo());
153
154 emit emptyObjectAdded(object->id());
155
156 return object->id();
157 }
158
159 //----------------------------------------------------------------------------
160
161
162 void TypePolyhedralMeshPlugin::slotKeyEvent(QKeyEvent* _event) {
163
164 switch (_event->key()) {
165 case Qt::Key_F8:
166 if (_event->modifiers() & Qt::ShiftModifier)
167 slot_change_shrinkage();
168 break;
169 default:
170 break;
171 }
172 }
173
174 //----------------------------------------------------------------------------
175
176 void TypePolyhedralMeshPlugin::slotObjectUpdated(int _identifier, const UpdateType& _type) {
177
178 if( !_type.contains(UPDATE_ALL) && !_type.contains(UPDATE_GEOMETRY))
179 return;
180
181 PlaneObject* pobj;
182 if (PluginFunctions::getObject(_identifier, pobj))
183 slot_update_planes_in_scenegraph_node();
184 }
185
186 //----------------------------------------------------------------------------
187
188 void TypePolyhedralMeshPlugin::objectDeleted(int _identifier) {
189
190 PlaneObject* pobj;
191 if (PluginFunctions::getObject(_identifier, pobj)) {
192 slot_update_planes_in_scenegraph_node(_identifier);
193 }
194 }
195
196 //----------------------------------------------------------------------------
197
198 void TypePolyhedralMeshPlugin::switchRendering() {
199
200 QVariant contextObject = render_switch_->data();
201 int objectId = contextObject.toInt();
202
203 if(objectId == -1)
204 return;
205
206 BaseObjectData* bod = 0;
207 if(!PluginFunctions::getObject(objectId, bod))
208 return;
209
210 PolyhedralMeshObject* polyMeshObject = PluginFunctions::polyhedralMeshObject(bod);
211
212 if(polyMeshObject) {
213 polyMeshObject->meshNode()->set_boundary_only(render_switch_->isChecked());
214 polyMeshObject->meshNode()->set_geometry_changed(true);
215 }
216 }
217
218 //----------------------------------------------------------------------------
219
220 void TypePolyhedralMeshPlugin::setTranslucencyFactor() {
221
222 QVariant contextObject = translucency_factor_action_->data();
223 int objectId = contextObject.toInt();
224
225 if(objectId == -1)
226 return;
227
228 BaseObjectData* bod = 0;
229 if(!PluginFunctions::getObject(objectId, bod))
230 return;
231
232 PolyhedralMeshObject* polyMeshObject = PluginFunctions::polyhedralMeshObject(bod);
233
234 if(polyMeshObject) {
235
236 bool ok;
237 float val = polyMeshObject->meshNode()->translucency_factor();
238 double factor = QInputDialog::getDouble(0, tr("Set translucency factor"), tr("Factor [0, 1]:"), val,
239 0.0, 1.0, 2, &ok);
240
241 if (ok)
242 polyMeshObject->meshNode()->set_translucency_factor(static_cast<float>(factor));
243 }
244 }
245
246 //----------------------------------------------------------------------------
247
248 void TypePolyhedralMeshPlugin::slot_update_planes_in_scenegraph_node(int _deletedObject) {
249
250 std::vector<Plane> planes;
251
252 // collect planes
253 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_PLANE); o_it
254 != PluginFunctions::objectsEnd(); ++o_it) {
255
256 if(o_it->id() == _deletedObject) continue;
257
258 ACG::Vec3d p = (ACG::Vec3d) PluginFunctions::planeNode(*o_it)->position();
259 ACG::Vec3d n = (ACG::Vec3d) PluginFunctions::planeNode(*o_it)->normal();
260 ACG::Vec3d x = (ACG::Vec3d) PluginFunctions::planeNode(*o_it)->xDirection();
261 ACG::Vec3d y = (ACG::Vec3d) PluginFunctions::planeNode(*o_it)->yDirection();
262 x /= x.sqrnorm();
263 y /= y.sqrnorm();
264
265 planes.push_back(Plane(p, n, x, y));
266 }
267
268 // iterate over all target polyvolmeshes
269 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_POLYHEDRAL_MESH); o_it
270 != PluginFunctions::objectsEnd(); ++o_it) {
271
272 PluginFunctions::polyhedralMeshObject(*o_it)->meshNode()->clear_cut_planes();
273 for (unsigned int i = 0; i < planes.size(); ++i) {
274 PluginFunctions::polyhedralMeshObject(*o_it)->meshNode()->add_cut_plane(planes[i]);
275 }
276 PluginFunctions::polyhedralMeshObject(*o_it)->meshNode()->set_geometry_changed(true);
277 }
278
279 emit updateView();
280 }
281
282 //----------------------------------------------------------------------------
283
284
285 void TypePolyhedralMeshPlugin::slot_change_shrinkage() {
286
287 for (PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS, DATA_POLYHEDRAL_MESH); o_it
288 != PluginFunctions::objectsEnd(); ++o_it) {
289 // Popup dialog
290 bool ok;
291 double val = PluginFunctions::polyhedralMeshObject(*o_it)->meshNode()->scaling();
292 double scale = QInputDialog::getDouble(0, tr("Set singularity scaling for cell shrinkage"), tr("Size * :"), val,
293 0.0, 1.0, 2, &ok);
294
295 if (ok) {
296 PluginFunctions::polyhedralMeshObject(*o_it)->meshNode()->set_scaling(scale);
297 emit updatedObject((*o_it)->id(), UPDATE_GEOMETRY);
298 }
299 }
300 }
301
302 //------------------------------------------------------------------------------
303
304 bool TypePolyhedralMeshPlugin::initializeOptionsWidget(QWidget*& _widget)
305 {
306 if (!optionsWidget_) {
307
308 optionsWidget_ = new QWidget;
309 QFormLayout* layout = new QFormLayout;
310
311 scalingFactorSpinBox_ = new QDoubleSpinBox;
312 scalingFactorSpinBox_->setRange(0.0, 1.0);
313 scalingFactorSpinBox_->setDecimals(2);
314 scalingFactorSpinBox_->setSingleStep(0.01);
315
316 translucencyFactorSpinBox_ = new QDoubleSpinBox;
317 translucencyFactorSpinBox_->setRange(0.0, 1.0);
318 translucencyFactorSpinBox_->setDecimals(2);
319 translucencyFactorSpinBox_->setSingleStep(0.01);
320
321 renderBoundaryCheckBox_ = new QCheckBox(tr("Render boundary only"), optionsWidget_);
322
323 layout->addRow(new QLabel(tr("Default cell scaling factor")), scalingFactorSpinBox_);
324 layout->addRow(new QLabel(tr("Default translucency factor")), translucencyFactorSpinBox_);
325 layout->addRow(renderBoundaryCheckBox_);
326
327 optionsWidget_->setLayout(layout);
328 }
329
330 double scalingFactor = OpenFlipperSettings().value(scalingFactorSettingName_, 0.8).toDouble();
331 double translucencyFactor = OpenFlipperSettings().value(translucencyFactorSettingName_, 0.1).toDouble();
332 bool renderBoundary = OpenFlipperSettings().value(renderBoundarySettingName_, false).toBool();
333
334 scalingFactorSpinBox_->setValue(scalingFactor);
335 translucencyFactorSpinBox_->setValue(translucencyFactor);
336 renderBoundaryCheckBox_->setChecked(renderBoundary);
337
338 _widget = optionsWidget_;
339
340 return true;
341 }
342
343 //------------------------------------------------------------------------------
344
345 void TypePolyhedralMeshPlugin::applyOptions()
346 {
347 OpenFlipperSettings().setValue(scalingFactorSettingName_, scalingFactorSpinBox_->value());
348 OpenFlipperSettings().setValue(translucencyFactorSettingName_, translucencyFactorSpinBox_->value());
349 OpenFlipperSettings().setValue(renderBoundarySettingName_, renderBoundaryCheckBox_->isChecked());
350 }
351
352
353
DATA_POLYHEDRAL_MESH
#define DATA_POLYHEDRAL_MESH
Definition: PolyhedralMesh.hh:54
UPDATE_GEOMETRY
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(1)<< 2)
Geometry updated.
UPDATE_ALL
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
PluginFunctions::polyhedralMeshObject
PolyhedralMeshObject * polyhedralMeshObject(BaseObjectData *_object)
Cast an BaseObject to an PolyhedralMeshObject if possible.
Definition: PluginFunctionsPolyhedralMesh.cc:134
BaseInterface::updateView
virtual void updateView()
Update current view in Main Application.
Definition: BaseInterface.hh:122
PlaneNode::yDirection
ACG::Vec3d yDirection()
local y direction (multiplied with height)
Definition: PlaneNode.cc:279
PluginFunctions::objectCount
int objectCount()
Get the number of available objects.
Definition: PluginFunctions.cc:1002
PluginFunctions::getObject
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
Definition: PluginFunctions.cc:296
GlobalOptions.hh
PolyhedralMeshObject
VolumeMeshObject< PolyhedralMesh > PolyhedralMeshObject
Typedef for a mesh object containing a polyhedral mesh.
Definition: PolyhedralMesh.hh:62
PlaneNode::xDirection
ACG::Vec3d xDirection()
local x direction (multiplied with width)
Definition: PlaneNode.cc:272
OpenMesh::VectorT
Definition: Vector11T.hh:83
PluginFunctions::ALL_OBJECTS
const QStringList ALL_OBJECTS
Iterable object range.
Definition: PluginFunctions.hh:430
PluginFunctions.hh
PluginFunctions::planeNode
PlaneNode * planeNode(BaseObjectData *_object)
Get a PlaneNode from an object.
Definition: PluginFunctionsPlane.cc:82
BaseObject::id
int id() const
Definition: BaseObject.cc:190
addDataType
DLLEXPORT DataType addDataType(QString _name, QString _readableName)
Adds a datatype and returns the id for the new type.
Definition: Types.cc:117
PluginFunctions::objectsEnd
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
Definition: PluginFunctionsIterator.cc:177
setTypeIcon
DLLEXPORT void setTypeIcon(DataType _id, QString _icon)
Set an Icon for a given DataType.
Definition: Types.cc:223
OpenFlipperQSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: OpenFlipperQSettings.cc:46
PluginFunctions::ObjectIterator
Core Data Iterator.
Definition: PluginFunctions.hh:441
PlaneNode::position
ACG::Vec3d position()
get center position of the plane
Definition: PlaneNode.cc:258
PluginFunctions::polyMeshObject
PolyMeshObject * polyMeshObject(BaseObjectData *_object)
Cast an BaseObject to a PolyMeshObject if possible.
Definition: PluginFunctionsPolyMesh.cc:149
PluginFunctions::targetCount
int targetCount()
Get the number of target objects.
Definition: PluginFunctions.cc:1008
BaseObjectData
Definition: BaseObjectData.hh:102
VolumeMeshObject
Definition: VolumeMeshObject.hh:63
UpdateType
Update type class.
Definition: UpdateType.hh:60
PluginFunctions::TARGET_OBJECTS
const QStringList TARGET_OBJECTS("target")
Iterable object range.
TypeHexahedralMeshPlugin::name
QString name()
Return a name for the plugin.
Definition: TypeHexahedralMesh.hh:112
KeyInterface::registerKey
virtual void registerKey(int _key, Qt::KeyboardModifiers _modifiers, QString _description, bool _multiUse=false)
Register a key-combination for your plugin.
Definition: KeyInterface.hh:71
UpdateType::contains
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
Definition: UpdateType.cc:104
VolumeMeshObject::meshNode
ACG::SceneGraph::VolumeMeshNodeT< MeshT > * meshNode()
Get the Scenegraph Mesh Node.
Definition: VolumeMeshObjectT_impl.hh:325
OpenMesh::VectorT::sqrnorm
decltype(std::declval< S >() *std::declval< S >()) sqrnorm() const
compute squared euclidean norm
Definition: Vector11T.hh:402
DATA_PLANE
#define DATA_PLANE
Definition: Plane.hh:58
PlaneObject
Definition: PlaneObject.hh:75
TypePolyhedralMeshPlugin::initializeOptionsWidget
bool initializeOptionsWidget(QWidget *&_widget)
Initialize the Options Widget.
Definition: TypePolyhedralMesh.cc:304
ACG::Geometry::Plane
Definition: PlaneType.hh:50
Plane.hh
OpenFlipperQSettings::setValue
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
Definition: OpenFlipperQSettings.cc:61
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:1038
PlaneNode::normal
ACG::Vec3d normal()
get current normal
Definition: PlaneNode.cc:265
CONTEXTOBJECTMENU
The Menu will be shown when an object was picked.
Definition: ContextMenuInterface.hh:59
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
ACG::SceneGraph::MaterialNode::All
apply all properites
Definition: MaterialNode.hh:348