+double Length2D::GetValue( long theElementId)
+{
+ TSequenceOfXYZ P;
+
+ //cout<<"Length2D::GetValue"<<endl;
+ if (GetPoints(theElementId,P)){
+ //for(int jj=1; jj<=P.size(); jj++)
+ // cout<<"jj="<<jj<<" P("<<P(jj).X()<<","<<P(jj).Y()<<","<<P(jj).Z()<<")"<<endl;
+
+ double aVal;// = GetValue( P );
+ const SMDS_MeshElement* aElem = myMesh->FindElement( theElementId );
+ SMDSAbs_ElementType aType = aElem->GetType();
+
+ int len = P.size();
+
+ switch (aType){
+ case SMDSAbs_All:
+ case SMDSAbs_Node:
+ case SMDSAbs_Edge:
+ if (len == 2){
+ aVal = getDistance( P( 1 ), P( 2 ) );
+ break;
+ }
+ else if (len == 3){ // quadratic edge
+ aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 ));
+ break;
+ }
+ 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 ));
+ aVal = Max(Max(L1,L2),Max(L3,L4));
+ break;
+ }
+ 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));
+ //cout<<"L1="<<L1<<" L2="<<L2<<"L3="<<L3<<" aVal="<<aVal<<endl;
+ break;
+ }
+ else if (len == 8){ // 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 ));
+ aVal = Max(Max(L1,L2),Max(L3,L4));
+ break;
+ }
+ case SMDSAbs_Volume:
+ if (len == 4){ // tetraidrs
+ double L1 = getDistance(P( 1 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 1 ));
+ double L4 = getDistance(P( 1 ),P( 4 ));
+ double L5 = getDistance(P( 2 ),P( 4 ));
+ double L6 = getDistance(P( 3 ),P( 4 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ break;
+ }
+ else if (len == 5){ // piramids
+ double L1 = getDistance(P( 1 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 1 ));
+ double L4 = getDistance(P( 4 ),P( 1 ));
+ double L5 = getDistance(P( 1 ),P( 5 ));
+ double L6 = getDistance(P( 2 ),P( 5 ));
+ double L7 = getDistance(P( 3 ),P( 5 ));
+ double L8 = getDistance(P( 4 ),P( 5 ));
+
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(L7,L8));
+ break;
+ }
+ else if (len == 6){ // pentaidres
+ double L1 = getDistance(P( 1 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 1 ));
+ double L4 = getDistance(P( 4 ),P( 5 ));
+ double L5 = getDistance(P( 5 ),P( 6 ));
+ double L6 = getDistance(P( 6 ),P( 4 ));
+ double L7 = getDistance(P( 1 ),P( 4 ));
+ double L8 = getDistance(P( 2 ),P( 5 ));
+ double L9 = getDistance(P( 3 ),P( 6 ));
+
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(Max(L7,L8),L9));
+ break;
+ }
+ else if (len == 8){ // hexaider
+ 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 L5 = getDistance(P( 5 ),P( 6 ));
+ double L6 = getDistance(P( 6 ),P( 7 ));
+ double L7 = getDistance(P( 7 ),P( 8 ));
+ double L8 = getDistance(P( 8 ),P( 5 ));
+ double L9 = getDistance(P( 1 ),P( 5 ));
+ double L10= getDistance(P( 2 ),P( 6 ));
+ double L11= getDistance(P( 3 ),P( 7 ));
+ double L12= getDistance(P( 4 ),P( 8 ));
+
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+ aVal = Max(aVal,Max(L11,L12));
+ break;
+
+ }
+
+ if (len == 10){ // quadratic tetraidrs
+ double L1 = getDistance(P( 1 ),P( 5 )) + getDistance(P( 5 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 6 )) + getDistance(P( 6 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 7 )) + getDistance(P( 7 ),P( 1 ));
+ double L4 = getDistance(P( 1 ),P( 8 )) + getDistance(P( 8 ),P( 4 ));
+ double L5 = getDistance(P( 2 ),P( 9 )) + getDistance(P( 9 ),P( 4 ));
+ double L6 = getDistance(P( 3 ),P( 10 )) + getDistance(P( 10 ),P( 4 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ break;
+ }
+ else if (len == 13){ // quadratic piramids
+ double L1 = getDistance(P( 1 ),P( 6 )) + getDistance(P( 6 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 7 )) + getDistance(P( 7 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 8 )) + getDistance(P( 8 ),P( 1 ));
+ double L4 = getDistance(P( 4 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+ double L5 = getDistance(P( 1 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+ double L6 = getDistance(P( 2 ),P( 11 )) + getDistance(P( 11 ),P( 5 ));
+ double L7 = getDistance(P( 3 ),P( 12 )) + getDistance(P( 12 ),P( 5 ));
+ double L8 = getDistance(P( 4 ),P( 13 )) + getDistance(P( 13 ),P( 5 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(L7,L8));
+ break;
+ }
+ else if (len == 15){ // quadratic pentaidres
+ double L1 = getDistance(P( 1 ),P( 7 )) + getDistance(P( 7 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 8 )) + getDistance(P( 8 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 9 )) + getDistance(P( 9 ),P( 1 ));
+ double L4 = getDistance(P( 4 ),P( 10 )) + getDistance(P( 10 ),P( 5 ));
+ double L5 = getDistance(P( 5 ),P( 11 )) + getDistance(P( 11 ),P( 6 ));
+ double L6 = getDistance(P( 6 ),P( 12 )) + getDistance(P( 12 ),P( 4 ));
+ double L7 = getDistance(P( 1 ),P( 13 )) + getDistance(P( 13 ),P( 4 ));
+ double L8 = getDistance(P( 2 ),P( 14 )) + getDistance(P( 14 ),P( 5 ));
+ double L9 = getDistance(P( 3 ),P( 15 )) + getDistance(P( 15 ),P( 6 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(Max(L7,L8),L9));
+ break;
+ }
+ else if (len == 20){ // quadratic hexaider
+ double L1 = getDistance(P( 1 ),P( 9 )) + getDistance(P( 9 ),P( 2 ));
+ double L2 = getDistance(P( 2 ),P( 10 )) + getDistance(P( 10 ),P( 3 ));
+ double L3 = getDistance(P( 3 ),P( 11 )) + getDistance(P( 11 ),P( 4 ));
+ double L4 = getDistance(P( 4 ),P( 12 )) + getDistance(P( 12 ),P( 1 ));
+ double L5 = getDistance(P( 5 ),P( 13 )) + getDistance(P( 13 ),P( 6 ));
+ double L6 = getDistance(P( 6 ),P( 14 )) + getDistance(P( 14 ),P( 7 ));
+ double L7 = getDistance(P( 7 ),P( 15 )) + getDistance(P( 15 ),P( 8 ));
+ double L8 = getDistance(P( 8 ),P( 16 )) + getDistance(P( 16 ),P( 5 ));
+ double L9 = getDistance(P( 1 ),P( 17 )) + getDistance(P( 17 ),P( 5 ));
+ double L10= getDistance(P( 2 ),P( 18 )) + getDistance(P( 18 ),P( 6 ));
+ double L11= getDistance(P( 3 ),P( 19 )) + getDistance(P( 19 ),P( 7 ));
+ double L12= getDistance(P( 4 ),P( 20 )) + getDistance(P( 20 ),P( 8 ));
+ aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(L5,L6));
+ aVal = Max(aVal,Max(Max(L7,L8),Max(L9,L10)));
+ aVal = Max(aVal,Max(L11,L12));
+ break;
+
+ }
+
+ default: aVal=-1;
+ }
+
+ if (aVal <0){
+ return 0.;
+ }
+
+ if ( myPrecision >= 0 )
+ {
+ double prec = pow( 10., (double)( myPrecision ) );
+ aVal = floor( aVal * prec + 0.5 ) / prec;
+ }
+
+ return aVal;
+
+ }
+ return 0.;
+}
+
+double Length2D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+ // meaningless as it is not quality control functor
+ return Value;
+}
+
+SMDSAbs_ElementType Length2D::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+Length2D::Value::Value(double theLength,long thePntId1, long thePntId2):
+ myLength(theLength)
+{
+ myPntId[0] = thePntId1; myPntId[1] = thePntId2;
+ if(thePntId1 > thePntId2){
+ myPntId[1] = thePntId1; myPntId[0] = thePntId2;
+ }
+}
+
+bool Length2D::Value::operator<(const Length2D::Value& x) const{
+ if(myPntId[0] < x.myPntId[0]) return true;
+ if(myPntId[0] == x.myPntId[0])
+ if(myPntId[1] < x.myPntId[1]) return true;
+ return false;
+}
+
+void Length2D::GetValues(TValues& theValues){
+ TValues aValues;
+ SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+ for(; anIter->more(); ){
+ const SMDS_MeshFace* anElem = anIter->next();
+
+ if(anElem->IsQuadratic()) {
+ const SMDS_QuadraticFaceOfNodes* F =
+ static_cast<const SMDS_QuadraticFaceOfNodes*>(anElem);
+ // use special nodes iterator
+ SMDS_NodeIteratorPtr anIter = F->interlacedNodesIterator();
+ long aNodeId[4];
+ gp_Pnt P[4];
+
+ double aLength;
+ const SMDS_MeshElement* aNode;
+ if(anIter->more()){
+ aNode = anIter->next();
+ const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+ P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+ aNodeId[0] = aNodeId[1] = aNode->GetID();
+ aLength = 0;
+ }
+ for(; anIter->more(); ){
+ const SMDS_MeshNode* N1 = static_cast<const SMDS_MeshNode*> (anIter->next());
+ P[2] = gp_Pnt(N1->X(),N1->Y(),N1->Z());
+ aNodeId[2] = N1->GetID();
+ aLength = P[1].Distance(P[2]);
+ if(!anIter->more()) break;
+ const SMDS_MeshNode* N2 = static_cast<const SMDS_MeshNode*> (anIter->next());
+ P[3] = gp_Pnt(N2->X(),N2->Y(),N2->Z());
+ aNodeId[3] = N2->GetID();
+ aLength += P[2].Distance(P[3]);
+ Value aValue1(aLength,aNodeId[1],aNodeId[2]);
+ Value aValue2(aLength,aNodeId[2],aNodeId[3]);
+ P[1] = P[3];
+ aNodeId[1] = aNodeId[3];
+ theValues.insert(aValue1);
+ theValues.insert(aValue2);
+ }
+ aLength += P[2].Distance(P[0]);
+ Value aValue1(aLength,aNodeId[1],aNodeId[2]);
+ Value aValue2(aLength,aNodeId[2],aNodeId[0]);
+ theValues.insert(aValue1);
+ theValues.insert(aValue2);
+ }
+ else {
+ SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
+ long aNodeId[2];
+ gp_Pnt P[3];
+
+ double aLength;
+ const SMDS_MeshElement* aNode;
+ if(aNodesIter->more()){
+ aNode = aNodesIter->next();
+ const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+ P[0] = P[1] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+ aNodeId[0] = aNodeId[1] = aNode->GetID();
+ aLength = 0;
+ }
+ for(; aNodesIter->more(); ){
+ aNode = aNodesIter->next();
+ const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode;
+ long anId = aNode->GetID();
+
+ P[2] = gp_Pnt(aNodes->X(),aNodes->Y(),aNodes->Z());
+
+ aLength = P[1].Distance(P[2]);
+
+ Value aValue(aLength,aNodeId[1],anId);
+ aNodeId[1] = anId;
+ P[1] = P[2];
+ theValues.insert(aValue);
+ }
+
+ aLength = P[0].Distance(P[1]);
+
+ Value aValue(aLength,aNodeId[0],aNodeId[1]);
+ theValues.insert(aValue);
+ }
+ }
+}
+
+/*
+ Class : MultiConnection
+ Description : Functor for calculating number of faces conneted to the edge
+*/
+double MultiConnection::GetValue( const TSequenceOfXYZ& P )
+{
+ return 0;
+}
+double MultiConnection::GetValue( long theId )
+{
+ return getNbMultiConnection( myMesh, theId );
+}
+
+double MultiConnection::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+ // meaningless as it is not quality control functor
+ return Value;
+}
+
+SMDSAbs_ElementType MultiConnection::GetType() const
+{
+ return SMDSAbs_Edge;
+}
+
+/*
+ Class : MultiConnection2D
+ Description : Functor for calculating number of faces conneted to the edge
+*/
+double MultiConnection2D::GetValue( const TSequenceOfXYZ& P )
+{
+ return 0;
+}
+
+double MultiConnection2D::GetValue( long theElementId )
+{
+ int aResult = 0;
+
+ const SMDS_MeshElement* aFaceElem = myMesh->FindElement(theElementId);
+ SMDSAbs_ElementType aType = aFaceElem->GetType();
+
+ switch (aType) {
+ case SMDSAbs_Face:
+ {
+ int i = 0, len = aFaceElem->NbNodes();
+ SMDS_ElemIteratorPtr anIter = aFaceElem->nodesIterator();
+ if (!anIter) break;
+
+ const SMDS_MeshNode *aNode, *aNode0;
+ TColStd_MapOfInteger aMap, aMapPrev;
+
+ for (i = 0; i <= len; i++) {
+ aMapPrev = aMap;
+ aMap.Clear();
+
+ int aNb = 0;
+ if (anIter->more()) {
+ aNode = (SMDS_MeshNode*)anIter->next();
+ } else {
+ if (i == len)
+ aNode = aNode0;
+ else
+ break;
+ }
+ if (!aNode) break;
+ if (i == 0) aNode0 = aNode;
+
+ SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator();
+ while (anElemIter->more()) {
+ const SMDS_MeshElement* anElem = anElemIter->next();
+ if (anElem != 0 && anElem->GetType() == SMDSAbs_Face) {
+ int anId = anElem->GetID();
+
+ aMap.Add(anId);
+ if (aMapPrev.Contains(anId)) {
+ aNb++;
+ }
+ }
+ }
+ aResult = Max(aResult, aNb);
+ }
+ }
+ break;
+ default:
+ aResult = 0;
+ }
+
+ return aResult;
+}
+
+double MultiConnection2D::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+ // meaningless as it is not quality control functor
+ return Value;
+}
+
+SMDSAbs_ElementType MultiConnection2D::GetType() const
+{
+ return SMDSAbs_Face;
+}
+
+MultiConnection2D::Value::Value(long thePntId1, long thePntId2)
+{
+ myPntId[0] = thePntId1; myPntId[1] = thePntId2;
+ if(thePntId1 > thePntId2){
+ myPntId[1] = thePntId1; myPntId[0] = thePntId2;
+ }
+}
+
+bool MultiConnection2D::Value::operator<(const MultiConnection2D::Value& x) const{
+ if(myPntId[0] < x.myPntId[0]) return true;
+ if(myPntId[0] == x.myPntId[0])
+ if(myPntId[1] < x.myPntId[1]) return true;
+ return false;
+}
+
+void MultiConnection2D::GetValues(MValues& theValues){
+ SMDS_FaceIteratorPtr anIter = myMesh->facesIterator();
+ for(; anIter->more(); ){
+ const SMDS_MeshFace* anElem = anIter->next();
+ SMDS_ElemIteratorPtr aNodesIter;
+ if ( anElem->IsQuadratic() )
+ aNodesIter = static_cast<const SMDS_QuadraticFaceOfNodes*>
+ (anElem)->interlacedNodesElemIterator();
+ else
+ aNodesIter = anElem->nodesIterator();
+ long aNodeId[3];
+
+ //int aNbConnects=0;
+ const SMDS_MeshNode* aNode0;
+ const SMDS_MeshNode* aNode1;
+ const SMDS_MeshNode* aNode2;
+ if(aNodesIter->more()){
+ aNode0 = (SMDS_MeshNode*) aNodesIter->next();
+ aNode1 = aNode0;
+ const SMDS_MeshNode* aNodes = (SMDS_MeshNode*) aNode1;
+ aNodeId[0] = aNodeId[1] = aNodes->GetID();
+ }
+ for(; aNodesIter->more(); ) {
+ aNode2 = (SMDS_MeshNode*) aNodesIter->next();
+ long anId = aNode2->GetID();
+ aNodeId[2] = anId;
+
+ Value aValue(aNodeId[1],aNodeId[2]);
+ MValues::iterator aItr = theValues.find(aValue);
+ if (aItr != theValues.end()){
+ aItr->second += 1;
+ //aNbConnects = nb;
+ }
+ else {
+ theValues[aValue] = 1;
+ //aNbConnects = 1;
+ }
+ //cout << "NodeIds: "<<aNodeId[1]<<","<<aNodeId[2]<<" nbconn="<<aNbConnects<<endl;
+ aNodeId[1] = aNodeId[2];
+ aNode1 = aNode2;
+ }
+ Value aValue(aNodeId[0],aNodeId[2]);
+ MValues::iterator aItr = theValues.find(aValue);
+ if (aItr != theValues.end()) {
+ aItr->second += 1;
+ //aNbConnects = nb;
+ }
+ else {
+ theValues[aValue] = 1;
+ //aNbConnects = 1;
+ }
+ //cout << "NodeIds: "<<aNodeId[0]<<","<<aNodeId[2]<<" nbconn="<<aNbConnects<<endl;
+ }
+
+}
+
+/*
+ PREDICATES
+*/
+
+/*
+ Class : BadOrientedVolume
+ Description : Predicate bad oriented volumes
+*/
+
+BadOrientedVolume::BadOrientedVolume()
+{
+ myMesh = 0;
+}
+
+void BadOrientedVolume::SetMesh( const SMDS_Mesh* theMesh )
+{
+ myMesh = theMesh;
+}
+
+bool BadOrientedVolume::IsSatisfy( long theId )
+{
+ if ( myMesh == 0 )
+ return false;
+
+ SMDS_VolumeTool vTool( myMesh->FindElement( theId ));
+ return !vTool.IsForward();
+}
+
+SMDSAbs_ElementType BadOrientedVolume::GetType() const
+{
+ return SMDSAbs_Volume;
+}
+
+
+
+/*
+ Class : FreeBorders
+ Description : Predicate for free borders
+*/
+
+FreeBorders::FreeBorders()
+{
+ myMesh = 0;
+}
+
+void FreeBorders::SetMesh( const SMDS_Mesh* theMesh )