1 // Copyright (C) 2014-2017 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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "XGUI_InspectionPanel.h"
22 #include "XGUI_SelectionMgr.h"
23 #include "XGUI_Selection.h"
24 #include "XGUI_Tools.h"
26 #include <ModuleBase_ViewerPrs.h>
27 #include <ModuleBase_Tools.h>
29 #include <ModelAPI_Result.h>
32 #include <QScrollArea>
35 #include <QTableWidget>
36 #include <QHeaderView>
37 #include <QTextBrowser>
39 #include <BRep_Tool.hxx>
40 #include <GeomAbs_CurveType.hxx>
41 #include <GeomAdaptor_Curve.hxx>
42 #include <Geom_BSplineCurve.hxx>
43 #include <gp_Circ.hxx>
44 #include <gp_Elips.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_ListOfShape.hxx>
47 #include <TopoDS_Iterator.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <TopoDS_Edge.hxx>
51 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic
53 XGUI_InspectionPanel::XGUI_InspectionPanel(QWidget* theParent, XGUI_SelectionMgr* theMgr)
54 : QDockWidget(theParent),
55 mySelectionMgr(theMgr)
57 setWindowTitle(tr("Inspection Panel"));
58 setObjectName(INSPECTION_PANEL);
59 setStyleSheet("::title { position: relative; padding-left: 5px; text-align: left center }");
61 QScrollArea* aScrollArea = new QScrollArea(this);
62 setWidget(aScrollArea);
64 // Create an internal widget
65 QWidget* aMainWidget = new QWidget(aScrollArea);
67 QVBoxLayout* aMainLayout = new QVBoxLayout(aMainWidget);
68 aMainLayout->setContentsMargins(5, 5, 5, 5);
70 QWidget* aNameWgt = new QWidget(aMainWidget);
71 QHBoxLayout* aNameLayout = new QHBoxLayout(aNameWgt);
72 aNameLayout->setContentsMargins(0, 0, 0, 0);
73 aNameLayout->addWidget(new QLabel(tr("Object"), aNameWgt));
74 myNameEdt = new QLineEdit(aNameWgt);
75 myNameEdt->setReadOnly(true);
76 aNameLayout->addWidget(myNameEdt);
78 aMainLayout->addWidget(aNameWgt);
80 // Table with sub-shapes
81 mySubShapesTab = new QTableWidget(9, 2, aMainWidget);
82 mySubShapesTab->setFocusPolicy(Qt::NoFocus);
83 mySubShapesTab->verticalHeader()->hide();
85 aTitles << tr("Sub-shapes") << tr("Number");
86 mySubShapesTab->setHorizontalHeaderLabels(aTitles);
88 QStringList aSubShapes;
89 aSubShapes << "SHAPE" << "COMPOUND" << "COMPSOLID" <<
90 "SOLID" << "SHELL" << "FACE" << "WIRE" << "EDGE" << "VERTEX";
92 foreach(QString aType, aSubShapes) {
93 QTableWidgetItem* aItem = new QTableWidgetItem(aType);
94 aItem->setFlags(Qt::ItemIsEnabled);
95 mySubShapesTab->setItem(i++, 0, aItem);
97 for (i = 0; i < 9; i++) {
98 QTableWidgetItem* aItem = new QTableWidgetItem("");
99 aItem->setFlags(Qt::ItemIsEnabled);
100 aItem->setTextAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
101 mySubShapesTab->setItem(i, 1, aItem);
103 mySubShapesTab->setColumnWidth(0, 90);
104 mySubShapesTab->setColumnWidth(1, 70);
106 mySubShapesTab->setMaximumWidth(170);
107 mySubShapesTab->setMinimumHeight(300);
109 aMainLayout->addWidget(mySubShapesTab);
112 QWidget* aTypeWgt = new QWidget(aMainWidget);
113 QHBoxLayout* aTypeLayout = new QHBoxLayout(aTypeWgt);
114 aTypeLayout->setContentsMargins(0, 0, 0, 0);
116 aTypeLayout->addWidget(new QLabel(tr("Type:"), aTypeWgt));
117 myTypeLbl = new QLabel("", aTypeWgt);
118 aTypeLayout->addWidget(myTypeLbl);
120 aMainLayout->addWidget(aTypeWgt);
122 myTypeParams = new QTextBrowser(aMainWidget);
123 myTypeParams->setMaximumWidth(170);
124 myTypeParams->setMaximumHeight(160);
125 myTypeParams->setReadOnly(true);
126 myTypeParams->setFocusPolicy(Qt::NoFocus);
127 myTypeParams->setFrameStyle(QFrame::NoFrame);
128 myTypeParams->viewport()->setBackgroundRole(QPalette::Window);
130 aMainLayout->addWidget(myTypeParams);
132 aScrollArea->setWidget(aMainWidget);
134 connect(mySelectionMgr, SIGNAL(selectionChanged()), SLOT(onSelectionChanged()));
137 //********************************************************************
138 XGUI_InspectionPanel::~XGUI_InspectionPanel()
142 //********************************************************************
143 void XGUI_InspectionPanel::setSubShapeValue(SudShape theId, int theVal)
145 mySubShapesTab->item(theId, 1)->setText(QString::number(theVal));
148 //********************************************************************
149 void XGUI_InspectionPanel::clearContent()
152 for (int i = 0; i <= VertexId; i++) {
153 mySubShapesTab->item((SudShape)i, 1)->setText("");
155 myTypeLbl->setText("");
156 myTypeParams->setText("");
159 //********************************************************************
160 void XGUI_InspectionPanel::onSelectionChanged()
163 XGUI_Selection* aSelection = mySelectionMgr->selection();
164 QList<ModuleBase_ViewerPrsPtr> aSelectedList = aSelection->getSelected(ModuleBase_ISelection::Viewer);
165 if (aSelectedList.count() > 0) {
166 ModuleBase_ViewerPrsPtr aPrs = aSelectedList.first();
167 setName(XGUI_Tools::generateName(aPrs));
169 TopoDS_Shape aShape = ModuleBase_Tools::getSelectedShape(aPrs);
170 setShapeContent(aShape);
171 setShapeParams(aShape);
175 //********************************************************************
176 void XGUI_InspectionPanel::setName(const QString& theName)
178 myNameEdt->setText(theName);
181 //********************************************************************
182 void XGUI_InspectionPanel::setShapeContent(const TopoDS_Shape& theShape)
186 int iType, nbTypes[TopAbs_SHAPE];
187 for (iType = 0; iType < TopAbs_SHAPE; ++iType) {
190 nbTypes[theShape.ShapeType()]++;
192 TopTools_MapOfShape aMapOfShape;
193 aMapOfShape.Add(theShape);
194 TopTools_ListOfShape aListOfShape;
195 aListOfShape.Append(theShape);
197 TopTools_ListIteratorOfListOfShape itL(aListOfShape);
198 for (; itL.More(); itL.Next()) {
199 TopoDS_Shape sp = itL.Value();
200 TopoDS_Iterator it(sp);
201 for (; it.More(); it.Next()) {
202 TopoDS_Shape s = it.Value();
203 if (aMapOfShape.Add(s)) {
204 aListOfShape.Append(s);
205 nbTypes[s.ShapeType()]++;
209 setSubShapeValue(VertexId, nbTypes[TopAbs_VERTEX]);
210 setSubShapeValue(EdgeId, nbTypes[TopAbs_EDGE]);
211 setSubShapeValue(WireId, nbTypes[TopAbs_WIRE]);
212 setSubShapeValue(FaceId, nbTypes[TopAbs_FACE]);
213 setSubShapeValue(ShellId, nbTypes[TopAbs_SHELL]);
214 setSubShapeValue(SolidId, nbTypes[TopAbs_SOLID]);
215 setSubShapeValue(CompsolidId, nbTypes[TopAbs_COMPSOLID]);
216 setSubShapeValue(CompoundId, nbTypes[TopAbs_COMPOUND]);
217 setSubShapeValue(ShapeId, aMapOfShape.Extent());
219 catch (Standard_Failure) {
220 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
221 //SetErrorCode(aFail->GetMessageString());
225 //********************************************************************
226 void XGUI_InspectionPanel::setShapeParams(const TopoDS_Shape& theShape)
228 switch (theShape.ShapeType()) {
230 fillVertex(theShape);
243 case TopAbs_COMPSOLID:
244 case TopAbs_COMPOUND:
245 fillContainer(theShape);
250 //********************************************************************
251 void XGUI_InspectionPanel::fillVertex(const TopoDS_Shape& theShape)
253 TopoDS_Vertex aV = TopoDS::Vertex(theShape);
254 gp_Pnt aP = BRep_Tool::Pnt(aV);
255 setVertexType(aP.XYZ());
258 //********************************************************************
259 void XGUI_InspectionPanel::fillEdge(const TopoDS_Shape& theShape)
261 TopoDS_Edge aE = TopoDS::Edge(theShape);
263 bool bDegenerated = BRep_Tool::Degenerated(aE);
266 Handle(Geom_Curve) aC3D = BRep_Tool::Curve(aE, aT1, aT2);
267 GeomAdaptor_Curve aGAC(aC3D);
268 GeomAbs_CurveType aCT = aGAC.GetType();
270 if (aCT == GeomAbs_Line) { // Line
274 setLineType(aP1.XYZ(), aP2.XYZ());
276 } else if (aCT == GeomAbs_Circle) {
277 gp_Circ aCirc = aGAC.Circle();
278 gp_Pnt aP = aCirc.Location();
279 gp_Ax2 aAx2 = aCirc.Position();
280 double aR1 = aCirc.Radius();
281 gp_Dir aDir = aAx2.Axis().Direction();
283 bool isArc = (Abs(aT2 - aT1 - aC3D->Period()) >= Precision::PConfusion());
288 setArcType(aP.XYZ(), aDir.XYZ(), aR1, aP1.XYZ(), aP2.XYZ());
290 setCircleType(aP.XYZ(), aDir.XYZ(), aR1);
292 } else if (aCT == GeomAbs_Ellipse) {
293 gp_Elips aElips = aGAC.Ellipse();
294 gp_Pnt aP = aElips.Location();
295 gp_Ax2 aAx2 = aElips.Position();
296 double aR1 = aElips.MajorRadius();
297 double aR2 = aElips.MinorRadius();
298 gp_Dir aDir = aAx2.Axis().Direction();
302 bool isArc = aP1.Distance(aP2) > Precision::Confusion();
304 setEllipseArcType(aP.XYZ(), aDir.XYZ(), aR1, aR2, aP1.XYZ(), aP2.XYZ());
306 setEllipseType(aP.XYZ(), aDir.XYZ(), aR1, aR2);
310 //********************************************************************
311 void XGUI_InspectionPanel::fillFace(const TopoDS_Shape& theShape)
316 //********************************************************************
317 void XGUI_InspectionPanel::fillSolid(const TopoDS_Shape& theShape)
322 //********************************************************************
323 void XGUI_InspectionPanel::fillContainer(const TopoDS_Shape& theShape)
328 //********************************************************************
329 #define TITLE(val) ("<b>" + val + "</b>")
331 void XGUI_InspectionPanel::setCylinderType(double theX, double theY, double theZ,
332 double theDX, double theDY, double theDZ, double theRadius, double theHeight)
334 myTypeLbl->setText(tr("Cylinder"));
335 QString aParams = TITLE(tr("Center")) +
336 "<br> X: " + QString::number(theX) +
337 "<br> Y: " + QString::number(theY) +
338 "<br> Z: " + QString::number(theZ) +
339 "<br>" + TITLE(tr("Axis")) +
340 "<br> DX: " + QString::number(theDX) +
341 "<br> DY: " + QString::number(theDY) +
342 "<br> DZ: " + QString::number(theDZ) +
343 "<br>" + TITLE(tr("Dimensions")) +
344 "<br>" + tr("Radius:") + QString::number(theRadius) +
345 "<br>" + tr("Height") + QString::number(theHeight);
347 myTypeParams->setText(aParams);
350 //********************************************************************
351 void XGUI_InspectionPanel::setSphereType(double theX, double theY, double theZ, double theRadius)
353 myTypeLbl->setText(tr("Sphere"));
354 QString aParams = TITLE(tr("Center")) +
355 "<br> X: " + QString::number(theX) +
356 "<br> Y: " + QString::number(theY) +
357 "<br> Z: " + QString::number(theZ) +
358 "<br>" + TITLE(tr("Dimensions")) +
359 "<br>" + tr("Radius:") + QString::number(theRadius);
360 myTypeParams->setText(aParams);
363 //********************************************************************
364 void XGUI_InspectionPanel::setBoxType(double theX, double theY, double theZ,
365 double theXsize, double theYsize, double theZsize)
367 myTypeLbl->setText(tr("Box"));
368 QString aParams = TITLE(tr("Position")) +
369 "<br> X: " + QString::number(theX) +
370 "<br> Y: " + QString::number(theY) +
371 "<br> Z: " + QString::number(theZ) +
372 "<br>" + TITLE(tr("Dimensions")) +
373 "<br>" + "Ax :" + QString::number(theXsize) +
374 "<br>" + "Ay :" + QString::number(theYsize) +
375 "<br>" + "Az :" + QString::number(theZsize);
376 myTypeParams->setText(aParams);
379 //********************************************************************
380 void XGUI_InspectionPanel::setRotatedBoxType(double theX, double theY, double theZ,
381 double theZaxisX, double theZaxisY, double theZaxisZ,
382 double theXaxisX, double theXaxisY, double theXaxisZ,
383 double theXsize, double theYsize, double theZsize)
385 myTypeLbl->setText(tr("Box"));
386 QString aParams = TITLE(tr("Position")) +
387 "<br> X: " + QString::number(theX) +
388 "<br> Y: " + QString::number(theY) +
389 "<br> Z: " + QString::number(theZ) +
390 "<br>" + TITLE(tr("Z axis")) +
391 "<br> DX: " + QString::number(theZaxisX) +
392 "<br> DY: " + QString::number(theZaxisY) +
393 "<br> DZ: " + QString::number(theZaxisZ) +
394 "<br>" + TITLE(tr("X axis")) +
395 "<br> DX: " + QString::number(theXaxisX) +
396 "<br> DY: " + QString::number(theXaxisY) +
397 "<br> DZ: " + QString::number(theXaxisZ) +
398 "<br>" + TITLE(tr("Dimensions")) +
399 "<br>" + "Ax :" + QString::number(theXsize) +
400 "<br>" + "Ay :" + QString::number(theYsize) +
401 "<br>" + "Az :" + QString::number(theZsize);
402 myTypeParams->setText(aParams);
405 //********************************************************************
406 void XGUI_InspectionPanel::setPlaneType(double theX, double theY, double theZ,
407 double theDX, double theDY, double theDZ)
409 myTypeLbl->setText(tr("Plane"));
410 QString aParams = TITLE(tr("Center")) +
411 "<br> X: " + QString::number(theX) +
412 "<br> Y: " + QString::number(theY) +
413 "<br> Z: " + QString::number(theZ) +
414 "<br>" + TITLE(tr("Normal")) +
415 "<br> DX: " + QString::number(theDX) +
416 "<br> DY: " + QString::number(theDY) +
417 "<br> DZ: " + QString::number(theDZ);
418 myTypeParams->setText(aParams);
421 //********************************************************************
422 void XGUI_InspectionPanel::setVertexType(const gp_XYZ& theLoc)
424 myTypeLbl->setText(tr("Vertex"));
425 QString aParams = TITLE(tr("Coordinates")) +
426 "<br> X: " + QString::number(theLoc.X()) +
427 "<br> Y: " + QString::number(theLoc.Y()) +
428 "<br> Z: " + QString::number(theLoc.Z());
429 myTypeParams->setText(aParams);
432 //********************************************************************
433 void XGUI_InspectionPanel::setCircleType(const gp_XYZ& theLoc, const gp_XYZ& theDir,
436 myTypeLbl->setText(tr("Circle"));
437 QString aParams = TITLE(tr("Center")) +
438 "<br> X: " + QString::number(theLoc.X()) +
439 "<br> Y: " + QString::number(theLoc.Y()) +
440 "<br> Z: " + QString::number(theLoc.Z()) +
441 "<br>" + TITLE(tr("Normal")) +
442 "<br> DX: " + QString::number(theDir.X()) +
443 "<br> DY: " + QString::number(theDir.Y()) +
444 "<br> DZ: " + QString::number(theDir.Z()) +
445 "<br>" + TITLE(tr("Dimensions")) +
446 "<br>" + tr("Radius:") + QString::number(theRadius);
447 myTypeParams->setText(aParams);
450 //********************************************************************
451 void XGUI_InspectionPanel::setArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir,
452 double theRadius, const gp_XYZ& theP1, const gp_XYZ& theP2)
454 myTypeLbl->setText(tr("Arc"));
455 QString aParams = TITLE(tr("Center")) +
456 "<br> X: " + QString::number(theLoc.X()) +
457 "<br> Y: " + QString::number(theLoc.Y()) +
458 "<br> Z: " + QString::number(theLoc.Z()) +
459 "<br>" + TITLE(tr("Normal")) +
460 "<br> DX: " + QString::number(theDir.X()) +
461 "<br> DY: " + QString::number(theDir.Y()) +
462 "<br> DZ: " + QString::number(theDir.Z()) +
463 "<br>" + TITLE(tr("Dimensions")) +
464 "<br>" + tr("Radius:") + QString::number(theRadius) +
465 "<br>" + TITLE(tr("Point 1")) +
466 "<br> X: " + QString::number(theP1.X()) +
467 "<br> Y: " + QString::number(theP1.Y()) +
468 "<br> Z: " + QString::number(theP1.Z()) +
469 "<br>" + TITLE(tr("Point 2")) +
470 "<br> X: " + QString::number(theP2.X()) +
471 "<br> Y: " + QString::number(theP2.Y()) +
472 "<br> Z: " + QString::number(theP2.Z());
473 myTypeParams->setText(aParams);
476 //********************************************************************
477 void XGUI_InspectionPanel::setEllipseType(const gp_XYZ& theLoc, const gp_XYZ& theDir,
478 double theMajorRad, double theMinorRad)
480 myTypeLbl->setText(tr("Ellipse"));
481 QString aParams = TITLE(tr("Center")) +
482 "<br> X: " + QString::number(theLoc.X()) +
483 "<br> Y: " + QString::number(theLoc.Y()) +
484 "<br> Z: " + QString::number(theLoc.Z()) +
485 "<br>" + TITLE(tr("Normal")) +
486 "<br> DX: " + QString::number(theDir.X()) +
487 "<br> DY: " + QString::number(theDir.Y()) +
488 "<br> DZ: " + QString::number(theDir.Z()) +
489 "<br>" + TITLE(tr("Dimensions")) +
490 "<br>" + tr("Major radius:") + QString::number(theMajorRad) +
491 "<br>" + tr("Minor radius:") + QString::number(theMinorRad);
492 myTypeParams->setText(aParams);
495 //********************************************************************
496 void XGUI_InspectionPanel::setEllipseArcType(const gp_XYZ& theLoc, const gp_XYZ& theDir,
497 double theMajorRad, double theMinorRad, const gp_XYZ& theP1, const gp_XYZ& theP2)
499 myTypeLbl->setText(tr("Elliptical arc"));
500 QString aParams = TITLE(tr("Center")) +
501 "<br> X: " + QString::number(theLoc.X()) +
502 "<br> Y: " + QString::number(theLoc.Y()) +
503 "<br> Z: " + QString::number(theLoc.Z()) +
504 "<br>" + TITLE(tr("Normal")) +
505 "<br> DX: " + QString::number(theDir.X()) +
506 "<br> DY: " + QString::number(theDir.Y()) +
507 "<br> DZ: " + QString::number(theDir.Z()) +
508 "<br>" + TITLE(tr("Dimensions")) +
509 "<br>" + tr("Major radius:") + QString::number(theMajorRad) +
510 "<br>" + tr("Minor radius:") + QString::number(theMinorRad) +
511 "<br>" + TITLE(tr("Point 1")) +
512 "<br> X: " + QString::number(theP1.X()) +
513 "<br> Y: " + QString::number(theP1.Y()) +
514 "<br> Z: " + QString::number(theP1.Z()) +
515 "<br>" + TITLE(tr("Point 2")) +
516 "<br> X: " + QString::number(theP2.X()) +
517 "<br> Y: " + QString::number(theP2.Y()) +
518 "<br> Z: " + QString::number(theP2.Z());
519 myTypeParams->setText(aParams);
522 void XGUI_InspectionPanel::setLineType(const gp_XYZ& theP1, const gp_XYZ& theP2)
524 myTypeLbl->setText(tr("Line"));
525 QString aParams = TITLE(tr("Point 1")) +
526 "<br> X: " + QString::number(theP1.X()) +
527 "<br> Y: " + QString::number(theP1.Y()) +
528 "<br> Z: " + QString::number(theP1.Z()) +
529 "<br>" + TITLE(tr("Point 2")) +
530 "<br> X: " + QString::number(theP2.X()) +
531 "<br> Y: " + QString::number(theP2.Y()) +
532 "<br> Z: " + QString::number(theP2.Z());
533 myTypeParams->setText(aParams);