mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2024-11-11 16:19:16 +05:00
[bos #38052][EDF](2023-T3) Option to replace polyhedrons by hexahedrons in the body frontier based in a predefined volume relation.
Including quanta option to hypothesis with persistence. Working version w/o support to add faces on the boundary elements. Intermedial commit. Intermedial commit. Adding documentation and test. Final adjust for conformity with NRT.
This commit is contained in:
parent
3b570ddfbe
commit
9a170f0e1e
Binary file not shown.
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 174 KiB |
@ -65,6 +65,8 @@ This dialog allows to define
|
||||
* **Create Faces** check-box activates creation on mesh faces.
|
||||
* **Consider Shared and Internal Faces** check-box activates treatment of faces shared by solids and internal. By default the algorithm considers only outer boundaries of the geometry.
|
||||
* **Apply Threshold to Shared / Internal Faces** check-box activates application of **Threshold** to cells cut by shared and internal faces, that can cause appearance of holes inside the mesh.
|
||||
* **Set Quanta** check-box activates application of **Quanta Value** to replace **polyhedrons** by hexahedrons at the boundary of the geometry.
|
||||
* **Quanta Value** the relation between the volume of a polyhedrons and the equivalent hexahedron at the solid boundary. When **Set Quanta** is checked, those elements are replaced by hexahedrons if the volume of the polyhedron divided by the equivalente hexahedron is bigger than **Quanta**.
|
||||
* **Definition mode** allows choosing how Cartesian structured grid is defined. Location of nodes along each grid axis is defined individually:
|
||||
|
||||
* You can specify the **Coordinates** of grid nodes. **Insert** button inserts a node at **Step** distance (negative or positive) from the selected node. **Delete** button removes the selected node. Double click on a coordinate in the list enables its edition. **Note** that node coordinates are measured along directions of axes that can differ from the directions of the Global Coordinate System.
|
||||
|
@ -1063,6 +1063,15 @@ module StdMeshers
|
||||
void SetToCreateFaces(in boolean toCreate);
|
||||
boolean GetToCreateFaces();
|
||||
|
||||
/*!
|
||||
* Enable creation of mesh faces.
|
||||
*/
|
||||
void SetToUseQuanta(in boolean toUseQuanta);
|
||||
boolean GetToUseQuanta();
|
||||
|
||||
void SetQuanta(in double quanta) raises (SALOME::SALOME_Exception);
|
||||
double GetQuanta();
|
||||
|
||||
/*!
|
||||
* Return axes at which a number of generated hexahedra is maximal
|
||||
*/
|
||||
|
@ -2137,6 +2137,52 @@ bool SMDS_VolumeTool::IsFreeFace( int faceIndex, const SMDS_MeshElement** otherV
|
||||
return isFree;
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Check that only one volume is built on the face nodes
|
||||
* Different to IsFreeFace function, all nodes of the face are checked.
|
||||
* For non conforming meshes, the face that is not conform with the neighbor
|
||||
* will be identify as free.
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
bool SMDS_VolumeTool::IsFreeFaceCheckAllNodes( int faceIndex, const SMDS_MeshElement** otherVol/*=0*/ ) const
|
||||
{
|
||||
const bool isFree = true;
|
||||
|
||||
if ( !setFace( faceIndex ))
|
||||
return !isFree;
|
||||
|
||||
const SMDS_MeshNode** nodes = GetFaceNodes( faceIndex );
|
||||
|
||||
const int di = myVolume->IsQuadratic() ? 2 : 1;
|
||||
const int nbN = myCurFace.myNbNodes/di;
|
||||
std::vector<bool> allNodesCoincideWithNeighbor(nbN,false);
|
||||
|
||||
for (int nodeId = 0; nodeId < nbN; nodeId++)
|
||||
{
|
||||
SMDS_ElemIteratorPtr eIt = nodes[nodeId]->GetInverseElementIterator( SMDSAbs_Volume );
|
||||
int count = 0;
|
||||
while ( eIt->more() )
|
||||
{
|
||||
const SMDS_MeshElement* vol = eIt->next();
|
||||
if ( vol == myVolume )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( count==0 /*free corner in the face means free face*/)
|
||||
{
|
||||
if ( otherVol ) *otherVol = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return IsFreeFace( faceIndex, otherVol );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Thorough check that only one volume is built on the face nodes
|
||||
|
@ -188,6 +188,12 @@ class SMDS_EXPORT SMDS_VolumeTool
|
||||
bool IsFreeFace( int faceIndex, const SMDS_MeshElement** otherVol=0 ) const;
|
||||
// Fast check that only one volume is built on nodes of a given face
|
||||
// otherVol returns another volume sharing the given facet
|
||||
// Function works for conforming mesh.
|
||||
|
||||
bool IsFreeFaceCheckAllNodes( int faceIndex, const SMDS_MeshElement** otherVol=0 ) const;
|
||||
// Check that only one volume is built on nodes of a given face
|
||||
// otherVol returns another volume sharing the given facet
|
||||
// Function to be used on mesh with non conforming elements. The face shared between
|
||||
|
||||
bool IsFreeFaceAdv( int faceIndex, const SMDS_MeshElement** otherVol=0 ) const;
|
||||
// Thorough check that all volumes built on the face nodes lays on one side
|
||||
|
@ -67,7 +67,9 @@ StdMeshers_CartesianParameters3D::StdMeshers_CartesianParameters3D(int h
|
||||
_toAddEdges( false ),
|
||||
_toConsiderInternalFaces( false ),
|
||||
_toUseThresholdForInternalFaces( false ),
|
||||
_toCreateFaces( false )
|
||||
_toCreateFaces( false ),
|
||||
_toUseQuanta(false),
|
||||
_quanta(0.01)
|
||||
{
|
||||
_name = "CartesianParameters3D"; // used by "Cartesian_3D"
|
||||
_param_algo_dim = 3; // 3D
|
||||
@ -774,6 +776,37 @@ void StdMeshers_CartesianParameters3D::SetToCreateFaces(bool toCreate)
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetToUseQuanta
|
||||
//purpose : Enables use of quanta
|
||||
//=======================================================================
|
||||
|
||||
void StdMeshers_CartesianParameters3D::SetToUseQuanta(bool toUseQuanta)
|
||||
{
|
||||
if ( _toUseQuanta != toUseQuanta )
|
||||
{
|
||||
_toUseQuanta = toUseQuanta;
|
||||
NotifySubMeshesHypothesisModification();
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetQuanta
|
||||
//purpose : Set size quanta value
|
||||
//=======================================================================
|
||||
|
||||
void StdMeshers_CartesianParameters3D::SetQuanta(const double quanta)
|
||||
{
|
||||
if ( quanta < 1e-6 || quanta > 1.0 )
|
||||
throw SALOME_Exception(LOCALIZED("Quanta must be in the range [0.01,1] "));
|
||||
|
||||
bool changed = (_quanta != quanta);
|
||||
_quanta = quanta;
|
||||
|
||||
if ( changed )
|
||||
NotifySubMeshesHypothesisModification();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsDefined
|
||||
//purpose : Return true if parameters are well defined
|
||||
@ -823,7 +856,9 @@ std::ostream & StdMeshers_CartesianParameters3D::SaveTo(std::ostream & save)
|
||||
|
||||
save << " " << _toConsiderInternalFaces
|
||||
<< " " << _toUseThresholdForInternalFaces
|
||||
<< " " << _toCreateFaces;
|
||||
<< " " << _toCreateFaces
|
||||
<< " " << _toUseQuanta
|
||||
<< " " << _quanta;
|
||||
|
||||
return save;
|
||||
}
|
||||
@ -889,6 +924,9 @@ std::istream & StdMeshers_CartesianParameters3D::LoadFrom(std::istream & load)
|
||||
load >> _toCreateFaces;
|
||||
}
|
||||
|
||||
if ( load >> _toUseQuanta )
|
||||
load >> _quanta;
|
||||
|
||||
return load;
|
||||
}
|
||||
|
||||
|
@ -157,6 +157,19 @@ public:
|
||||
void SetToCreateFaces(bool toCreate);
|
||||
bool GetToCreateFaces() const { return _toCreateFaces; }
|
||||
|
||||
/*!
|
||||
* \brief Enables use of quanta for hexahedrons at the solid external boundary
|
||||
*/
|
||||
void SetToUseQuanta(bool toUseQuanta);
|
||||
bool GetToUseQuanta() const { return _toUseQuanta; }
|
||||
|
||||
/*!
|
||||
* \brief Value of the quanta (volPolyhedron/volHexahedron) to use
|
||||
* \remark value [0.1, 1.0]
|
||||
*/
|
||||
void SetQuanta(const double quanta );
|
||||
double GetQuanta() const { return _quanta; }
|
||||
|
||||
|
||||
/*!
|
||||
* \brief Return true if parameters are well defined
|
||||
@ -193,6 +206,8 @@ public:
|
||||
bool _toConsiderInternalFaces;
|
||||
bool _toUseThresholdForInternalFaces;
|
||||
bool _toCreateFaces;
|
||||
bool _toUseQuanta;
|
||||
double _quanta;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -470,6 +470,8 @@ namespace
|
||||
int _nodeShift[8];
|
||||
|
||||
vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
|
||||
vector< const SMDS_MeshNode* > _allBorderNodes; // mesh nodes between the bounding box and the geometry boundary
|
||||
|
||||
vector< const F_IntersectPoint* > _gridIntP; // grid node intersection with geometry
|
||||
ObjectPool< E_IntersectPoint > _edgeIntPool; // intersections with EDGEs
|
||||
ObjectPool< F_IntersectPoint > _extIntPool; // intersections with extended INTERNAL FACEs
|
||||
@ -481,6 +483,8 @@ namespace
|
||||
bool _toConsiderInternalFaces;
|
||||
bool _toUseThresholdForInternalFaces;
|
||||
double _sizeThreshold;
|
||||
bool _toUseQuanta;
|
||||
double _quanta;
|
||||
|
||||
SMESH_MesherHelper* _helper;
|
||||
|
||||
@ -692,6 +696,7 @@ namespace
|
||||
struct _Node //!< node either at a hexahedron corner or at intersection
|
||||
{
|
||||
const SMDS_MeshNode* _node; // mesh node at hexahedron corner
|
||||
const SMDS_MeshNode* _boundaryCornerNode; // missing mesh node due to hex truncation on the boundary
|
||||
const B_IntersectPoint* _intPoint;
|
||||
const _Face* _usedInFace;
|
||||
char _isInternalFlags;
|
||||
@ -700,6 +705,8 @@ namespace
|
||||
:_node(n), _intPoint(ip), _usedInFace(0), _isInternalFlags(0) {}
|
||||
const SMDS_MeshNode* Node() const
|
||||
{ return ( _intPoint && _intPoint->_node ) ? _intPoint->_node : _node; }
|
||||
const SMDS_MeshNode* BoundaryNode() const
|
||||
{ return _node ? _node : _boundaryCornerNode; }
|
||||
const E_IntersectPoint* EdgeIntPnt() const
|
||||
{ return static_cast< const E_IntersectPoint* >( _intPoint ); }
|
||||
const F_IntersectPoint* FaceIntPnt() const
|
||||
@ -1882,6 +1889,7 @@ namespace
|
||||
const size_t nbGridNodes = _coords[0].size() * _coords[1].size() * _coords[2].size();
|
||||
vector< TGeomID > shapeIDVec( nbGridNodes, theUndefID );
|
||||
_nodes.resize( nbGridNodes, 0 );
|
||||
_allBorderNodes.resize( nbGridNodes, 0 );
|
||||
_gridIntP.resize( nbGridNodes, NULL );
|
||||
|
||||
SMESHDS_Mesh* mesh = helper.GetMeshDS();
|
||||
@ -1936,6 +1944,7 @@ namespace
|
||||
}
|
||||
if ( nodeCoord == coordEnd ) break;
|
||||
}
|
||||
|
||||
// create a mesh node on a GridLine at ip if it does not coincide with a grid node
|
||||
if ( nodeParam > ip->_paramOnLine + _tol )
|
||||
{
|
||||
@ -1996,6 +2005,14 @@ namespace
|
||||
SetOnShape( _nodes[ nodeIndex ], *_gridIntP[ nodeIndex ], & v );
|
||||
UpdateFacesOfVertex( *_gridIntP[ nodeIndex ], v );
|
||||
}
|
||||
else if ( _toUseQuanta && !_allBorderNodes[ nodeIndex ] /*add all nodes outside the body. Used to reconstruct the hexahedrals when polys are not desired!*/)
|
||||
{
|
||||
gp_XYZ xyz = ( _coords[0][x] * _axes[0] +
|
||||
_coords[1][y] * _axes[1] +
|
||||
_coords[2][z] * _axes[2] );
|
||||
_allBorderNodes[ nodeIndex ] = mesh->AddNode( xyz.X(), xyz.Y(), xyz.Z() );
|
||||
mesh->SetNodeInVolume( _allBorderNodes[ nodeIndex ], shapeIDVec[ nodeIndex ]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _MY_DEBUG_
|
||||
@ -2668,11 +2685,16 @@ namespace
|
||||
{
|
||||
_hexNodes[iN]._isInternalFlags = 0;
|
||||
|
||||
// Grid node
|
||||
_hexNodes[iN]._node = _grid->_nodes [ _origNodeInd + _grid->_nodeShift[iN] ];
|
||||
_hexNodes[iN]._intPoint = _grid->_gridIntP[ _origNodeInd + _grid->_nodeShift[iN] ];
|
||||
|
||||
if ( _grid->_allBorderNodes[ _origNodeInd + _grid->_nodeShift[iN] ] )
|
||||
_hexNodes[iN]._boundaryCornerNode = _grid->_allBorderNodes [ _origNodeInd + _grid->_nodeShift[iN] ];
|
||||
|
||||
if ( _hexNodes[iN]._node && !solid->Contains( _hexNodes[iN]._node->GetShapeID() ))
|
||||
_hexNodes[iN]._node = 0;
|
||||
|
||||
if ( _hexNodes[iN]._intPoint && !solid->ContainsAny( _hexNodes[iN]._intPoint->_faceIDs ))
|
||||
_hexNodes[iN]._intPoint = 0;
|
||||
|
||||
@ -4808,6 +4830,7 @@ namespace
|
||||
{
|
||||
F_IntersectPoint noIntPnt;
|
||||
const bool toCheckNodePos = _grid->IsToCheckNodePos();
|
||||
const bool useQuanta = _grid->_toUseQuanta;
|
||||
|
||||
int nbAdded = 0;
|
||||
// add elements resulted from hexahedron intersection
|
||||
@ -4855,16 +4878,15 @@ namespace
|
||||
} // loop to get nodes
|
||||
|
||||
const SMDS_MeshElement* v = 0;
|
||||
|
||||
if ( !volDef->_quantities.empty() )
|
||||
{
|
||||
if ( !useQuanta )
|
||||
{
|
||||
// split polyhedrons of with disjoint volumes
|
||||
std::vector<std::vector<int>> splitQuantities;
|
||||
std::vector<std::vector< const SMDS_MeshNode* > > splitNodes;
|
||||
if ( checkPolyhedronValidity( volDef, splitQuantities, splitNodes ) == 1 )
|
||||
{
|
||||
v = addPolyhedronToMesh( volDef, helper, nodes, volDef->_quantities );
|
||||
}
|
||||
else
|
||||
{
|
||||
int counter = -1;
|
||||
@ -4879,6 +4901,19 @@ namespace
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const double quanta = _grid->_quanta;
|
||||
double polyVol = volDef->_size;
|
||||
double hexaVolume = _sideLength[0] * _sideLength[1] * _sideLength[2];
|
||||
if ( hexaVolume > 0.0 && polyVol/hexaVolume >= quanta /*set the volume if the relation is satisfied*/)
|
||||
v = helper.AddVolume( _hexNodes[0].BoundaryNode(), _hexNodes[2].BoundaryNode(),
|
||||
_hexNodes[3].BoundaryNode(), _hexNodes[1].BoundaryNode(),
|
||||
_hexNodes[4].BoundaryNode(), _hexNodes[6].BoundaryNode(),
|
||||
_hexNodes[7].BoundaryNode(), _hexNodes[5].BoundaryNode() );
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch ( nodes.size() )
|
||||
{
|
||||
@ -4945,6 +4980,8 @@ namespace
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Return true if the element is in a hole
|
||||
* \remark consider a cell to be in a hole if all links in any direction
|
||||
* comes OUT of geometry
|
||||
*/
|
||||
bool Hexahedron::isInHole() const
|
||||
{
|
||||
@ -5695,6 +5732,7 @@ namespace
|
||||
SMESH_MeshEditor::ElemFeatures face( SMDSAbs_Face );
|
||||
SMESHDS_Mesh* meshDS = helper.GetMeshDS();
|
||||
|
||||
bool isQuantaSet = _grid->_toUseQuanta;
|
||||
// check if there are internal or shared FACEs
|
||||
bool hasInternal = ( !_grid->_geometry.IsOneSolid() ||
|
||||
_grid->_geometry._soleSolid.HasInternalFaces() );
|
||||
@ -5703,17 +5741,15 @@ namespace
|
||||
{
|
||||
if ( !vTool.Set( boundaryVolumes[ iV ]))
|
||||
continue;
|
||||
|
||||
TGeomID solidID = vTool.Element()->GetShapeID();
|
||||
Solid * solid = _grid->GetOneOfSolids( solidID );
|
||||
|
||||
// find boundary facets
|
||||
|
||||
bndFacets.clear();
|
||||
for ( int iF = 0, n = vTool.NbFaces(); iF < n; iF++ )
|
||||
{
|
||||
const SMDS_MeshElement* otherVol;
|
||||
bool isBoundary = vTool.IsFreeFace( iF, &otherVol );
|
||||
bool isBoundary = isQuantaSet ? vTool.IsFreeFaceCheckAllNodes( iF, &otherVol ) : vTool.IsFreeFace( iF, &otherVol );
|
||||
if ( isBoundary )
|
||||
{
|
||||
bndFacets.push_back( iF );
|
||||
@ -5735,7 +5771,6 @@ namespace
|
||||
continue;
|
||||
|
||||
// create faces
|
||||
|
||||
if ( !vTool.IsPoly() )
|
||||
vTool.SetExternalNormal();
|
||||
for ( size_t i = 0; i < bndFacets.size(); ++i ) // loop on boundary facets
|
||||
@ -5763,7 +5798,7 @@ namespace
|
||||
if ( nn[ iN ]->GetPosition()->GetDim() == 2 )
|
||||
faceID = nn[ iN ]->GetShapeID();
|
||||
}
|
||||
if ( faceID == 0 )
|
||||
if ( faceID == 0 && !isQuantaSet /*if quanta is set boundary nodes at boundary does not coincide with any geometrical face */ )
|
||||
faceID = findCommonFace( face.myNodes, helper.GetMesh() );
|
||||
|
||||
bool toCheckFace = faceID && (( !isBoundary ) ||
|
||||
@ -5780,7 +5815,7 @@ namespace
|
||||
// if ( !faceID && !isBoundary )
|
||||
// continue;
|
||||
}
|
||||
if ( !faceID && !isBoundary )
|
||||
if ( !faceID && !isBoundary && !isQuantaSet )
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -6625,6 +6660,8 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh,
|
||||
grid._toConsiderInternalFaces = _hyp->GetToConsiderInternalFaces();
|
||||
grid._toUseThresholdForInternalFaces = _hyp->GetToUseThresholdForInternalFaces();
|
||||
grid._sizeThreshold = _hyp->GetSizeThreshold();
|
||||
grid._toUseQuanta = _hyp->GetToUseQuanta();
|
||||
grid._quanta = _hyp->GetQuanta();
|
||||
if ( _isComputeOffset )
|
||||
{
|
||||
grid._toAddEdges = true;
|
||||
@ -6763,6 +6800,15 @@ bool StdMeshers_Cartesian_3D::Compute(SMESH_Mesh & theMesh,
|
||||
grid._nodes[i]->setIsMarked( true );
|
||||
}
|
||||
|
||||
for ( size_t i = 0; i < grid._allBorderNodes.size(); ++i )
|
||||
if ( grid._allBorderNodes[i] &&
|
||||
!grid._allBorderNodes[i]->IsNull() &&
|
||||
grid._allBorderNodes[i]->NbInverseElements() == 0 )
|
||||
{
|
||||
nodesToRemove.push_back( grid._allBorderNodes[i] );
|
||||
grid._allBorderNodes[i]->setIsMarked( true );
|
||||
}
|
||||
|
||||
// do remove
|
||||
for ( size_t i = 0; i < nodesToRemove.size(); ++i )
|
||||
meshDS->RemoveFreeNode( nodesToRemove[i], /*smD=*/0, /*fromGroups=*/false );
|
||||
|
@ -830,6 +830,17 @@ QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
|
||||
myUseThresholdForInternalFaces = new QCheckBox( tr("USE_THRESHOLD_FOR_INTERNAL_FACES"), GroupC1 );
|
||||
argGroupLayout->addWidget( myUseThresholdForInternalFaces, row, 0, 1, 2 );
|
||||
row++;
|
||||
mySetQuanta = new QCheckBox( tr("SET_QUANTA"), GroupC1 );
|
||||
argGroupLayout->addWidget( mySetQuanta, row, 0, 1, 2 );
|
||||
row++;
|
||||
|
||||
argGroupLayout->addWidget( new QLabel( tr("QUANTA_VALUE"), GroupC1 ), row, 0 );
|
||||
myQuanta = new SMESHGUI_SpinBox( GroupC1 );
|
||||
myQuanta->setAcceptNames( false );
|
||||
myQuanta->RangeStepAndValidator( 1e-6, 1, 0.05, "length_precision" );
|
||||
myQuanta->setEnabled(false);
|
||||
argGroupLayout->addWidget( myQuanta, row, 1 );
|
||||
row++;
|
||||
|
||||
// 3) Grid definition
|
||||
QTabWidget* tabWdg = new QTabWidget( fr );
|
||||
@ -935,6 +946,7 @@ QFrame* StdMeshersGUI_CartesianParamCreator::buildFrame()
|
||||
connect( resetBtn, SIGNAL( clicked(bool)), SLOT( onResetAxes(bool)));
|
||||
connect( myConsiderInternalFaces, SIGNAL( toggled(bool)),
|
||||
myUseThresholdForInternalFaces, SLOT( setEnabled(bool)));
|
||||
connect( mySetQuanta, SIGNAL( clicked(bool)), SLOT( onSetQuanta(bool)) );
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
{
|
||||
connect( myXDirSpin[i], SIGNAL(valueChanged (const QString&)),
|
||||
@ -1011,6 +1023,10 @@ void StdMeshersGUI_CartesianParamCreator::retrieveParams() const
|
||||
myCreateFaces->setChecked( h->GetToCreateFaces() );
|
||||
myConsiderInternalFaces->setChecked( h->GetToConsiderInternalFaces() );
|
||||
myUseThresholdForInternalFaces->setChecked( h->GetToUseThresholdForInternalFaces() );
|
||||
mySetQuanta->setChecked( h->GetToUseQuanta() );
|
||||
myQuanta->setValue( h->GetQuanta() );
|
||||
if (h->GetToUseQuanta())
|
||||
myQuanta->setEnabled(true);
|
||||
|
||||
// grid definition
|
||||
for ( int ax = 0; ax < 3; ++ax )
|
||||
@ -1101,6 +1117,8 @@ QString StdMeshersGUI_CartesianParamCreator::storeParams() const
|
||||
h->SetToCreateFaces( myCreateFaces->isChecked() );
|
||||
h->SetToConsiderInternalFaces( myConsiderInternalFaces->isChecked() );
|
||||
h->SetToUseThresholdForInternalFaces( myUseThresholdForInternalFaces->isChecked() );
|
||||
h->SetToUseQuanta( mySetQuanta->isChecked() );
|
||||
h->SetQuanta( myQuanta->text().toDouble() );
|
||||
|
||||
// grid
|
||||
for ( int ax = 0; ax < 3; ++ax )
|
||||
@ -1453,3 +1471,19 @@ void StdMeshersGUI_CartesianParamCreator::onGridModeChanged(int)
|
||||
|
||||
myFixedPointGrp->setEnabled( haveSpacing );
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
/*!
|
||||
* \brief Enable and disable quanta value combo box
|
||||
*/
|
||||
//================================================================================
|
||||
|
||||
void StdMeshersGUI_CartesianParamCreator::onSetQuanta(bool)
|
||||
{
|
||||
StdMeshers::StdMeshers_CartesianParameters3D_var h =
|
||||
StdMeshers::StdMeshers_CartesianParameters3D::_narrow( hypothesis() );
|
||||
if ( h->_is_nil() )
|
||||
return;
|
||||
|
||||
myQuanta->setEnabled( mySetQuanta->isChecked() );
|
||||
}
|
||||
|
@ -147,6 +147,7 @@ private slots:
|
||||
void onOptimalAxes(bool);
|
||||
void onResetAxes(bool);
|
||||
void onGridModeChanged(int);
|
||||
void onSetQuanta(bool);
|
||||
|
||||
private:
|
||||
QLineEdit* myName;
|
||||
@ -155,6 +156,8 @@ private:
|
||||
QCheckBox* myCreateFaces;
|
||||
QCheckBox* myConsiderInternalFaces;
|
||||
QCheckBox* myUseThresholdForInternalFaces;
|
||||
QCheckBox* mySetQuanta;
|
||||
SMESHGUI_SpinBox* myQuanta;
|
||||
|
||||
StdMeshersGUI::GridAxisTab* myAxisTabs[3];
|
||||
QGroupBox* myFixedPointGrp;
|
||||
|
@ -586,6 +586,14 @@ Consider creating another hypothesis instead of using this one for this mesh/sub
|
||||
<source>USE_THRESHOLD_FOR_INTERNAL_FACES</source>
|
||||
<translation>Apply Threshold to Shared / Internal Faces</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SET_QUANTA</source>
|
||||
<translation>Set Quanta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>QUANTA_VALUE</source>
|
||||
<translation>Quanta Value</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>AXIS_X</source>
|
||||
<translation>Axis X</translation>
|
||||
|
@ -562,6 +562,14 @@ Veuillez plutôt créer une autre hypothèse à la place de celle-ci pour ce mai
|
||||
<source>USE_THRESHOLD_FOR_INTERNAL_FACES</source>
|
||||
<translation>Appliquer le seuil aux faces partagées/internes</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>SET_QUANTA</source>
|
||||
<translation>Utiliser Quanta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>QUANTA_VALUE</source>
|
||||
<translation>Valeur Quanta</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>AXIS_X</source>
|
||||
<translation>Axe X</translation>
|
||||
|
@ -418,6 +418,63 @@ CORBA::Boolean StdMeshers_CartesianParameters3D_i::GetToCreateFaces()
|
||||
return GetImpl()->GetToCreateFaces();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//function : SetToUseQuanta
|
||||
//purpose : Enables use of quanta value.
|
||||
//=======================================================================
|
||||
|
||||
void StdMeshers_CartesianParameters3D_i::SetToUseQuanta(CORBA::Boolean toUseQuanta)
|
||||
{
|
||||
if ( GetToUseQuanta() == toUseQuanta )
|
||||
return;
|
||||
GetImpl()->SetToUseQuanta( toUseQuanta );
|
||||
SMESH::TPythonDump() << _this() << ".SetToUseQuanta( " << toUseQuanta << " )";
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetToUseQuanta
|
||||
//purpose : Check the value of toUseQuanta option
|
||||
//=======================================================================
|
||||
|
||||
CORBA::Boolean StdMeshers_CartesianParameters3D_i::GetToUseQuanta()
|
||||
{
|
||||
return GetImpl()->GetToUseQuanta();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* SetQuanta
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
void StdMeshers_CartesianParameters3D_i::SetQuanta(CORBA::Double quanta)
|
||||
|
||||
{
|
||||
ASSERT( myBaseImpl );
|
||||
try {
|
||||
this->GetImpl()->SetQuanta(quanta);
|
||||
}
|
||||
catch ( SALOME_Exception& S_ex ) {
|
||||
THROW_SALOME_CORBA_EXCEPTION( S_ex.what(), SALOME::BAD_PARAM );
|
||||
}
|
||||
|
||||
if ( GetToUseQuanta() )
|
||||
// Update Python script
|
||||
SMESH::TPythonDump() << _this() << ".SetQuanta( " << SMESH::TVar(quanta) << " )";
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
/*!
|
||||
* GetQuanta
|
||||
*/
|
||||
//=============================================================================
|
||||
|
||||
CORBA::Double StdMeshers_CartesianParameters3D_i::GetQuanta()
|
||||
{
|
||||
return this->GetImpl()->GetQuanta();
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : IsGridBySpacing
|
||||
//purpose : Return true if the grid is defined by spacing functions and
|
||||
|
@ -125,6 +125,17 @@ class STDMESHERS_I_EXPORT StdMeshers_CartesianParameters3D_i:
|
||||
void SetToCreateFaces(CORBA::Boolean toCreate);
|
||||
CORBA::Boolean GetToCreateFaces();
|
||||
|
||||
/*!
|
||||
* Set quanta option to allow replace polyhedrons by hexahedrons
|
||||
*/
|
||||
void SetToUseQuanta(CORBA::Boolean toUseQuanta);
|
||||
CORBA::Boolean GetToUseQuanta();
|
||||
|
||||
/*!
|
||||
* Define the quanta value
|
||||
*/
|
||||
void SetQuanta(CORBA::Double quanta);
|
||||
CORBA::Double GetQuanta();
|
||||
|
||||
/*!
|
||||
* \brief Return true if the grid is defined by spacing functions and
|
||||
|
50
test/body_fitting_quanta_sphere.py
Normal file
50
test/body_fitting_quanta_sphere.py
Normal file
@ -0,0 +1,50 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import salome
|
||||
salome.salome_init()
|
||||
import GEOM
|
||||
from salome.geom import geomBuilder
|
||||
geompy = geomBuilder.New()
|
||||
|
||||
import SMESH, SALOMEDS
|
||||
from salome.smesh import smeshBuilder
|
||||
smesh = smeshBuilder.New()
|
||||
|
||||
O = geompy.MakeVertex(0, 0, 0)
|
||||
OX = geompy.MakeVectorDXDYDZ(1, 0, 0)
|
||||
OY = geompy.MakeVectorDXDYDZ(0, 1, 0)
|
||||
OZ = geompy.MakeVectorDXDYDZ(0, 0, 1)
|
||||
Sphere_1 = geompy.MakeSphereR(100)
|
||||
geompy.addToStudy( O, 'O' )
|
||||
geompy.addToStudy( OX, 'OX' )
|
||||
geompy.addToStudy( OY, 'OY' )
|
||||
geompy.addToStudy( OZ, 'OZ' )
|
||||
geompy.addToStudy( Sphere_1, 'Sphere_1' )
|
||||
|
||||
Mesh_1 = smesh.Mesh(Sphere_1,'Mesh_1')
|
||||
Cartesian_3D = Mesh_1.BodyFitted()
|
||||
Body_Fitting_Parameters_1 = Cartesian_3D.SetGrid([ [ '34.641' ], [ 0, 1 ]],[ [ '34.641' ], [ 0, 1 ]],[ [ '34.641' ], [ 0, 1 ]],4,0)
|
||||
Body_Fitting_Parameters_1.SetToUseQuanta( 1 )
|
||||
Body_Fitting_Parameters_1.SetQuanta( 0.8 )
|
||||
isDone = Mesh_1.Compute()
|
||||
|
||||
Polys = Mesh_1.NbPolyhedrons()
|
||||
Hexas1 = Mesh_1.NbHexas()
|
||||
|
||||
#No polyhedrons in the mesh
|
||||
assert(Polys==0)
|
||||
|
||||
Body_Fitting_Parameters_1.SetQuanta( 0.2 )
|
||||
isDone = Mesh_1.Compute()
|
||||
|
||||
Polys = Mesh_1.NbPolyhedrons()
|
||||
Hexas2 = Mesh_1.NbHexas()
|
||||
|
||||
#Still no polyhedrons in the mesh
|
||||
assert(Polys==0)
|
||||
|
||||
#Numher of hexahedrons is bigger for hexas2 becuase quanta value is smaller
|
||||
assert( Hexas1 < Hexas2 )
|
||||
|
||||
if salome.sg.hasDesktop():
|
||||
salome.sg.updateObjBrowser()
|
@ -32,6 +32,7 @@ SET(BAD_TESTS
|
||||
blocFissure_07_without_session.py
|
||||
body_fitting_viscous_layer_cylinder.py
|
||||
body_fitting_viscous_layer_tpipe.py
|
||||
body_fitting_quanta_sphere.py
|
||||
ex04_cube5tetraHexa.py
|
||||
ex21_lamp.py
|
||||
ex29_refine.py
|
||||
|
Loading…
Reference in New Issue
Block a user