-// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2019 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
#include "SMESH_SMESH.hxx"
-#include "SMDS_MeshElement.hxx"
#include "SMESH_Controls.hxx"
-#include "SMESH_Mesh.hxx"
#include "SMESH_TypeDefs.hxx"
#include "SMESH_ComputeError.hxx"
#include <map>
#include <set>
+class SMDS_MeshElement;
class SMDS_MeshFace;
class SMDS_MeshNode;
-class gp_Ax1;
-class gp_Vec;
-class gp_Pnt;
+class SMESHDS_Group;
+class SMESHDS_Mesh;
+class SMESHDS_SubMesh;
+class SMESH_ElementSearcher;
+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_Pnt;
+class gp_Vec;
// ============================================================
/*!
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<int> myPolyhedQuantities;
+ std::vector<const SMDS_MeshNode*> myNodes; // not managed by ElemFeatures
+
+ 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<int>& quanities, bool isQuad=false )
+ { myType = SMDSAbs_Volume; myIsPoly = 1; myIsQuad = isQuad;
+ myPolyhedQuantities.swap( quanities ); return *this; }
+
+ SMESH_EXPORT ElemFeatures& Init( const std::vector<int>& 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<const SMDS_MeshNode*> & 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<int> & nodeIDs,
- const SMDSAbs_ElementType type,
- const bool isPoly,
- const int ID = -1);
+ SMDS_MeshElement* AddElement(const std::vector<int> & nodeIDs,
+ const ElemFeatures& features);
int Remove (const std::list< int >& theElemIDs, const bool isNodes);
// Remove a node or an element.
// Modify a compute state of sub-meshes which become empty
void Create0DElementsOnAllNodes( const TIDSortedElemSet& elements,
- TIDSortedElemSet& all0DElems);
- // Create 0D elements on all nodes of the given object except those
- // nodes on which a 0D element already exists. \a all0DElems returns
+ TIDSortedElemSet& all0DElems,
+ const bool duplicateElements);
+ // Create 0D elements on all nodes of the given. \a all0DElems returns
// all 0D elements found or created on nodes of \a elements
bool InverseDiag (const SMDS_MeshElement * theTria1,
* \param theElems - The triangles to be fused.
* \param theCriterion - Is used to choose a neighbour to fuse with.
* \param theMaxAngle - Is a max angle between element normals at which fusion
- * is still performed; theMaxAngle is mesured in radians.
+ * is still performed; theMaxAngle is measured in radians.
* \return bool - Success or not.
*/
bool TriToQuad (TIDSortedElemSet & theElems,
const double theMaxAngle);
/*!
* \brief Split quadrangles into triangles.
- * \param theElems - The faces to be splitted.
+ * \param theElems - The faces to be split.
* \param theCriterion - Is used to choose a diagonal for splitting.
* \return bool - Success or not.
*/
SMESH::Controls::NumericalFunctorPtr theCriterion);
/*!
* \brief Split quadrangles into triangles.
- * \param theElems - The faces to be splitted.
+ * \param theElems - The faces to be split.
* \param the13Diag - Is used to choose a diagonal for splitting.
* \return bool - Success or not.
*/
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.
+ * \param theElems - The faces to be split. If empty all faces are split.
*/
void QuadTo4Tri (TIDSortedElemSet & theElems);
/*!
* \brief For hexahedra that will be split into prisms, finds facets to
- * split into triangles
+ * split into triangles
* \param [in,out] theHexas - the hexahedra
* \param [in] theFacetNormal - facet normal
* \param [out] theFacets - the hexahedra and found facet IDs
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 };
typedef TNodeOfNodeListMap::iterator TNodeOfNodeListMapItr;
typedef std::vector<TNodeOfNodeListMapItr> TVecOfNnlmiMap;
typedef std::map<const SMDS_MeshElement*, TVecOfNnlmiMap, TElemSort > TElemOfVecOfNnlmiMap;
- typedef std::auto_ptr< std::list<int> > PGroupIDs;
+ typedef std::unique_ptr< std::list< int > > PGroupIDs;
- PGroupIDs RotationSweep (TIDSortedElemSet & theElements,
+ PGroupIDs RotationSweep (TIDSortedElemSet theElements[2],
const gp_Ax1& theAxis,
const double theAngle,
const int theNbSteps,
// 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
+ * ANGLE_LINEAR_VARIATION: to make linear variation of angles
*/
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,
+ EXTRUSION_FLAG_ANGLE_LINEAR_VARIATION = 0x40
};
-
+
/*!
- * 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
+ {
+ public:
+ //! Point on extrusion path
+ struct PathPoint
+ {
+ gp_Pnt myPnt;
+ gp_Dir myTgt;
+ double myAngle, myScale;
+ PathPoint(): myPnt(99., 99., 99.), myTgt(1.,0.,0.), myAngle(0), myScale(0) {}
+ };
+
+ ExtrusParam( const gp_Vec& theStep,
+ const int theNbSteps,
+ const std::list<double>& theScales,
+ const std::list<double>& theAngles,
+ 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
+ ExtrusParam( const std::vector< PathPoint >& thePoints,
+ const gp_Pnt* theBaseP,
+ const std::list<double>& theScales,
+ const bool theMakeGroups); // for extrusion along path
+
+ 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 IsScaleVariation() const { return myFlags & EXTRUSION_FLAG_SCALE_LINEAR_VARIATION; }
+ bool IsAngleVariation() const { return myFlags & EXTRUSION_FLAG_ANGLE_LINEAR_VARIATION; }
+ int NbSteps() const {
+ return mySteps.IsNull() ? myPathPoints.size() - 1: 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<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes)
+ {
+ return (this->*myMakeNodesFun)( mesh, srcNode, newNodes, makeMediumNodes );
+ }
+ private:
+
+ gp_Dir myDir; // direction of extrusion
Handle(TColStd_HSequenceOfReal) mySteps; // magnitudes for each step
- SMESH_SequenceOfNode myNodes; // nodes for using in sewing
+ std::vector<double> myScales;// scale factors
+ std::vector<double> myAngles;// angles
+ gp_XYZ myBaseP; // scaling/rotation 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
+ std::vector< PathPoint > myPathPoints; // points along a path
+ int (ExtrusParam::* myMakeNodesFun)(SMESHDS_Mesh*, // function of extrusion method
+ const SMDS_MeshNode*,
+ std::list<const SMDS_MeshNode*> &,
+ const bool);
+ int makeNodesByDir( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByDirAndSew( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByNormal2D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesByNormal1D( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & newNodes,
+ const bool makeMediumNodes);
+ int makeNodesAlongTrack( SMESHDS_Mesh* mesh,
+ const SMDS_MeshNode* srcNode,
+ std::list<const SMDS_MeshNode*> & 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
* @param theTolerance - uses for comparing locations of nodes if flag
* EXTRUSION_FLAG_SEW is set
*/
- PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
+ PGroupIDs ExtrusionSweep (TIDSortedElemSet theElems[2],
const gp_Vec& theStep,
const int theNbSteps,
TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
- const int theFlags = EXTRUSION_FLAG_BOUNDARY,
+ const int theFlags,
const double theTolerance = 1.e-6);
/*!
* EXTRUSION_FLAG_SEW is set
* @param theParams - special structure for manage of extrusion
*/
- PGroupIDs ExtrusionSweep (TIDSortedElemSet & theElems,
+ PGroupIDs ExtrusionSweep (TIDSortedElemSet theElems[2],
ExtrusParam& theParams,
- TTElemOfElemListMap& newElemsMap,
- const bool theMakeGroups,
- const int theFlags,
- const double theTolerance);
+ TTElemOfElemListMap& newElemsMap);
// Generate new elements by extrusion of theElements
EXTR_CANT_GET_TANGENT
};
- Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements,
- SMESH_subMesh* theTrackPattern,
+ Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet theElements[2],
+ SMESH_Mesh* theTrackMesh,
+ SMDS_ElemIteratorPtr theTrackIterator,
const SMDS_MeshNode* theNodeStart,
- const bool theHasAngles,
std::list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
+ const bool theAngleVariation,
+ std::list<double>& theScales,
+ const bool theScaleVariation,
+ const gp_Pnt* theRefPoint,
const bool theMakeGroups);
- Extrusion_Error ExtrusionAlongTrack (TIDSortedElemSet & theElements,
- SMESH_Mesh* theTrackPattern,
- const SMDS_MeshNode* theNodeStart,
- const bool theHasAngles,
- std::list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
- const bool theMakeGroups);
- // Generate new elements by extrusion of theElements along path given by theTrackPattern,
+ // Generate new elements by extrusion of theElements along path given by theTrackIterator,
// theHasAngles are the rotation angles, base point can be given by theRefPoint
PGroupIDs Transform (TIDSortedElemSet & theElements,
SMESH_Mesh* theTargetMesh=0);
// Move or copy theElements applying theTrsf to their nodes
+ PGroupIDs Offset( TIDSortedElemSet & theElements,
+ const double theValue,
+ SMESH_Mesh* theTgtMesh,
+ const bool theMakeGroups,
+ const bool theCopyElements,
+ const bool theFixSelfIntersection);
+ // Make an offset mesh from a source 2D mesh
+
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.
- void MergeNodes (TListOfListOfNodes & theNodeGroups);
+ void MergeNodes (TListOfListOfNodes & theNodeGroups,
+ const bool theAvoidMakingHoles = false);
// In each group, the cdr of nodes are substituted by the first one
// in all elements.
// of the side 2. If nb of links in the free border and
// between theSide2FirstNode and theSide2LastNode are different,
// additional nodes are inserted on a link provided that no
- // volume elements share the splitted link.
+ // volume elements share the split link.
// The side 2 is a free border if theSide2IsFreeBorder == true.
- // Sewing is peformed between the given first, second and last
+ // Sewing is performed between the given first, second and last
// nodes on the sides.
// theBorderFirstNode is merged with theSide2FirstNode.
// if (!theSide2IsFreeBorder) then theSide2SecondNode gives
void sweepElement(const SMDS_MeshElement* elem,
const std::vector<TNodeOfNodeListMapItr> & newNodesItVec,
std::list<const SMDS_MeshElement*>& newElems,
- const int nbSteps,
+ const size_t nbSteps,
SMESH_SequenceOfElemPtr& srcElements);
+ /*!
+ * \brief Computes new connectivity of an element after merging nodes
+ * \param [in] elems - the element
+ * \param [out] newElemDefs - definition(s) of result element(s)
+ * \param [inout] nodeNodeMap - nodes to merge
+ * \param [in] avoidMakingHoles - if true and and the element becomes invalid
+ * after merging (but not degenerated), removes nodes causing
+ * the invalidity from \a nodeNodeMap.
+ * \return bool - true if the element should be removed
+ */
+ bool applyMerge( const SMDS_MeshElement* elems,
+ std::vector< ElemFeatures >& newElemDefs,
+ TNodeNodeMap& nodeNodeMap,
+ const bool avoidMakingHoles );
/*!
* \brief Create 1D and 2D elements around swept elements
* \param mapNewNodes - source nodes and ones generated from them
const int nbSteps,
SMESH_SequenceOfElemPtr& srcElements);
- struct SMESH_MeshEditor_PathPoint
- {
- gp_Pnt myPnt;
- gp_Dir myTgt;
- double myAngle, myPrm;
-
- SMESH_MeshEditor_PathPoint(): myPnt(99., 99., 99.), myTgt(1.,0.,0.), myAngle(0), myPrm(0) {}
- void SetPnt (const gp_Pnt& aP3D) { myPnt =aP3D; }
- void SetTangent (const gp_Dir& aTgt) { myTgt =aTgt; }
- void SetAngle (const double& aBeta) { myAngle=aBeta; }
- void SetParameter(const double& aPrm) { myPrm =aPrm; }
- const gp_Pnt& Pnt ()const { return myPnt; }
- const gp_Dir& Tangent ()const { return myTgt; }
- double Angle ()const { return myAngle; }
- double Parameter ()const { return myPrm; }
- };
- Extrusion_Error MakeEdgePathPoints(std::list<double>& aPrms,
- const TopoDS_Edge& aTrackEdge,
- bool aFirstIsStart,
- std::list<SMESH_MeshEditor_PathPoint>& aLPP);
- Extrusion_Error MakeExtrElements(TIDSortedElemSet& theElements,
- std::list<SMESH_MeshEditor_PathPoint>& theFullList,
- const bool theHasAngles,
- std::list<double>& theAngles,
- const bool theLinearVariation,
- const bool theHasRefPoint,
- const gp_Pnt& theRefPoint,
- const bool theMakeGroups);
- void LinearAngleVariation(const int NbSteps,
- list<double>& 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<double>& theAngles);
+ static void linearScaleVariation(const int NbSteps,
+ std::list<double>& theScales);
+
+ 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 );
// Nodes and elements created during last operation
SMESH_SequenceOfElemPtr myLastCreatedNodes, myLastCreatedElems;
- // Description of error/warning occured during last operation
+ // Description of error/warning occurred during last operation
SMESH_ComputeErrorPtr myError;
};