Salome HOME
485ea4077e56edff5c099b6481bd83293675504a
[tools/medcoupling.git] / src / INTERP_KERNEL / MeshRegion.txx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #ifndef __MESHREGION_TXX__
20 #define __MESHREGION_TXX__
21
22 #include "MeshRegion.hxx"
23
24 #include "MeshElement.txx"
25 #include "MeshUtils.hxx"
26
27 namespace INTERP_KERNEL
28 {
29     
30   /**
31    * Default constructor
32    * 
33    */
34   template<class ConnType>
35   MeshRegion<ConnType>::MeshRegion():_box(0)
36   {
37   }
38     
39   /**
40    * Destructor
41    *
42    */
43   template<class ConnType>
44   MeshRegion<ConnType>::~MeshRegion()
45   {
46     delete _box;
47   }
48   
49   /**
50    * Adds an element to the region, updating the bounding box. If the bounding box does not yet
51    * exist, it is created here. This creation is delayed to make it possible to have empty MeshRegions
52    *
53    * @param element pointer to element to add to region
54    * @param mesh    mesh to which element belongs
55    *
56    */
57   template<class ConnType>
58   template<class MyMeshType>
59   void MeshRegion<ConnType>::addElement(MeshElement<ConnType>* const element, const MyMeshType& mesh)
60   {
61     _elements.push_back(element);
62
63     const unsigned char numNodes = element->getNumberOfNodes();
64     const ConnType elemIdx = element->getIndex();
65        
66     if(_box == 0)
67       {
68         const double** pts = new const double*[numNodes];
69
70         // get coordinates of the nodes of the element
71         for(unsigned char i = 0 ; i < numNodes ; ++i)
72           {
73             pts[i] = getCoordsOfNode(i, OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(elemIdx), mesh);
74           }
75            
76         _box = new BoundingBox(pts, numNodes);
77         delete [] pts;
78
79       } else {
80
81       for(unsigned char i = 0 ; i < numNodes ; ++i)
82         {
83           const double* pt = getCoordsOfNode(i, OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(elemIdx), mesh);
84           _box->updateWithPoint(pt);
85         }
86     }
87   }
88
89   /**
90    * Splits the region in two along the given axis, copying the elements with bounding boxes whose maximum
91    * coordinate along the axis are smaller than the middle of the bounding box of this region in region1. The
92    * rest of the elements are copied to region2.
93    *
94    * @param region1 region in which to store one half of this region
95    * @param region2 region in which to store the other of this region
96    * @param coord   coordinate of BoundingBox to use when splitting the region
97    * @param mesh    mesh to which region belongs
98    *
99    */
100   template<class ConnType>
101   template<class MyMeshType>
102   void MeshRegion<ConnType>::split(MeshRegion<ConnType>& region1, MeshRegion<ConnType>& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh)
103   {
104     // create ordering
105     ElementBBoxOrder cmp(coord);
106
107     // sort elements by their bounding boxes
108     std::sort(_elements.begin(), _elements.end(), cmp);
109
110     // put the first half of the elements in region1 and the 
111     // rest in region2
112     typename std::vector< MeshElement<ConnType> *>::const_iterator iter = _elements.begin();
113     int elemCount = 0;
114
115     while(elemCount < static_cast<int>(_elements.size() / 2))
116       {
117         region1.addElement(*iter, mesh);
118         ++iter;
119         ++elemCount;
120       }
121
122     while(iter != _elements.end())
123       {
124         region2.addElement(*iter, mesh);
125         ++iter;
126       }
127   }
128
129   /**
130    * Determines if a given element can intersect the elements of this region by 
131    * testing whether the bounding box of the region intersects the bounding box of the element.
132    * Note that the test is only true in one direction : if the bounding boxes are disjoint, the
133    * element cannot intersect any of the elements in the region, but if they are not disjoint, the 
134    * element may or may not do so.
135    *
136    * @param   elem  Element with which to test for disjoint-ness
137    * @return  true if the bounding box of the element is disjoint with the bounding box of the region, false otherwise
138    */
139   template<class ConnType>
140   bool MeshRegion<ConnType>::isDisjointWithElementBoundingBox(const MeshElement<ConnType>& elem) const
141   {
142     const BoundingBox* elemBox = elem.getBoundingBox();
143
144     assert(_box != 0);
145     assert(elemBox != 0);
146
147     return _box->isDisjointWith(*elemBox);
148   }  
149
150   
151 }
152
153 #endif