From 0482db55d30f2eab70a425a7040f3ea7f976dcc1 Mon Sep 17 00:00:00 2001 From: jfa Date: Thu, 3 Mar 2005 13:03:05 +0000 Subject: [PATCH] Advanced feature for sewing - polygons creation instead of splitting. --- idl/SMESH_Mesh.idl | 3 +- src/SMESH/SMESH_MeshEditor.cxx | 148 ++++++++++++++++++-- src/SMESH/SMESH_MeshEditor.hxx | 10 +- src/SMESHDS/SMESHDS_Mesh.cxx | 19 +++ src/SMESHDS/SMESHDS_Mesh.hxx | 2 + src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx | 9 +- src/SMESHGUI/SMESHGUI_SewingDlg.cxx | 16 ++- src/SMESHGUI/SMESHGUI_SewingDlg.h | 1 + src/SMESH_I/SMESH_MeshEditor_i.cxx | 12 +- src/SMESH_I/SMESH_MeshEditor_i.hxx | 3 +- 10 files changed, 196 insertions(+), 27 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index fd0ad8e51..10debd7fd 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -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, diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 2067282e3..1fdb16b71 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -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 #include #include -#include #include - #include -#include "utilities.h" - using namespace std; using namespace SMESH::Controls; @@ -2365,7 +2363,7 @@ void SMESH_MeshEditor::Transform (set & 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( itN->next() ); if (nodeMap.find( node ) != nodeMap.end() ) @@ -2431,6 +2429,82 @@ void SMESH_MeshEditor::Transform (set & theElems, int nbNodes = elem->NbNodes(); int elemType = elem->GetType(); + if (elem->IsPoly()) { + // Polygon or Polyhedral Volume + switch ( elemType ) { + case SMDSAbs_Face: + { + vector poly_nodes (nbNodes); + int iNode = 0; + SMDS_ElemIteratorPtr itN = elem->nodesIterator(); + while (itN->more()) { + const SMDS_MeshNode* node = + static_cast(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 poly_nodes; + vector 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 & 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& theNodesToInsert) + list& 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 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( nodeIt->next() ); + poly_nodes[iNode++] = n; + if (n == nodes[il1]) { + isFLN = true; + } + } + + // add nodes to insert + list::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( 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 ]; diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index 677d9c033..638e6152b 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -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& theNodesToInsert); - // insert theNodesToInsert into theFace between theBetweenNode1 - // and theBetweenNode2 and split theElement. + std::list& 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[] ); diff --git a/src/SMESHDS/SMESHDS_Mesh.cxx b/src/SMESHDS/SMESHDS_Mesh.cxx index c0c758c74..b72a6b6b3 100644 --- a/src/SMESHDS/SMESHDS_Mesh.cxx +++ b/src/SMESHDS/SMESHDS_Mesh.cxx @@ -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 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 : diff --git a/src/SMESHDS/SMESHDS_Mesh.hxx b/src/SMESHDS/SMESHDS_Mesh.hxx index 115ab3756..5da0423b0 100644 --- a/src/SMESHDS/SMESHDS_Mesh.hxx +++ b/src/SMESHDS/SMESHDS_Mesh.hxx @@ -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 nodes); bool ChangePolyhedronNodes(const SMDS_MeshElement * elem, std::vector nodes, std::vector quantities); diff --git a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx index ffdfb5113..266320ba4 100644 --- a/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_AddMeshElementDlg.cxx @@ -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 diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx index 0cfe1f643..5a0e1375c 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx @@ -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(), diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.h b/src/SMESHGUI/SMESHGUI_SewingDlg.h index b5433bb2d..80740d79d 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.h +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.h @@ -111,6 +111,7 @@ private: QLineEdit* LineEdit5; QLineEdit* LineEdit6; QCheckBox* CheckBoxMerge; + QCheckBox* CheckBoxPoly; private slots: diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 0f46b537e..d1b0e9f1d 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -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) ); } //======================================================================= diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index 7325f53e4..73e26d2ac 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -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, -- 2.30.2