1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "PartSet_FieldStepPrs.h"
22 #include <ModuleBase_Preferences.h>
24 #include <CollectionPlugin_Field.h>
26 #include <ModelAPI_AttributeSelectionList.h>
27 #include <ModelAPI_AttributeIntArray.h>
28 #include <ModelAPI_AttributeStringArray.h>
30 #include <SUIT_ResourceMgr.h>
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>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <Graphic3d_Text.hxx>
43 IMPLEMENT_STANDARD_RTTIEXT(PartSet_FieldStepPrs, ViewerData_AISShape);
48 void emptyDeleter(ModelAPI_ResultField* /*theF*/)
53 PartSet_FieldStepPrs::PartSet_FieldStepPrs(FieldStepPtr theStep)
54 : ViewerData_AISShape(TopoDS_Shape()), myStep(theStep)
56 ModelAPI_ResultField* aField = theStep->field();
57 GeomShapePtr aShapePtr = aField->shape();
58 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
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);
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);
73 aDrawer->SetPointAspect(
74 new Prs3d_PointAspect(Aspect_TOM_POINT, Quantity_NOC_YELLOW, POINT_SIZE));
76 SetMaterial(Graphic3d_NOM_PLASTIC);
80 ModelAPI_AttributeTables::ValueType PartSet_FieldStepPrs::dataType() const
82 DataPtr aData = myFeature->data();
83 AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
84 return aTablesAttr->type();
87 bool PartSet_FieldStepPrs::dataRange(double& theMin, double& theMax) const
89 ModelAPI_AttributeTables::ValueType aType = dataType();
90 if ((aType == ModelAPI_AttributeTables::DOUBLE) || (aType == ModelAPI_AttributeTables::INTEGER)) {
91 range(theMin, theMax);
97 QList<double> PartSet_FieldStepPrs::range(double& theMin, double& theMax) const
99 ModelAPI_AttributeTables::ValueType aType = dataType();
100 DataPtr aData = myFeature->data();
101 AttributeSelectionListPtr aSelList = aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
102 std::string aTypeStr = aSelList->selectionType();
104 int aStep = myStep->id();
105 AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
106 int aRows = aTablesAttr->rows();
107 int aCols = aTablesAttr->columns();
109 QList<double> aFieldStepData;
110 int aStart = (aTypeStr == "part")? 0:1;
111 for (int k = aStart; k < aRows; k++) { // Do not use default values
112 for (int j = 0; j < aCols; j++) {
113 ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
115 case ModelAPI_AttributeTables::DOUBLE:
116 aFieldStepData << aVal.myDouble;
118 case ModelAPI_AttributeTables::INTEGER:
119 aFieldStepData << aVal.myInt;
121 default: // [to avoid compilation warning]
126 QList<double> aShapeData;
127 double aRangeMin = aFieldStepData.first(), aRangeMax = aFieldStepData.last();
129 for (int aRow = 0; aRow < aRows - aStart; aRow++) {
130 double aValue = aFieldStepData.at(aRow);
131 aRangeMin = Min(aRangeMin, aValue);
132 aRangeMax = Max(aRangeMax, aValue);
133 aShapeData << aValue;
137 for (int aRow = 0; aRow < aRows - aStart; aRow++) {
139 int aBaseIndex = aRow * aCols;
140 for (int aCol = 0; aCol < aCols; aCol++) {
141 int anIndex = aCol + aBaseIndex;
142 double aValue = aFieldStepData.at(anIndex);
143 aNorm += aValue * aValue;
145 aNorm = pow(aNorm, 0.5);
146 aRangeMin = Min(aRangeMin, aNorm);
147 aRangeMax = Max(aRangeMax, aNorm);
157 void PartSet_FieldStepPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePrsMgr,
158 const Handle(Prs3d_Presentation)& thePrs, const Standard_Integer theMode)
160 SUIT_ResourceMgr* aResMgr = ModuleBase_Preferences::resourceMgr();
161 QColor aQColor = aResMgr->colorValue("Viewer", "scalar_bar_text_color", Qt::black);
162 Quantity_Color aLabelColor = Quantity_Color(aQColor.redF(), aQColor.greenF(), aQColor.blueF(),
165 ModelAPI_AttributeTables::ValueType aType = dataType();
166 DataPtr aData = myFeature->data();
168 case ModelAPI_AttributeTables::DOUBLE:
169 case ModelAPI_AttributeTables::INTEGER:
172 QList<double> aShapeData = range(aMin, aMax);
174 AttributeSelectionListPtr aSelList =
175 aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
176 std::string aTypeStr = aSelList->selectionType();
177 if (aTypeStr == "part") {
178 Quantity_Color aColor;
179 if (AIS_ColorScale::FindColor(aMin, aMin, aMax, 1, aColor)) {
184 int aNbIntertvals = aResMgr->integerValue("Viewer", "scalar_bar_nb_intervals", 20);
185 for (int i = 0; i < aSelList->size(); i++) {
186 AttributeSelectionPtr aSelection = aSelList->value(i);
187 GeomShapePtr aShapePtr = aSelection->value();
188 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
189 double aValue = aShapeData.at(i);
190 Quantity_Color aColor;
191 if (AIS_ColorScale::FindColor(aValue, aMin, aMax, aNbIntertvals, aColor))
192 SetCustomColor(aShape, aColor);
197 case ModelAPI_AttributeTables::BOOLEAN:
199 QList<double> aShapeData = booleanValues();
201 AttributeSelectionListPtr aSelList =
202 aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
203 for (int i = 0; i < aSelList->size(); i++) {
204 AttributeSelectionPtr aSelection = aSelList->value(i);
205 GeomShapePtr aShapePtr = aSelection->value();
206 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
207 double aValue = aShapeData.at(i);
208 Quantity_Color aColor;
209 if (AIS_ColorScale::FindColor(aValue, 0., 1., 2, aColor))
210 SetCustomColor(aShape, aColor);
214 case ModelAPI_AttributeTables::STRING:
216 QStringList aValues = strings();
217 AttributeSelectionListPtr aSelList =
218 aData->selectionList(CollectionPlugin_Field::SELECTED_ID());
219 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
220 for (int i = 0; i < aSelList->size(); i++) {
221 AttributeSelectionPtr aSelection = aSelList->value(i);
222 GeomShapePtr aShapePtr = aSelection->value();
223 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
225 if (computeMassCenter(aShape, aCenter)) {
226 Handle(Graphic3d_AspectText3d) anAspectText3d = new Graphic3d_AspectText3d();
227 anAspectText3d->SetStyle(Aspect_TOST_ANNOTATION);
228 anAspectText3d->SetColor(aLabelColor);
229 aGroup->SetPrimitivesAspect(anAspectText3d);
231 int aT = aResMgr->integerValue("Viewer", "scalar_bar_text_height", 14);
232 QString aString = aValues.at(i);
233 Handle(Graphic3d_Text) aText = new Graphic3d_Text(aT);
234 aText->SetText(aString.toUtf8().constData());
235 aText->SetPosition(aCenter);
236 aGroup->AddText(aText);
242 ViewerData_AISShape::Compute(thePrsMgr, thePrs, theMode);
245 QList<double> PartSet_FieldStepPrs::booleanValues() const
247 DataPtr aData = myFeature->data();
248 int aStep = myStep->id();
249 AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
250 int aRows = aTablesAttr->rows();
251 int aCols = aTablesAttr->columns();
252 QList<int> aFieldStepData;
253 for (int k = 1; k < aRows; k++) { // Do not use default values
254 for (int j = 0; j < aCols; j++) {
255 ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
256 aFieldStepData << (aVal.myBool ? 1 : 0);
259 QList<double> aShapeData;
260 for (int aRow = 0; aRow < aRows - 1; aRow++) {
262 int aBaseIndex = aRow * aCols;
263 for (int aCol = 0; aCol < aCols; aCol++) {
264 aNorm += aFieldStepData.at(aCol + aBaseIndex);
272 QStringList PartSet_FieldStepPrs::strings() const
274 DataPtr aData = myFeature->data();
275 int aStep = myStep->id();
276 AttributeTablesPtr aTablesAttr = aData->tables(CollectionPlugin_Field::VALUES_ID());
277 int aRows = aTablesAttr->rows();
278 int aCols = aTablesAttr->columns();
279 QStringList aFieldStepData;
280 for (int k = 1; k < aRows; k++) { // Do not use default values
281 for (int j = 0; j < aCols; j++) {
282 ModelAPI_AttributeTables::Value aVal = aTablesAttr->value(k, j, aStep);
283 aFieldStepData << aVal.myStr.c_str();
286 QStringList aShapeData;
287 for (int aRow = 0; aRow < aRows - 1; aRow++) {
288 QStringList aRowStrings;
289 int aBaseIndex = aRow * aCols;
290 for (int aCol = 0; aCol < aCols; aCol++) {
291 aRowStrings << aFieldStepData.at(aCol + aBaseIndex);
293 aRowStrings.join('\n');
294 aShapeData << aRowStrings;
299 bool PartSet_FieldStepPrs::computeMassCenter(const TopoDS_Shape& theShape, gp_Pnt& theCenter)
301 theCenter.SetCoord(0, 0, 0);
304 if (theShape.ShapeType() == TopAbs_EDGE) {
306 Handle(Geom_Curve) curve = BRep_Tool::Curve(TopoDS::Edge(theShape), f, l);
307 if (!curve.IsNull()) {
308 theCenter = curve->Value(0.5 * (f + l));
312 else if (theShape.ShapeType() == TopAbs_FACE) {
313 const TopoDS_Face& F = TopoDS::Face(theShape);
314 BRepAdaptor_Surface surface(F);
317 Handle(Poly_Triangulation) triangulation = BRep_Tool::Triangulation(F, L);
318 if (!triangulation.IsNull() && triangulation->HasUVNodes()) {
321 const TColgp_Array1OfPnt2d& uvArray = triangulation->UVNodes();
322 const Poly_Array1OfTriangle& trias = triangulation->Triangles();
324 for (int iT = trias.Lower(); iT <= trias.Upper(); ++iT) {
325 trias(iT).Get(n1, n2, n3);
326 const gp_Pnt2d& uv1 = uvArray(n1);
327 const gp_Pnt2d& uv2 = uvArray(n2);
328 const gp_Pnt2d& uv3 = uvArray(n3);
329 double a = 0.5 * sqrt((uv1.X() - uv3.X()) * (uv2.Y() - uv1.Y()) -
330 (uv1.X() - uv2.X()) * (uv3.Y() - uv1.Y()));
331 C += (uv1.XY() + uv2.XY() + uv3.XY()) / 3. * a;
334 if (A > std::numeric_limits<double>::min()) {
336 theCenter = surface.Value(C.X(), C.Y());
340 if (aNbPoints == 0) {
341 theCenter = surface.Value(0.5 * (surface.FirstUParameter() + surface.LastUParameter()),
342 0.5 * (surface.FirstVParameter() + surface.LastVParameter()));
347 if (aNbPoints == 0) {
348 TopExp_Explorer anExp;
349 for (anExp.Init(theShape, TopAbs_VERTEX); anExp.More(); anExp.Next()) {
350 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
351 if (!aVertex.IsNull()) {
352 gp_Pnt aPnt = BRep_Tool::Pnt(aVertex);
353 theCenter.ChangeCoord() += aPnt.XYZ();
360 theCenter.ChangeCoord() /= (double)aNbPoints;