22394: [CEA 984] Propagation of the number of segments and propagation of the distribution

This commit is contained in:
eap 2013-12-24 12:42:43 +00:00
parent b0d030f73d
commit ebcf93e362
11 changed files with 217 additions and 66 deletions

View File

@ -483,7 +483,8 @@ module StdMeshers
};
/*!
* StdMeshers_Propagation: interface of "Propagation" hypothesis.
* StdMeshers_Propagation: interface of "Propagation of 1D Hyp. on
* Opposite Edges" hypothesis.
* Presence of this hypothesis on any edge propagates any other 1D
* hypothesis from this edge on all edges, opposite to it.
* It concerns only edges of quadrangle faces.
@ -492,6 +493,17 @@ module StdMeshers
{
};
/*!
* StdMeshers_Propagation: interface of "Propagation of Node
* Distribution on Opposite Edges" hypothesis.
* Presence of this hypothesis on any edge propagates distribution of nodes
* from this edge on all edges, opposite to it.
* It concerns only edges of quadrangle faces.
*/
interface StdMeshers_PropagOfDistribution : SMESH::SMESH_Hypothesis
{
};
/*!
* StdMeshers_QuadranglePreference: interface of "QuadranglePreference" hypothesis.
* This hypothesis is used by StdMeshers_Quadrangle_2D algorithm.

View File

@ -86,6 +86,12 @@
dim ="1"
auxiliary="true"/>
<hypothesis type ="PropagOfDistribution"
label-id ="Propagation of Node Distribution on Opposite Edges"
icon-id ="mesh_hypo_length.png"
dim ="1"
auxiliary="true"/>
<hypothesis type ="AutomaticLength"
label-id ="Automatic Length"
icon-id ="mesh_hypo_length.png"
@ -206,7 +212,7 @@
label-id ="Wire Discretisation"
icon-id ="mesh_algo_regular.png"
hypos ="Adaptive1D,LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
opt-hypos="Propagation,QuadraticMesh"
opt-hypos="Propagation,PropagOfDistribution,QuadraticMesh"
input ="VERTEX"
output ="EDGE"
dim ="1">
@ -229,7 +235,7 @@
label-id ="Composite Side Discretisation"
icon-id ="mesh_algo_regular.png"
hypos ="Adaptive1D,LocalLength,MaxLength,Arithmetic1D,StartEndLength,NumberOfSegments,Deflection1D,AutomaticLength,FixedPoints1D"
opt-hypos="Propagation,QuadraticMesh"
opt-hypos="Propagation,PropagOfDistribution,QuadraticMesh"
input ="VERTEX"
output ="EDGE"
dim ="1">

View File

@ -295,12 +295,23 @@ class StdMeshersBuilder_Segment(Mesh_Algorithm):
hyp.SetDeflection(d)
return hyp
## Defines "Propagation" hypothesis that propagates all other hypotheses on all other edges that are at
# the opposite side in case of quadrangular faces
## Defines "Propagation" hypothesis that propagates 1D hypotheses
# from an edge where this hypothesis is assigned to
# on all other edges that are at the opposite side in case of quadrangular faces
# This hypothesis should be assigned to an edge to propagate a hypothesis from.
# @ingroup l3_hypos_additi
def Propagation(self):
return self.Hypothesis("Propagation", UseExisting=1, CompareMethod=self.CompareEqualHyp)
## Defines "Propagation of Node Distribution" hypothesis that propagates
# distribution of nodes from an edge where this hypothesis is assigned to,
# to opposite edges of quadrangular faces, so that number of segments on all these
# edges will be the same, as well as relations between segment lengths.
# @ingroup l3_hypos_additi
def PropagationOfDistribution(self):
return self.Hypothesis("PropagOfDistribution", UseExisting=1,
CompareMethod=self.CompareEqualHyp)
## Defines "AutomaticLength" hypothesis
# @param fineness for the fineness [0-1]
# @param UseExisting if ==true - searches for an existing hypothesis created with the

View File

@ -64,7 +64,8 @@ namespace {
/*!
* \brief Return an edge from which hypotheses are propagated from
*/
static TopoDS_Edge GetSource(SMESH_subMesh * submesh);
static TopoDS_Edge GetSource(SMESH_subMesh * submesh,
bool& isPropagOfDistribution);
/*!
* \brief Does it's main job
*/
@ -90,23 +91,28 @@ StdMeshers_Propagation::StdMeshers_Propagation (int hypId, int studyId, SMESH_Ge
_name = GetName();
_param_algo_dim = -1; // 1D auxiliary
}
StdMeshers_PropagOfDistribution::StdMeshers_PropagOfDistribution (int hypId,
int studyId,
SMESH_Gen * gen)
: StdMeshers_Propagation(hypId, studyId, gen) { _name = GetName(); }
StdMeshers_Propagation::~StdMeshers_Propagation() {}
string StdMeshers_Propagation::GetName () { return "Propagation"; }
string StdMeshers_PropagOfDistribution::GetName () { return "PropagOfDistribution"; }
ostream & StdMeshers_Propagation::SaveTo (ostream & save) { return save; }
istream & StdMeshers_Propagation::LoadFrom (istream & load) { return load; }
ostream & operator << (ostream & save, StdMeshers_Propagation & hyp) { return hyp.SaveTo(save); }
istream & operator >> (istream & load, StdMeshers_Propagation & hyp) { return hyp.LoadFrom(load); }
bool StdMeshers_Propagation::SetParametersByMesh(const SMESH_Mesh*,
const TopoDS_Shape& ) { return false; }
bool StdMeshers_Propagation::SetParametersByDefaults(const TDefaults&,const SMESH_Mesh*) { return false; }
void StdMeshers_Propagation::SetPropagationMgr(SMESH_subMesh* subMesh) { PropagationMgr::Set( subMesh ); }
/*!
* \brief Return an edge from which hypotheses are propagated from
* \brief Return an edge from which hypotheses are propagated
*/
TopoDS_Edge StdMeshers_Propagation::GetPropagationSource(SMESH_Mesh& theMesh,
const TopoDS_Shape& theEdge)
const TopoDS_Shape& theEdge,
bool& isPropagOfDistribution)
{
return PropagationMgr::GetSource(theMesh.GetSubMeshContaining( theEdge ));
return PropagationMgr::GetSource( theMesh.GetSubMeshContaining( theEdge ),
isPropagOfDistribution);
}
//=============================================================================
@ -126,11 +132,13 @@ namespace {
struct PropagationMgrData : public EventListenerData
{
bool myForward; //!< true if a curve of edge in chain is codirected with one of source edge
bool myIsPropagOfDistribution; //!< type of Propagation hyp
PropagationMgrData( SubMeshState state=WAIT_PROPAG_HYP ): EventListenerData(true) {
myType = state; myForward = true;
myType = state; myForward = true; myIsPropagOfDistribution = false;
}
void Init() {
myType = WAIT_PROPAG_HYP; mySubMeshes.clear(); myForward = true;
myIsPropagOfDistribution = false;
}
SubMeshState State() const {
return (SubMeshState) myType;
@ -217,8 +225,13 @@ namespace {
const SMESH_Hypothesis* getProagationHyp (SMESH_Mesh& theMesh,
const TopoDS_Shape& theEdge)
{
static SMESH_HypoFilter propagHypFilter
( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ()));
static SMESH_HypoFilter propagHypFilter;
if ( propagHypFilter.IsEmpty() )
{
propagHypFilter.
Init( SMESH_HypoFilter::HasName( StdMeshers_Propagation::GetName ())).
Or ( SMESH_HypoFilter::HasName( StdMeshers_PropagOfDistribution::GetName ()));
}
return theMesh.GetHypothesis( theEdge, propagHypFilter, true );
}
//================================================================================
@ -248,6 +261,10 @@ namespace {
PropagationMgrData* chainData = getData( theMainSubMesh );
chainData->SetState( HAS_PROPAG_HYP );
if ( const SMESH_Hypothesis * propagHyp = getProagationHyp( *mesh, theMainEdge ))
chainData->myIsPropagOfDistribution =
( StdMeshers_PropagOfDistribution::GetName() == propagHyp->GetName() );
// Edge submeshes, to which the 1D hypothesis will be propagated from theMainEdge
list<SMESH_subMesh*> & chain = chainData->mySubMeshes;
chain.clear();
@ -462,25 +479,30 @@ namespace {
{
if ( findData( submesh )) return;
DBGMSG( "PropagationMgr::Set() on " << submesh->GetId() );
EventListenerData* data = new PropagationMgrData();
PropagationMgrData* data = new PropagationMgrData();
submesh->SetEventListener( getListener(), data, submesh );
const SMESH_Hypothesis * propagHyp =
getProagationHyp( *submesh->GetFather(), submesh->GetSubShape() );
if ( propagHyp )
{
data->myIsPropagOfDistribution =
( StdMeshers_PropagOfDistribution::GetName() == propagHyp->GetName() );
getListener()->ProcessEvent( SMESH_subMesh::ADD_HYP,
SMESH_subMesh::ALGO_EVENT,
submesh,
data,
propagHyp);
}
}
//================================================================================
/*!
* \brief Return an edge from which hypotheses are propagated
*/
//================================================================================
TopoDS_Edge PropagationMgr::GetSource(SMESH_subMesh * submesh)
TopoDS_Edge PropagationMgr::GetSource(SMESH_subMesh * submesh,
bool& isPropagOfDistribution)
{
if ( PropagationMgrData* data = findData( submesh )) {
if ( data->State() == IN_CHAIN ) {
@ -489,6 +511,9 @@ namespace {
TopoDS_Shape edge = sm->GetSubShape();
edge = edge.Oriented( data->myForward ? TopAbs_FORWARD : TopAbs_REVERSED );
DBGMSG( " GetSource() = edge " << sm->GetId() << " REV = " << (!data->myForward));
isPropagOfDistribution = false;
if ( PropagationMgrData* data = findData( sm ))
isPropagOfDistribution = data->myIsPropagOfDistribution;
if ( edge.ShapeType() == TopAbs_EDGE )
return TopoDS::Edge( edge );
}
@ -516,7 +541,8 @@ namespace {
return;
DBGMSG( "PropagationMgr::ProcessEvent() on " << subMesh->GetId() );
bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() );
bool isPropagHyp = ( StdMeshers_Propagation::GetName() == hyp->GetName() ||
StdMeshers_PropagOfDistribution::GetName() == hyp->GetName() );
PropagationMgrData* data = static_cast<PropagationMgrData*>( listenerData );
switch ( data->State() ) {

View File

@ -50,8 +50,6 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
virtual std::ostream & SaveTo(std::ostream & save);
virtual std::istream & LoadFrom(std::istream & load);
friend std::ostream & operator <<(std::ostream & save, StdMeshers_Propagation & hyp);
friend std::istream & operator >>(std::istream & load, StdMeshers_Propagation & hyp);
static std::string GetName ();
@ -69,7 +67,9 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
* \param theEdge - edge to which hypotheses are propagated
* \retval TopoDS_Edge - source edge, also passing orientation
*/
static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh, const TopoDS_Shape& theEdge);
static TopoDS_Edge GetPropagationSource(SMESH_Mesh& theMesh,
const TopoDS_Shape& theEdge,
bool& isPropagOfDistribution );
/*!
* \brief Initialize my parameter values by the mesh built on the geometry
@ -88,4 +88,19 @@ class STDMESHERS_EXPORT StdMeshers_Propagation:public SMESH_Hypothesis
virtual bool SetParametersByDefaults(const TDefaults& dflts, const SMESH_Mesh* theMesh=0);
};
// =======================================================================
/*!
* \brief Propagation Of Distribution hypothesis
*/
// =======================================================================
class STDMESHERS_EXPORT StdMeshers_PropagOfDistribution: public StdMeshers_Propagation
{
public:
StdMeshers_PropagOfDistribution(int hypId, int studyId, SMESH_Gen * gen);
static std::string GetName();
};
#endif

View File

@ -92,9 +92,10 @@ StdMeshers_Regular_1D::StdMeshers_Regular_1D(int hypId, int studyId,
_compatibleHypothesis.push_back("FixedPoints1D");
_compatibleHypothesis.push_back("AutomaticLength");
_compatibleHypothesis.push_back("Adaptive1D");
_compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
_compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
// auxiliary:
_compatibleHypothesis.push_back("QuadraticMesh");
_compatibleHypothesis.push_back("Propagation");
_compatibleHypothesis.push_back("PropagOfDistribution");
}
//=============================================================================
@ -616,6 +617,58 @@ bool StdMeshers_Regular_1D::computeInternalParameters(SMESH_Mesh & theMesh,
double f = theFirstU, l = theLastU;
// Propagation Of Distribution
//
if ( !_mainEdge.IsNull() && _isPropagOfDistribution )
{
TopoDS_Edge mainEdge = TopoDS::Edge( _mainEdge ); // should not be a reference!
_gen->Compute( theMesh, mainEdge, /*aShapeOnly=*/true, /*anUpward=*/true);
SMESHDS_SubMesh* smDS = theMesh.GetMeshDS()->MeshElements( mainEdge );
if ( !smDS )
return error("No mesh on the source edge of Propagation Of Distribution");
if ( smDS->NbNodes() < 1 )
return true; // 1 segment
vector< double > mainEdgeParams;
if ( ! SMESH_Algo::GetNodeParamOnEdge( theMesh.GetMeshDS(), mainEdge, mainEdgeParams ))
return error("Bad node parameters on the source edge of Propagation Of Distribution");
vector< double > segLen( mainEdgeParams.size() - 1 );
double totalLen = 0;
BRepAdaptor_Curve mainEdgeCurve( mainEdge );
for ( size_t i = 1; i < mainEdgeParams.size(); ++i )
{
segLen[ i-1 ] = GCPnts_AbscissaPoint::Length( mainEdgeCurve,
mainEdgeParams[i-1],
mainEdgeParams[i]);
totalLen += segLen[ i-1 ];
}
for ( size_t i = 0; i < segLen.size(); ++i )
segLen[ i ] *= theLength / totalLen;
size_t iSeg = theReverse ? segLen.size()-1 : 0;
size_t dSeg = theReverse ? -1 : +1;
double param = theFirstU;
int nbParams = 0;
for ( int i = 0, nb = segLen.size()-1; i < nb; ++i, iSeg += dSeg )
{
GCPnts_AbscissaPoint Discret( theC3d, segLen[ iSeg ], param );
if ( !Discret.IsDone() ) break;
param = Discret.Parameter();
theParams.push_back( param );
++nbParams;
}
if ( nbParams != segLen.size()-1 )
return error( SMESH_Comment("Can't divide into ") << segLen.size() << " segements");
compensateError( segLen[ theReverse ? segLen.size()-1 : 0 ],
segLen[ theReverse ? 0 : segLen.size()-1 ],
f, l, theLength, theC3d, theParams, true );
return true;
}
switch( _hypType )
{
case LOCAL_LENGTH:
@ -1231,7 +1284,8 @@ StdMeshers_Regular_1D::GetUsedHypothesis(SMESH_Mesh & aMesh,
if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
{
// Check, if propagated from some other edge
_mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape );
_mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape,
_isPropagOfDistribution );
if ( !_mainEdge.IsNull() )
{
// Propagation of 1D hypothesis from <aMainEdge> on this edge;

View File

@ -140,6 +140,7 @@ protected:
// a source of propagated hypothesis, is set by CheckHypothesis()
// always called before Compute()
TopoDS_Shape _mainEdge;
bool _isPropagOfDistribution;
};
#endif

View File

@ -231,6 +231,10 @@
<source>ICON_SMESH_TREE_HYPO_Propagation</source>
<translation>mesh_tree_hypo_length.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_HYPO_PropagOfDistribution</source>
<translation>mesh_tree_hypo_length.png</translation>
</message>
<message>
<source>ICON_SMESH_TREE_HYPO_QuadranglePreference</source>
<translation>mesh_tree_algo_quad.png</translation>

View File

@ -23,7 +23,6 @@
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : StdMeshers_Propagation_i.cxx
// Module : SMESH
// $Header$
//
#include "StdMeshers_Propagation_i.hxx"
#include "SMESH_Gen.hxx"
@ -52,31 +51,6 @@ StdMeshers_Propagation_i::StdMeshers_Propagation_i (PortableServer::POA_ptr theP
theGenImpl);
}
//=============================================================================
/*!
* StdMeshers_Propagation_i::~StdMeshers_Propagation_i
*
* Destructor
*/
//=============================================================================
StdMeshers_Propagation_i::~StdMeshers_Propagation_i()
{
MESSAGE( "StdMeshers_Propagation_i::~StdMeshers_Propagation_i" );
}
//=============================================================================
/*!
* StdMeshers_Propagation_i::GetImpl
*
* Get implementation
*/
//=============================================================================
::StdMeshers_Propagation* StdMeshers_Propagation_i::GetImpl()
{
MESSAGE( "StdMeshers_Propagation_i::GetImpl" );
return ( ::StdMeshers_Propagation* )myBaseImpl;
}
//================================================================================
/*!
* \brief Verify whether hypothesis supports given entity type
@ -91,3 +65,36 @@ CORBA::Boolean StdMeshers_Propagation_i::IsDimSupported( SMESH::Dimension type )
return type == SMESH::DIM_1D;
}
//=============================================================================
/*!
* StdMeshers_PropagOfDistribution_i::StdMeshers_PropagOfDistribution_i
*
* Constructor
*/
//=============================================================================
StdMeshers_PropagOfDistribution_i::
StdMeshers_PropagOfDistribution_i (PortableServer::POA_ptr thePOA,
int theStudyId,
::SMESH_Gen* theGenImpl )
: SALOME::GenericObj_i( thePOA ),
SMESH_Hypothesis_i( thePOA )
{
myBaseImpl = new ::StdMeshers_PropagOfDistribution(theGenImpl->GetANewId(),
theStudyId,
theGenImpl);
}
//================================================================================
/*!
* \brief Verify whether hypothesis supports given entity type
* \param type - dimension (see SMESH::Dimension enumeration)
* \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise
*
* Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration)
*/
//================================================================================
CORBA::Boolean StdMeshers_PropagOfDistribution_i::IsDimSupported( SMESH::Dimension type )
{
return type == SMESH::DIM_1D;
}

View File

@ -23,7 +23,6 @@
// SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
// File : StdMeshers_Propagation_i.hxx
// Module : SMESH
// $Header$
//
#ifndef _SMESH_PROPAGATION_I_HXX_
#define _SMESH_PROPAGATION_I_HXX_
@ -41,6 +40,7 @@ class SMESH_Gen;
// ======================================================
// Propagation hypothesis
// ======================================================
class STDMESHERS_I_EXPORT StdMeshers_Propagation_i:
public virtual POA_StdMeshers::StdMeshers_Propagation,
public virtual SMESH_Hypothesis_i
@ -50,11 +50,24 @@ public:
StdMeshers_Propagation_i (PortableServer::POA_ptr thePOA,
int theStudyId,
::SMESH_Gen* theGenImpl);
// Destructor
virtual ~StdMeshers_Propagation_i();
// Get implementation
::StdMeshers_Propagation* GetImpl();
// Verify whether hypothesis supports given entity type
CORBA::Boolean IsDimSupported( SMESH::Dimension type );
};
// ======================================================
// Propagation of Distribution hypothesis
// ======================================================
class STDMESHERS_I_EXPORT StdMeshers_PropagOfDistribution_i:
public virtual POA_StdMeshers::StdMeshers_PropagOfDistribution,
public virtual SMESH_Hypothesis_i
{
public:
// Constructor
StdMeshers_PropagOfDistribution_i (PortableServer::POA_ptr thePOA,
int theStudyId,
::SMESH_Gen* theGenImpl);
// Verify whether hypothesis supports given entity type
CORBA::Boolean IsDimSupported( SMESH::Dimension type );

View File

@ -136,6 +136,8 @@ STDMESHERS_I_EXPORT
aCreator = new StdHypothesisCreator_i<StdMeshers_NotConformAllowed_i>;
else if (strcmp(aHypName, "Propagation") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_Propagation_i>;
else if (strcmp(aHypName, "PropagOfDistribution") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_PropagOfDistribution_i>;
else if (strcmp(aHypName, "MaxElementArea") == 0)
aCreator = new StdHypothesisCreator_i<StdMeshers_MaxElementArea_i>;
else if (strcmp(aHypName, "MaxElementVolume") == 0)