-// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016 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
#include <Basics_Utils.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
+#include <BRepBuilderAPI_Copy.hxx>
#include <BRepClass_FaceClassifier.hxx>
#include <BRep_Tool.hxx>
#include <Geom_CylindricalSurface.hxx>
n += q2 ^ q3;
}
double len = n.Modulus();
- bool zeroLen = ( len <= numeric_limits<double>::min());
+ bool zeroLen = ( len <= std::numeric_limits<double>::min());
if ( !zeroLen )
n /= len;
*/
//================================================================================
-void NumericalFunctor::GetHistogram(int nbIntervals,
- std::vector<int>& nbEvents,
- std::vector<double>& funValues,
- const vector<int>& elements,
- const double* minmax,
- const bool isLogarithmic)
+void NumericalFunctor::GetHistogram(int nbIntervals,
+ std::vector<int>& nbEvents,
+ std::vector<double>& funValues,
+ const std::vector<int>& elements,
+ const double* minmax,
+ const bool isLogarithmic)
{
if ( nbIntervals < 1 ||
!myMesh ||
}
else
{
- vector<int>::const_iterator id = elements.begin();
+ std::vector<int>::const_iterator id = elements.begin();
for ( ; id != elements.end(); ++id )
values.insert( GetValue( *id ));
}
dynamic_cast<const SMDS_VtkFace*>(anElem);
// use special nodes iterator
SMDS_ElemIteratorPtr anIter = F->interlacedNodesElemIterator();
- long aNodeId[4];
+ long aNodeId[4] = { 0,0,0,0 };
gp_Pnt P[4];
- double aLength;
+ double aLength = 0;
const SMDS_MeshElement* aNode;
if(anIter->more()){
aNode = anIter->next();
}
else {
SMDS_ElemIteratorPtr aNodesIter = anElem->nodesIterator();
- long aNodeId[2];
+ long aNodeId[2] = {0,0};
gp_Pnt P[3];
double aLength;
SMDS_ElemIteratorPtr anIter = aFaceElem->nodesIterator();
if (!anIter) break;
- const SMDS_MeshNode *aNode, *aNode0;
+ const SMDS_MeshNode *aNode, *aNode0 = 0;
TColStd_MapOfInteger aMap, aMapPrev;
for (i = 0; i <= len; i++) {
(anElem)->interlacedNodesElemIterator();
else
aNodesIter = anElem->nodesIterator();
- long aNodeId[3];
+ long aNodeId[3] = {0,0,0};
//int aNbConnects=0;
const SMDS_MeshNode* aNode0;
return SMDSAbs_Ball;
}
+//================================================================================
+/*
+ Class : NodeConnectivityNumber
+ Description : Functor returning number of elements connected to a node
+*/
+//================================================================================
+
+double NodeConnectivityNumber::GetValue( long theId )
+{
+ double nb = 0;
+
+ if ( const SMDS_MeshNode* node = myMesh->FindNode( theId ))
+ {
+ SMDSAbs_ElementType type;
+ if ( myMesh->NbVolumes() > 0 )
+ type = SMDSAbs_Volume;
+ else if ( myMesh->NbFaces() > 0 )
+ type = SMDSAbs_Face;
+ else if ( myMesh->NbEdges() > 0 )
+ type = SMDSAbs_Edge;
+ else
+ return 0;
+ nb = node->NbInverseElements( type );
+ }
+ return nb;
+}
+
+double NodeConnectivityNumber::GetBadRate( double Value, int /*nbNodes*/ ) const
+{
+ return Value;
+}
+
+SMDSAbs_ElementType NodeConnectivityNumber::GetType() const
+{
+ return SMDSAbs_Node;
+}
/*
PREDICATES
if ( myTool.IsFreeFace( iF ))
{
const SMDS_MeshNode** n = myTool.GetFaceNodes(iF);
- vector< const SMDS_MeshNode*> nodes( n, n+myTool.NbFaceNodes(iF));
+ std::vector< const SMDS_MeshNode*> nodes( n, n+myTool.NbFaceNodes(iF));
if ( !myMesh->FindElement( nodes, SMDSAbs_Face, /*Nomedium=*/false))
return true;
}
while ( nIt->more() )
nodesToCheck.insert( nodesToCheck.end(), nIt->next() );
- list< list< const SMDS_MeshNode*> > nodeGroups;
+ std::list< std::list< const SMDS_MeshNode*> > nodeGroups;
SMESH_OctreeNode::FindCoincidentNodes ( nodesToCheck, &nodeGroups, myToler );
myCoincidentIDs.Clear();
- list< list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin();
+ std::list< std::list< const SMDS_MeshNode*> >::iterator groupIt = nodeGroups.begin();
for ( ; groupIt != nodeGroups.end(); ++groupIt )
{
- list< const SMDS_MeshNode*>& coincNodes = *groupIt;
- list< const SMDS_MeshNode*>::iterator n = coincNodes.begin();
+ std::list< const SMDS_MeshNode*>& coincNodes = *groupIt;
+ std::list< const SMDS_MeshNode*>::iterator n = coincNodes.begin();
for ( ; n != coincNodes.end(); ++n )
myCoincidentIDs.Add( (*n)->GetID() );
}
if ( const SMDS_MeshElement* e = myMesh->FindElement( theElementId ))
{
if ( e->GetType() != GetType() ) return false;
- set< const SMDS_MeshNode* > elemNodes( e->begin_nodes(), e->end_nodes() );
+ std::set< const SMDS_MeshNode* > elemNodes( e->begin_nodes(), e->end_nodes() );
const int nbNodes = e->NbNodes();
SMDS_ElemIteratorPtr invIt = (*elemNodes.begin())->GetInverseElementIterator( GetType() );
while ( invIt->more() )
interlacedNodesElemIterator();
else
aNodesIter = anElem->nodesIterator();
- long aNodeId[2];
+ long aNodeId[2] = {0,0};
const SMDS_MeshElement* aNode;
if(aNodesIter->more()){
aNode = aNodesIter->next();
int nbNode = aFace->NbNodes();
// collect volumes to check that number of volumes with count equal nbNode not less than 2
- typedef map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
- typedef map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
+ typedef std::map< SMDS_MeshElement*, int > TMapOfVolume; // map of volume counters
+ typedef std::map< SMDS_MeshElement*, int >::iterator TItrMapOfVolume; // iterator
TMapOfVolume mapOfVol;
SMDS_ElemIteratorPtr nodeItr = aFace->nodesIterator();
- while ( nodeItr->more() ) {
+ while ( nodeItr->more() )
+ {
const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(nodeItr->next());
if ( !aNode ) continue;
SMDS_ElemIteratorPtr volItr = aNode->GetInverseElementIterator(SMDSAbs_Volume);
- while ( volItr->more() ) {
+ while ( volItr->more() )
+ {
SMDS_MeshElement* aVol = (SMDS_MeshElement*)volItr->next();
- TItrMapOfVolume itr = mapOfVol.insert(make_pair(aVol, 0)).first;
+ TItrMapOfVolume itr = mapOfVol.insert( std::make_pair( aVol, 0 )).first;
(*itr).second++;
}
}
return;
// iterates on groups and find necessary elements ids
- const std::set<SMESHDS_GroupBase*>& aGroups = aMesh->GetGroups();
- set<SMESHDS_GroupBase*>::const_iterator GrIt = aGroups.begin();
+ const std::set<SMESHDS_GroupBase*>& aGroups = aMesh->GetGroups();
+ std::set<SMESHDS_GroupBase*>::const_iterator GrIt = aGroups.begin();
for (; GrIt != aGroups.end(); GrIt++)
{
SMESHDS_GroupBase* aGrp = (*GrIt);
// find myNodeID by myXYZ if possible
if ( myMeshModifTracer.GetMesh() )
{
- auto_ptr<SMESH_ElementSearcher> searcher
+ SMESHUtils::Deleter<SMESH_ElementSearcher> searcher
( SMESH_MeshAlgos::GetElementSearcher( (SMDS_Mesh&) *myMeshModifTracer.GetMesh() ));
- vector< const SMDS_MeshElement* > foundElems;
+ std::vector< const SMDS_MeshElement* > foundElems;
searcher->FindElementsByPoint( gp_Pnt(x,y,z), SMDSAbs_All, foundElems );
if ( !foundElems.empty() )
if ( !node0 )
return false;
- list< const SMDS_MeshNode* > nodeQueue( 1, node0 );
+ std::list< const SMDS_MeshNode* > nodeQueue( 1, node0 );
std::set< int > checkedNodeIDs;
// algo:
// foreach node in nodeQueue:
const double cosTol = Cos( myToler * M_PI / 180. );
NCollection_Map< SMESH_TLink, SMESH_TLink > checkedLinks;
- std::list< pair< const SMDS_MeshElement*, gp_Vec > > faceQueue;
- faceQueue.push_back( make_pair( face, myNorm ));
+ std::list< std::pair< const SMDS_MeshElement*, gp_Vec > > faceQueue;
+ faceQueue.push_back( std::make_pair( face, myNorm ));
while ( !faceQueue.empty() )
{
face = faceQueue.front().first;
if (!normOK || isLessAngle( myNorm, norm, cosTol))
{
myCoplanarIDs.Add( f->GetID() );
- faceQueue.push_back( make_pair( f, norm ));
+ faceQueue.push_back( std::make_pair( f, norm ));
}
}
}
myIds.Clear();
TCollection_AsciiString aStr = theStr;
- //aStr.RemoveAll( ' ' );
- //aStr.RemoveAll( '\t' );
for ( int i = 1; i <= aStr.Length(); ++i )
- if ( isspace( aStr.Value( i )))
+ {
+ char c = aStr.Value( i );
+ if ( !isdigit( c ) && c != ',' && c != '-' )
aStr.SetValue( i, ',');
-
- for ( int aPos = aStr.Search( ",," ); aPos != -1; aPos = aStr.Search( ",," ) )
- aStr.Remove( aPos, 1 );
+ }
+ aStr.RemoveAll( ' ' );
TCollection_AsciiString tmpStr = aStr.Token( ",", 1 );
int i = 1;
return myGroup ? myGroup->GetType() : SMDSAbs_All;
}
-/*
- ElementsOnSurface
-*/
+//================================================================================
+// ElementsOnSurface
+//================================================================================
ElementsOnSurface::ElementsOnSurface()
{
}
-/*
- ElementsOnShape
-*/
+//================================================================================
+// ElementsOnShape
+//================================================================================
-ElementsOnShape::ElementsOnShape()
- : //myMesh(0),
- myType(SMDSAbs_All),
- myToler(Precision::Confusion()),
- myAllNodesFlag(false)
+namespace {
+ const int theIsCheckedFlag = 0x0000100;
+}
+
+struct ElementsOnShape::Classifier
+{
+ Classifier() { mySolidClfr = 0; myFlags = 0; }
+ ~Classifier();
+ void Init(const TopoDS_Shape& s, double tol, const Bnd_B3d* box = 0 );
+ bool IsOut(const gp_Pnt& p) { return SetChecked( true ), (this->*myIsOutFun)( p ); }
+ TopAbs_ShapeEnum ShapeType() const { return myShape.ShapeType(); }
+ const TopoDS_Shape& Shape() const { return myShape; }
+ const Bnd_B3d* GetBndBox() const { return & myBox; }
+ bool IsChecked() { return myFlags & theIsCheckedFlag; }
+ bool IsSetFlag( int flag ) const { return myFlags & flag; }
+ void SetChecked( bool is ) { is ? SetFlag( theIsCheckedFlag ) : UnsetFlag( theIsCheckedFlag ); }
+ void SetFlag ( int flag ) { myFlags |= flag; }
+ void UnsetFlag( int flag ) { myFlags &= ~flag; }
+
+private:
+ bool isOutOfSolid (const gp_Pnt& p);
+ bool isOutOfBox (const gp_Pnt& p);
+ bool isOutOfFace (const gp_Pnt& p);
+ bool isOutOfEdge (const gp_Pnt& p);
+ bool isOutOfVertex(const gp_Pnt& p);
+ bool isBox (const TopoDS_Shape& s);
+
+ bool (Classifier::* myIsOutFun)(const gp_Pnt& p);
+ BRepClass3d_SolidClassifier* mySolidClfr; // ptr because of a run-time forbidden copy-constructor
+ Bnd_B3d myBox;
+ GeomAPI_ProjectPointOnSurf myProjFace;
+ GeomAPI_ProjectPointOnCurve myProjEdge;
+ gp_Pnt myVertexXYZ;
+ TopoDS_Shape myShape;
+ double myTol;
+ int myFlags;
+};
+
+struct ElementsOnShape::OctreeClassifier : public SMESH_Octree
+{
+ OctreeClassifier( const std::vector< ElementsOnShape::Classifier* >& classifiers );
+ OctreeClassifier( const OctreeClassifier* otherTree,
+ const std::vector< ElementsOnShape::Classifier >& clsOther,
+ std::vector< ElementsOnShape::Classifier >& cls );
+ void GetClassifiersAtPoint( const gp_XYZ& p,
+ std::vector< ElementsOnShape::Classifier* >& classifiers );
+protected:
+ OctreeClassifier() {}
+ SMESH_Octree* newChild() const { return new OctreeClassifier; }
+ void buildChildrenData();
+ Bnd_B3d* buildRootBox();
+
+ std::vector< ElementsOnShape::Classifier* > myClassifiers;
+};
+
+
+ElementsOnShape::ElementsOnShape():
+ myOctree(0),
+ myType(SMDSAbs_All),
+ myToler(Precision::Confusion()),
+ myAllNodesFlag(false)
{
}
clearClassifiers();
}
+Predicate* ElementsOnShape::clone() const
+{
+ ElementsOnShape* cln = new ElementsOnShape();
+ cln->SetAllNodes ( myAllNodesFlag );
+ cln->SetTolerance( myToler );
+ cln->SetMesh ( myMeshModifTracer.GetMesh() );
+ cln->myShape = myShape; // avoid creation of myClassifiers
+ cln->SetShape ( myShape, myType );
+ cln->myClassifiers.resize( myClassifiers.size() );
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ cln->myClassifiers[ i ].Init( BRepBuilderAPI_Copy( myClassifiers[ i ].Shape()),
+ myToler, myClassifiers[ i ].GetBndBox() );
+ if ( myOctree ) // copy myOctree
+ {
+ cln->myOctree = new OctreeClassifier( myOctree, myClassifiers, cln->myClassifiers );
+ }
+ return cln;
+}
+
SMDSAbs_ElementType ElementsOnShape::GetType() const
{
return myType;
void ElementsOnShape::SetShape (const TopoDS_Shape& theShape,
const SMDSAbs_ElementType theType)
{
+ bool shapeChanges = ( myShape != 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;
- for ( int i = 0; i < 4; ++i )
+ if ( shapeChanges )
{
- 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() );
- }
+ 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() );
+ }
- clearClassifiers();
- myClassifiers.resize( shapesMap.Extent() );
- for ( int i = 0; i < shapesMap.Extent(); ++i )
- myClassifiers[ i ] = new TClassifier( shapesMap( i+1 ), myToler );
+ clearClassifiers();
+ myClassifiers.resize( shapesMap.Extent() );
+ for ( int i = 0; i < shapesMap.Extent(); ++i )
+ myClassifiers[ i ].Init( shapesMap( i+1 ), myToler );
+ }
if ( theType == SMDSAbs_Node )
{
void ElementsOnShape::clearClassifiers()
{
- for ( size_t i = 0; i < myClassifiers.size(); ++i )
- delete myClassifiers[ i ];
+ // for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ // delete myClassifiers[ i ];
myClassifiers.clear();
+
+ delete myOctree;
+ myOctree = 0;
}
-bool ElementsOnShape::IsSatisfy (long elemId)
+bool ElementsOnShape::IsSatisfy( long elemId )
{
const SMDS_Mesh* mesh = myMeshModifTracer.GetMesh();
const SMDS_MeshElement* elem =
gp_XYZ centerXYZ (0, 0, 0);
+ if ( !myOctree && myClassifiers.size() > 5 )
+ {
+ myWorkClassifiers.resize( myClassifiers.size() );
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ myWorkClassifiers[ i ] = & myClassifiers[ i ];
+ myOctree = new OctreeClassifier( myWorkClassifiers );
+ }
+
SMDS_ElemIteratorPtr aNodeItr = elem->nodesIterator();
while (aNodeItr->more() && (isSatisfy == myAllNodesFlag))
{
isNodeOut = true;
if ( !getNodeIsOut( aPnt._node, isNodeOut ))
{
- for ( size_t i = 0; i < myClassifiers.size() && isNodeOut; ++i )
- isNodeOut = myClassifiers[i]->IsOut( aPnt );
+ if ( myOctree )
+ {
+ myWorkClassifiers.clear();
+ myOctree->GetClassifiersAtPoint( aPnt, myWorkClassifiers );
+ for ( size_t i = 0; i < myWorkClassifiers.size(); ++i )
+ myWorkClassifiers[i]->SetChecked( false );
+
+ for ( size_t i = 0; i < myWorkClassifiers.size() && isNodeOut; ++i )
+ if ( !myWorkClassifiers[i]->IsChecked() )
+ isNodeOut = myWorkClassifiers[i]->IsOut( aPnt );
+ }
+ else
+ {
+ 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[0]->ShapeType() == TopAbs_SOLID)
+ 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 ( myOctree )
+ for ( size_t i = 0; i < myWorkClassifiers.size() && !isSatisfy; ++i )
+ isSatisfy = ! myWorkClassifiers[i]->IsOut( centerXYZ );
+ else
+ for ( size_t i = 0; i < myClassifiers.size() && !isSatisfy; ++i )
+ isSatisfy = ! myClassifiers[i].IsOut( centerXYZ );
}
return isSatisfy;
}
-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)
+void ElementsOnShape::Classifier::Init( const TopoDS_Shape& theShape,
+ double theTol,
+ const Bnd_B3d* theBox )
{
myShape = theShape;
myTol = theTol;
+ myFlags = 0;
+
+ bool isShapeBox = false;
switch ( myShape.ShapeType() )
{
- case TopAbs_SOLID: {
- if ( isBox( theShape ))
+ case TopAbs_SOLID:
+ {
+ if (( isShapeBox = isBox( theShape )))
{
- myIsOutFun = & ElementsOnShape::TClassifier::isOutOfBox;
+ myIsOutFun = & ElementsOnShape::Classifier::isOutOfBox;
}
else
{
- mySolidClfr.Load(theShape);
- myIsOutFun = & ElementsOnShape::TClassifier::isOutOfSolid;
+ mySolidClfr = new BRepClass3d_SolidClassifier(theShape);
+ myIsOutFun = & ElementsOnShape::Classifier::isOutOfSolid;
}
break;
}
- case TopAbs_FACE: {
+ 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;
+ myIsOutFun = & ElementsOnShape::Classifier::isOutOfFace;
break;
}
- case TopAbs_EDGE: {
+ case TopAbs_EDGE:
+ {
Standard_Real u1, u2;
- Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge(theShape), u1, u2);
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( TopoDS::Edge( theShape ), u1, u2);
myProjEdge.Init(curve, u1, u2);
- myIsOutFun = & ElementsOnShape::TClassifier::isOutOfEdge;
+ myIsOutFun = & ElementsOnShape::Classifier::isOutOfEdge;
break;
}
- case TopAbs_VERTEX:{
+ case TopAbs_VERTEX:
+ {
myVertexXYZ = BRep_Tool::Pnt( TopoDS::Vertex( theShape ) );
- myIsOutFun = & ElementsOnShape::TClassifier::isOutOfVertex;
+ myIsOutFun = & ElementsOnShape::Classifier::isOutOfVertex;
break;
}
default:
- throw SALOME_Exception("Programmer error in usage of ElementsOnShape::TClassifier");
+ throw SALOME_Exception("Programmer error in usage of ElementsOnShape::Classifier");
+ }
+
+ if ( !isShapeBox )
+ {
+ if ( theBox )
+ {
+ myBox = *theBox;
+ }
+ else
+ {
+ Bnd_Box box;
+ BRepBndLib::Add( myShape, box );
+ myBox.Clear();
+ myBox.Add( box.CornerMin() );
+ myBox.Add( box.CornerMax() );
+ gp_XYZ halfSize = 0.5 * ( box.CornerMax().XYZ() - box.CornerMin().XYZ() );
+ for ( int iDim = 1; iDim <= 3; ++iDim )
+ {
+ double x = halfSize.Coord( iDim );
+ halfSize.SetCoord( iDim, x + Max( myTol, 1e-2 * x ));
+ }
+ myBox.SetHSize( halfSize );
+ }
}
}
-bool ElementsOnShape::TClassifier::isOutOfSolid (const gp_Pnt& p)
+ElementsOnShape::Classifier::~Classifier()
{
- mySolidClfr.Perform( p, myTol );
- return ( mySolidClfr.State() != TopAbs_IN && mySolidClfr.State() != TopAbs_ON );
+ delete mySolidClfr; mySolidClfr = 0;
}
-bool ElementsOnShape::TClassifier::isOutOfBox (const gp_Pnt& p)
+bool ElementsOnShape::Classifier::isOutOfSolid (const gp_Pnt& p)
+{
+ mySolidClfr->Perform( p, myTol );
+ return ( mySolidClfr->State() != TopAbs_IN && mySolidClfr->State() != TopAbs_ON );
+}
+
+bool ElementsOnShape::Classifier::isOutOfBox (const gp_Pnt& p)
{
return myBox.IsOut( p.XYZ() );
}
-bool ElementsOnShape::TClassifier::isOutOfFace (const gp_Pnt& p)
+bool ElementsOnShape::Classifier::isOutOfFace (const gp_Pnt& p)
{
myProjFace.Perform( p );
if ( myProjFace.IsDone() && myProjFace.LowerDistance() <= myTol )
return true;
}
-bool ElementsOnShape::TClassifier::isOutOfEdge (const gp_Pnt& p)
+bool ElementsOnShape::Classifier::isOutOfEdge (const gp_Pnt& p)
{
myProjEdge.Perform( p );
return ! ( myProjEdge.NbPoints() > 0 && myProjEdge.LowerDistance() <= myTol );
}
-bool ElementsOnShape::TClassifier::isOutOfVertex(const gp_Pnt& p)
+bool ElementsOnShape::Classifier::isOutOfVertex(const gp_Pnt& p)
{
return ( myVertexXYZ.Distance( p ) > myTol );
}
-bool ElementsOnShape::TClassifier::isBox (const TopoDS_Shape& theShape)
+bool ElementsOnShape::Classifier::isBox (const TopoDS_Shape& theShape)
{
TopTools_IndexedMapOfShape vMap;
TopExp::MapShapes( theShape, TopAbs_VERTEX, vMap );
return true;
}
+ElementsOnShape::
+OctreeClassifier::OctreeClassifier( const std::vector< ElementsOnShape::Classifier* >& classifiers )
+ :SMESH_Octree( new SMESH_TreeLimit )
+{
+ myClassifiers = classifiers;
+ compute();
+}
+
+ElementsOnShape::
+OctreeClassifier::OctreeClassifier( const OctreeClassifier* otherTree,
+ const std::vector< ElementsOnShape::Classifier >& clsOther,
+ std::vector< ElementsOnShape::Classifier >& cls )
+ :SMESH_Octree( new SMESH_TreeLimit )
+{
+ myBox = new Bnd_B3d( *otherTree->getBox() );
+
+ if (( myIsLeaf = otherTree->isLeaf() ))
+ {
+ myClassifiers.resize( otherTree->myClassifiers.size() );
+ for ( size_t i = 0; i < otherTree->myClassifiers.size(); ++i )
+ {
+ int ind = otherTree->myClassifiers[i] - & clsOther[0];
+ myClassifiers[ i ] = & cls[ ind ];
+ }
+ }
+ else if ( otherTree->myChildren )
+ {
+ myChildren = new SMESH_Tree< Bnd_B3d, 8 > * [ 8 ];
+ for ( int i = 0; i < nbChildren(); i++ )
+ myChildren[i] =
+ new OctreeClassifier( static_cast<const OctreeClassifier*>( otherTree->myChildren[i]),
+ clsOther, cls );
+ }
+}
+
+void ElementsOnShape::
+OctreeClassifier::GetClassifiersAtPoint( const gp_XYZ& point,
+ std::vector< ElementsOnShape::Classifier* >& result )
+{
+ if ( getBox()->IsOut( point ))
+ return;
+
+ if ( isLeaf() )
+ {
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ if ( !myClassifiers[i]->GetBndBox()->IsOut( point ))
+ result.push_back( myClassifiers[i] );
+ }
+ else
+ {
+ for (int i = 0; i < nbChildren(); i++)
+ ((OctreeClassifier*) myChildren[i])->GetClassifiersAtPoint( point, result );
+ }
+}
+
+void ElementsOnShape::OctreeClassifier::buildChildrenData()
+{
+ // distribute myClassifiers among myChildren
+
+ const int childFlag[8] = { 0x0000001,
+ 0x0000002,
+ 0x0000004,
+ 0x0000008,
+ 0x0000010,
+ 0x0000020,
+ 0x0000040,
+ 0x0000080 };
+ int nbInChild[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ {
+ for ( int j = 0; j < nbChildren(); j++ )
+ {
+ if ( !myClassifiers[i]->GetBndBox()->IsOut( *myChildren[j]->getBox() ))
+ {
+ myClassifiers[i]->SetFlag( childFlag[ j ]);
+ ++nbInChild[ j ];
+ }
+ }
+ }
+
+ for ( int j = 0; j < nbChildren(); j++ )
+ {
+ OctreeClassifier* child = static_cast<OctreeClassifier*>( myChildren[ j ]);
+ child->myClassifiers.resize( nbInChild[ j ]);
+ for ( size_t i = 0; nbInChild[ j ] && i < myClassifiers.size(); ++i )
+ {
+ if ( myClassifiers[ i ]->IsSetFlag( childFlag[ j ]))
+ {
+ --nbInChild[ j ];
+ child->myClassifiers[ nbInChild[ j ]] = myClassifiers[ i ];
+ myClassifiers[ i ]->UnsetFlag( childFlag[ j ]);
+ }
+ }
+ }
+ SMESHUtils::FreeVector( myClassifiers );
+
+ // define if a child isLeaf()
+ for ( int i = 0; i < nbChildren(); i++ )
+ {
+ OctreeClassifier* child = static_cast<OctreeClassifier*>( myChildren[ i ]);
+ child->myIsLeaf = ( child->myClassifiers.size() <= 5 );
+ }
+}
+
+Bnd_B3d* ElementsOnShape::OctreeClassifier::buildRootBox()
+{
+ Bnd_B3d* box = new Bnd_B3d;
+ for ( size_t i = 0; i < myClassifiers.size(); ++i )
+ box->Add( *myClassifiers[i]->GetBndBox() );
+ return box;
+}
/*
Class : BelongToGeom
BelongToGeom::BelongToGeom()
: myMeshDS(NULL),
- myType(SMDSAbs_All),
+ myType(SMDSAbs_NbElementTypes),
myIsSubshape(false),
myTolerance(Precision::Confusion())
{}
+Predicate* BelongToGeom::clone() const
+{
+ BelongToGeom* cln = new BelongToGeom( *this );
+ cln->myElementsOnShapePtr.reset( static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() ));
+ return cln;
+}
+
void BelongToGeom::SetMesh( const SMDS_Mesh* theMesh )
{
- myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
- init();
+ if ( myMeshDS != theMesh )
+ {
+ myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
+ init();
+ }
}
void BelongToGeom::SetGeom( const TopoDS_Shape& theShape )
{
- myShape = theShape;
- init();
+ if ( myShape != theShape )
+ {
+ myShape = theShape;
+ init();
+ }
}
static bool IsSubShape (const TopTools_IndexedMapOfShape& theMap,
- const TopoDS_Shape& theShape)
+ const TopoDS_Shape& theShape)
{
if (theMap.Contains(theShape)) return true;
void BelongToGeom::init()
{
- if (!myMeshDS || myShape.IsNull()) return;
+ if ( !myMeshDS || myShape.IsNull() ) return;
// is sub-shape of main shape?
TopoDS_Shape aMainShape = myMeshDS->ShapeToMesh();
}
else {
TopTools_IndexedMapOfShape aMap;
- TopExp::MapShapes(aMainShape, aMap);
- myIsSubshape = IsSubShape(aMap, myShape);
+ TopExp::MapShapes( aMainShape, aMap );
+ myIsSubshape = IsSubShape( aMap, myShape );
+ if ( myIsSubshape )
+ {
+ aMap.Clear();
+ TopExp::MapShapes( myShape, aMap );
+ mySubShapesIDs.Clear();
+ for ( int i = 1; i <= aMap.Extent(); ++i )
+ {
+ int subID = myMeshDS->ShapeToIndex( aMap( i ));
+ if ( subID > 0 )
+ mySubShapesIDs.Add( subID );
+ }
+ }
}
//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);
+ if ( !myElementsOnShapePtr )
+ 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 myElementsOnShapePtr->IsSatisfy(theId);
}
- // Case of submesh
+ // Case of sub-mesh
+
if (myType == SMDSAbs_Node)
{
- if( const SMDS_MeshNode* aNode = myMeshDS->FindNode( theId ) )
+ 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 ));
- default:;
- }
+ else
+ return mySubShapesIDs.Contains( aNode->getshapeId() );
}
}
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() )
+ if ( anElem->GetType() == myType )
{
- 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 ));
- default:;
- }
+ if ( anElem->getshapeId() < 1 )
+ return myElementsOnShapePtr->IsSatisfy(theId);
+ else
+ return mySubShapesIDs.Contains( anElem->getshapeId() );
}
}
}
void BelongToGeom::SetType (SMDSAbs_ElementType theType)
{
- myType = theType;
- init();
+ if ( myType != theType )
+ {
+ myType = theType;
+ init();
+ }
}
SMDSAbs_ElementType BelongToGeom::GetType() const
void BelongToGeom::SetTolerance (double theTolerance)
{
myTolerance = theTolerance;
- if (!myIsSubshape)
- init();
+ init();
}
double BelongToGeom::GetTolerance()
/*
Class : LyingOnGeom
Description : Predicate for verifying whether entiy lying or partially lying on
- specified geometrical support
+ specified geometrical support
*/
LyingOnGeom::LyingOnGeom()
: myMeshDS(NULL),
- myType(SMDSAbs_All),
+ myType(SMDSAbs_NbElementTypes),
myIsSubshape(false),
myTolerance(Precision::Confusion())
{}
+Predicate* LyingOnGeom::clone() const
+{
+ LyingOnGeom* cln = new LyingOnGeom( *this );
+ cln->myElementsOnShapePtr.reset( static_cast<ElementsOnShape*>( myElementsOnShapePtr->clone() ));
+ return cln;
+}
+
void LyingOnGeom::SetMesh( const SMDS_Mesh* theMesh )
{
- myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
- init();
+ if ( myMeshDS != theMesh )
+ {
+ myMeshDS = dynamic_cast<const SMESHDS_Mesh*>(theMesh);
+ init();
+ }
}
void LyingOnGeom::SetGeom( const TopoDS_Shape& theShape )
{
- myShape = theShape;
- init();
+ if ( myShape != theShape )
+ {
+ myShape = theShape;
+ init();
+ }
}
void LyingOnGeom::init()
mySubShapesIDs.Add( subID );
}
}
- else
+ // else // to be always ready to check an element not bound to geometry
{
- myElementsOnShapePtr.reset(new ElementsOnShape());
- myElementsOnShapePtr->SetTolerance(myTolerance);
- myElementsOnShapePtr->SetAllNodes(false); // lays on, while true means "belong"
- myElementsOnShapePtr->SetMesh(myMeshDS);
- myElementsOnShapePtr->SetShape(myShape, myType);
+ if ( !myElementsOnShapePtr )
+ myElementsOnShapePtr.reset( new ElementsOnShape() );
+ myElementsOnShapePtr->SetTolerance( myTolerance );
+ myElementsOnShapePtr->SetAllNodes( false ); // lays on, while true means "belong"
+ myElementsOnShapePtr->SetMesh( myMeshDS );
+ myElementsOnShapePtr->SetShape( myShape, myType );
}
}
if ( mySubShapesIDs.Contains( elem->getshapeId() ))
return true;
- if ( elem->GetType() != SMDSAbs_Node )
+ if ( elem->GetType() != SMDSAbs_Node && elem->GetType() == myType )
{
SMDS_ElemIteratorPtr nodeItr = elem->nodesIterator();
while ( nodeItr->more() )
void LyingOnGeom::SetType( SMDSAbs_ElementType theType )
{
- myType = theType;
- init();
+ if ( myType != theType )
+ {
+ myType = theType;
+ init();
+ }
}
SMDSAbs_ElementType LyingOnGeom::GetType() const
void LyingOnGeom::SetTolerance (double theTolerance)
{
myTolerance = theTolerance;
- if (!myIsSubshape)
- init();
+ 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)
{}