From e67f8c2cabe52f01cc64b646330f3827ab06bb13 Mon Sep 17 00:00:00 2001 From: eap Date: Tue, 15 Oct 2019 16:04:58 +0300 Subject: [PATCH] #17828 [CEA 17805] Polyhedron Mesh volume calculation and volume orientation criterion Implement ChangePolyhedronNodes() + Enable Orientation of Faces in wireframe mode --- src/OBJECT/SMESH_DeviceActor.cxx | 2 +- src/SMDS/SMDS_Mesh.cxx | 46 ++++++++++++++++++++++++++++-- src/SMDS/SMDS_Mesh.hxx | 10 ++++++- src/SMDS/SMDS_MeshVolume.cxx | 39 +++++++++++++++++++++++++ src/SMDS/SMDS_MeshVolume.hxx | 4 +++ src/SMDS/SMDS_UnstructuredGrid.cxx | 13 ++++----- src/SMESHDS/SMESHDS_Mesh.cxx | 16 +++++------ src/SMESHDS/SMESHDS_Mesh.hxx | 6 ++-- src/SMESHUtils/SMESH_Slot.cxx | 4 +-- 9 files changed, 114 insertions(+), 26 deletions(-) diff --git a/src/OBJECT/SMESH_DeviceActor.cxx b/src/OBJECT/SMESH_DeviceActor.cxx index 7cbf49a44..e9c904f25 100644 --- a/src/OBJECT/SMESH_DeviceActor.cxx +++ b/src/OBJECT/SMESH_DeviceActor.cxx @@ -749,7 +749,7 @@ SMESH_DeviceActor { bool aShowFaceOrientation = myIsFacesOriented; aShowFaceOrientation &= vtkLODActor::GetVisibility(); //GetVisibility(); -- avoid calling GetUnstructuredGrid() - aShowFaceOrientation &= myRepresentation == eSurface; + aShowFaceOrientation &= ( myRepresentation != ePoint ); myFaceOrientation->SetVisibility(aShowFaceOrientation); } diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index d6a40165c..b4cac78c9 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1044,6 +1044,31 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh) return found; } +//======================================================================= +//function : ChangePolyhedronNodes +//purpose : +//======================================================================= + +bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element, + const std::vector& nodes, + const std::vector& quantities) +{ + // keep current nodes of element + std::set oldNodes( element->begin_nodes(), element->end_nodes() ); + + // change nodes + bool Ok = false; + if ( const SMDS_MeshVolume* vol = DownCast( element )) + Ok = vol->ChangeNodes( nodes, quantities ); + + if ( Ok ) + { + setMyModified(); + updateInverseElements( element, &nodes[0], nodes.size(), oldNodes ); + } + return Ok; +} + //======================================================================= //function : ChangeElementNodes //purpose : @@ -1062,14 +1087,30 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, Ok = cell->ChangeNodes(nodes, nbnodes); if ( Ok ) + { setMyModified(); + updateInverseElements( element, nodes, nbnodes, oldNodes ); + } + return Ok; +} - if ( Ok && GetGrid()->HasLinks() ) // update InverseElements +//======================================================================= +//function : updateInverseElements +//purpose : update InverseElements when element changes node +//======================================================================= + +void SMDS_Mesh::updateInverseElements( const SMDS_MeshElement * element, + const SMDS_MeshNode* const* nodes, + const int nbnodes, + std::set& oldNodes ) +{ + if ( GetGrid()->HasLinks() ) // update InverseElements { std::set::iterator it; // AddInverseElement to new nodes - for ( int i = 0; i < nbnodes; i++ ) { + for ( int i = 0; i < nbnodes; i++ ) + { it = oldNodes.find( nodes[i] ); if ( it == oldNodes.end() ) // new node @@ -1086,7 +1127,6 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element, } } - return Ok; } const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node) diff --git a/src/SMDS/SMDS_Mesh.hxx b/src/SMDS/SMDS_Mesh.hxx index 3da801f59..da7c9d5f8 100644 --- a/src/SMDS/SMDS_Mesh.hxx +++ b/src/SMDS/SMDS_Mesh.hxx @@ -613,6 +613,9 @@ public: bool ChangeElementNodes(const SMDS_MeshElement * elem, const SMDS_MeshNode * nodes[], const int nbnodes); + bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, + const std::vector& nodes, + const std::vector& quantities); //virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); // Renumber all nodes or elements. @@ -708,7 +711,7 @@ public: void Modified(); vtkMTimeType GetMTime() const; -protected: + protected: SMDS_Mesh(SMDS_Mesh * parent); void addChildrenWithNodes(std::set& setOfChildren, @@ -725,6 +728,11 @@ protected: else if (z < zmin) zmin = z; } + void updateInverseElements( const SMDS_MeshElement * element, + const SMDS_MeshNode* const* nodes, + const int nbnodes, + std::set& oldNodes ); + void setNbShapes( size_t nbShapes ); diff --git a/src/SMDS/SMDS_MeshVolume.cxx b/src/SMDS/SMDS_MeshVolume.cxx index ec1ecc0c0..ee9eb939f 100644 --- a/src/SMDS/SMDS_MeshVolume.cxx +++ b/src/SMDS/SMDS_MeshVolume.cxx @@ -75,6 +75,45 @@ void SMDS_MeshVolume::init( const std::vector& vtkNodeIds ) SMDS_MeshCell::init( aType, vtkNodeIds ); } +bool SMDS_MeshVolume::ChangeNodes(const std::vector& nodes, + const std::vector& quantities) const +{ + if ( !IsPoly() ) + return false; + + vtkIdType nFaces = 0; + vtkIdType* ptIds = 0; + getGrid()->GetFaceStream( GetVtkID(), nFaces, ptIds ); + + // stream size and nb faces should not change + + if ((int) quantities.size() != nFaces ) + { + return false; + } + int id = 0, nbPoints = 0; + for ( int i = 0; i < nFaces; i++ ) + { + int nodesInFace = ptIds[id]; + nbPoints += nodesInFace; + id += (nodesInFace + 1); + } + if ((int) nodes.size() != nbPoints ) + { + return false; + } + + // update ptIds + size_t iP = 0, iN = 0; + for ( size_t i = 0; i < quantities.size(); ++i ) + { + ptIds[ iP++ ] = quantities[ i ]; // nb face nodes + for ( int j = 0; j < quantities[ i ]; ++j ) + ptIds[ iP++ ] = nodes[ iN++ ]->GetVtkID(); + } + return true; +} + const SMDS_MeshNode* SMDS_MeshVolume::GetNode(const int ind) const { if ( !IsPoly() ) diff --git a/src/SMDS/SMDS_MeshVolume.hxx b/src/SMDS/SMDS_MeshVolume.hxx index 76fabc201..84a2a64cf 100644 --- a/src/SMDS/SMDS_MeshVolume.hxx +++ b/src/SMDS/SMDS_MeshVolume.hxx @@ -59,8 +59,12 @@ class SMDS_EXPORT SMDS_MeshVolume : public SMDS_MeshCell virtual SMDS_ElemIteratorPtr nodesIterator() const = 0; virtual SMDS_NodeIteratorPtr nodeIterator() const = 0; + bool ChangeNodes(const std::vector& nodes, + const std::vector& quantities) const; + // 1 <= face_ind <= NbFaces() int NbFaceNodes (const int face_ind) const; + // 1 <= face_ind <= NbFaces() // 1 <= node_ind <= NbFaceNodes() const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; diff --git a/src/SMDS/SMDS_UnstructuredGrid.cxx b/src/SMDS/SMDS_UnstructuredGrid.cxx index 72cb0fa00..8594efb8f 100644 --- a/src/SMDS/SMDS_UnstructuredGrid.cxx +++ b/src/SMDS/SMDS_UnstructuredGrid.cxx @@ -158,18 +158,15 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p i++; for (int k = 0; k < nbnodes; k++) { - setOfNodes.insert(pts[i]); + if ( setOfNodes.insert( pts[i] ).second ) + { + this->Links->ResizeCellList( pts[i], 1 ); + this->Links->AddCellReference( cellid, pts[i] ); + } i++; } } - std::set::iterator it = setOfNodes.begin(); - for (; it != setOfNodes.end(); ++it) - { - this->Links->ResizeCellList(*it, 1); - this->Links->AddCellReference(cellid, *it); - } - return cellid; } diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index 6c91b4e53..b0c90a803 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -246,17 +246,17 @@ bool SMESHDS_Mesh::ChangePolygonNodes //======================================================================= //function : ChangePolyhedronNodes -//purpose : +//purpose : //======================================================================= -bool SMESHDS_Mesh::ChangePolyhedronNodes -(const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities) +bool SMESHDS_Mesh +::ChangePolyhedronNodes (const SMDS_MeshElement * elem, + const std::vector& nodes, + const std::vector & quantities) { ASSERT(nodes.size() > 3); - //if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities)) - return false; + if ( !SMDS_Mesh::ChangePolyhedronNodes( elem, nodes, quantities )) + return false; int i, len = nodes.size(); std::vector nodes_ids (len); @@ -270,7 +270,7 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes //======================================================================= //function : Renumber -//purpose : +//purpose : //======================================================================= void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 5ca8a2df4..0a15cd448 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -597,9 +597,9 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh const int nbnodes); bool ChangePolygonNodes(const SMDS_MeshElement * elem, std::vector nodes); - bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, - std::vector nodes, - std::vector quantities); + bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, + const std::vector& nodes, + const std::vector& quantities); bool ModifyCellNodes(int smdsVolId, std::map localClonedNodeIds); void Renumber (const bool isNodes, const int startID=1, const int deltaID=1); diff --git a/src/SMESHUtils/SMESH_Slot.cxx b/src/SMESHUtils/SMESH_Slot.cxx index b17225edc..00521c0b5 100644 --- a/src/SMESHUtils/SMESH_Slot.cxx +++ b/src/SMESHUtils/SMESH_Slot.cxx @@ -806,10 +806,10 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt, isOut( intPnt[1].myNode, planeNormal, intPnt[1].myIsOutPln, 1 ); const Segment * closeSeg[2] = { 0, 0 }; if ( intPnt[0].myIsOutPln[0] ) - closeSeg[0] = findTooCloseSegment( intPnt[0], 0.5 * theWidth - tol, tol, + closeSeg[0] = findTooCloseSegment( intPnt[0], 0.5 * theWidth - 1e-3*tol, tol, segment, n1, segmentsOfNode ); if ( intPnt[1].myIsOutPln[0] ) - closeSeg[1] = findTooCloseSegment( intPnt[1], 0.5 * theWidth - tol, tol, + closeSeg[1] = findTooCloseSegment( intPnt[1], 0.5 * theWidth - 1e-3*tol, tol, segment, n1, segmentsOfNode ); int nbCut = bool( closeSeg[0] ) + bool( closeSeg[1] ); if ( nbCut == 0 )