]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_FieldStepPrs.cpp
Salome HOME
Cut too long lines
[modules/shaper.git] / src / PartSet / PartSet_FieldStepPrs.cpp
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library 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.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "PartSet_FieldStepPrs.h"
21
22 #include <ModuleBase_Preferences.h>
23
24 #include <CollectionPlugin_Field.h>
25
26 #include <ModelAPI_AttributeSelectionList.h>
27 #include <ModelAPI_AttributeIntArray.h>
28 #include <ModelAPI_AttributeStringArray.h>
29
30 #include <SUIT_ResourceMgr.h>
31
32 #include <AIS_ColorScale.hxx>
33 #include <Prs3d_Drawer.hxx>
34 #include <Prs3d_PointAspect.hxx>
35 #include <BRep_Tool.hxx>
36 #include <BRepAdaptor_Surface.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <Prs3d_Root.hxx>
41
42
43 IMPLEMENT_STANDARD_RTTIEXT(PartSet_FieldStepPrs, ViewerData_AISShape);
44
45 #define POINT_SIZE 8
46
47
48 void emptyDeleter(ModelAPI_ResultField* theF)
49 {
50   // Do nothing
51 }
52
53 PartSet_FieldStepPrs::PartSet_FieldStepPrs(FieldStepPtr theStep)
54 : ViewerData_AISShape(TopoDS_Shape()), myStep(theStep)
55 {
56   ModelAPI_ResultField* aField = theStep->field();
57   GeomShapePtr aShapePtr = aField->shape();
58   TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
59   Set(aShape);
60
61   // Get parameters of the Field
62   // Make shared_ptr which will not delete original pointer after exit
63   std::shared_ptr<ModelAPI_ResultField> aFieldPtr(aField, emptyDeleter);
64   myFeature = ModelAPI_Feature::feature(aFieldPtr);
65
66   if (dataType() != ModelAPI_AttributeTables::STRING) {
67     Handle(Prs3d_Drawer) aDrawer = Attributes();
68     if (aDrawer->HasOwnPointAspect()) {
69       aDrawer->PointAspect()->SetTypeOfMarker(Aspect_TOM_POINT);
70       aDrawer->PointAspect()->SetScale(POINT_SIZE);
71     }
72     else
73       aDrawer->SetPointAspect(
74         new Prs3d_PointAspect(Aspect_TOM_POINT, Quantity_NOC_YELLOW, POINT_SIZE));
75   }
76   SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
77   QColor aQColor = aResMgr->colorValue("Viewer", "scalar_bar_text_color", Qt::black);
78
79   myLabelColor = Quantity_Color(aQColor.redF(), aQColor.greenF(), aQColor.blueF(),
80     Quantity_TOC_RGB);
81
82   SetMaterial(Graphic3d_NOM_PLASTIC);
83 }
84
85
86 ModelAPI_AttributeTables::ValueType PartSet_FieldStepPrs::dataType() const
87 {
88   DataPtr aData = myFeature->data();
89   AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
90   return aTablesAttr->type();
91 }
92
93 bool PartSet_FieldStepPrs::dataRange(double& theMin, double& theMax) const
94 {
95   ModelAPI_AttributeTables::ValueType aType = dataType();
96   if ((aType == ModelAPI_AttributeTables::DOUBLE) || (aType == ModelAPI_AttributeTables::INTEGER)) {
97     range(theMin, theMax);
98     return true;
99   }
100   return false;
101 }
102
103 QList<double> PartSet_FieldStepPrs::range(double& theMin, double& theMax) const
104 {
105   ModelAPI_AttributeTables::ValueType aType = dataType();
106   DataPtr aData = myFeature->data();
107   int aStep = myStep->id();
108   AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
109   int aRows = aTablesAttr->rows();
110   int aCols = aTablesAttr->columns();
111
112   QList<double> aFieldStepData;
113   for (int k = 1; k < aRows; k++) { // Do not use default values
114     for (int j = 0; j < aCols; j++) {
115       ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
116       switch (aType) {
117       case ModelAPI_AttributeTables::DOUBLE:
118         aFieldStepData << aVal.myDouble;
119         break;
120       case ModelAPI_AttributeTables::INTEGER:
121         aFieldStepData << aVal.myInt;
122         break;
123       }
124     }
125   }
126   QList<double> aShapeData;
127   double aRangeMin = aFieldStepData.first(), aRangeMax = aFieldStepData.last();
128   for (int aRow = 0; aRow < aRows - 1; aRow++) {
129     double aNorm = 0;
130     int aBaseIndex = aRow * aCols;
131     for (int aCol = 0; aCol < aCols; aCol++) {
132       int anIndex = aCol + aBaseIndex;
133       double aValue = aFieldStepData.at(anIndex);
134       aNorm += aValue * aValue;
135     }
136     aNorm = pow(aNorm, 0.5);
137     aRangeMin = Min(aRangeMin, aNorm);
138     aRangeMax = Max(aRangeMax, aNorm);
139     aShapeData << aNorm;
140   }
141   theMin = aRangeMin;
142   theMax = aRangeMax;
143   return aShapeData;
144 }
145
146
147 void PartSet_FieldStepPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
148   const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode)
149 {
150   SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
151   ModelAPI_AttributeTables::ValueType aType = dataType();
152   DataPtr aData = myFeature->data();
153   switch (aType) {
154   case ModelAPI_AttributeTables::DOUBLE:
155   case ModelAPI_AttributeTables::INTEGER:
156   {
157     double aMin, aMax;
158     QList<double> aShapeData = range(aMin, aMax);
159     int aNbIntertvals = aResMgr->integerValue("Viewer", "scalar_bar_nb_intervals", 20);
160
161     AttributeSelectionListPtr aSelList =
162       aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
163     for (int i = 0; i < aSelList->size(); i++) {
164       AttributeSelectionPtr aSelection = aSelList->value(i);
165       GeomShapePtr aShapePtr = aSelection->value();
166       TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
167       double aValue = aShapeData.at(i);
168       Quantity_Color aColor;
169       if (AIS_ColorScale::FindColor(aValue, aMin, aMax, aNbIntertvals, aColor))
170         SetCustomColor(aShape, aColor);
171     }
172   }
173   break;
174   case ModelAPI_AttributeTables::BOOLEAN:
175   {
176     QList<double> aShapeData = booleanValues();
177
178     AttributeSelectionListPtr aSelList =
179       aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
180     for (int i = 0; i < aSelList->size(); i++) {
181       AttributeSelectionPtr aSelection = aSelList->value(i);
182       GeomShapePtr aShapePtr = aSelection->value();
183       TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
184       double aValue = aShapeData.at(i);
185       Quantity_Color aColor;
186       if (AIS_ColorScale::FindColor(aValue, 0., 1., 2, aColor))
187         SetCustomColor(aShape, aColor);
188     }
189   }
190   break;
191   case ModelAPI_AttributeTables::STRING:
192   {
193     QStringList aValues = strings();
194     AttributeSelectionListPtr aSelList =
195       aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
196     Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup(thePrs);
197     for (int i = 0; i < aSelList->size(); i++) {
198       AttributeSelectionPtr aSelection = aSelList->value(i);
199       GeomShapePtr aShapePtr = aSelection->value();
200       TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
201       gp_Pnt aCenter;
202       if (computeMassCenter(aShape, aCenter)) {
203         Graphic3d_Vertex aVertex(aCenter.X(), aCenter.Y(), aCenter.Z());
204
205         Handle(Graphic3d_AspectText3d) anAspectText3d = new Graphic3d_AspectText3d();
206         anAspectText3d->SetStyle(Aspect_TOST_ANNOTATION);
207         anAspectText3d->SetColor(myLabelColor);
208         aGroup->SetPrimitivesAspect(anAspectText3d);
209
210         int aT = aResMgr->integerValue("Viewer", "scalar_bar_text_height", 14);
211         QString aString = aValues.at(i);
212         aGroup->Text(aString.toUtf8().constData(), aVertex, aT);
213       }
214     }
215   }
216   break;
217   }
218   ViewerData_AISShape::Compute(thePrsMgr, thePrs, theMode);
219 }
220
221 QList<double> PartSet_FieldStepPrs::booleanValues() const
222 {
223   DataPtr aData = myFeature->data();
224   int aStep = myStep->id();
225   AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
226   int aRows = aTablesAttr->rows();
227   int aCols = aTablesAttr->columns();
228   QList<int> aFieldStepData;
229   for (int k = 1; k < aRows; k++) { // Do not use default values
230     for (int j = 0; j < aCols; j++) {
231       ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
232       aFieldStepData << (aVal.myBool ? 1 : 0);
233     }
234   }
235   QList<double> aShapeData;
236   double aRangeMin = aFieldStepData.first(), aRangeMax = aFieldStepData.last();
237   for (int aRow = 0; aRow < aRows - 1; aRow++) {
238     double aNorm = 0;
239     int aBaseIndex = aRow * aCols;
240     for (int aCol = 0; aCol < aCols; aCol++) {
241       aNorm += aFieldStepData.at(aCol + aBaseIndex);
242     }
243     aNorm /= aCols;
244     aShapeData << aNorm;
245   }
246   return aShapeData;
247 }
248
249 QStringList PartSet_FieldStepPrs::strings() const
250 {
251   DataPtr aData = myFeature->data();
252   int aStep = myStep->id();
253   AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
254   int aRows = aTablesAttr->rows();
255   int aCols = aTablesAttr->columns();
256   QStringList aFieldStepData;
257   for (int k = 1; k < aRows; k++) { // Do not use default values
258     for (int j = 0; j < aCols; j++) {
259       ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
260       aFieldStepData << aVal.myStr.c_str();
261     }
262   }
263   QStringList aShapeData;
264   for (int aRow = 0; aRow < aRows - 1; aRow++) {
265     QStringList aRowStrings;
266     int aBaseIndex = aRow * aCols;
267     for (int aCol = 0; aCol < aCols; aCol++) {
268       aRowStrings << aFieldStepData.at(aCol + aBaseIndex);
269     }
270     aRowStrings.join('\n');
271     aShapeData << aRowStrings;
272   }
273   return aShapeData;
274 }
275
276 bool PartSet_FieldStepPrs::computeMassCenter(const TopoDS_Shape& theShape, gp_Pnt& theCenter)
277 {
278   theCenter.SetCoord(0, 0, 0);
279   int aNbPoints = 0;
280
281   if (theShape.ShapeType() == TopAbs_EDGE) {
282     double f, l;
283     Handle(Geom_Curve) curve = BRep_Tool::Curve(TopoDS::Edge(theShape), f, l);
284     if (!curve.IsNull()) {
285       theCenter = curve->Value(0.5 * (f + l));
286       aNbPoints = 1;
287     }
288   }
289   else if (theShape.ShapeType() == TopAbs_FACE) {
290     const TopoDS_Face& F = TopoDS::Face(theShape);
291     BRepAdaptor_Surface surface(F);
292
293     TopLoc_Location L;
294     Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(F, L);
295     if (!triangulation.IsNull() && triangulation->HasUVNodes()) {
296       gp_XY C(0, 0);
297       double A = 0;
298       const TColgp_Array1OfPnt2d& uvArray = triangulation->UVNodes();
299       const Poly_Array1OfTriangle&  trias = triangulation->Triangles();
300       int n1, n2, n3;
301       for (int iT = trias.Lower(); iT <= trias.Upper(); ++iT) {
302         trias(iT).Get(n1, n2, n3);
303         const gp_Pnt2d& uv1 = uvArray(n1);
304         const gp_Pnt2d& uv2 = uvArray(n2);
305         const gp_Pnt2d& uv3 = uvArray(n3);
306         double a = 0.5 * sqrt((uv1.X() - uv3.X()) * (uv2.Y() - uv1.Y()) -
307           (uv1.X() - uv2.X()) * (uv3.Y() - uv1.Y()));
308         C += (uv1.XY() + uv2.XY() + uv3.XY()) / 3. * a;
309         A += a;
310       }
311       if (A > std::numeric_limits<double>::min()) {
312         C /= A;
313         theCenter = surface.Value(C.X(), C.Y());
314         aNbPoints = 1;
315       }
316     }
317     if (aNbPoints == 0) {
318       theCenter = surface.Value(0.5 * (surface.FirstUParameter() + surface.LastUParameter()),
319         0.5 * (surface.FirstVParameter() + surface.LastVParameter()));
320     }
321     aNbPoints = 1;
322   }
323
324   if (aNbPoints == 0) {
325     TopExp_Explorer anExp;
326     for (anExp.Init(theShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
327       TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
328       if (!aVertex.IsNull()) {
329         gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
330         theCenter.ChangeCoord() += aPnt.XYZ();
331         aNbPoints++;
332       }
333     }
334   }
335
336   if (aNbPoints > 0)
337     theCenter.ChangeCoord() /= (double)aNbPoints;
338
339   return aNbPoints;
340 }