differentialProperties.cpp 9.07 KB
Newer Older
1 2 3 4 5
#include "differentialProperties.h"

#include "mapHandler.h"

#include "Algo/Geometry/normal.h"
6
#include "Algo/Geometry/curvature.h"
7 8 9

bool DifferentialPropertiesPlugin::enable()
{
10 11
	m_computeNormalDialog = new ComputeNormalDialog(m_window);
	m_computeCurvatureDialog = new ComputeCurvatureDialog(m_window);
12

13 14
	m_computeNormalAction = new QAction("Compute Normal", this);
	m_computeCurvatureAction = new QAction("Compute Curvature", this);
Pierre Kraemer's avatar
Pierre Kraemer committed
15

16 17
	addMenuAction("Surface;Differential Properties;Compute Normal", m_computeNormalAction);
	addMenuAction("Surface;Differential Properties;Compute Curvature", m_computeCurvatureAction);
Pierre Kraemer's avatar
Pierre Kraemer committed
18

19 20
	connect(m_computeNormalAction, SIGNAL(triggered()), this, SLOT(openComputeNormalDialog()));
	connect(m_computeCurvatureAction, SIGNAL(triggered()), this, SLOT(openComputeCurvatureDialog()));
21

22 23
	connect(m_computeNormalDialog, SIGNAL(accepted()), this, SLOT(computeNormalFromDialog()));
	connect(m_computeNormalDialog->button_apply, SIGNAL(clicked()), this, SLOT(computeNormalFromDialog()));
24

25 26
	connect(m_computeCurvatureDialog, SIGNAL(accepted()), this, SLOT(computeCurvatureFromDialog()));
	connect(m_computeCurvatureDialog->button_apply, SIGNAL(clicked()), this, SLOT(computeCurvatureFromDialog()));
27

28 29 30
	connect(m_window, SIGNAL(mapAdded(MapHandlerGen*)), this, SLOT(mapAdded(MapHandlerGen*)));
	connect(m_window, SIGNAL(mapRemoved(MapHandlerGen*)), this, SLOT(mapRemoved(MapHandlerGen*)));

31 32 33
	return true;
}

34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
void DifferentialPropertiesPlugin::mapAdded(MapHandlerGen *map)
{
	connect(map, SIGNAL(attributeModified(unsigned int, QString)), this, SLOT(attributeModified(unsigned int, QString)));
}

void DifferentialPropertiesPlugin::mapRemoved(MapHandlerGen *map)
{
	disconnect(map, SIGNAL(attributeModified(unsigned int, QString)), this, SLOT(attributeModified(unsigned int, QString)));
}

void DifferentialPropertiesPlugin::attributeModified(unsigned int orbit, QString nameAttr)
{
	if(orbit == VERTEX)
	{
		MapHandlerGen* map = static_cast<MapHandlerGen*>(QObject::sender());
		if(computeNormalLastParameters.contains(map->getName()))
		{
			ComputeNormalParameters& params = computeNormalLastParameters[map->getName()];
Pierre Kraemer's avatar
Pierre Kraemer committed
52 53 54 55 56 57 58 59 60 61 62 63 64
			if(params.autoUpdate && params.positionName == nameAttr)
				computeNormal(map->getName(), params.positionName, params.normalName, true);
		}
		if(computeCurvatureLastParameters.contains(map->getName()))
		{
			ComputeCurvatureParameters& params = computeCurvatureLastParameters[map->getName()];
			if(params.autoUpdate && (params.positionName == nameAttr || params.normalName == nameAttr))
				computeCurvature(
					map->getName(),
					params.positionName, params.normalName,
					params.KmaxName, params.kmaxName, params.KminName, params.kminName, params.KnormalName,
					true
				);
65 66 67 68
		}
	}
}

69
void DifferentialPropertiesPlugin::openComputeNormalDialog()
70 71 72 73
{
	m_computeNormalDialog->show();
}

74
void DifferentialPropertiesPlugin::openComputeCurvatureDialog()
75
{
76
	m_computeCurvatureDialog->show();
77 78
}

79
void DifferentialPropertiesPlugin::computeNormalFromDialog()
80
{
81
	QList<QListWidgetItem*> currentItems = m_computeNormalDialog->mapList->selectedItems();
82 83
	if(!currentItems.empty())
	{
84
		const QString& mapName = currentItems[0]->text();
Pierre Kraemer's avatar
Pierre Kraemer committed
85

86
		QString positionName = m_computeNormalDialog->combo_positionAttribute->currentText();
87

88
		QString normalName;
89
		if(m_computeNormalDialog->normalAttributeName->text().isEmpty())
90
			normalName = m_computeNormalDialog->combo_normalAttribute->currentText();
91
		else
92
			normalName = m_computeNormalDialog->normalAttributeName->text();
93

94 95
		bool autoUpdate = (currentItems[0]->checkState() == Qt::Checked);

96
		computeNormal(mapName, positionName, normalName, autoUpdate);
97 98 99
	}
}

100
void DifferentialPropertiesPlugin::computeCurvatureFromDialog()
101 102 103 104
{
	QList<QListWidgetItem*> currentItems = m_computeCurvatureDialog->mapList->selectedItems();
	if(!currentItems.empty())
	{
105
		const QString& mapName = currentItems[0]->text();
106

107 108
		QString positionName = m_computeCurvatureDialog->combo_positionAttribute->currentText();
		QString normalName = m_computeCurvatureDialog->combo_normalAttribute->currentText();
109

110
		QString KmaxName;
111
		if(m_computeCurvatureDialog->KmaxAttributeName->text().isEmpty())
112
			KmaxName = m_computeCurvatureDialog->combo_KmaxAttribute->currentText();
113
		else
114
			KmaxName = m_computeCurvatureDialog->KmaxAttributeName->text();
115

116
		QString kmaxName;
117
		if(m_computeCurvatureDialog->kmaxAttributeName->text().isEmpty())
118
			kmaxName = m_computeCurvatureDialog->combo_kmaxAttribute->currentText();
119
		else
120
			kmaxName = m_computeCurvatureDialog->kmaxAttributeName->text();
121

122
		QString KminName;
123
		if(m_computeCurvatureDialog->KminAttributeName->text().isEmpty())
124
			KminName = m_computeCurvatureDialog->combo_KminAttribute->currentText();
125
		else
126
			KminName = m_computeCurvatureDialog->KminAttributeName->text();
127

128
		QString kminName;
129
		if(m_computeCurvatureDialog->kminAttributeName->text().isEmpty())
130
			kminName = m_computeCurvatureDialog->combo_kminAttribute->currentText();
131
		else
132
			kminName = m_computeCurvatureDialog->kminAttributeName->text();
133

134
		QString KnormalName;
135
		if(m_computeCurvatureDialog->KnormalAttributeName->text().isEmpty())
136
			KnormalName = m_computeCurvatureDialog->combo_KnormalAttribute->currentText();
137
		else
138
			KnormalName = m_computeCurvatureDialog->KnormalAttributeName->text();
139 140

		bool autoUpdate = (currentItems[0]->checkState() == Qt::Checked);
141

142
		computeCurvature(
143 144 145 146
			mapName,
			positionName, normalName,
			KmaxName, kmaxName, KminName, kminName, KnormalName,
			autoUpdate
147 148 149
		);
	}
}
150

151 152 153 154
void DifferentialPropertiesPlugin::computeNormal(
	const QString& mapName,
	const QString& positionAttributeName,
	const QString& normalAttributeName,
155
	bool autoUpdate)
156 157 158 159
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_window->getMap(mapName));
	if(mh == NULL)
		return;
Pierre Kraemer's avatar
Pierre Kraemer committed
160

161 162 163 164 165 166 167 168 169 170 171
	VertexAttribute<PFP2::VEC3> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<PFP2::VEC3> normal = mh->getAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		normal = mh->addAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);

	PFP2::MAP* map = mh->getMap();
	Algo::Surface::Geometry::computeNormalVertices<PFP2>(*map, position, normal);

172
	computeNormalLastParameters[mapName] =
173
		ComputeNormalParameters(positionAttributeName, normalAttributeName, autoUpdate);
174

175
	mh->createVBO(normal);
176

177
	mh->notifyAttributeModification(normal);
178 179 180 181 182 183 184 185 186 187 188
}

void DifferentialPropertiesPlugin::computeCurvature(
	const QString& mapName,
	const QString& positionAttributeName,
	const QString& normalAttributeName,
	const QString& KmaxAttributeName,
	const QString& kmaxAttributeName,
	const QString& KminAttributeName,
	const QString& kminAttributeName,
	const QString& KnormalAttributeName,
189
	bool autoUpdate)
190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
{
	MapHandler<PFP2>* mh = static_cast<MapHandler<PFP2>*>(m_window->getMap(mapName));
	if(mh == NULL)
		return;

	VertexAttribute<PFP2::VEC3> position = mh->getAttribute<PFP2::VEC3, VERTEX>(positionAttributeName);
	if(!position.isValid())
		return;

	VertexAttribute<PFP2::VEC3> normal = mh->getAttribute<PFP2::VEC3, VERTEX>(normalAttributeName);
	if(!normal.isValid())
		return;

	VertexAttribute<PFP2::VEC3> Kmax = mh->getAttribute<PFP2::VEC3, VERTEX>(KmaxAttributeName);
	if(!Kmax.isValid())
		Kmax = mh->addAttribute<PFP2::VEC3, VERTEX>(KmaxAttributeName);

	VertexAttribute<PFP2::REAL> kmax = mh->getAttribute<PFP2::REAL, VERTEX>(kmaxAttributeName);
	if(!kmax.isValid())
		kmax = mh->addAttribute<PFP2::REAL, VERTEX>(kmaxAttributeName);

	VertexAttribute<PFP2::VEC3> Kmin = mh->getAttribute<PFP2::VEC3, VERTEX>(KminAttributeName);
	if(!Kmin.isValid())
		Kmin = mh->addAttribute<PFP2::VEC3, VERTEX>(KminAttributeName);

	VertexAttribute<PFP2::REAL> kmin = mh->getAttribute<PFP2::REAL, VERTEX>(kminAttributeName);
	if(!kmin.isValid())
		kmin = mh->addAttribute<PFP2::REAL, VERTEX>(kminAttributeName);

	VertexAttribute<PFP2::VEC3> Knormal = mh->getAttribute<PFP2::VEC3, VERTEX>(KnormalAttributeName);
	if(!Knormal.isValid())
		Knormal = mh->addAttribute<PFP2::VEC3, VERTEX>(KnormalAttributeName);

	EdgeAttribute<PFP2::REAL> edgeAngle = mh->getAttribute<PFP2::REAL, EDGE>("edgeAngle");
	if(!edgeAngle.isValid())
		edgeAngle = mh->addAttribute<PFP2::REAL, EDGE>("edgeAngle");

	PFP2::MAP* map = mh->getMap();
	Algo::Surface::Geometry::computeAnglesBetweenNormalsOnEdges<PFP2>(*map, position, edgeAngle);
	Algo::Surface::Geometry::computeCurvatureVertices_NormalCycles_Projected<PFP2>(*map, 0.02f * mh->getBBdiagSize(), position, normal, edgeAngle, kmax, kmin, Kmax, Kmin, Knormal);

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
	computeCurvatureLastParameters[mapName] =
		ComputeCurvatureParameters(
			positionAttributeName, normalAttributeName,
			KmaxAttributeName, kmaxAttributeName, KminAttributeName, kminAttributeName, KnormalAttributeName,
			autoUpdate);

	mh->createVBO(Kmax);
	mh->createVBO(kmax);
	mh->createVBO(Kmin);
	mh->createVBO(kmin);
	mh->createVBO(Knormal);

	mh->notifyAttributeModification(Kmax);
	mh->notifyAttributeModification(kmax);
	mh->notifyAttributeModification(Kmin);
	mh->notifyAttributeModification(kmin);
	mh->notifyAttributeModification(Knormal);
248 249
}

250 251 252 253 254
#ifndef DEBUG
Q_EXPORT_PLUGIN2(DifferentialPropertiesPlugin, DifferentialPropertiesPlugin)
#else
Q_EXPORT_PLUGIN2(DifferentialPropertiesPluginD, DifferentialPropertiesPlugin)
#endif