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