// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
-// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
//
//
//
#include "SMESH_Mesh.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_Algo.hxx"
+#include "SMESHDS_SubMesh.hxx"
#include "utilities.h"
*/
//=============================================================================
-StdMeshers_AutomaticLength::StdMeshers_AutomaticLength(int hypId, int studyId,
- SMESH_Gen * gen):SMESH_Hypothesis(hypId, studyId, gen)
+StdMeshers_AutomaticLength::StdMeshers_AutomaticLength(int hypId, int studyId, SMESH_Gen * gen)
+ :SMESH_Hypothesis(hypId, studyId, gen)
{
_name = "AutomaticLength";
_param_algo_dim = 1; // is used by SMESH_Regular_1D
_mesh = 0;
+ _fineness = 0;
}
//=============================================================================
{
}
+//================================================================================
+/*!
+ * \brief Set Fineness
+ * \param theFineness - The Fineness value [0.0-1.0],
+ * 0 - coarse mesh
+ * 1 - fine mesh
+ *
+ * Raise if theFineness is out of range
+ * The "Initial Number of Elements on the Shortest Edge" (S0)
+ * is divided by (0.5 + 4.5 x theFineness)
+ */
+//================================================================================
+
+const double theCoarseConst = 0.5;
+const double theFineConst = 4.5;
+
+void StdMeshers_AutomaticLength::SetFineness(double theFineness)
+ throw(SALOME_Exception)
+{
+ if ( theFineness < 0.0 || theFineness > 1.0 )
+ throw SALOME_Exception(LOCALIZED("theFineness is out of range [0.0-1.0]"));
+
+ if ( _fineness != theFineness )
+ {
+ NotifySubMeshesHypothesisModification();
+ _fineness = theFineness;
+ }
+}
+
//================================================================================
/*!
* \brief Return pointer to TopoDS_TShape
*/
//================================================================================
-static void computeLengths( const SMESH_Mesh* theMesh,
+static void computeLengths( SMESHDS_Mesh* aMesh,
map<const TopoDS_TShape*, double> & theTShapeToLengthMap)
{
theTShapeToLengthMap.clear();
- SMESHDS_Mesh* aMesh = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
TopoDS_Shape aMainShape = aMesh->ShapeToMesh();
// Find length of longest and shortest edge
for ( int i = 1; i <= edgeMap.Extent(); ++i )
{
TopoDS_Edge edge = TopoDS::Edge( edgeMap(i) );
+ //if ( BRep_Tool::Degenerated( edge )) continue;
+
Standard_Real L = SMESH_Algo::EdgeLength( edge );
- if ( L > Lmax )
- Lmax = L;
- if ( L < Lmin )
- Lmin = L;
+ if ( L < DBL_MIN ) continue;
+
+ if ( L > Lmax ) Lmax = L;
+ if ( L < Lmin ) Lmin = L;
+
// remember i-th edge length
- theTShapeToLengthMap.insert( theTShapeToLengthMap.end(),
- make_pair( getTShape( edge ), L ));
+ theTShapeToLengthMap.insert( make_pair( getTShape( edge ), L ));
}
// Compute S0
if ( anEdge.IsNull() || anEdge.ShapeType() != TopAbs_EDGE )
throw SALOME_Exception(LOCALIZED("Bad edge shape"));
- if ( theMesh != _mesh ) {
- computeLengths( theMesh, _TShapeToLength );
+ if ( theMesh != _mesh )
+ {
+ SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* > ( theMesh )->GetMeshDS();
+ computeLengths( aMeshDS, _TShapeToLength );
_mesh = theMesh;
}
map<const TopoDS_TShape*, double>::iterator tshape_length =
_TShapeToLength.find( getTShape( anEdge ));
- ASSERT( tshape_length != _TShapeToLength.end() );
- return tshape_length->second;
+
+ if ( tshape_length == _TShapeToLength.end() )
+ return 1; // it is a dgenerated edge
+
+ return tshape_length->second / (theCoarseConst + theFineConst * _fineness);
}
//=============================================================================
ostream & StdMeshers_AutomaticLength::SaveTo(ostream & save)
{
+ save << _fineness;
return save;
}
istream & StdMeshers_AutomaticLength::LoadFrom(istream & load)
{
+ if ( ! ( load >> _fineness ))
+ load.clear(ios::badbit | load.rdstate());
return load;
}
{
return hyp.LoadFrom( load );
}
+
+//================================================================================
+/*!
+ * \brief Initialize Fineness by the mesh built on the geometry
+ * \param theMesh - the built mesh
+ * \param theShape - the geometry of interest
+ * \retval bool - true if parameter values have been successfully defined
+ */
+//================================================================================
+
+bool StdMeshers_AutomaticLength::SetParametersByMesh(const SMESH_Mesh* theMesh,
+ const TopoDS_Shape& theShape)
+{
+ if ( !theMesh || theShape.IsNull() )
+ return false;
+
+ _fineness = 0;
+
+ SMESHDS_Mesh* aMeshDS = const_cast< SMESH_Mesh* >( theMesh )->GetMeshDS();
+
+ int nbEdges = 0;
+ TopTools_IndexedMapOfShape edgeMap;
+ TopExp::MapShapes( theShape, TopAbs_EDGE, edgeMap );
+ for ( int i = 1; i <= edgeMap.Extent(); ++i )
+ {
+ const TopoDS_Edge& edge = TopoDS::Edge( edgeMap( i ));
+
+ // assure the base automatic length is stored in _TShapeToLength
+ if ( i == 1 )
+ GetLength( theMesh, edge );
+
+ // get current segment length
+ double L = SMESH_Algo::EdgeLength( edge );
+ if ( L <= DBL_MIN )
+ continue;
+ SMESHDS_SubMesh * eSubMesh = aMeshDS->MeshElements( edge );
+ if ( !eSubMesh )
+ return false;
+ int nbSeg = eSubMesh->NbElements();
+ if ( nbSeg < 1 )
+ continue;
+ double segLen = L / nbSeg;
+
+ // get segment length from _TShapeToLength
+ map<const TopoDS_TShape*, double>::iterator tshape_length =
+ _TShapeToLength.find( getTShape( edge ));
+ if ( tshape_length == _TShapeToLength.end() )
+ continue;
+ double autoLen = tshape_length->second;
+
+ // segLen = autoLen / (theCoarseConst + theFineConst * _fineness) -->
+ _fineness += ( autoLen / segLen - theCoarseConst ) / theFineConst;
+
+ ++nbEdges;
+ }
+ if ( nbEdges )
+ _fineness /= nbEdges;
+
+ if (_fineness > 1.0)
+ _fineness = 1.0;
+ else if (_fineness < 0.0)
+ _fineness = 0.0;
+
+ return nbEdges;
+}