From 376d3f226c11ba3024b43f67c4b356912358f8e7 Mon Sep 17 00:00:00 2001 From: ouv Date: Tue, 5 Aug 2008 09:43:34 +0000 Subject: [PATCH] Feature 0017291: EDF 591 SMESH : Visualization of the orientation of the normal vector of the mesh faces --- resources/SalomeApp.xml | 3 + src/OBJECT/Makefile.am | 6 +- src/OBJECT/SMESH_Actor.cxx | 31 ++- src/OBJECT/SMESH_Actor.h | 3 + src/OBJECT/SMESH_ActorDef.h | 5 + src/OBJECT/SMESH_ActorUtils.cxx | 2 +- src/OBJECT/SMESH_DeviceActor.cxx | 74 ++++- src/OBJECT/SMESH_DeviceActor.h | 14 + src/OBJECT/SMESH_FaceOrientationFilter.cxx | 306 +++++++++++++++++++++ src/OBJECT/SMESH_FaceOrientationFilter.h | 67 +++++ src/SMESHGUI/SMESHGUI.cxx | 37 +++ src/SMESHGUI/SMESHGUI_Selection.cxx | 20 +- src/SMESHGUI/SMESHGUI_Selection.h | 1 + src/SMESHGUI/SMESH_msg_en.ts | 28 ++ 14 files changed, 584 insertions(+), 13 deletions(-) create mode 100644 src/OBJECT/SMESH_FaceOrientationFilter.cxx create mode 100644 src/OBJECT/SMESH_FaceOrientationFilter.h diff --git a/resources/SalomeApp.xml b/resources/SalomeApp.xml index 8f4b7b0e8..699b8b52c 100644 --- a/resources/SalomeApp.xml +++ b/resources/SalomeApp.xml @@ -12,6 +12,9 @@ + + + diff --git a/src/OBJECT/Makefile.am b/src/OBJECT/Makefile.am index 23723718d..5da7d38af 100644 --- a/src/OBJECT/Makefile.am +++ b/src/OBJECT/Makefile.am @@ -32,7 +32,8 @@ salomeinclude_HEADERS = \ SMESH_Actor.h \ SMESH_Object.h \ SMESH_ObjectDef.h \ - SMESH_ActorUtils.h + SMESH_ActorUtils.h \ + SMESH_FaceOrientationFilter.h # Libraries targets @@ -43,7 +44,8 @@ dist_libSMESHObject_la_SOURCES = \ SMESH_DeviceActor.cxx \ SMESH_Actor.cxx \ SMESH_ExtractGeometry.cxx \ - SMESH_ActorUtils.cxx + SMESH_ActorUtils.cxx \ + SMESH_FaceOrientationFilter.cxx libSMESHObject_la_CPPFLAGS = \ $(KERNEL_CXXFLAGS) \ diff --git a/src/OBJECT/SMESH_Actor.cxx b/src/OBJECT/SMESH_Actor.cxx index b22919124..9655756f5 100644 --- a/src/OBJECT/SMESH_Actor.cxx +++ b/src/OBJECT/SMESH_Actor.cxx @@ -116,6 +116,8 @@ SMESH_ActorDef::SMESH_ActorDef() myIsShrinkable = false; myIsShrunk = false; + myIsFacesOriented = false; + myControlsPrecision = -1; SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) ) @@ -512,6 +514,22 @@ void SMESH_ActorDef::SetCellsLabeled(bool theIsCellsLabeled) } +void SMESH_ActorDef::SetFacesOriented(bool theIsFacesOriented) +{ + myIsFacesOriented = theIsFacesOriented; + + my2DActor->SetFacesOriented(theIsFacesOriented); + my3DActor->SetFacesOriented(theIsFacesOriented); + + myTimeStamp->Modified(); +} + +bool SMESH_ActorDef::GetFacesOriented() +{ + return myIsFacesOriented; +} + + void SMESH_ActorDef:: SetControlMode(eControl theMode) @@ -693,8 +711,8 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){ theRenderer->AddActor(myNodeActor); theRenderer->AddActor(myBaseActor); - theRenderer->AddActor(my3DActor); - theRenderer->AddActor(my2DActor); + my3DActor->AddToRender(theRenderer); + my2DActor->AddToRender(theRenderer); theRenderer->AddActor(my1DActor); theRenderer->AddActor(my1DExtActor); @@ -721,8 +739,8 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){ theRenderer->RemoveActor(my1DActor); theRenderer->RemoveActor(my1DExtActor); - theRenderer->RemoveActor(my2DActor); - theRenderer->RemoveActor(my3DActor); + my2DActor->RemoveFromRender(theRenderer); + my3DActor->RemoveFromRender(theRenderer); theRenderer->RemoveActor(myScalarBarActor); theRenderer->RemoveActor(myPointLabels); @@ -770,7 +788,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj, //SetIsShrunkable(theGrid->GetNumberOfCells() > 10); SetIsShrunkable(true); - SetShrinkFactor( SMESH::GetFloat( "SMESH:shrink_coeff", 0.75 ) ); + SetShrinkFactor( SMESH::GetFloat( "SMESH:shrink_coeff", 75 ) / 100. ); int aMode = mgr->integerValue( "SMESH", "display_mode" ); SetRepresentation(-1); @@ -1266,6 +1284,9 @@ void SMESH_ActorDef::Update(){ if(myIsCellsLabeled){ SetCellsLabeled(myIsCellsLabeled); } + if(myIsFacesOriented){ + SetFacesOriented(myIsFacesOriented); + } SetEntityMode(GetEntityMode()); SetVisibility(GetVisibility()); diff --git a/src/OBJECT/SMESH_Actor.h b/src/OBJECT/SMESH_Actor.h index 04dd4cead..638e9c9d5 100644 --- a/src/OBJECT/SMESH_Actor.h +++ b/src/OBJECT/SMESH_Actor.h @@ -93,6 +93,9 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor virtual void SetCellsLabeled(bool theIsCellsLabeled) = 0; virtual bool GetCellsLabeled() = 0; + virtual void SetFacesOriented(bool theIsFacesOriented) = 0; + virtual bool GetFacesOriented() = 0; + enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eMultiConnection, eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew, eAspectRatio3D, eMultiConnection2D, eVolume3D}; diff --git a/src/OBJECT/SMESH_ActorDef.h b/src/OBJECT/SMESH_ActorDef.h index c1e55d415..a087e08d3 100644 --- a/src/OBJECT/SMESH_ActorDef.h +++ b/src/OBJECT/SMESH_ActorDef.h @@ -168,6 +168,9 @@ class SMESH_ActorDef : public SMESH_Actor virtual void SetCellsLabeled(bool theIsCellsLabeled); virtual bool GetCellsLabeled(){ return myIsCellsLabeled;} + virtual void SetFacesOriented(bool theIsFacesOriented); + virtual bool GetFacesOriented(); + virtual void SetControlMode(eControl theMode); virtual eControl GetControlMode(){ return myControlMode;} @@ -250,6 +253,8 @@ class SMESH_ActorDef : public SMESH_Actor TCippingPlaneCont myCippingPlaneCont; long myControlsPrecision; + bool myIsFacesOriented; + SMESH_ActorDef(); ~SMESH_ActorDef(); diff --git a/src/OBJECT/SMESH_ActorUtils.cxx b/src/OBJECT/SMESH_ActorUtils.cxx index cee51d0fb..946a93df9 100644 --- a/src/OBJECT/SMESH_ActorUtils.cxx +++ b/src/OBJECT/SMESH_ActorUtils.cxx @@ -62,7 +62,7 @@ namespace SMESH vtkFloatingPointType val = theDefault; SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); if( mgr ) - val = (vtkFloatingPointType) mgr->doubleValue( theValue, theSection, theDefault ); + val = (vtkFloatingPointType) mgr->doubleValue( theSection, theValue, theDefault ); return val; } diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 8a7341b49..2399636e5 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -31,6 +31,7 @@ #include "SMESH_ExtractGeometry.h" #include "SMESH_ControlsDef.hxx" #include "SMESH_ActorUtils.h" +#include "SMESH_FaceOrientationFilter.h" #include "VTKViewer_CellLocationsArray.h" #include @@ -61,6 +62,8 @@ #include #include +#include + #include "utilities.h" #ifdef _DEBUG_ @@ -111,6 +114,21 @@ SMESH_DeviceActor for(int i = 0; i < 6; i++) myPassFilter.push_back(vtkPassThroughFilter::New()); + + // Orientation of faces + myIsFacesOriented = false; + + vtkFloatingPointType anRGB[3] = { 1, 1, 1 }; + SMESH::GetColor( "SMESH", "orientation_color", anRGB[0], anRGB[1], anRGB[2], QColor( 255, 255, 255 ) ); + + myFaceOrientationFilter = SMESH_FaceOrientationFilter::New(); + + myFaceOrientationDataMapper = vtkPolyDataMapper::New(); + myFaceOrientationDataMapper->SetInput(myFaceOrientationFilter->GetOutput()); + + myFaceOrientation = vtkActor::New(); + myFaceOrientation->SetMapper(myFaceOrientationDataMapper); + myFaceOrientation->GetProperty()->SetColor(anRGB[0], anRGB[1], anRGB[2]); } @@ -138,6 +156,14 @@ SMESH_DeviceActor for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++){ myPassFilter[i]->Delete(); } + + // Orientation of faces + myFaceOrientationFilter->Delete(); + + myFaceOrientationDataMapper->RemoveAllInputs(); + myFaceOrientationDataMapper->Delete(); + + myFaceOrientation->Delete(); } @@ -221,17 +247,13 @@ SMESH_DeviceActor anId++; // 3 myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); - myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); anId++; // 4 myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() ); myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() ); - myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() ); - myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() ); anId++; // 5 myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); - myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); vtkLODActor::SetMapper( myMapper ); Modified(); @@ -536,6 +558,7 @@ SMESH_DeviceActor mTime = max(mTime,myMergeFilter->GetMTime()); mTime = max(mTime,myGeomFilter->GetMTime()); mTime = max(mTime,myTransformFilter->GetMTime()); + mTime = max(mTime,myFaceOrientationFilter->GetMTime()); return mTime; } @@ -576,6 +599,30 @@ SMESH_DeviceActor } +void +SMESH_DeviceActor +::SetFacesOriented(bool theIsFacesOriented) +{ + if ( vtkDataSet* aDataSet = myPassFilter[ 1 ]->GetOutput() ) + { + myIsFacesOriented = theIsFacesOriented; + if( theIsFacesOriented ) + myFaceOrientationFilter->SetInput( aDataSet ); + UpdateFaceOrientation(); + } +} + +void +SMESH_DeviceActor +::UpdateFaceOrientation() +{ + bool aShowFaceOrientation = myIsFacesOriented; + aShowFaceOrientation &= GetVisibility(); + aShowFaceOrientation &= myRepresentation == eSurface; + myFaceOrientation->SetVisibility(aShowFaceOrientation); +} + + void SMESH_DeviceActor ::SetRepresentation(EReperesent theMode) @@ -602,6 +649,7 @@ SMESH_DeviceActor GetProperty()->SetRepresentation(theMode); } myRepresentation = theMode; + UpdateFaceOrientation(); GetProperty()->Modified(); myMapper->Modified(); Modified(); @@ -619,6 +667,7 @@ SMESH_DeviceActor }else{ vtkLODActor::SetVisibility(false); } + UpdateFaceOrientation(); } @@ -633,6 +682,23 @@ SMESH_DeviceActor } +void +SMESH_DeviceActor +::AddToRender(vtkRenderer* theRenderer) +{ + theRenderer->AddActor(this); + theRenderer->AddActor(myFaceOrientation); +} + +void +SMESH_DeviceActor +::RemoveFromRender(vtkRenderer* theRenderer) +{ + theRenderer->RemoveActor(this); + theRenderer->RemoveActor(myFaceOrientation); +} + + int SMESH_DeviceActor ::GetNodeObjId(int theVtkID) diff --git a/src/OBJECT/SMESH_DeviceActor.h b/src/OBJECT/SMESH_DeviceActor.h index 5ec3be21d..f8ed9af9d 100644 --- a/src/OBJECT/SMESH_DeviceActor.h +++ b/src/OBJECT/SMESH_DeviceActor.h @@ -52,6 +52,7 @@ class VTKViewer_TransformFilter; class VTKViewer_ExtractUnstructuredGrid; class SMESH_ExtractGeometry; +class SMESH_FaceOrientationFilter; class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ @@ -74,6 +75,11 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ virtual void SetTransform(VTKViewer_Transform* theTransform); virtual unsigned long int GetMTime(); + virtual void SetFacesOriented(bool theIsFacesOriented); + virtual bool GetFacesOriented() { return myIsFacesOriented; } + + void UpdateFaceOrientation(); + vtkFloatingPointType GetShrinkFactor(); void SetShrinkFactor(vtkFloatingPointType value); @@ -89,6 +95,9 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ virtual void SetVisibility(int theMode); virtual int GetVisibility(); + virtual void AddToRender(vtkRenderer* theRenderer); + virtual void RemoveFromRender(vtkRenderer* theRenderer); + VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid(); vtkUnstructuredGrid* GetUnstructuredGrid(); @@ -124,6 +133,11 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ vtkMergeFilter* myMergeFilter; VTKViewer_ExtractUnstructuredGrid* myExtractUnstructuredGrid; + bool myIsFacesOriented; + SMESH_FaceOrientationFilter* myFaceOrientationFilter; + vtkPolyDataMapper* myFaceOrientationDataMapper; + vtkActor* myFaceOrientation; + bool myStoreClippingMapping; VTKViewer_GeometryFilter *myGeomFilter; VTKViewer_TransformFilter *myTransformFilter; diff --git a/src/OBJECT/SMESH_FaceOrientationFilter.cxx b/src/OBJECT/SMESH_FaceOrientationFilter.cxx new file mode 100644 index 000000000..e3d312e03 --- /dev/null +++ b/src/OBJECT/SMESH_FaceOrientationFilter.cxx @@ -0,0 +1,306 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SMESH_FaceOrientationFilter.h" +#include "SMESH_ActorUtils.h" + +#include "SUIT_Session.h" +#include "SUIT_ResourceMgr.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define PI 3.14159265359 + +vtkCxxRevisionMacro(SMESH_FaceOrientationFilter, "$Revision$"); +vtkStandardNewMacro(SMESH_FaceOrientationFilter); + +/*! + * \class SMESH_FaceOrientationFilter + * Passive filter take a polydata as input and create a dataset as output. + */ + +SMESH_FaceOrientationFilter::SMESH_FaceOrientationFilter() +{ + SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); + myOrientationScale = mgr->doubleValue( "SMESH", "orientation_scale", 0.1 ); + my3dVectors = mgr->booleanValue( "SMESH", "orientation_3d_vectors", false ); + + myArrowPolyData = CreateArrowPolyData(); + + myFacePolyData = vtkPolyData::New(); + + myFaceCenters = vtkCellCenters::New(); + myFaceCenters->SetInput(myFacePolyData); + + myFaceMaskPoints = vtkMaskPoints::New(); + myFaceMaskPoints->SetInput(myFaceCenters->GetOutput()); + myFaceMaskPoints->SetOnRatio(1); + + myGlyphSource = vtkGlyphSource2D::New(); + myGlyphSource->SetGlyphTypeToThickArrow(); + myGlyphSource->SetFilled(0); + myGlyphSource->SetCenter(0.5, 0.0, 0.0); + + myBaseGlyph = vtkGlyph3D::New(); + myBaseGlyph->SetInput(myFaceMaskPoints->GetOutput()); + myBaseGlyph->SetVectorModeToUseVector(); + myBaseGlyph->SetSource(my3dVectors ? myArrowPolyData : myGlyphSource->GetOutput()); +} + +SMESH_FaceOrientationFilter::~SMESH_FaceOrientationFilter() +{ + myArrowPolyData->Delete(); + myFacePolyData->Delete(); + myFaceCenters->Delete(); + myFaceMaskPoints->Delete(); + myGlyphSource->Delete(); + myBaseGlyph->Delete(); +} + +vtkPolyData* SMESH_FaceOrientationFilter::CreateArrowPolyData() +{ + vtkPoints* points = vtkPoints::New(); + vtkCellArray* polys = vtkCellArray::New(); + + float l1 = 0.8; + float l2 = 1.0; + int n = 16; + float r1 = 0.04; + float r2 = 0.08; + float angle = 2. * PI / n; + float p[3]; + vtkIdType c3[3]; + vtkIdType c4[4]; + + float p0[3] = { 0.0, 0.0, 0.0 }; + float p1[3] = { l1, 0.0, 0.0 }; + float p2[3] = { l2, 0.0, 0.0 }; + + points->InsertPoint( 0, p0 ); + points->InsertPoint( 1, p1 ); + points->InsertPoint( 2, p2 ); + + // shaft + for( int i = 0; i < n; i++ ) + { + p[0] = 0; + p[1] = r1 * sin( i * angle ); + p[2] = r1 * cos( i * angle ); + points->InsertPoint( i + 3, p ); + + p[0] = l1; + points->InsertPoint( i + 3 + n, p ); + } + + // insert the last cells outside a loop + { + c3[0] = 0; + c3[1] = 3; + c3[2] = 3 + n - 1; + polys->InsertNextCell( 3, c3 ); + + c4[0] = 3; + c4[1] = 3 + n - 1; + c4[2] = 3 + 2 * n - 1; + c4[3] = 3 + n; + polys->InsertNextCell( 4, c4 ); + } + for( int i = 0; i < n - 1; i++ ) + { + c3[0] = 0; + c3[1] = i + 3; + c3[2] = i + 4; + polys->InsertNextCell( 3, c3 ); + + c4[0] = i + 3; + c4[1] = i + 4; + c4[2] = i + 4 + n; + c4[3] = i + 3 + n; + polys->InsertNextCell( 4, c4 ); + } + + // cone + for( int i = 0; i < n; i++ ) + { + p[0] = l1; + p[1] = r2 * sin( i * angle ); + p[2] = r2 * cos( i * angle ); + points->InsertPoint( i + 3 + 2 * n, p ); + } + + // insert the last cells outside a loop + { + c3[0] = 1; + c3[1] = 3 + 2 * n; + c3[2] = 3 + 2 * n + n - 1; + polys->InsertNextCell( 3, c3 ); + + c3[0] = 2; + polys->InsertNextCell( 3, c3 ); + } + for( int i = 0; i < n - 1; i++ ) + { + c3[0] = 1; + c3[1] = 3 + i + 2 * n; + c3[2] = 3 + i + 2 * n + 1; + polys->InsertNextCell( 3, c3 ); + + c3[0] = 2; + polys->InsertNextCell( 3, c3 ); + } + + vtkPolyData* aPolyData = vtkPolyData::New(); + + aPolyData->SetPoints(points); + points->Delete(); + + aPolyData->SetPolys(polys); + polys->Delete(); + + return aPolyData; +} + +void GetFaceParams( vtkCell* theFace, double theNormal[3], double& theSize ) +{ + vtkPoints* aPoints = theFace->GetPoints(); + + // here we get first 3 points from the face and calculate the normal as a cross-product of vectors + double x0 = aPoints->GetPoint(0)[0], y0 = aPoints->GetPoint(0)[1], z0 = aPoints->GetPoint(0)[2]; + double x1 = aPoints->GetPoint(1)[0], y1 = aPoints->GetPoint(1)[1], z1 = aPoints->GetPoint(1)[2]; + double x2 = aPoints->GetPoint(2)[0], y2 = aPoints->GetPoint(2)[1], z2 = aPoints->GetPoint(2)[2]; + + theNormal[0] = ( y1 - y0 ) * ( z2 - z0 ) - ( z1 - z0 ) * ( y2 - y0 ); + theNormal[1] = ( z1 - z0 ) * ( x2 - x0 ) - ( x1 - x0 ) * ( z2 - z0 ); + theNormal[2] = ( x1 - x0 ) * ( y2 - y0 ) - ( y1 - y0 ) * ( x2 - x0 ); + + double* aBounds = theFace->GetBounds(); + theSize = pow( pow( aBounds[1] - aBounds[0], 2 ) + + pow( aBounds[3] - aBounds[2], 2 ) + + pow( aBounds[5] - aBounds[4], 2 ), 0.5 ); +} + +/*! + * Execute method. Output calculation. + */ +int SMESH_FaceOrientationFilter::RequestData( + vtkInformation *request, + vtkInformationVector **inputVector, + vtkInformationVector *outputVector) +{ + // get the info objects + vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); + vtkInformation *outInfo = outputVector->GetInformationObject(0); + + // get the input and ouptut + vtkDataSet *input = vtkDataSet::SafeDownCast( + inInfo->Get(vtkDataObject::DATA_OBJECT())); + vtkPolyData *output = vtkPolyData::SafeDownCast( + outInfo->Get(vtkDataObject::DATA_OBJECT())); + + myFacePolyData->Initialize(); + myFacePolyData->ShallowCopy(input); + + vtkCellArray* aFaces = vtkCellArray::New(); + + vtkFloatArray* aVectors = vtkFloatArray::New(); + aVectors->SetNumberOfComponents(3); + + int anAllFaces = 0; + double anAverageSize = 0; + + vtkIdList* aNeighborIds = vtkIdList::New(); + + for(int aCellId = 0, aNbCells = input->GetNumberOfCells(); aCellId < aNbCells; aCellId++) + { + vtkCell* aCell = input->GetCell(aCellId); + + if( aCell->GetNumberOfFaces() == 0 && aCell->GetNumberOfPoints() > 2 ) // cell is a face + { + double aSize, aNormal[3]; + GetFaceParams( aCell, aNormal, aSize ); + + aFaces->InsertNextCell(aCell); + aVectors->InsertNextTuple(aNormal); + + anAllFaces++; + anAverageSize += aSize; + + continue; + } + + for(int aFaceId = 0, aNbFaces = aCell->GetNumberOfFaces(); aFaceId < aNbFaces; aFaceId++) + { + vtkCell* aFace = aCell->GetFace(aFaceId); + + input->GetCellNeighbors( aCellId, aFace->PointIds, aNeighborIds ); + if( aNeighborIds->GetNumberOfIds() > 0 ) + continue; + + double aSize, aNormal[3]; + GetFaceParams( aFace, aNormal, aSize ); + + aFaces->InsertNextCell(aFace->GetPointIds()); + aVectors->InsertNextTuple(aNormal); + + anAllFaces++; + anAverageSize += aSize; + } + } + aNeighborIds->Delete(); + + myFacePolyData->SetPolys(aFaces); + aFaces->Delete(); + + myFacePolyData->GetCellData()->SetVectors(aVectors); + aVectors->Delete(); + + if( anAllFaces == 0 ) + return 0; + + anAverageSize /= anAllFaces; + anAverageSize *= myOrientationScale; + + myBaseGlyph->SetScaleFactor( anAverageSize ); + myBaseGlyph->Update(); + + output->ShallowCopy( myBaseGlyph->GetOutput() ); + + return 1; +} + +int SMESH_FaceOrientationFilter::FillInputPortInformation(int, vtkInformation *info) +{ + info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet"); + return 1; +} diff --git a/src/OBJECT/SMESH_FaceOrientationFilter.h b/src/OBJECT/SMESH_FaceOrientationFilter.h new file mode 100644 index 000000000..4c52c2daa --- /dev/null +++ b/src/OBJECT/SMESH_FaceOrientationFilter.h @@ -0,0 +1,67 @@ +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef SMESH_FACEORIENTATIONFILTER_H +#define SMESH_FACEORIENTATIONFILTER_H + +#include "SMESH_Object.h" + +#include + +class vtkCellCenters; +class vtkGlyph3D; +class vtkGlyphSource2D; +class vtkMaskPoints; + +class SMESHOBJECT_EXPORT SMESH_FaceOrientationFilter : public vtkPolyDataAlgorithm +{ +public: + vtkTypeRevisionMacro( SMESH_FaceOrientationFilter, vtkPolyDataAlgorithm ); + + /*!Create a new SMESH_FaceOrientationFilter.*/ + static SMESH_FaceOrientationFilter *New(); + +protected: + SMESH_FaceOrientationFilter(); + virtual ~SMESH_FaceOrientationFilter(); + + virtual int RequestData(vtkInformation *, vtkInformationVector **, + vtkInformationVector *); //generate output data + + virtual int FillInputPortInformation(int port, vtkInformation *info); + + vtkPolyData* CreateArrowPolyData(); + +private: + SMESH_FaceOrientationFilter( const SMESH_FaceOrientationFilter& ); //!< Not implemented. + void operator=( const SMESH_FaceOrientationFilter& ); //!< Not implemented. + +private: + bool my3dVectors; + vtkFloatingPointType myOrientationScale; + vtkPolyData* myArrowPolyData; + vtkPolyData* myFacePolyData; + vtkCellCenters* myFaceCenters; + vtkMaskPoints* myFaceMaskPoints; + vtkGlyphSource2D* myGlyphSource; + vtkGlyph3D* myBaseGlyph; +}; + +#endif diff --git a/src/SMESHGUI/SMESHGUI.cxx b/src/SMESHGUI/SMESHGUI.cxx index 9c5dab2b6..7f5322540 100644 --- a/src/SMESHGUI/SMESHGUI.cxx +++ b/src/SMESHGUI/SMESHGUI.cxx @@ -1403,6 +1403,23 @@ bool SMESHGUI::OnGUIEvent( int theCommandID ) ::SetDisplayEntity(theCommandID); break; + case 221: // Orientation of faces + { + LightApp_SelectionMgr* mgr = selectionMgr(); + SALOME_ListIO selected; mgr->selectedObjects( selected ); + + SALOME_ListIteratorOfListIO it(selected); + for( ; it.More(); it.Next()) { + Handle(SALOME_InteractiveObject) anIObject = it.Value(); + if(anIObject->hasEntry()) { + if(SMESH_Actor *anActor = SMESH::FindActorByEntry(anIObject->getEntry())){ + anActor->SetFacesOriented( !anActor->GetFacesOriented() ); + } + } + } + break; + } + case 214: // UPDATE { if(checkLock(aStudy)) break; @@ -2620,6 +2637,7 @@ void SMESHGUI::initialize( CAM_Application* app ) createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true ); createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true ); createSMESHAction( 220, "ALL" ); + createSMESHAction( 221, "FACE_ORIENTATION", "", 0, true ); createSMESHAction( 1100, "EDIT_HYPO" ); createSMESHAction( 1101, "RENAME", "", Qt::Key_F2 ); createSMESHAction( 1102, "UNASSIGN" ); @@ -3009,6 +3027,13 @@ void SMESHGUI::initialize( CAM_Application* app ) popupMgr()->insert( action( 220 ), anId, -1 ); // ALL popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule ); + //------------------------------------------------- + // Orientation of faces + //------------------------------------------------- + popupMgr()->insert( action( 221 ), -1, -1 ); + popupMgr()->setRule( action( 221 ), aMeshInVTK + "&& isVisible", QtxPopupMgr::VisibleRule); + popupMgr()->setRule( action( 221 ), "facesOrientationMode = 'IsOriented'", QtxPopupMgr::ToggleRule ); + //------------------------------------------------- // Color / Size //------------------------------------------------- @@ -3355,6 +3380,18 @@ void SMESHGUI::createPreferences() setPreferenceProperty( shrink, "min", 0 ); setPreferenceProperty( shrink, "max", 100 ); + int orientGroup = addPreference( tr( "PREF_GROUP_FACES_ORIENTATION" ), meshTab ); + setPreferenceProperty( orientGroup, "columns", 1 ); + + addPreference( tr( "PREF_ORIENTATION_COLOR" ), orientGroup, LightApp_Preferences::Color, "SMESH", "orientation_color" ); + int orientScale = addPreference( tr( "PREF_ORIENTATION_SCALE" ), orientGroup, LightApp_Preferences::DblSpin, "SMESH", "orientation_scale" ); + + setPreferenceProperty( orientScale, "min", 0 ); + setPreferenceProperty( orientScale, "max", 1 ); + setPreferenceProperty( orientScale, "step", 0.1 ); + + addPreference( tr( "PREF_ORIENTATION_3D_VECTORS" ), orientGroup, LightApp_Preferences::Bool, "SMESH", "orientation_3d_vectors" ); + int selTab = addPreference( tr( "PREF_TAB_SELECTION" ) ); int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab ); diff --git a/src/SMESHGUI/SMESHGUI_Selection.cxx b/src/SMESHGUI/SMESHGUI_Selection.cxx index 6ec33b7ce..4711f1d10 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.cxx +++ b/src/SMESHGUI/SMESHGUI_Selection.cxx @@ -115,7 +115,7 @@ QVariant SMESHGUI_Selection::parameter( const int ind, const QString& p ) const else if ( p=="isComputable" ) val = QVariant( isComputable( ind ) ); else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) ); else if ( p=="isImported" ) val = QVariant( isImported( ind ) ); - + else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) ); if( val.isValid() ) return val; @@ -255,6 +255,22 @@ QString SMESHGUI_Selection::controlMode( int ind ) const return "eNone"; } +//======================================================================= +//function : facesOrientationMode +//purpose : +//======================================================================= + +QString SMESHGUI_Selection::facesOrientationMode( int ind ) const +{ + SMESH_Actor* actor = getActor( ind ); + if ( actor ) { + if ( actor->GetFacesOriented() ) + return "IsOriented"; + return "IsNotOriented"; + } + return "Unknown"; +} + //======================================================================= //function : isAutoColor //purpose : @@ -494,6 +510,7 @@ bool SMESHGUI_Selection::isImported( const int ind ) const QString e = entry( ind ); _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() ); bool res = false; + /* if( SO ) { SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( SO ) ); @@ -503,5 +520,6 @@ bool SMESHGUI_Selection::isImported( const int ind ) const res = strlen( (char*)inf->fileName ) > 0; } } + */ return res; } diff --git a/src/SMESHGUI/SMESHGUI_Selection.h b/src/SMESHGUI/SMESHGUI_Selection.h index 4d1ba4a63..dfcac17f6 100644 --- a/src/SMESHGUI/SMESHGUI_Selection.h +++ b/src/SMESHGUI/SMESHGUI_Selection.h @@ -64,6 +64,7 @@ public: virtual QString shrinkMode( int ) const; virtual QList entityMode( int ) const; virtual QString controlMode( int ) const; + virtual QString facesOrientationMode( int ) const; SMESH_Actor* getActor( int ) const; diff --git a/src/SMESHGUI/SMESH_msg_en.ts b/src/SMESHGUI/SMESH_msg_en.ts index bef24fd98..cf8fff441 100644 --- a/src/SMESHGUI/SMESH_msg_en.ts +++ b/src/SMESHGUI/SMESH_msg_en.ts @@ -202,6 +202,10 @@ MEN_DEL_GROUP Delete Groups + + MEN_FACE_ORIENTATION + Orientation of faces + MEN_DISABLE_AUTO_COLOR Disable auto color @@ -1940,6 +1944,10 @@ Consider saving your work before application crash STB_DEL_GROUP Delete Groups + + STB_FACE_ORIENTATION + Orientation of faces + STB_DISABLE_AUTO_COLOR Disable auto color @@ -2392,6 +2400,10 @@ Consider saving your work before application crash TOP_DEL_GROUP Delete Groups + + TOP_FACE_ORIENTATION + Orientation of faces + TOP_DISABLE_AUTO_COLOR Disable auto color @@ -2796,6 +2808,18 @@ Please, create VTK viewer and try again PREF_COLOR Color + + PREF_ORIENTATION_COLOR + Color + + + PREF_ORIENTATION_3D_VECTORS + 3D vectors + + + PREF_ORIENTATION_SCALE + Scale + PREF_DISPLAY_ENTITY Display entity @@ -2828,6 +2852,10 @@ Please, create VTK viewer and try again PREF_GROUP_EXPORT Mesh export + + PREF_GROUP_FACES_ORIENTATION + Orientation of faces + PREF_GROUP_COMPUTE Mesh computation -- 2.39.2