X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.hxx;h=5dd53807a813bcac52c0ba0270c3b0c8f1d4f79b;hp=28e0c98d4cc7e38aacd5cbe036ae6922bdab75a1;hb=5504d02a2237b17b8459bcd3b1fb2a89468598cd;hpb=bd8f1aee7c78f7d2eb82bd4fec5e08c9e3d280ce diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 28e0c98d4..5dd53807a 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 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 @@ -30,9 +30,7 @@ #include "SMESH_SMESH.hxx" -#include "SMDS_MeshElement.hxx" #include "SMESH_Controls.hxx" -#include "SMESH_Mesh.hxx" #include "SMESH_TypeDefs.hxx" #include "SMESH_ComputeError.hxx" @@ -45,59 +43,22 @@ #include #include +class SMDS_MeshElement; class SMDS_MeshFace; class SMDS_MeshNode; +class SMESHDS_Mesh; +class SMESHDS_SubMesh; +class SMESH_Group; +class SMESH_Mesh; +class SMESH_MesherHelper; +class SMESH_NodeSearcher; +class SMESH_subMesh; +class TopoDS_Edge; +class TopoDS_Shape; +class TopoDS_Vertex; class gp_Ax1; -class gp_Vec; class gp_Pnt; -class SMESH_MesherHelper; - - -//======================================================================= -/*! - * \brief Searcher for the node closest to point - */ -//======================================================================= -struct SMESH_NodeSearcher -{ - virtual const SMDS_MeshNode* FindClosestTo( const gp_Pnt& pnt ) = 0; - virtual void MoveNode( const SMDS_MeshNode* node, const gp_Pnt& toPnt ) = 0; -}; - -//======================================================================= -/*! - * \brief Searcher for elements - */ -//======================================================================= - -struct SMESH_ElementSearcher -{ - /*! - * \brief Find elements of given type where the given point is IN or ON. - * Returns nb of found elements and elements them-selves. - * - * 'ALL' type means elements of any type excluding nodes and 0D elements - */ - virtual int FindElementsByPoint(const gp_Pnt& point, - SMDSAbs_ElementType type, - std::vector< const SMDS_MeshElement* >& foundElems)=0; - /*! - * \brief Return an element most close to the given point - */ - virtual const SMDS_MeshElement* FindClosestTo( const gp_Pnt& point, - SMDSAbs_ElementType type) = 0; - /*! - * \brief Return elements possibly intersecting the line - */ - virtual void GetElementsNearLine( const gp_Ax1& line, - SMDSAbs_ElementType type, - std::vector< const SMDS_MeshElement* >& foundElems)=0; - /*! - * \brief Find out if the given point is out of closed 2D mesh. - */ - virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; - -}; +class gp_Vec; // ============================================================ /*! @@ -111,29 +72,57 @@ public: SMESH_MeshEditor( SMESH_Mesh* theMesh ); - SMESH_Mesh * GetMesh() { return myMesh; } - SMESHDS_Mesh * GetMeshDS() { return myMesh->GetMeshDS(); } + SMESH_Mesh * GetMesh() { return myMesh; } + SMESHDS_Mesh * GetMeshDS(); const SMESH_SequenceOfElemPtr& GetLastCreatedNodes() const { return myLastCreatedNodes; } const SMESH_SequenceOfElemPtr& GetLastCreatedElems() const { return myLastCreatedElems; } - void CrearLastCreated(); + void ClearLastCreated(); SMESH_ComputeErrorPtr & GetError() { return myError; } + // -------------------------------------------------------------------------------- + struct ElemFeatures //!< Features of element to create + { + SMDSAbs_ElementType myType; + bool myIsPoly, myIsQuad; + int myID; + double myBallDiameter; + std::vector myPolyhedQuantities; + + SMESH_EXPORT ElemFeatures( SMDSAbs_ElementType type=SMDSAbs_All, bool isPoly=false, bool isQuad=false ) + :myType( type ), myIsPoly(isPoly), myIsQuad(isQuad), myID(-1), myBallDiameter(0) {} + + SMESH_EXPORT ElemFeatures& Init( SMDSAbs_ElementType type, bool isPoly=false, bool isQuad=false ) + { myType = type; myIsPoly = isPoly; myIsQuad = isQuad; return *this; } + + SMESH_EXPORT ElemFeatures& Init( const SMDS_MeshElement* elem, bool basicOnly=true ); + + SMESH_EXPORT ElemFeatures& Init( double diameter ) + { myType = SMDSAbs_Ball; myBallDiameter = diameter; return *this; } + + SMESH_EXPORT ElemFeatures& Init( std::vector& quanities, bool isQuad=false ) + { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad; + myPolyhedQuantities.swap( quanities ); return *this; } + + SMESH_EXPORT ElemFeatures& Init( const std::vector& quanities, bool isQuad=false ) + { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad; + myPolyhedQuantities = quanities; return *this; } + + SMESH_EXPORT ElemFeatures& SetPoly(bool isPoly) { myIsPoly = isPoly; return *this; } + SMESH_EXPORT ElemFeatures& SetQuad(bool isQuad) { myIsQuad = isQuad; return *this; } + SMESH_EXPORT ElemFeatures& SetID (int ID) { myID = ID; return *this; } + }; + /*! * \brief Add element */ SMDS_MeshElement* AddElement(const std::vector & nodes, - const SMDSAbs_ElementType type, - const bool isPoly, - const int ID = -1, - const double ballDiameter=0.); + const ElemFeatures& features); /*! * \brief Add element */ - SMDS_MeshElement* AddElement(const std::vector & nodeIDs, - const SMDSAbs_ElementType type, - const bool isPoly, - const int ID = -1); + SMDS_MeshElement* AddElement(const std::vector & nodeIDs, + const ElemFeatures& features); int Remove (const std::list< int >& theElemIDs, const bool isNodes); // Remove a node or an element. @@ -172,6 +161,12 @@ public: // Reverse theFaces whose orientation to be same as that of theFace // oriented according to theDirection. Return nb of reoriented faces + int Reorient2DBy3D (TIDSortedElemSet & theFaces, + TIDSortedElemSet & theVolumes, + const bool theOutsideNormal); + // Reorient faces basing on orientation of adjacent volumes. + // Return nb of reoriented faces + /*! * \brief Fuse neighbour triangles into quadrangles. * \param theElems - The triangles to be fused. @@ -183,7 +178,6 @@ public: bool TriToQuad (TIDSortedElemSet & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion, const double theMaxAngle); - /*! * \brief Split quadrangles into triangles. * \param theElems - The faces to be splitted. @@ -192,7 +186,6 @@ public: */ bool QuadToTri (TIDSortedElemSet & theElems, SMESH::Controls::NumericalFunctorPtr theCriterion); - /*! * \brief Split quadrangles into triangles. * \param theElems - The faces to be splitted. @@ -201,6 +194,11 @@ public: */ bool QuadToTri (TIDSortedElemSet & theElems, const bool the13Diag); + /*! + * \brief Split each of given quadrangles into 4 triangles. + * \param theElems - The faces to be splitted. If empty all faces are split. + */ + void QuadTo4Tri (TIDSortedElemSet & theElems); /*! * \brief Find better diagonal for splitting. @@ -212,12 +210,43 @@ public: SMESH::Controls::NumericalFunctorPtr theCriterion); - enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, HEXA_TO_6 = 2, HEXA_TO_24 = 3 };//! TFacetOfElem; + + //!<2nd arg of SplitVolumes() + enum SplitVolumToTetraFlags { HEXA_TO_5 = 1, // split into tetrahedra + HEXA_TO_6, + HEXA_TO_24, + HEXA_TO_2_PRISMS, // split into prisms + HEXA_TO_4_PRISMS }; + /*! + * \brief Split volumic elements into tetrahedra or prisms. + * If facet ID < 0, element is split into tetrahedra, + * else a hexahedron is split into prisms so that the given facet is + * split into triangles + */ + void SplitVolumes (const TFacetOfElem & theElems, const int theMethodFlags); + /*! - * \brief Split volumic elements into tetrahedra. + * \brief For hexahedra that will be split into prisms, finds facets to + * split into triangles + * \param [in,out] theHexas - the hexahedra + * \param [in] theFacetNormal - facet normal + * \param [out] theFacets - the hexahedra and found facet IDs */ - void SplitVolumesIntoTetra (const TIDSortedElemSet & theElems, const int theMethodFlags); + void GetHexaFacetsToSplit( TIDSortedElemSet& theHexas, + const gp_Ax1& theFacetNormal, + TFacetOfElem & theFacets); + /*! + * \brief Split bi-quadratic elements into linear ones without creation of additional nodes + * - bi-quadratic triangle will be split into 3 linear quadrangles; + * - bi-quadratic quadrangle will be split into 4 linear quadrangles; + * - tri-quadratic hexahedron will be split into 8 linear hexahedra; + * Quadratic elements of lower dimension adjacent to the split bi-quadratic element + * will be split in order to keep the mesh conformal. + * \param elems - elements to split + */ + void SplitBiQuadraticIntoLinear(TIDSortedElemSet& theElems); enum SmoothMethod { LAPLACIAN = 0, CENTROIDAL }; @@ -236,9 +265,16 @@ public: // If the2D, smoothing is performed using UV parameters of nodes // on geometrical faces + typedef TIDTypeCompare TElemSort; + typedef std::map < const SMDS_MeshElement*, + std::list, TElemSort > TTElemOfElemListMap; + typedef std::map > TNodeOfNodeListMap; + typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr; + typedef std::vector TVecOfNnlmiMap; + typedef std::map TElemOfVecOfNnlmiMap; typedef std::auto_ptr< std::list > PGroupIDs; - PGroupIDs RotationSweep (TIDSortedElemSet & theElements, + PGroupIDs RotationSweep (TIDSortedElemSet theElements[2], const gp_Ax1& theAxis, const double theAngle, const int theNbSteps, @@ -249,34 +285,108 @@ public: // by theAngle by theNbSteps /*! - * Auxilary flag for advanced extrusion. + * Flags of extrusion. * BOUNDARY: create or not boundary for result of extrusion * SEW: try to use existing nodes or create new nodes in any case + * GROUPS: to create groups + * BY_AVG_NORMAL: step size is measured along average normal to elements, + * else step size is measured along average normal of any element + * USE_INPUT_ELEMS_ONLY: to use only input elements to compute extrusion direction + * for ExtrusionByNormal() + * SCALE_LINEAR_VARIATION: to make linear variation of scale factors */ enum ExtrusionFlags { EXTRUSION_FLAG_BOUNDARY = 0x01, - EXTRUSION_FLAG_SEW = 0x02 + EXTRUSION_FLAG_SEW = 0x02, + EXTRUSION_FLAG_GROUPS = 0x04, + EXTRUSION_FLAG_BY_AVG_NORMAL = 0x08, + EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY = 0x10, + EXTRUSION_FLAG_SCALE_LINEAR_VARIATION = 0x20 }; - + /*! - * special structure for control of extrusion functionality + * Generator of nodes for extrusion functionality */ - struct ExtrusParam { - gp_Dir myDir; // direction of extrusion + class SMESH_EXPORT ExtrusParam + { + gp_Dir myDir; // direction of extrusion Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step - SMESH_SequenceOfNode myNodes; // nodes for using in sewing + std::vector myScales, myMediumScales;// scale factors + gp_XYZ myBaseP; // scaling center + SMESH_SequenceOfNode myNodes; // nodes for using in sewing + int myFlags; // see ExtrusionFlags + double myTolerance; // tolerance for sewing nodes + const TIDSortedElemSet* myElemsToUse; // elements to use for extrusion by normal + + int (ExtrusParam::*myMakeNodesFun)(SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes); + + public: + ExtrusParam( const gp_Vec& theStep, + const int theNbSteps, + const std::list& theScales, + const gp_XYZ* theBaseP, + const int theFlags = 0, + const double theTolerance = 1e-6); + ExtrusParam( const gp_Dir& theDir, + Handle(TColStd_HSequenceOfReal) theSteps, + const int theFlags = 0, + const double theTolerance = 1e-6); + ExtrusParam( const double theStep, + const int theNbSteps, + const int theFlags, + const int theDim); // for extrusion by normal + + SMESH_SequenceOfNode& ChangeNodes() { return myNodes; } + int& Flags() { return myFlags; } + bool ToMakeBoundary() const { return myFlags & EXTRUSION_FLAG_BOUNDARY; } + bool ToMakeGroups() const { return myFlags & EXTRUSION_FLAG_GROUPS; } + bool ToUseInpElemsOnly() const { return myFlags & EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY; } + bool IsLinearVariation() const { return myFlags & EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; } + int NbSteps() const { return mySteps->Length(); } + + // stores elements to use for extrusion by normal, depending on + // state of EXTRUSION_FLAG_USE_INPUT_ELEMS_ONLY flag; + // define myBaseP for scaling + void SetElementsToUse( const TIDSortedElemSet& elems, const TIDSortedElemSet& nodes ); + + // creates nodes and returns number of nodes added in \a newNodes + int MakeNodes( SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes) + { + return (this->*myMakeNodesFun)( mesh, srcNode, newNodes, makeMediumNodes ); + } + private: + + int makeNodesByDir( SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes); + int makeNodesByDirAndSew( SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes); + int makeNodesByNormal2D( SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes); + int makeNodesByNormal1D( SMESHDS_Mesh* mesh, + const SMDS_MeshNode* srcNode, + std::list & newNodes, + const bool makeMediumNodes); + // step iteration + void beginStepIter( bool withMediumNodes ); + bool moreSteps(); + double nextStep(); + std::vector< double > myCurSteps; + bool myWithMediumNodes; + int myNextStep; }; - /*! - * Create new node in the mesh with given coordinates - * (auxiliary for advanced extrusion) - */ - const SMDS_MeshNode* CreateNode(const double x, - const double y, - const double z, - const double tolnode, - SMESH_SequenceOfNode& aNodes); - /*! * Generate new elements by extrusion of theElements * It is a method used in .idl file. All functionality @@ -289,13 +399,12 @@ public: * @param theTolerance - uses for comparing locations of nodes if flag * EXTRUSION_FLAG_SEW is set */ - PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems, - const gp_Vec& theStep, - const int theNbSteps, - TElemOfElemListMap& newElemsMap, - const bool theMakeGroups, - const int theFlags = EXTRUSION_FLAG_BOUNDARY, - const double theTolerance = 1.e-6); + PGroupIDs ExtrusionSweep (TIDSortedElemSet theElems[2], + const gp_Vec& theStep, + const int theNbSteps, + TTElemOfElemListMap& newElemsMap, + const int theFlags, + const double theTolerance = 1.e-6); /*! * Generate new elements by extrusion of theElements @@ -307,12 +416,9 @@ public: * EXTRUSION_FLAG_SEW is set * @param theParams - special structure for manage of extrusion */ - PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems, - ExtrusParam& theParams, - TElemOfElemListMap& newElemsMap, - const bool theMakeGroups, - const int theFlags, - const double theTolerance); + PGroupIDs ExtrusionSweep (TIDSortedElemSet theElems[2], + ExtrusParam& theParams, + TTElemOfElemListMap& newElemsMap); // Generate new elements by extrusion of theElements @@ -328,7 +434,7 @@ public: EXTR_CANT_GET_TANGENT }; - Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements, + Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet theElements[2], SMESH_subMesh* theTrackPattern, const SMDS_MeshNode* theNodeStart, const bool theHasAngles, @@ -337,7 +443,7 @@ public: const bool theHasRefPoint, const gp_Pnt& theRefPoint, const bool theMakeGroups); - Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements, + Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet theElements[2], SMESH_Mesh* theTrackPattern, const SMDS_MeshNode* theNodeStart, const bool theHasAngles, @@ -356,22 +462,12 @@ public: SMESH_Mesh* theTargetMesh=0); // Move or copy theElements applying theTrsf to their nodes - /*! - * \brief Return SMESH_NodeSearcher. The caller is responsible for deleteing it - */ - SMESH_NodeSearcher* GetNodeSearcher(); - - /*! - * \brief Return SMESH_ElementSearcher. The caller is responsible for deleting it - */ - SMESH_ElementSearcher* GetElementSearcher(); - SMESH_ElementSearcher* GetElementSearcher( SMDS_ElemIteratorPtr elemIt ); - typedef std::list< std::list< const SMDS_MeshNode* > > TListOfListOfNodes; void FindCoincidentNodes (TIDSortedNodeSet & theNodes, const double theTolerance, - TListOfListOfNodes & theGroupsOfNodes); + TListOfListOfNodes & theGroupsOfNodes, + bool theSeparateCornersAndMedium); // Return list of group of nodes close to each other within theTolerance. // Search among theNodes or in the whole mesh if theNodes is empty. @@ -393,16 +489,9 @@ public: // Remove all but one of elements built on the same nodes. // Return nb of successfully merged groups. - /*! - * \brief Return true if the point is IN or ON of the element - */ - static bool IsOut( const SMDS_MeshElement* element, const gp_Pnt& point, double tol ); - - static double GetDistance( const SMDS_MeshFace* face, const gp_Pnt& point ); - - int SimplifyFace (const std::vector faceNodes, - std::vector& poly_nodes, - std::vector& quantities) const; + int SimplifyFace (const std::vector& faceNodes, + std::vector& poly_nodes, + std::vector& quantities) const; // Split face, defined by , into several faces by repeating nodes. // Is used by MergeNodes() @@ -533,17 +622,6 @@ public: TIDSortedElemSet & linkedNodes, SMDSAbs_ElementType type = SMDSAbs_All ); - static const SMDS_MeshElement* FindFaceInSet(const SMDS_MeshNode* n1, - const SMDS_MeshNode* n2, - const TIDSortedElemSet& elemSet, - const TIDSortedElemSet& avoidSet, - int* i1=0, - int* i2=0); - // Return a face having linked nodes n1 and n2 and which is - // - not in avoidSet, - // - in elemSet provided that !elemSet.empty() - // i1 and i2 optionally returns indices of n1 and n2 - /*! * \brief Find corresponding nodes in two sets of faces * \param theSide1 - first face set @@ -576,6 +654,8 @@ public: // Return an index of the shape theElem is on // or zero if a shape not found + void DoubleElements( const TIDSortedElemSet& theElements ); + bool DoubleNodes( const std::list< int >& theListOfNodes, const std::list< int >& theListOfModifiedElems ); @@ -595,7 +675,8 @@ public: double OrientedAngle(const gp_Pnt& p0, const gp_Pnt& p1, const gp_Pnt& g1, const gp_Pnt& g2); bool DoubleNodesOnGroupBoundaries( const std::vector& theElems, - bool createJointElems); + bool createJointElems, + bool onAllBoundaries); bool CreateFlatElementsOnFacesGroups( const std::vector& theElems ); @@ -646,18 +727,14 @@ public: * \param nodeGens - nodes making corresponding myLastCreatedNodes * \param elemGens - elements making corresponding myLastCreatedElems * \param postfix - to append to names of new groups + * \param targetMesh - mesh to create groups in + * \param topPresent - is there "top" elements that are created by sweeping */ PGroupIDs generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, const SMESH_SequenceOfElemPtr& elemGens, const std::string& postfix, - SMESH_Mesh* targetMesh=0); - - - typedef std::map > TNodeOfNodeListMap; - typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr; - typedef std::vector TVecOfNnlmiMap; - typedef std::map TElemOfVecOfNnlmiMap; - + SMESH_Mesh* targetMesh=0, + const bool topPresent=true); /*! * \brief Create elements by sweeping an element * \param elem - element to sweep @@ -669,7 +746,7 @@ public: void sweepElement(const SMDS_MeshElement* elem, const std::vector & newNodesItVec, std::list& newElems, - const int nbSteps, + const size_t nbSteps, SMESH_SequenceOfElemPtr& srcElements); /*! @@ -682,7 +759,7 @@ public: * \param srcElements - to append elem for each generated element */ void makeWalls (TNodeOfNodeListMap & mapNewNodes, - TElemOfElemListMap & newElemsMap, + TTElemOfElemListMap & newElemsMap, TElemOfVecOfNnlmiMap & elemNewNodesMap, TIDSortedElemSet& elemSet, const int nbSteps, @@ -708,7 +785,7 @@ public: const TopoDS_Edge& aTrackEdge, bool aFirstIsStart, std::list& aLPP); - Extrusion_Error MakeExtrElements(TIDSortedElemSet& theElements, + Extrusion_Error MakeExtrElements(TIDSortedElemSet theElements[2], std::list& theFullList, const bool theHasAngles, std::list& theAngles, @@ -716,14 +793,17 @@ public: const bool theHasRefPoint, const gp_Pnt& theRefPoint, const bool theMakeGroups); - void LinearAngleVariation(const int NbSteps, - list& theAngles); - - bool doubleNodes( SMESHDS_Mesh* theMeshDS, - const TIDSortedElemSet& theElems, - const TIDSortedElemSet& theNodesNot, - std::map< const SMDS_MeshNode*, const SMDS_MeshNode* >& theNodeNodeMap, - const bool theIsDoubleElem ); + static void LinearAngleVariation(const int NbSteps, + std::list& theAngles); + + bool doubleNodes( SMESHDS_Mesh* theMeshDS, + const TIDSortedElemSet& theElems, + const TIDSortedElemSet& theNodesNot, + TNodeNodeMap& theNodeNodeMap, + const bool theIsDoubleElem ); + + void copyPosition( const SMDS_MeshNode* from, + const SMDS_MeshNode* to ); private: