X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMDS%2FSMDS_MeshNode.cxx;h=542798277413e60557770323318340af367a90b3;hp=c672fe702e0d856e35453df8204b4036653246f7;hb=a5ebdbe87e2c7f21e10a0db66022e6ca0f9ad1c5;hpb=e4737e85f0da6d3f90fd08f6be1c2825195fe16f diff --git a/src/SMDS/SMDS_MeshNode.cxx b/src/SMDS/SMDS_MeshNode.cxx index c672fe702..542798277 100644 --- a/src/SMDS/SMDS_MeshNode.cxx +++ b/src/SMDS/SMDS_MeshNode.cxx @@ -1,205 +1,269 @@ -// SMESH SMDS : implementaion of Salome mesh data structure +// 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 +// +// 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// 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. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// SMESH SMDS : implementation of Salome mesh data structure +// +#ifdef _MSC_VER +#pragma warning(disable:4786) +#endif #include "SMDS_MeshNode.hxx" + +#include "SMDS_ElementFactory.hxx" +#include "SMDS_Mesh.hxx" +#include "SMDS_SetIterator.hxx" #include "SMDS_SpacePosition.hxx" -#include "SMDS_IteratorOfElements.hxx" -using namespace std; +#include +#include +#include -//======================================================================= -//function : SMDS_MeshNode -//purpose : -//======================================================================= +#include -SMDS_MeshNode::SMDS_MeshNode(double x, double y, double z): - myX(x), myY(y), myZ(z), - myPosition(SMDS_SpacePosition::originSpacePosition()) +void SMDS_MeshNode::init(double x, double y, double z) { + SMDS_UnstructuredGrid * grid = getGrid(); + vtkPoints *points = grid->GetPoints(); + points->InsertPoint( GetVtkID(), x, y, z ); + if ( grid->HasLinks() ) + grid->GetLinks()->ResizeForPoint( GetVtkID() ); } //======================================================================= //function : RemoveInverseElement -//purpose : +//purpose : //======================================================================= -void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * parent) +void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem) { - myInverseElements.erase(parent); + if ( getGrid()->HasLinks() ) + getGrid()->RemoveReferenceToCell( GetVtkID(), elem->GetVtkID()); } //======================================================================= //function : Print -//purpose : +//purpose : //======================================================================= void SMDS_MeshNode::Print(ostream & OS) const { - OS << "Node <" << GetID() << "> : X = " << myX << " Y = " - << myY << " Z = " << myZ << endl; + OS << "Node <" << GetID() << "> : X = " << X() << " Y = " + << Y() << " Z = " << Z() << endl; } //======================================================================= //function : SetPosition -//purpose : +//purpose : //======================================================================= -void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos) +void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos, int shapeID) { - myPosition = aPos; + myHolder->SetPosition( this, aPos, shapeID ); } //======================================================================= //function : GetPosition -//purpose : +//purpose : Return a position of this node on shape +//warning : result is std::unique_ptr ! //======================================================================= -const SMDS_PositionPtr& SMDS_MeshNode::GetPosition() const +SMDS_PositionPtr SMDS_MeshNode::GetPosition() const { - return myPosition; + return myHolder->GetPosition( this ); } -class SMDS_MeshNode_MyInvIterator:public SMDS_ElemIterator +//======================================================================= +/*! + * \brief Iterator on list of elements + */ +//======================================================================= + +namespace { - const set& mySet; - set::iterator myIterator; - public: - SMDS_MeshNode_MyInvIterator(const set& s): - mySet(s) + struct InverseIterator: public SMDS_ElemIterator { - myIterator=mySet.begin(); - } + const SMDS_Mesh* myMesh; + size_t myIter; + std::vector myCellList; + + InverseIterator(const SMDS_Mesh * mesh = 0, + const vtkIdType* cells = 0, + const int ncells = 0, + SMDSAbs_ElementType type = SMDSAbs_All) + : myMesh(mesh), myIter(0) + { + if ( ncells ) + { + myCellList.reserve( ncells ); + if (type == SMDSAbs_All) + { + myCellList.assign( cells, cells + ncells ); + } + else + { + for (int i = 0; i < ncells; i++) + { + int vtkId = cells[i]; + int smdsId = myMesh->FromVtkToSmds( vtkId ); + const SMDS_MeshElement* elem = myMesh->FindElement( smdsId ); + if ( elem->GetType() == type ) + { + myCellList.push_back(vtkId); + } + } + } + } + } - bool more() - { - return myIterator!=mySet.end(); - } + bool more() + { + return ( myIter < myCellList.size() ); + } - const SMDS_MeshElement* next() - { - const SMDS_MeshElement* current=*myIterator; - myIterator++; - return current; - } -}; + const SMDS_MeshElement* next() + { + int vtkId = myCellList[ myIter++ ]; + int smdsId = myMesh->FromVtkToSmds( vtkId ); + const SMDS_MeshElement* elem = myMesh->FindElement(smdsId); + if (!elem) + { + MESSAGE("InverseIterator problem Null element"); + throw SALOME_Exception("InverseIterator problem Null element"); + } + return elem; + } + }; -SMDS_ElemIteratorPtr SMDS_MeshNode:: - GetInverseElementIterator() const -{ - return SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyInvIterator(myInverseElements)); -} + //======================================================================= + /*! + * \brief Iterator on a node + */ + //======================================================================= -// Same as GetInverseElementIterator but the create iterator only return -// wanted type elements. -class SMDS_MeshNode_MyIterator:public SMDS_ElemIterator -{ - set mySet; - set::iterator myIterator; - public: - SMDS_MeshNode_MyIterator(SMDSAbs_ElementType type, - const set& s) + template< class ELEM_ITERATOR > + struct Iterator : public ELEM_ITERATOR { - const SMDS_MeshElement * e; - bool toInsert; - set::iterator it=s.begin(); - while(it!=s.end()) + typedef typename ELEM_ITERATOR::value_type element_type; + const SMDS_MeshNode* myNode; + + Iterator( const SMDS_MeshNode* n ): myNode( n ) {} + + virtual bool more() { - e=*it; - switch(type) - { - case SMDSAbs_Edge: toInsert=true; break; - case SMDSAbs_Face: toInsert=(e->GetType()!=SMDSAbs_Edge); break; - case SMDSAbs_Volume: toInsert=(e->GetType()==SMDSAbs_Volume); break; - } - if(toInsert) mySet.insert(e); - it++; + return myNode; } - myIterator=mySet.begin(); - } + virtual element_type next() + { + element_type res = static_cast( myNode ); + myNode = 0; + return res; + } + }; +} - bool more() +SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const +{ + if ( GetMesh()->NbElements() > 0 ) // avoid building links { - return myIterator!=mySet.end(); + vtkCellLinks::Link& l = getGrid()->GetLinks()->GetLink( GetVtkID() ); + return boost::make_shared< InverseIterator >( GetMesh(), l.cells, l.ncells, type ); } - - const SMDS_MeshElement* next() + else { - const SMDS_MeshElement* current=*myIterator; - myIterator++; - return current; + return boost::make_shared< InverseIterator >(); } -}; +} -SMDS_ElemIteratorPtr SMDS_MeshNode:: - elementsIterator(SMDSAbs_ElementType type) const +SMDS_ElemIteratorPtr SMDS_MeshNode::nodesIterator() const { - if(type==SMDSAbs_Node) - return SMDS_MeshElement::elementsIterator(SMDSAbs_Node); - else - return SMDS_ElemIteratorPtr - (new SMDS_IteratorOfElements - (this,type, - SMDS_ElemIteratorPtr(new SMDS_MeshNode_MyIterator(type, myInverseElements)))); + return boost::make_shared< Iterator< SMDS_ElemIterator > >( this ); +} + +SMDS_NodeIteratorPtr SMDS_MeshNode::nodeIterator() const +{ + return boost::make_shared< Iterator< SMDS_NodeIterator > >( this ); } -int SMDS_MeshNode::NbNodes() const +const SMDS_MeshNode* SMDS_MeshNode::GetNode(const int ind) const { - return 1; + return ind == 0 ? this : 0; +} + +double* SMDS_MeshNode::getCoord() const +{ + return getGrid()->GetPoint( GetVtkID() ); } double SMDS_MeshNode::X() const { - return myX; + double *coord = getCoord(); + return coord[0]; } double SMDS_MeshNode::Y() const { - return myY; + double *coord = getCoord(); + return coord[1]; } double SMDS_MeshNode::Z() const { - return myZ; + double *coord = getCoord(); + return coord[2]; } -void SMDS_MeshNode::setXYZ(double x, double y, double z) +//================================================================================ +/*! + * \brief thread safe getting coords + */ +//================================================================================ + +void SMDS_MeshNode::GetXYZ(double xyz[3]) const { - myX=x; - myY=y; - myZ=z; + return getGrid()->GetPoint( GetVtkID(), xyz ); } -SMDSAbs_ElementType SMDS_MeshNode::GetType() const +//================================================================================ +void SMDS_MeshNode::setXYZ( double x, double y, double z ) { - return SMDSAbs_Node; + vtkPoints *points = getGrid()->GetPoints(); + points->InsertPoint( GetVtkID(), x, y, z ); + //GetMesh()->adjustBoundingBox(x, y, z); + GetMesh()->setMyModified(); } //======================================================================= //function : AddInverseElement //purpose : //======================================================================= -void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) +void SMDS_MeshNode::AddInverseElement( const SMDS_MeshElement* elem ) { - myInverseElements.insert(ME); + SMDS_UnstructuredGrid* grid = getGrid(); + if ( grid->HasLinks() ) + { + vtkCellLinks *Links = grid->GetLinks(); + Links->ResizeCellList( GetVtkID(), 1 ); + Links->AddCellReference( elem->GetVtkID(), GetVtkID() ); + } } //======================================================================= @@ -208,27 +272,31 @@ void SMDS_MeshNode::AddInverseElement(const SMDS_MeshElement* ME) //======================================================================= void SMDS_MeshNode::ClearInverseElements() { - myInverseElements.clear(); + getGrid()->ResizeCellList( GetVtkID(), 0); } -bool SMDS_MeshNode::emptyInverseElements() -{ - return myInverseElements.empty(); -} +//================================================================================ +/*! + * \brief Count inverse elements of given type + */ +//================================================================================ -/////////////////////////////////////////////////////////////////////////////// -/// To be used with STL set -/////////////////////////////////////////////////////////////////////////////// -bool operator<(const SMDS_MeshNode& e1, const SMDS_MeshNode& e2) +int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const { - return e1.GetID()NbElements() > 0 ) // avoid building links + { + vtkCellLinks::Link& l = mesh->GetGrid()->GetLinks()->GetLink( GetVtkID() ); + if ( type == SMDSAbs_All ) + return l.ncells; + + for ( int i = 0; i < l.ncells; i++ ) + { + const SMDS_MeshElement* elem = mesh->FindElement( mesh->FromVtkToSmds( l.cells[i] )); + nb += ( elem->GetType() == type ); + } + } + return nb; +}