1 // Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // SMESH SMDS : implementation of Salome mesh data structure
26 #pragma warning(disable:4786)
29 #include "SMDS_MeshNode.hxx"
31 #include "SMDS_ElementFactory.hxx"
32 #include "SMDS_Mesh.hxx"
33 #include "SMDS_SetIterator.hxx"
34 #include "SMDS_SpacePosition.hxx"
36 #include <utilities.h>
37 #include <Utils_SALOME_Exception.hxx>
40 #include <boost/make_shared.hpp>
42 void SMDS_MeshNode::init(double x, double y, double z)
44 SMDS_UnstructuredGrid * grid = getGrid();
45 vtkPoints *points = grid->GetPoints();
46 points->InsertPoint( GetVtkID(), x, y, z );
47 if ( grid->HasLinks() )
48 grid->GetLinks()->ResizeForPoint( GetVtkID() );
51 //=======================================================================
52 //function : RemoveInverseElement
54 //=======================================================================
56 void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem)
58 if ( getGrid()->HasLinks() )
59 getGrid()->RemoveReferenceToCell( GetVtkID(), elem->GetVtkID());
62 //=======================================================================
65 //=======================================================================
67 void SMDS_MeshNode::Print(ostream & OS) const
69 OS << "Node <" << GetID() << "> : X = " << X() << " Y = "
70 << Y() << " Z = " << Z() << endl;
73 //=======================================================================
74 //function : SetPosition
76 //=======================================================================
78 void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos, int shapeID)
80 myHolder->SetPosition( this, aPos, shapeID );
83 //=======================================================================
84 //function : GetPosition
85 //purpose : Return a position of this node on shape
86 //warning : result is std::unique_ptr !
87 //=======================================================================
89 SMDS_PositionPtr SMDS_MeshNode::GetPosition() const
91 return myHolder->GetPosition( this );
94 //=======================================================================
96 * \brief Iterator on list of elements
98 //=======================================================================
102 struct InverseIterator: public SMDS_ElemIterator
104 const SMDS_Mesh* myMesh;
106 std::vector<vtkIdType> myCellList;
108 InverseIterator(const SMDS_Mesh * mesh = 0,
109 const vtkIdType* cells = 0,
110 const int ncells = 0,
111 SMDSAbs_ElementType type = SMDSAbs_All)
112 : myMesh(mesh), myIter(0)
116 myCellList.reserve( ncells );
117 if (type == SMDSAbs_All)
119 myCellList.assign( cells, cells + ncells );
123 for (int i = 0; i < ncells; i++)
125 int vtkId = cells[i];
126 int smdsId = myMesh->FromVtkToSmds( vtkId );
127 const SMDS_MeshElement* elem = myMesh->FindElement( smdsId );
128 if ( elem->GetType() == type )
130 myCellList.push_back(vtkId);
139 return ( myIter < myCellList.size() );
142 const SMDS_MeshElement* next()
144 int vtkId = myCellList[ myIter++ ];
145 int smdsId = myMesh->FromVtkToSmds( vtkId );
146 const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
149 MESSAGE("InverseIterator problem Null element");
150 throw SALOME_Exception("InverseIterator problem Null element");
156 //=======================================================================
158 * \brief Iterator on a node
160 //=======================================================================
162 template< class ELEM_ITERATOR >
163 struct Iterator : public ELEM_ITERATOR
165 typedef typename ELEM_ITERATOR::value_type element_type;
166 const SMDS_MeshNode* myNode;
168 Iterator( const SMDS_MeshNode* n ): myNode( n ) {}
174 virtual element_type next()
176 element_type res = static_cast<element_type>( myNode );
183 SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const
185 if ( GetMesh()->NbElements() > 0 ) // avoid building links
187 vtkCellLinks::Link& l = getGrid()->GetLinks()->GetLink( GetVtkID() );
188 return boost::make_shared< InverseIterator >( GetMesh(), l.cells, l.ncells, type );
192 return boost::make_shared< InverseIterator >();
196 SMDS_ElemIteratorPtr SMDS_MeshNode::nodesIterator() const
198 return boost::make_shared< Iterator< SMDS_ElemIterator > >( this );
201 SMDS_NodeIteratorPtr SMDS_MeshNode::nodeIterator() const
203 return boost::make_shared< Iterator< SMDS_NodeIterator > >( this );
206 const SMDS_MeshNode* SMDS_MeshNode::GetNode(const int ind) const
208 return ind == 0 ? this : 0;
211 double* SMDS_MeshNode::getCoord() const
213 return getGrid()->GetPoint( GetVtkID() );
216 double SMDS_MeshNode::X() const
218 double *coord = getCoord();
222 double SMDS_MeshNode::Y() const
224 double *coord = getCoord();
228 double SMDS_MeshNode::Z() const
230 double *coord = getCoord();
234 //================================================================================
236 * \brief thread safe getting coords
238 //================================================================================
240 void SMDS_MeshNode::GetXYZ(double xyz[3]) const
242 return getGrid()->GetPoint( GetVtkID(), xyz );
245 //================================================================================
246 void SMDS_MeshNode::setXYZ( double x, double y, double z )
248 vtkPoints *points = getGrid()->GetPoints();
249 points->InsertPoint( GetVtkID(), x, y, z );
250 //GetMesh()->adjustBoundingBox(x, y, z);
251 GetMesh()->setMyModified();
254 //=======================================================================
255 //function : AddInverseElement
257 //=======================================================================
258 void SMDS_MeshNode::AddInverseElement( const SMDS_MeshElement* elem )
260 SMDS_UnstructuredGrid* grid = getGrid();
261 if ( grid->HasLinks() )
263 vtkCellLinks *Links = grid->GetLinks();
264 Links->ResizeCellList( GetVtkID(), 1 );
265 Links->AddCellReference( elem->GetVtkID(), GetVtkID() );
269 //=======================================================================
270 //function : ClearInverseElements
272 //=======================================================================
273 void SMDS_MeshNode::ClearInverseElements()
275 getGrid()->ResizeCellList( GetVtkID(), 0);
278 //================================================================================
280 * \brief Count inverse elements of given type
282 //================================================================================
284 int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
287 SMDS_Mesh *mesh = GetMesh();
288 if ( mesh->NbElements() > 0 ) // avoid building links
290 vtkCellLinks::Link& l = mesh->GetGrid()->GetLinks()->GetLink( GetVtkID() );
292 if ( type == SMDSAbs_All )
295 for ( int i = 0; i < l.ncells; i++ )
297 const SMDS_MeshElement* elem = mesh->FindElement( mesh->FromVtkToSmds( l.cells[i] ));
298 nb += ( elem->GetType() == type );