Salome HOME
484ed7aeab16fd68e23ceca625d94ad43a2d5eef
[modules/med.git] / src / MEDCoupling / MEDCoupling1GTUMesh.cxx
1 // Copyright (C) 2007-2013  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.
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 // Author : Anthony Geay (CEA/DEN)
20
21 #include "MEDCoupling1GTUMesh.hxx"
22 #include "MEDCouplingUMesh.hxx"
23 #include "MEDCouplingFieldDouble.hxx"
24
25 #include "SplitterTetra.hxx"
26
27 using namespace ParaMEDMEM;
28
29 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):_cm(&cm)
30 {
31   setName(name);
32 }
33
34 MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm)
35 {
36 }
37
38 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
39 {
40   if(type==INTERP_KERNEL::NORM_ERROR)
41     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
42   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
43   if(!cm.isDynamic())
44     return MEDCoupling1SGTUMesh::New(name,type);
45   else
46     return MEDCoupling1DGTUMesh::New(name,type);
47 }
48
49 MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
50 {
51   if(!m)
52     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !");
53   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
54   if(gts.size()!=1)
55     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !");
56   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin());
57   if(!cm.isDynamic())
58     return MEDCoupling1SGTUMesh::New(m);
59   else
60     return MEDCoupling1DGTUMesh::New(m);
61 }
62
63 const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const throw(INTERP_KERNEL::Exception)
64 {
65   return *_cm;
66 }
67
68 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const throw(INTERP_KERNEL::Exception)
69 {
70   return _cm->getEnum();
71 }
72
73 int MEDCoupling1GTUMesh::getMeshDimension() const
74 {
75   return (int)_cm->getDimension();
76 }
77
78 /*!
79  * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
80  * This method does not throw exception if geometric type \a type is not in \a this.
81  * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
82  * The coordinates array is not considered here.
83  *
84  * \param [in] type the geometric type
85  * \return cell ids in this having geometric type \a type.
86  */
87 DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
88 {
89   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
90   if(type==getCellModelEnum())
91     ret->alloc(getNumberOfCells(),1);
92   else
93     ret->alloc(0,1);
94   ret->iota();
95   return ret.retn();
96 }
97
98 /*!
99  * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type.
100  */
101 int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
102 {
103   return type==getCellModelEnum()?getNumberOfCells():0;
104 }
105
106 /*!
107  * Returns a type of a cell by its id.
108  *  \param [in] cellId - the id of the cell of interest.
109  *  \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type.
110  *  \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ).
111  */
112 INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const
113 {
114   if(cellId>=0 && cellId<getNumberOfCells())
115     return getCellModelEnum();
116   std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !";
117   throw INTERP_KERNEL::Exception(oss.str().c_str());
118 }
119
120 /*!
121  * Returns a set of all cell types available in \a this mesh.
122  * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types.
123  * \warning this method does not throw any exception even if \a this is not defined.
124  */
125 std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const
126 {
127   std::set<INTERP_KERNEL::NormalizedCellType> ret;
128   ret.insert(getCellModelEnum());
129   return ret;
130 }
131
132 /*!
133  * This method expects that \a this is sorted by types. If not an exception will be thrown.
134  * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
135  * \a this is composed in cell types.
136  * The returned array is of size 3*n where n is the number of different types present in \a this. 
137  * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. 
138  * This parameter is kept only for compatibility with other methode listed above.
139  */
140 std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
141 {
142   std::vector<int> ret(3);
143   ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1;
144   return ret;
145 }
146
147 /*!
148  * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type.
149  * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType.
150  * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType.
151  * 
152  * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method.
153  * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i,
154  *              \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0]
155  * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type.
156  *              This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile.
157  * 
158  * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType.
159  *
160  * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined
161  *
162  *  \b Example1: <br>
163  *          - Before \a this has 3 cells \a profile contains [0,1,2]
164  *          - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br>
165  * 
166  *  \b Example2: <br>
167  *          - Before \a this has 3 cells \a profile contains [1,2]
168  *          - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br>
169
170  */
171 void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
172 {
173   if(!profile)
174     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !");
175   if(profile->getNumberOfComponents()!=1)
176     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !");
177   int nbTuples=profile->getNumberOfTuples();
178   int nbOfCells=getNumberOfCells();
179   code.resize(3); idsInPflPerType.resize(1);
180   code[0]=(int)getCellModelEnum(); code[1]=nbTuples;
181   idsInPflPerType.resize(1);
182   if(profile->isIdentity() && nbTuples==nbOfCells)
183     {
184       code[2]=-1;
185       idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef();
186       idsPerType.clear();
187       return ;
188     }
189   code[2]=0;
190   profile->checkAllIdsInRange(0,nbOfCells);
191   idsPerType.resize(1);
192   idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef();
193   idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1);
194 }
195
196 /*!
197  * This method tries to minimize at most the number of deep copy.
198  * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return.
199  * 
200  * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig
201  */
202 DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
203 {
204   int nbOfCells=getNumberOfCells();
205   if(code.size()!=3)
206     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !");
207   if(code[0]!=(int)getCellModelEnum())
208     {
209       std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !";
210       throw INTERP_KERNEL::Exception(oss.str().c_str());
211     }
212   if(code[2]==-1)
213     {
214       if(code[1]==nbOfCells)
215         return 0;
216       else
217         {
218           std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !";
219           throw INTERP_KERNEL::Exception(oss.str().c_str());
220         }
221     }
222   if(code[2]!=0)
223     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !");
224   if(idsPerType.size()!=1)
225     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !");
226   const DataArrayInt *pfl=idsPerType[0];
227   if(!pfl)
228     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !");
229   if(pfl->getNumberOfComponents()!=1)
230     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !");
231   pfl->checkAllIdsInRange(0,nbOfCells);
232   pfl->incrRef();
233   return const_cast<DataArrayInt *>(pfl);
234 }
235
236 void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
237 {
238   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
239   m->writeVTKLL(ofs,cellData,pointData);
240 }
241
242 std::string MEDCoupling1GTUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
243 {
244   return std::string("UnstructuredGrid");
245 }
246
247 std::size_t MEDCoupling1GTUMesh::getHeapMemorySize() const
248 {
249   return MEDCouplingPointSet::getHeapMemorySize();
250 }
251
252 bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
253 {
254   if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
255     return false;
256   if(!other)
257     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !");
258   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
259   if(!otherC)
260     {
261       reason="mesh given in input is not castable in MEDCouplingSGTUMesh !";
262       return false;
263     }
264   if(_cm!=otherC->_cm)
265     {
266       reason="mismatch in geometric type !";
267       return false;
268     }
269   return true;
270 }
271
272 bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
273 {
274   if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
275     return false;
276   if(!other)
277     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
278   const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other);
279   if(!otherC)
280     return false;
281   if(_cm!=otherC->_cm)
282     return false;
283   return true;
284 }
285
286 void MEDCoupling1GTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
287 {
288   MEDCouplingPointSet::checkCoherency();
289 }
290
291 DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const
292 {
293   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
294   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner();
295   return ret.retn();
296 }
297
298 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const
299 {
300   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
301   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs);
302   ret->setMesh(this);
303   return ret.retn();
304 }
305
306 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const
307 {
308   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
309   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs);
310   ret->setMesh(this);
311   return ret.retn();
312 }
313
314 /*!
315  * to improve perf !
316  */
317 int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const
318 {
319   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
320   return m->getCellContainingPoint(pos,eps);
321 }
322
323 MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const
324 {
325   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
326   MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField();
327   ret->setMesh(this);
328   return ret.retn();
329 }
330
331 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const
332 {
333   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
334   return m->getCellsInBoundingBox(bbox,eps);
335 }
336
337 DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps)
338 {
339   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
340   return m->getCellsInBoundingBox(bbox,eps);
341 }
342
343 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const
344 {
345   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
346   return m->buildFacePartOfMySelfNode(start,end,fullyIn);
347 }
348
349 DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const
350 {
351   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
352   return m->findBoundaryNodes();
353 }
354
355 MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const
356 {
357   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
358   return m->buildBoundaryMesh(keepCoords);
359 }
360
361 void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const throw(INTERP_KERNEL::Exception)
362 {
363   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured();
364   m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr);
365 }
366
367 int MEDCoupling1GTUMesh::getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception)
368 {
369   const DataArrayInt *c1(getNodalConnectivity());
370   if(!c1)
371     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !");
372   if(c1->getNumberOfComponents()!=1)
373     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !");
374   if(!c1->isAllocated())
375     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !");
376   return c1->getNumberOfTuples();
377 }
378
379 /*!
380  * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned).
381  * The order of cells is the returned instance is those in the order of instances in \a parts.
382  *
383  * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates.
384  * \return MEDCouplingUMesh * - new object to be dealt by the caller.
385  *
386  * \throw If one element is null in \a parts.
387  * \throw If not all the parts do not have the same mesh dimension.
388  * \throw If not all the parts do not share the same coordinates.
389  * \throw If not all the parts have their connectivity set properly.
390  * \throw If \a parts is empty.
391  */
392 MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) throw(INTERP_KERNEL::Exception)
393 {
394   if(parts.empty())
395     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !");
396   const MEDCoupling1GTUMesh *firstPart(parts[0]);
397   if(!firstPart)
398     throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !");
399   const DataArrayDouble *coords(firstPart->getCoords());
400   int meshDim(firstPart->getMeshDimension());
401   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName().c_str(),meshDim)); ret->setDescription(firstPart->getDescription().c_str());
402   ret->setCoords(coords);
403   int nbOfCells(0),connSize(0);
404   for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
405     {
406       if(!(*it))
407         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !");
408       if((*it)->getMeshDimension()!=meshDim)
409         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !");
410       if((*it)->getCoords()!=coords)
411         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !");
412       nbOfCells+=(*it)->getNumberOfCells();
413       connSize+=(*it)->getNodalConnectivityLength();
414     }
415   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
416   connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1);
417   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
418   for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++)
419     {
420       int curNbCells((*it)->getNumberOfCells());
421       int geoType((int)(*it)->getCellModelEnum());
422       const int *cinPtr((*it)->getNodalConnectivity()->begin());
423       const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it));
424       const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it));
425       if(ps && !pd)
426         {
427           int nNodesPerCell(ps->getNumberOfNodesPerCell());
428           for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell)
429             {
430               *c++=geoType;
431               c=std::copy(cinPtr,cinPtr+nNodesPerCell,c);
432               ci[1]=ci[0]+nNodesPerCell+1;
433             }
434         }
435       else if(!ps && pd)
436         {
437           const int *ciinPtr(pd->getNodalConnectivityIndex()->begin());
438           for(int i=0;i<curNbCells;i++,ci++,ciinPtr++)
439             {
440               *c++=geoType;
441               c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c);
442               ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1;
443             }
444         }
445       else
446         throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !");
447     }
448   ret->setConnectivity(conn,connI,true);
449   return ret.retn();
450 }
451
452 //==
453
454 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
455 {
456   if(recDeepCpy)
457     {
458       const DataArrayInt *c(other._conn);
459       if(c)
460         _conn=c->deepCpy();
461     }
462 }
463
464 MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
465 {
466 }
467
468 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
469 {
470   if(type==INTERP_KERNEL::NORM_ERROR)
471     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
472   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
473   if(cm.isDynamic())
474     {
475       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !";
476       throw INTERP_KERNEL::Exception(oss.str().c_str());
477     }
478   return new MEDCoupling1SGTUMesh(name,cm);
479 }
480
481 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
482 {
483   if(!m)
484     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !");
485   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
486   if(gts.size()!=1)
487     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !");
488   int geoType((int)*gts.begin());
489   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName().c_str(),*gts.begin()));
490   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
491   int nbCells(m->getNumberOfCells());
492   int nbOfNodesPerCell(ret->getNumberOfNodesPerCell());
493   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1);
494   int *c(conn->getPointer());
495   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
496   for(int i=0;i<nbCells;i++,ciin++)
497     {
498       if(cin[ciin[0]]==geoType)
499         {
500           if(ciin[1]-ciin[0]==nbOfNodesPerCell+1)
501             c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
502           else
503             {
504               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !";
505               throw INTERP_KERNEL::Exception(oss.str().c_str());
506             }
507         }
508       else
509         {
510           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
511           throw INTERP_KERNEL::Exception(oss.str().c_str());
512         }
513     }
514   ret->setNodalConnectivity(conn);
515   return ret.retn();
516 }
517
518 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const
519 {
520   return new MEDCoupling1SGTUMesh(*this,recDeepCpy);
521 }
522
523 /*!
524  * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
525  * The coordinates are shared between \a this and the returned instance.
526  * 
527  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
528  * \sa MEDCoupling1SGTUMesh::deepCpy
529  */
530 MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
531 {
532   checkCoherency();
533   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false));
534   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy());
535   ret->setNodalConnectivity(c);
536   return ret.retn();
537 }
538
539 void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
540 {
541   if(!other)
542     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
543   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
544   if(!otherC)
545     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !");
546   setNodalConnectivity(otherC->getNodalConnectivity());
547 }
548
549 void MEDCoupling1SGTUMesh::updateTime() const
550 {
551   MEDCoupling1GTUMesh::updateTime();
552   const DataArrayInt *c(_conn);
553   if(c)
554     updateTimeWith(*c);
555 }
556
557 std::size_t MEDCoupling1SGTUMesh::getHeapMemorySize() const
558 {
559   std::size_t ret=0;
560   const DataArrayInt *c(_conn);
561   if(c)
562     ret+=c->getHeapMemorySize();
563   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
564 }
565
566 MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const
567 {
568   return clone(true);
569 }
570
571 bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
572 {
573   if(!other)
574     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !");
575   std::ostringstream oss; oss.precision(15);
576   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
577   if(!otherC)
578     {
579       reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !";
580       return false;
581     }
582   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
583     return false;
584   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
585   if(c1==c2)
586     return true;
587   if(!c1 || !c2)
588     {
589       reason="in connectivity of single static geometric type exactly one among this and other is null !";
590       return false;
591     }
592   if(!c1->isEqualIfNotWhy(*c2,reason))
593     {
594       reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
595       return false;
596     }
597   return true;
598 }
599
600 bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
601 {
602   if(!other)
603     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
604   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
605   if(!otherC)
606     return false;
607   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
608     return false;
609   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
610   if(c1==c2)
611     return true;
612   if(!c1 || !c2)
613     return false;
614   if(!c1->isEqualWithoutConsideringStr(*c2))
615     return false;
616   return true;
617 }
618
619 void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
620 {
621   const DataArrayInt *c1(_conn);
622   if(c1)
623     {
624       if(c1->getNumberOfComponents()!=1)
625         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
626       if(c1->getInfoOnComponent(0)!="")
627         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
628       c1->checkAllocated();
629     }
630   else
631     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
632 }
633
634 void MEDCoupling1SGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
635 {
636   MEDCouplingPointSet::checkCoherency();
637   checkCoherencyOfConnectivity();
638 }
639
640 void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
641 {
642   checkCoherency();
643   const DataArrayInt *c1(_conn);
644   int nbOfTuples=c1->getNumberOfTuples();
645   int nbOfNodesPerCell=(int)_cm->getNumberOfNodes();
646   if(nbOfTuples%nbOfNodesPerCell!=0)
647     {
648       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
649       throw INTERP_KERNEL::Exception(oss.str().c_str());
650     }
651   int nbOfNodes=getNumberOfNodes();
652   int nbOfCells=nbOfTuples/nbOfNodesPerCell;
653   const int *w(c1->begin());
654   for(int i=0;i<nbOfCells;i++)
655     for(int j=0;j<nbOfNodesPerCell;j++,w++)
656       {
657         if(*w<0 || *w>=nbOfNodes)
658           {
659             std::ostringstream oss; oss << "At node #" << j << " of  cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !";
660             throw INTERP_KERNEL::Exception(oss.str().c_str());
661           }
662       }
663 }
664
665 void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
666 {
667   checkCoherency1(eps);
668 }
669
670 int MEDCoupling1SGTUMesh::getNumberOfCells() const
671 {
672   int nbOfTuples=getNodalConnectivityLength();
673   int nbOfNodesPerCell=getNumberOfNodesPerCell();
674   if(nbOfTuples%nbOfNodesPerCell!=0)
675     {
676       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !";
677       throw INTERP_KERNEL::Exception(oss.str().c_str());
678     }
679   return nbOfTuples/nbOfNodesPerCell;
680 }
681
682 int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
683 {
684   return getNumberOfNodesPerCell();
685 }
686
687 int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
688 {
689   checkNonDynamicGeoType();
690   return (int)_cm->getNumberOfNodes();
691 }
692
693 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
694 {
695   checkNonDynamicGeoType();
696   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
697   ret->alloc(getNumberOfCells(),1);
698   ret->fillWithValue((int)_cm->getNumberOfNodes());
699   return ret.retn();
700 }
701
702 DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
703 {
704   checkNonDynamicGeoType();
705   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
706   ret->alloc(getNumberOfCells(),1);
707   ret->fillWithValue((int)_cm->getNumberOfSons());
708   return ret.retn();
709 }
710
711 DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
712 {
713   checkNonDynamicGeoType();
714   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
715   int nbCells(getNumberOfCells());
716   ret->alloc(nbCells,1);
717   int *retPtr(ret->getPointer());
718   int nbNodesPerCell(getNumberOfNodesPerCell());
719   const int *conn(_conn->begin());
720   for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++)
721     {
722       std::set<int> s(conn,conn+nbNodesPerCell);
723       *retPtr=(int)s.size();
724     }
725   return ret.retn();
726 }
727
728 void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
729 {
730   int sz=getNumberOfNodesPerCell();
731   conn.resize(sz);
732   if(cellId>=0 && cellId<getNumberOfCells())
733     std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin());
734   else
735     {
736       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !";
737       throw INTERP_KERNEL::Exception(oss.str().c_str());
738     }
739 }
740
741 void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const throw(INTERP_KERNEL::Exception)
742 {
743   if(_cm->isDynamic())
744     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !");
745 }
746
747 std::string MEDCoupling1SGTUMesh::simpleRepr() const
748 {
749   static const char msg0[]="No coordinates specified !";
750   std::ostringstream ret;
751   ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
752   ret << "Description of mesh : \"" << getDescription() << "\"\n";
753   int tmpp1,tmpp2;
754   double tt=getTime(tmpp1,tmpp2);
755   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
756   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
757   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
758   if(_coords!=0)
759     {
760       const int spaceDim=getSpaceDimension();
761       ret << spaceDim << "\nInfo attached on space dimension : ";
762       for(int i=0;i<spaceDim;i++)
763         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
764       ret << "\n";
765     }
766   else
767     ret << msg0 << "\n";
768   ret << "Number of nodes : ";
769   if(_coords!=0)
770     ret << getNumberOfNodes() << "\n";
771   else
772     ret << msg0 << "\n";
773   ret << "Number of cells : ";
774   if((const DataArrayInt *)_conn)
775     {
776       if(_conn->isAllocated())
777         {
778           if(_conn->getNumberOfComponents()==1)
779             ret << getNumberOfCells() << "\n";
780           else
781             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
782         }
783       else
784         ret << "Nodal connectivity array specified but not allocated !" << "\n";
785     }
786   else
787     ret << "No connectivity specified !" << "\n";
788   ret << "Cell type : " << _cm->getRepr() << "\n";
789   return ret.str();
790 }
791
792 std::string MEDCoupling1SGTUMesh::advancedRepr() const
793 {
794   std::ostringstream ret;
795   ret << simpleRepr();
796   ret << "\nCoordinates array : \n___________________\n\n";
797   if(_coords)
798     _coords->reprWithoutNameStream(ret);
799   else
800     ret << "No array set !\n";
801   ret << "\n\nConnectivity array : \n____________________\n\n";
802   //
803   if((const DataArrayInt *)_conn)
804     {
805       if(_conn->isAllocated())
806         {
807           if(_conn->getNumberOfComponents()==1)
808             {
809              int nbOfCells=getNumberOfCells();
810              int sz=getNumberOfNodesPerCell();
811              const int *connPtr=_conn->begin();
812              for(int i=0;i<nbOfCells;i++,connPtr+=sz)
813                {
814                  ret << "Cell #" << i << " : ";
815                  std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," "));
816                  ret << "\n";
817                }
818             }
819           else
820             ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n";
821         }
822       else
823         ret << "Nodal connectivity array specified but not allocated !" << "\n";
824     }
825   else
826     ret << "No connectivity specified !" << "\n";
827   return ret.str();
828 }
829
830 DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
831 {
832   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
833   int spaceDim=getSpaceDimension();
834   int nbOfCells=getNumberOfCells();//checkCoherency()
835   int nbOfNodes=getNumberOfNodes();
836   ret->alloc(nbOfCells,spaceDim);
837   double *ptToFill=ret->getPointer();
838   const double *coor=_coords->begin();
839   const int *nodal=_conn->begin();
840   int sz=getNumberOfNodesPerCell();
841   double coeff=1./(double)sz;
842   for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim)
843     {
844       std::fill(ptToFill,ptToFill+spaceDim,0.);
845       for(int j=0;j<sz;j++,nodal++)
846         if(*nodal>=0 && *nodal<nbOfNodes)
847           std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
848         else
849           {
850             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
851             throw INTERP_KERNEL::Exception(oss.str().c_str());
852           }
853       std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff));
854     }
855   return ret.retn();
856 }
857
858 void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
859 {
860   int nbCells=getNumberOfCells();
861   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
862   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
863   if(check)
864     o2n=o2n->checkAndPreparePermutation();
865   //
866   const int *conn=_conn->begin();
867   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells);
868   const int *n2oPtr=n2o->begin();
869   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
870   newConn->alloc(_conn->getNumberOfTuples(),1);
871   newConn->copyStringInfoFrom(*_conn);
872   int sz=getNumberOfNodesPerCell();
873   //
874   int *newC=newConn->getPointer();
875   for(int i=0;i<nbCells;i++,newC+=sz)
876     {
877       int pos=n2oPtr[i];
878       std::copy(conn+pos*sz,conn+(pos+1)*sz,newC);
879     }
880   _conn=newConn;
881 }
882
883 /*!
884  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
885  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
886  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
887  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
888  *
889  * \param [in] begin input start of array of node ids.
890  * \param [in] end input end of array of node ids.
891  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
892  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
893  */
894 void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
895 {
896   int nbOfCells=getNumberOfCells();
897   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
898   int tmp=-1;
899   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
900   std::vector<bool> fastFinder(sz,false);
901   for(const int *work=begin;work!=end;work++)
902     if(*work>=0 && *work<sz)
903       fastFinder[*work]=true;
904   const int *conn=_conn->begin();
905   int nbNodesPerCell=getNumberOfNodesPerCell();
906   for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell)
907     {
908       int ref=0,nbOfHit=0;
909       for(int j=0;j<nbNodesPerCell;j++)
910         if(conn[j]>=0)
911           {
912             ref++;
913             if(fastFinder[conn[j]])
914               nbOfHit++;
915           }
916       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
917         cellIdsKept->pushBackSilent(i);
918     }
919   cellIdsKeptArr=cellIdsKept.retn();
920 }
921
922 MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
923 {
924   if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED)
925     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !");
926   const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other);
927   return Merge1SGTUMeshes(this,otherC);
928 }
929
930 MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
931 {
932   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
933   ret->setCoords(getCoords());
934   const int *nodalConn=_conn->begin();
935   int nbCells=getNumberOfCells();
936   int nbNodesPerCell=getNumberOfNodesPerCell();
937   int geoType=(int)getCellModelEnum();
938   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1);
939   int *cPtr=c->getPointer();
940   for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell)
941     {
942       *cPtr++=geoType;
943       cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr);
944     }
945   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1);
946   ret->setConnectivity(c,cI,true);
947   return ret.retn();
948 }
949
950 DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
951 {
952   switch(policy)
953     {
954     case 0:
955       return simplexizePol0();
956     case 1:
957       return simplexizePol1();
958     case (int) INTERP_KERNEL::PLANAR_FACE_5:
959       return simplexizePlanarFace5();
960     case (int) INTERP_KERNEL::PLANAR_FACE_6:
961       return simplexizePlanarFace6();
962     default:
963       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n  - 0 or 1 (only available for meshdim=2) \n  - PLANAR_FACE_5, PLANAR_FACE_6  (only for meshdim=3)");
964     }
965 }
966
967 /// @cond INTERNAL
968
969 struct MEDCouplingAccVisit
970 {
971   MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
972   int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
973   int _new_nb_of_nodes;
974 };
975
976 /// @endcond
977
978 /*!
979  * Finds nodes not used in any cell and returns an array giving a new id to every node
980  * by excluding the unused nodes, for which the array holds -1. The result array is
981  * a mapping in "Old to New" mode. 
982  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
983  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
984  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
985  *          if the node is unused or a new id else. The caller is to delete this
986  *          array using decrRef() as it is no more needed.  
987  *  \throw If the coordinates array is not set.
988  *  \throw If the nodal connectivity of cells is not defined.
989  *  \throw If the nodal connectivity includes an invalid id.
990  */
991 DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
992 {
993   nbrOfNodesInUse=-1;
994   int nbOfNodes=getNumberOfNodes();
995   int nbOfCells=getNumberOfCells();
996   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
997   ret->alloc(nbOfNodes,1);
998   int *traducer=ret->getPointer();
999   std::fill(traducer,traducer+nbOfNodes,-1);
1000   const int *conn=_conn->begin();
1001   int nbNodesPerCell=getNumberOfNodesPerCell();
1002   for(int i=0;i<nbOfCells;i++)
1003     for(int j=0;j<nbNodesPerCell;j++,conn++)
1004       if(*conn>=0 && *conn<nbOfNodes)
1005         traducer[*conn]=1;
1006       else
1007         {
1008           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  conn[j] << " not in [0," << nbOfNodes << ") !";
1009           throw INTERP_KERNEL::Exception(oss.str().c_str());
1010         }
1011   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
1012   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
1013   return ret.retn();
1014 }
1015
1016 /*!
1017  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
1018  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
1019  * This method is a generalization of shiftNodeNumbersInConn().
1020  *  \warning This method performs no check of validity of new ids. **Use it with care !**
1021  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
1022  *         this->getNumberOfNodes(), in "Old to New" mode. 
1023  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
1024  *  \throw If the nodal connectivity of cells is not defined.
1025  */
1026 void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
1027 {
1028   getNumberOfCells();//only to check that all is well defined.
1029   _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes());
1030   updateTime();
1031 }
1032
1033 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
1034 {
1035   std::vector<const MEDCoupling1SGTUMesh *> tmp(2);
1036   tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2);
1037   return Merge1SGTUMeshes(tmp);
1038 }
1039
1040 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1041 {
1042   std::size_t sz=a.size();
1043   if(sz==0)
1044     return Merge1SGTUMeshesLL(a);
1045   for(std::size_t ii=0;ii<sz;ii++)
1046     if(!a[ii])
1047       {
1048         std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
1049         throw INTERP_KERNEL::Exception(oss.str().c_str());
1050       }
1051   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
1052   for(std::size_t ii=0;ii<sz;ii++)
1053     if(&(a[ii]->getCellModel())!=cm)
1054       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !");
1055   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz);
1056   std::vector< const MEDCoupling1SGTUMesh * > aa(sz);
1057   int spaceDim=-3;
1058   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
1059     {
1060       const MEDCoupling1SGTUMesh *cur=a[i];
1061       const DataArrayDouble *coo=cur->getCoords();
1062       if(coo)
1063         spaceDim=coo->getNumberOfComponents();
1064     }
1065   if(spaceDim==-3)
1066     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !");
1067   for(std::size_t i=0;i<sz;i++)
1068     {
1069       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
1070       aa[i]=bb[i];
1071     }
1072   return Merge1SGTUMeshesLL(aa);
1073 }
1074
1075 /*!
1076  * \throw If presence of a null instance in the input vector \a a.
1077  * \throw If a is empty
1078  */
1079 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1080 {
1081   if(a.empty())
1082     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !");
1083   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1084   if(!(*it))
1085     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !");
1086   std::vector<const DataArrayInt *> ncs(a.size());
1087   int nbOfCells=(*it)->getNumberOfCells();
1088   const DataArrayDouble *coords=(*it)->getCoords();
1089   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1090   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1091   ncs[0]=(*it)->getNodalConnectivity();
1092   it++;
1093   for(int i=1;it!=a.end();i++,it++)
1094     {
1095       if(!(*it))
1096         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !");
1097       if(cm!=&((*it)->getCellModel()))
1098         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1099       (*it)->getNumberOfCells();//to check that all is OK
1100       ncs[i]=(*it)->getNodalConnectivity();
1101       if(coords!=(*it)->getCoords())
1102         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !");
1103     }
1104   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1105   ret->setCoords(coords);
1106   ret->_conn=DataArrayInt::Aggregate(ncs);
1107   return ret.retn();
1108 }
1109
1110 /*!
1111  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
1112  */
1113 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
1114 {
1115   if(a.empty())
1116     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !");
1117   std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin();
1118   int nbOfCells=(*it)->getNumberOfCells();
1119   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
1120   int nbNodesPerCell=(*it)->getNumberOfNodesPerCell();
1121   it++;
1122   for(;it!=a.end();it++)
1123     {
1124       if(cm!=&((*it)->getCellModel()))
1125         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !");
1126       nbOfCells+=(*it)->getNumberOfCells();
1127     }
1128   std::vector<const MEDCouplingPointSet *> aps(a.size());
1129   std::copy(a.begin(),a.end(),aps.begin());
1130   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
1131   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm));
1132   ret->setCoords(pts);
1133   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
1134   c->alloc(nbOfCells*nbNodesPerCell,1);
1135   int *cPtr=c->getPointer();
1136   int offset=0;
1137   for(it=a.begin();it!=a.end();it++)
1138     {
1139       int curConnLgth=(*it)->getNodalConnectivityLength();
1140       const int *curC=(*it)->_conn->begin();
1141       cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset));
1142       offset+=(*it)->getNumberOfNodes();
1143     }
1144   //
1145   ret->setNodalConnectivity(c);
1146   return ret.retn();
1147 }
1148
1149 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
1150 {
1151   int ncell=getNumberOfCells();
1152   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1153   ret->setCoords(_coords);
1154   std::size_t nbOfElemsRet=std::distance(begin,end);
1155   const int *inConn=_conn->getConstPointer();
1156   int sz=getNumberOfNodesPerCell();
1157   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1158   int *connPtr=connRet->getPointer();
1159   for(const int *work=begin;work!=end;work++,connPtr+=sz)
1160     {
1161       if(*work>=0 && *work<ncell)
1162         std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr);
1163       else
1164         {
1165           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
1166           throw INTERP_KERNEL::Exception(oss.str().c_str());
1167         }
1168     }
1169   ret->_conn=connRet;
1170   ret->copyTinyInfoFrom(this);
1171   return ret.retn();
1172 }
1173
1174 MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
1175 {
1176   int ncell=getNumberOfCells();
1177   int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : ");
1178   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1179   ret->setCoords(_coords);
1180   const int *inConn=_conn->getConstPointer();
1181   int sz=getNumberOfNodesPerCell();
1182   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1);
1183   int *connPtr=connRet->getPointer();
1184   int curId=start;
1185   for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step)
1186     {
1187       if(curId>=0 && curId<ncell)
1188         std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr);
1189       else
1190         {
1191           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId  << " should be in [0," << ncell << ") !";
1192           throw INTERP_KERNEL::Exception(oss.str().c_str());
1193         }
1194     }
1195   ret->_conn=connRet;
1196   ret->copyTinyInfoFrom(this);
1197   return ret.retn();
1198 }
1199
1200 void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
1201 {
1202   int sz((int)nodeIdsInUse.size());
1203   int nbCells(getNumberOfCells());
1204   int nbOfNodesPerCell(getNumberOfNodesPerCell());
1205   const int *w(_conn->begin());
1206   for(int i=0;i<nbCells;i++)
1207     for(int j=0;j<nbOfNodesPerCell;j++,w++)
1208       {
1209         if(*w>=0 && *w<sz)
1210           nodeIdsInUse[*w]=true;
1211         else
1212           {
1213             std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *w << " should be in [0," << sz << ") !";
1214             throw INTERP_KERNEL::Exception(oss.str().c_str());
1215           }
1216       }
1217 }
1218
1219 MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
1220 {
1221   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName().c_str(),*_cm));
1222   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1;
1223   const DataArrayInt *nodalConn(_conn);
1224   if(!nodalConn)
1225     {
1226       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
1227     }
1228   else
1229     tmp1=_conn;
1230   ret->_conn=tmp1;
1231   if(!_coords)
1232     {
1233       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
1234       ret->setCoords(coords);
1235     }
1236   else
1237     ret->setCoords(_coords);
1238   return ret.retn();
1239 }
1240
1241 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
1242 {
1243   int nbOfCells=getNumberOfCells();
1244   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1245     return DataArrayInt::Range(0,nbOfCells,1);
1246   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1247   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1248   const int *c(_conn->begin());
1249   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1250   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1251     {
1252       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2];
1253       newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1254       retPtr[0]=i; retPtr[1]=i;
1255     }
1256   _conn=newConn;
1257   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1258   updateTime();
1259   return ret.retn();
1260 }
1261
1262 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
1263 {
1264   int nbOfCells=getNumberOfCells();
1265   if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4)
1266     return DataArrayInt::Range(0,nbOfCells,1);
1267   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1);
1268   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1);
1269   const int *c(_conn->begin());
1270   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1271   for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2)
1272     {
1273       newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3];
1274       newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3];
1275       retPtr[0]=i; retPtr[1]=i;
1276     }
1277   _conn=newConn;
1278   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3);
1279   updateTime();
1280   return ret.retn();
1281 }
1282
1283 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() throw(INTERP_KERNEL::Exception)
1284 {
1285   int nbOfCells=getNumberOfCells();
1286   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1287     return DataArrayInt::Range(0,nbOfCells,1);
1288   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1);
1289   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1);
1290   const int *c(_conn->begin());
1291   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1292   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5)
1293     {
1294       for(int j=0;j<20;j++)
1295         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]];
1296       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i;
1297     }
1298   _conn=newConn;
1299   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1300   updateTime();
1301   return ret.retn();
1302 }
1303
1304 DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() throw(INTERP_KERNEL::Exception)
1305 {
1306   int nbOfCells=getNumberOfCells();
1307   if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8)
1308     return DataArrayInt::Range(0,nbOfCells,1);
1309   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1);
1310   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1);
1311   const int *c(_conn->begin());
1312   int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer());
1313   for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6)
1314     {
1315       for(int j=0;j<24;j++)
1316         newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]];
1317       retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i;
1318     }
1319   _conn=newConn;
1320   _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4);
1321   updateTime();
1322   return ret.retn();
1323 }
1324
1325 void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
1326 {
1327   stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
1328   stream << " Mesh dimension : " << getMeshDimension() << ".";
1329   if(!_coords)
1330     { stream << " No coordinates set !"; return ; }
1331   if(!_coords->isAllocated())
1332     { stream << " Coordinates set but not allocated !"; return ; }
1333   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
1334   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
1335   if(!(const DataArrayInt *)_conn)
1336     { stream << std::endl << "Nodal connectivity NOT set !"; return ; }
1337   if(_conn->isAllocated())
1338     {
1339       if(_conn->getNumberOfComponents()==1)
1340         stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
1341     }
1342 }
1343
1344 void MEDCoupling1SGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
1345 {
1346   if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords))
1347     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined.");
1348 }
1349
1350 /*!
1351  * First step of unserialization process.
1352  */
1353 bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
1354 {
1355   throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !");
1356 }
1357
1358 /*!
1359  * Checks if \a this and \a other meshes are geometrically equivalent with high
1360  * probability, else an exception is thrown. The meshes are considered equivalent if
1361  * (1) meshes contain the same number of nodes and the same number of elements of the
1362  * same types (2) three cells of the two meshes (first, last and middle) are based
1363  * on coincident nodes (with a specified precision).
1364  *  \param [in] other - the mesh to compare with.
1365  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1366  *  \throw If the two meshes do not match.
1367  */
1368 void MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1369 {
1370   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1371   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1372   if(!otherC)
1373     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !");
1374   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1375   if(c1==c2)
1376     return;
1377   if(!c1 || !c2)
1378     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1379   if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1380     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1381   if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1382     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1383   if(c1->getHashCode()!=c2->getHashCode())
1384     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1385 }
1386
1387 MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
1388 {
1389   if(!other)
1390     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
1391   const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other);
1392   if(!otherC)
1393     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
1394   std::vector<const MEDCoupling1SGTUMesh *> ms(2);
1395   ms[0]=this;
1396   ms[1]=otherC;
1397   return Merge1SGTUMeshesOnSameCoords(ms);
1398 }
1399
1400 void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
1401 {
1402   checkFullyDefined();
1403   int nbOfNodes=getNumberOfNodes();
1404   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
1405   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
1406   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
1407   const int *conn=_conn->begin();
1408   int nbOfCells=getNumberOfCells();
1409   int nbOfEltsInRevNodal=0;
1410   int nbOfNodesPerCell=getNumberOfNodesPerCell();
1411   for(int eltId=0;eltId<nbOfCells;eltId++)
1412     {
1413       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1414         {
1415           if(conn[0]>=0 && conn[0]<nbOfNodes)
1416             {
1417               nbOfEltsInRevNodal++;
1418               revNodalIndxPtr[conn[0]+1]++;
1419             }
1420           else
1421             {
1422               std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
1423               throw INTERP_KERNEL::Exception(oss.str().c_str());
1424             }
1425         }
1426     }
1427   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
1428   conn=_conn->begin();
1429   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
1430   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
1431   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
1432   for(int eltId=0;eltId<nbOfCells;eltId++)
1433     {
1434       for(int j=0;j<nbOfNodesPerCell;j++,conn++)
1435         {
1436           *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
1437         }
1438     }
1439 }
1440
1441 /*!
1442  * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null.
1443  */
1444 void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception)
1445 {
1446   if(nodalConn)
1447     nodalConn->incrRef();
1448   _conn=nodalConn;
1449   declareAsNew();
1450 }
1451
1452 /*!
1453  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
1454  */
1455 DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
1456 {
1457   const DataArrayInt *ret(_conn);
1458   return const_cast<DataArrayInt *>(ret);
1459 }
1460
1461 /*!
1462  * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted,
1463  * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter.
1464  * If a nodal connectivity previouly existed before the call of this method, it will be reset.
1465  *
1466  *  \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain.
1467  */
1468 void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
1469 {
1470   if(nbOfCells<0)
1471     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !");
1472   _conn=DataArrayInt::New();
1473   _conn->reserve(getNumberOfNodesPerCell()*nbOfCells);
1474   declareAsNew();
1475 }
1476
1477 /*!
1478  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
1479  *
1480  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
1481  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
1482  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
1483  *        attached to \a this.
1484  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
1485  */
1486 void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
1487 {
1488   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
1489   int ref=getNumberOfNodesPerCell();
1490   if(sz==ref)
1491     {
1492       DataArrayInt *c(_conn);
1493       if(c)
1494         c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
1495       else
1496         throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !");
1497     }
1498   else
1499     {
1500       std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this (";
1501       oss << ref << ") !";
1502       throw INTERP_KERNEL::Exception(oss.str().c_str());
1503     }
1504 }
1505
1506 /*!
1507  * This method builds the dual mesh of \a this and returns it.
1508  * 
1509  * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller.
1510  * \throw If \a this is not a mesh containing only simplex cells.
1511  * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !).
1512  * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !)
1513  */
1514 MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const throw(INTERP_KERNEL::Exception)
1515 {
1516   const INTERP_KERNEL::CellModel& cm(getCellModel());
1517   if(!cm.isSimplex())
1518     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !");
1519   switch(getMeshDimension())
1520     {
1521     case 3:
1522       return computeDualMesh3D();
1523     case 2:
1524       return computeDualMesh2D();
1525     default:
1526       throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !");
1527     }
1528 }
1529
1530 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const throw(INTERP_KERNEL::Exception)
1531 {
1532   static const int DUAL_TETRA_0[36]={
1533     4,1,0, 6,0,3, 7,3,1,
1534     4,0,1, 5,2,0, 8,1,2,
1535     6,3,0, 5,0,2, 9,2,3,
1536     7,1,3, 9,3,2, 8,2,1
1537   };
1538   static const int DUAL_TETRA_1[36]={
1539     8,4,10, 11,5,8, 10,7,11,
1540     9,4,8, 8,5,12, 12,6,9,
1541     10,4,9, 9,6,13, 13,7,10,
1542     12,5,11, 13,6,12, 11,7,13
1543   };
1544   static const int FACEID_NOT_SH_NODE[4]={2,3,1,0};
1545   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4)
1546     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !");
1547   checkFullyDefined();
1548   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1549   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1550   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1551   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1552   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New());
1553   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr));
1554   const int *d1(d1Arr->begin());
1555   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1556   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1557   const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1558   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1559   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells());
1560   edges=0; faces=0;
1561   std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr;
1562   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0;
1563   std::string name("DualOf_"); name+=getName();
1564   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr);
1565   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1566   for(int i=0;i<nbOfNodes;i++,revNodI++)
1567     {
1568       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1569       if(nbOfCellsSharingNode==0)
1570         {
1571           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; 
1572           throw INTERP_KERNEL::Exception(oss.str().c_str());
1573         }
1574       for(int j=0;j<nbOfCellsSharingNode;j++)
1575         {
1576           int curCellId(revNod[revNodI[0]+j]);
1577           const int *connOfCurCell(nodal+4*curCellId);
1578           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1579           if(j!=0) cArr->pushBackSilent(-1);
1580           int tmp[14];
1581           //
1582           tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes;
1583           tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes;
1584           tmp[4]=-1;
1585           tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes;
1586           tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes;
1587           tmp[9]=-1;
1588           tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes;
1589           tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes;
1590           cArr->insertAtTheEnd(tmp,tmp+14);
1591           int kk(0);
1592           for(int k=0;k<4;k++)
1593             {
1594               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1595                 {
1596                   const int *faceId(d2+4*curCellId+k);
1597                   if(rdi2[*faceId+1]-rdi2[*faceId]==1)
1598                     {
1599                       int tmp2[5]; tmp2[0]=-1; tmp2[1]=i;
1600                       tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0;
1601                       tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes;
1602                       tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0;
1603                       cArr->insertAtTheEnd(tmp2,tmp2+5);
1604                     }
1605                   kk++;
1606                 }
1607             }
1608         }
1609       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1610     }
1611   ret->setNodalConnectivity(cArr,ciArr);
1612   return ret.retn();
1613 }
1614
1615 MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const throw(INTERP_KERNEL::Exception)
1616 {
1617   static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1};
1618   static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5};
1619   static const int FACEID_NOT_SH_NODE[3]={1,2,0};
1620   if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3)
1621     throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !");
1622   checkFullyDefined();
1623   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured());
1624   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New());
1625   thisu->getReverseNodalConnectivity(revNodArr,revNodIArr);
1626   const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin());
1627   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New());
1628   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr));  thisu=0;
1629   const int *d2(d2Arr->begin()),*rd2(rd2Arr->begin()),*rdi2(rdi2Arr->begin());
1630   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner());
1631   const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells());
1632   edges=0;
1633   std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr;
1634   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0;
1635   std::string name("DualOf_"); name+=getName();
1636   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name.c_str(),INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr);
1637   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1);
1638   for(int i=0;i<nbOfNodes;i++,revNodI++)
1639     {
1640       int nbOfCellsSharingNode(revNodI[1]-revNodI[0]);
1641       if(nbOfCellsSharingNode==0)
1642         {
1643           std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; 
1644           throw INTERP_KERNEL::Exception(oss.str().c_str());
1645         }
1646       std::vector< std::vector<int> > polyg;
1647       for(int j=0;j<nbOfCellsSharingNode;j++)
1648         {
1649           int curCellId(revNod[revNodI[0]+j]);
1650           const int *connOfCurCell(nodal+3*curCellId);
1651           std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i)));
1652           std::vector<int> locV(3);
1653           locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes;
1654           polyg.push_back(locV);
1655           int kk(0);
1656           for(int k=0;k<3;k++)
1657             {
1658               if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k)
1659                 {
1660                   const int *edgeId(d2+3*curCellId+k);
1661                   if(rdi2[*edgeId+1]-rdi2[*edgeId]==1)
1662                     {
1663                       std::vector<int> locV2(2);
1664                       int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]);
1665                       if(zeLocEdgeIdRel>0)
1666                         {  locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes;  locV2[1]=i; }
1667                       else
1668                         {  locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; }
1669                       polyg.push_back(locV2);
1670                     }
1671                   kk++;
1672                 }
1673             }
1674         }
1675       std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg));
1676       cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end());
1677       ciArr->setIJ(i+1,0,cArr->getNumberOfTuples());
1678     }
1679   ret->setNodalConnectivity(cArr,ciArr);
1680   return ret.retn();
1681 }
1682
1683 //== 
1684
1685 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const char *name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception)
1686 {
1687   if(type==INTERP_KERNEL::NORM_ERROR)
1688     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !");
1689   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
1690   if(!cm.isDynamic())
1691     {
1692       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !";
1693       throw INTERP_KERNEL::Exception(oss.str().c_str());
1694     }
1695   return new MEDCoupling1DGTUMesh(name,cm);
1696 }
1697
1698 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const char *name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm)
1699 {
1700 }
1701
1702 MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn)
1703 {
1704   if(recDeepCpy)
1705     {
1706       const DataArrayInt *c(other._conn);
1707       if(c)
1708         _conn=c->deepCpy();
1709       c=other._conn_indx;
1710       if(c)
1711         _conn_indx=c->deepCpy();
1712     }
1713 }
1714
1715 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const
1716 {
1717   return new MEDCoupling1DGTUMesh(*this,recDeepCpy);
1718 }
1719
1720 /*!
1721  * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied.
1722  * The coordinates are shared between \a this and the returned instance.
1723  * 
1724  * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes)
1725  * \sa MEDCoupling1DGTUMesh::deepCpy
1726  */
1727 MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception)
1728 {
1729   checkCoherency();
1730   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false));
1731   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy());
1732   ret->setNodalConnectivity(c,ci);
1733   return ret.retn();
1734 }
1735
1736 void MEDCoupling1DGTUMesh::updateTime() const
1737 {
1738   MEDCoupling1GTUMesh::updateTime();
1739   const DataArrayInt *c(_conn);
1740   if(c)
1741     updateTimeWith(*c);
1742   c=_conn_indx;
1743   if(c)
1744     updateTimeWith(*c);
1745 }
1746
1747 std::size_t MEDCoupling1DGTUMesh::getHeapMemorySize() const
1748 {
1749   std::size_t ret=0;
1750   const DataArrayInt *c(_conn);
1751   if(c)
1752     ret+=c->getHeapMemorySize();
1753   c=_conn_indx;
1754   if(c)
1755     ret+=c->getHeapMemorySize();
1756   return MEDCoupling1GTUMesh::getHeapMemorySize()+ret;
1757 }
1758
1759 MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const
1760 {
1761   return clone(true);
1762 }
1763
1764 bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
1765 {
1766   if(!other)
1767     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !");
1768   std::ostringstream oss; oss.precision(15);
1769   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1770   if(!otherC)
1771     {
1772       reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !";
1773       return false;
1774     }
1775   if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason))
1776     return false;
1777   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1778   if(c1==c2)
1779     return true;
1780   if(!c1 || !c2)
1781     {
1782       reason="in connectivity of single dynamic geometric type exactly one among this and other is null !";
1783       return false;
1784     }
1785   if(!c1->isEqualIfNotWhy(*c2,reason))
1786     {
1787       reason.insert(0,"Nodal connectivity DataArrayInt differs : ");
1788       return false;
1789     }
1790   c1=_conn_indx; c2=otherC->_conn_indx;
1791   if(c1==c2)
1792     return true;
1793   if(!c1 || !c2)
1794     {
1795       reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !";
1796       return false;
1797     }
1798   if(!c1->isEqualIfNotWhy(*c2,reason))
1799     {
1800       reason.insert(0,"Nodal connectivity index DataArrayInt differs : ");
1801       return false;
1802     }
1803   return true;
1804 }
1805
1806 bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
1807 {
1808   if(!other)
1809     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !");
1810   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1811   if(!otherC)
1812     return false;
1813   if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec))
1814     return false;
1815   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1816   if(c1==c2)
1817     return true;
1818   if(!c1 || !c2)
1819     return false;
1820   if(!c1->isEqualWithoutConsideringStr(*c2))
1821     return false;
1822   return true;
1823   c1=_conn_indx; c2=otherC->_conn_indx;
1824   if(c1==c2)
1825     return true;
1826   if(!c1 || !c2)
1827     return false;
1828   if(!c1->isEqualWithoutConsideringStr(*c2))
1829     return false;
1830   return true;
1831 }
1832
1833 /*!
1834  * Checks if \a this and \a other meshes are geometrically equivalent with high
1835  * probability, else an exception is thrown. The meshes are considered equivalent if
1836  * (1) meshes contain the same number of nodes and the same number of elements of the
1837  * same types (2) three cells of the two meshes (first, last and middle) are based
1838  * on coincident nodes (with a specified precision).
1839  *  \param [in] other - the mesh to compare with.
1840  *  \param [in] prec - the precision used to compare nodes of the two meshes.
1841  *  \throw If the two meshes do not match.
1842  */
1843 void MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
1844 {
1845   MEDCouplingPointSet::checkFastEquivalWith(other,prec);
1846   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
1847   if(!otherC)
1848     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !");
1849   const DataArrayInt *c1(_conn),*c2(otherC->_conn);
1850   if(c1!=c2)
1851     {
1852       if(!c1 || !c2)
1853         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !");
1854       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1855         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !");
1856       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1857         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !");
1858       if(c1->getHashCode()!=c2->getHashCode())
1859         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs");
1860     }
1861   c1=_conn_indx; c2=otherC->_conn_indx;
1862   if(c1!=c2)
1863     {
1864       if(!c1 || !c2)
1865         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !");
1866       if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated()))
1867         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !");
1868       if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1)
1869         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !");
1870       if(c1->getHashCode()!=c2->getHashCode())
1871         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs");
1872     }
1873 }
1874
1875 void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception)
1876 {
1877   const DataArrayInt *c1(_conn);
1878   if(c1)
1879     {
1880       if(c1->getNumberOfComponents()!=1)
1881         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
1882       if(c1->getInfoOnComponent(0)!="")
1883         throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
1884       c1->checkAllocated();
1885     }
1886   else
1887     throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !");
1888   //
1889   int sz2=_conn->getNumberOfTuples();
1890   c1=_conn_indx;
1891   if(c1)
1892     {
1893       if(c1->getNumberOfComponents()!=1)
1894         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
1895       c1->checkAllocated();
1896       if(c1->getNumberOfTuples()<1)
1897         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !");
1898       if(c1->getInfoOnComponent(0)!="")
1899         throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
1900       int f=c1->front(),ll=c1->back();
1901       if(f<0 || f>=sz2)
1902         {
1903           std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !";
1904           throw INTERP_KERNEL::Exception(oss.str().c_str());
1905         }
1906       if(ll<0 || ll>sz2)
1907         {
1908           std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !";
1909           throw INTERP_KERNEL::Exception(oss.str().c_str());
1910         }
1911       if(f>ll)
1912         {
1913           std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !";
1914           throw INTERP_KERNEL::Exception(oss.str().c_str());
1915         }
1916     }
1917   else
1918     throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !");
1919   int szOfC1Exp=_conn_indx->back();
1920   if(sz2<szOfC1Exp)
1921     {
1922       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !";
1923       throw INTERP_KERNEL::Exception(oss.str().c_str());
1924     }
1925 }
1926
1927 /*!
1928  * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated.
1929  * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one.
1930  * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array.
1931  */
1932 void MEDCoupling1DGTUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
1933 {
1934   MEDCouplingPointSet::checkCoherency();
1935   checkCoherencyOfConnectivity();
1936 }
1937
1938 void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
1939 {
1940   checkCoherency();
1941   const DataArrayInt *c1(_conn),*c2(_conn_indx);
1942   if(!c2->isMonotonic(true))
1943     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !");
1944   //
1945   int nbOfTuples=c1->getNumberOfTuples();
1946   int nbOfNodes=getNumberOfNodes();
1947   const int *w(c1->begin());
1948   for(int i=0;i<nbOfTuples;i++,w++)
1949     {
1950       if(*w==-1) continue;
1951       if(*w<0 || *w>=nbOfNodes)
1952         {
1953           std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !";
1954           throw INTERP_KERNEL::Exception(oss.str().c_str());
1955         }
1956     }
1957 }
1958
1959 void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
1960 {
1961   checkCoherency1(eps);
1962 }
1963
1964 int MEDCoupling1DGTUMesh::getNumberOfCells() const
1965 {
1966   checkCoherencyOfConnectivity();//do not remove
1967   return _conn_indx->getNumberOfTuples()-1;
1968 }
1969
1970 /*!
1971  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1972  * For each cell in \b this the number of nodes constituting cell is computed.
1973  * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned.
1974  * So for pohyhedrons some nodes can be counted several times in the returned result.
1975  * 
1976  * \return a newly allocated array
1977  */
1978 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
1979 {
1980   checkCoherency();
1981   _conn_indx->checkMonotonic(true);
1982   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
1983     return _conn_indx->deltaShiftIndex();
1984   // for polyhedrons
1985   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
1986   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
1987   ret->alloc(nbOfCells,1);
1988   int *retPtr=ret->getPointer();
1989   const int *ci=_conn_indx->begin(),*c=_conn->begin();
1990   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
1991     *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1);
1992   return ret.retn();
1993 }
1994
1995 /*!
1996  * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
1997  * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed.
1998  * 
1999  * \return a newly allocated array
2000  */
2001 DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception)
2002 {
2003   checkCoherency();
2004   _conn_indx->checkMonotonic(true);
2005   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG)
2006     return _conn_indx->deltaShiftIndex();
2007   if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG)
2008     {
2009       MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex();
2010       ret->applyDivideBy(2);
2011       return ret.retn();
2012     }
2013   // for polyhedrons
2014   int nbOfCells=_conn_indx->getNumberOfTuples()-1;
2015   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2016   ret->alloc(nbOfCells,1);
2017   int *retPtr=ret->getPointer();
2018   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2019   for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2020     *retPtr=std::count(c+ci[0],c+ci[1],-1)+1;
2021   return ret.retn();
2022 }
2023
2024 /*!
2025  * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell,
2026  * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method.
2027  *
2028  * \return DataArrayInt * - new object to be deallocated by the caller.
2029  * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell
2030  */
2031 DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2032 {
2033   checkCoherency();
2034   _conn_indx->checkMonotonic(true);
2035   int nbOfCells(_conn_indx->getNumberOfTuples()-1);
2036   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2037   ret->alloc(nbOfCells,1);
2038   int *retPtr(ret->getPointer());
2039   const int *ci(_conn_indx->begin()),*c(_conn->begin());
2040   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2041     {
2042       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2043         {
2044           std::set<int> s(c+ci[0],c+ci[1]);
2045           *retPtr=(int)s.size();
2046         }
2047     }
2048   else
2049     {
2050       for(int i=0;i<nbOfCells;i++,retPtr++,ci++)
2051         {
2052           std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1);
2053           *retPtr=(int)s.size();
2054         }
2055     }
2056   return ret.retn();
2057 }
2058
2059 void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
2060 {
2061   int nbOfCells(getNumberOfCells());//performs checks
2062   if(cellId>=0 && cellId<nbOfCells)
2063     {
2064       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2065       int nbOfNodes=stp-strt;
2066       if(nbOfNodes<0)
2067         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !");
2068       conn.resize(nbOfNodes);
2069       std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin());
2070     }
2071   else
2072     {
2073       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2074       throw INTERP_KERNEL::Exception(oss.str().c_str());
2075     }
2076 }
2077
2078 int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception)
2079 {
2080   int nbOfCells(getNumberOfCells());//performs checks
2081   if(cellId>=0 && cellId<nbOfCells)
2082     {
2083       const int *conn(_conn->begin());
2084       int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0);
2085       return stp-strt-std::count(conn+strt,conn+stp,-1);
2086     }
2087   else
2088     {
2089       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !";
2090       throw INTERP_KERNEL::Exception(oss.str().c_str());
2091     }
2092 }
2093
2094 std::string MEDCoupling1DGTUMesh::simpleRepr() const
2095 {
2096   static const char msg0[]="No coordinates specified !";
2097   std::ostringstream ret;
2098   ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured mesh with name : \"" << getName() << "\"\n";
2099   ret << "Description of mesh : \"" << getDescription() << "\"\n";
2100   int tmpp1,tmpp2;
2101   double tt=getTime(tmpp1,tmpp2);
2102   ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
2103   ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
2104   ret << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : ";
2105   if(_coords!=0)
2106     {
2107       const int spaceDim=getSpaceDimension();
2108       ret << spaceDim << "\nInfo attached on space dimension : ";
2109       for(int i=0;i<spaceDim;i++)
2110         ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
2111       ret << "\n";
2112     }
2113   else
2114     ret << msg0 << "\n";
2115   ret << "Number of nodes : ";
2116   if(_coords!=0)
2117     ret << getNumberOfNodes() << "\n";
2118   else
2119     ret << msg0 << "\n";
2120   ret << "Number of cells : ";
2121   bool isOK=true;
2122   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2123     {
2124       ret << "Nodal connectivity arrays are not set or badly set !\n";
2125       isOK=false;
2126     }
2127   if(isOK)
2128     ret << getNumberOfCells() << "\n";
2129   ret << "Cell type : " << _cm->getRepr() << "\n";
2130   return ret.str();
2131 }
2132
2133 std::string MEDCoupling1DGTUMesh::advancedRepr() const
2134 {
2135   std::ostringstream ret;
2136   ret << simpleRepr();
2137   ret << "\nCoordinates array : \n___________________\n\n";
2138   if(_coords)
2139     _coords->reprWithoutNameStream(ret);
2140   else
2141     ret << "No array set !\n";
2142   ret << "\n\nNodal Connectivity : \n____________________\n\n";
2143   //
2144   bool isOK=true;
2145   try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& e)
2146     {
2147       ret << "Nodal connectivity arrays are not set or badly set !\n";
2148       isOK=false;
2149     }
2150   if(!isOK)
2151     return ret.str();
2152   int nbOfCells=getNumberOfCells();
2153   const int *ci=_conn_indx->begin(),*c=_conn->begin();
2154   for(int i=0;i<nbOfCells;i++,ci++)
2155     {
2156       ret << "Cell #" << i << " : ";
2157       std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," "));
2158       ret << "\n";
2159     }
2160   return ret.str();
2161 }
2162
2163 DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
2164 {
2165   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
2166   int spaceDim=getSpaceDimension();
2167   int nbOfCells=getNumberOfCells();//checkCoherency()
2168   int nbOfNodes=getNumberOfNodes();
2169   ret->alloc(nbOfCells,spaceDim);
2170   double *ptToFill=ret->getPointer();
2171   const double *coor=_coords->begin();
2172   const int *nodal=_conn->begin(),*nodali=_conn_indx->begin();
2173   nodal+=nodali[0];
2174   if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED)
2175     {
2176       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2177         {
2178           std::fill(ptToFill,ptToFill+spaceDim,0.);
2179           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2180             {
2181               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2182                 {
2183                   if(*nodal>=0 && *nodal<nbOfNodes)
2184                     std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2185                   else
2186                     {
2187                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2188                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2189                     }
2190                   std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0])));
2191                 }
2192             }
2193           else
2194             {
2195               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !";
2196               throw INTERP_KERNEL::Exception(oss.str().c_str());
2197             }
2198         }
2199     }
2200   else
2201     {
2202       for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++)
2203         {
2204           std::fill(ptToFill,ptToFill+spaceDim,0.);
2205           if(nodali[0]<nodali[1])// >= to avoid division by 0.
2206             {
2207               int nbOfNod=0;
2208               for(int j=nodali[0];j<nodali[1];j++,nodal++)
2209                 {
2210                   if(*nodal==-1) continue;
2211                   if(*nodal>=0 && *nodal<nbOfNodes)
2212                     {
2213                       std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>());
2214                       nbOfNod++;
2215                     }
2216                   else
2217                     {
2218                       std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," <<   nbOfNodes << ") !";
2219                       throw INTERP_KERNEL::Exception(oss.str().c_str());
2220                     }
2221                 }
2222               if(nbOfNod!=0)
2223                 std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod));
2224               else
2225                 {
2226                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !";
2227                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2228                 }
2229             }
2230           else
2231             {
2232               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron)  : at cell #" << i << " the nodal index array is invalid !";
2233               throw INTERP_KERNEL::Exception(oss.str().c_str());
2234             }
2235         }
2236     }
2237   return ret.retn();
2238 }
2239
2240 void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
2241 {
2242   int nbCells=getNumberOfCells();
2243   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New();
2244   o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1);
2245   if(check)
2246     o2n=o2n->checkAndPreparePermutation();
2247   //
2248   const int *o2nPtr=o2n->getPointer();
2249   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2250   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
2251   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
2252   newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1);
2253   newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx);
2254   //
2255   int *newC=newConn->getPointer(),*newCI=newConnI->getPointer();
2256   for(int i=0;i<nbCells;i++)
2257     {
2258       int newPos=o2nPtr[i];
2259       int sz=conni[i+1]-conni[i];
2260       if(sz>=0)
2261         newCI[newPos]=sz;
2262       else
2263         {
2264           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !";
2265           throw INTERP_KERNEL::Exception(oss.str().c_str());
2266         }
2267     }
2268   newConnI->computeOffsets2(); newCI=newConnI->getPointer();
2269   //
2270   for(int i=0;i<nbCells;i++,conni++)
2271     {
2272       int sz=conni[1]-conni[0];
2273       int newp=o2nPtr[i];
2274       std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]);
2275     }
2276   _conn=newConn;
2277   _conn_indx=newConnI;
2278 }
2279
2280 MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
2281 {
2282   if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED)
2283     throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !");
2284   const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other);
2285   return Merge1DGTUMeshes(this,otherC);
2286 }
2287
2288 MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
2289 {
2290   MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName().c_str(),getMeshDimension());
2291   ret->setCoords(getCoords());
2292   const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin();
2293   int nbCells=getNumberOfCells();//checkCoherency
2294   int geoType=(int)getCellModelEnum();
2295   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1);
2296   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1);
2297   int *cPtr=c->getPointer(),*ciPtr=cI->getPointer();
2298   ciPtr[0]=0;
2299   for(int i=0;i<nbCells;i++,ciPtr++)
2300     {
2301       int sz=nodalConnI[i+1]-nodalConnI[i];
2302       if(sz>=0)
2303         {
2304           *cPtr++=geoType;
2305           cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr);
2306           ciPtr[1]=ciPtr[0]+sz+1;
2307         }
2308       else
2309         {
2310           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !";
2311           throw INTERP_KERNEL::Exception(oss.str().c_str());
2312         }
2313     }
2314   ret->setConnectivity(c,cI,true);
2315   return ret.retn();
2316 }
2317
2318 /*!
2319  * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes
2320  */
2321 DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
2322 {
2323   int nbOfCells=getNumberOfCells();
2324   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2325   ret->alloc(nbOfCells,1);
2326   ret->iota(0);
2327   return ret.retn();
2328 }
2329
2330 void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const throw(INTERP_KERNEL::Exception)
2331 {
2332   stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\".";
2333   stream << " Mesh dimension : " << getMeshDimension() << ".";
2334   if(!_coords)
2335     { stream << " No coordinates set !"; return ; }
2336   if(!_coords->isAllocated())
2337     { stream << " Coordinates set but not allocated !"; return ; }
2338   stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl;
2339   stream << "Number of nodes : " << _coords->getNumberOfTuples() << ".";
2340   bool isOK=true;
2341   try { checkCoherency(); } catch(INTERP_KERNEL::Exception& e)
2342     {
2343       stream << std::endl << "Nodal connectivity NOT set properly !\n";
2344       isOK=false;
2345     }
2346   if(isOK)
2347     stream << std::endl << "Number of cells : " << getNumberOfCells() << ".";
2348 }
2349
2350 void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception)
2351 {
2352   if(!other)
2353     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !");
2354   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2355   if(!otherC)
2356     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !");
2357   setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex());
2358 }
2359
2360 MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const
2361 {
2362   if(!other)
2363     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !");
2364   const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other);
2365   if(!otherC)
2366     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !");
2367   std::vector<const MEDCoupling1DGTUMesh *> ms(2);
2368   ms[0]=this;
2369   ms[1]=otherC;
2370   return Merge1DGTUMeshesOnSameCoords(ms);
2371 }
2372
2373 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
2374 {
2375   checkCoherency();
2376   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2377   ret->setCoords(_coords);
2378   DataArrayInt *c=0,*ci=0;
2379   MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci);
2380   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2381   ret->setNodalConnectivity(c,ci);
2382   return ret.retn();
2383 }
2384
2385 MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
2386 {
2387   checkCoherency();
2388   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2389   ret->setCoords(_coords);
2390   DataArrayInt *c=0,*ci=0;
2391   MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci);
2392   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci);
2393   ret->setNodalConnectivity(c,ci);
2394   return ret.retn();
2395 }
2396
2397 void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const throw(INTERP_KERNEL::Exception)
2398 {
2399   int sz((int)nodeIdsInUse.size());
2400   int nbCells(getNumberOfCells());
2401   const int *w(_conn->begin()),*wi(_conn_indx->begin());
2402   for(int i=0;i<nbCells;i++,wi++)
2403     for(const int *pt=w+wi[0];pt!=w+wi[1];pt++)
2404       if(*pt!=-1)
2405         {
2406           if(*pt>=0 && *pt<sz)
2407             nodeIdsInUse[*pt]=true;
2408           else
2409             {
2410               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At cell #" << i << " presence of node id #" << *pt << " should be in [0," << sz << ") !";
2411               throw INTERP_KERNEL::Exception(oss.str().c_str());
2412             }
2413         }
2414 }
2415
2416 void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
2417 {
2418   checkFullyDefined();
2419   int nbOfNodes=getNumberOfNodes();
2420   int *revNodalIndxPtr=(int *)malloc((nbOfNodes+1)*sizeof(int));
2421   revNodalIndx->useArray(revNodalIndxPtr,true,C_DEALLOC,nbOfNodes+1,1);
2422   std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
2423   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2424   int nbOfCells=getNumberOfCells();
2425   int nbOfEltsInRevNodal=0;
2426   for(int eltId=0;eltId<nbOfCells;eltId++)
2427     {
2428       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2429       if(nbOfNodesPerCell>=0)
2430         {
2431           for(int j=0;j<nbOfNodesPerCell;j++)
2432             {
2433               int nodeId=conn[conni[eltId]+j];
2434               if(nodeId==-1) continue;            
2435               if(nodeId>=0 && nodeId<nbOfNodes)
2436                 {
2437                   nbOfEltsInRevNodal++;
2438                   revNodalIndxPtr[nodeId+1]++;
2439                 }
2440               else
2441                 {
2442                   std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !";
2443                   throw INTERP_KERNEL::Exception(oss.str().c_str());
2444                 }
2445             }
2446         }
2447       else
2448         {
2449           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !";
2450           throw INTERP_KERNEL::Exception(oss.str().c_str());
2451         }
2452     }
2453   std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
2454   conn=_conn->begin();
2455   int *revNodalPtr=(int *)malloc((nbOfEltsInRevNodal)*sizeof(int));
2456   revNodal->useArray(revNodalPtr,true,C_DEALLOC,nbOfEltsInRevNodal,1);
2457   std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
2458   for(int eltId=0;eltId<nbOfCells;eltId++)
2459     {
2460       int nbOfNodesPerCell=conni[eltId+1]-conni[eltId];
2461       for(int j=0;j<nbOfNodesPerCell;j++)
2462         {
2463           int nodeId=conn[conni[eltId]+j];
2464           if(nodeId!=-1)
2465             *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
2466         }
2467     }
2468 }
2469
2470 void MEDCoupling1DGTUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
2471 {
2472   if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords))
2473     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined.");
2474 }
2475
2476 bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
2477 {
2478   throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !");
2479 }
2480
2481 /*!
2482  * Finds nodes not used in any cell and returns an array giving a new id to every node
2483  * by excluding the unused nodes, for which the array holds -1. The result array is
2484  * a mapping in "Old to New" mode. 
2485  *  \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity.
2486  *  \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a
2487  *          this->getNumberOfNodes(). It holds for each node of \a this mesh either -1
2488  *          if the node is unused or a new id else. The caller is to delete this
2489  *          array using decrRef() as it is no more needed.  
2490  *  \throw If the coordinates array is not set.
2491  *  \throw If the nodal connectivity of cells is not defined.
2492  *  \throw If the nodal connectivity includes an invalid id.
2493  */
2494 DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
2495 {
2496   nbrOfNodesInUse=-1;
2497   int nbOfNodes=getNumberOfNodes();
2498   int nbOfCells=getNumberOfCells();//checkCoherency
2499   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
2500   ret->alloc(nbOfNodes,1);
2501   int *traducer=ret->getPointer();
2502   std::fill(traducer,traducer+nbOfNodes,-1);
2503   const int *conn=_conn->begin(),*conni(_conn_indx->begin());
2504   for(int i=0;i<nbOfCells;i++,conni++)
2505     {
2506       int nbNodesPerCell=conni[1]-conni[0];
2507       for(int j=0;j<nbNodesPerCell;j++)
2508         {
2509           int nodeId=conn[conni[0]+j];
2510           if(nodeId==-1) continue;
2511           if(nodeId>=0 && nodeId<nbOfNodes)
2512             traducer[nodeId]=1;
2513           else
2514             {
2515               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i  << " presence of node id " <<  nodeId << " not in [0," << nbOfNodes << ") !";
2516               throw INTERP_KERNEL::Exception(oss.str().c_str());
2517             }
2518         }
2519     }
2520   nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
2521   std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
2522   return ret.retn();
2523 }
2524
2525 /*!
2526  * Changes ids of nodes within the nodal connectivity arrays according to a permutation
2527  * array in "Old to New" mode. The node coordinates array is \b not changed by this method.
2528  * This method is a generalization of shiftNodeNumbersInConn().
2529  *  \warning This method performs no check of validity of new ids. **Use it with care !**
2530  *  \param [in] newNodeNumbersO2N - a permutation array, of length \a
2531  *         this->getNumberOfNodes(), in "Old to New" mode. 
2532  *         See \ref MEDCouplingArrayRenumbering for more info on renumbering modes.
2533  *  \throw If the nodal connectivity of cells is not defined.
2534  */
2535 void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
2536 {
2537   getNumberOfCells();//only to check that all is well defined.
2538   //
2539   int nbElemsIn=getNumberOfNodes();
2540   int nbOfTuples=_conn->getNumberOfTuples();
2541   int *pt=_conn->getPointer();
2542   for(int i=0;i<nbOfTuples;i++,pt++)
2543     {
2544       if(*pt==-1) continue;
2545       if(*pt>=0 && *pt<nbElemsIn)
2546         *pt=newNodeNumbersO2N[*pt];
2547       else
2548         {
2549           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
2550           throw INTERP_KERNEL::Exception(oss.str().c_str());
2551         }
2552     }
2553   _conn->declareAsNew();
2554   //
2555   updateTime();
2556 }
2557
2558 /*!
2559  * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end).
2560  * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
2561  * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not.
2562  * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept.
2563  *
2564  * \param [in] begin input start of array of node ids.
2565  * \param [in] end input end of array of node ids.
2566  * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in.
2567  * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end.
2568  */
2569 void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const
2570 {
2571   int nbOfCells=getNumberOfCells();
2572   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1);
2573   int tmp=-1;
2574   int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1;
2575   std::vector<bool> fastFinder(sz,false);
2576   for(const int *work=begin;work!=end;work++)
2577     if(*work>=0 && *work<sz)
2578       fastFinder[*work]=true;
2579   const int *conn=_conn->begin(),*conni=_conn_indx->begin();
2580   for(int i=0;i<nbOfCells;i++,conni++)
2581     {
2582       int ref=0,nbOfHit=0;
2583       int nbNodesPerCell=conni[1]-conni[0];
2584       if(nbNodesPerCell>=0)
2585         {
2586           for(int j=0;j<nbNodesPerCell;j++)
2587             {
2588               int nodeId=conn[conni[0]+j];
2589               if(nodeId>=0)
2590                 {
2591                   ref++;
2592                   if(fastFinder[nodeId])
2593                     nbOfHit++;
2594                 }
2595             }
2596         }
2597       else
2598         {
2599           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !";
2600           throw INTERP_KERNEL::Exception(oss.str().c_str());
2601         }
2602       if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn))
2603         cellIdsKept->pushBackSilent(i);
2604     }
2605   cellIdsKeptArr=cellIdsKept.retn();
2606 }
2607
2608 void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) throw(INTERP_KERNEL::Exception)
2609 {
2610   if(nbOfCells<0)
2611     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !");
2612   _conn=DataArrayInt::New();
2613   _conn->reserve(nbOfCells*3);
2614   _conn_indx=DataArrayInt::New();
2615   _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0);
2616   declareAsNew();
2617 }
2618
2619 /*!
2620  * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ).
2621  *
2622  * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add.
2623  * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add.
2624  * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type
2625  *        attached to \a this.
2626  * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before).
2627  */
2628 void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) throw(INTERP_KERNEL::Exception)
2629 {
2630   int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd);
2631   DataArrayInt *c(_conn),*c2(_conn_indx);
2632   if(c && c2)
2633     {
2634       int pos=c2->back();
2635       if(pos==c->getNumberOfTuples())
2636         {
2637           c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd);
2638           c2->pushBackSilent(pos+sz);
2639         }
2640       else
2641         {
2642           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !";
2643           throw INTERP_KERNEL::Exception(oss.str().c_str());
2644         }
2645     }
2646   else
2647     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !");
2648 }
2649
2650 void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception)
2651 {
2652   if(nodalConn)
2653     nodalConn->incrRef();
2654   _conn=nodalConn;
2655   if(nodalConnIndex)
2656     nodalConnIndex->incrRef();
2657   _conn_indx=nodalConnIndex;
2658   declareAsNew();
2659 }
2660
2661 /*!
2662  * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it.
2663  */
2664 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const throw(INTERP_KERNEL::Exception)
2665 {
2666   const DataArrayInt *ret(_conn);
2667   return const_cast<DataArrayInt *>(ret);
2668 }
2669
2670 /*!
2671  * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it.
2672  */
2673 DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception)
2674 {
2675   const DataArrayInt *ret(_conn_indx);
2676   return const_cast<DataArrayInt *>(ret);
2677 }
2678
2679 /*!
2680  * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here".
2681  * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity).
2682  * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this.
2683  *
2684  * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this.
2685  * 
2686  * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal
2687  *              connectivity arrays are different (false)
2688  * \return a new object to be managed by the caller.
2689  * 
2690  * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked
2691  */
2692 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const throw(INTERP_KERNEL::Exception)
2693 {
2694   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2695   DataArrayInt *nc=0,*nci=0;
2696   isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci);
2697   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci);
2698   ret->_conn=ncs; ret->_conn_indx=ncis;
2699   ret->setCoords(getCoords());
2700   return ret.retn();
2701 }
2702
2703 /*!
2704  * This method allows to compute, if needed, the packed nodal connectivity pair.
2705  * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array.
2706  * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn.
2707  * 
2708  * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
2709  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2710  *
2711  * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false
2712  * will be returned.
2713  * 
2714  * This method return 3 elements.
2715  * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter
2716  *                          this pointer can be seen as a new object, that is to managed by the caller.
2717  * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter
2718  *                              this pointer can be seen as a new object, that is to managed by the caller.
2719  * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then
2720  * output parameters are newly created objects.
2721  *
2722  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2723  */
2724 bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const throw(INTERP_KERNEL::Exception)
2725 {
2726   if(isPacked())//performs the checkCoherency
2727     {
2728       const DataArrayInt *c0(_conn),*c1(_conn_indx);
2729       nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1);
2730       nodalConn->incrRef(); nodalConnIndx->incrRef();
2731       return true;
2732     }
2733   int bg=_conn_indx->front(),end=_conn_indx->back();
2734   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1));
2735   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy());
2736   nci->applyLin(1,-bg);
2737   nodalConn=nc.retn(); nodalConnIndx=nci.retn();
2738   return false;
2739 }
2740
2741 /*
2742  * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array)
2743  * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case.
2744  * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned.
2745  * \return bool - true if \a this looks packed, false is not.
2746  *
2747  * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test
2748  */
2749 bool MEDCoupling1DGTUMesh::isPacked() const throw(INTERP_KERNEL::Exception)
2750 {
2751   checkCoherency();
2752   return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples();
2753 }
2754
2755 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) throw(INTERP_KERNEL::Exception)
2756 {
2757   std::vector<const MEDCoupling1DGTUMesh *> tmp(2);
2758   tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2);
2759   return Merge1DGTUMeshes(tmp);
2760 }
2761
2762 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2763 {
2764   std::size_t sz=a.size();
2765   if(sz==0)
2766     return Merge1DGTUMeshesLL(a);
2767   for(std::size_t ii=0;ii<sz;ii++)
2768     if(!a[ii])
2769       {
2770         std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
2771         throw INTERP_KERNEL::Exception(oss.str().c_str());
2772       }
2773   const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel());
2774   for(std::size_t ii=0;ii<sz;ii++)
2775     if(&(a[ii]->getCellModel())!=cm)
2776       throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !");
2777   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz);
2778   std::vector< const MEDCoupling1DGTUMesh * > aa(sz);
2779   int spaceDim=-3;
2780   for(std::size_t i=0;i<sz && spaceDim==-3;i++)
2781     {
2782       const MEDCoupling1DGTUMesh *cur=a[i];
2783       const DataArrayDouble *coo=cur->getCoords();
2784       if(coo)
2785         spaceDim=coo->getNumberOfComponents();
2786     }
2787   if(spaceDim==-3)
2788     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !");
2789   for(std::size_t i=0;i<sz;i++)
2790     {
2791       bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
2792       aa[i]=bb[i];
2793     }
2794   return Merge1DGTUMeshesLL(aa);
2795 }
2796
2797 /*!
2798  * \throw If presence of a null instance in the input vector \a a.
2799  * \throw If a is empty
2800  */
2801 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2802 {
2803   if(a.empty())
2804     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !");
2805   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2806   if(!(*it))
2807     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !");
2808   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2809   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2810   int nbOfCells=(*it)->getNumberOfCells();
2811   const DataArrayDouble *coords=(*it)->getCoords();
2812   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2813   bool tmp;
2814   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2815   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2816   it++;
2817   for(int i=1;it!=a.end();i++,it++)
2818     {
2819       if(!(*it))
2820         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !");
2821       if(cm!=&((*it)->getCellModel()))
2822         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2823       (*it)->getNumberOfCells();//to check that all is OK
2824       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2825       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2826       if(coords!=(*it)->getCoords())
2827         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !");
2828     }
2829   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2830   ret->setCoords(coords);
2831   ret->_conn=DataArrayInt::Aggregate(ncs);
2832   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2833   return ret.retn();
2834 }
2835
2836 /*!
2837  * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL)
2838  */
2839 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) throw(INTERP_KERNEL::Exception)
2840 {
2841   if(a.empty())
2842     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !");
2843   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size());
2844   std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size());
2845   std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin();
2846   std::vector<int> nbNodesPerElt(a.size());
2847   int nbOfCells=(*it)->getNumberOfCells();
2848   bool tmp;
2849   objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp);
2850   ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex();
2851   nbNodesPerElt[0]=0;
2852   int prevNbOfNodes=(*it)->getNumberOfNodes();
2853   const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel());
2854   it++;
2855   for(int i=1;it!=a.end();i++,it++)
2856     {
2857       if(cm!=&((*it)->getCellModel()))
2858         throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !");
2859       objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp);
2860       ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex();
2861       nbOfCells+=(*it)->getNumberOfCells();
2862       nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes;
2863       prevNbOfNodes=(*it)->getNumberOfNodes();
2864     }
2865   std::vector<const MEDCouplingPointSet *> aps(a.size());
2866   std::copy(a.begin(),a.end(),aps.begin());
2867   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps);
2868   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm));
2869   ret->setCoords(pts);
2870   ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt);
2871   ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis);
2872   return ret.retn();
2873 }
2874
2875 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
2876 {
2877   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName().c_str(),*_cm));
2878   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
2879   const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx);
2880   if(!nodalConn)
2881     {
2882       tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
2883     }
2884   else
2885     tmp1=_conn;
2886   ret->_conn=tmp1;
2887   //
2888   if(!nodalConnI)
2889     {
2890       tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
2891     }
2892   else
2893     tmp2=_conn_indx;
2894   ret->_conn_indx=tmp2;
2895   //
2896   if(!_coords)
2897     {
2898       MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
2899       ret->setCoords(coords);
2900     }
2901   else
2902     ret->setCoords(_coords);
2903   return ret.retn();
2904 }
2905
2906 std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) throw(INTERP_KERNEL::Exception)
2907 {
2908   std::vector<int> ret;
2909   if(parts.empty())
2910     return ret;
2911   ret.insert(ret.end(),parts[0].begin(),parts[0].end());
2912   int ref(ret.back());
2913   std::size_t sz(parts.size()),nbh(1);
2914   std::vector<bool> b(sz,true); b[0]=false;
2915   while(nbh<sz)
2916     {
2917       std::size_t i(0);
2918       for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; }
2919       if(i<sz)
2920         ref=ret.back();
2921       else
2922         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !");
2923     }
2924   if(ret.back()==ret.front())
2925     ret.pop_back();
2926   return ret;
2927 }
2928
2929 /*!
2930  * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the 
2931  * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt.
2932  * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron).
2933  *
2934  * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt.
2935  * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply.
2936  * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation.
2937  * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty.
2938  * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size.
2939  * \throw If presence of null pointer in \a nodalConns.
2940  * \throw If presence of not allocated or array with not exactly one component in \a nodalConns.
2941  */
2942 DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception)
2943 {
2944   std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size());
2945   if(sz1!=sz2)
2946     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !");
2947   if(sz1==0)
2948     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !");
2949   int nbOfTuples=0;
2950   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++)
2951     {
2952       if(!(*it))
2953         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !");
2954       if(!(*it)->isAllocated())
2955         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !");
2956       if((*it)->getNumberOfComponents()!=1)
2957         throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !");
2958       nbOfTuples+=(*it)->getNumberOfTuples();
2959     }
2960   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1);
2961   int *pt=ret->getPointer();
2962   int i=0;
2963   for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++)
2964     {
2965       int curNbt=(*it)->getNumberOfTuples();
2966       const int *inPt=(*it)->begin();
2967       int offset=offsetInNodeIdsPerElt[i];
2968       for(int j=0;j<curNbt;j++,pt++)
2969         {
2970           if(inPt[j]!=-1)
2971             *pt=inPt[j]+offset;
2972           else
2973             *pt=-1;
2974         }
2975     }
2976   return ret.retn();
2977 }
2978
2979 MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception)
2980 {
2981   if(!m)
2982     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !");
2983   std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes());
2984   if(gts.size()!=1)
2985     throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !");
2986   int geoType((int)*gts.begin());
2987   MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName().c_str(),*gts.begin()));
2988   ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription().c_str());
2989   int nbCells(m->getNumberOfCells());
2990   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New());
2991   conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1);
2992   int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0;
2993   const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin());
2994   for(int i=0;i<nbCells;i++,ciin++,ci++)
2995     {
2996       if(cin[ciin[0]]==geoType)
2997         {
2998           if(ciin[1]-ciin[0]>=1)
2999             {
3000               c=std::copy(cin+ciin[0]+1,cin+ciin[1],c);
3001               ci[1]=ci[0]+ciin[1]-ciin[0]-1;
3002             }
3003           else
3004             {
3005               std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !";
3006               throw INTERP_KERNEL::Exception(oss.str().c_str());
3007             }
3008         }
3009       else
3010         {
3011           std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !";
3012           throw INTERP_KERNEL::Exception(oss.str().c_str());
3013         }
3014     }
3015   ret->setNodalConnectivity(conn,connI);
3016   return ret.retn();
3017 }