+ }
+}
+
+/*!
+ * This method takes in input a compact format [[Xmax,Xmin),[Ymin,Ymax)] and returns the corresponding dimensions for each axis that is to say
+ * [Xmax-Xmin,Ymax-Ymin].
+ *
+ * \throw if an axis range is so that max<min
+ * \sa GetCompactFrmtFromDimensions
+ */
+std::vector<mcIdType> MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(const std::vector< std::pair<mcIdType,mcIdType> >& partCompactFormat)
+{
+ std::vector<mcIdType> ret(partCompactFormat.size());
+ for(std::size_t i=0;i<partCompactFormat.size();i++)
+ {
+ if(partCompactFormat[i].first>partCompactFormat[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " end is before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ ret[i]=partCompactFormat[i].second-partCompactFormat[i].first;
+ }
+ return ret;
+}
+
+/*!
+ * This method takes in input a vector giving the number of entity per axis and returns for each axis a range starting from [0,0...]
+ *
+ * \throw if there is an axis in \a dims that is < 0.
+ * \sa GetDimensionsFromCompactFrmt, ChangeReferenceFromGlobalOfCompactFrmt, ChangeReferenceToGlobalOfCompactFrmt
+ */
+std::vector< std::pair<mcIdType,mcIdType> > MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(const std::vector<mcIdType>& dims)
+{
+ std::size_t sz(dims.size());
+ std::vector< std::pair<mcIdType,mcIdType> > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ if(dims[i]<0)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " dimension < 0 !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ ret[i].first=0;
+ ret[i].second=dims[i];
+ }
+ return ret;
+}
+
+/*!
+ * This method returns the intersection zone of two ranges (in compact format) \a r1 and \a r2.
+ * This method will throw exception if on one axis the intersection is empty.
+ *
+ * \sa AreRangesIntersect
+ */
+std::vector< std::pair<mcIdType,mcIdType> > MEDCouplingStructuredMesh::IntersectRanges(const std::vector< std::pair<mcIdType,mcIdType> >& r1, const std::vector< std::pair<mcIdType,mcIdType> >& r2)
+{
+ std::size_t sz(r1.size());
+ if(sz!=r2.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IntersectRanges : the two ranges must have the same dimension !");
+ std::vector< std::pair<mcIdType,mcIdType> > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ if(r1[i].first>r1[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r1, end is before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(r2[i].first>r2[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r2, end is before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ ret[i].first=std::max(r1[i].first,r2[i].first);
+ ret[i].second=std::min(r1[i].second,r2[i].second);
+ if(ret[i].first>ret[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " the intersection of r1 and r2 is empty !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ return ret;
+}
+
+/*!
+ * This method states if \a r1 and \a r2 do overlap of not. If yes you can call IntersectRanges to know the intersection area.
+ *
+ * \sa IntersectRanges
+ */
+bool MEDCouplingStructuredMesh::AreRangesIntersect(const std::vector< std::pair<mcIdType,mcIdType> >& r1, const std::vector< std::pair<mcIdType,mcIdType> >& r2)
+{
+ std::size_t sz(r1.size());
+ if(sz!=r2.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::AreRangesIntersect : the two ranges must have the same dimension !");
+ for(std::size_t i=0;i<sz;i++)
+ {
+ if(r1[i].first>r1[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r1, end is before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(r2[i].first>r2[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r2, end is before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(r1[i].second<=r2[i].first)
+ return false;
+ if(r1[i].first>=r2[i].second)
+ return false;
+ }
+ return true;
+}
+
+/*!
+ * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayIdType instance containing explicit ids it
+ * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not
+ * available in python.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \param [in,out] vectToSwitchOn Vector which fetched items are enabled.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, ExtractFieldOfBoolFrom
+ */
+void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector<mcIdType>& st, const std::vector< std::pair<mcIdType,mcIdType> >& partCompactFormat, std::vector<bool>& vectToSwitchOn)
+{
+ if(st.size()!=partCompactFormat.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !");
+ if(ToIdType(vectToSwitchOn.size())!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !");
+ std::vector<mcIdType> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ switch(st.size())
+ {
+ case 3:
+ {
+ for(mcIdType i=0;i<dims[2];i++)
+ {
+ mcIdType a=(partCompactFormat[2].first+i)*st[0]*st[1];
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ vectToSwitchOn[partCompactFormat[0].first+k+b+a]=true;
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ vectToSwitchOn[partCompactFormat[0].first+k+b]=true;
+ }
+ break;
+ }
+ case 1:
+ {
+ for(mcIdType k=0;k<dims[0];k++)
+ vectToSwitchOn[partCompactFormat[0].first+k]=true;
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : Dimension supported are 1,2 or 3 !");
+ }
+}
+
+/*!
+ * Obviously this method is \b NOT wrapped in python.
+ * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfBool having the structure \a st.
+ * The extraction is defined by \a partCompactFormat.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] fieldOfBool field of booleans having the size equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st).
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \param [out] fieldOut the result of the extraction.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfDoubleFrom
+ */
+void MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(const std::vector<mcIdType>& st, const std::vector<bool>& fieldOfBool, const std::vector< std::pair<mcIdType,mcIdType> >& partCompactFormat, std::vector<bool>& fieldOut)
+{
+ if(st.size()!=partCompactFormat.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : input arrays must have the same size !");
+ if(ToIdType(fieldOfBool.size())!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : invalid size of input field of boolean regarding the structure !");
+ std::vector<mcIdType> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ mcIdType nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims));
+ fieldOut.resize(nbOfTuplesOfOutField);
+ mcIdType it(0);
+ switch(st.size())
+ {
+ case 3:
+ {
+ for(mcIdType i=0;i<dims[2];i++)
+ {
+ mcIdType a=(partCompactFormat[2].first+i)*st[0]*st[1];
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b+a];
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b];
+ }
+ break;
+ }
+ case 1:
+ {
+ for(mcIdType k=0;k<dims[0];k++)
+ fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k];
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : Dimension supported are 1,2 or 3 !");
+ }
+}
+
+/*!
+ * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfDbl having the structure \a st.
+ * The extraction is defined by \a partCompactFormat.
+ *
+ * \param [in] st The entity structure.
+ * \param [in] fieldOfDbl field of doubles having a number of tuples equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st).
+ * \param [in] partCompactFormat The compact subpart to be enabled.
+ * \return DataArrayDouble * -the result of the extraction.
+ *
+ * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom
+ */
+DataArrayDouble *MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(const std::vector<mcIdType>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<mcIdType,mcIdType> >& partCompactFormat)
+{
+ if(!fieldOfDbl || !fieldOfDbl->isAllocated())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input array of double is NULL or not allocated!");
+ if(st.size()!=partCompactFormat.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input arrays must have the same size !");
+ if(fieldOfDbl->getNumberOfTuples()!=DeduceNumberOfGivenStructure(st))
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !");
+ std::vector<mcIdType> dims(GetDimensionsFromCompactFrmt(partCompactFormat));
+ mcIdType nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims));
+ std::size_t nbComp(fieldOfDbl->getNumberOfComponents());
+ MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp);
+ ret->copyStringInfoFrom(*fieldOfDbl);
+ double *ptRet(ret->getPointer());
+ const double *fieldOfDblPtr(fieldOfDbl->begin());
+ switch(st.size())
+ {
+ case 3:
+ {
+ for(mcIdType i=0;i<dims[2];i++)
+ {
+ mcIdType a=(partCompactFormat[2].first+i)*st[0]*st[1];
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b+a)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+a+1)*nbComp,ptRet);
+ }
+ }
+ break;
+ }
+ case 2:
+ {
+ for(mcIdType j=0;j<dims[1];j++)
+ {
+ mcIdType b=(partCompactFormat[1].first+j)*st[0];
+ for(mcIdType k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+1)*nbComp,ptRet);
+ }
+ break;
+ }
+ case 1:
+ {
+ for(mcIdType k=0;k<dims[0];k++)
+ ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+1)*nbComp,ptRet);
+ break;
+ }
+ default:
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : Dimension supported are 1,2 or 3 !");
+ }
+ return ret.retn();
+}
+
+/*!
+ * This method assign a part of values in \a fieldOfDbl using entirely values of \b other.
+ *
+ * \param [in] st - the structure of \a fieldOfDbl.
+ * \param [in,out] fieldOfDbl - the array that will be partially filled using \a other.
+ * \param [in] partCompactFormat - the specification of the part.
+ * \param [in] other - the array that will be used to fill \a fieldOfDbl.
+ */
+void MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(const std::vector<mcIdType>& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair<mcIdType,mcIdType> >& partCompactFormat, const DataArrayDouble *other)
+{//to be optimized
+ std::vector<mcIdType> facts(st.size(),1);
+ MEDCouplingIMesh::CondenseFineToCoarse(st,other,partCompactFormat,facts,fieldOfDbl);
+}
+
+/*!
+ * This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs.
+ * So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs
+ * This method also checks (if \a check=true) that \a partOfBigInAbs is included in \a bigInAbs.
+ * This method is useful to extract a part from a field lying on a big mesh.
+ *
+ * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom
+ */
+void MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<mcIdType,mcIdType> >& bigInAbs, const std::vector< std::pair<mcIdType,mcIdType> >& partOfBigInAbs, std::vector< std::pair<mcIdType,mcIdType> >& partOfBigRelativeToBig, bool check)
+{
+ std::size_t dim(bigInAbs.size());
+ if(dim!=partOfBigInAbs.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : The size of parts (dimension) must be the same !");
+ partOfBigRelativeToBig.resize(dim);
+ for(std::size_t i=0;i<dim;i++)
+ {
+ if(check)
+ {
+ if(bigInAbs[i].first>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(partOfBigInAbs[i].first<bigInAbs[i].first || partOfBigInAbs[i].first>=bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (start) !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ partOfBigRelativeToBig[i].first=partOfBigInAbs[i].first-bigInAbs[i].first;
+ if(check)
+ {
+ if(partOfBigInAbs[i].second<partOfBigInAbs[i].first || partOfBigInAbs[i].second>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (end) !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ partOfBigRelativeToBig[i].second=partOfBigInAbs[i].second-bigInAbs[i].first;
+ }
+}
+
+/*
+ * This method is performs the opposite reference modification than explained in ChangeReferenceFromGlobalOfCompactFrmt.
+ *
+ * \sa ChangeReferenceFromGlobalOfCompactFrmt
+ */
+void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<mcIdType,mcIdType> >& bigInAbs, const std::vector< std::pair<mcIdType,mcIdType> >& partOfBigRelativeToBig, std::vector< std::pair<mcIdType,mcIdType> >& partOfBigInAbs, bool check)
+{
+ std::size_t dim(bigInAbs.size());
+ if(dim!=partOfBigRelativeToBig.size())
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : The size of parts (dimension) must be the same !");
+ partOfBigInAbs.resize(dim);
+ for(std::size_t i=0;i<dim;i++)
+ {
+ if(check)
+ {
+ if(bigInAbs[i].first>bigInAbs[i].second)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ if(partOfBigRelativeToBig[i].first<0 || partOfBigRelativeToBig[i].first>=bigInAbs[i].second-bigInAbs[i].first)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the start of part is not in the big one !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ partOfBigInAbs[i].first=partOfBigRelativeToBig[i].first+bigInAbs[i].first;
+ if(check)
+ {
+ if(partOfBigRelativeToBig[i].second<partOfBigRelativeToBig[i].first || partOfBigRelativeToBig[i].second>bigInAbs[i].second-bigInAbs[i].first)
+ {
+ std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the end of part is not in the big one !";
+ throw INTERP_KERNEL::Exception(oss.str().c_str());
+ }
+ }
+ partOfBigInAbs[i].second=partOfBigRelativeToBig[i].second+bigInAbs[i].first;
+ }
+}
+
+/*!
+ * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part.
+ *
+ * \sa FindTranslationFrom
+ */
+std::vector< std::pair<mcIdType,mcIdType> > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair<mcIdType,mcIdType> >& part, const std::vector<mcIdType>& translation)
+{
+ std::size_t sz(part.size());
+ if(translation.size()!=sz)
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the sizes are not equal !");
+ std::vector< std::pair<mcIdType,mcIdType> > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ ret[i].first=part[i].first+translation[i];
+ ret[i].second=part[i].second+translation[i];
+ }
+ return ret;
+}
+
+/*!
+ * \sa TranslateCompactFrmt
+ */
+std::vector<mcIdType> MEDCouplingStructuredMesh::FindTranslationFrom(const std::vector< std::pair<mcIdType,mcIdType> >& startingFrom, const std::vector< std::pair<mcIdType,mcIdType> >& goingTo)
+{
+ std::size_t sz(startingFrom.size());
+ if(goingTo.size()!=sz)
+ throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindTranslationFrom : the sizes are not equal !");
+ std::vector< mcIdType > ret(sz);
+ for(std::size_t i=0;i<sz;i++)
+ {
+ ret[i]=goingTo[i].first-startingFrom[i].first;