#17828 [CEA 17805] Polyhedron Mesh volume calculation and volume orientation criterion

Implement ChangePolyhedronNodes()

+ Enable  Orientation of Faces in wireframe mode
This commit is contained in:
eap 2019-10-15 16:04:58 +03:00
parent d66fe4a500
commit e67f8c2cab
9 changed files with 114 additions and 26 deletions

View File

@ -749,7 +749,7 @@ SMESH_DeviceActor
{ {
bool aShowFaceOrientation = myIsFacesOriented; bool aShowFaceOrientation = myIsFacesOriented;
aShowFaceOrientation &= vtkLODActor::GetVisibility(); //GetVisibility(); -- avoid calling GetUnstructuredGrid() aShowFaceOrientation &= vtkLODActor::GetVisibility(); //GetVisibility(); -- avoid calling GetUnstructuredGrid()
aShowFaceOrientation &= myRepresentation == eSurface; aShowFaceOrientation &= ( myRepresentation != ePoint );
myFaceOrientation->SetVisibility(aShowFaceOrientation); myFaceOrientation->SetVisibility(aShowFaceOrientation);
} }

View File

@ -1044,6 +1044,31 @@ bool SMDS_Mesh::RemoveSubMesh(const SMDS_Mesh * aMesh)
return found; return found;
} }
//=======================================================================
//function : ChangePolyhedronNodes
//purpose :
//=======================================================================
bool SMDS_Mesh::ChangePolyhedronNodes(const SMDS_MeshElement * element,
const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities)
{
// keep current nodes of element
std::set<const SMDS_MeshNode*> oldNodes( element->begin_nodes(), element->end_nodes() );
// change nodes
bool Ok = false;
if ( const SMDS_MeshVolume* vol = DownCast<SMDS_MeshVolume>( element ))
Ok = vol->ChangeNodes( nodes, quantities );
if ( Ok )
{
setMyModified();
updateInverseElements( element, &nodes[0], nodes.size(), oldNodes );
}
return Ok;
}
//======================================================================= //=======================================================================
//function : ChangeElementNodes //function : ChangeElementNodes
//purpose : //purpose :
@ -1062,14 +1087,30 @@ bool SMDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * element,
Ok = cell->ChangeNodes(nodes, nbnodes); Ok = cell->ChangeNodes(nodes, nbnodes);
if ( Ok ) if ( Ok )
{
setMyModified(); 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<const SMDS_MeshNode*>& oldNodes )
{
if ( GetGrid()->HasLinks() ) // update InverseElements
{ {
std::set<const SMDS_MeshNode*>::iterator it; std::set<const SMDS_MeshNode*>::iterator it;
// AddInverseElement to new nodes // AddInverseElement to new nodes
for ( int i = 0; i < nbnodes; i++ ) { for ( int i = 0; i < nbnodes; i++ )
{
it = oldNodes.find( nodes[i] ); it = oldNodes.find( nodes[i] );
if ( it == oldNodes.end() ) if ( it == oldNodes.end() )
// new node // 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) const SMDS_Mesh0DElement* SMDS_Mesh::Find0DElement(const SMDS_MeshNode * node)

View File

@ -613,6 +613,9 @@ public:
bool ChangeElementNodes(const SMDS_MeshElement * elem, bool ChangeElementNodes(const SMDS_MeshElement * elem,
const SMDS_MeshNode * nodes[], const SMDS_MeshNode * nodes[],
const int nbnodes); const int nbnodes);
bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities);
//virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1); //virtual void Renumber (const bool isNodes, const int startID = 1, const int deltaID = 1);
// Renumber all nodes or elements. // Renumber all nodes or elements.
@ -708,7 +711,7 @@ public:
void Modified(); void Modified();
vtkMTimeType GetMTime() const; vtkMTimeType GetMTime() const;
protected: protected:
SMDS_Mesh(SMDS_Mesh * parent); SMDS_Mesh(SMDS_Mesh * parent);
void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren, void addChildrenWithNodes(std::set<const SMDS_MeshElement*>& setOfChildren,
@ -725,6 +728,11 @@ protected:
else if (z < zmin) zmin = z; else if (z < zmin) zmin = z;
} }
void updateInverseElements( const SMDS_MeshElement * element,
const SMDS_MeshNode* const* nodes,
const int nbnodes,
std::set<const SMDS_MeshNode*>& oldNodes );
void setNbShapes( size_t nbShapes ); void setNbShapes( size_t nbShapes );

View File

@ -75,6 +75,45 @@ void SMDS_MeshVolume::init( const std::vector<vtkIdType>& vtkNodeIds )
SMDS_MeshCell::init( aType, vtkNodeIds ); SMDS_MeshCell::init( aType, vtkNodeIds );
} }
bool SMDS_MeshVolume::ChangeNodes(const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& 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 const SMDS_MeshNode* SMDS_MeshVolume::GetNode(const int ind) const
{ {
if ( !IsPoly() ) if ( !IsPoly() )

View File

@ -59,8 +59,12 @@ class SMDS_EXPORT SMDS_MeshVolume : public SMDS_MeshCell
virtual SMDS_ElemIteratorPtr nodesIterator() const = 0; virtual SMDS_ElemIteratorPtr nodesIterator() const = 0;
virtual SMDS_NodeIteratorPtr nodeIterator() const = 0; virtual SMDS_NodeIteratorPtr nodeIterator() const = 0;
bool ChangeNodes(const std::vector<const SMDS_MeshNode*>& nodes,
const std::vector<int>& quantities) const;
// 1 <= face_ind <= NbFaces() // 1 <= face_ind <= NbFaces()
int NbFaceNodes (const int face_ind) const; int NbFaceNodes (const int face_ind) const;
// 1 <= face_ind <= NbFaces() // 1 <= face_ind <= NbFaces()
// 1 <= node_ind <= NbFaceNodes() // 1 <= node_ind <= NbFaceNodes()
const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const; const SMDS_MeshNode* GetFaceNode (const int face_ind, const int node_ind) const;

View File

@ -158,18 +158,15 @@ int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *p
i++; i++;
for (int k = 0; k < nbnodes; k++) 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++; i++;
} }
} }
std::set<vtkIdType>::iterator it = setOfNodes.begin();
for (; it != setOfNodes.end(); ++it)
{
this->Links->ResizeCellList(*it, 1);
this->Links->AddCellReference(cellid, *it);
}
return cellid; return cellid;
} }

View File

@ -246,17 +246,17 @@ bool SMESHDS_Mesh::ChangePolygonNodes
//======================================================================= //=======================================================================
//function : ChangePolyhedronNodes //function : ChangePolyhedronNodes
//purpose : //purpose :
//======================================================================= //=======================================================================
bool SMESHDS_Mesh::ChangePolyhedronNodes bool SMESHDS_Mesh
(const SMDS_MeshElement * elem, ::ChangePolyhedronNodes (const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes, const std::vector<const SMDS_MeshNode*>& nodes,
std::vector<int> quantities) const std::vector<int> & quantities)
{ {
ASSERT(nodes.size() > 3); ASSERT(nodes.size() > 3);
//if (!SMDS_Mesh::ChangePolyhedronNodes(elem, nodes, quantities)) if ( !SMDS_Mesh::ChangePolyhedronNodes( elem, nodes, quantities ))
return false; return false;
int i, len = nodes.size(); int i, len = nodes.size();
std::vector<int> nodes_ids (len); std::vector<int> nodes_ids (len);
@ -270,7 +270,7 @@ bool SMESHDS_Mesh::ChangePolyhedronNodes
//======================================================================= //=======================================================================
//function : Renumber //function : Renumber
//purpose : //purpose :
//======================================================================= //=======================================================================
void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID) void SMESHDS_Mesh::Renumber (const bool isNodes, const int startID, const int deltaID)

View File

@ -597,9 +597,9 @@ class SMESHDS_EXPORT SMESHDS_Mesh : public SMDS_Mesh
const int nbnodes); const int nbnodes);
bool ChangePolygonNodes(const SMDS_MeshElement * elem, bool ChangePolygonNodes(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes); std::vector<const SMDS_MeshNode*> nodes);
bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes, const std::vector<const SMDS_MeshNode*>& nodes,
std::vector<int> quantities); const std::vector<int>& quantities);
bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds); bool ModifyCellNodes(int smdsVolId, std::map<int,int> localClonedNodeIds);
void Renumber (const bool isNodes, const int startID=1, const int deltaID=1); void Renumber (const bool isNodes, const int startID=1, const int deltaID=1);

View File

@ -806,10 +806,10 @@ SMESH_MeshAlgos::MakeSlot( SMDS_ElemIteratorPtr theSegmentIt,
isOut( intPnt[1].myNode, planeNormal, intPnt[1].myIsOutPln, 1 ); isOut( intPnt[1].myNode, planeNormal, intPnt[1].myIsOutPln, 1 );
const Segment * closeSeg[2] = { 0, 0 }; const Segment * closeSeg[2] = { 0, 0 };
if ( intPnt[0].myIsOutPln[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 ); segment, n1, segmentsOfNode );
if ( intPnt[1].myIsOutPln[0] ) 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 ); segment, n1, segmentsOfNode );
int nbCut = bool( closeSeg[0] ) + bool( closeSeg[1] ); int nbCut = bool( closeSeg[0] ) + bool( closeSeg[1] );
if ( nbCut == 0 ) if ( nbCut == 0 )