vec = geompy.MakeVectorDXDYDZ( 1, 1, 1 )
+# ============
+# Reorient2D()
+# ============
+
# Each of arguments of Reorient2D() function can be of different types:
#
# 2DObject - the whole mesh
# FaceOrPoint - a SMESH.PointStruct structure
mesh.Reorient2D( localAlgo.GetSubMesh().GetIDs(), [10,1,0], SMESH.PointStruct(0,0,0))
+# ========================
+# Reorient2DByNeighbours()
+# ========================
+
+# Use faces of 'group' as a reference to reorient equally all faces
+mesh.Reorient2DByNeighbours([mesh], [group])
+
+# Orient equally face on 'group', but not define which orientation is correct
+mesh.Reorient2DByNeighbours([group])
+
+# =================
+# Reorient2DBy3D()
+# =================
# Use Reorient2DBy3D() to orient faces of 2 geom faces to have their normal pointing inside volumes
Mesh.Reorient
Mesh.ReorientObject
Mesh.Reorient2D
+ Mesh.Reorient2DByNeighbours
Mesh.Reorient2DBy3D
Uniting triangles
************
This operation allows fixing the orientation of a set of faces in the following ways:
-
+
* The required orientation of a set of neighboring faces can be defined by a vector giving the direction of a normal to a certain face. Since the direction of face normals in the set can be even opposite, it is necessary to specify a *control* face, the normal to which will be compared with the vector. This face can be either:
* found by proximity to a given point, or
* specified explicitly.
+* The required orientation is given by faces of specified reference groups or/and sub-meshes. The reference groups can be omitted, then orientation of an arbitrary selected face to orient defines common orientation.
* Alternatively, the faces can be oriented relatively to the adjacent volumes.
The orientation of a face is changed by reverting the order of its nodes.
*To set orientation of faces:*
-.. |img| image:: ../images/reorient_faces_face.png
+.. |imgfac| image:: ../images/reorient_faces_face.png
+.. |imgpnt| image:: ../images/reorient_faces_point.png
+.. |imggrp| image:: ../images/reorient_faces_ref_groups.png
+.. |imgvol| image:: ../images/reorient_faces_volume.png
-#. In the **Modification** menu select **Reorient faces** item or click *"Reorient faces"* button |img| in the toolbar.
+#. In the **Modification** menu select **Reorient faces** item or click *"Reorient faces"* button |imgfac| in the toolbar.
#. In the "Reorient faces" dialog box
- * Select the **Object** (mesh, sub-mesh or group) containing faces to reorient, in the Object Browser or in the 3D Viewer.
+ * Select a way to define orientation:
+
+ * |imgpnt| - by specifying a point and a vector
+ * |imgfac| - by specifying a face and a vector
+ * |imggrp| - by specifying reference face groups
+ * |imgvol| - by specifying reference volume groups
+
+ * Select the **Object(s)** (mesh, groups and/or sub-meshes) containing faces to reorient, in the Object Browser or in the 3D Viewer.
* To reorient by direction of the face normal:
* Specify the coordinates of the **Point** by which the control face will be found. You can specify the **Point** by picking a node in the 3D Viewer or selecting a vertex in the Object Browser.
.. centered::
The orientation of adjacent faces is chosen according to a vector. The control face is found by point.
- * In the second mode it is possible to pick the **Face** by mouse in the 3D Viewer or directly input the **Face** ID in the corresponding field.
+ * In the second mode it is possible to pick the **Face** by mouse in the 3D Viewer or directly enter the **Face** ID in the corresponding field.
.. image:: ../images/reorient_2d_face.png
:align: center
The orientation of adjacent faces is chosen according to a vector. The control face is explicitly given.
- * In the third mode, the faces can be reoriented according to volumes:
+ * In the third mode, the faces can be reoriented equally to reference faces:
+
+ * If necessary, select 2D **Reference objects** (groups or/and sub-meshes) containing the reference faces, in the Object Browser or in the 3D Viewer. This field can be left empty, then orientation of an arbitrary face will be used as a reference.
+
+
+ .. image:: ../images/reorient_2d_refgroup.png
+ :align: center
+
+ .. centered::
+ The orientation of faces is given by reference face groups and/or sub-meshes.
+
+ * In the fourth mode, the faces can be reoriented according to volumes:
* Select an object (mesh, sub-mesh or group) containing reference **Volumes**, in the Object Browser or in the 3D Viewer.
* Specify whether face normals should point outside or inside the reference volumes using **Face normal outside volume** check-box.
- .. image:: ../images/reorient_2d_volume.png
- :align: center
+ .. image:: ../images/reorient_2d_volume.png
+ :align: center
- .. centered::
- The orientation of faces is chosen relatively to adjacent volumes.
+ .. centered::
+ The orientation of faces is chosen relatively to adjacent volumes.
#. Click the **Apply** or **Apply and Close** button to confirm the operation.
in DirStruct theDirection,
in long theFace,
in PointStruct thePoint) raises (SALOME::SALOME_Exception);
+ /*!
+ * \brief Reorient faces contained in a list of \a objectFaces
+ * equally to faces contained in a list of \a referenceFaces.
+ * \param objectFaces - faces to reorient in a list including either
+ * the whole mesh or groups and/or sub-meshes.
+ * \param referenceFaces - correctly oriented faces in a list of groups and/or sub-meshes.
+ * It can be empty, then the 1st face in \a objectFaces is used as the reference.
+ * \return number of reoriented faces.
+ */
+ long Reorient2DByNeighbours(in SMESH::ListOfIDSources objectFaces,
+ in SMESH::ListOfIDSources referenceFaces)
+ raises (SALOME::SALOME_Exception);
+
/*!
* \brief Reorient faces basing on orientation of adjacent volumes.
* \param faces - a list of objects containing face to reorient
* is still performed; theMaxAngle is measured in radians.
* \return \c true in case of success, FALSE otherwise.
*/
+
boolean TriToQuad (in smIdType_array IDsOfElements,
in NumericalFunctor Criterion,
in double MaxAngle) raises (SALOME::SALOME_Exception);
pattern_sample_3D.png
reorient_faces_face.png
reorient_faces_point.png
+ reorient_faces_ref_groups.png
reorient_faces_volume.png
scale.png
scale_along_axes.png
return vtkID + 1;
}
+//================================================================================
+/*!
+ * \brief Clear marked flag of all elements
+ */
+//================================================================================
+
+void SMDS_ElementFactory::SetAllNotMarked()
+{
+ for ( SMDS_ElementChunk& chunk : myChunks )
+ chunk.SetAllNotMarked();
+}
+
//================================================================================
/*!
* \brief Mark the element as non-used
myMarkedSet[ Index( e )] = is;
}
+//================================================================================
+/*!
+ * \brief Clear marked flag of all elements
+ */
+//================================================================================
+
+void SMDS_ElementChunk::SetAllNotMarked()
+{
+ clearVector( myMarkedSet );
+}
+
//================================================================================
/*!
* \brief Return SMDS_Position of a node on a shape
boost::shared_ptr< ElemIterator > GetShapeIterator( int shapeID,
size_t nbElemsToReturn,
const SMDS_MeshElement* sm1stElem );
+ //! Clear marked flag of all elements
+ void SetAllNotMarked();
//! Mark the element as non-used
void Free( const SMDS_MeshElement* );
bool IsMarked ( const SMDS_MeshElement* e ) const;
void SetIsMarked( const SMDS_MeshElement* e, bool is );
+ void SetAllNotMarked();
SMDS_PositionPtr GetPosition( const SMDS_MeshNode* n ) const;
void SetPosition( const SMDS_MeshNode* n, const SMDS_PositionPtr& pos, int shapeID );
return found;
}
+//=======================================================================
+//function : SetAllNodesNotMarked
+//purpose : Clear marked flag of all nodes
+//=======================================================================
+
+void SMDS_Mesh::SetAllNodesNotMarked()
+{
+ myNodeFactory->SetAllNotMarked();
+}
+
+//=======================================================================
+//function : SetAllCellsNotMarked
+//purpose : Clear marked flag of all cells
+//=======================================================================
+
+void SMDS_Mesh::SetAllCellsNotMarked()
+{
+ myCellFactory->SetAllNotMarked();
+}
+
//=======================================================================
//function : ChangePolyhedronNodes
//purpose :
const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities);
+ void SetAllNodesNotMarked();
+ void SetAllCellsNotMarked();
+
//virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
// Renumber all nodes or elements.
/*!
* \brief Reorient faces.
* \param theFaces - the faces to reorient. If empty the whole mesh is meant
- * \param theDirection - desired direction of normal of \a theFace
- * \param theFace - one of \a theFaces that should be oriented according to
- * \a theDirection and whose orientation defines orientation of other faces
+ * \param theDirection - desired direction of normal of \a theRefFaces.
+ * It can be (0,0,0) in order to keep orientation of \a theRefFaces.
+ * \param theRefFaces - correctly oriented faces whose orientation defines
+ * orientation of other faces.
* \return number of reoriented faces.
*/
//================================================================================
-int SMESH_MeshEditor::Reorient2D (TIDSortedElemSet & theFaces,
- const gp_Dir& theDirection,
- const SMDS_MeshElement * theFace)
+int SMESH_MeshEditor::Reorient2D( TIDSortedElemSet & theFaces,
+ const gp_Vec& theDirection,
+ TIDSortedElemSet & theRefFaces,
+ bool theAllowNonManifold )
{
int nbReori = 0;
- if ( !theFace || theFace->GetType() != SMDSAbs_Face ) return nbReori;
if ( theFaces.empty() )
{
- SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator(/*idInceasingOrder=true*/);
+ SMDS_FaceIteratorPtr fIt = GetMeshDS()->facesIterator();
while ( fIt->more() )
theFaces.insert( theFaces.end(), fIt->next() );
+
+ if ( theFaces.empty() )
+ return nbReori;
}
- // orient theFace according to theDirection
- gp_XYZ normal;
- SMESH_MeshAlgos::FaceNormal( theFace, normal, /*normalized=*/false );
- if ( normal * theDirection.XYZ() < 0 )
- nbReori += Reorient( theFace );
+ // orient theRefFaces according to theDirection
+ if ( theDirection.X() != 0 || theDirection.Y() != 0 || theDirection.Z() != 0 )
+ for ( const SMDS_MeshElement* refFace : theRefFaces )
+ {
+ gp_XYZ normal;
+ SMESH_MeshAlgos::FaceNormal( refFace, normal, /*normalized=*/false );
+ if ( normal * theDirection.XYZ() < 0 )
+ nbReori += Reorient( refFace );
+ }
- // Orient other faces
+ // mark reference faces
+ GetMeshDS()->SetAllCellsNotMarked();
+ for ( const SMDS_MeshElement* refFace : theRefFaces )
+ refFace->setIsMarked( true );
- set< const SMDS_MeshElement* > startFaces, visitedFaces;
- TIDSortedElemSet avoidSet;
- set< SMESH_TLink > checkedLinks;
- pair< set< SMESH_TLink >::iterator, bool > linkIt_isNew;
+ // erase reference faces from theFaces
+ for ( TIDSortedElemSet::iterator fIt = theFaces.begin(); fIt != theFaces.end(); )
+ if ( (*fIt)->isMarked() )
+ fIt = theFaces.erase( fIt );
+ else
+ ++fIt;
+
+ if ( theRefFaces.empty() )
+ {
+ theRefFaces.insert( *theFaces.begin() );
+ theFaces.erase( theFaces.begin() );
+ }
+
+ // Orient theFaces
- if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces
- theFaces.erase( theFace );
- startFaces.insert( theFace );
+ // if ( theFaces.size() > 1 )// leave 1 face to prevent finding not selected faces
+ // theFaces.erase( theFace );
int nodeInd1, nodeInd2;
- const SMDS_MeshElement* otherFace;
+ const SMDS_MeshElement* refFace, *otherFace;
vector< const SMDS_MeshElement* > facesNearLink;
vector< std::pair< int, int > > nodeIndsOfFace;
+ TIDSortedElemSet avoidSet, emptySet;
+ NCollection_Map< SMESH_TLink, SMESH_TLink > checkedLinks;
- set< const SMDS_MeshElement* >::iterator startFace = startFaces.begin();
- while ( !startFaces.empty() )
+ while ( !theRefFaces.empty() )
{
- startFace = startFaces.begin();
- theFace = *startFace;
- startFaces.erase( startFace );
- if ( !visitedFaces.insert( theFace ).second )
- continue;
+ auto refFaceIt = theRefFaces.begin();
+ refFace = *refFaceIt;
+ theRefFaces.erase( refFaceIt );
avoidSet.clear();
- avoidSet.insert(theFace);
+ avoidSet.insert( refFace );
- NLink link( theFace->GetNode( 0 ), (SMDS_MeshNode *) 0 );
+ NLink link( refFace->GetNode( 0 ), nullptr );
- const int nbNodes = theFace->NbCornerNodes();
- for ( int i = 0; i < nbNodes; ++i ) // loop on links of theFace
+ const int nbNodes = refFace->NbCornerNodes();
+ for ( int i = 0; i < nbNodes; ++i ) // loop on links of refFace
{
- link.second = theFace->GetNode(( i+1 ) % nbNodes );
- linkIt_isNew = checkedLinks.insert( link );
- if ( !linkIt_isNew.second )
+ link.second = refFace->GetNode(( i+1 ) % nbNodes );
+ bool isLinkVisited = checkedLinks.Contains( link );
+ if ( isLinkVisited )
{
// link has already been checked and won't be encountered more
// if the group (theFaces) is manifold
}
else
{
+ checkedLinks.Add( link );
+
facesNearLink.clear();
nodeIndsOfFace.clear();
+ TIDSortedElemSet::iterator objFaceIt = theFaces.end();
+
while (( otherFace = SMESH_MeshAlgos::FindFaceInSet( link.first, link.second,
- theFaces, avoidSet,
+ emptySet, avoidSet,
&nodeInd1, &nodeInd2 )))
- if ( otherFace != theFace)
+ {
+ if (( otherFace->isMarked() ) || // ref face
+ (( objFaceIt = theFaces.find( otherFace )) != theFaces.end() )) // object face
{
facesNearLink.push_back( otherFace );
nodeIndsOfFace.push_back( make_pair( nodeInd1, nodeInd2 ));
- avoidSet.insert( otherFace );
}
+ avoidSet.insert( otherFace );
+ }
if ( facesNearLink.size() > 1 )
{
// NON-MANIFOLD mesh shell !
- // select a face most co-directed with theFace,
+ if ( !theAllowNonManifold )
+ {
+ throw SALOME_Exception("Non-manifold topology of groups");
+ }
+ // select a face most co-directed with refFace,
// other faces won't be visited this time
gp_XYZ NF, NOF;
- SMESH_MeshAlgos::FaceNormal( theFace, NF, /*normalized=*/false );
+ SMESH_MeshAlgos::FaceNormal( refFace, NF, /*normalized=*/false );
double proj, maxProj = -1;
- for ( size_t i = 0; i < facesNearLink.size(); ++i ) {
+ for ( size_t i = 0; i < facesNearLink.size(); ++i )
+ {
SMESH_MeshAlgos::FaceNormal( facesNearLink[i], NOF, /*normalized=*/false );
- if (( proj = Abs( NF * NOF )) > maxProj ) {
+ if (( proj = Abs( NF * NOF )) > maxProj )
+ {
maxProj = proj;
otherFace = facesNearLink[i];
nodeInd1 = nodeIndsOfFace[i].first;
}
}
// not to visit rejected faces
- for ( size_t i = 0; i < facesNearLink.size(); ++i )
- if ( facesNearLink[i] != otherFace && theFaces.size() > 1 )
- visitedFaces.insert( facesNearLink[i] );
+ // for ( size_t i = 0; i < facesNearLink.size(); ++i )
+ // if ( facesNearLink[i] != otherFace && theFaces.size() > 1 )
+ // visitedFaces.insert( facesNearLink[i] );
}
else if ( facesNearLink.size() == 1 )
{
nodeInd1 = nodeIndsOfFace.back().first;
nodeInd2 = nodeIndsOfFace.back().second;
}
- if ( otherFace && otherFace != theFace)
+ if ( otherFace )
{
- // link must be reverse in otherFace if orientation to otherFace
- // is same as that of theFace
- if ( abs(nodeInd2-nodeInd1) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 )
+ // link must be reverse in otherFace if orientation of otherFace
+ // is same as that of refFace
+ if ( abs( nodeInd2 - nodeInd1 ) == 1 ? nodeInd2 > nodeInd1 : nodeInd1 > nodeInd2 )
{
+ if ( otherFace->isMarked() )
+ throw SALOME_Exception("Different orientation of reference faces");
nbReori += Reorient( otherFace );
}
- startFaces.insert( otherFace );
+ if ( !otherFace->isMarked() )
+ {
+ theRefFaces.insert( otherFace );
+ if ( objFaceIt != theFaces.end() )
+ theFaces.erase( objFaceIt );
+ }
}
}
- std::swap( link.first, link.second ); // reverse the link
+ link.first = link.second; // reverse the link
+
+ } // loop on links of refFace
+
+ if ( theRefFaces.empty() && !theFaces.empty() )
+ {
+ theRefFaces.insert( *theFaces.begin() );
+ theFaces.erase( theFaces.begin() );
}
- }
+
+ } // while ( !theRefFaces.empty() )
+
return nbReori;
}
bool Reorient (const SMDS_MeshElement * theElement);
// Reverse theElement orientation
- int Reorient2D (TIDSortedElemSet & theFaces,
- const gp_Dir& theDirection,
- const SMDS_MeshElement * theFace);
- // Reverse theFaces whose orientation to be same as that of theFace
- // oriented according to theDirection. Return nb of reoriented faces
+ int Reorient2D (TIDSortedElemSet & theFaces,
+ const gp_Vec& theDirection,
+ TIDSortedElemSet & theRefFaces,
+ bool theAllowNonManifold);
+ // Reverse theFaces whose orientation to be same as that of theRefFaces
+ // optionally oriented according to theDirection. Return nb of reoriented faces
int Reorient2DBy3D (TIDSortedElemSet & theFaces,
TIDSortedElemSet & theVolumes,
IDSOURCE,
IDSOURCE_EDGE, // IDSource including edges
IDSOURCE_FACE,
- IDSOURCE_VOLUME
+ IDSOURCE_VOLUME,
+ NB_SMESH_TYPES
};
}
#endif
#include <vtkProperty.h>
// IDL includes
-#include <SALOMEconfig.h>
-#include CORBA_SERVER_HEADER(SMESH_Mesh)
#include CORBA_SERVER_HEADER(SMESH_MeshEditor)
// std
#define SPACING 6
#define MARGIN 11
-enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_VOLUME,
- EObject, EPoint, EFace, EDirection, EVolumes };
+enum { CONSTRUCTOR_POINT=0, CONSTRUCTOR_FACE, CONSTRUCTOR_FACE_GROUPS, CONSTRUCTOR_VOLUME,
+ EObject, EPoint, EFace, EDirection, ERefGroups };
//=======================================================================
/*!
QPixmap iconReoriPoint (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_POINT")));
QPixmap iconReoriFace (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_FACE")));
+ QPixmap iconReoriGroups(resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_GROUPS")));
QPixmap iconReoriVolum (resMgr()->loadPixmap("SMESH", tr("ICON_DLG_REORIENT2D_VOLUME")));
QGroupBox* aConstructorBox = new QGroupBox(tr("REORIENT_FACES"), aFrame);
aConstructorGrpLayout->addWidget(aFaceBut);
myConstructorGrp->addButton(aFaceBut, CONSTRUCTOR_FACE);
+ QRadioButton* aGroupBut= new QRadioButton(aConstructorBox);
+ aGroupBut->setIcon(iconReoriGroups);
+ aConstructorGrpLayout->addWidget(aGroupBut);
+ myConstructorGrp->addButton(aGroupBut, CONSTRUCTOR_FACE_GROUPS);
+
QRadioButton* aVolBut= new QRadioButton(aConstructorBox);
aVolBut->setIcon(iconReoriVolum);
aConstructorGrpLayout->addWidget(aVolBut);
createObject( tr("POINT") , aFrame, EPoint );
createObject( tr("FACE") , aFrame, EFace );
createObject( tr("DIRECTION"), aFrame, EDirection );
- createObject( tr("VOLUMES"), aFrame, EVolumes );
- setNameIndication( EObject, OneName );
+ createObject( tr("VOLUMES"), aFrame, ERefGroups );
+ setNameIndication( EObject, ListOfNames );
setNameIndication( EFace, OneName );
+ setNameIndication( ERefGroups, ListOfNames );
setReadOnly( EFace, false );
if ( QLineEdit* le = qobject_cast<QLineEdit*>( objectWg( EFace, Control ) ))
le->setValidator( new SMESHGUI_IdValidator( this,1 ));
objectWg( EObject , Label )->setFixedWidth( width );
objectWg( EPoint , Label )->setFixedWidth( width );
objectWg( EFace , Label )->setFixedWidth( width );
- objectWg( EVolumes , Label )->setFixedWidth( width );
myOutsideChk = new QCheckBox( tr("OUTSIDE_VOLUME_NORMAL"), aFrame);
myOutsideChk->setChecked( true );
aFaceGrpLayout->addWidget( objectWg( EFace, Btn ) );
aFaceGrpLayout->addWidget( objectWg( EFace, Control ) );
- myVolumFrm = new QFrame(aFrame);
- QGridLayout* aVolumGrpLayout = new QGridLayout(myVolumFrm);
- aVolumGrpLayout->setMargin(0);
- aVolumGrpLayout->setSpacing(SPACING);
- aVolumGrpLayout->addWidget( objectWg( EVolumes, Label ), 0, 0 );
- aVolumGrpLayout->addWidget( objectWg( EVolumes, Btn ), 0, 1 );
- aVolumGrpLayout->addWidget( objectWg( EVolumes, Control ), 0, 2 );
- aVolumGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 );
+ myRefGroupFrm = new QFrame(aFrame);
+ QGridLayout* aRefGrpLayout = new QGridLayout(myRefGroupFrm);
+ aRefGrpLayout->setMargin(0);
+ aRefGrpLayout->setSpacing(SPACING);
+ aRefGrpLayout->addWidget( objectWg( ERefGroups, Label ), 0, 0 );
+ aRefGrpLayout->addWidget( objectWg( ERefGroups, Btn ), 0, 1 );
+ aRefGrpLayout->addWidget( objectWg( ERefGroups, Control ), 0, 2 );
+ aRefGrpLayout->addWidget( myOutsideChk, 1, 0, 1, 3 );
myDirFrm = new QFrame(aFrame);
QHBoxLayout* aDirectGrpLayout = new QHBoxLayout(myDirFrm);
QVBoxLayout* anOrientGrpLayout = new QVBoxLayout ( anOrientGrp );
anOrientGrpLayout->addWidget(myPointFrm);
anOrientGrpLayout->addWidget(myFaceFrm);
- anOrientGrpLayout->addWidget(myVolumFrm);
+ anOrientGrpLayout->addWidget(myRefGroupFrm);
anOrientGrpLayout->addWidget(myDirFrm);
if ( id == CONSTRUCTOR_FACE )
{
myPointFrm->hide();
- myVolumFrm->hide();
+ myRefGroupFrm->hide();
myFaceFrm->show();
myDirFrm->show();
activateObject( EFace );
else if ( id == CONSTRUCTOR_POINT )
{
myFaceFrm->hide();
- myVolumFrm->hide();
+ myRefGroupFrm->hide();
myPointFrm->show();
myDirFrm->show();
activateObject( EPoint );
}
- else // CONSTRUCTOR_VOLUME
+ else // CONSTRUCTOR_VOLUME || CONSTRUCTOR_FACE_GROUPS
{
myFaceFrm->hide();
myPointFrm->hide();
myDirFrm->hide();
- myVolumFrm->show();
- activateObject( EVolumes );
+ myOutsideChk->setVisible( id == CONSTRUCTOR_VOLUME );
+ myRefGroupFrm->show();
+ QAbstractButton* refButton = qobject_cast<QAbstractButton*>( objectWg( ERefGroups, Btn ));
+ refButton->setChecked( false ); // force ERefGroups activation
+ activateObject( ERefGroups );
+ setLabel( ERefGroups, id == CONSTRUCTOR_VOLUME ? "VOLUMES" : "REF_GROUPS" );
+ }
+
+ // minimize width of labels
+ QFontMetrics font = objectWg( EDirection, Label )->fontMetrics();
+ int width = 0;
+ for ( int obj = EObject; obj <= ERefGroups; ++obj )
+ {
+ QLabel* label = qobject_cast< QLabel* >( objectWg( obj, Label ));
+ if ( label->isVisible() )
+ width = std::max( width, font.width( label->text() ));
}
+
+ for ( int obj = EObject; obj <= ERefGroups; ++obj )
+ {
+ QWidget* label = objectWg( obj, Label );
+ if ( label->isVisible() )
+ label->setFixedWidth( width );
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Set object label
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesDlg::setLabel( int object, const char* text )
+{
+ qobject_cast< QLabel* >( objectWg( object, Label ))->setText( tr( text ));
}
//================================================================================
/*!
* \brief Constructor
-*/
+ */
//================================================================================
SMESHGUI_ReorientFacesOp::SMESHGUI_ReorientFacesOp()
myDlg = new SMESHGUI_ReorientFacesDlg;
myDlg->constructorChange( CONSTRUCTOR_POINT );
+ myRefGroupFilter = new SMESH_TypeFilter( SMESH::GROUP_VOLUME );
+ myRefSubMeshFilter = new SMESH_TypeFilter( SMESH::SUBMESH_SOLID );
+ myRefMeshFilter = new SMESH_TypeFilter( SMESH::MESH );
+
+ myObjects = new SMESH::ListOfIDSources();
+ myRefGroups = new SMESH::ListOfIDSources();
+
// connect signals and slots
connect( myDlg->objectWg( EFace, LightApp_Dialog::Control ), SIGNAL(textChanged(const QString&)),
this, SLOT(onTextChange(const QString&)));
- // connect(myDlg->myX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
- // connect(myDlg->myY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
- // connect(myDlg->myZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
- // connect(myDlg->myDX, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
- // connect(myDlg->myDY, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
- // connect(myDlg->myDZ, SIGNAL (valueChanged(double)), this, SLOT(redisplayPreview()));
-
}
//=======================================================================
{
myObjectActor = 0;
- // init simulation with a current View
- //if ( myVectorPreview ) delete myVectorPreview;
- // myVectorPreview = new SMESHGUI_MeshEditPreview(SMESH::GetViewWindow( getSMESHGUI() ));
- // vtkProperty* aProp = vtkProperty::New();
- // aProp->SetRepresentationToWireframe();
- // aProp->SetColor(250, 0, 250);
- // aProp->SetPointSize(5);
- // aProp->SetLineWidth( SMESH::GetFloat("SMESH:element_width",1) + 1);
- // myVectorPreview->GetActor()->SetProperty(aProp);
- // aProp->Delete();
-
SMESHGUI_SelectionOp::startOperation();
myDlg->show();
- mySelectionMode = 0;
+ mySelectionMode = EObject;
myDlg->activateObject( EObject );
+
+ selectionDone();
}
//================================================================================
void SMESHGUI_ReorientFacesOp::stopOperation()
{
- //myVectorPreview->SetVisibility(false);
- if ( myObjectActor ) {
+ if ( myObjectActor )
+ {
myObjectActor->SetPointRepresentation(false);
SMESH::RepaintCurrentView();
myObjectActor = 0;
void SMESHGUI_ReorientFacesOp::onActivateObject( int what )
{
if ( what == mySelectionMode )
- return;
- mySelectionMode = what;
- switch ( mySelectionMode )
{
- case EPoint:
- case EDirection:
- SMESH::SetPointRepresentation(true);
- setSelectionMode( NodeSelection );
- SMESH::SetPickable();
- break;
- case EObject:
- case EVolumes:
- SMESH::SetPointRepresentation(false);
- setSelectionMode( ActorSelection );
- break;
- case EFace:
- SMESH::SetPointRepresentation(false);
- setSelectionMode( FaceSelection );
- if ( myObjectActor )
- SMESH::SetPickable( myObjectActor );
- else
+ if ( what == ERefGroups )
+ setRefFiltersByConstructor();
+ }
+ else
+ {
+ mySelectionMode = what;
+ switch ( mySelectionMode )
+ {
+ case EPoint:
+ case EDirection:
+ SMESH::SetPointRepresentation(true);
+ setSelectionMode( NodeSelection );
SMESH::SetPickable();
- break;
+ break;
+ case EObject:
+ SMESH::SetPointRepresentation(false);
+ setSelectionMode( ActorSelection );
+ break;
+ case ERefGroups:
+ SMESH::SetPointRepresentation(false);
+ setSelectionMode( ActorSelection );
+ setRefFiltersByConstructor();
+ break;
+ case EFace:
+ SMESH::SetPointRepresentation(false);
+ setSelectionMode( FaceSelection );
+ if ( myObjectActor )
+ SMESH::SetPickable( myObjectActor );
+ else
+ SMESH::SetPickable();
+ break;
+ }
}
SMESHGUI_SelectionOp::onActivateObject( what );
+
+ myDlg->setLabel( EObject, onlyOneObjAllowed() ? "OBJECT" : "OBJECTS" );
}
//================================================================================
filters.append( new SMESH_TypeFilter( SMESH::GROUP_FACE ));
return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
}
- case EVolumes:
+ case ERefGroups:
{
QList<SUIT_SelectionFilter*> filters;
- filters.append( new SMESH_TypeFilter( SMESH::MESH ));
- filters.append( new SMESH_TypeFilter( SMESH::SUBMESH_SOLID ));
- filters.append( new SMESH_TypeFilter( SMESH::GROUP_VOLUME ));
+ filters << myRefGroupFilter << myRefSubMeshFilter << myRefMeshFilter;
return new SMESH_LogicalFilter( filters, SMESH_LogicalFilter::LO_OR );
}
case EPoint:
return NULL;
}
+//================================================================================
+/*!
+ * \brief Switch between selection of faces and volumes according to the constructor
+ */
+//================================================================================
+
+void SMESHGUI_ReorientFacesOp::setRefFiltersByConstructor()
+{
+ if ( constructorID() == CONSTRUCTOR_VOLUME )
+ {
+ myRefMeshFilter ->setType( SMESH::MESH );// SMESH::NB_SMESH_TYPES
+ myRefGroupFilter ->setType( SMESH::GROUP_VOLUME );
+ myRefSubMeshFilter->setType( SMESH::SUBMESH_SOLID );
+ }
+ else
+ {
+ myRefMeshFilter ->setType( SMESH::NB_SMESH_TYPES ); // mesh not allowed
+ myRefGroupFilter ->setType( SMESH::GROUP_FACE );
+ myRefSubMeshFilter->setType( SMESH::SUBMESH_FACE );
+ }
+}
+
//================================================================================
/*!
* \brief get data from selection
if ( !myDlg->isVisible() || !myDlg->isEnabled() )
return;
- if ( mySelectionMode == EVolumes )
- {
- SMESHGUI_SelectionOp::selectionDone();
- return;
- }
-
myDlg->clearSelection( mySelectionMode );
SALOME_ListIO aList;
if ( nbSelected == 0 )
return;
+ if ( onlyOneObjAllowed() && nbSelected != 1 )
+ return;
+
+ if ( mySelectionMode == ERefGroups )
+ {
+ SMESHGUI_SelectionOp::selectionDone();
+ return;
+ }
+
Handle(SALOME_InteractiveObject) anIO = aList.First();
try
{
case EObject: { // get an actor of object
- if ( nbSelected == 1 )
- {
- myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
- // typeById( aList.First()->getEntry(),
- // SMESHGUI_SelectionOp::Object ),
- myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
- }
+ SMESHGUI_SelectionOp::selectionDone();
+ myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
break;
}
case EFace: { // get a face ID
- if ( nbSelected == 1 )
+ SVTK_TIndexedMapOfVtkId faceIndices;
+ selector()->GetIndex( anIO, faceIndices );
+ if ( faceIndices.Extent() == 1 )
{
- SVTK_TIndexedMapOfVtkId faceIndices;
- selector()->GetIndex( anIO, faceIndices );
- if ( faceIndices.Extent() == 1 )
- {
- SMESH_Actor* savedActor = myObjectActor;
- myObjectActor = 0; // to prevent work of onTextChange()
- myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) ));
- myObjectActor = savedActor;
+ SMESH_Actor* savedActor = myObjectActor;
+ myObjectActor = 0; // to prevent work of onTextChange()
+ myDlg->setObjectText( EFace, QString("%1").arg( faceIndices(1) ));
+ myObjectActor = savedActor;
- if ( !myObjectActor )
- {
- myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
- // typeById( aList.First()->getEntry(),
- // SMESHGUI_SelectionOp::Object ),
- myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
- }
+ if ( !myObjectActor )
+ {
+ myDlg->selectObject( EObject, anIO->getName(), 0, anIO->getEntry(), true );
+ // typeById( aList.First()->getEntry(),
+ // SMESHGUI_SelectionOp::Object ),
+ myObjectActor = SMESH::FindActorByEntry( anIO->getEntry() );
}
}
break;
case EPoint:
case EDirection: { // set XYZ by selected nodes or vertices
- if ( mySelectionMode == EPoint && aList.Extent() > 1 )
- return;
-
TColgp_SequenceOfXYZ points;
for( SALOME_ListIteratorOfListIO anIt( aList ); anIt.More(); anIt.Next() )
{
try {
SUIT_OverrideCursor wc;
- SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh();
+ SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh();
if ( aMesh->_is_nil() ) return false;
SMESH::SMESH_MeshEditor_var aMeshEditor = aMesh->GetMeshEditor();
if (aMeshEditor->_is_nil()) return false;
int aResult = 0;
- if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME )
+ switch ( constructorID() )
+ {
+ case CONSTRUCTOR_VOLUME:
{
- SMESH::ListOfIDSources_var faceGroups = new SMESH::ListOfIDSources;
- faceGroups->length(1);
- faceGroups[0] = myObject;
-
bool outsideNormal = myDlg->myOutsideChk->isChecked();
- aResult = aMeshEditor->Reorient2DBy3D( faceGroups, myVolumeObj, outsideNormal );
+ aResult = aMeshEditor->Reorient2DBy3D( myObjects, myRefGroups[0], outsideNormal );
+
+ break;
+ }
+ case CONSTRUCTOR_FACE_GROUPS:
+ {
+ aResult = aMeshEditor->Reorient2DByNeighbours( myObjects, myRefGroups );
+
+ break;
}
- else
+ default:
{
SMESH::DirStruct direction;
direction.PS.x = myDlg->myDX->GetValue();
direction.PS.z = myDlg->myDZ->GetValue();
long face = myDlg->objectText( EFace ).toInt();
- if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_POINT )
+ if ( constructorID() == CONSTRUCTOR_POINT )
face = -1;
SMESH::PointStruct point;
aMesh->SetParameters( aParameters.join(":").toUtf8().constData() );
- aResult = aMeshEditor->Reorient2D( myObject, direction, face, point );
+ aResult = aMeshEditor->Reorient2D( myObjects[0], direction, face, point );
+ }
}
if (aResult)
bool SMESHGUI_ReorientFacesOp::isValid( QString& msg )
{
- // check object
- QString objectEntry = myDlg->selectedObject( EObject );
- _PTR(SObject) pSObject = SMESH::getStudy()->FindObjectID( objectEntry.toUtf8().data() );
- myObject = SMESH::SMESH_IDSource::_narrow( _CAST( SObject,pSObject )->GetObject() );
- if ( myObject->_is_nil() )
+ // Check objects
+
+ QStringList objectEntries;
+ myDlg->selectedObject( EObject, objectEntries );
+ if ( objectEntries.size() == 0 )
{
msg = tr("NO_OBJECT_SELECTED");
return false;
}
- bool hasFaces = false;
- SMESH::array_of_ElementType_var types = myObject->GetTypes();
- for ( size_t i = 0; i < types->length() && !hasFaces; ++i )
- hasFaces = ( types[i] == SMESH::FACE );
- if ( !hasFaces )
+ myObjects->length( objectEntries.size() );
+ int nbObj = 0;
+ for ( QString & entry : objectEntries )
+ {
+ SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry );
+ if ( !obj->_is_nil() )
+ {
+ bool hasFaces = false;
+ SMESH::array_of_ElementType_var types = obj->GetTypes();
+ for ( size_t i = 0; i < types->length() && !hasFaces; ++i )
+ hasFaces = ( types[i] == SMESH::FACE );
+ if ( hasFaces )
+ myObjects[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj );
+ }
+ }
+ if ( nbObj == 0 )
{
msg = tr("NO_FACES");
return false;
}
+ myObjects->length( nbObj );
+
+ // Check volume object or ref faces
- // check volume object
- if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_VOLUME )
+ int constructorType = constructorID();
+ if ( constructorType >= CONSTRUCTOR_FACE_GROUPS )
{
- objectEntry = myDlg->selectedObject( EVolumes );
- _PTR(SObject) pSObject = SMESH::getStudy()->FindObjectID( objectEntry.toUtf8().data() );
- myVolumeObj = SMESH::SObjectToInterface< SMESH::SMESH_IDSource>( pSObject );
- if ( myVolumeObj->_is_nil() )
+ objectEntries.clear();
+ myDlg->selectedObject( ERefGroups, objectEntries );
+ myRefGroups->length( objectEntries.size() );
+ nbObj = 0;
+ for ( QString & entry : objectEntries )
{
- msg = tr("NO_VOLUME_OBJECT_SELECTED");
- return false;
+ SMESH::SMESH_IDSource_var obj = SMESH::EntryToInterface< SMESH::SMESH_IDSource >( entry );
+ if ( !obj->_is_nil() )
+ {
+ bool hasElems = false;
+ SMESH::ElementType elemType =
+ ( constructorType == CONSTRUCTOR_VOLUME ? SMESH::VOLUME : SMESH::FACE );
+ SMESH::array_of_ElementType_var types = obj->GetTypes();
+ for ( size_t i = 0; i < types->length() && !hasElems; ++i )
+ hasElems = ( types[i] == elemType );
+ if ( hasElems )
+ myRefGroups[ nbObj++ ] = SMESH::SMESH_IDSource::_duplicate( obj );
+ }
}
- bool hasVolumes = false;
- types = myVolumeObj->GetTypes();
- for ( size_t i = 0; i < types->length() && !hasVolumes; ++i )
- hasVolumes = ( types[i] == SMESH::VOLUME );
- if ( !hasVolumes )
+ if ( nbObj == 0 && constructorType == CONSTRUCTOR_VOLUME )
{
msg = tr("NO_VOLUMES");
return false;
}
+ myRefGroups->length( nbObj );
}
- // check vector
+
+ // Check vector
+
gp_Vec vec( myDlg->myDX->GetValue(),
myDlg->myDY->GetValue(),
myDlg->myDZ->GetValue() );
return false;
}
- // check face ID
- if ( myDlg->myConstructorGrp->checkedId() == CONSTRUCTOR_FACE )
+ // Check face ID
+
+ if ( constructorID() == CONSTRUCTOR_FACE )
{
int faceID = myDlg->objectText( EFace ).toInt();
bool faceOK = ( faceID > 0 );
}
else
{
- SMESH::SMESH_Mesh_var aMesh = myObject->GetMesh();
- if ( !aMesh->_is_nil() )
+ SMESH::SMESH_Mesh_var aMesh = myObjects[0]->GetMesh();
+ if ( !aMesh->_is_nil() )
faceOK = ( aMesh->GetElementType( faceID, true ) == SMESH::FACE );
}
}
//================================================================================
/*!
* \brief Destructor
-*/
+ */
//================================================================================
SMESHGUI_ReorientFacesOp::~SMESHGUI_ReorientFacesOp()
return myDlg;
}
+//================================================================================
+/*!
+ * \brief ID of a current constructor: CONSTRUCTOR_FACE, CONSTRUCTOR_POINT etc.
+ */
+//================================================================================
+
+int SMESHGUI_ReorientFacesOp::constructorID()
+{
+ return myDlg->myConstructorGrp->checkedId();
+}
+
+//================================================================================
+/*!
+ * \brief Check if selection of multiple objects allowed
+ */
+//================================================================================
+
+bool SMESHGUI_ReorientFacesOp::onlyOneObjAllowed()
+{
+ return (( constructorID() <= CONSTRUCTOR_FACE ) ||
+ ( constructorID() == CONSTRUCTOR_VOLUME && mySelectionMode == ERefGroups ));
+}
+
//================================================================================
/*!
* \brief update preview
void SMESHGUI_ReorientFacesOp::redisplayPreview()
{
-// SMESH::MeshPreviewStruct_var aMeshPreviewStruct;
-
-// bool moveShown = false;
-// if ( myObjectActor)
-// {
-// const bool autoSearch = myDlg->myAutoSearchChkBox->isChecked();
-// const bool preview = myDlg->myPreviewChkBox->isChecked();
-// if ( autoSearch )
-// {
-// myDlg->myCurrentX->SetValue(0);
-// myDlg->myCurrentY->SetValue(0);
-// myDlg->myCurrentZ->SetValue(0);
-// myDlg->myDX->SetValue(0);
-// myDlg->myDY->SetValue(0);
-// myDlg->myDZ->SetValue(0);
-// myDlg->myId->setText("");
-// }
-// QString msg;
-// if ( autoSearch || isValid( msg ) )
-// {
-// try {
-// SMESH::SMESH_Mesh_var aMesh = SMESH::GetMeshByIO(myObjectActor->getIO());
-// if (!aMesh->_is_nil()) {
-// SMESH::SMESH_MeshEditor_var aPreviewer = aMesh->GetMeshEditPreviewer();
-// if (!aPreviewer->_is_nil())
-// {
-// SUIT_OverrideCursor aWaitCursor;
-
-// int anId = 0;
-// if ( autoSearch )
-// anId = aPreviewer->FindNodeClosestTo(myDlg->myX->GetValue(),
-// myDlg->myY->GetValue(),
-// myDlg->myZ->GetValue());
-// else
-// anId = myDlg->myId->text().toInt();
-
-// // find id and/or just compute preview
-// aPreviewer->MoveNode(anId,
-// myDlg->myX->GetValue(),
-// myDlg->myY->GetValue(),
-// myDlg->myZ->GetValue());
-// if ( autoSearch ) { // set found id
-// QString idTxt("%1");
-// if ( anId > 0 )
-// idTxt = idTxt.arg( anId );
-// else
-// idTxt = "";
-// myDlg->myId->setText( idTxt );
-// }
-
-// SMESH::double_array* aXYZ = aMesh->GetNodeXYZ( anId );
-// if( aXYZ && aXYZ->length() >= 3 )
-// {
-// double x = aXYZ->operator[](0);
-// double y = aXYZ->operator[](1);
-// double z = aXYZ->operator[](2);
-// double dx = myDlg->myX->GetValue() - x;
-// double dy = myDlg->myY->GetValue() - y;
-// double dz = myDlg->myZ->GetValue() - z;
-// myDlg->myCurrentX->SetValue(x);
-// myDlg->myCurrentY->SetValue(y);
-// myDlg->myCurrentZ->SetValue(z);
-// myDlg->myDX->SetValue(dx);
-// myDlg->myDY->SetValue(dy);
-// myDlg->myDZ->SetValue(dz);
-// }
-
-// if ( preview ) { // fill preview data
-// aMeshPreviewStruct = aPreviewer->GetPreviewData();
-// moveShown = ( anId > 0 );
-// }
-// }
-// }
-// }catch (...) {
-// }
-// }
-// }
-
-// if ( !moveShown )
-// {
-// aMeshPreviewStruct = new SMESH::MeshPreviewStruct();
-
-// aMeshPreviewStruct->nodesXYZ.length(1);
-// aMeshPreviewStruct->nodesXYZ[0].x = myDlg->myX->GetValue();
-// aMeshPreviewStruct->nodesXYZ[0].y = myDlg->myY->GetValue();
-// aMeshPreviewStruct->nodesXYZ[0].z = myDlg->myZ->GetValue();
-
-// aMeshPreviewStruct->elementTypes.length(1);
-// aMeshPreviewStruct->elementTypes[0].SMDS_ElementType = SMESH::NODE;
-// aMeshPreviewStruct->elementTypes[0].isPoly = false;
-// aMeshPreviewStruct->elementTypes[0].nbNodesInElement = 1;
-
-// aMeshPreviewStruct->elementConnectivities.length(1);
-// aMeshPreviewStruct->elementConnectivities[0] = 0;
-// }
-
-// // display data
-// if ( & aMeshPreviewStruct.in() )
-// {
-// myVectorPreview->SetData(aMeshPreviewStruct.in());
-// }
-// else
-// {
-// myVectorPreview->SetVisibility(false);
-// }
-
}
#define SMESHGUI_ReorientFacesDlg_H
// SMESH includes
+
#include "SMESH_SMESHGUI.hxx"
#include "SMESHGUI_Dialog.h"
#include "SMESHGUI_SelectionOp.h"
+#include <SALOMEconfig.h>
+#include CORBA_SERVER_HEADER(SMESH_Mesh)
+
class QButtonGroup;
class QCheckBox;
class QLineEdit;
class SMESHGUI_SpinBox;
class SMESHGUI_ReorientFacesDlg;
+class SMESH_TypeFilter;
-/*!
+/*! ================================================================================
* \brief Operation to reorient faces according to some criterion
*/
+
class SMESHGUI_EXPORT SMESHGUI_ReorientFacesOp: public SMESHGUI_SelectionOp
{
Q_OBJECT
-public:
+ public:
SMESHGUI_ReorientFacesOp();
virtual ~SMESHGUI_ReorientFacesOp();
virtual LightApp_Dialog* dlg() const;
-protected:
+ protected:
virtual void startOperation();
virtual void stopOperation();
virtual void selectionDone();
bool isValid( QString& );
+ void setRefFiltersByConstructor();
+ int constructorID();
+
-protected slots:
+ protected slots:
virtual bool onApply();
-private slots:
+ private slots:
virtual void onActivateObject( int );
void redisplayPreview();
void onTextChange( const QString& );
+ bool onlyOneObjAllowed();
-private:
- SMESHGUI_ReorientFacesDlg* myDlg;
+ private:
+
+ SMESHGUI_ReorientFacesDlg* myDlg;
+
+ SMESH_Actor* myObjectActor;
+ int mySelectionMode;
- //SMESHGUI_MeshEditPreview* myVectorPreview;
- SMESH_Actor* myObjectActor;
- int mySelectionMode;
+ SMESH_TypeFilter* myRefGroupFilter;
+ SMESH_TypeFilter* myRefSubMeshFilter;
+ SMESH_TypeFilter* myRefMeshFilter;
- SMESH::SMESH_IDSource_var myObject;
- SMESH::SMESH_IDSource_var myVolumeObj;
+ SMESH::ListOfIDSources_var myObjects;
+ SMESH::ListOfIDSources_var myRefGroups;
};
-/*!
+/*! ================================================================================
* \brief Dialog to reorient faces according to vector
*/
{
Q_OBJECT
-public:
+ public:
SMESHGUI_ReorientFacesDlg();
public slots:
private:
QWidget* createMainFrame( QWidget* );
+ void setLabel( int object, const char* text );
QButtonGroup* myConstructorGrp;
QFrame* myFaceFrm;
QFrame* myPointFrm;
QFrame* myDirFrm;
- QFrame* myVolumFrm;
+ QFrame* myRefGroupFrm;
QCheckBox* myOutsideChk;
SMESHGUI_SpinBox* myX;
SMESHGUI_SpinBox* myY;
<source>ICON_DLG_REORIENT2D_FACE</source>
<translation>reorient_faces_face.png</translation>
</message>
+ <message>
+ <source>ICON_DLG_REORIENT2D_GROUPS</source>
+ <translation>reorient_faces_ref_groups.png</translation>
+ </message>
<message>
<source>ICON_DLG_REORIENT2D_VOLUME</source>
<translation>reorient_faces_volume.png</translation>
<source>OBJECT</source>
<translation>Object</translation>
</message>
+ <message>
+ <source>OBJECTS</source>
+ <translation>Objects</translation>
+ </message>
<message>
<source>POINT</source>
<translation>Point</translation>
<source>VOLUMES</source>
<translation>Volumes</translation>
</message>
+ <message>
+ <source>REF_GROUPS</source>
+ <translation>Ref. objects (optional)</translation>
+ </message>
<message>
<source>OUTSIDE_VOLUME_NORMAL</source>
<translation>Face normal outside volume</translation>
</message>
<message>
<source>TOP_REORIENT_2D</source>
- <translation>Réorienter des faces selon un vecteur</translation>
+ <translation>Réorienter des faces</translation>
</message>
<message>
<source>MEN_REORIENT_2D</source>
- <translation>Réorienter des faces selon un vecteur</translation>
+ <translation>Réorienter des faces</translation>
</message>
<message>
<source>STB_REORIENT_2D</source>
- <translation>Réorienter des faces selon un vecteur</translation>
+ <translation>Réorienter des faces</translation>
</message>
<message>
<source>TOP_FIND_ELEM</source>
<name>SMESHGUI_ReorientFacesDlg</name>
<message>
<source>CAPTION</source>
- <translation>Réorienter des faces selon un vector</translation>
+ <translation>Réorienter des faces</translation>
</message>
<message>
<source>REORIENT_FACES</source>
<source>OBJECT</source>
<translation>Objet</translation>
</message>
+ <message>
+ <source>OBJECTS</source>
+ <translation>Objets</translation>
+ </message>
<message>
<source>POINT</source>
<translation>Point</translation>
<source>VOLUMES</source>
<translation>Volumes</translation>
</message>
+ <message>
+ <source>REF_GROUPS</source>
+ <translation>Objets de référence (optionnel)</translation>
+ </message>
<message>
<source>OUTSIDE_VOLUME_NORMAL</source>
<translation>Normale de face en dehors du volume</translation>
"RemoveElements","RemoveNodes","RemoveOrphanNodes",
"AddNode","Add0DElement","AddEdge","AddFace","AddPolygonalFace","AddBall",
"AddVolume","AddPolyhedralVolume","AddPolyhedralVolumeByFaces",
- "MoveNode", "MoveClosestNodeToPoint",
- "InverseDiag","DeleteDiag","Reorient","ReorientObject","Reorient2DBy3D",
+ "MoveNode", "MoveClosestNodeToPoint","InverseDiag","DeleteDiag",
+ "Reorient","ReorientObject","Reorient2DBy3D","Reorient2DByNeighbours",
"TriToQuad","TriToQuadObject", "QuadTo4Tri", "SplitQuad","SplitQuadObject",
"BestSplit","Smooth","SmoothObject","SmoothParametric","SmoothParametricObject",
"ConvertToQuadratic","ConvertFromQuadratic","RenumberNodes","RenumberElements",
if ( dirVec.Magnitude() < std::numeric_limits< double >::min() )
THROW_SALOME_CORBA_EXCEPTION("Zero size vector", SALOME::BAD_PARAM);
- int nbReori = getEditor().Reorient2D( elements, dirVec, face );
+ TIDSortedElemSet refFaces = { face };
+ int nbReori = getEditor().Reorient2D( elements, dirVec, refFaces, /*allowNonManifold=*/true );
if ( nbReori ) {
declareMeshModified( /*isReComputeSafe=*/false );
return 0;
}
+//=======================================================================
+//function : Reorient2DByNeighbours
+//purpose : Reorient faces contained in a list of objectFaces
+// equally to faces contained in a list of referenceFaces.
+//=======================================================================
+
+CORBA::Long
+SMESH_MeshEditor_i::Reorient2DByNeighbours(const SMESH::ListOfIDSources& theObjectFaces,
+ const SMESH::ListOfIDSources& theReferenceFaces)
+{
+ SMESH_TRY;
+ initData(/*deleteSearchers=*/false);
+
+ if ( theObjectFaces.length() == 0 )
+ return 0;
+
+ // get object faces
+ TIDSortedElemSet objFaces;
+ bool invalidObjFaces = false;
+ for ( CORBA::ULong i = 0; i < theObjectFaces.length(); ++i )
+ {
+ IDSource_Error err;
+ if ( !idSourceToSet( theObjectFaces[i], getMeshDS(), objFaces, SMDSAbs_Face,
+ /*emptyIfIsMesh=*/1, &err ) &&
+ err == IDSource_INVALID )
+ invalidObjFaces = true;
+ }
+ if ( objFaces.empty() && invalidObjFaces )
+ THROW_SALOME_CORBA_EXCEPTION("No valid faces in given groups", SALOME::BAD_PARAM);
+
+ // get reference faces
+ TIDSortedElemSet refFaces;
+ for ( CORBA::ULong i = 0; i < theReferenceFaces.length(); ++i )
+ {
+ idSourceToSet( theReferenceFaces[i], getMeshDS(), refFaces, SMDSAbs_Face, /*emptyIfIsMesh=*/1 );
+ }
+ if ( refFaces.empty() && theReferenceFaces.length() > 0 )
+ THROW_SALOME_CORBA_EXCEPTION("Reference faces are invalid", SALOME::BAD_PARAM);
+
+
+ gp_Vec zeroVec( 0,0,0 );
+
+ // reorient
+ int nbReori = getEditor().Reorient2D( objFaces, zeroVec, refFaces, /*allowNonManifold=*/false );
+
+ if ( nbReori )
+ declareMeshModified( /*isReComputeSafe=*/false );
+
+ TPythonDump() << this << ".Reorient2DByNeighbours("
+ << theObjectFaces << ", "
+ << theReferenceFaces << ")";
+
+ return nbReori;
+
+ SMESH_CATCH( SMESH::throwCorbaException );
+ return 0;
+}
+
//=======================================================================
//function : Reorient2DBy3D
//purpose : Reorient faces basing on orientation of adjacent volumes.
const SMESH::DirStruct& theDirection,
CORBA::Long theFace,
const SMESH::PointStruct& thePoint);
+ /*!
+ * \brief Reorient faces contained in a list of \a objectFaces
+ * equally to faces contained in a list of \a referenceFaces.
+ * \param objectFaces - faces to reorient in a list including either
+ * the whole mesh or groups and/or sub-meshes.
+ * \param referenceFaces - correctly oriented faces in a list of groups and/or sub-meshes.
+ * It can be empty, then the 1st face in \a objectFaces is used as the reference.
+ * \return number of reoriented faces.
+ */
+ CORBA::Long Reorient2DByNeighbours(const SMESH::ListOfIDSources& objectFaces,
+ const SMESH::ListOfIDSources& referenceFaces);
/*!
* \brief Reorient faces basing on orientation of adjacent volumes.
* \param faces - a list of objects containing face to reorient
theFace = -1
return self.editor.Reorient2D( the2DObject, theDirection, theFace, thePoint )
+ def Reorient2DByNeighbours(self, objectFaces, referenceFaces=[]):
+ """
+ Reorient faces contained in a list of *objectFaces*
+ equally to faces contained in a list of *referenceFaces*.
+
+ Parameters:
+ objectFaces: list of :class:`mesh, sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding faces to reorient.
+ referenceFaces: list of :class:`sub-mesh, group, filter <SMESH.SMESH_IDSource>` holding reference faces. It can be empty, then any face in *objectFaces* is used as the reference.
+
+ Returns:
+ number of reoriented faces.
+ """
+ if not isinstance( objectFaces, list ):
+ objectFaces = [ objectFaces ]
+ for i,obj2D in enumerate( objectFaces ):
+ if isinstance( obj2D, Mesh ):
+ objectFaces[i] = obj2D.GetMesh()
+ if not isinstance( referenceFaces, list ):
+ referenceFaces = [ referenceFaces ]
+
+ return self.editor.Reorient2DByNeighbours( objectFaces, referenceFaces )
+
+
def Reorient2DBy3D(self, the2DObject, the3DObject, theOutsideNormal=True ):
"""
Reorient faces according to adjacent volumes.
continue;
gp_Dir direction(1,0,0);
- const SMDS_MeshElement* anyFace = *facesToOrient.begin();
- editor.Reorient2D( facesToOrient, direction, anyFace );
+ TIDSortedElemSet refFaces;
+ editor.Reorient2D( facesToOrient, direction, refFaces, /*allowNonManifold=*/true );
}
}
return;