1 // Copyright (C) 2007-2022 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>
39 #include <smIdType.hxx>
41 #include <boost/make_shared.hpp>
43 void SMDS_MeshNode::init(double x, double y, double z)
45 SMDS_UnstructuredGrid * grid = getGrid();
46 vtkPoints *points = grid->GetPoints();
47 points->InsertPoint( GetVtkID(), x, y, z );
48 if ( grid->HasLinks() )
49 grid->GetLinks()->ResizeForPoint( GetVtkID() );
52 //=======================================================================
53 //function : RemoveInverseElement
55 //=======================================================================
57 void SMDS_MeshNode::RemoveInverseElement(const SMDS_MeshElement * elem)
59 if ( getGrid()->HasLinks() )
60 getGrid()->RemoveReferenceToCell( GetVtkID(), elem->GetVtkID());
63 //=======================================================================
66 //=======================================================================
68 void SMDS_MeshNode::Print(ostream & OS) const
70 OS << "Node <" << GetID() << "> : X = " << X() << " Y = "
71 << Y() << " Z = " << Z() << endl;
74 //=======================================================================
75 //function : SetPosition
77 //=======================================================================
79 void SMDS_MeshNode::SetPosition(const SMDS_PositionPtr& aPos, int shapeID)
81 myHolder->SetPosition( this, aPos, shapeID );
84 //=======================================================================
85 //function : GetPosition
86 //purpose : Return a position of this node on shape
87 //warning : result is std::unique_ptr !
88 //=======================================================================
90 SMDS_PositionPtr SMDS_MeshNode::GetPosition() const
92 return myHolder->GetPosition( this );
95 //=======================================================================
97 * \brief Iterator on list of elements
99 //=======================================================================
103 struct InverseIterator: public SMDS_ElemIterator
105 const SMDS_Mesh* myMesh;
107 std::vector<vtkIdType> myCellList;
109 InverseIterator(const SMDS_Mesh * mesh = 0,
110 const vtkIdType* cells = 0,
111 const int ncells = 0,
112 SMDSAbs_ElementType type = SMDSAbs_All)
113 : myMesh(mesh), myIter(0)
117 myCellList.reserve( ncells );
118 if (type == SMDSAbs_All)
120 myCellList.assign( cells, cells + ncells );
124 for (int i = 0; i < ncells; i++)
126 vtkIdType vtkId = cells[i];
127 smIdType smdsId = myMesh->FromVtkToSmds( vtkId );
128 const SMDS_MeshElement* elem = myMesh->FindElement( smdsId );
129 if ( elem->GetType() == type )
131 myCellList.push_back(vtkId);
140 return ( myIter < myCellList.size() );
143 const SMDS_MeshElement* next()
145 vtkIdType vtkId = myCellList[ myIter++ ];
146 smIdType smdsId = myMesh->FromVtkToSmds( vtkId );
147 const SMDS_MeshElement* elem = myMesh->FindElement(smdsId);
150 MESSAGE("InverseIterator problem Null element");
151 throw SALOME_Exception("InverseIterator problem Null element");
157 //=======================================================================
159 * \brief Iterator on a node
161 //=======================================================================
163 template< class ELEM_ITERATOR >
164 struct Iterator : public ELEM_ITERATOR
166 typedef typename ELEM_ITERATOR::value_type element_type;
167 const SMDS_MeshNode* myNode;
169 Iterator( const SMDS_MeshNode* n ): myNode( n ) {}
175 virtual element_type next()
177 element_type res = static_cast<element_type>( myNode );
184 SMDS_ElemIteratorPtr SMDS_MeshNode::GetInverseElementIterator(SMDSAbs_ElementType type) const
186 if ( GetMesh()->NbElements() > 0 ) // avoid building links
188 vtkCellLinks::Link& l = getGrid()->GetLinks()->GetLink( GetVtkID() );
189 return boost::make_shared< InverseIterator >( GetMesh(), l.cells, l.ncells, type );
193 return boost::make_shared< InverseIterator >();
197 SMDS_ElemIteratorPtr SMDS_MeshNode::nodesIterator() const
199 return boost::make_shared< Iterator< SMDS_ElemIterator > >( this );
202 SMDS_NodeIteratorPtr SMDS_MeshNode::nodeIterator() const
204 return boost::make_shared< Iterator< SMDS_NodeIterator > >( this );
207 const SMDS_MeshNode* SMDS_MeshNode::GetNode(const int ind) const
209 return ind == 0 ? this : 0;
212 double* SMDS_MeshNode::getCoord() const
214 return getGrid()->GetPoint( GetVtkID() );
217 double SMDS_MeshNode::X() const
219 double *coord = getCoord();
223 double SMDS_MeshNode::Y() const
225 double *coord = getCoord();
229 double SMDS_MeshNode::Z() const
231 double *coord = getCoord();
235 //================================================================================
237 * \brief thread safe getting coords
239 //================================================================================
241 void SMDS_MeshNode::GetXYZ(double xyz[3]) const
243 return getGrid()->GetPoint( GetVtkID(), xyz );
246 //================================================================================
247 void SMDS_MeshNode::setXYZ( double x, double y, double z )
249 vtkPoints *points = getGrid()->GetPoints();
250 points->InsertPoint( GetVtkID(), x, y, z );
251 //GetMesh()->adjustBoundingBox(x, y, z);
252 GetMesh()->setMyModified();
255 //=======================================================================
256 //function : AddInverseElement
258 //=======================================================================
259 void SMDS_MeshNode::AddInverseElement( const SMDS_MeshElement* elem )
261 SMDS_UnstructuredGrid* grid = getGrid();
262 if ( grid->HasLinks() )
264 vtkCellLinks *Links = grid->GetLinks();
265 Links->ResizeCellList( GetVtkID(), 1 );
266 Links->AddCellReference( elem->GetVtkID(), GetVtkID() );
270 //=======================================================================
271 //function : ClearInverseElements
273 //=======================================================================
274 void SMDS_MeshNode::ClearInverseElements()
276 getGrid()->ResizeCellList( GetVtkID(), 0);
279 //================================================================================
281 * \brief Count inverse elements of given type
283 //================================================================================
285 int SMDS_MeshNode::NbInverseElements(SMDSAbs_ElementType type) const
288 SMDS_Mesh *mesh = GetMesh();
289 if ( mesh->NbElements() > 0 ) // avoid building links
291 vtkCellLinks::Link& l = mesh->GetGrid()->GetLinks()->GetLink( GetVtkID() );
293 if ( type == SMDSAbs_All )
296 for ( int i = 0; i < l.ncells; i++ )
298 const SMDS_MeshElement* elem = mesh->FindElement( mesh->FromVtkToSmds( l.cells[i] ));
299 nb += ( elem->GetType() == type );