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.
* **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.
*/
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
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
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
_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
}
}
+//=======================================================================
+//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
save << " " << _toConsiderInternalFaces
<< " " << _toUseThresholdForInternalFaces
- << " " << _toCreateFaces;
+ << " " << _toCreateFaces
+ << " " << _toUseQuanta
+ << " " << _quanta;
return save;
}
load >> _toCreateFaces;
}
+ if ( load >> _toUseQuanta )
+ load >> _quanta;
+
return load;
}
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
bool _toConsiderInternalFaces;
bool _toUseThresholdForInternalFaces;
bool _toCreateFaces;
+ bool _toUseQuanta;
+ double _quanta;
};
#endif
// index shift within _nodes of nodes of a cell from the 1st node
int _nodeShift[8];
- vector< const SMDS_MeshNode* > _nodes; // mesh nodes at grid nodes
+ 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
bool _toConsiderInternalFaces;
bool _toUseThresholdForInternalFaces;
double _sizeThreshold;
+ bool _toUseQuanta;
+ double _quanta;
SMESH_MesherHelper* _helper;
// --------------------------------------------------------------------------------
struct _Node //!< node either at a hexahedron corner or at intersection
{
- const SMDS_MeshNode* _node; // mesh node at hexahedron corner
+ 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;
:_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
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();
if ( ++nodeCoord < coordEnd )
nodeParam = *nodeCoord - *coord0;
else
- break;
+ break;
}
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 )
{
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_
{
_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;
{
F_IntersectPoint noIntPnt;
const bool toCheckNodePos = _grid->IsToCheckNodePos();
+ const bool useQuanta = _grid->_toUseQuanta;
int nbAdded = 0;
// add elements resulted from hexahedron intersection
}
} // loop to get nodes
- const SMDS_MeshElement* v = 0;
-
+ const SMDS_MeshElement* v = 0;
if ( !volDef->_quantities.empty() )
- {
- // 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 );
+ {
+ 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;
+ for (size_t id = 0; id < splitQuantities.size(); id++)
+ {
+ v = addPolyhedronToMesh( volDef, helper, splitNodes[ id ], splitQuantities[ id ] );
+ if ( id < splitQuantities.size()-1 )
+ volDef->_brotherVolume.push_back( v );
+ counter++;
+ }
+ nbAdded += counter;
+ }
}
else
{
- int counter = -1;
- for (size_t id = 0; id < splitQuantities.size(); id++)
- {
- v = addPolyhedronToMesh( volDef, helper, splitNodes[ id ], splitQuantities[ id ] );
- if ( id < splitQuantities.size()-1 )
- volDef->_brotherVolume.push_back( v );
- counter++;
- }
- nbAdded += counter;
+ 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
//================================================================================
/*!
* \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
{
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() );
+ _grid->_geometry._soleSolid.HasInternalFaces() );
for ( size_t iV = 0; iV < boundaryVolumes.size(); ++iV )
{
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 );
continue;
// create faces
-
if ( !vTool.IsPoly() )
vTool.SetExternalNormal();
for ( size_t i = 0; i < bndFacets.size(); ++i ) // loop on boundary facets
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 ) ||
// if ( !faceID && !isBoundary )
// continue;
}
- if ( !faceID && !isBoundary )
+ if ( !faceID && !isBoundary && !isQuantaSet )
continue;
}
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;
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 );
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 );
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&)),
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 )
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 )
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() );
+}
void onOptimalAxes(bool);
void onResetAxes(bool);
void onGridModeChanged(int);
+ void onSetQuanta(bool);
private:
QLineEdit* myName;
QCheckBox* myCreateFaces;
QCheckBox* myConsiderInternalFaces;
QCheckBox* myUseThresholdForInternalFaces;
+ QCheckBox* mySetQuanta;
+ SMESHGUI_SpinBox* myQuanta;
StdMeshersGUI::GridAxisTab* myAxisTabs[3];
QGroupBox* myFixedPointGrp;
<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>
<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>
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
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
--- /dev/null
+#!/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()
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