#include "StdMeshers_Deflection1D.hxx"
#include "StdMeshers_AutomaticLength.hxx"
#include "StdMeshers_SegmentLengthAroundVertex.hxx"
+#include "StdMeshers_Propagation.hxx"
#include "SMESH_Gen.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_HypoFilter.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_subMeshEventListener.hxx"
+#include "SMESH_Comment.hxx"
#include "SMDS_MeshElement.hxx"
#include "SMDS_MeshNode.hxx"
#include <BRepAdaptor_Curve.hxx>
#include <BRep_Tool.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopExp_Explorer.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GCPnts_UniformAbscissa.hxx>
#include <GCPnts_UniformDeflection.hxx>
#include <Precision.hxx>
-
-#include <Standard_ErrorHandler.hxx>
-#include <Standard_Failure.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
#include <string>
-//#include <math.h>
using namespace std;
_compatibleHypothesis.push_back("AutomaticLength");
_compatibleHypothesis.push_back("QuadraticMesh"); // auxiliary !!!
+ _compatibleHypothesis.push_back("Propagation"); // auxiliary !!!
}
//=============================================================================
}
static bool computeParamByFunc(Adaptor3d_Curve& C3d, double first, double last,
- double length, bool theReverse,
+ double length, bool theReverse,
int nbSeg, Function& func,
list<double>& theParams)
{
sprintf( buf, "%f\n", float(x[i] ) );
MESSAGE( buf );
}
-
+
// apply parameters in range [0,1] to the space of the curve
int i, nPar = theParams.size();
if ( a1 + an < length && nPar > 1 )
{
+ bool reverse = ( U1 > Un );
+ GCPnts_AbscissaPoint Discret(C3d, reverse ? an : -an, Un);
+ if ( !Discret.IsDone() )
+ return;
+ double Utgt = Discret.Parameter(); // target value of the last parameter
list<double>::reverse_iterator itU = theParams.rbegin();
- double Ul = *itU++;
- // dist from the last point to the edge end <Un>, it should be equal to <an>
- double Ln = GCPnts_AbscissaPoint::Length( C3d, Ul, Un );
- double dLn = an - Ln; // signed error of <an>
- if ( Abs( dLn ) <= Precision::Confusion() )
+ double Ul = *itU++; // real value of the last parameter
+ double dUn = Utgt - Ul; // parametric error of <an>
+ if ( Abs(dUn) <= Precision::Confusion() )
return;
double dU = Abs( Ul - *itU ); // parametric length of the last but one segment
- double dUn = dLn * Abs( Un - U1 ) / length; // parametric error of <an>
- if ( adjustNeighbors2an || dUn < 0.5 * dU ) { // last segment is a bit shorter than it should
- dUn = -dUn; // move the last parameter to the edge beginning
+ if ( adjustNeighbors2an || Abs(dUn) < 0.5 * dU ) { // last segment is a bit shorter than it should
+ // move the last parameter to the edge beginning
}
else { // last segment is much shorter than it should -> remove the last param and
theParams.pop_back(); nPar--; // move the rest points toward the edge end
- Ln = GCPnts_AbscissaPoint::Length( C3d, theParams.back(), Un );
- dUn = ( an - Ln ) * Abs( Un - U1 ) / length;
- if ( dUn < 0.5 * dU )
- dUn = -dUn;
+ dUn = Utgt - theParams.back();
}
- bool reverse = ( U1 > Un );
- if ( reverse )
- dUn = -dUn;
double q = dUn / ( nPar - 1 );
if ( !adjustNeighbors2an ) {
double sign = reverse ? -1 : 1;
double prevU = theParams.back();
itU = theParams.rbegin();
- for ( ++itU, i = 1; i < nPar; ++itU, i++ ) {
+ for ( ++itU, i = 2; i < nPar; ++itU, i++ ) {
double newU = *itU + dUn;
if ( newU*sign < prevU*sign ) {
prevU = *itU = newU;
*/
//================================================================================
-struct VertexEventListener : public SMESH_subMeshEventListener
-{
- VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
- {}
- /*!
- * \brief Clean mesh on edges
- * \param event - algo_event or compute_event itself (of SMESH_subMesh)
- * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
- * \param subMesh - the submesh where the event occures
- */
- void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
- EventListenerData*, SMESH_Hypothesis*)
- {
- if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
- {
- subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
- }
- }
-}; // struct VertexEventListener
+// struct VertexEventListener : public SMESH_subMeshEventListener
+// {
+// VertexEventListener():SMESH_subMeshEventListener(0) // won't be deleted by submesh
+// {}
+// /*!
+// * \brief Clean mesh on edges
+// * \param event - algo_event or compute_event itself (of SMESH_subMesh)
+// * \param eventType - ALGO_EVENT or COMPUTE_EVENT (of SMESH_subMesh)
+// * \param subMesh - the submesh where the event occures
+// */
+// void ProcessEvent(const int event, const int eventType, SMESH_subMesh* subMesh,
+// EventListenerData*, const SMESH_Hypothesis*)
+// {
+// if ( eventType == SMESH_subMesh::ALGO_EVENT) // all algo events
+// {
+// subMesh->ComputeStateEngine( SMESH_subMesh::MODIF_ALGO_STATE );
+// }
+// }
+// }; // struct VertexEventListener
//=============================================================================
/*!
void StdMeshers_Regular_1D::SetEventListener(SMESH_subMesh* subMesh)
{
- static VertexEventListener listener;
- const map < int, SMESH_subMesh * >& vSMs = subMesh->DependsOn();
- map < int, SMESH_subMesh * >::const_iterator itsub;
- for (itsub = vSMs.begin(); itsub != vSMs.end(); itsub++)
- {
- subMesh->SetEventListener( &listener, 0, itsub->second );
- }
+// static VertexEventListener listener;
+// SMESH_subMeshIteratorPtr smIt = subMesh->getDependsOnIterator(false,false);
+// while (smIt->more()) {
+// subMesh->SetEventListener( &listener, 0, smIt->next() );
+// }
+ StdMeshers_Propagation::SetPropagationMgr( subMesh );
}
//=============================================================================
StdMeshers_Regular_1D::getVertexHyp(SMESH_Mesh & theMesh,
const TopoDS_Vertex & theV)
{
- static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentLengthAroundVertex"));
- const SMESH_Hypothesis * hyp = theMesh.GetHypothesis( theV, filter, true );
- return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hyp );
+ static SMESH_HypoFilter filter( SMESH_HypoFilter::HasName("SegmentAroundVertex_0D"));
+ if ( const SMESH_Hypothesis * h = theMesh.GetHypothesis( theV, filter, true ))
+ {
+ SMESH_Algo* algo = const_cast< SMESH_Algo* >( static_cast< const SMESH_Algo* > ( h ));
+ const list <const SMESHDS_Hypothesis *> & hypList = algo->GetUsedHypothesis( theMesh, theV, 0 );
+ if ( !hypList.empty() && string("SegmentLengthAroundVertex") == hypList.front()->GetName() )
+ return static_cast<const StdMeshers_SegmentLengthAroundVertex*>( hypList.front() );
+ }
+ return 0;
}
//================================================================================
double theLength,
std::list< double > & theParameters,
const TopoDS_Vertex & theVf,
- const TopoDS_Vertex & theVl) const
+ const TopoDS_Vertex & theVl)
{
double f = theC3d.FirstParameter(), l = theC3d.LastParameter();
int nPar = theParameters.size();
double vertexLength = hyp->GetLength();
if ( vertexLength > theLength / 2.0 )
continue;
- if ( isEnd1 ) {
+ if ( isEnd1 ) { // to have a segment of interest at end of theParameters
theParameters.reverse();
std::swap( f, l );
}
- if ( _hypType == NB_SEGMENTS || nPar < 5 )
+ if ( _hypType == NB_SEGMENTS )
{
compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
}
+ else if ( nPar <= 3 )
+ {
+ if ( !isEnd1 )
+ vertexLength = -vertexLength;
+ GCPnts_AbscissaPoint Discret(theC3d, vertexLength, l);
+ if ( Discret.IsDone() ) {
+ if ( nPar == 0 )
+ theParameters.push_back( Discret.Parameter());
+ else {
+ double L = GCPnts_AbscissaPoint::Length( theC3d, theParameters.back(), l);
+ if ( vertexLength < L / 2.0 )
+ theParameters.push_back( Discret.Parameter());
+ else
+ compensateError(0, vertexLength, f, l, theLength, theC3d, theParameters, true );
+ }
+ }
+ }
else
{
// recompute params between the last segment and a middle one.
double theFirstU,
double theLastU,
list<double> & theParams,
- const bool theReverse) const
+ const bool theReverse)
{
theParams.clear();
}
GCPnts_UniformAbscissa Discret(theC3d, eltSize, f, l);
if ( !Discret.IsDone() )
- return false;
+ return error( "GCPnts_UniformAbscissa failed");
int NbPoints = Discret.NbPoints();
for ( int i = 2; i < NbPoints; i++ )
GCPnts_AbscissaPoint Discret( theC3d, eltSize, param );
if ( !Discret.IsDone() ) break;
param = Discret.Parameter();
- if ( param > f && param < l )
+ if ( f < param && param < l )
theParams.push_back( param );
else
break;
eltSize *= q;
}
compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
+ if (theReverse) theParams.reverse(); // NPAL18025
return true;
}
eltSize += q;
}
compensateError( a1, an, U1, Un, theLength, theC3d, theParams );
+ if (theReverse) theParams.reverse(); // NPAL18025
return true;
}
theParams.push_back( param );
}
return true;
-
}
default:;
bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape)
{
- //MESSAGE("StdMeshers_Regular_1D::Compute");
-
if ( _hypType == NONE )
return false;
TopExp::Vertices(E, VFirst, VLast); // Vfirst corresponds to f and Vlast to l
ASSERT(!VFirst.IsNull());
- const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
- if (!idFirst) {
- MESSAGE (" NO NODE BUILT ON VERTEX ");
- return false;
- }
-
ASSERT(!VLast.IsNull());
+ const SMDS_MeshNode * idFirst = SMESH_Algo::VertexNode( VFirst, meshDS );
const SMDS_MeshNode * idLast = SMESH_Algo::VertexNode( VLast, meshDS );
- if (!idLast) {
- MESSAGE (" NO NODE BUILT ON VERTEX ");
- return false;
- }
+ if (!idFirst || !idLast)
+ return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
- if (!Curve.IsNull()) {
+ if (!Curve.IsNull())
+ {
list< double > params;
bool reversed = false;
if ( !_mainEdge.IsNull() )
- reversed = aMesh.IsReversedInChain( EE, _mainEdge );
+ reversed = ( _mainEdge.Orientation() == TopAbs_REVERSED );
+
BRepAdaptor_Curve C3d( E );
double length = EdgeLength( E );
- try {
-#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
- OCC_CATCH_SIGNALS;
-#endif
- if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
- return false;
- }
- redistributeNearVertices( aMesh, C3d, length, params, VFirst, VLast );
- }
- catch ( Standard_Failure ) {
+ if ( ! computeInternalParameters( C3d, length, f, l, params, reversed )) {
return false;
}
+ redistributeNearVertices( aMesh, 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
const SMDS_MeshNode * idPrev = idFirst;
double parPrev = f;
double parLast = l;
-
+
+ /* NPAL18025
+ if (reversed) {
+ idPrev = idLast;
+ idLast = idFirst;
+ idFirst = idPrev;
+ parPrev = l;
+ parLast = f;
+ }
+ */
+
for (list<double>::iterator itU = params.begin(); itU != params.end(); itU++) {
double param = *itU;
gp_Pnt P = Curve->Value(param);
meshDS->SetMeshElementOnShape(edge, shapeID);
}
}
- else {
+ else
+ {
+ //MESSAGE("************* Degenerated edge! *****************");
+
// Edge is a degenerated Edge : We put n = 5 points on the edge.
const int NbPoints = 5;
+ BRep_Tool::Range( E, f, l ); // PAL15185
double du = (l - f) / (NbPoints - 1);
- //MESSAGE("************* Degenerated edge! *****************");
gp_Pnt P = BRep_Tool::Pnt(VFirst);
// get non-auxiliary assigned to aShape
int nbHyp = aMesh.GetHypotheses( aShape, compatibleFilter, _usedHypList, false );
- if (nbHyp == 0)
+ if (nbHyp == 0 && aShape.ShapeType() == TopAbs_EDGE)
{
// Check, if propagated from some other edge
- if (aShape.ShapeType() == TopAbs_EDGE &&
- aMesh.IsPropagatedHypothesis(aShape, _mainEdge))
+ _mainEdge = StdMeshers_Propagation::GetPropagationSource( aMesh, aShape );
+ if ( !_mainEdge.IsNull() )
{
// Propagation of 1D hypothesis from <aMainEdge> on this edge;
// get non-auxiliary assigned to _mainEdge