\r
<h3><a name=Average_length>Average Length hypothesis</a></h3>\r
\r
-<p><span style="font-weight: bold;"><B>Average Length </B></span>hypothesis can \r
- be applied for meshing of edges composing your geometrical object. Definition \r
- of this hypothesis consists of setting the <span style="font-weight: bold;"><B>length</B></span> \r
- of segments, which will split these edges. The points on the edges generated \r
- by these segments will represent nodes of your mesh. Later these nodes \r
- will be used for meshing of the faces abutting to these edges.</p>\r
+<p><span style="font-weight: bold;"><B>Average Length </B></span>hypothesis\r
+ can be applied for meshing of edges composing your geometrical\r
+ object. Definition of this hypothesis consists of setting the\r
+ <span style="font-weight: bold;"><B>length </B></span>of segments,\r
+ which will split these edges, and the <span style="font-weight:bold;"><B>precision </B></span>\r
+ of rounding. The points on the edges generated by these segments will represent nodes of your\r
+ mesh. Later these nodes will be used for meshing of the faces abutting\r
+ to these edges.</p>\r
+\r
+<p> </p>\r
+\r
+<p>The <span style="font-weight: bold;"><B>precision </B></span>\r
+ parameter is used to allow rounding a number of\r
+ segments, calculated from the edge length and average length of\r
+ segment, to the lower integer, if this value outstands from it in\r
+ bounds of the precision. Otherwise, the number of segments is rounded\r
+ to the higher integer. Use value 0.5 to provide rounding to the\r
+ nearest integer, 1.0 for the lower integer, 0.0 for the higher\r
+ integer. Default value is 1e-07.</p>\r
\r
<p> </p>\r
\r
*/
void SetLength(in double length)
raises (SALOME::SALOME_Exception);
-
+
+ /*!
+ * Sets <precision> parameter value
+ *
+ * Precision parameter is used to allow rounding a number of segments,
+ * calculated from the edge length and average length of segment,
+ * to the lower integer, if this value outstands from it in bounds of the precision.
+ * Otherwise, the number of segments is rounded to the higher integer.
+ * Use value 0.5 to provide rounding to the nearest integer,
+ * 1.0 for the lower integer, 0.0 for the higher integer.
+ * Default value is 1e-07. In old studies, restored from file,
+ * this value will be set to zero, what corresponds to the old behaviour.
+ */
+ void SetPrecision(in double precision)
+ raises (SALOME::SALOME_Exception);
+
/*!
* Returns <length> parameter value
*/
double GetLength();
+
+ /*!
+ * Returns <precision> parameter value
+ */
+ double GetPrecision();
};
/*!
auto_ptr< BRepAdaptor_CompCurve > C3d ( side->GetCurve3d() );
double f = C3d->FirstParameter(), l = C3d->LastParameter();
list< double > params;
- if ( !computeInternalParameters ( *C3d, side->Length(), f, l, params, false ))
+ if ( !computeInternalParameters ( aMesh, *C3d, side->Length(), f, l, params, false ))
return false;
// Redistribute parameters near ends
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
+#include <Precision.hxx>
using namespace std;
:SMESH_Hypothesis(hypId, studyId, gen)
{
_length = 1.;
+ _precision = Precision::Confusion();
_name = "LocalLength";
_param_algo_dim = 1; // is used by SMESH_Regular_1D
}
void StdMeshers_LocalLength::SetLength(double length) throw(SALOME_Exception)
{
- double oldLength = _length;
- if (length <= 0)
- throw SALOME_Exception(LOCALIZED("length must be positive"));
- _length = length;
- if (oldLength != _length)
- NotifySubMeshesHypothesisModification();
+ double oldLength = _length;
+ if (length <= 0)
+ throw SALOME_Exception(LOCALIZED("length must be positive"));
+ _length = length;
+ const double precision = 1e-7;
+ if (fabs(oldLength - _length) > precision)
+ NotifySubMeshesHypothesisModification();
}
//=============================================================================
double StdMeshers_LocalLength::GetLength() const
{
- return _length;
+ return _length;
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+void StdMeshers_LocalLength::SetPrecision (double thePrecision) throw(SALOME_Exception)
+{
+ double oldPrecision = _precision;
+ if (_precision < 0)
+ throw SALOME_Exception(LOCALIZED("precision cannot be negative"));
+ _precision = thePrecision;
+ const double precision = 1e-8;
+ if (fabs(oldPrecision - _precision) > precision)
+ NotifySubMeshesHypothesisModification();
+}
+
+//=============================================================================
+/*!
+ *
+ */
+//=============================================================================
+double StdMeshers_LocalLength::GetPrecision() const
+{
+ return _precision;
}
//=============================================================================
ostream & StdMeshers_LocalLength::SaveTo(ostream & save)
{
- save << this->_length;
+ save << this->_length << " " << this->_precision;
return save;
}
{
bool isOK = true;
double a;
+
isOK = (load >> a);
if (isOK)
this->_length = a;
else
load.clear(ios::badbit | load.rdstate());
+
+ isOK = (load >> a);
+ if (isOK)
+ this->_precision = a;
+ else
+ {
+ load.clear(ios::badbit | load.rdstate());
+ // old format, without precision
+ _precision = 0.;
+ }
+
return load;
}
if ( nbEdges )
_length /= nbEdges;
+ _precision = Precision::Confusion();
+
return nbEdges;
}
#include "SMESH_Hypothesis.hxx"
#include "Utils_SALOME_Exception.hxx"
-class StdMeshers_LocalLength:public SMESH_Hypothesis
+class StdMeshers_LocalLength: public SMESH_Hypothesis
{
public:
StdMeshers_LocalLength(int hypId, int studyId, SMESH_Gen * gen);
virtual ~ StdMeshers_LocalLength();
void SetLength(double length) throw(SALOME_Exception);
+ void SetPrecision(double precision) throw(SALOME_Exception);
double GetLength() const;
+ double GetPrecision() const;
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);
protected:
double _length;
+ double _precision;
};
#endif
BRepAdaptor_Curve C3D(edge);
double f = C3D.FirstParameter(), l = C3D.LastParameter();
list< double > params;
- if ( !StdMeshers_Regular_1D::computeInternalParameters( C3D, len, f, l, params, false ))
+ if ( !StdMeshers_Regular_1D::computeInternalParameters( aMesh, C3D, len, f, l, params, false ))
return error("StdMeshers_Regular_1D failed to compute layers distribution");
positions.clear();
const StdMeshers_LocalLength * hyp =
dynamic_cast <const StdMeshers_LocalLength * >(theHyp);
ASSERT(hyp);
- _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength();
+ //_value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength();
+ _value[ BEG_LENGTH_IND ] = hyp->GetLength();
+ _value[ END_LENGTH_IND ] = hyp->GetPrecision();
ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
_hypType = LOCAL_LENGTH;
aStatus = SMESH_Hypothesis::HYP_OK;
StdMeshers_AutomaticLength * hyp = const_cast<StdMeshers_AutomaticLength *>
(dynamic_cast <const StdMeshers_AutomaticLength * >(theHyp));
ASSERT(hyp);
- _value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
+ //_value[ BEG_LENGTH_IND ] = _value[ END_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
+ _value[ BEG_LENGTH_IND ] = hyp->GetLength( &aMesh, aShape );
+ _value[ END_LENGTH_IND ] = Precision::Confusion(); // ?? or set to zero?
ASSERT( _value[ BEG_LENGTH_IND ] > 0 );
_hypType = LOCAL_LENGTH;
aStatus = SMESH_Hypothesis::HYP_OK;
std::swap( algo._value[ BEG_LENGTH_IND ], algo._value[ END_LENGTH_IND ]);
}
list<double> params;
- if ( algo.computeInternalParameters( theC3d, L, from, to, params, false ))
+ if ( algo.computeInternalParameters( theMesh, theC3d, L, from, to, params, false ))
{
if ( isEnd1 ) params.reverse();
while ( 1 + nHalf-- )
*
*/
//=============================================================================
-bool StdMeshers_Regular_1D::computeInternalParameters(Adaptor3d_Curve& theC3d,
+bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
+ Adaptor3d_Curve& theC3d,
double theLength,
double theFirstU,
double theLastU,
list<double> & theParams,
- const bool theReverse)
+ const bool theReverse,
+ bool theConsiderPropagation)
{
theParams.clear();
{
// Local Length hypothesis
double nbseg = ceil(theLength / _value[ BEG_LENGTH_IND ]); // integer sup
+
+ // NPAL17873:
+ bool isFound = false;
+ if (theConsiderPropagation && !_mainEdge.IsNull()) // propagated from some other edge
+ {
+ // Advanced processing to assure equal number of segments in case of Propagation
+ SMESH_subMesh* sm = theMesh.GetSubMeshContaining(_mainEdge);
+ if (sm) {
+ bool computed = sm->IsMeshComputed();
+ if (!computed) {
+ if (sm->GetComputeState() == SMESH_subMesh::READY_TO_COMPUTE) {
+ sm->ComputeStateEngine(SMESH_subMesh::COMPUTE);
+ computed = sm->IsMeshComputed();
+ }
+ }
+ if (computed) {
+ SMESHDS_SubMesh* smds = sm->GetSubMeshDS();
+ int nb_segments = smds->NbElements();
+ if (nbseg - 1 <= nb_segments && nb_segments <= nbseg + 1) {
+ isFound = true;
+ nbseg = nb_segments;
+ }
+ }
+ }
+ }
+ if (!isFound) // not found by meshed edge in the propagation chain, use precision
+ {
+ double aPrecision = _value[ END_LENGTH_IND ];
+ double nbseg_prec = ceil((theLength / _value[ BEG_LENGTH_IND ]) - aPrecision);
+ if (nbseg_prec == (nbseg - 1)) nbseg--;
+ }
+
if (nbseg <= 0)
nbseg = 1; // degenerated edge
eltSize = theLength / nbseg;
*/
//=============================================================================
-bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
+bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
{
if ( _hypType == NONE )
return false;
- SMESHDS_Mesh * meshDS = aMesh.GetMeshDS();
+ SMESHDS_Mesh * meshDS = theMesh.GetMeshDS();
- const TopoDS_Edge & EE = TopoDS::Edge(aShape);
+ const TopoDS_Edge & EE = TopoDS::Edge(theShape);
TopoDS_Edge E = TopoDS::Edge(EE.Oriented(TopAbs_FORWARD));
int shapeID = meshDS->ShapeToIndex( E );
BRepAdaptor_Curve C3d( E );
double length = EdgeLength( E );
- if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
+ if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed )) {
return false;
}
- redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
+ redistributeNearVertices( theMesh, C3d, length, params, VFirst, VLast );
// edge extrema (indexes : 1 & NbPoints) already in SMDS (TopoDS_Vertex)
// only internal nodes receive an edge position with param on curve
protected:
- virtual bool computeInternalParameters (Adaptor3d_Curve & theC3d,
- double theLength,
- double theFirstU,
- double theLastU,
- std::list< double > & theParameters,
- const bool theReverse);
+ virtual bool computeInternalParameters (SMESH_Mesh & theMesh,
+ Adaptor3d_Curve & theC3d,
+ double theLength,
+ double theFirstU,
+ double theLastU,
+ std::list<double> & theParameters,
+ const bool theReverse,
+ bool theConsiderPropagation = false);
virtual void redistributeNearVertices (SMESH_Mesh & theMesh,
Adaptor3d_Curve & theC3d,
StdMeshers::StdMeshers_LocalLength::_narrow( hypothesis() );
h->SetLength( params[0].myValue.toDouble() );
+ h->SetPrecision( params[1].myValue.toDouble() );
}
else if( hypType()=="SegmentLengthAroundVertex" )
{
item.myName = tr("SMESH_LOCAL_LENGTH_PARAM");
item.myValue = h->GetLength();
p.append( item );
+ item.myName = tr("SMESH_LOCAL_LENGTH_PRECISION");
+ item.myValue = h->GetPrecision();
+ p.append( item );
}
else if( hypType()=="SegmentLengthAroundVertex" )
{
* \param int - parameter index
*/
//================================================================================
-
void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget( QWidget* w, const int ) const
-{
+{
SMESHGUI_SpinBox* sb = w->inherits( "SMESHGUI_SpinBox" ) ? ( SMESHGUI_SpinBox* )w : 0;
if( hypType()=="LocalLength" && sb )
{
- sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
+ if (sb->name() == tr("SMESH_LOCAL_LENGTH_PARAM"))
+ sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
+ else if (sb->name() == tr("SMESH_LOCAL_LENGTH_PRECISION"))
+ sb->RangeStepAndValidator( 0.0, 1.0, 0.05, 6 );
}
else if( hypType()=="Arithmetic1D" && sb )
{
msgid "SMESH_LOCAL_LENGTH_HYPOTHESIS"
msgstr "Average Length"
+msgid "SMESH_LOCAL_LENGTH_PRECISION"
+msgstr "Precision"
+
msgid "SMESH_LOCAL_LENGTH_PARAM"
msgstr "Length"
* Constructor
*/
//=============================================================================
-
StdMeshers_LocalLength_i::StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA,
- int theStudyId,
- ::SMESH_Gen* theGenImpl )
+ int theStudyId,
+ ::SMESH_Gen* theGenImpl )
: SALOME::GenericObj_i( thePOA ),
SMESH_Hypothesis_i( thePOA )
{
MESSAGE( "StdMeshers_LocalLength_i::StdMeshers_LocalLength_i" );
myBaseImpl = new ::StdMeshers_LocalLength( theGenImpl->GetANewId(),
- theStudyId,
- theGenImpl );
+ theStudyId,
+ theGenImpl );
}
//=============================================================================
* Destructor
*/
//=============================================================================
-
StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i()
{
MESSAGE( "StdMeshers_LocalLength_i::~StdMeshers_LocalLength_i" );
* Set length
*/
//=============================================================================
-
void StdMeshers_LocalLength_i::SetLength( CORBA::Double theLength )
throw ( SALOME::SALOME_Exception )
{
SMESH::TPythonDump() << _this() << ".SetLength( " << theLength << " )";
}
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::SetPrecision
+ *
+ * Set length
+ */
+//=============================================================================
+void StdMeshers_LocalLength_i::SetPrecision( CORBA::Double thePrecision )
+ throw ( SALOME::SALOME_Exception )
+{
+ MESSAGE( "StdMeshers_LocalLength_i::SetPrecision" );
+ ASSERT( myBaseImpl );
+ try {
+ this->GetImpl()->SetPrecision( thePrecision );
+ }
+ catch ( SALOME_Exception& S_ex ) {
+ THROW_SALOME_CORBA_EXCEPTION( S_ex.what(),
+ SALOME::BAD_PARAM );
+ }
+
+ // Update Python script
+ SMESH::TPythonDump() << _this() << ".SetPrecision( " << thePrecision << " )";
+}
+
//=============================================================================
/*!
* StdMeshers_LocalLength_i::GetLength
* Get length
*/
//=============================================================================
-
CORBA::Double StdMeshers_LocalLength_i::GetLength()
{
MESSAGE( "StdMeshers_LocalLength_i::GetLength" );
return this->GetImpl()->GetLength();
}
+//=============================================================================
+/*!
+ * StdMeshers_LocalLength_i::GetPrecision
+ *
+ * Get precision
+ */
+//=============================================================================
+CORBA::Double StdMeshers_LocalLength_i::GetPrecision()
+{
+ MESSAGE( "StdMeshers_LocalLength_i::GetPrecision" );
+ ASSERT( myBaseImpl );
+ return this->GetImpl()->GetPrecision();
+}
+
//=============================================================================
/*!
* StdMeshers_LocalLength_i::GetImpl
* Get implementation
*/
//=============================================================================
-
::StdMeshers_LocalLength* StdMeshers_LocalLength_i::GetImpl()
{
MESSAGE( "StdMeshers_LocalLength_i::GetImpl" );
// Set length
void SetLength( CORBA::Double theLength )
throw ( SALOME::SALOME_Exception );
+ // Set precision
+ void SetPrecision( CORBA::Double thePrecision )
+ throw ( SALOME::SALOME_Exception );
+
// Get length
CORBA::Double GetLength();
+ // Get precision
+ CORBA::Double GetPrecision();
// Get implementation
::StdMeshers_LocalLength* GetImpl();