Advanced feature for sewing - polygons creation instead of splitting.

This commit is contained in:
jfa 2005-03-03 13:03:05 +00:00
parent 7a4b3f4798
commit 0482db55d3
10 changed files with 196 additions and 27 deletions

View File

@ -657,7 +657,8 @@ module SMESH
in long LastNodeID1,
in long FirstNodeID2,
in long SecondNodeID2,
in long LastNodeID2);
in long LastNodeID2,
in boolean CreatePoly);
Sew_Error SewConformFreeBorders (in long FirstNodeID1,
in long SecondNodeID1,

View File

@ -28,12 +28,14 @@
#include "SMESH_MeshEditor.hxx"
#include "SMESH_ControlsDef.hxx"
#include "SMDS_FaceOfNodes.hxx"
#include "SMDS_VolumeTool.hxx"
#include "SMDS_EdgePosition.hxx"
#include "SMDS_PolyhedralVolumeOfNodes.hxx"
#include "SMESHDS_Group.hxx"
#include "SMESHDS_Mesh.hxx"
#include "SMESH_subMesh.hxx"
#include "SMESH_ControlsDef.hxx"
@ -51,14 +53,10 @@
#include <gp.hxx>
#include <gp_Pln.hxx>
#include <BRep_Tool.hxx>
#include <SMDS_EdgePosition.hxx>
#include <Geom_Curve.hxx>
#include <map>
#include "utilities.h"
using namespace std;
using namespace SMESH::Controls;
@ -2365,7 +2363,7 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while ( itN->more() ) {
// check if a node has been already transormed
// check if a node has been already transformed
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>( itN->next() );
if (nodeMap.find( node ) != nodeMap.end() )
@ -2431,6 +2429,82 @@ void SMESH_MeshEditor::Transform (set<const SMDS_MeshElement*> & theElems,
int nbNodes = elem->NbNodes();
int elemType = elem->GetType();
if (elem->IsPoly()) {
// Polygon or Polyhedral Volume
switch ( elemType ) {
case SMDSAbs_Face:
{
vector<const SMDS_MeshNode*> poly_nodes (nbNodes);
int iNode = 0;
SMDS_ElemIteratorPtr itN = elem->nodesIterator();
while (itN->more()) {
const SMDS_MeshNode* node =
static_cast<const SMDS_MeshNode*>(itN->next());
TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
if (nodeMapIt == nodeMap.end())
break; // not all nodes transformed
if (needReverse) {
// reverse mirrored faces and volumes
poly_nodes[nbNodes - iNode - 1] = (*nodeMapIt).second;
} else {
poly_nodes[iNode] = (*nodeMapIt).second;
}
iNode++;
}
if ( iNode != nbNodes )
continue; // not all nodes transformed
if ( theCopy ) {
aMesh->AddPolygonalFace(poly_nodes);
} else {
aMesh->ChangePolygonNodes(elem, poly_nodes);
}
}
break;
case SMDSAbs_Volume:
{
// ATTENTION: Reversing is not yet done!!!
const SMDS_PolyhedralVolumeOfNodes* aPolyedre =
(const SMDS_PolyhedralVolumeOfNodes*) elem;
if (!aPolyedre) {
MESSAGE("Warning: bad volumic element");
continue;
}
vector<const SMDS_MeshNode*> poly_nodes;
vector<int> quantities;
bool allTransformed = true;
int nbFaces = aPolyedre->NbFaces();
for (int iface = 1; iface <= nbFaces && allTransformed; iface++) {
int nbFaceNodes = aPolyedre->NbFaceNodes(iface);
for (int inode = 1; inode <= nbFaceNodes && allTransformed; inode++) {
const SMDS_MeshNode* node = aPolyedre->GetFaceNode(iface, inode);
TNodeNodeMap::iterator nodeMapIt = nodeMap.find(node);
if (nodeMapIt == nodeMap.end()) {
allTransformed = false; // not all nodes transformed
} else {
poly_nodes.push_back((*nodeMapIt).second);
}
}
quantities.push_back(nbFaceNodes);
}
if ( !allTransformed )
continue; // not all nodes transformed
if ( theCopy ) {
aMesh->AddPolyhedralVolume(poly_nodes, quantities);
} else {
aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities);
}
}
break;
default:;
}
continue;
}
// Regular elements
int* i = index[ FORWARD ];
if ( needReverse && nbNodes > 2) // reverse mirrored faces and volumes
if ( elemType == SMDSAbs_Face )
@ -3136,7 +3210,8 @@ SMESH_MeshEditor::Sew_Error
const SMDS_MeshNode* theSideFirstNode,
const SMDS_MeshNode* theSideSecondNode,
const SMDS_MeshNode* theSideThirdNode,
bool theSideIsFreeBorder)
const bool theSideIsFreeBorder,
const bool toCreatePoly)
{
MESSAGE("::SewFreeBorder()");
Sew_Error aResult = SEW_OK;
@ -3482,12 +3557,12 @@ SMESH_MeshEditor::Sew_Error
list<const SMDS_MeshNode*> & nodeList = (*insertMapIt).second;
const SMDS_MeshNode* n12 = nodeList.front(); nodeList.pop_front();
const SMDS_MeshNode* n22 = nodeList.front(); nodeList.pop_front();
InsertNodesIntoLink( elem, n12, n22, nodeList );
InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePoly );
// 2. perform insertion into the link of adjacent faces
while (true) {
const SMDS_MeshElement* adjElem = findAdjacentFace( n12, n22, elem );
if ( adjElem )
InsertNodesIntoLink( adjElem, n12, n22, nodeList );
InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePoly );
else
break;
}
@ -3530,14 +3605,14 @@ SMESH_MeshEditor::Sew_Error
const SMDS_MeshNode* n1 = nodeList.front(); nodeList.pop_front();
const SMDS_MeshNode* n2 = nodeList.front(); nodeList.pop_front();
InsertNodesIntoLink( elem, n1, n2, nodeList );
InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePoly );
if ( !theSideIsFreeBorder ) {
// look for and insert nodes into the faces adjacent to elem
while (true) {
const SMDS_MeshElement* adjElem = findAdjacentFace( n1, n2, elem );
if ( adjElem )
InsertNodesIntoLink( adjElem, n1, n2, nodeList );
InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePoly );
else
break;
}
@ -3560,7 +3635,8 @@ SMESH_MeshEditor::Sew_Error
void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace,
const SMDS_MeshNode* theBetweenNode1,
const SMDS_MeshNode* theBetweenNode2,
list<const SMDS_MeshNode*>& theNodesToInsert)
list<const SMDS_MeshNode*>& theNodesToInsert,
const bool toCreatePoly)
{
if ( theFace->GetType() != SMDSAbs_Face ) return;
@ -3600,6 +3676,52 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace,
i4 = iNode;
}
if (toCreatePoly || theFace->IsPoly()) {
iNode = 0;
vector<const SMDS_MeshNode *> poly_nodes (nbFaceNodes + theNodesToInsert.size());
// add nodes of face up to first node of link
bool isFLN = false;
nodeIt = theFace->nodesIterator();
while ( nodeIt->more() && !isFLN ) {
const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
poly_nodes[iNode++] = n;
if (n == nodes[il1]) {
isFLN = true;
}
}
// add nodes to insert
list<const SMDS_MeshNode*>::iterator nIt = theNodesToInsert.begin();
for (; nIt != theNodesToInsert.end(); nIt++) {
poly_nodes[iNode++] = *nIt;
}
// add nodes of face starting from last node of link
while ( nodeIt->more() ) {
const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nodeIt->next() );
poly_nodes[iNode++] = n;
}
// edit or replace the face
SMESHDS_Mesh *aMesh = GetMeshDS();
if (theFace->IsPoly()) {
aMesh->ChangePolygonNodes(theFace, poly_nodes);
} else {
int aShapeId = FindShape( theFace );
SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes);
if ( aShapeId && newElem )
aMesh->SetMeshElementOnShape( newElem, aShapeId );
aMesh->RemoveElement(theFace);
}
return;
}
// put theNodesToInsert between theBetweenNode1 and theBetweenNode2
int nbLinkNodes = 2 + theNodesToInsert.size();
const SMDS_MeshNode* linkNodes[ nbLinkNodes ];

View File

@ -189,7 +189,8 @@ class SMESH_MeshEditor {
const SMDS_MeshNode* theSide2FirstNode,
const SMDS_MeshNode* theSide2SecondNode,
const SMDS_MeshNode* theSide2ThirdNode = 0,
bool theSide2IsFreeBorder = true);
const bool theSide2IsFreeBorder = true,
const bool toCreatePoly = false);
// Sew the free border to the side2 by replacing nodes in
// elements on the free border with nodes of the elements
// of the side 2. If nb of links in the free border and
@ -226,9 +227,10 @@ class SMESH_MeshEditor {
void InsertNodesIntoLink(const SMDS_MeshElement* theFace,
const SMDS_MeshNode* theBetweenNode1,
const SMDS_MeshNode* theBetweenNode2,
std::list<const SMDS_MeshNode*>& theNodesToInsert);
// insert theNodesToInsert into theFace between theBetweenNode1
// and theBetweenNode2 and split theElement.
std::list<const SMDS_MeshNode*>& theNodesToInsert,
const bool toCreatePoly = false);
// insert theNodesToInsert into theFace between theBetweenNode1 and theBetweenNode2.
// If toCreatePoly is true, replace theFace by polygon, else split theFace.
static int SortQuadNodes (const SMDS_Mesh * theMesh,
int theNodeIds[] );

View File

@ -181,6 +181,25 @@ bool SMESHDS_Mesh::ChangeElementNodes(const SMDS_MeshElement * elem,
return true;
}
//=======================================================================
//function : ChangePolygonNodes
//purpose :
//=======================================================================
bool SMESHDS_Mesh::ChangePolygonNodes
(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes)
{
ASSERT(nodes.size() > 3);
int nb = nodes.size();
const SMDS_MeshNode* nodes_array [nb];
for (int inode = 0; inode < nb; inode++) {
nodes_array[inode] = nodes[inode];
}
return ChangeElementNodes(elem, nodes_array, nb);
}
//=======================================================================
//function : ChangePolyhedronNodes
//purpose :

View File

@ -186,6 +186,8 @@ public:
bool ChangeElementNodes(const SMDS_MeshElement * elem,
const SMDS_MeshNode * nodes[],
const int nbnodes);
bool ChangePolygonNodes(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes);
bool ChangePolyhedronNodes(const SMDS_MeshElement * elem,
std::vector<const SMDS_MeshNode*> nodes,
std::vector<int> quantities);

View File

@ -593,10 +593,13 @@ void SMESHGUI_AddMeshElementDlg::SelectionIntoArgument()
myBusy = true;
myEditCurrentArgument->setText( aString );
myBusy = false;
if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes>=3 ) {
} else if (myIsPoly && myElementType == SMDSAbs_Volume && nbNodes>=4){
} else if (myNbNodes != nbNodes)
if (myIsPoly && myElementType == SMDSAbs_Face && nbNodes >= 3 ) {
myNbNodes = nbNodes;
} else if (myIsPoly && myElementType == SMDSAbs_Volume && nbNodes >= 4) {
myNbNodes = nbNodes;
} else if (myNbNodes != nbNodes) {
return;
}
// OK

View File

@ -245,6 +245,11 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( QWidget* parent, const char* name, SALOM
CheckBoxMerge->setText( tr( "MERGE_EQUAL_ELEMENTS" ) );
GroupArgumentsLayout->addWidget( CheckBoxMerge, 2, 0 );
// Control for the polygons creation instead of splitting
CheckBoxPoly = new QCheckBox( GroupArguments, "CheckBoxPoly" );
CheckBoxPoly->setText( tr( "CREATE_POLYGONS_INSTEAD_SPLITTING" ) );
GroupArgumentsLayout->addWidget( CheckBoxPoly, 3, 0 );
SMESHGUI_SewingDlgLayout->addWidget( GroupArguments, 1, 0 );
@ -320,6 +325,7 @@ void SMESHGUI_SewingDlg::Init()
myActor = 0;
myMesh = SMESH::SMESH_Mesh::_nil();
CheckBoxMerge->setChecked(false);
CheckBoxPoly->setChecked(false);
SelectionIntoArgument();
}
@ -355,6 +361,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId)
LineEdit6->setEnabled(true);
}
if (constructorId != 0 && CheckBoxPoly->isVisible())
CheckBoxPoly->hide();
switch(constructorId)
{
case 0 :
@ -362,6 +371,9 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId)
GroupArguments->setTitle( tr( "SEW_FREE_BORDERS" ) );
SubGroup1->setTitle( tr( "BORDER_1" ) );
SubGroup2->setTitle( tr( "BORDER_2" ) );
if (!CheckBoxPoly->isVisible())
CheckBoxPoly->show();
break;
}
@ -449,6 +461,7 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
if ( IsValid() )
{
bool toMerge = CheckBoxMerge->isChecked();
bool toCreatePoly = CheckBoxPoly->isChecked();
try
{
@ -464,7 +477,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply()
LineEdit3->text().toLong(),
LineEdit4->text().toLong(),
LineEdit5->text().toLong(),
LineEdit6->text().toLong());
LineEdit6->text().toLong(),
toCreatePoly);
else if (aConstructorId == 1)
anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(),
LineEdit2->text().toLong(),

View File

@ -111,6 +111,7 @@ private:
QLineEdit* LineEdit5;
QLineEdit* LineEdit6;
QCheckBox* CheckBoxMerge;
QCheckBox* CheckBoxPoly;
private slots:

View File

@ -916,7 +916,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
CORBA::Long LastNodeID1,
CORBA::Long FirstNodeID2,
CORBA::Long SecondNodeID2,
CORBA::Long LastNodeID2)
CORBA::Long LastNodeID2,
CORBA::Boolean CreatePoly)
{
SMESHDS_Mesh* aMesh = GetMeshDS();
@ -943,7 +944,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
aSide2FirstNode,
aSide2SecondNode,
aSide2ThirdNode,
true));
true,
CreatePoly) );
}
//=======================================================================
@ -982,7 +984,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
aSide2FirstNode,
aSide2SecondNode,
aSide2ThirdNode,
true ));
true,
false) );
}
//=======================================================================
@ -1021,7 +1024,8 @@ SMESH::SMESH_MeshEditor::Sew_Error
aSide2FirstNode,
aSide2SecondNode,
aSide2ThirdNode,
false));
false,
false) );
}
//=======================================================================

View File

@ -164,7 +164,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor
CORBA::Long LastNodeID1,
CORBA::Long FirstNodeID2,
CORBA::Long SecondNodeID2,
CORBA::Long LastNodeID2);
CORBA::Long LastNodeID2,
CORBA::Boolean CreatePoly);
SMESH::SMESH_MeshEditor::Sew_Error
SewConformFreeBorders(CORBA::Long FirstNodeID1,
CORBA::Long SecondNodeID1,