#include "SMESH_ControlsDef.hxx"
-#include <set>
-#include <limits>
+#include "SMDS_BallElement.hxx"
+#include "SMDS_Iterator.hxx"
+#include "SMDS_Mesh.hxx"
+#include "SMDS_MeshElement.hxx"
+#include "SMDS_MeshNode.hxx"
+#include "SMDS_QuadraticEdge.hxx"
+#include "SMDS_QuadraticFaceOfNodes.hxx"
+#include "SMDS_VolumeTool.hxx"
+#include "SMESHDS_GroupBase.hxx"
+#include "SMESHDS_Mesh.hxx"
+#include "SMESH_OctreeNode.hxx"
#include <BRepAdaptor_Surface.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRep_Tool.hxx>
-
-#include <TopAbs.hxx>
-#include <TopoDS.hxx>
-#include <TopoDS_Edge.hxx>
-#include <TopoDS_Face.hxx>
-#include <TopoDS_Shape.hxx>
-#include <TopoDS_Vertex.hxx>
-#include <TopoDS_Iterator.hxx>
-
#include <Geom_CylindricalSurface.hxx>
#include <Geom_Plane.hxx>
#include <Geom_Surface.hxx>
-
#include <Precision.hxx>
#include <TColStd_MapIteratorOfMapOfInteger.hxx>
#include <TColStd_MapOfInteger.hxx>
#include <TColStd_SequenceOfAsciiString.hxx>
#include <TColgp_Array1OfXYZ.hxx>
-
+#include <TopAbs.hxx>
+#include <TopoDS.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Vertex.hxx>
#include <gp_Ax3.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Dir.hxx>
#include <gp_Vec.hxx>
#include <gp_XYZ.hxx>
-#include "SMDS_Mesh.hxx"
-#include "SMDS_Iterator.hxx"
-#include "SMDS_MeshElement.hxx"
-#include "SMDS_MeshNode.hxx"
-#include "SMDS_VolumeTool.hxx"
-#include "SMDS_QuadraticFaceOfNodes.hxx"
-#include "SMDS_QuadraticEdge.hxx"
-
-#include "SMESHDS_Mesh.hxx"
-#include "SMESHDS_GroupBase.hxx"
+#include <vtkMeshQuality.h>
-#include "SMESH_OctreeNode.hxx"
+#include <set>
+#include <limits>
-#include <vtkMeshQuality.h>
/*
AUXILIARY METHODS
Class : MaxElementLength2D
Description : Functor calculating maximum length of 2D element
*/
+double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P )
+{
+ if(P.size() == 0)
+ return 0.;
+ double aVal = 0;
+ int len = P.size();
+ if( len == 3 ) { // triangles
+ double L1 = getDistance(P( 1 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 1 ));
+ aVal = Max(L1,Max(L2,L3));
+ }
+ else if( len == 4 ) { // quadrangles
+ double L1 = getDistance(P( 1 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 4 ));
+ double L4 = getDistance(P( 4 ),P( 1 ));
+ double D1 = getDistance(P( 1 ),P( 3 ));
+ double D2 = getDistance(P( 2 ),P( 4 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+ }
+ else if( len == 6 ) { // quadratic triangles
+ double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+ double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+ double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
+ aVal = Max(L1,Max(L2,L3));
+ }
+ else if( len == 8 || len == 9 ) { // quadratic quadrangles
+ double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
+ double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
+ double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
+ double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+ double D1 = getDistance(P( 1 ),P( 5 ));
+ double D2 = getDistance(P( 3 ),P( 7 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
+ }
+
+ if( myPrecision >= 0 )
+ {
+ double prec = pow( 10., (double)myPrecision );
+ aVal = floor( aVal * prec + 0.5 ) / prec;
+ }
+ return aVal;
+}
double MaxElementLength2D::GetValue( long theElementId )
{
TSequenceOfXYZ P;
- if( GetPoints( theElementId, P ) ) {
- double aVal = 0;
- const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
- SMDSAbs_ElementType aType = aElem->GetType();
- int len = P.size();
- switch( aType ) {
- case SMDSAbs_Face:
- if( len == 3 ) { // triangles
- double L1 = getDistance(P( 1 ),P( 2 ));
- double L2 = getDistance(P( 2 ),P( 3 ));
- double L3 = getDistance(P( 3 ),P( 1 ));
- aVal = Max(L1,Max(L2,L3));
- break;
- }
- else if( len == 4 ) { // quadrangles
- double L1 = getDistance(P( 1 ),P( 2 ));
- double L2 = getDistance(P( 2 ),P( 3 ));
- double L3 = getDistance(P( 3 ),P( 4 ));
- double L4 = getDistance(P( 4 ),P( 1 ));
- double D1 = getDistance(P( 1 ),P( 3 ));
- double D2 = getDistance(P( 2 ),P( 4 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
- break;
- }
- else if( len == 6 ) { // quadratic triangles
- double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
- double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
- double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 1 ));
- aVal = Max(L1,Max(L2,L3));
- break;
- }
- else if( len == 8 || len == 9 ) { // quadratic quadrangles
- double L1 = getDistance(P( 1 ),P( 2 )) + getDistance(P( 2 ),P( 3 ));
- double L2 = getDistance(P( 3 ),P( 4 )) + getDistance(P( 4 ),P( 5 ));
- double L3 = getDistance(P( 5 ),P( 6 )) + getDistance(P( 6 ),P( 7 ));
- double L4 = getDistance(P( 7 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
- double D1 = getDistance(P( 1 ),P( 5 ));
- double D2 = getDistance(P( 3 ),P( 7 ));
- aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2));
- break;
- }
- }
-
- if( myPrecision >= 0 )
- {
- double prec = pow( 10., (double)myPrecision );
- aVal = floor( aVal * prec + 0.5 ) / prec;
- }
- return aVal;
+ if( GetPoints( theElementId, P ) && myMesh->FindElement( theElementId )->GetType() == SMDSAbs_Face) {
+ GetValue(P);
}
return 0.;
}
Class : AspectRatio
Description : Functor for calculating aspect ratio
*/
+double AspectRatio::GetValue( long theId )
+{
+ double aVal = 0;
+ myCurrElement = myMesh->FindElement( theId );
+ if ( myCurrElement && myCurrElement->GetVtkType() == VTK_QUAD )
+ {
+ // issue 21723
+ vtkUnstructuredGrid* grid = SMDS_Mesh::_meshList[myCurrElement->getMeshId()]->getGrid();
+ if ( vtkCell* avtkCell = grid->GetCell( myCurrElement->getVtkId() ))
+ aVal = Round( vtkMeshQuality::QuadAspectRatio( avtkCell ));
+ }
+ else
+ {
+ TSequenceOfXYZ P;
+ if ( GetPoints( myCurrElement, P ))
+ aVal = Round( GetValue( P ));
+ }
+ return aVal;
+}
+
double AspectRatio::GetValue( const TSequenceOfXYZ& P )
{
// According to "Mesh quality control" by Nadir Bouhamau referring to
}
+/*
+ Class : BallDiameter
+ Description : Functor returning diameter of a ball element
+*/
+double BallDiameter::GetValue( long theId )
+{
+ double diameter = 0;
+
+ if ( const SMDS_BallElement* ball =
+ dynamic_cast<const SMDS_BallElement*>( myMesh->FindElement( theId )))
+ {
+ diameter = ball->GetDiameter();
+ }
+ return diameter;
+}
+
+double BallDiameter::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+ // meaningless as it is not a quality control functor
+ return Value;
+}
+
+SMDSAbs_ElementType BallDiameter::GetType() const
+{
+ return SMDSAbs_Ball;
+}
+
+
/*
PREDICATES
*/
const SMDSAbs_ElementType anElemType = anElem->GetType();
if ( myType != SMDSAbs_All && anElemType != myType )
return false;
- const int aNbNode = anElem->NbNodes();
- bool isOk = false;
- switch( anElemType )
- {
- case SMDSAbs_Node:
- isOk = (myGeomType == SMDSGeom_POINT);
- break;
-
- case SMDSAbs_Edge:
- isOk = (myGeomType == SMDSGeom_EDGE);
- break;
-
- case SMDSAbs_Face:
- if ( myGeomType == SMDSGeom_TRIANGLE )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 6 : aNbNode == 3));
- else if ( myGeomType == SMDSGeom_QUADRANGLE )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? ( aNbNode == 8 || aNbNode == 9 ) : aNbNode == 4));
- else if ( myGeomType == SMDSGeom_POLYGON )
- isOk = anElem->IsPoly();
- break;
-
- case SMDSAbs_Volume:
- if ( myGeomType == SMDSGeom_TETRA )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 10 : aNbNode == 4));
- else if ( myGeomType == SMDSGeom_PYRAMID )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 13 : aNbNode == 5));
- else if ( myGeomType == SMDSGeom_PENTA )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? aNbNode == 15 : aNbNode == 6));
- else if ( myGeomType == SMDSGeom_HEXA )
- isOk = (!anElem->IsPoly() && (anElem->IsQuadratic() ? ( aNbNode == 20 || aNbNode == 27 ): aNbNode == 8));
- else if ( myGeomType == SMDSGeom_HEXAGONAL_PRISM )
- isOk = (anElem->GetEntityType() == SMDSEntity_Hexagonal_Prism );
- else if ( myGeomType == SMDSGeom_POLYHEDRA )
- isOk = anElem->IsPoly();
- break;
- default: break;
- }
+ bool isOk = ( anElem->GetGeomType() == myGeomType );
return isOk;
}
return;
const double radianTol = myToler * M_PI / 180.;
- typedef SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > TFaceIt;
- std::set<const SMDS_MeshElement*> checkedFaces, checkedNodes;
- std::list<const SMDS_MeshElement*> faceQueue( 1, face );
+ std::set< SMESH_TLink > checkedLinks;
+
+ std::list< pair< const SMDS_MeshElement*, gp_Vec > > faceQueue;
+ faceQueue.push_back( make_pair( face, myNorm ));
while ( !faceQueue.empty() )
{
- face = faceQueue.front();
- if ( checkedFaces.insert( face ).second )
+ face = faceQueue.front().first;
+ myNorm = faceQueue.front().second;
+ faceQueue.pop_front();
+
+ for ( int i = 0, nbN = face->NbCornerNodes(); i < nbN; ++i )
{
- gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(face), &normOK );
- if (!normOK || myNorm.Angle( norm ) <= radianTol)
+ const SMDS_MeshNode* n1 = face->GetNode( i );
+ const SMDS_MeshNode* n2 = face->GetNode(( i+1 )%nbN);
+ if ( !checkedLinks.insert( SMESH_TLink( n1, n2 )).second )
+ continue;
+ SMDS_ElemIteratorPtr fIt = n1->GetInverseElementIterator(SMDSAbs_Face);
+ while ( fIt->more() )
{
- myCoplanarIDs.insert( face->GetID() );
- std::set<const SMDS_MeshElement*> neighborFaces;
- for ( int i = 0; i < face->NbCornerNodes(); ++i )
+ const SMDS_MeshElement* f = fIt->next();
+ if ( f->GetNodeIndex( n2 ) > -1 )
{
- const SMDS_MeshNode* n = face->GetNode( i );
- if ( checkedNodes.insert( n ).second )
- neighborFaces.insert( TFaceIt( n->GetInverseElementIterator(SMDSAbs_Face)),
- TFaceIt());
+ gp_Vec norm = getNormale( static_cast<const SMDS_MeshFace*>(f), &normOK );
+ if (!normOK || myNorm.Angle( norm ) <= radianTol)
+ {
+ myCoplanarIDs.insert( f->GetID() );
+ faceQueue.push_back( make_pair( f, norm ));
+ }
}
- faceQueue.insert( faceQueue.end(), neighborFaces.begin(), neighborFaces.end() );
}
}
- faceQueue.pop_front();
}
}
}
}
/*
- *Class : RangeOfIds
+ *Class : RangeOfIds
*Description : Predicate for Range of Ids.
* Range may be specified with two ways.
* 1. Using AddToRange method
myPredicate = thePredicate;
}
-template<class TElement, class TIterator, class TPredicate>
-inline void FillSequence(const TIterator& theIterator,
- TPredicate& thePredicate,
- Filter::TIdSequence& theSequence)
-{
- if ( theIterator ) {
- while( theIterator->more() ) {
- TElement anElem = theIterator->next();
- long anId = anElem->GetID();
- if ( thePredicate->IsSatisfy( anId ) )
- theSequence.push_back( anId );
- }
- }
-}
-
-void
-Filter::
-GetElementsId( const SMDS_Mesh* theMesh,
- PredicatePtr thePredicate,
- TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh* theMesh,
+ PredicatePtr thePredicate,
+ TIdSequence& theSequence )
{
theSequence.clear();
thePredicate->SetMesh( theMesh );
- SMDSAbs_ElementType aType = thePredicate->GetType();
- switch(aType){
- case SMDSAbs_Node:
- FillSequence<const SMDS_MeshNode*>(theMesh->nodesIterator(),thePredicate,theSequence);
- break;
- case SMDSAbs_Edge:
- FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
- break;
- case SMDSAbs_Face:
- FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
- break;
- case SMDSAbs_Volume:
- FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
- break;
- case SMDSAbs_All:
- FillSequence<const SMDS_MeshElement*>(theMesh->edgesIterator(),thePredicate,theSequence);
- FillSequence<const SMDS_MeshElement*>(theMesh->facesIterator(),thePredicate,theSequence);
- FillSequence<const SMDS_MeshElement*>(theMesh->volumesIterator(),thePredicate,theSequence);
- break;
+ SMDS_ElemIteratorPtr elemIt = theMesh->elementsIterator( thePredicate->GetType() );
+ if ( elemIt ) {
+ while ( elemIt->more() ) {
+ const SMDS_MeshElement* anElem = elemIt->next();
+ long anId = anElem->GetID();
+ if ( thePredicate->IsSatisfy( anId ) )
+ theSequence.push_back( anId );
+ }
}
}
-void
-Filter::GetElementsId( const SMDS_Mesh* theMesh,
- Filter::TIdSequence& theSequence )
+void Filter::GetElementsId( const SMDS_Mesh* theMesh,
+ Filter::TIdSequence& theSequence )
{
GetElementsId(theMesh,myPredicate,theSequence);
}
ElementsOnSurface::ElementsOnSurface()
{
- myMesh = 0;
myIds.Clear();
myType = SMDSAbs_All;
mySurf.Nullify();
ElementsOnSurface::~ElementsOnSurface()
{
- myMesh = 0;
}
void ElementsOnSurface::SetMesh( const SMDS_Mesh* theMesh )
{
- if ( myMesh == theMesh )
- return;
- myMesh = theMesh;
- process();
+ myMeshModifTracer.SetMesh( theMesh );
+ if ( myMeshModifTracer.IsMeshModified())
+ process();
}
bool ElementsOnSurface::IsSatisfy( long theElementId )
if ( mySurf.IsNull() )
return;
- if ( myMesh == 0 )
+ if ( !myMeshModifTracer.GetMesh() )
return;
- if ( myType == SMDSAbs_Face || myType == SMDSAbs_All )
- {
- myIds.ReSize( myMesh->NbFaces() );
- SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
- for(; anIter->more(); )
- process( anIter->next() );
- }
-
- if ( myType == SMDSAbs_Edge || myType == SMDSAbs_All )
- {
- myIds.ReSize( myIds.Extent() + myMesh->NbEdges() );
- SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
- for(; anIter->more(); )
- process( anIter->next() );
- }
+ myIds.ReSize( myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType ));
- if ( myType == SMDSAbs_Node )
- {
- myIds.ReSize( myMesh->NbNodes() );
- SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
- for(; anIter->more(); )
- process( anIter->next() );
- }
+ SMDS_ElemIteratorPtr anIter = myMeshModifTracer.GetMesh()->elementsIterator( myType );
+ for(; anIter->more(); )
+ process( anIter->next() );
}
void ElementsOnSurface::process( const SMDS_MeshElement* theElemPtr )
if ( !myMesh ) return;
- switch (myType)
- {
- case SMDSAbs_All:
- myIds.ReSize(myMesh->NbEdges() + myMesh->NbFaces() + myMesh->NbVolumes());
- break;
- case SMDSAbs_Node:
- myIds.ReSize(myMesh->NbNodes());
- break;
- case SMDSAbs_Edge:
- myIds.ReSize(myMesh->NbEdges());
- break;
- case SMDSAbs_Face:
- myIds.ReSize(myMesh->NbFaces());
- break;
- case SMDSAbs_Volume:
- myIds.ReSize(myMesh->NbVolumes());
- break;
- default:
- break;
- }
+ myIds.ReSize( myMeshModifTracer.GetMesh()->GetMeshInfo().NbElements( myType ));
myShapesMap.Clear();
addShape(myShape);
if (myShape.IsNull() || myMesh == 0)
return;
- if (myType == SMDSAbs_Node)
- {
- SMDS_NodeIteratorPtr anIter = myMesh->nodesIterator();
- while (anIter->more())
- process(anIter->next());
- }
- else
- {
- if (myType == SMDSAbs_Edge || myType == SMDSAbs_All)
- {
- SMDS_EdgeIteratorPtr anIter = myMesh->edgesIterator();
- while (anIter->more())
- process(anIter->next());
- }
-
- if (myType == SMDSAbs_Face || myType == SMDSAbs_All)
- {
- SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
- while (anIter->more()) {
- process(anIter->next());
- }
- }
-
- if (myType == SMDSAbs_Volume || myType == SMDSAbs_All)
- {
- SMDS_VolumeIteratorPtr anIter = myMesh->volumesIterator();
- while (anIter->more())
- process(anIter->next());
- }
- }
+ SMDS_ElemIteratorPtr anIter = myMesh->elementsIterator(myType);
+ while (anIter->more())
+ process(anIter->next());
}
void ElementsOnShape::process (const SMDS_MeshElement* theElemPtr)
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{
- SMDS_MeshNode* aNode = (SMDS_MeshNode*)aNodeItr->next();
- gp_Pnt aPnt (aNode->X(), aNode->Y(), aNode->Z());
- centerXYZ += aPnt.XYZ();
+ SMESH_TNodeXYZ aPnt ( aNodeItr->next() );
+ centerXYZ += aPnt;
switch (myCurShapeType)
{
break;
case TopAbs_VERTEX:
{
- isSatisfy = (aPnt.Distance(myCurPnt) <= myToler);
+ isSatisfy = (myCurPnt.Distance(aPnt) <= myToler);
}
break;
default: