<b>Average Length</b> hypothesis can be applied for meshing of edges
composing your geometrical object. Definition of this hypothesis
consists of setting the \b length of segments, which will split these
-edges. The points on the edges generated by these segments will
-represent nodes of your mesh. Later these nodes will be used for
-meshing of the faces abutting to these edges.
+edges, and the \b precision of rounding. The points on the edges
+generated by these segments will represent nodes of your mesh.
+Later these nodes will be used for meshing of the faces abutting to
+these edges.
+
+The \b 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.
\image html image41.gif
\image html image148.gif
-*/
\ No newline at end of file
+*/
/*!
* Sets <length> parameter value
*/
- void SetLength(in double length)
+ 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();
};
/*!
/*!
* Sets <number of segments> parameter value
*/
- void SetNumberOfSegments(in long segmentsNumber)
+ void SetNumberOfSegments(in long segmentsNumber)
raises (SALOME::SALOME_Exception);
/*!
return;
for ( int iE = 0; iE < side.NbEdges(); ++iE )
{
- // set listener and its data
+ // set listener and its data
EventListenerData * listenerData = new EventListenerData(true);
const TopoDS_Edge& edge = side.Edge( iE );
SMESH_subMesh * sm = side.GetMesh()->GetSubMesh( edge );
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
const SMDS_MeshNode * nFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS );
- if (!nFirst)
+ if (!nFirst)
return error(COMPERR_BAD_INPUT_MESH, TComm("No node on vertex ")
<<meshDS->ShapeToIndex(VFirst));
if (!nLast)
return true;
}
-
#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_EXPORT StdMeshers_LocalLength:public SMESH_Hypothesis
+class STDMESHERS_EXPORT 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
// to delete helper at exit from Compute()
std::auto_ptr<SMESH_MesherHelper> helperDeleter( myHelper );
- // get 2 shells
+ // get 2 shells
TopoDS_Solid solid = TopoDS::Solid( aShape );
TopoDS_Shell outerShell = BRepTools::OuterShell( solid );
TopoDS_Shape innerShell;
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;
// never do this way
//OSD::SetSignal( true );
- if( nbSeg<=0 )
+ if (nbSeg <= 0)
return false;
MESSAGE( "computeParamByFunc" );
int nbPnt = 1 + nbSeg;
vector<double> x(nbPnt, 0.);
- if( !buildDistribution( func, 0.0, 1.0, nbSeg, x, 1E-4 ) )
+ if (!buildDistribution(func, 0.0, 1.0, nbSeg, x, 1E-4))
return false;
MESSAGE( "Points:\n" );
char buf[1024];
- for( int i=0; i<=nbSeg; i++ )
+ for ( int i=0; i<=nbSeg; i++ )
{
sprintf( buf, "%f\n", float(x[i] ) );
MESSAGE( buf );
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, true )) {
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,
BEG_LENGTH_IND = 0,
END_LENGTH_IND = 1,
DEFLECTION_IND = 0
- };
+ };
enum IValueIndex {
NB_SEGMENTS_IND = 0,
DISTR_TYPE_IND = 1,
- CONV_MODE_IND = 2
+ CONV_MODE_IND = 2
};
enum VValueIndex {
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" )
{
*/
//================================================================================
-void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget( QWidget* w, const int ) const
+void StdMeshersGUI_StdHypothesisCreator::attuneStdWidget (QWidget* w, const int param) 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 (param == 0) // Length
+ sb->RangeStepAndValidator( VALUE_SMALL, VALUE_MAX, 1.0, 6 );
+ else // Precision
+ sb->RangeStepAndValidator( 0.0, 1.0, 0.05, 6 );
}
else if( hypType()=="Arithmetic1D" && sb )
{
msgid "SMESH_LOCAL_LENGTH_PARAM"
msgstr "Length"
+msgid "SMESH_LOCAL_LENGTH_PRECISION"
+msgstr "Precision"
+
msgid "SMESH_LOCAL_LENGTH_TITLE"
msgstr "Hypothesis Construction"
//=============================================================================
StdMeshers_LocalLength_i::StdMeshers_LocalLength_i( PortableServer::POA_ptr thePOA,
- int theStudyId,
- ::SMESH_Gen* theGenImpl )
- : SALOME::GenericObj_i( thePOA ),
+ 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 );
}
//=============================================================================
* 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" );
{
return type == SMESH::DIM_1D;
}
-
// 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();