X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FControls%2FSMESH_Controls.cxx;h=769096df4344b7e69a9d61ac59e8d7d6d903b5f9;hp=eb1e5bdb95e8f0d7879d1588ac4dc96b45f5977f;hb=07589de92eb5d8e7d4e3bfde8b26f0d69251acf0;hpb=7aebb99e42c6b0c3c056a5eecb0f29033db2231a;ds=sidebyside diff --git a/src/Controls/SMESH_Controls.cxx b/src/Controls/SMESH_Controls.cxx index eb1e5bdb9..769096df4 100644 --- a/src/Controls/SMESH_Controls.cxx +++ b/src/Controls/SMESH_Controls.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2015 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 @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -18,6 +18,7 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include "SMESH_ControlsDef.hxx" @@ -30,9 +31,13 @@ #include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMESHDS_GroupBase.hxx" +#include "SMESHDS_GroupOnFilter.hxx" #include "SMESHDS_Mesh.hxx" +#include "SMESH_MeshAlgos.hxx" #include "SMESH_OctreeNode.hxx" +#include + #include #include #include @@ -45,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -64,7 +70,6 @@ #include #include - /* AUXILIARY METHODS */ @@ -131,8 +136,8 @@ namespace { int aResult0 = 0, aResult1 = 0; // last node, it is a medium one in a quadratic edge const SMDS_MeshNode* aLastNode = anEdge->GetNode( anEdge->NbNodes() - 1 ); - const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 ); - const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 ); + const SMDS_MeshNode* aNode0 = anEdge->GetNode( 0 ); + const SMDS_MeshNode* aNode1 = anEdge->GetNode( 1 ); if ( aNode1 == aLastNode ) aNode1 = 0; SMDS_ElemIteratorPtr anElemIter = aLastNode->GetInverseElementIterator(); @@ -154,29 +159,6 @@ namespace { } int aResult = std::max ( aResult0, aResult1 ); -// TColStd_MapOfInteger aMap; - -// SMDS_ElemIteratorPtr anIter = anEdge->nodesIterator(); -// if ( anIter != 0 ) { -// while( anIter->more() ) { -// const SMDS_MeshNode* aNode = (SMDS_MeshNode*)anIter->next(); -// if ( aNode == 0 ) -// return 0; -// SMDS_ElemIteratorPtr anElemIter = aNode->GetInverseElementIterator(); -// while( anElemIter->more() ) { -// const SMDS_MeshElement* anElem = anElemIter->next(); -// if ( anElem != 0 && anElem->GetType() != SMDSAbs_Edge ) { -// int anId = anElem->GetID(); - -// if ( anIter->more() ) // i.e. first node -// aMap.Add( anId ); -// else if ( aMap.Contains( anId ) ) -// aResult++; -// } -// } -// } -// } - return aResult; } @@ -228,7 +210,7 @@ void NumericalFunctor::SetMesh( const SMDS_Mesh* theMesh ) myMesh = theMesh; } -bool NumericalFunctor::GetPoints(const int theId, +bool NumericalFunctor::GetPoints(const int theId, TSequenceOfXYZ& theRes ) const { theRes.clear(); @@ -252,6 +234,7 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, return false; theRes.reserve( anElem->NbNodes() ); + theRes.setElement( anElem ); // Get nodes of the element SMDS_ElemIteratorPtr anIter; @@ -268,7 +251,6 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, break; default: anIter = anElem->nodesIterator(); - //return false; } } else { @@ -276,9 +258,13 @@ bool NumericalFunctor::GetPoints(const SMDS_MeshElement* anElem, } if ( anIter ) { + double xyz[3]; while( anIter->more() ) { if ( const SMDS_MeshNode* aNode = static_cast( anIter->next() )) - theRes.push_back( gp_XYZ( aNode->X(), aNode->Y(), aNode->Z() ) ); + { + aNode->GetXYZ( xyz ); + theRes.push_back( gp_XYZ( xyz[0], xyz[1], xyz[2] )); + } } } @@ -303,7 +289,7 @@ double NumericalFunctor::GetValue( long theId ) myCurrElement = myMesh->FindElement( theId ); TSequenceOfXYZ P; - if ( GetPoints( theId, P )) + if ( GetPoints( theId, P )) // elem type is checked here aVal = Round( GetValue( P )); return aVal; @@ -343,7 +329,7 @@ void NumericalFunctor::GetHistogram(int nbIntervals, std::multiset< double > values; if ( elements.empty() ) { - SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator(GetType()); + SMDS_ElemIteratorPtr elemIt = myMesh->elementsIterator( GetType() ); while ( elemIt->more() ) values.insert( GetValue( elemIt->next()->GetID() )); } @@ -476,6 +462,27 @@ double MaxElementLength2D::GetValue( const TSequenceOfXYZ& P ) double D2 = getDistance(P( 3 ),P( 7 )); aVal = Max(Max(Max(L1,L2),Max(L3,L4)),Max(D1,D2)); } + // Diagonals are undefined for concave polygons + // else if ( P.getElementEntity() == SMDSEntity_Quad_Polygon && P.size() > 2 ) // quad polygon + // { + // // sides + // aVal = getDistance( P( 1 ), P( P.size() )) + getDistance( P( P.size() ), P( P.size()-1 )); + // for ( size_t i = 1; i < P.size()-1; i += 2 ) + // { + // double L = getDistance( P( i ), P( i+1 )) + getDistance( P( i+1 ), P( i+2 )); + // aVal = Max( aVal, L ); + // } + // // diagonals + // for ( int i = P.size()-5; i > 0; i -= 2 ) + // for ( int j = i + 4; j < P.size() + i - 2; i += 2 ) + // { + // double D = getDistance( P( i ), P( j )); + // aVal = Max( aVal, D ); + // } + // } + // { // polygons + + // } if( myPrecision >= 0 ) { @@ -694,8 +701,9 @@ double MinimumAngle::GetValue( const TSequenceOfXYZ& P ) aMin = getAngle(P( P.size() ), P( 1 ), P( 2 )); aMin = Min(aMin,getAngle(P( P.size()-1 ), P( P.size() ), P( 1 ))); - for (int i=2; i 2 ) { + if ( P.size() > 2 ) + { gp_Vec aVec1( P(2) - P(1) ); gp_Vec aVec2( P(3) - P(1) ); gp_Vec SumVec = aVec1 ^ aVec2; - for (int i=4; i<=P.size(); i++) { + + for (int i=4; i<=P.size(); i++) + { gp_Vec aVec1( P(i-1) - P(1) ); gp_Vec aVec2( P(i) - P(1) ); gp_Vec tmp = aVec1 ^ aVec2; @@ -1510,81 +1529,78 @@ SMDSAbs_ElementType Length::GetType() const //================================================================================ /* Class : Length2D - Description : Functor for calculating length of edge + Description : Functor for calculating minimal length of edge */ //================================================================================ -double Length2D::GetValue( long theElementId) +double Length2D::GetValue( long theElementId ) { TSequenceOfXYZ P; - //cout<<"Length2D::GetValue"<FindElement( theElementId ); - SMDSAbs_ElementType aType = aElem->GetType(); - + if ( GetPoints( theElementId, P )) + { + double aVal = 0; int len = P.size(); + SMDSAbs_EntityType aType = P.getElementEntity(); - switch (aType){ - case SMDSAbs_All: - case SMDSAbs_Node: - case SMDSAbs_Edge: - if (len == 2){ + switch (aType) { + case SMDSEntity_Edge: + if (len == 2) aVal = getDistance( P( 1 ), P( 2 ) ); - break; - } - else if (len == 3){ // quadratic edge + break; + case SMDSEntity_Quad_Edge: + if (len == 3) // quadratic edge aVal = getDistance(P( 1 ),P( 3 )) + getDistance(P( 3 ),P( 2 )); - break; - } - case SMDSAbs_Face: + break; + case SMDSEntity_Triangle: 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; + aVal = Min(L1,Min(L2,L3)); } - else if (len == 4){ // quadrangles + break; + case SMDSEntity_Quadrangle: + 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; + aVal = Min(Min(L1,L2),Min(L3,L4)); } - if (len == 6){ // quadratic triangles + break; + case SMDSEntity_Quad_Triangle: + case SMDSEntity_BiQuad_Triangle: + 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="< +// #include + +// namespace Parallel +// { +// typedef tbb::enumerable_thread_specific< TIdSequence > TIdSeq; + +// struct Predicate +// { +// const SMDS_Mesh* myMesh; +// PredicatePtr myPredicate; +// TIdSeq & myOKIds; +// Predicate( const SMDS_Mesh* m, PredicatePtr p, TIdSeq & ids ): +// myMesh(m), myPredicate(p->Duplicate()), myOKIds(ids) {} +// void operator() ( const tbb::blocked_range& r ) const +// { +// for ( size_t i = r.begin(); i != r.end(); ++i ) +// if ( myPredicate->IsSatisfy( i )) +// myOKIds.local().push_back(); +// } +// } +// } +// #endif + Filter::Filter() {} @@ -3635,9 +3869,59 @@ void ManifoldPart::getFacesByLink( const ManifoldPart::Link& theLink, } } +/* + Class : BelongToMeshGroup + Description : Verify whether a mesh element is included into a mesh group +*/ +BelongToMeshGroup::BelongToMeshGroup(): myGroup( 0 ) +{ +} + +void BelongToMeshGroup::SetGroup( SMESHDS_GroupBase* g ) +{ + myGroup = g; +} + +void BelongToMeshGroup::SetStoreName( const std::string& sn ) +{ + myStoreName = sn; +} + +void BelongToMeshGroup::SetMesh( const SMDS_Mesh* theMesh ) +{ + if ( myGroup && myGroup->GetMesh() != theMesh ) + { + myGroup = 0; + } + if ( !myGroup && !myStoreName.empty() ) + { + if ( const SMESHDS_Mesh* aMesh = dynamic_cast(theMesh)) + { + const std::set& grps = aMesh->GetGroups(); + std::set::const_iterator g = grps.begin(); + for ( ; g != grps.end() && !myGroup; ++g ) + if ( *g && myStoreName == (*g)->GetStoreName() ) + myGroup = *g; + } + } + if ( myGroup ) + { + myGroup->IsEmpty(); // make GroupOnFilter update its predicate + } +} + +bool BelongToMeshGroup::IsSatisfy( long theElementId ) +{ + return myGroup ? myGroup->Contains( theElementId ) : false; +} + +SMDSAbs_ElementType BelongToMeshGroup::GetType() const +{ + return myGroup ? myGroup->GetType() : SMDSAbs_All; +} /* - ElementsOnSurface + ElementsOnSurface */ ElementsOnSurface::ElementsOnSurface() @@ -3814,7 +4098,41 @@ void ElementsOnShape::SetAllNodes (bool theAllNodes) void ElementsOnShape::SetMesh (const SMDS_Mesh* theMesh) { - myMesh = theMesh; + myMeshModifTracer.SetMesh( theMesh ); + if ( myMeshModifTracer.IsMeshModified()) + { + size_t nbNodes = theMesh ? theMesh->NbNodes() : 0; + if ( myNodeIsChecked.size() == nbNodes ) + { + std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false ); + } + else + { + SMESHUtils::FreeVector( myNodeIsChecked ); + SMESHUtils::FreeVector( myNodeIsOut ); + myNodeIsChecked.resize( nbNodes, false ); + myNodeIsOut.resize( nbNodes ); + } + } +} + +bool ElementsOnShape::getNodeIsOut( const SMDS_MeshNode* n, bool& isOut ) +{ + if ( n->GetID() >= (int) myNodeIsChecked.size() || + !myNodeIsChecked[ n->GetID() ]) + return false; + + isOut = myNodeIsOut[ n->GetID() ]; + return true; +} + +void ElementsOnShape::setNodeIsOut( const SMDS_MeshNode* n, bool isOut ) +{ + if ( n->GetID() < (int) myNodeIsChecked.size() ) + { + myNodeIsChecked[ n->GetID() ] = true; + myNodeIsOut [ n->GetID() ] = isOut; + } } void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, @@ -3823,7 +4141,7 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, myType = theType; myShape = theShape; if ( myShape.IsNull() ) return; - + TopTools_IndexedMapOfShape shapesMap; TopAbs_ShapeEnum shapeTypes[4] = { TopAbs_SOLID, TopAbs_FACE, TopAbs_EDGE, TopAbs_VERTEX }; TopExp_Explorer sub; @@ -3841,6 +4159,16 @@ void ElementsOnShape::SetShape (const TopoDS_Shape& theShape, myClassifiers.resize( shapesMap.Extent() ); for ( int i = 0; i < shapesMap.Extent(); ++i ) myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler ); + + if ( theType == SMDSAbs_Node ) + { + SMESHUtils::FreeVector( myNodeIsChecked ); + SMESHUtils::FreeVector( myNodeIsOut ); + } + else + { + std::fill( myNodeIsChecked.begin(), myNodeIsChecked.end(), false ); + } } void ElementsOnShape::clearClassifiers() @@ -3852,38 +4180,45 @@ void ElementsOnShape::clearClassifiers() bool ElementsOnShape::IsSatisfy (long elemId) { + const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh(); const SMDS_MeshElement* elem = - ( myType == SMDSAbs_Node ? myMesh->FindNode( elemId ) : myMesh->FindElement( elemId )); + ( myType == SMDSAbs_Node ? mesh->FindNode( elemId ) : mesh->FindElement( elemId )); if ( !elem || myClassifiers.empty() ) return false; - for ( size_t i = 0; i < myClassifiers.size(); ++i ) + bool isSatisfy = myAllNodesFlag, isNodeOut; + + gp_XYZ centerXYZ (0, 0, 0); + + SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator(); + while (aNodeItr->more() && (isSatisfy == myAllNodesFlag)) { - SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator(); - bool isSatisfy = myAllNodesFlag; - - gp_XYZ centerXYZ (0, 0, 0); + SMESH_TNodeXYZ aPnt( aNodeItr->next() ); + centerXYZ += aPnt; - while (aNodeItr->more() && (isSatisfy == myAllNodesFlag)) + isNodeOut = true; + if ( !getNodeIsOut( aPnt._node, isNodeOut )) { - SMESH_TNodeXYZ aPnt ( aNodeItr->next() ); - centerXYZ += aPnt; - isSatisfy = ! myClassifiers[i]->IsOut( aPnt ); + for ( size_t i = 0; i < myClassifiers.size() && isNodeOut; ++i ) + isNodeOut = myClassifiers[i]->IsOut( aPnt ); + + setNodeIsOut( aPnt._node, isNodeOut ); } + isSatisfy = !isNodeOut; + } - // Check the center point for volumes MantisBug 0020168 - if (isSatisfy && - myAllNodesFlag && - myClassifiers[i]->ShapeType() == TopAbs_SOLID) - { - centerXYZ /= elem->NbNodes(); + // Check the center point for volumes MantisBug 0020168 + if (isSatisfy && + myAllNodesFlag && + myClassifiers[0]->ShapeType() == TopAbs_SOLID) + { + centerXYZ /= elem->NbNodes(); + isSatisfy = false; + for ( size_t i = 0; i < myClassifiers.size() && !isSatisfy; ++i ) isSatisfy = ! myClassifiers[i]->IsOut( centerXYZ ); - } - if ( isSatisfy ) - return true; } - return false; + return isSatisfy; } TopAbs_ShapeEnum ElementsOnShape::TClassifier::ShapeType() const @@ -3903,8 +4238,15 @@ void ElementsOnShape::TClassifier::Init (const TopoDS_Shape& theShape, double th switch ( myShape.ShapeType() ) { case TopAbs_SOLID: { - mySolidClfr.Load(theShape); - myIsOutFun = & ElementsOnShape::TClassifier::isOutOfSolid; + if ( isBox( theShape )) + { + myIsOutFun = & ElementsOnShape::TClassifier::isOutOfBox; + } + else + { + mySolidClfr.Load(theShape); + myIsOutFun = & ElementsOnShape::TClassifier::isOutOfSolid; + } break; } case TopAbs_FACE: { @@ -3938,6 +4280,11 @@ bool ElementsOnShape::TClassifier::isOutOfSolid (const gp_Pnt& p) return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON ); } +bool ElementsOnShape::TClassifier::isOutOfBox (const gp_Pnt& p) +{ + return myBox.IsOut( p.XYZ() ); +} + bool ElementsOnShape::TClassifier::isOutOfFace (const gp_Pnt& p) { myProjFace.Perform( p ); @@ -3965,21 +4312,390 @@ bool ElementsOnShape::TClassifier::isOutOfVertex(const gp_Pnt& p) return ( myVertexXYZ.Distance( p ) > myTol ); } +bool ElementsOnShape::TClassifier::isBox (const TopoDS_Shape& theShape) +{ + TopTools_IndexedMapOfShape vMap; + TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap ); + if ( vMap.Extent() != 8 ) + return false; -TSequenceOfXYZ::TSequenceOfXYZ() + myBox.Clear(); + for ( int i = 1; i <= 8; ++i ) + myBox.Add( BRep_Tool::Pnt( TopoDS::Vertex( vMap( i ))).XYZ() ); + + gp_XYZ pMin = myBox.CornerMin(), pMax = myBox.CornerMax(); + for ( int i = 1; i <= 8; ++i ) + { + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( vMap( i ))); + for ( int iC = 1; iC <= 3; ++ iC ) + { + double d1 = Abs( pMin.Coord( iC ) - p.Coord( iC )); + double d2 = Abs( pMax.Coord( iC ) - p.Coord( iC )); + if ( Min( d1, d2 ) > myTol ) + return false; + } + } + myBox.Enlarge( myTol ); + return true; +} + + +/* + Class : BelongToGeom + Description : Predicate for verifying whether entity belongs to + specified geometrical support +*/ + +BelongToGeom::BelongToGeom() + : myMeshDS(NULL), + myType(SMDSAbs_All), + myIsSubshape(false), + myTolerance(Precision::Confusion()) {} -TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n) +void BelongToGeom::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMeshDS = dynamic_cast(theMesh); + init(); +} + +void BelongToGeom::SetGeom( const TopoDS_Shape& theShape ) +{ + myShape = theShape; + init(); +} + +static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap, + const TopoDS_Shape& theShape) +{ + if (theMap.Contains(theShape)) return true; + + if (theShape.ShapeType() == TopAbs_COMPOUND || + theShape.ShapeType() == TopAbs_COMPSOLID) + { + TopoDS_Iterator anIt (theShape, Standard_True, Standard_True); + for (; anIt.More(); anIt.Next()) + { + if (!IsSubShape(theMap, anIt.Value())) { + return false; + } + } + return true; + } + + return false; +} + +void BelongToGeom::init() +{ + if (!myMeshDS || myShape.IsNull()) return; + + // is sub-shape of main shape? + TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); + if (aMainShape.IsNull()) { + myIsSubshape = false; + } + else { + TopTools_IndexedMapOfShape aMap; + TopExp::MapShapes(aMainShape, aMap); + myIsSubshape = IsSubShape(aMap, myShape); + } + + //if (!myIsSubshape) // to be always ready to check an element not bound to geometry + { + myElementsOnShapePtr.reset(new ElementsOnShape()); + myElementsOnShapePtr->SetTolerance(myTolerance); + myElementsOnShapePtr->SetAllNodes(true); // "belong", while false means "lays on" + myElementsOnShapePtr->SetMesh(myMeshDS); + myElementsOnShapePtr->SetShape(myShape, myType); + } +} + +static bool IsContains( const SMESHDS_Mesh* theMeshDS, + const TopoDS_Shape& theShape, + const SMDS_MeshElement* theElem, + TopAbs_ShapeEnum theFindShapeEnum, + TopAbs_ShapeEnum theAvoidShapeEnum = TopAbs_SHAPE ) +{ + TopExp_Explorer anExp( theShape,theFindShapeEnum,theAvoidShapeEnum ); + + while( anExp.More() ) + { + const TopoDS_Shape& aShape = anExp.Current(); + if( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape ) ){ + if( aSubMesh->Contains( theElem ) ) + return true; + } + anExp.Next(); + } + return false; +} + +bool BelongToGeom::IsSatisfy (long theId) +{ + if (myMeshDS == 0 || myShape.IsNull()) + return false; + + if (!myIsSubshape) + { + return myElementsOnShapePtr->IsSatisfy(theId); + } + + // Case of submesh + if (myType == SMDSAbs_Node) + { + if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) ) + { + if ( aNode->getshapeId() < 1 ) + return myElementsOnShapePtr->IsSatisfy(theId); + + const SMDS_PositionPtr& aPosition = aNode->GetPosition(); + SMDS_TypeOfPosition aTypeOfPosition = aPosition->GetTypeOfPosition(); + switch( aTypeOfPosition ) + { + case SMDS_TOP_VERTEX : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_VERTEX )); + case SMDS_TOP_EDGE : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_EDGE )); + case SMDS_TOP_FACE : return ( IsContains( myMeshDS,myShape,aNode,TopAbs_FACE )); + case SMDS_TOP_3DSPACE: return ( IsContains( myMeshDS,myShape,aNode,TopAbs_SOLID ) || + IsContains( myMeshDS,myShape,aNode,TopAbs_SHELL )); + } + } + } + else + { + if ( const SMDS_MeshElement* anElem = myMeshDS->FindElement( theId )) + { + if ( anElem->getshapeId() < 1 ) + return myElementsOnShapePtr->IsSatisfy(theId); + + if( myType == SMDSAbs_All ) + { + return ( IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE ) || + IsContains( myMeshDS,myShape,anElem,TopAbs_FACE ) || + IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )|| + IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )); + } + else if( myType == anElem->GetType() ) + { + switch( myType ) + { + case SMDSAbs_Edge : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_EDGE )); + case SMDSAbs_Face : return ( IsContains( myMeshDS,myShape,anElem,TopAbs_FACE )); + case SMDSAbs_Volume: return ( IsContains( myMeshDS,myShape,anElem,TopAbs_SOLID )|| + IsContains( myMeshDS,myShape,anElem,TopAbs_SHELL )); + } + } + } + } + + return false; +} + +void BelongToGeom::SetType (SMDSAbs_ElementType theType) +{ + myType = theType; + init(); +} + +SMDSAbs_ElementType BelongToGeom::GetType() const +{ + return myType; +} + +TopoDS_Shape BelongToGeom::GetShape() +{ + return myShape; +} + +const SMESHDS_Mesh* BelongToGeom::GetMeshDS() const +{ + return myMeshDS; +} + +void BelongToGeom::SetTolerance (double theTolerance) +{ + myTolerance = theTolerance; + if (!myIsSubshape) + init(); +} + +double BelongToGeom::GetTolerance() +{ + return myTolerance; +} + +/* + Class : LyingOnGeom + Description : Predicate for verifying whether entiy lying or partially lying on + specified geometrical support +*/ + +LyingOnGeom::LyingOnGeom() + : myMeshDS(NULL), + myType(SMDSAbs_All), + myIsSubshape(false), + myTolerance(Precision::Confusion()) {} -TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t) +void LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh ) +{ + myMeshDS = dynamic_cast(theMesh); + init(); +} + +void LyingOnGeom::SetGeom( const TopoDS_Shape& theShape ) +{ + myShape = theShape; + init(); +} + +void LyingOnGeom::init() +{ + if (!myMeshDS || myShape.IsNull()) return; + + // is sub-shape of main shape? + TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh(); + if (aMainShape.IsNull()) { + myIsSubshape = false; + } + else { + myIsSubshape = myMeshDS->IsGroupOfSubShapes( myShape ); + } + + if (myIsSubshape) + { + TopTools_IndexedMapOfShape shapes; + TopExp::MapShapes( myShape, shapes ); + mySubShapesIDs.Clear(); + for ( int i = 1; i <= shapes.Extent(); ++i ) + { + int subID = myMeshDS->ShapeToIndex( shapes( i )); + if ( subID > 0 ) + mySubShapesIDs.Add( subID ); + } + } + else + { + myElementsOnShapePtr.reset(new ElementsOnShape()); + myElementsOnShapePtr->SetTolerance(myTolerance); + myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong" + myElementsOnShapePtr->SetMesh(myMeshDS); + myElementsOnShapePtr->SetShape(myShape, myType); + } +} + +bool LyingOnGeom::IsSatisfy( long theId ) +{ + if ( myMeshDS == 0 || myShape.IsNull() ) + return false; + + if (!myIsSubshape) + { + return myElementsOnShapePtr->IsSatisfy(theId); + } + + // Case of sub-mesh + + const SMDS_MeshElement* elem = + ( myType == SMDSAbs_Node ) ? myMeshDS->FindNode( theId ) : myMeshDS->FindElement( theId ); + + if ( mySubShapesIDs.Contains( elem->getshapeId() )) + return true; + + if ( elem->GetType() != SMDSAbs_Node ) + { + SMDS_ElemIteratorPtr nodeItr = elem->nodesIterator(); + while ( nodeItr->more() ) + { + const SMDS_MeshElement* aNode = nodeItr->next(); + if ( mySubShapesIDs.Contains( aNode->getshapeId() )) + return true; + } + } + + return false; +} + +void LyingOnGeom::SetType( SMDSAbs_ElementType theType ) +{ + myType = theType; + init(); +} + +SMDSAbs_ElementType LyingOnGeom::GetType() const +{ + return myType; +} + +TopoDS_Shape LyingOnGeom::GetShape() +{ + return myShape; +} + +const SMESHDS_Mesh* LyingOnGeom::GetMeshDS() const +{ + return myMeshDS; +} + +void LyingOnGeom::SetTolerance (double theTolerance) +{ + myTolerance = theTolerance; + if (!myIsSubshape) + init(); +} + +double LyingOnGeom::GetTolerance() +{ + return myTolerance; +} + +bool LyingOnGeom::Contains( const SMESHDS_Mesh* theMeshDS, + const TopoDS_Shape& theShape, + const SMDS_MeshElement* theElem, + TopAbs_ShapeEnum theFindShapeEnum, + TopAbs_ShapeEnum theAvoidShapeEnum ) +{ + // if (IsContains(theMeshDS, theShape, theElem, theFindShapeEnum, theAvoidShapeEnum)) + // return true; + + // TopTools_MapOfShape aSubShapes; + // TopExp_Explorer exp( theShape, theFindShapeEnum, theAvoidShapeEnum ); + // for ( ; exp.More(); exp.Next() ) + // { + // const TopoDS_Shape& aShape = exp.Current(); + // if ( !aSubShapes.Add( aShape )) continue; + + // if ( SMESHDS_SubMesh* aSubMesh = theMeshDS->MeshElements( aShape )) + // { + // if ( aSubMesh->Contains( theElem )) + // return true; + + // SMDS_ElemIteratorPtr nodeItr = theElem->nodesIterator(); + // while ( nodeItr->more() ) + // { + // const SMDS_MeshElement* aNode = nodeItr->next(); + // if ( aSubMesh->Contains( aNode )) + // return true; + // } + // } + // } + return false; +} + +TSequenceOfXYZ::TSequenceOfXYZ(): myElem(0) {} -TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray) +TSequenceOfXYZ::TSequenceOfXYZ(size_type n) : myArray(n), myElem(0) +{} + +TSequenceOfXYZ::TSequenceOfXYZ(size_type n, const gp_XYZ& t) : myArray(n,t), myElem(0) +{} + +TSequenceOfXYZ::TSequenceOfXYZ(const TSequenceOfXYZ& theSequenceOfXYZ) : myArray(theSequenceOfXYZ.myArray), myElem(theSequenceOfXYZ.myElem) {} template -TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd) +TSequenceOfXYZ::TSequenceOfXYZ(InputIterator theBegin, InputIterator theEnd): myArray(theBegin,theEnd), myElem(0) {} TSequenceOfXYZ::~TSequenceOfXYZ() @@ -3988,6 +4704,7 @@ TSequenceOfXYZ::~TSequenceOfXYZ() TSequenceOfXYZ& TSequenceOfXYZ::operator=(const TSequenceOfXYZ& theSequenceOfXYZ) { myArray = theSequenceOfXYZ.myArray; + myElem = theSequenceOfXYZ.myElem; return *this; } @@ -4021,6 +4738,11 @@ TSequenceOfXYZ::size_type TSequenceOfXYZ::size() const return myArray.size(); } +SMDSAbs_EntityType TSequenceOfXYZ::getElementEntity() const +{ + return myElem ? myElem->GetEntityType() : SMDSEntity_Last; +} + TMeshModifTracer::TMeshModifTracer(): myMeshModifTime(0), myMesh(0) {