Code_TYMPAN  4.4.0
Industrial site acoustic simulation
TYAltimetrieGraphic.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) <2012-2024> <EDF-DTG> <FRANCE>
3  * This file is part of Code_TYMPAN (R).
4  * Code_TYMPAN (R) is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  * Code_TYMPAN (R) is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * See the GNU General Public License for more details.
12  * You should have received a copy of the GNU General Public License along
13  * with Code_TYMPAN (R). If not, see <https://www.gnu.org/licenses/>.
14  */
15 
24 #include "gui/tools/OGLArrayMesh.h"
25 #include "gui/tools/OGLMesh.h"
28 #include "models/common/3d.h"
29 #include <memory>
30 #include <numeric>
31 #include <qcolor.h>
32 #include <qgenericmatrix.h>
33 #include <qimage.h>
34 #include <qmatrix4x4.h>
35 #include <qnamespace.h>
36 #include <qopengltexture.h>
37 #include <qpoint.h>
38 #include <qtransform.h>
39 #include <qvector2d.h>
40 #include <qvector3d.h>
41 #include <vector>
42 #ifdef _MSC_VER
43  #pragma warning(disable : 4284)
44 #endif
45 
46 #include "Tympan/core/color.h"
48 
50 
53 
54 #include "TYAltimetrieGraphic.h"
56 #include <QtOpenGL>
57 
58 #include <math.h>
59 
60 #define IMG(id) OLocalizator::getPicture("TYAltimetrieGraphic", (id))
61 
63  : TYElementGraphic(pElement), _mesh(std::make_shared<OGLArrayMesh>())
64 {
65  _mesh->setPrimitiveType(OGLPrivimitiveType::Triangles);
66  _mesh->material().lightingMode = OGLSimpleMaterial::LightingMode::Shaded;
67  float hueRange[2] = {0.4f, 0.15f};
68  float saturationRange[2] = {1.0f, 0.8f};
69  float valueRange[2] = {0.5f, 0.25f};
70  TYColorManager::getLinearColorTable(256, hueRange, saturationRange, valueRange, _oColorMap);
71  _angle = 0.0;
72  _visible = false;
73 }
74 
76 
77 void TYAltimetrieGraphic::update(bool force /*=false*/)
78 {
79  if (getModified() || force)
80  {
81  float minHue = 80.0f;
82  float minSaturation = 255.0f;
83  float minValue = 255.0f;
84  float maxHue = 120.0f;
85  float maxSaturation = 255.0f;
86  float maxValue = 112.0f;
87 
88 #if TY_USE_IHM
89  // Couleurs
90  if ((TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMinR")) &&
91  (TYPreferenceManager::exists(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMaxR")))
92  {
93  TYPreferenceManager::getColor(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMin", minHue,
94  minSaturation, minValue);
95 
96  TYPreferenceManager::getColor(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMax", maxHue,
97  maxSaturation, maxValue);
98  }
99  else
100  {
101  TYPreferenceManager::setColor(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMin", minHue,
102  minSaturation, minValue);
103  TYPreferenceManager::setColor(TYDIRPREFERENCEMANAGER, "AltiGraphicColorMax", maxHue,
104  maxSaturation, maxValue);
105  }
106 #endif
107  // Get shortest path between min hue and max hue
108  float adjustedMaxHue = minHue + 180 - abs(abs(maxHue - minHue) - 180);
109  float hueRange[2] = {minHue / 360.f, adjustedMaxHue / 360.f};
110  float saturationRange[2] = {minSaturation / 255.f, maxSaturation / 255.f};
111  float valueRange[2] = {minValue / 255.f, maxValue / 255.f};
112  qDebug() << hueRange << saturationRange << valueRange;
113  TYColorManager::getLinearColorTable(256, hueRange, saturationRange, valueRange, _oColorMap);
114 
116  }
117 }
118 
119 void TYAltimetrieGraphic::getChilds(TYListPtrTYElementGraphic& childs, bool recursif /*=true*/)
120 {
121  for (int i = 0; i < getElement()->getListFaces().size(); i++)
122  {
123  TYElementGraphic* pTYElementGraphic = getElement()->getFace(i)->getGraphicObject();
124  childs.push_back(pTYElementGraphic);
125  if (recursif)
126  {
127  pTYElementGraphic->getChilds(childs, recursif);
128  }
129  }
130 }
131 
133 {
135 
136  for (int i = 0; i < getElement()->getListFaces().size(); i++)
137  {
138  boundingBox.Enlarge((float)(getElement()->getFace(i)->getPoints()[0]._x),
139  (float)(getElement()->getFace(i)->getPoints()[0]._y),
140  (float)(getElement()->getFace(i)->getPoints()[0]._z));
141  boundingBox.Enlarge((float)(getElement()->getFace(i)->getPoints()[1]._x),
142  (float)(getElement()->getFace(i)->getPoints()[1]._y),
143  (float)(getElement()->getFace(i)->getPoints()[1]._z));
144  boundingBox.Enlarge((float)(getElement()->getFace(i)->getPoints()[2]._x),
145  (float)(getElement()->getFace(i)->getPoints()[2]._y),
146  (float)(getElement()->getFace(i)->getPoints()[2]._z));
147  }
148  return boundingBox;
149 }
150 
152 {
153  if (getElement() == NULL)
154  {
155  return;
156  }
157 
158  if (_visible && renderContext.type == TYRenderType::Picking)
159  {
160  TYPickingTable::addElement(getElement());
161  glPushName((GLuint)(TYPickingTable::getIndex()));
162 
163  for (int i = 0; i < getElement()->getListFaces().size(); i++)
164  {
165  TYElementGraphic* pTYElementGraphic = getElement()->getFace(i)->getGraphicObject();
166  LPTYPolygonGraphic pPolygonGraphic = (TYPolygonGraphic*)pTYElementGraphic;
167  if (pPolygonGraphic != NULL)
168  {
169  pPolygonGraphic->display(renderContext);
170  }
171  }
172 
173  glPopName();
174  }
175 }
176 
177 void TYAltimetrieGraphic::setBackgroundImage(std::shared_ptr<QImage>& image, int semiX, int semiY,
178  TYPoint ptPosition, OVector3D bgImageOrientation)
179 {
180  _image = image;
181  _semiX = semiX;
182  _semiY = semiY;
183  _imagePosition = ptPosition;
184  _bgImageOrientation = bgImageOrientation;
185  update(true);
186 }
187 
189 {
190  _image.reset();
191  _semiX = 0;
192  _semiY = 0;
195 }
196 
197 void TYAltimetrieGraphic::collectMeshInstances(std::vector<OGLMeshInstance>& meshInstances,
198  TYRenderContext* renderContext) const
199 {
200  bool renderBackgroundImage = _image != nullptr;
201 
202  // Texture transform
203  double angle = 0.0;
204  OVector3D vecOrientation = _bgImageOrientation;
205 
206  // On verifie que le vecteur orientation n'est pas nul
207  if (vecOrientation.norme() != 0)
208  {
209  // Calcul de l'angle
210  angle = SIGNE(vecOrientation._y) * acos(vecOrientation._x / vecOrientation.norme());
211  angle = (M_PI / 2.0) - angle;
212  }
213  QMatrix4x4 backgroundImageTransform;
214  backgroundImageTransform.translate(0.5, 0.5);
215  backgroundImageTransform.scale(1. / _semiX / 2, 1. / _semiY / 2, 1);
216  backgroundImageTransform.translate(-_imagePosition._x, -_imagePosition._y);
217  backgroundImageTransform.rotate(-angle * 180 / M_PI, 0, 0, 1);
218 
219  std::vector<QVector3D> vertices;
220  std::vector<QVector3D> normals;
221  std::vector<QVector2D> textureCoordinates;
222  std::vector<QColor> verticesColors;
223  float zmin = NAN, zmax = NAN, zrange = NAN;
224  zmin = boundingBox()._min._z;
225  zmax = boundingBox()._max._z;
226  zrange = zmax - zmin;
227  for (auto face : getElement()->getListFaces())
228  {
229  OVector3D normal = face->normal();
230  for (int i : {0, 1, 2})
231  {
232  OPoint3D point = face->getPoint(i);
233  vertices.emplace_back(point._x, point._y, point._z);
234  normals.emplace_back(normal._x, normal._y, normal._z);
235  if (zrange != 0)
236  {
237  float scalar = (point._z - zmin) / zrange;
238  verticesColors.emplace_back(_oColorMap[scalar * 255]);
239  }
240  textureCoordinates.emplace_back(backgroundImageTransform * QVector3D(point._x, point._y, 1));
241  }
242  }
243  if (renderBackgroundImage)
244  {
245  _mesh->material().image = _image;
246  _mesh->material().textureBlend = OGLSimpleMaterial::TextureBlend::Overlay;
247  }
248  else
249  {
250  _mesh->material().image = nullptr;
251  _mesh->material().textureBlend = OGLSimpleMaterial::TextureBlend::Multiply;
252  }
253  _mesh->setNormals(normals);
254  _mesh->setVertices(vertices);
255  std::vector<unsigned int> indices(vertices.size());
256  std::iota(indices.begin(), indices.end(), 0);
257  _mesh->setIndices(indices);
258  _mesh->setVerticesColors(verticesColors);
259  _mesh->setTextureCoordinates(textureCoordinates);
260  _mesh->material().lightingMode = OGLSimpleMaterial::LightingMode::Shaded;
261  meshInstances.emplace_back(_mesh, globalMatrix());
262 }
All base classes related to 3D manipulation.
double SIGNE(double a)
Return the number sign.
Definition: 3d.h:78
Representation graphique de l'altimetrie (fichier header)
list< TYElementGraphic * > TYListPtrTYElementGraphic
List de pointeur de TYElement.
#define TYDIRPREFERENCEMANAGER
Definition: TYElement.h:51
Gestion de la table de correspondance indice/element pour le picking (fichier header)
Contexte de rendu utilisé par les fonctions d'affichage.
@ Picking
The current render is only done for picking purpose.
Classe Modeler specialisee pour l'edition des sites (fichier header)
The box class.
Definition: 3d.h:1346
virtual void Enlarge(const OPoint3D &pt)
Enlarge the box with the point if the point is outside the box.
Definition: 3d.cpp:1614
OPoint3D _min
Minimal coordinates of the OBox.
Definition: 3d.h:1423
OPoint3D _max
Maximal coordinates of the OBox.
Definition: 3d.h:1424
double _y
y coordinate of OCoord3D
Definition: 3d.h:283
double _z
z coordinate of OCoord3D
Definition: 3d.h:284
double _x
x coordinate of OCoord3D
Definition: 3d.h:282
The 3D point class.
Definition: 3d.h:487
The 3D vector class.
Definition: 3d.h:298
double norme() const
Computes the length of this vector.
Definition: 3d.cpp:215
OVector3D normal(const OVector3D &vector2, const OVector3D &vector3) const
Computes the normal with this vector and 2 others.
Definition: 3d.cpp:220
void setBackgroundImage(std::shared_ptr< QImage > &image, int semiX, int semiY, TYPoint ptPosition, OVector3D bgImageOrientation)
virtual OBox computeBoundingBox() const
std::shared_ptr< QImage > _image
TYAltimetrieGraphic(TYAltimetrie *pElement)
virtual void getChilds(TYListPtrTYElementGraphic &childs, bool recursif=true)
virtual void update(bool force=false)
void collectMeshInstances(std::vector< OGLMeshInstance > &meshInstances, TYRenderContext *renderContext) const override
std::shared_ptr< OGLArrayMesh > _mesh
virtual void display(TYRenderContext &renderContext)
Assigne une altitude a chaque point de l'espace.
Definition: TYAltimetrie.h:35
static void getLinearColorTable(const unsigned int &nbColors, const float *hueRange, const float *saturationRange, const float *valueRange, OLookupTable &outColors)
Generation de la table de couleurs basee sur une rampe lineaire ( y = x+0.5/255 )
Definition: color.cpp:308
classe graphique pour un element de base
bool _visible
Inique si l'element est visible.
OBox boundingBox() const
virtual void update(bool force=false)
virtual void getChilds(TYListPtrTYElementGraphic &childs, bool recursif=true)
QMatrix4x4 globalMatrix() const
bool getModified() const
static int getIndex()
static void addElement(TYElement *pElt)
classe graphique pour un polygone
TYRenderType type
#define M_PI
Pi.
Definition: color.cpp:25