X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Prism_3D.hxx;h=9e288f5aad0c518c17ccfd96bc524f9471c81de1;hp=5a3ea214528a7154bd241ecf748dd245168417f8;hb=refs%2Ftags%2FV9_7_0a1;hpb=9a54694a0ab1e5cbc558a35c4606ceea4f7af2ef diff --git a/src/StdMeshers/StdMeshers_Prism_3D.hxx b/src/StdMeshers/StdMeshers_Prism_3D.hxx index 5a3ea2145..9e288f5aa 100644 --- a/src/StdMeshers/StdMeshers_Prism_3D.hxx +++ b/src/StdMeshers/StdMeshers_Prism_3D.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions +// SMESH SMESH : implementation of SMESH idl descriptions // File : StdMeshers_Prism_3D.hxx // Module : SMESH // @@ -29,21 +29,20 @@ #include "SMESH_StdMeshers.hxx" -#include "SMDS_MeshNode.hxx" -#include "SMDS_TypeOfPosition.hxx" #include "SMESHDS_Mesh.hxx" -#include "SMESH_Algo.hxx" #include "SMESH_Block.hxx" #include "SMESH_Comment.hxx" #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_TypeDefs.hxx" #include "SMESH_subMesh.hxx" +#include "StdMeshers_ProjectionUtils.hxx" #include #include #include #include +#include #include #include #include @@ -102,13 +101,17 @@ namespace Prism_3D TopoDS_Face myBottom; TopoDS_Face myTop; std::list< TopoDS_Edge > myBottomEdges; - std::vector< TQuadList> myWallQuads; // wall sides can be vertically composite + std::vector< TQuadList> myWallQuads; // wall sides can be vertically composite std::vector< int > myRightQuadIndex; // index of right neighbour wall quad std::list< int > myNbEdgesInWires; bool myNotQuadOnTop; + mutable SMESH_subMesh* myAlgoSM; // sub-mesh with algo which computed myBottom + + size_t NbWires() const { return myNbEdgesInWires.size(); } void Clear(); + void SetUpsideDown(); }; } @@ -151,7 +154,7 @@ class STDMESHERS_EXPORT StdMeshers_PrismAsBlock: public SMESH_Block * \brief Return number of nodes on every vertical edge * \retval int - number of nodes including end nodes */ - int VerticalSize() const { return myParam2ColumnMaps[0].begin()->second.size(); } + size_t VerticalSize() const { return myParam2ColumnMaps[0].begin()->second.size(); } bool HasNotQuadElemOnTop() const { return myNotQuadOnTop; } @@ -180,6 +183,16 @@ class STDMESHERS_EXPORT StdMeshers_PrismAsBlock: public SMESH_Block return col_frw.first; } + /*! + * \brief Return pointer to column of nodes + * \param node - bottom node from which the returned column goes up + * \retval const TNodeColumn* - the found column + */ + bool HasNodeColumn(const SMDS_MeshNode* node) const + { + return myShapeIndex2ColumnMap.count( node->getshapeId() ); + } + /*! * \brief Return transformations to get coordinates of nodes of each internal layer * by nodes of the bottom. Layer is a set of nodes at a certain step @@ -233,12 +246,12 @@ class STDMESHERS_EXPORT StdMeshers_PrismAsBlock: public SMESH_Block { return myShapeIDMap.FindIndex( shape ); } /*! - * \brief Check curve orientation of a bootom edge + * \brief Check curve orientation of a bottom edge * \param meshDS - mesh DS * \param columnsMap - node columns map of side face - * \param bottomEdge - the bootom edge + * \param bottomEdge - the bottom edge * \param sideFaceID - side face in-block ID - * \retval bool - true if orienation coinside with in-block froward orienation + * \retval bool - true if orientation coincide with in-block forward orientation */ static bool IsForwardEdge(SMESHDS_Mesh* meshDS, const TParam2ColumnMap& columnsMap, @@ -265,35 +278,38 @@ private: TParam2ColumnMap* myParamToColumnMap; PSurface mySurface; TopoDS_Edge myBaseEdge; - map< int, PSurface > myShapeID2Surf; - // first and last normalized params and orientaion for each component or it-self - std::vector< std::pair< double, double> > myParams; + std::map< int, PSurface > myShapeID2Surf; + // first and last normalized params and orientation for each component or it-self + std::vector< std::pair< double, double> > myParams; // select my columns in myParamToColumnMap bool myIsForward; std::vector< TSideFace* > myComponents; - SMESH_MesherHelper * myHelper; + SMESH_MesherHelper myHelper; public: - TSideFace( SMESH_MesherHelper* helper, + TSideFace( SMESH_Mesh& mesh, const int faceID, const Prism_3D::TQuadList& quadList, const TopoDS_Edge& baseEdge, TParam2ColumnMap* columnsMap, const double first = 0.0, const double last = 1.0); - TSideFace( const std::vector< TSideFace* >& components, + TSideFace( SMESH_Mesh& mesh, + const std::vector< TSideFace* >& components, const std::vector< std::pair< double, double> > & params); TSideFace( const TSideFace& other ); ~TSideFace(); bool IsComplex() const { return ( NbComponents() > 0 || myParams[0].first != 0. || myParams[0].second != 1. ); } int FaceID() const { return myID; } + SMESH_Mesh* GetMesh() const { return myHelper.GetMesh(); } TParam2ColumnMap* GetColumns() const { return myParamToColumnMap; } - gp_XY GetNodeUV(const TopoDS_Face& F, const SMDS_MeshNode* n) const - { return myHelper->GetNodeUV( F, n ); } + gp_XY GetNodeUV(const TopoDS_Face& F, const SMDS_MeshNode* n, const SMDS_MeshNode* n2=0) const + { return ((SMESH_MesherHelper&) myHelper).SetSubShape(F), myHelper.GetNodeUV( F, n, n2 ); } const TopoDS_Edge & BaseEdge() const { return myBaseEdge; } int ColumnHeight() const { if ( NbComponents() ) return GetComponent(0)->GetColumns()->begin()->second.size(); else return GetColumns()->begin()->second.size(); } double GetColumns(const double U, TParam2ColumnIt & col1, TParam2ColumnIt& col2 ) const; + void GetNodesAtZ(const int Z, std::map& nodes ) const; int NbComponents() const { return myComponents.size(); } TSideFace* GetComponent(const int i) const { return myComponents.at( i ); } void SetComponent(const int i, TSideFace* c) @@ -357,14 +373,11 @@ private: // -------------------------------------------------------------------- class STDMESHERS_EXPORT TPCurveOnHorFaceAdaptor: public Adaptor2d_Curve2d { - const TSideFace* mySide; - int myZ; - TopoDS_Face myFace; + std::map< double, gp_XY > myUVmap; // normalized parameter to UV on a horizontal face public: TPCurveOnHorFaceAdaptor( const TSideFace* sideFace, const bool isTop, - const TopoDS_Face& horFace) - : mySide(sideFace), myFace(horFace), myZ(isTop ? mySide->ColumnHeight() - 1 : 0 ) {} + const TopoDS_Face& horFace); gp_Pnt2d Value(const Standard_Real U) const; Standard_Real FirstParameter() const { return 0; } Standard_Real LastParameter() const { return 1; } @@ -389,16 +402,85 @@ private: myError = SMESH_ComputeError::New(error,comment); return myError->IsOK(); } + /*! + * \brief Prints a script creating a normal grid on the prism side + */ + void faceGridToPythonDump(const SMESH_Block::TShapeID face, + const int nb=10); + }; // class StdMeshers_PrismAsBlock -// ============================================= +// =============================================== +/*! + * \brief Tool building internal nodes in a prism + */ +struct StdMeshers_Sweeper +{ + // input data + SMESH_MesherHelper* myHelper; + TopoDS_Face myBotFace; + TopoDS_Face myTopFace; + std::vector< TNodeColumn* > myBndColumns; // boundary nodes + // output data + std::vector< TNodeColumn* > myIntColumns; // internal nodes + + bool ComputeNodesByTrsf( const double tol, + const bool allowHighBndError ); + + bool CheckSameZ(); + + bool ComputeNodesOnStraightSameZ(); + + bool ComputeNodesOnStraight(); + +private: + + gp_XYZ bndPoint( int iP, int z ) const + { return SMESH_TNodeXYZ( (*myBndColumns[ iP ])[ z ]); } + + gp_XYZ intPoint( int iP, int z ) const + { return SMESH_TNodeXYZ( (*myIntColumns[ iP ])[ z ]); } + + bool projectIntPoints(const std::vector< gp_XYZ >& fromBndPoints, + const std::vector< gp_XYZ >& toBndPoints, + const std::vector< gp_XYZ >& fromIntPoints, + std::vector< gp_XYZ >& toIntPoints, + const double r, + StdMeshers_ProjectionUtils::TrsfFinder3D& trsf, + std::vector< gp_XYZ > * bndError); + + typedef std::vector< double > TZColumn; + static void fillZColumn( TZColumn& zColumn, + TNodeColumn& nodes ); + + void prepareTopBotDelaunay(); + bool findDelaunayTriangles(); + + std::vector< TZColumn > myZColumns; // Z distribution of boundary nodes + + StdMeshers_ProjectionUtils::DelaunayPtr myTopDelaunay; + StdMeshers_ProjectionUtils::DelaunayPtr myBotDelaunay; + TColStd_DataMapOfIntegerInteger myNodeID2ColID; + + // top and bottom Delaulay triangles including an internal column + struct TopBotTriangles + { + double myBotBC[3], myTopBC[3]; // barycentric coordinates of a node within a triangle + int myBotTriaNodes[3], myTopTriaNodes[3]; // indices of boundary columns + TopBotTriangles(); + void SetTopByBottom(); + }; + std::vector< TopBotTriangles> myTopBotTriangles; +}; + +// =============================================== /*! * \brief Algo building prisms on a prism shape */ class STDMESHERS_EXPORT StdMeshers_Prism_3D: public SMESH_3D_Algo { public: - StdMeshers_Prism_3D(int hypId, int studyId, SMESH_Gen* gen); + StdMeshers_Prism_3D(int hypId, SMESH_Gen* gen); virtual ~StdMeshers_Prism_3D(); virtual bool CheckHypothesis(SMESH_Mesh& aMesh, @@ -425,16 +507,24 @@ public: * \param nodeColumns - columns of nodes generated from nodes of a mesh face * \param helper - helper initialized by mesh and shape to add prisms to */ - static void AddPrisms( std::vector & nodeColumns, - SMESH_MesherHelper* helper); + static bool AddPrisms( std::vector & nodeColumns, + SMESH_MesherHelper* helper); -private: + static bool IsApplicable(const TopoDS_Shape & aShape, bool toCheckAll); + virtual bool IsApplicableToShape(const TopoDS_Shape & shape, bool toCheckAll) const + { + return IsApplicable( shape, toCheckAll ); + } + + private: /*! * \brief Analyse shape geometry and mesh. * If there are triangles on one of faces, it becomes 'bottom' */ - bool initPrism(Prism_3D::TPrismTopo& thePrism, const TopoDS_Shape& theSolid); + bool initPrism(Prism_3D::TPrismTopo& thePrism, + const TopoDS_Shape& theSolid, + const bool selectBottom = true); /*! * \brief Fill thePrism.myWallQuads and thePrism.myTopEdges @@ -447,25 +537,58 @@ private: */ bool compute(const Prism_3D::TPrismTopo& thePrism); + /*! + * \brief Compute the base face of a prism + */ + bool computeBase(const Prism_3D::TPrismTopo& thePrism); + /*! * \brief Compute 2D mesh on walls FACEs of a prism */ bool computeWalls(const Prism_3D::TPrismTopo& thePrism); + /*! + * \brief Create artificial wall quads for vertical projection between the outer and inner walls + */ + void makeQuadsForOutInProjection( const Prism_3D::TPrismTopo& thePrism, + std::multimap< int, int >& wgt2quad, + std::map< int, FaceQuadStruct >& iW2oiQuads); + /*! + * \brief Returns a source EDGE of propagation to a given EDGE + */ + TopoDS_Edge findPropagationSource( const TopoDS_Edge& E ); + /*! * \brief Find correspondence between bottom and top nodes. * If elements on the bottom and top faces are topologically different, * and projection is possible and allowed, perform the projection * \retval bool - is a success or not */ - bool assocOrProjBottom2Top(); + bool assocOrProjBottom2Top( const gp_Trsf & bottomToTopTrsf, + const Prism_3D::TPrismTopo& thePrism); /*! * \brief Remove quadrangles from the top face and * create triangles there by projection from the bottom * \retval bool - a success or not */ - bool projectBottomToTop(); + bool projectBottomToTop( const gp_Trsf & bottomToTopTrsf, + const Prism_3D::TPrismTopo& thePrism ); + + /*! + * \brief Compute tolerance to pass to StdMeshers_Sweeper + */ + double getSweepTolerance( const Prism_3D::TPrismTopo& thePrism ); + + /*! + * \brief Defines if it's safe to use the block approach + */ + bool isSimpleBottom( const Prism_3D::TPrismTopo& thePrism ); + + /*! + * \brief Defines if all "vertical" EDGEs are straight + */ + bool allVerticalEdgesStraight( const Prism_3D::TPrismTopo& thePrism ); /*! * \brief Project mesh faces from a source FACE of one prism to @@ -496,9 +619,11 @@ private: bool myProjectTriangles; bool mySetErrorToSM; + bool myUseBlock; StdMeshers_PrismAsBlock myBlock; SMESH_MesherHelper* myHelper; + SMESH_subMesh* myPrevBottomSM; std::vector myShapeXYZ; // point on each sub-shape of the block @@ -506,6 +631,8 @@ private: // (the column includes the bottom node) TNode2ColumnMap myBotToColumnMap; + TopTools_IndexedMapOfShape* myPropagChains; + }; // class StdMeshers_Prism_3D #endif