-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
* FUNCTORS
*/
+//================================================================================
/*
Class : NumericalFunctor
Description : Base class for numerical functors
*/
+//================================================================================
+
NumericalFunctor::NumericalFunctor():
myMesh(NULL)
{
std::vector<int>& nbEvents,
std::vector<double>& funValues,
const vector<int>& elements,
- const double* minmax)
+ const double* minmax,
+ const bool isLogarithmic)
{
if ( nbIntervals < 1 ||
!myMesh ||
for ( int i = 0; i < nbIntervals; ++i )
{
// find end value of i-th interval
- double r = (i+1) / double( nbIntervals );
- funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+ double r = (i+1) / double(nbIntervals);
+ if (isLogarithmic && funValues.front() > 1e-07 && funValues.back() > 1e-07) {
+ double logmin = log10(funValues.front());
+ double lval = logmin + r * (log10(funValues.back()) - logmin);
+ funValues[i+1] = pow(10.0, lval);
+ }
+ else {
+ funValues[i+1] = funValues.front() * (1-r) + funValues.back() * r;
+ }
// count values in the i-th interval if there are any
if ( min != values.end() && *min <= funValues[i+1] )
}
//=======================================================================
-//function : GetValue
-//purpose :
-//=======================================================================
+/*
+ Class : Volume
+ Description : Functor calculating volume of a 3D element
+*/
+//================================================================================
double Volume::GetValue( long theElementId )
{
return 0;
}
-//=======================================================================
-//function : GetBadRate
-//purpose : meaningless as it is not quality control functor
-//=======================================================================
-
double Volume::GetBadRate( double Value, int /*nbNodes*/ ) const
{
return Value;
}
-//=======================================================================
-//function : GetType
-//purpose :
-//=======================================================================
-
SMDSAbs_ElementType Volume::GetType() const
{
return SMDSAbs_Volume;
Class : MaxElementLength2D
Description : Functor calculating maximum length of 2D element
*/
+//================================================================================
+
double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
{
if(P.size() == 0)
Class : MaxElementLength3D
Description : Functor calculating maximum length of 3D element
*/
+//================================================================================
double MaxElementLength3D::GetValue( long theElementId )
{
Class : MinimumAngle
Description : Functor for calculation of minimum angle
*/
+//================================================================================
double MinimumAngle::GetValue( const TSequenceOfXYZ& P )
{
}
+//================================================================================
/*
Class : AspectRatio
Description : Functor for calculating aspect ratio
*/
+//================================================================================
+
double AspectRatio::GetValue( long theId )
{
double aVal = 0;
}
+//================================================================================
/*
Class : AspectRatio3D
Description : Functor for calculating aspect ratio
*/
+//================================================================================
+
namespace{
inline double getHalfPerimeter(double theTria[3]){
}
+//================================================================================
/*
Class : Warping
Description : Functor for calculating warping
*/
+//================================================================================
+
double Warping::GetValue( const TSequenceOfXYZ& P )
{
if ( P.size() != 4 )
double A3 = ComputeA( P( 3 ), P( 4 ), P( 1 ), G );
double A4 = ComputeA( P( 4 ), P( 1 ), P( 2 ), G );
- return Max( Max( A1, A2 ), Max( A3, A4 ) );
+ double val = Max( Max( A1, A2 ), Max( A3, A4 ) );
+
+ const double eps = 0.1; // val is in degrees
+
+ return val < eps ? 0. : val;
}
double Warping::ComputeA( const gp_XYZ& thePnt1,
}
+//================================================================================
/*
Class : Taper
Description : Functor for calculating taper
*/
+//================================================================================
+
double Taper::GetValue( const TSequenceOfXYZ& P )
{
if ( P.size() != 4 )
double T3 = fabs( ( J3 - JA ) / JA );
double T4 = fabs( ( J4 - JA ) / JA );
- return Max( Max( T1, T2 ), Max( T3, T4 ) );
+ double val = Max( Max( T1, T2 ), Max( T3, T4 ) );
+
+ const double eps = 0.01;
+
+ return val < eps ? 0. : val;
}
double Taper::GetBadRate( double Value, int /*nbNodes*/ ) const
return SMDSAbs_Face;
}
-
+//================================================================================
/*
Class : Skew
Description : Functor for calculating skew in degrees
*/
+//================================================================================
+
static inline double skewAngle( const gp_XYZ& p1, const gp_XYZ& p2, const gp_XYZ& p3 )
{
gp_XYZ p12 = ( p2 + p1 ) / 2.;
return 0.;
// Compute skew
- static double PI2 = M_PI / 2.;
+ const double PI2 = M_PI / 2.;
if ( P.size() == 3 )
{
double A0 = fabs( PI2 - skewAngle( P( 3 ), P( 1 ), P( 2 ) ) );
double A = v1.Magnitude() <= gp::Resolution() || v2.Magnitude() <= gp::Resolution()
? 0. : fabs( PI2 - v1.Angle( v2 ) );
- //BUG SWP12743
- if ( A < theEps )
- return theInf;
+ double val = A * 180. / M_PI;
+
+ const double eps = 0.1; // val is in degrees
- return A * 180. / M_PI;
+ return val < eps ? 0. : val;
}
}
}
+//================================================================================
/*
Class : Area
Description : Functor for calculating area
*/
+//================================================================================
+
double Area::GetValue( const TSequenceOfXYZ& P )
{
double val = 0.0;
return SMDSAbs_Face;
}
-
+//================================================================================
/*
Class : Length
Description : Functor for calculating length of edge
*/
+//================================================================================
+
double Length::GetValue( const TSequenceOfXYZ& P )
{
switch ( P.size() ) {
return SMDSAbs_Edge;
}
+//================================================================================
/*
Class : Length2D
Description : Functor for calculating length of edge
*/
+//================================================================================
double Length2D::GetValue( long theElementId)
{
}
}
+//================================================================================
/*
Class : MultiConnection
Description : Functor for calculating number of faces conneted to the edge
*/
+//================================================================================
+
double MultiConnection::GetValue( const TSequenceOfXYZ& P )
{
return 0;
return SMDSAbs_Edge;
}
+//================================================================================
/*
Class : MultiConnection2D
Description : Functor for calculating number of faces conneted to the edge
*/
+//================================================================================
+
double MultiConnection2D::GetValue( const TSequenceOfXYZ& P )
{
return 0;
}
+//================================================================================
/*
Class : BallDiameter
Description : Functor returning diameter of a ball element
*/
+//================================================================================
+
double BallDiameter::GetValue( long theId )
{
double diameter = 0;
PREDICATES
*/
+//================================================================================
/*
Class : BadOrientedVolume
Description : Predicate bad oriented volumes
*/
+//================================================================================
BadOrientedVolume::BadOrientedVolume()
{
return false;
}
+//================================================================================
/*
Class : BareBorderFace
*/
+//================================================================================
bool BareBorderFace::IsSatisfy(long theElementId )
{
return ok;
}
+//================================================================================
/*
Class : OverConstrainedVolume
*/
+//================================================================================
bool OverConstrainedVolume::IsSatisfy(long theElementId )
{
return false;
}
+//================================================================================
/*
Class : OverConstrainedFace
*/
+//================================================================================
bool OverConstrainedFace::IsSatisfy(long theElementId )
{
return false;
}
+//================================================================================
/*
Class : CoincidentNodes
Description : Predicate of Coincident nodes
*/
+//================================================================================
CoincidentNodes::CoincidentNodes()
{
}
}
+//================================================================================
/*
Class : CoincidentElements
Description : Predicate of Coincident Elements
Note : This class is suitable only for visualization of Coincident Elements
*/
+//================================================================================
CoincidentElements::CoincidentElements()
{
}
+//================================================================================
/*
Class : FreeBorders
Description : Predicate for free borders
*/
+//================================================================================
FreeBorders::FreeBorders()
{
}
+//================================================================================
/*
Class : FreeEdges
Description : Predicate for free Edges
*/
+//================================================================================
+
FreeEdges::FreeEdges()
{
myMesh = 0;
}
}
-
+//================================================================================
/*
Class : FreeNodes
Description : Predicate for free nodes
*/
+//================================================================================
FreeNodes::FreeNodes()
{
}
+//================================================================================
/*
Class : FreeFaces
Description : Predicate for free faces
*/
+//================================================================================
FreeFaces::FreeFaces()
{
return SMDSAbs_Face;
}
+//================================================================================
/*
Class : LinearOrQuadratic
Description : Predicate to verify whether a mesh element is linear
*/
+//================================================================================
LinearOrQuadratic::LinearOrQuadratic()
{
return myType;
}
+//================================================================================
/*
Class : GroupColor
Description : Functor for check color of group to whic mesh element belongs to
*/
+//================================================================================
GroupColor::GroupColor()
{
// Purpose : Get range as a string.
// Example: "1,2,3,50-60,63,67,70-"
//=======================================================================
+
void GroupColor::GetColorStr( TCollection_AsciiString& theResStr ) const
{
theResStr.Clear();
theResStr += TCollection_AsciiString( ";" ) + TCollection_AsciiString( myColor.Blue() );
}
+//================================================================================
/*
Class : ElemGeomType
Description : Predicate to check element geometry type
*/
+//================================================================================
ElemGeomType::ElemGeomType()
{
return myGeomType;
}
+//================================================================================
+/*
+ Class : ElemEntityType
+ Description : Predicate to check element entity type
+*/
+//================================================================================
+
+ElemEntityType::ElemEntityType():
+ myMesh( 0 ),
+ myType( SMDSAbs_All ),
+ myEntityType( SMDSEntity_0D )
+{
+}
+
+void ElemEntityType::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool ElemEntityType::IsSatisfy( long theId )
+{
+ if ( !myMesh ) return false;
+ const SMDS_MeshElement* anElem = myMesh->FindElement( theId );
+ return ( anElem &&
+ myEntityType == anElem->GetEntityType() &&
+ ( myType == SMDSAbs_Edge || myType == SMDSAbs_Face || myType == SMDSAbs_Volume ));
+}
+
+void ElemEntityType::SetType( SMDSAbs_ElementType theType )
+{
+ myType = theType;
+}
+
+SMDSAbs_ElementType ElemEntityType::GetType() const
+{
+ return myType;
+}
+
+void ElemEntityType::SetElemEntityType( SMDSAbs_EntityType theEntityType )
+{
+ myEntityType = theEntityType;
+}
+
+SMDSAbs_EntityType ElemEntityType::GetElemEntityType() const
+{
+ return myEntityType;
+}
+
//================================================================================
/*!
* \brief Class CoplanarFaces
myToler(Precision::Confusion()),
myAllNodesFlag(false)
{
- myCurShapeType = TopAbs_SHAPE;
}
ElementsOnShape::~ElementsOnShape()
{
-}
-
-void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
-{
- myMeshModifTracer.SetMesh( theMesh );
- if ( myMeshModifTracer.IsMeshModified())
- SetShape(myShape, myType);
-}
-
-bool ElementsOnShape::IsSatisfy (long theElementId)
-{
- return myIds.Contains(theElementId);
+ clearClassifiers();
}
SMDSAbs_ElementType ElementsOnShape::GetType() const
void ElementsOnShape::SetAllNodes (bool theAllNodes)
{
- if (myAllNodesFlag != theAllNodes) {
- myAllNodesFlag = theAllNodes;
- SetShape(myShape, myType);
- }
+ myAllNodesFlag = theAllNodes;
+}
+
+void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh)
+{
+ myMesh = theMesh;
}
void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType)
{
- myType = theType;
+ myType = theType;
myShape = theShape;
- myIds.Clear();
-
- const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
+ if ( myShape.IsNull() ) return;
- if ( !myMesh ) return;
-
- myIds.ReSize( myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType ));
+ TopTools_IndexedMapOfShape shapesMap;
+ TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX };
+ TopExp_Explorer sub;
+ for ( int i = 0; i < 4; ++i )
+ {
+ if ( shapesMap.IsEmpty() )
+ for ( sub.Init( myShape, shapeTypes[i] ); sub.More(); sub.Next() )
+ shapesMap.Add( sub.Current() );
+ if ( i > 0 )
+ for ( sub.Init( myShape, shapeTypes[i], shapeTypes[i-1] ); sub.More(); sub.Next() )
+ shapesMap.Add( sub.Current() );
+ }
- myShapesMap.Clear();
- addShape(myShape);
+ clearClassifiers();
+ myClassifiers.resize( shapesMap.Extent() );
+ for ( int i = 0; i < shapesMap.Extent(); ++i )
+ myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
}
-void ElementsOnShape::addShape (const TopoDS_Shape& theShape)
+void ElementsOnShape::clearClassifiers()
{
- if (theShape.IsNull() || myMeshModifTracer.GetMesh() == 0)
- return;
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ delete myClassifiers[ i ];
+ myClassifiers.clear();
+}
- if (!myShapesMap.Add(theShape)) return;
+bool ElementsOnShape::IsSatisfy (long elemId)
+{
+ const SMDS_MeshElement* elem =
+ ( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId ));
+ if ( !elem || myClassifiers.empty() )
+ return false;
- myCurShapeType = theShape.ShapeType();
- switch (myCurShapeType)
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
{
- case TopAbs_COMPOUND:
- case TopAbs_COMPSOLID:
- case TopAbs_SHELL:
- case TopAbs_WIRE:
+ SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
+ bool isSatisfy = myAllNodesFlag;
+
+ gp_XYZ centerXYZ (0, 0, 0);
+
+ while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{
- TopoDS_Iterator anIt (theShape, Standard_True, Standard_True);
- for (; anIt.More(); anIt.Next()) addShape(anIt.Value());
+ SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
+ centerXYZ += aPnt;
+ isSatisfy = ! myClassifiers[i]->IsOut( aPnt );
}
- break;
- case TopAbs_SOLID:
+
+ // Check the center point for volumes MantisBug 0020168
+ if (isSatisfy &&
+ myAllNodesFlag &&
+ myClassifiers[i]->ShapeType() == TopAbs_SOLID)
{
- myCurSC.Load(theShape);
- process();
+ centerXYZ /= elem->NbNodes();
+ isSatisfy = ! myClassifiers[i]->IsOut( centerXYZ );
}
+ if ( isSatisfy )
+ return true;
+ }
+
+ return false;
+}
+
+TopAbs_ShapeEnum ElementsOnShape::TClassifier::ShapeType() const
+{
+ return myShape.ShapeType();
+}
+
+bool ElementsOnShape::TClassifier::IsOut(const gp_Pnt& p)
+{
+ return (this->*myIsOutFun)( p );
+}
+
+void ElementsOnShape::TClassifier::Init (const TopoDS_Shape& theShape, double theTol)
+{
+ myShape = theShape;
+ myTol = theTol;
+ switch ( myShape.ShapeType() )
+ {
+ case TopAbs_SOLID: {
+ mySolidClfr.Load(theShape);
+ myIsOutFun = & ElementsOnShape::TClassifier::isOutOfSolid;
break;
- case TopAbs_FACE:
- {
- TopoDS_Face aFace = TopoDS::Face(theShape);
- BRepAdaptor_Surface SA (aFace, true);
- Standard_Real
- u1 = SA.FirstUParameter(),
- u2 = SA.LastUParameter(),
- v1 = SA.FirstVParameter(),
- v2 = SA.LastVParameter();
- Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace);
- myCurProjFace.Init(surf, u1,u2, v1,v2);
- myCurFace = aFace;
- process();
- }
+ }
+ case TopAbs_FACE: {
+ Standard_Real u1,u2,v1,v2;
+ Handle(Geom_Surface) surf = BRep_Tool::Surface( TopoDS::Face( theShape ));
+ surf->Bounds( u1,u2,v1,v2 );
+ myProjFace.Init(surf, u1,u2, v1,v2, myTol );
+ myIsOutFun = & ElementsOnShape::TClassifier::isOutOfFace;
break;
- case TopAbs_EDGE:
- {
- TopoDS_Edge anEdge = TopoDS::Edge(theShape);
- Standard_Real u1, u2;
- Handle(Geom_Curve) curve = BRep_Tool::Curve(anEdge, u1, u2);
- myCurProjEdge.Init(curve, u1, u2);
- process();
- }
+ }
+ case TopAbs_EDGE: {
+ Standard_Real u1, u2;
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge(theShape), u1, u2);
+ myProjEdge.Init(curve, u1, u2);
+ myIsOutFun = & ElementsOnShape::TClassifier::isOutOfEdge;
break;
- case TopAbs_VERTEX:
- {
- TopoDS_Vertex aV = TopoDS::Vertex(theShape);
- myCurPnt = BRep_Tool::Pnt(aV);
- process();
- }
+ }
+ case TopAbs_VERTEX:{
+ myVertexXYZ = BRep_Tool::Pnt( TopoDS::Vertex( theShape ) );
+ myIsOutFun = & ElementsOnShape::TClassifier::isOutOfVertex;
break;
+ }
default:
- break;
+ throw SALOME_Exception("Programmer error in usage of ElementsOnShape::TClassifier");
}
}
-void ElementsOnShape::process()
+bool ElementsOnShape::TClassifier::isOutOfSolid (const gp_Pnt& p)
{
- const SMDS_Mesh* myMesh = myMeshModifTracer.GetMesh();
- if (myShape.IsNull() || myMesh == 0)
- return;
-
- SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType);
- while (anIter->more())
- process(anIter->next());
+ mySolidClfr.Perform( p, myTol );
+ return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON );
}
-void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
+bool ElementsOnShape::TClassifier::isOutOfFace (const gp_Pnt& p)
{
- if (myShape.IsNull())
- return;
-
- SMDS_ElemIteratorPtr aNodeItr = theElemPtr->nodesIterator();
- bool isSatisfy = myAllNodesFlag;
-
- gp_XYZ centerXYZ (0, 0, 0);
-
- while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
+ myProjFace.Perform( p );
+ if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol )
{
- SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
- centerXYZ += aPnt;
-
- switch (myCurShapeType)
- {
- case TopAbs_SOLID:
- {
- myCurSC.Perform(aPnt, myToler);
- isSatisfy = (myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON);
- }
- break;
- case TopAbs_FACE:
- {
- myCurProjFace.Perform(aPnt);
- isSatisfy = (myCurProjFace.IsDone() && myCurProjFace.LowerDistance() <= myToler);
- if (isSatisfy)
- {
- // check relatively the face
- Quantity_Parameter u, v;
- myCurProjFace.LowerDistanceParameters(u, v);
- gp_Pnt2d aProjPnt (u, v);
- BRepClass_FaceClassifier aClsf (myCurFace, aProjPnt, myToler);
- isSatisfy = (aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON);
- }
- }
- break;
- case TopAbs_EDGE:
- {
- myCurProjEdge.Perform(aPnt);
- isSatisfy = (myCurProjEdge.NbPoints() > 0 && myCurProjEdge.LowerDistance() <= myToler);
- }
- break;
- case TopAbs_VERTEX:
- {
- isSatisfy = (myCurPnt.Distance(aPnt) <= myToler);
- }
- break;
- default:
- {
- isSatisfy = false;
- }
- }
+ // check relatively to the face
+ Quantity_Parameter u, v;
+ myProjFace.LowerDistanceParameters(u, v);
+ gp_Pnt2d aProjPnt (u, v);
+ BRepClass_FaceClassifier aClsf ( TopoDS::Face( myShape ), aProjPnt, myTol );
+ if ( aClsf.State() == TopAbs_IN || aClsf.State() == TopAbs_ON )
+ return false;
}
+ return true;
+}
- if (isSatisfy && myCurShapeType == TopAbs_SOLID) { // Check the center point for volumes MantisBug 0020168
- centerXYZ /= theElemPtr->NbNodes();
- gp_Pnt aCenterPnt (centerXYZ);
- myCurSC.Perform(aCenterPnt, myToler);
- if ( !(myCurSC.State() == TopAbs_IN || myCurSC.State() == TopAbs_ON))
- isSatisfy = false;
- }
+bool ElementsOnShape::TClassifier::isOutOfEdge (const gp_Pnt& p)
+{
+ myProjEdge.Perform( p );
+ return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol );
+}
- if (isSatisfy)
- myIds.Add(theElemPtr->GetID());
+bool ElementsOnShape::TClassifier::isOutOfVertex(const gp_Pnt& p)
+{
+ return ( myVertexXYZ.Distance( p ) > myTol );
}
+
TSequenceOfXYZ::TSequenceOfXYZ()
{}