Feature 0017291: EDF 591 SMESH : Visualization of the orientation of the normal vector of the mesh faces

This commit is contained in:
ouv 2008-08-05 09:43:34 +00:00
parent 003b5a3e76
commit 376d3f226c
14 changed files with 584 additions and 13 deletions

View File

@ -12,6 +12,9 @@
<parameter name="node_size" value="3" /> <parameter name="node_size" value="3" />
<parameter name="element_width" value="1" /> <parameter name="element_width" value="1" />
<parameter name="shrink_coeff" value="75"/> <parameter name="shrink_coeff" value="75"/>
<parameter name="orientation_color" value="255, 255, 255"/>
<parameter name="orientation_scale" value="0.1"/>
<parameter name="orientation_3d_vectors" value="false"/>
<parameter name="selection_element_color" value="255, 255, 0"/> <parameter name="selection_element_color" value="255, 255, 0"/>
<parameter name="selection_object_color" value="255, 255, 255"/> <parameter name="selection_object_color" value="255, 255, 255"/>
<parameter name="selection_precision_element" value="0.005"/> <parameter name="selection_precision_element" value="0.005"/>

View File

@ -32,7 +32,8 @@ salomeinclude_HEADERS = \
SMESH_Actor.h \ SMESH_Actor.h \
SMESH_Object.h \ SMESH_Object.h \
SMESH_ObjectDef.h \ SMESH_ObjectDef.h \
SMESH_ActorUtils.h SMESH_ActorUtils.h \
SMESH_FaceOrientationFilter.h
# Libraries targets # Libraries targets
@ -43,7 +44,8 @@ dist_libSMESHObject_la_SOURCES = \
SMESH_DeviceActor.cxx \ SMESH_DeviceActor.cxx \
SMESH_Actor.cxx \ SMESH_Actor.cxx \
SMESH_ExtractGeometry.cxx \ SMESH_ExtractGeometry.cxx \
SMESH_ActorUtils.cxx SMESH_ActorUtils.cxx \
SMESH_FaceOrientationFilter.cxx
libSMESHObject_la_CPPFLAGS = \ libSMESHObject_la_CPPFLAGS = \
$(KERNEL_CXXFLAGS) \ $(KERNEL_CXXFLAGS) \

View File

@ -116,6 +116,8 @@ SMESH_ActorDef::SMESH_ActorDef()
myIsShrinkable = false; myIsShrinkable = false;
myIsShrunk = false; myIsShrunk = false;
myIsFacesOriented = false;
myControlsPrecision = -1; myControlsPrecision = -1;
SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
if ( mgr && mgr->booleanValue( "SMESH", "use_precision", false ) ) 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 void
SMESH_ActorDef:: SMESH_ActorDef::
SetControlMode(eControl theMode) SetControlMode(eControl theMode)
@ -693,8 +711,8 @@ void SMESH_ActorDef::AddToRender(vtkRenderer* theRenderer){
theRenderer->AddActor(myNodeActor); theRenderer->AddActor(myNodeActor);
theRenderer->AddActor(myBaseActor); theRenderer->AddActor(myBaseActor);
theRenderer->AddActor(my3DActor); my3DActor->AddToRender(theRenderer);
theRenderer->AddActor(my2DActor); my2DActor->AddToRender(theRenderer);
theRenderer->AddActor(my1DActor); theRenderer->AddActor(my1DActor);
theRenderer->AddActor(my1DExtActor); theRenderer->AddActor(my1DExtActor);
@ -721,8 +739,8 @@ void SMESH_ActorDef::RemoveFromRender(vtkRenderer* theRenderer){
theRenderer->RemoveActor(my1DActor); theRenderer->RemoveActor(my1DActor);
theRenderer->RemoveActor(my1DExtActor); theRenderer->RemoveActor(my1DExtActor);
theRenderer->RemoveActor(my2DActor); my2DActor->RemoveFromRender(theRenderer);
theRenderer->RemoveActor(my3DActor); my3DActor->RemoveFromRender(theRenderer);
theRenderer->RemoveActor(myScalarBarActor); theRenderer->RemoveActor(myScalarBarActor);
theRenderer->RemoveActor(myPointLabels); theRenderer->RemoveActor(myPointLabels);
@ -770,7 +788,7 @@ bool SMESH_ActorDef::Init(TVisualObjPtr theVisualObj,
//SetIsShrunkable(theGrid->GetNumberOfCells() > 10); //SetIsShrunkable(theGrid->GetNumberOfCells() > 10);
SetIsShrunkable(true); 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" ); int aMode = mgr->integerValue( "SMESH", "display_mode" );
SetRepresentation(-1); SetRepresentation(-1);
@ -1266,6 +1284,9 @@ void SMESH_ActorDef::Update(){
if(myIsCellsLabeled){ if(myIsCellsLabeled){
SetCellsLabeled(myIsCellsLabeled); SetCellsLabeled(myIsCellsLabeled);
} }
if(myIsFacesOriented){
SetFacesOriented(myIsFacesOriented);
}
SetEntityMode(GetEntityMode()); SetEntityMode(GetEntityMode());
SetVisibility(GetVisibility()); SetVisibility(GetVisibility());

View File

@ -93,6 +93,9 @@ class SMESHOBJECT_EXPORT SMESH_Actor: public SALOME_Actor
virtual void SetCellsLabeled(bool theIsCellsLabeled) = 0; virtual void SetCellsLabeled(bool theIsCellsLabeled) = 0;
virtual bool GetCellsLabeled() = 0; virtual bool GetCellsLabeled() = 0;
virtual void SetFacesOriented(bool theIsFacesOriented) = 0;
virtual bool GetFacesOriented() = 0;
enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eMultiConnection, enum eControl{eNone, eLength, eLength2D, eFreeBorders, eFreeEdges, eMultiConnection,
eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew, eArea, eTaper, eAspectRatio, eMinimumAngle, eWarping, eSkew,
eAspectRatio3D, eMultiConnection2D, eVolume3D}; eAspectRatio3D, eMultiConnection2D, eVolume3D};

View File

@ -168,6 +168,9 @@ class SMESH_ActorDef : public SMESH_Actor
virtual void SetCellsLabeled(bool theIsCellsLabeled); virtual void SetCellsLabeled(bool theIsCellsLabeled);
virtual bool GetCellsLabeled(){ return myIsCellsLabeled;} virtual bool GetCellsLabeled(){ return myIsCellsLabeled;}
virtual void SetFacesOriented(bool theIsFacesOriented);
virtual bool GetFacesOriented();
virtual void SetControlMode(eControl theMode); virtual void SetControlMode(eControl theMode);
virtual eControl GetControlMode(){ return myControlMode;} virtual eControl GetControlMode(){ return myControlMode;}
@ -250,6 +253,8 @@ class SMESH_ActorDef : public SMESH_Actor
TCippingPlaneCont myCippingPlaneCont; TCippingPlaneCont myCippingPlaneCont;
long myControlsPrecision; long myControlsPrecision;
bool myIsFacesOriented;
SMESH_ActorDef(); SMESH_ActorDef();
~SMESH_ActorDef(); ~SMESH_ActorDef();

View File

@ -62,7 +62,7 @@ namespace SMESH
vtkFloatingPointType val = theDefault; vtkFloatingPointType val = theDefault;
SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr(); SUIT_ResourceMgr* mgr = SUIT_Session::session()->resourceMgr();
if( mgr ) if( mgr )
val = (vtkFloatingPointType) mgr->doubleValue( theValue, theSection, theDefault ); val = (vtkFloatingPointType) mgr->doubleValue( theSection, theValue, theDefault );
return val; return val;
} }

View File

@ -31,6 +31,7 @@
#include "SMESH_ExtractGeometry.h" #include "SMESH_ExtractGeometry.h"
#include "SMESH_ControlsDef.hxx" #include "SMESH_ControlsDef.hxx"
#include "SMESH_ActorUtils.h" #include "SMESH_ActorUtils.h"
#include "SMESH_FaceOrientationFilter.h"
#include "VTKViewer_CellLocationsArray.h" #include "VTKViewer_CellLocationsArray.h"
#include <VTKViewer_Transform.h> #include <VTKViewer_Transform.h>
@ -61,6 +62,8 @@
#include <vtkImplicitBoolean.h> #include <vtkImplicitBoolean.h>
#include <vtkPassThroughFilter.h> #include <vtkPassThroughFilter.h>
#include <vtkRenderer.h>
#include "utilities.h" #include "utilities.h"
#ifdef _DEBUG_ #ifdef _DEBUG_
@ -111,6 +114,21 @@ SMESH_DeviceActor
for(int i = 0; i < 6; i++) for(int i = 0; i < 6; i++)
myPassFilter.push_back(vtkPassThroughFilter::New()); 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++){ for(int i = 0, iEnd = myPassFilter.size(); i < iEnd; i++){
myPassFilter[i]->Delete(); myPassFilter[i]->Delete();
} }
// Orientation of faces
myFaceOrientationFilter->Delete();
myFaceOrientationDataMapper->RemoveAllInputs();
myFaceOrientationDataMapper->Delete();
myFaceOrientation->Delete();
} }
@ -221,17 +247,13 @@ SMESH_DeviceActor
anId++; // 3 anId++; // 3
myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
anId++; // 4 anId++; // 4
myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() ); myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() ); myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
anId++; // 5 anId++; // 5
myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() ); myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
vtkLODActor::SetMapper( myMapper ); vtkLODActor::SetMapper( myMapper );
Modified(); Modified();
@ -536,6 +558,7 @@ SMESH_DeviceActor
mTime = max(mTime,myMergeFilter->GetMTime()); mTime = max(mTime,myMergeFilter->GetMTime());
mTime = max(mTime,myGeomFilter->GetMTime()); mTime = max(mTime,myGeomFilter->GetMTime());
mTime = max(mTime,myTransformFilter->GetMTime()); mTime = max(mTime,myTransformFilter->GetMTime());
mTime = max(mTime,myFaceOrientationFilter->GetMTime());
return mTime; 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 void
SMESH_DeviceActor SMESH_DeviceActor
::SetRepresentation(EReperesent theMode) ::SetRepresentation(EReperesent theMode)
@ -602,6 +649,7 @@ SMESH_DeviceActor
GetProperty()->SetRepresentation(theMode); GetProperty()->SetRepresentation(theMode);
} }
myRepresentation = theMode; myRepresentation = theMode;
UpdateFaceOrientation();
GetProperty()->Modified(); GetProperty()->Modified();
myMapper->Modified(); myMapper->Modified();
Modified(); Modified();
@ -619,6 +667,7 @@ SMESH_DeviceActor
}else{ }else{
vtkLODActor::SetVisibility(false); 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 int
SMESH_DeviceActor SMESH_DeviceActor
::GetNodeObjId(int theVtkID) ::GetNodeObjId(int theVtkID)

View File

@ -52,6 +52,7 @@ class VTKViewer_TransformFilter;
class VTKViewer_ExtractUnstructuredGrid; class VTKViewer_ExtractUnstructuredGrid;
class SMESH_ExtractGeometry; class SMESH_ExtractGeometry;
class SMESH_FaceOrientationFilter;
class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{ 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 void SetTransform(VTKViewer_Transform* theTransform);
virtual unsigned long int GetMTime(); virtual unsigned long int GetMTime();
virtual void SetFacesOriented(bool theIsFacesOriented);
virtual bool GetFacesOriented() { return myIsFacesOriented; }
void UpdateFaceOrientation();
vtkFloatingPointType GetShrinkFactor(); vtkFloatingPointType GetShrinkFactor();
void SetShrinkFactor(vtkFloatingPointType value); void SetShrinkFactor(vtkFloatingPointType value);
@ -89,6 +95,9 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
virtual void SetVisibility(int theMode); virtual void SetVisibility(int theMode);
virtual int GetVisibility(); virtual int GetVisibility();
virtual void AddToRender(vtkRenderer* theRenderer);
virtual void RemoveFromRender(vtkRenderer* theRenderer);
VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid(); VTKViewer_ExtractUnstructuredGrid* GetExtractUnstructuredGrid();
vtkUnstructuredGrid* GetUnstructuredGrid(); vtkUnstructuredGrid* GetUnstructuredGrid();
@ -124,6 +133,11 @@ class SMESHOBJECT_EXPORT SMESH_DeviceActor: public vtkLODActor{
vtkMergeFilter* myMergeFilter; vtkMergeFilter* myMergeFilter;
VTKViewer_ExtractUnstructuredGrid* myExtractUnstructuredGrid; VTKViewer_ExtractUnstructuredGrid* myExtractUnstructuredGrid;
bool myIsFacesOriented;
SMESH_FaceOrientationFilter* myFaceOrientationFilter;
vtkPolyDataMapper* myFaceOrientationDataMapper;
vtkActor* myFaceOrientation;
bool myStoreClippingMapping; bool myStoreClippingMapping;
VTKViewer_GeometryFilter *myGeomFilter; VTKViewer_GeometryFilter *myGeomFilter;
VTKViewer_TransformFilter *myTransformFilter; VTKViewer_TransformFilter *myTransformFilter;

View File

@ -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 <vtkCellData.h>
#include <vtkDataSet.h>
#include <vtkPolyData.h>
#include <vtkObjectFactory.h>
#include <vtkInformation.h>
#include <vtkInformationVector.h>
#include <vtkFloatArray.h>
#include <vtkCellArray.h>
#include <vtkMaskPoints.h>
#include <vtkCellCenters.h>
#include <vtkGlyph3D.h>
#include <vtkGlyphSource2D.h>
#include <QColor>
#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;
}

View File

@ -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 <vtkPolyDataAlgorithm.h>
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

View File

@ -1403,6 +1403,23 @@ bool SMESHGUI::OnGUIEvent( int theCommandID )
::SetDisplayEntity(theCommandID); ::SetDisplayEntity(theCommandID);
break; 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 case 214: // UPDATE
{ {
if(checkLock(aStudy)) break; if(checkLock(aStudy)) break;
@ -2620,6 +2637,7 @@ void SMESHGUI::initialize( CAM_Application* app )
createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true ); createSMESHAction( 218, "FACES", "ICON_DLG_TRIANGLE", 0, true );
createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true ); createSMESHAction( 219, "VOLUMES", "ICON_DLG_TETRAS", 0, true );
createSMESHAction( 220, "ALL" ); createSMESHAction( 220, "ALL" );
createSMESHAction( 221, "FACE_ORIENTATION", "", 0, true );
createSMESHAction( 1100, "EDIT_HYPO" ); createSMESHAction( 1100, "EDIT_HYPO" );
createSMESHAction( 1101, "RENAME", "", Qt::Key_F2 ); createSMESHAction( 1101, "RENAME", "", Qt::Key_F2 );
createSMESHAction( 1102, "UNASSIGN" ); createSMESHAction( 1102, "UNASSIGN" );
@ -3009,6 +3027,13 @@ void SMESHGUI::initialize( CAM_Application* app )
popupMgr()->insert( action( 220 ), anId, -1 ); // ALL popupMgr()->insert( action( 220 ), anId, -1 ); // ALL
popupMgr()->setRule( action( 220 ), aDiffElemsInVTK + "&& isVisible && not( elemTypes in entityMode )", QtxPopupMgr::VisibleRule ); 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 // Color / Size
//------------------------------------------------- //-------------------------------------------------
@ -3355,6 +3380,18 @@ void SMESHGUI::createPreferences()
setPreferenceProperty( shrink, "min", 0 ); setPreferenceProperty( shrink, "min", 0 );
setPreferenceProperty( shrink, "max", 100 ); 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 selTab = addPreference( tr( "PREF_TAB_SELECTION" ) );
int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab ); int selGroup = addPreference( tr( "PREF_GROUP_SELECTION" ), selTab );

View File

@ -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=="isComputable" ) val = QVariant( isComputable( ind ) );
else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) ); else if ( p=="hasReference" ) val = QVariant( hasReference( ind ) );
else if ( p=="isImported" ) val = QVariant( isImported( ind ) ); else if ( p=="isImported" ) val = QVariant( isImported( ind ) );
else if ( p=="facesOrientationMode" ) val = QVariant( facesOrientationMode( ind ) );
if( val.isValid() ) if( val.isValid() )
return val; return val;
@ -255,6 +255,22 @@ QString SMESHGUI_Selection::controlMode( int ind ) const
return "eNone"; 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 //function : isAutoColor
//purpose : //purpose :
@ -494,6 +510,7 @@ bool SMESHGUI_Selection::isImported( const int ind ) const
QString e = entry( ind ); QString e = entry( ind );
_PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() ); _PTR(SObject) SO = SMESH::GetActiveStudyDocument()->FindObjectID( e.toLatin1().constData() );
bool res = false; bool res = false;
/*
if( SO ) if( SO )
{ {
SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( SMESH::SObjectToObject( 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; res = strlen( (char*)inf->fileName ) > 0;
} }
} }
*/
return res; return res;
} }

View File

@ -64,6 +64,7 @@ public:
virtual QString shrinkMode( int ) const; virtual QString shrinkMode( int ) const;
virtual QList<QVariant> entityMode( int ) const; virtual QList<QVariant> entityMode( int ) const;
virtual QString controlMode( int ) const; virtual QString controlMode( int ) const;
virtual QString facesOrientationMode( int ) const;
SMESH_Actor* getActor( int ) const; SMESH_Actor* getActor( int ) const;

View File

@ -202,6 +202,10 @@
<source>MEN_DEL_GROUP</source> <source>MEN_DEL_GROUP</source>
<translation>Delete Groups</translation> <translation>Delete Groups</translation>
</message> </message>
<message>
<source>MEN_FACE_ORIENTATION</source>
<translation>Orientation of faces</translation>
</message>
<message> <message>
<source>MEN_DISABLE_AUTO_COLOR</source> <source>MEN_DISABLE_AUTO_COLOR</source>
<translation>Disable auto color</translation> <translation>Disable auto color</translation>
@ -1940,6 +1944,10 @@ Consider saving your work before application crash</translation>
<source>STB_DEL_GROUP</source> <source>STB_DEL_GROUP</source>
<translation>Delete Groups</translation> <translation>Delete Groups</translation>
</message> </message>
<message>
<source>STB_FACE_ORIENTATION</source>
<translation>Orientation of faces</translation>
</message>
<message> <message>
<source>STB_DISABLE_AUTO_COLOR</source> <source>STB_DISABLE_AUTO_COLOR</source>
<translation>Disable auto color</translation> <translation>Disable auto color</translation>
@ -2392,6 +2400,10 @@ Consider saving your work before application crash</translation>
<source>TOP_DEL_GROUP</source> <source>TOP_DEL_GROUP</source>
<translation>Delete Groups</translation> <translation>Delete Groups</translation>
</message> </message>
<message>
<source>TOP_FACE_ORIENTATION</source>
<translation>Orientation of faces</translation>
</message>
<message> <message>
<source>TOP_DISABLE_AUTO_COLOR</source> <source>TOP_DISABLE_AUTO_COLOR</source>
<translation>Disable auto color</translation> <translation>Disable auto color</translation>
@ -2796,6 +2808,18 @@ Please, create VTK viewer and try again</translation>
<source>PREF_COLOR</source> <source>PREF_COLOR</source>
<translation>Color</translation> <translation>Color</translation>
</message> </message>
<message>
<source>PREF_ORIENTATION_COLOR</source>
<translation>Color</translation>
</message>
<message>
<source>PREF_ORIENTATION_3D_VECTORS</source>
<translation>3D vectors</translation>
</message>
<message>
<source>PREF_ORIENTATION_SCALE</source>
<translation>Scale</translation>
</message>
<message> <message>
<source>PREF_DISPLAY_ENTITY</source> <source>PREF_DISPLAY_ENTITY</source>
<translation>Display entity</translation> <translation>Display entity</translation>
@ -2828,6 +2852,10 @@ Please, create VTK viewer and try again</translation>
<source>PREF_GROUP_EXPORT</source> <source>PREF_GROUP_EXPORT</source>
<translation>Mesh export</translation> <translation>Mesh export</translation>
</message> </message>
<message>
<source>PREF_GROUP_FACES_ORIENTATION</source>
<translation>Orientation of faces</translation>
</message>
<message> <message>
<source>PREF_GROUP_COMPUTE</source> <source>PREF_GROUP_COMPUTE</source>
<translation>Mesh computation</translation> <translation>Mesh computation</translation>