1 // Copyright (C) 2014-2016 CEA/DEN, EDF R&D, OPEN CASCADE
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
21 #include "OCCViewer_Utilities.h"
22 #include "OCCViewer_ViewFrame.h"
23 #include "OCCViewer_ViewModel.h"
24 #include "OCCViewer_ViewPort3d.h"
26 #include "SUIT_ViewManager.h"
27 #include "QtxActionToolMgr.h"
28 #include "QtxMultiAction.h"
31 #include <Basics_OCCTVersion.hxx>
34 #include <V3d_View.hxx>
35 #include <Graphic3d_MapIteratorOfMapOfStructure.hxx>
42 Handle(Image_PixMap) OCCViewer_Utilities::imageToPixmap( const QImage& anImage )
44 Handle(Image_PixMap) aPixmap = new Image_PixMap();
45 if ( !anImage.isNull() ) {
46 aPixmap->InitTrash( Image_PixMap::ImgBGRA, anImage.width(), anImage.height() );
47 aPixmap->SetTopDown( Standard_True );
49 const uchar* aImageBytes = anImage.bits();
51 for ( int aLine = anImage.height() - 1; aLine >= 0; --aLine ) {
52 #if OCC_VERSION_LARGE > 0x06070100
53 // convert pixels from ARGB to renderer-compatible RGBA
54 for ( int aByte = 0; aByte < anImage.width(); ++aByte ) {
55 Image_ColorBGRA& aPixmapBytes = aPixmap->ChangeValue<Image_ColorBGRA>(aLine, aByte);
57 aPixmapBytes.b() = (Standard_Byte) *aImageBytes++;
58 aPixmapBytes.g() = (Standard_Byte) *aImageBytes++;
59 aPixmapBytes.r() = (Standard_Byte) *aImageBytes++;
60 aPixmapBytes.a() = (Standard_Byte) *aImageBytes++;
63 Image_ColorBGRA* aPixmapBytes = aPixmap->EditData<Image_ColorBGRA>().ChangeRow(aLine);
65 // convert pixels from ARGB to renderer-compatible RGBA
66 for ( int aByte = 0; aByte < anImage.width(); ++aByte ) {
67 aPixmapBytes->b() = (Standard_Byte) *aImageBytes++;
68 aPixmapBytes->g() = (Standard_Byte) *aImageBytes++;
69 aPixmapBytes->r() = (Standard_Byte) *aImageBytes++;
70 aPixmapBytes->a() = (Standard_Byte) *aImageBytes++;
79 OCCViewer_ViewWindow::Mode2dType OCCViewer_Utilities::setViewer2DMode
80 ( OCCViewer_Viewer* theViewer,
81 const OCCViewer_ViewWindow::Mode2dType& theMode )
83 OCCViewer_ViewWindow::Mode2dType anOldMode = OCCViewer_ViewWindow::No2dMode;
84 OCCViewer_ViewFrame* aFrame = dynamic_cast<OCCViewer_ViewFrame*>
85 ( theViewer->getViewManager()->getActiveView() );
86 OCCViewer_ViewWindow* aView = aFrame ? aFrame->getView( OCCViewer_ViewFrame::MAIN_VIEW ) : 0;
91 anOldMode = aView->get2dMode();
92 aView->set2dMode( theMode );
93 bool is2dMode = theMode != OCCViewer_ViewWindow::No2dMode;
95 // enable/disable view actions
96 QList<int> aNo2dActions;
97 aNo2dActions << OCCViewer_ViewWindow::ChangeRotationPointId
98 << OCCViewer_ViewWindow::RotationId
99 << OCCViewer_ViewWindow::FrontId
100 << OCCViewer_ViewWindow::BackId
101 //<< OCCViewer_ViewWindow::TopId
102 << OCCViewer_ViewWindow::BottomId
103 << OCCViewer_ViewWindow::LeftId
104 << OCCViewer_ViewWindow::RightId
105 << OCCViewer_ViewWindow::AntiClockWiseId
106 << OCCViewer_ViewWindow::ClockWiseId
107 << OCCViewer_ViewWindow::OrthographicId
108 << OCCViewer_ViewWindow::PerspectiveId
109 << OCCViewer_ViewWindow::ResetId;
111 QtxActionToolMgr* aToolMgr = aView->toolMgr();
113 for ( int i = 0, aNb = aNo2dActions.size(); i < aNb; i++ ) {
114 anAction = aToolMgr->action( aNo2dActions[i] );
116 anAction->setEnabled( !is2dMode );
118 QAction* aTop = aToolMgr->action( OCCViewer_ViewWindow::TopId );
119 QtxMultiAction* aMulti = dynamic_cast<QtxMultiAction*>( aTop->parent() );
120 aMulti->setActiveAction( aTop );
122 // change view position
123 Handle(V3d_View) aView3d = aView->getViewPort()->getView();
124 if ( !aView3d.IsNull() ) {
126 case OCCViewer_ViewWindow::XYPlane:
127 aView3d->SetProj (V3d_Zpos);
129 case OCCViewer_ViewWindow::XZPlane:
130 aView3d->SetProj (V3d_Yneg);
132 case OCCViewer_ViewWindow::YZPlane:
133 aView3d->SetProj (V3d_Xpos);
141 bool OCCViewer_Utilities::isDialogOpened( OCCViewer_ViewWindow* theView, const QString& theName )
143 bool isFound = false;
144 OCCViewer_ViewFrame* aViewFrame = dynamic_cast<OCCViewer_ViewFrame*>( theView->parent()->parent() );
145 QList<QDialog*> allDialogs = aViewFrame->findChildren<QDialog*>();
146 foreach ( QDialog* d, allDialogs )
147 if ( d->objectName() == theName )
152 bool OCCViewer_Utilities::computeVisibleBounds( const Handle(V3d_View) theView,
153 double theBounds[6] )
157 theBounds[0] = theBounds[2] = theBounds[4] = DBL_MAX;
158 theBounds[1] = theBounds[3] = theBounds[5] = -DBL_MAX;
160 Graphic3d_MapOfStructure aSetOfStructures;
161 theView->View()->DisplayedStructures( aSetOfStructures );
162 Graphic3d_MapIteratorOfMapOfStructure aStructureIt( aSetOfStructures );
164 for( ; aStructureIt.More(); aStructureIt.Next() ) {
165 const Handle(Graphic3d_Structure)& aStructure = aStructureIt.Key();
166 if ( aStructure->IsEmpty() || !aStructure->IsVisible() ||
167 aStructure->IsInfinite() || aStructure->CStructure()->IsForHighlight )
170 #if OCC_VERSION_LARGE > 0x06070100
171 Bnd_Box aBox = aStructure->MinMaxValues();
172 aBounds[0] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X();
173 aBounds[2] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y();
174 aBounds[4] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Z();
175 aBounds[1] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X();
176 aBounds[3] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y();
177 aBounds[5] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z();
179 aStructure->MinMaxValues( aBounds[0], aBounds[2], aBounds[4],
180 aBounds[1], aBounds[3], aBounds[5] );
183 if ( aBounds[0] > -DBL_MAX && aBounds[1] < DBL_MAX &&
184 aBounds[2] > -DBL_MAX && aBounds[3] < DBL_MAX &&
185 aBounds[4] > -DBL_MAX && aBounds[5] < DBL_MAX )
188 for ( int i = 0; i < 5; i = i + 2 ) {
189 theBounds[i] = std::min( theBounds[i], aBounds[i] );
190 theBounds[i+1] = std::max( theBounds[i+1], aBounds[i+1] );
197 bool OCCViewer_Utilities::computeVisibleBBCenter( const Handle(V3d_View) theView,
198 double& theX, double& theY, double& theZ )
201 if ( !computeVisibleBounds( theView, aBounds ) )
203 // null bounding box => the center is (0,0,0)
210 static double aMinDistance = 1.0 / DBL_MAX;
212 double aLength = aBounds[1]-aBounds[0];
213 aLength = std::max( ( aBounds[3]-aBounds[2]), aLength );
214 aLength = std::max( ( aBounds[5]-aBounds[4]), aLength );
216 if ( aLength < aMinDistance )
219 double aWidth = sqrt( ( aBounds[1] - aBounds[0] ) * ( aBounds[1] - aBounds[0] ) +
220 ( aBounds[3] - aBounds[2] ) * ( aBounds[3] - aBounds[2] ) +
221 ( aBounds[5] - aBounds[4] ) * ( aBounds[5] - aBounds[4] ) );
223 if(aWidth < aMinDistance)
226 theX = (aBounds[0] + aBounds[1])/2.0;
227 theY = (aBounds[2] + aBounds[3])/2.0;
228 theZ = (aBounds[4] + aBounds[5])/2.0;