From 44dfb5cb0a3e28774db53fdc4331d4a1bee31268 Mon Sep 17 00:00:00 2001 From: geay Date: Thu, 20 Feb 2014 12:38:38 +0100 Subject: [PATCH] Little refactory --- .../InterpKernelGeo2DQuadraticPolygon.cxx | 54 ++++++++++----- .../InterpKernelGeo2DQuadraticPolygon.hxx | 6 +- src/MEDCoupling/MEDCouplingUMesh.cxx | 65 ++++++++++++++++--- src/MEDCoupling/MEDCouplingUMesh.hxx | 1 + src/MEDCoupling_Swig/MEDCouplingCommon.i | 2 + 5 files changed, 102 insertions(+), 26 deletions(-) diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx index 431ee8ad9..9bbe6ce55 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -70,41 +70,63 @@ QuadraticPolygon::~QuadraticPolygon() { } -QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector& nodes, bool isClosed) +QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector& nodes) { - QuadraticPolygon *ret=new QuadraticPolygon; + QuadraticPolygon *ret(new QuadraticPolygon); std::size_t size=nodes.size(); - for(std::size_t i=0;i< (size - (isClosed?0:1));i++) + for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%size])); nodes[i]->decrRef(); } - if(!isClosed) - nodes[size-1]->decrRef(); return ret; } -QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector& nodes, bool isClosed) +QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector& nodes) { - QuadraticPolygon *ret=new QuadraticPolygon; + QuadraticPolygon *ret(new QuadraticPolygon); std::size_t size=nodes.size(); - std::size_t quad_offset = isClosed ? (size/2) : (size/2+1); - for(std::size_t i = 0; i < size/2; i++) + for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%quad_offset])); + ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)])); else - ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+quad_offset],nodes[(i+1)%quad_offset])); - nodes[i]->decrRef(); nodes[i+quad_offset]->decrRef(); + ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)])); + nodes[i]->decrRef(); nodes[i+size/2]->decrRef(); } - if(!isClosed) - nodes[quad_offset-1]->decrRef(); + return ret; +} + +Edge *QuadraticPolygon::BuildLinearEdge(std::vector& nodes) +{ + if(nodes.size()!=2) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !"); + Edge *ret(new EdgeLin(nodes[0],nodes[1])); + nodes[0]->decrRef(); nodes[1]->decrRef(); + return ret; +} + +Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector& nodes) +{ + if(nodes.size()!=3) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !"); + EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1])); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + Edge *ret(0); + if(colinearity) + ret=new EdgeLin(nodes[0],nodes[1]); + else + ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]); + nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef(); return ret; } diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx index a8097a256..c6d235e1c 100644 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx @@ -46,8 +46,10 @@ namespace INTERP_KERNEL INTERPKERNEL_EXPORT QuadraticPolygon() { } INTERPKERNEL_EXPORT QuadraticPolygon(const QuadraticPolygon& other):ComposedEdge(other) { } INTERPKERNEL_EXPORT QuadraticPolygon(const char *fileName); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector& nodes, bool isClosed=true); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector& nodes, bool isClosed=true); + INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector& nodes); + INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector& nodes); + INTERPKERNEL_EXPORT static Edge *BuildLinearEdge(std::vector& nodes); + INTERPKERNEL_EXPORT static Edge *BuildArcCircleEdge(std::vector& nodes); INTERPKERNEL_EXPORT static void BuildDbgFile(const std::vector& nodes, const char *fileName); INTERPKERNEL_EXPORT ~QuadraticPolygon(); INTERPKERNEL_EXPORT void closeMe() const; diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 7f339ddea..05bd3c7a7 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -6272,9 +6272,9 @@ MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const { int mDim(getMeshDimension()),sDim(getSpaceDimension()); - if(sDim!=2) // Compute refined boundary box for quadratic elements only in 2D. + if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3)) // Compute refined boundary box for quadratic elements only in 2D. return getBoundingBoxForBBTreeFast(); - else + if((mDim==2 && sDim==2) || (mDim==1 && sDim==2)) { bool presenceOfQuadratic(false); for(std::set::const_iterator it=_types.begin();it!=_types.end();it++) @@ -6283,11 +6283,14 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) con if(cm.isQuadratic()) presenceOfQuadratic=true; } - if(presenceOfQuadratic) + if(!presenceOfQuadratic) + return getBoundingBoxForBBTreeFast(); + if(mDim==2 && sDim==2) return getBoundingBoxForBBTree2DQuadratic(arcDetEps); else - return getBoundingBoxForBBTreeFast(); + return getBoundingBoxForBBTree1DQuadratic(arcDetEps); } + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !"); } /*! @@ -6349,12 +6352,13 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const * \throw If \a this is not fully defined. * \throw If \a this is not a mesh with meshDimension equal to 2. * \throw If \a this is not a mesh with spaceDimension equal to 2. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic */ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arcDetEps) const { checkFullyDefined(); int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - if(spaceDim!=2) + if(spaceDim!=2 || spaceDim!=2) throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic : This method should be applied on mesh with mesh dimension equal to 2 and space dimension also equal to 2!"); MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); double *bbox(ret->getPointer()); @@ -6364,7 +6368,7 @@ DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arc { const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI])); int sz(connI[1]-connI[0]-1); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-12; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps; std::vector nodes(sz); INTERP_KERNEL::QuadraticPolygon *pol(0); for(int j=0;jfillBounds(b); delete pol; bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); } return ret.retn(); } +/*! + * This method aggregates the bbox of each 1D cell in \a this considering the whole shape. This method is particularly + * useful for 2D meshes having quadratic cells + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers + * the two extremities of the arc of circle). + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * \throw If \a this is not fully defined. + * \throw If \a this is not a mesh with meshDimension equal to 1. + * \throw If \a this is not a mesh with spaceDimension equal to 2. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic + */ +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const +{ + checkFullyDefined(); + int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); + if(spaceDim!=2 || spaceDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!"); + MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + const double *coords(_coords->getConstPointer()); + const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); + for(int i=0;i nodes(sz); + INTERP_KERNEL::Edge *edge(0); + for(int j=0;jgetBounds()); + bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef(); + } + return ret.retn(); +} + /// @cond INTERNAL namespace ParaMEDMEMImpl diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index eaacda684..232784dd1 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -167,6 +167,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTreeFast() const; MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const; MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); MEDCOUPLING_EXPORT bool isFullyQuadratic() const; MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index 8723563df..d3dce4efd 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -270,6 +270,7 @@ using namespace INTERP_KERNEL; %newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh; %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast; %newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic; +%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic; %newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; %newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; %newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; @@ -1540,6 +1541,7 @@ namespace ParaMEDMEM DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception); DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); -- 2.30.2