From b6545f068bd1a99d94f83dff470150742a1583ea Mon Sep 17 00:00:00 2001 From: jfa Date: Mon, 14 Mar 2005 13:34:30 +0000 Subject: [PATCH] Allow to create polyedres near sewed faces; improve nodes merging to save polyedres; implement polyedres by faces creation. --- idl/SMESH_Mesh.idl | 6 +- idl/SMESH_Pattern.idl | 9 +- src/OBJECT/SMESH_Object.cxx | 4 +- src/SMDS/SMDS_Mesh.cxx | 3 +- src/SMESH/SMESH_MeshEditor.cxx | 380 ++++++++++++++++++----- src/SMESH/SMESH_MeshEditor.hxx | 15 +- src/SMESH/SMESH_Pattern.cxx | 13 +- src/SMESH/SMESH_Pattern.hxx | 4 +- src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx | 13 +- src/SMESHGUI/SMESHGUI_MeshPatternDlg.h | 3 +- src/SMESHGUI/SMESHGUI_SewingDlg.cxx | 45 ++- src/SMESHGUI/SMESHGUI_SewingDlg.h | 5 +- src/SMESH_I/SMESH_MeshEditor_i.cxx | 35 ++- src/SMESH_I/SMESH_MeshEditor_i.hxx | 6 +- src/SMESH_I/SMESH_Pattern_i.cxx | 5 +- src/SMESH_I/SMESH_Pattern_i.hxx | 3 +- 16 files changed, 420 insertions(+), 129 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index 029687e6a..78ecc771e 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -658,7 +658,8 @@ module SMESH in long FirstNodeID2, in long SecondNodeID2, in long LastNodeID2, - in boolean CreatePoly); + in boolean CreatePolygons, + in boolean CreatePolyedrs); Sew_Error SewConformFreeBorders (in long FirstNodeID1, in long SecondNodeID1, @@ -671,7 +672,8 @@ module SMESH in long LastNodeIDOnFreeBorder, in long FirstNodeIDOnSide, in long LastNodeIDOnSide, - in boolean CreatePoly); + in boolean CreatePolygons, + in boolean CreatePolyedrs); Sew_Error SewSideElements (in long_array IDsOfSide1Elements, in long_array IDsOfSide2Elements, diff --git a/idl/SMESH_Pattern.idl b/idl/SMESH_Pattern.idl index bf65b38e6..d2324a0b2 100644 --- a/idl/SMESH_Pattern.idl +++ b/idl/SMESH_Pattern.idl @@ -104,11 +104,14 @@ module SMESH /*! * Create nodes and elements in using nodes * coordinates computed by either of Apply...() methods. - * If CreatePoly is TRUE, replace adjacent faces by polygons, - * inserting new nodes in common links. + * If CreatePolygons is TRUE, replace adjacent faces by polygons + * to keep mesh conformity. + * If CreatePolyedrs is TRUE, replace adjacent volumes by polyedrs + * to keep mesh conformity. */ boolean MakeMesh (in SMESH_Mesh theMesh, - in boolean CreatePoly); + in boolean CreatePolygons, + in boolean CreatePolyedrs); /*! * Return the loaded pattern in the string form to be saved in file diff --git a/src/OBJECT/SMESH_Object.cxx b/src/OBJECT/SMESH_Object.cxx index a275a10b4..0399e4893 100644 --- a/src/OBJECT/SMESH_Object.cxx +++ b/src/OBJECT/SMESH_Object.cxx @@ -833,8 +833,8 @@ void SMESH_MeshObj::Update( int theIsClear ) // nb nodes int nbNodes = anIndexes[i++]; // nodes - ASSERT( nbNodes < 9 ); - const SMDS_MeshNode* aNodes[ 8 ]; + //ASSERT( nbNodes < 9 ); + const SMDS_MeshNode* aNodes[ nbNodes ]; for ( int iNode = 0; iNode < nbNodes; iNode++ ) aNodes[ iNode ] = FindNode( myMesh, anIndexes[i++] ); // change diff --git a/src/SMDS/SMDS_Mesh.cxx b/src/SMDS/SMDS_Mesh.cxx index 1da783697..0058da878 100644 --- a/src/SMDS/SMDS_Mesh.cxx +++ b/src/SMDS/SMDS_Mesh.cxx @@ -1985,7 +1985,8 @@ void SMDS_Mesh::RemoveElement(const SMDS_MeshElement * elem, // get finite elements built on elem set * s1; if (!hasConstructionEdges() && elem->GetType() == SMDSAbs_Edge || - !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face) + !hasConstructionFaces() && elem->GetType() == SMDSAbs_Face || + elem->GetType() == SMDSAbs_Volume) { s1 = new set(); s1->insert(elem); diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index 007aac451..ba6a407eb 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -492,11 +492,38 @@ bool SMESH_MeshEditor::Reorient (const SMDS_MeshElement * theElem) } case SMDSAbs_Volume: { - SMDS_VolumeTool vTool; - if ( !vTool.Set( theElem )) - return false; - vTool.Inverse(); - return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() ); + if (theElem->IsPoly()) { + const SMDS_PolyhedralVolumeOfNodes* aPolyedre = + static_cast( theElem ); + if (!aPolyedre) { + MESSAGE("Warning: bad volumic element"); + return false; + } + + int nbFaces = aPolyedre->NbFaces(); + vector poly_nodes; + vector quantities (nbFaces); + + // reverse each face of the polyedre + for (int iface = 1; iface <= nbFaces; iface++) { + int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); + quantities[iface - 1] = nbFaceNodes; + + for (inode = nbFaceNodes; inode >= 1; inode--) { + const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); + poly_nodes.push_back(curNode); + } + } + + return GetMeshDS()->ChangePolyhedronNodes( theElem, poly_nodes, quantities ); + + } else { + SMDS_VolumeTool vTool; + if ( !vTool.Set( theElem )) + return false; + vTool.Inverse(); + return GetMeshDS()->ChangeElementNodes( theElem, vTool.GetNodes(), vTool.NbNodes() ); + } } default:; } @@ -2620,6 +2647,88 @@ void SMESH_MeshEditor::FindCoincidentNodes (set & theNodes } } +//======================================================================= +//function : SimplifyFace +//purpose : +//======================================================================= +int SMESH_MeshEditor::SimplifyFace (const vector faceNodes, + vector& poly_nodes, + vector& quantities) const +{ + int nbNodes = faceNodes.size(); + + if (nbNodes < 3) + return 0; + + set nodeSet; + + // get simple seq of nodes + const SMDS_MeshNode* simpleNodes[ nbNodes ]; + int iSimple = 0, nbUnique = 0; + + simpleNodes[iSimple++] = faceNodes[0]; + nbUnique++; + for (int iCur = 1; iCur < nbNodes; iCur++) { + if (faceNodes[iCur] != simpleNodes[iSimple - 1]) { + simpleNodes[iSimple++] = faceNodes[iCur]; + if (nodeSet.insert( faceNodes[iCur] ).second) + nbUnique++; + } + } + int nbSimple = iSimple; + if (simpleNodes[nbSimple - 1] == simpleNodes[0]) { + nbSimple--; + iSimple--; + } + + if (nbUnique < 3) + return 0; + + // separate loops + int nbNew = 0; + bool foundLoop = (nbSimple > nbUnique); + while (foundLoop) { + foundLoop = false; + set loopSet; + for (iSimple = 0; iSimple < nbSimple && !foundLoop; iSimple++) { + const SMDS_MeshNode* n = simpleNodes[iSimple]; + if (!loopSet.insert( n ).second) { + foundLoop = true; + + // separate loop + int iC = 0, curLast = iSimple; + for (; iC < curLast; iC++) { + if (simpleNodes[iC] == n) break; + } + int loopLen = curLast - iC; + if (loopLen > 2) { + // create sub-element + nbNew++; + quantities.push_back(loopLen); + for (; iC < curLast; iC++) { + poly_nodes.push_back(simpleNodes[iC]); + } + } + // shift the rest nodes (place from the first loop position) + for (iC = curLast + 1; iC < nbSimple; iC++) { + simpleNodes[iC - loopLen] = simpleNodes[iC]; + } + nbSimple -= loopLen; + iSimple -= loopLen; + } + } // for (iSimple = 0; iSimple < nbSimple; iSimple++) + } // while (foundLoop) + + if (iSimple > 2) { + nbNew++; + quantities.push_back(iSimple); + for (int i = 0; i < iSimple; i++) + poly_nodes.push_back(simpleNodes[i]); + } + + return nbNew; +} + //======================================================================= //function : MergeNodes //purpose : In each group, the cdr of nodes are substituted by the first one @@ -2699,83 +2808,79 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) if (elem->GetType() == SMDSAbs_Face) { // Polygon - if (nbUniqueNodes < 3) { - isOk = false; - } else { - // get simple seq of nodes - const SMDS_MeshNode* simpleNodes[ nbNodes ]; - int iSimple = 0; - - simpleNodes[iSimple++] = curNodes[0]; - for (iCur = 1; iCur < nbNodes; iCur++) { - if (curNodes[iCur] != simpleNodes[iSimple - 1]) { - simpleNodes[iSimple++] = curNodes[iCur]; - } - } - int nbSimple = iSimple; - if (simpleNodes[nbSimple - 1] == simpleNodes[0]) { - nbSimple--; - } + vector face_nodes (nbNodes); + int inode = 0; + for (; inode < nbNodes; inode++) { + face_nodes[inode] = curNodes[inode]; + } - // separate cycles - bool foundCycle = (nbSimple > nbUniqueNodes); - while (foundCycle) { - foundCycle = false; - set cycleSet; - for (iSimple = 0; iSimple < nbSimple && !foundCycle; iSimple++) { - const SMDS_MeshNode* n = simpleNodes[iSimple]; - if (!cycleSet.insert( n ).second) { - foundCycle = true; - - // separate cycle - int iC = 0, curLast = iSimple; - for (; iC < curLast; iC++) { - if (simpleNodes[iC] == n) break; - } - int cycleLen = curLast - iC; - if (cycleLen > 2) { - // create sub-element - vector poly_nodes (cycleLen); - for (int ii = 0; iC < curLast; iC++) { - poly_nodes[ii++] = simpleNodes[iC]; - } - SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); - if (aShapeId) - aMesh->SetMeshElementOnShape(newElem, aShapeId); - } - // put the rest nodes from the first cycle position - for (iC = curLast + 1; iC < nbSimple; iC++) { - simpleNodes[iC - cycleLen] = simpleNodes[iC]; - } - nbSimple -= cycleLen; - } - } // for (iSimple = 0; iSimple < nbSimple; iSimple++) - } // while (foundCycle) + vector polygons_nodes; + vector quantities; + int nbNew = SimplifyFace(face_nodes, polygons_nodes, quantities); - if (iSimple > 2) { - aMesh->ChangeElementNodes(elem, simpleNodes, nbSimple); - } else { - isOk = false; + if (nbNew > 0) { + inode = 0; + for (int iface = 0; iface < nbNew - 1; iface++) { + int nbNodes = quantities[iface]; + vector poly_nodes (nbNodes); + for (int ii = 0; ii < nbNodes; ii++, inode++) { + poly_nodes[ii] = polygons_nodes[inode]; + } + SMDS_MeshElement* newElem = aMesh->AddPolygonalFace(poly_nodes); + if (aShapeId) + aMesh->SetMeshElementOnShape(newElem, aShapeId); } + aMesh->ChangeElementNodes(elem, &polygons_nodes[inode], quantities[nbNew - 1]); + } else { + rmElemIds.push_back(elem->GetID()); } } else if (elem->GetType() == SMDSAbs_Volume) { // Polyhedral volume if (nbUniqueNodes < 4) { - isOk = false; + rmElemIds.push_back(elem->GetID()); } else { // each face has to be analized in order to check volume validity - //aMesh->ChangeElementNodes(elem, uniqueNodes, nbUniqueNodes); - isOk = false; - } + const SMDS_PolyhedralVolumeOfNodes* aPolyedre = + static_cast( elem ); + if (aPolyedre) { + int nbFaces = aPolyedre->NbFaces(); + + vector poly_nodes; + vector quantities; + + for (int iface = 1; iface <= nbFaces; iface++) { + int nbFaceNodes = aPolyedre->NbFaceNodes(iface); + vector faceNodes (nbFaceNodes); + + for (int inode = 1; inode <= nbFaceNodes; inode++) { + const SMDS_MeshNode * faceNode = aPolyedre->GetFaceNode(iface, inode); + TNodeNodeMap::iterator nnIt = nodeNodeMap.find(faceNode); + if (nnIt != nodeNodeMap.end()) { // faceNode sticks + faceNode = (*nnIt).second; + } + faceNodes[inode - 1] = faceNode; + } + + SimplifyFace(faceNodes, poly_nodes, quantities); + } + if (quantities.size() > 3) { + // to be done: remove coincident faces + } + + if (quantities.size() > 3) + aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); + else + rmElemIds.push_back(elem->GetID()); + + } else { + rmElemIds.push_back(elem->GetID()); + } + } } else { - isOk = false; } - if (!isOk) - rmElemIds.push_back(elem->GetID()); - continue; } @@ -3021,10 +3126,41 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } // if ( nbNodes != nbUniqueNodes ) // some nodes stick - if ( isOk ) - aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes ); - else + if ( isOk ) { + if (elem->IsPoly() && elem->GetType() == SMDSAbs_Volume) { + // Change nodes of polyedre + const SMDS_PolyhedralVolumeOfNodes* aPolyedre = + static_cast( elem ); + if (aPolyedre) { + int nbFaces = aPolyedre->NbFaces(); + + vector poly_nodes; + vector quantities (nbFaces); + + for (int iface = 1; iface <= nbFaces; iface++) { + int inode, nbFaceNodes = aPolyedre->NbFaceNodes(iface); + quantities[iface - 1] = nbFaceNodes; + + for (inode = 1; inode <= nbFaceNodes; inode++) { + const SMDS_MeshNode* curNode = aPolyedre->GetFaceNode(iface, inode); + + TNodeNodeMap::iterator nnIt = nodeNodeMap.find( curNode ); + if (nnIt != nodeNodeMap.end()) { // curNode sticks + curNode = (*nnIt).second; + } + poly_nodes.push_back(curNode); + } + } + aMesh->ChangePolyhedronNodes( elem, poly_nodes, quantities ); + } + } else { + // Change regular element or polygon + aMesh->ChangeElementNodes( elem, uniqueNodes, nbUniqueNodes ); + } + } else { + // Remove invalid regular element or invalid polygon rmElemIds.push_back( elem->GetID() ); + } } // loop on elements @@ -3300,7 +3436,8 @@ SMESH_MeshEditor::Sew_Error const SMDS_MeshNode* theSideSecondNode, const SMDS_MeshNode* theSideThirdNode, const bool theSideIsFreeBorder, - const bool toCreatePoly) + const bool toCreatePolygons, + const bool toCreatePolyedrs) { MESSAGE("::SewFreeBorder()"); Sew_Error aResult = SEW_OK; @@ -3523,7 +3660,7 @@ SMESH_MeshEditor::Sew_Error } while ( sideNode != theSideSecondNode ); - if ( hasVolumes && sideNodes.size () != bordNodes.size() ) { + if ( hasVolumes && sideNodes.size () != bordNodes.size() && !toCreatePolyedrs) { MESSAGE("VOLUME SPLITTING IS FORBIDDEN"); return SEW_VOLUMES_TO_SPLIT; // volume splitting is forbidden } @@ -3647,15 +3784,19 @@ 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, toCreatePoly ); + InsertNodesIntoLink( elem, n12, n22, nodeList, toCreatePolygons ); // 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, toCreatePoly ); + InsertNodesIntoLink( adjElem, n12, n22, nodeList, toCreatePolygons ); else break; } + if (toCreatePolyedrs) { + // perform insertion into the links of adjacent volumes + UpdateVolumes(n12, n22, nodeList); + } // 3. find an element appeared on n1 and n2 after the insertion insertMap.erase( elem ); elem = findAdjacentFace( n1, n2, 0 ); @@ -3695,18 +3836,22 @@ 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, toCreatePoly ); + InsertNodesIntoLink( elem, n1, n2, nodeList, toCreatePolygons ); 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, toCreatePoly ); + InsertNodesIntoLink( adjElem, n1, n2, nodeList, toCreatePolygons ); else break; } } + if (toCreatePolyedrs) { + // perform insertion into the links of adjacent volumes + UpdateVolumes(n1, n2, nodeList); + } } } // end: insert new nodes @@ -3890,6 +4035,87 @@ void SMESH_MeshEditor::InsertNodesIntoLink(const SMDS_MeshElement* theFace, aMesh->ChangeElementNodes( theFace, newNodes, iSplit == iBestQuad ? 4 : 3 ); } +//======================================================================= +//function : UpdateVolumes +//purpose : +//======================================================================= +void SMESH_MeshEditor::UpdateVolumes (const SMDS_MeshNode* theBetweenNode1, + const SMDS_MeshNode* theBetweenNode2, + list& theNodesToInsert) +{ + SMDS_ElemIteratorPtr invElemIt = theBetweenNode1->GetInverseElementIterator(); + while (invElemIt->more()) { // loop on inverse elements of theBetweenNode1 + const SMDS_MeshElement* elem = invElemIt->next(); + if (elem->GetType() != SMDSAbs_Volume) + continue; + + // check, if current volume has link theBetweenNode1 - theBetweenNode2 + SMDS_VolumeTool aVolume (elem); + if (!aVolume.IsLinked(theBetweenNode1, theBetweenNode2)) + continue; + + // insert new nodes in all faces of the volume, sharing link theBetweenNode1 - theBetweenNode2 + int iface, nbFaces = aVolume.NbFaces(); + vector poly_nodes; + vector quantities (nbFaces); + + for (iface = 0; iface < nbFaces; iface++) { + int nbFaceNodes = aVolume.NbFaceNodes(iface), nbInserted = 0; + // faceNodes will contain (nbFaceNodes + 1) nodes, last = first + const SMDS_MeshNode** faceNodes = aVolume.GetFaceNodes(iface); + + for (int inode = 0; inode < nbFaceNodes; inode++) { + poly_nodes.push_back(faceNodes[inode]); + + if (nbInserted == 0) { + if (faceNodes[inode] == theBetweenNode1) { + if (faceNodes[inode + 1] == theBetweenNode2) { + nbInserted = theNodesToInsert.size(); + + // add nodes to insert + list::iterator nIt = theNodesToInsert.begin(); + for (; nIt != theNodesToInsert.end(); nIt++) { + poly_nodes.push_back(*nIt); + } + } + } else if (faceNodes[inode] == theBetweenNode2) { + if (faceNodes[inode + 1] == theBetweenNode1) { + nbInserted = theNodesToInsert.size(); + + // add nodes to insert in reversed order + list::iterator nIt = theNodesToInsert.end(); + nIt--; + for (; nIt != theNodesToInsert.begin(); nIt--) { + poly_nodes.push_back(*nIt); + } + poly_nodes.push_back(*nIt); + } + } else { + } + } + } + quantities[iface] = nbFaceNodes + nbInserted; + } + + // Replace or update the volume + SMESHDS_Mesh *aMesh = GetMeshDS(); + + if (elem->IsPoly()) { + aMesh->ChangePolyhedronNodes(elem, poly_nodes, quantities); + + } else { + int aShapeId = FindShape( elem ); + + SMDS_MeshElement* newElem = + aMesh->AddPolyhedralVolume(poly_nodes, quantities); + if (aShapeId && newElem) + aMesh->SetMeshElementOnShape(newElem, aShapeId); + + aMesh->RemoveElement(elem); + } + } +} + //======================================================================= //function : SewSideElements //purpose : diff --git a/src/SMESH/SMESH_MeshEditor.hxx b/src/SMESH/SMESH_MeshEditor.hxx index beafd34e1..e9252e6a8 100644 --- a/src/SMESH/SMESH_MeshEditor.hxx +++ b/src/SMESH/SMESH_MeshEditor.hxx @@ -154,6 +154,12 @@ class SMESH_MeshEditor { // Return list of group of nodes close to each other within theTolerance. // Search among theNodes or in the whole mesh if theNodes is empty. + int SimplifyFace (const vector faceNodes, + vector& poly_nodes, + vector& quantities) const; + // Split face, defined by , into several faces by repeating nodes. + // Is used by MergeNodes() + void MergeNodes (TListOfListOfNodes & theNodeGroups); // In each group, the cdr of nodes are substituted by the first one // in all elements. @@ -190,7 +196,8 @@ class SMESH_MeshEditor { const SMDS_MeshNode* theSide2SecondNode, const SMDS_MeshNode* theSide2ThirdNode = 0, const bool theSide2IsFreeBorder = true, - const bool toCreatePoly = false); + const bool toCreatePolygons = false, + const bool toCreatePolyedrs = 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 @@ -232,6 +239,12 @@ class SMESH_MeshEditor { // insert theNodesToInsert into theFace between theBetweenNode1 and theBetweenNode2. // If toCreatePoly is true, replace theFace by polygon, else split theFace. + void UpdateVolumes (const SMDS_MeshNode* theBetweenNode1, + const SMDS_MeshNode* theBetweenNode2, + std::list& theNodesToInsert); + // insert theNodesToInsert into all volumes, containing link + // theBetweenNode1 - theBetweenNode2, between theBetweenNode1 and theBetweenNode2. + // static int SortQuadNodes (const SMDS_Mesh * theMesh, // int theNodeIds[] ); // // Set 4 nodes of a quadrangle face in a good order. diff --git a/src/SMESH/SMESH_Pattern.cxx b/src/SMESH/SMESH_Pattern.cxx index 55c37130c..b82d4e7e2 100644 --- a/src/SMESH/SMESH_Pattern.cxx +++ b/src/SMESH/SMESH_Pattern.cxx @@ -3138,7 +3138,9 @@ bool SMESH_Pattern::Apply (const SMDS_MeshVolume* theVolume, // coordinates computed by either of Apply...() methods //======================================================================= -bool SMESH_Pattern::MakeMesh (SMESH_Mesh* theMesh, bool toCreatePoly) +bool SMESH_Pattern::MakeMesh (SMESH_Mesh* theMesh, + const bool toCreatePolygons, + const bool toCreatePolyedrs) { MESSAGE(" ::MakeMesh() " ); if ( !myIsComputed ) @@ -3371,13 +3373,14 @@ bool SMESH_Pattern::MakeMesh (SMESH_Mesh* theMesh, bool toCreatePoly) editor.Remove( elemIDs, false ); } - if (toCreatePoly && myIs2D) { + if (toCreatePolygons) { // replace adjacent faces by polygons, inserting nodes in common link map< TNodeSet, list< list > >::iterator linksIt; for (linksIt = myLinks.begin(); linksIt != myLinks.end(); linksIt++) { // end nodes of link set ends = linksIt->first; + if (ends.size() < 2) continue; set::iterator endsIt = ends.begin(); const SMDS_MeshNode* n1 = *endsIt; endsIt++; @@ -3403,13 +3406,17 @@ bool SMESH_Pattern::MakeMesh (SMESH_Mesh* theMesh, bool toCreatePoly) SMESH_MeshEditor::FindFaceInSet(n1, n2, elemSet, avoidSet); if (adjElem) { SMESH_MeshEditor editor (theMesh); - editor.InsertNodesIntoLink(adjElem, n1, n2, link_nodes, toCreatePoly); + editor.InsertNodesIntoLink(adjElem, n1, n2, link_nodes, toCreatePolygons); } else { break; } } } } + if (toCreatePolyedrs) { + // replace adjacent volumes by polyedres, inserting nodes in common link + + } return setErrorCode( ERR_OK ); } diff --git a/src/SMESH/SMESH_Pattern.hxx b/src/SMESH/SMESH_Pattern.hxx index baa9361b8..fb113c251 100644 --- a/src/SMESH/SMESH_Pattern.hxx +++ b/src/SMESH/SMESH_Pattern.hxx @@ -128,7 +128,9 @@ class SMESH_Pattern { bool GetMappedPoints ( std::list & thePoints ) const; // Return nodes coordinates computed by Apply() method - bool MakeMesh (SMESH_Mesh* theMesh, bool toCreatePoly = false); + bool MakeMesh (SMESH_Mesh* theMesh, + const bool toCreatePolygons = false, + const bool toCreatePolyedrs = false); // Create nodes and elements in using nodes // coordinates computed by either of Apply...() methods diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx index 657020393..d9ee92643 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.cxx @@ -207,7 +207,8 @@ QFrame* SMESHGUI_MeshPatternDlg::createMainFrame( QWidget* theParent ) myReverseChk = new QCheckBox( tr( "REVERSE" ), aPatGrp ); // CreatePoly check box - myCreatePolyChk = new QCheckBox( tr( "CREATE_POLYGONS_NEAR_BOUNDARY" ), aPatGrp ); + myCreatePolygonsChk = new QCheckBox( tr( "CREATE_POLYGONS_NEAR_BOUNDARY" ), aPatGrp ); + myCreatePolyedrsChk = new QCheckBox( tr( "CREATE_POLYEDRS_NEAR_BOUNDARY" ), aPatGrp ); // Pictures 2d and 3d for ( int i = 0; i < 2; i++ ) @@ -392,9 +393,10 @@ bool SMESHGUI_MeshPatternDlg::onApply() myGeomObj[ Object ], myGeomObj[ Vertex1 ], myGeomObj[ Vertex2 ] ); } - bool toCreatePoly = (myCreatePolyChk->isChecked() && (myType == Type_2d)); + bool toCreatePolygons = myCreatePolygonsChk->isChecked(); + bool toCreatePolyedrs = myCreatePolyedrsChk->isChecked(); - if ( myPattern->MakeMesh( myMesh, toCreatePoly ) ) + if ( myPattern->MakeMesh( myMesh, toCreatePolygons, toCreatePolyedrs ) ) { mySelection->ClearIObjects(); SMESHGUI* aCompGUI = SMESHGUI::GetSMESHGUI(); @@ -1119,6 +1121,9 @@ void SMESHGUI_MeshPatternDlg::onTypeChanged( int theType ) mySelEdit[ Vertex2 ]->setText( "" ); mySelEdit[ Ids ] ->setText( "" ); + myCreatePolygonsChk->show(); + myCreatePolyedrsChk->show(); + if ( theType == Type_2d ) { // Geom widgets @@ -1126,7 +1131,6 @@ void SMESHGUI_MeshPatternDlg::onTypeChanged( int theType ) mySelBtn [ Vertex2 ]->hide(); mySelEdit[ Vertex2 ]->hide(); myReverseChk->show(); - myCreatePolyChk->show(); myPicture2d->show(); myPicture3d->hide(); mySelLbl[ Object ]->setText( tr( "FACE" ) ); @@ -1143,7 +1147,6 @@ void SMESHGUI_MeshPatternDlg::onTypeChanged( int theType ) mySelBtn [ Vertex2 ]->show(); mySelEdit[ Vertex2 ]->show(); myReverseChk->hide(); - myCreatePolyChk->hide(); myPicture2d->hide(); myPicture3d->show(); mySelLbl[ Object ]->setText( tr( "3D_BLOCK" ) ); diff --git a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h index 4a780322b..a621dfa5d 100755 --- a/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h +++ b/src/SMESHGUI/SMESHGUI_MeshPatternDlg.h @@ -145,7 +145,8 @@ private: QPushButton* myNewBtn; QCheckBox* myReverseChk; - QCheckBox* myCreatePolyChk; + QCheckBox* myCreatePolygonsChk; + QCheckBox* myCreatePolyedrsChk; SMESHGUI_PatternWidget* myPicture2d; QFrame* myPicture3d; QLabel* myPreview3d; diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx index 391e72957..04e453826 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.cxx +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.cxx @@ -246,9 +246,14 @@ SMESHGUI_SewingDlg::SMESHGUI_SewingDlg( QWidget* parent, const char* name, SALOM 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 ); + CheckBoxPolygons = new QCheckBox( GroupArguments, "CheckBoxPolygons" ); + CheckBoxPolygons->setText( tr( "CREATE_POLYGONS_INSTEAD_SPLITTING" ) ); + GroupArgumentsLayout->addWidget( CheckBoxPolygons, 3, 0 ); + + // Control for the polyedres creation to obtain conform mesh + CheckBoxPolyedrs = new QCheckBox( GroupArguments, "CheckBoxPolyedrs" ); + CheckBoxPolyedrs->setText( tr( "CREATE_POLYEDRS_NEAR_BOUNDARY" ) ); + GroupArgumentsLayout->addWidget( CheckBoxPolyedrs, 4, 0 ); SMESHGUI_SewingDlgLayout->addWidget( GroupArguments, 1, 0 ); @@ -325,7 +330,8 @@ void SMESHGUI_SewingDlg::Init() myActor = 0; myMesh = SMESH::SMESH_Mesh::_nil(); CheckBoxMerge->setChecked(false); - CheckBoxPoly->setChecked(false); + CheckBoxPolygons->setChecked(false); + CheckBoxPolyedrs->setChecked(false); SelectionIntoArgument(); } @@ -361,8 +367,12 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId) LineEdit6->setEnabled(true); } - if (constructorId != 0 && CheckBoxPoly->isVisible()) - CheckBoxPoly->hide(); + if (constructorId == 1 || constructorId == 3) { + if (CheckBoxPolygons->isVisible()) + CheckBoxPolygons->hide(); + if (CheckBoxPolyedrs->isVisible()) + CheckBoxPolyedrs->hide(); + } switch(constructorId) { @@ -372,8 +382,10 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId) SubGroup1->setTitle( tr( "BORDER_1" ) ); SubGroup2->setTitle( tr( "BORDER_2" ) ); - if (!CheckBoxPoly->isVisible()) - CheckBoxPoly->show(); + if (!CheckBoxPolygons->isVisible()) + CheckBoxPolygons->show(); + if (!CheckBoxPolyedrs->isVisible()) + CheckBoxPolyedrs->show(); break; } @@ -401,8 +413,10 @@ void SMESHGUI_SewingDlg::ConstructorsClicked(int constructorId) SelectButton5->setEnabled(false); LineEdit5->setEnabled(false); - if (!CheckBoxPoly->isVisible()) - CheckBoxPoly->show(); + if (!CheckBoxPolygons->isVisible()) + CheckBoxPolygons->show(); + if (!CheckBoxPolyedrs->isVisible()) + CheckBoxPolyedrs->show(); myOk5 = true; @@ -464,8 +478,9 @@ bool SMESHGUI_SewingDlg::ClickOnApply() if ( IsValid() ) { bool toMerge = CheckBoxMerge->isChecked(); - bool toCreatePoly = CheckBoxPoly->isChecked(); - + bool toCreatePolygons = CheckBoxPolygons->isChecked(); + bool toCreatePolyedrs = CheckBoxPolyedrs->isChecked(); + try { SMESH::SMESH_MeshEditor_var aMeshEditor = myMesh->GetMeshEditor(); @@ -481,7 +496,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() LineEdit4->text().toLong(), LineEdit5->text().toLong(), LineEdit6->text().toLong(), - toCreatePoly); + toCreatePolygons, + toCreatePolyedrs); else if (aConstructorId == 1) anError = aMeshEditor->SewConformFreeBorders(LineEdit1->text().toLong(), LineEdit2->text().toLong(), @@ -494,7 +510,8 @@ bool SMESHGUI_SewingDlg::ClickOnApply() LineEdit3->text().toLong(), LineEdit4->text().toLong(), LineEdit6->text().toLong(), - toCreatePoly); + toCreatePolygons, + toCreatePolyedrs); else if (aConstructorId == 3) { QStringList aListElementsId1 = QStringList::split( " ", LineEdit1->text(), false); diff --git a/src/SMESHGUI/SMESHGUI_SewingDlg.h b/src/SMESHGUI/SMESHGUI_SewingDlg.h index 80740d79d..e2ac55848 100644 --- a/src/SMESHGUI/SMESHGUI_SewingDlg.h +++ b/src/SMESHGUI/SMESHGUI_SewingDlg.h @@ -111,8 +111,9 @@ private: QLineEdit* LineEdit5; QLineEdit* LineEdit6; QCheckBox* CheckBoxMerge; - QCheckBox* CheckBoxPoly; - + QCheckBox* CheckBoxPolygons; + QCheckBox* CheckBoxPolyedrs; + private slots: void ConstructorsClicked(int constructorId); diff --git a/src/SMESH_I/SMESH_MeshEditor_i.cxx b/src/SMESH_I/SMESH_MeshEditor_i.cxx index 46ccb4b89..442116dee 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.cxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.cxx @@ -190,13 +190,11 @@ CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolume { int NbNodes = IDsOfNodes.length(); std::vector n (NbNodes); - //const SMDS_MeshNode* n [NbNodes]; for (int i = 0; i < NbNodes; i++) n[i] = GetMeshDS()->FindNode(IDsOfNodes[i]); int NbFaces = Quantities.length(); std::vector q (NbFaces); - //int q [NbFaces]; for (int j = 0; j < NbFaces; j++) q[j] = Quantities[j]; @@ -213,13 +211,22 @@ CORBA::Boolean SMESH_MeshEditor_i::AddPolyhedralVolumeByFaces (const SMESH::long_array & IdsOfFaces) { int NbFaces = IdsOfFaces.length(); + std::vector poly_nodes; + std::vector quantities (NbFaces); + std::vector faces (NbFaces); - for (int i = 0; i < NbFaces; i++) - faces[i] = (SMDS_MeshFace *)GetMeshDS()->FindElement(IdsOfFaces[i]); + for (int i = 0; i < NbFaces; i++) { + const SMDS_MeshElement* aFace = GetMeshDS()->FindElement(IdsOfFaces[i]); + quantities[i] = aFace->NbNodes(); - //GetMeshDS()->AddPolyhedralVolumeByFaces(faces); - //return true; - return false; + SMDS_ElemIteratorPtr It = aFace->nodesIterator(); + while (It->more()) { + poly_nodes.push_back(static_cast(It->next())); + } + } + + GetMeshDS()->AddPolyhedralVolume(poly_nodes, quantities); + return true; }; //============================================================================= @@ -917,7 +924,8 @@ SMESH::SMESH_MeshEditor::Sew_Error CORBA::Long FirstNodeID2, CORBA::Long SecondNodeID2, CORBA::Long LastNodeID2, - CORBA::Boolean CreatePoly) + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) { SMESHDS_Mesh* aMesh = GetMeshDS(); @@ -945,7 +953,8 @@ SMESH::SMESH_MeshEditor::Sew_Error aSide2SecondNode, aSide2ThirdNode, true, - CreatePoly) ); + CreatePolygons, + CreatePolyedrs) ); } //======================================================================= @@ -985,7 +994,7 @@ SMESH::SMESH_MeshEditor::Sew_Error aSide2SecondNode, aSide2ThirdNode, true, - false) ); + false, false) ); } //======================================================================= @@ -999,7 +1008,8 @@ SMESH::SMESH_MeshEditor::Sew_Error CORBA::Long LastNodeIDOnFreeBorder, CORBA::Long FirstNodeIDOnSide, CORBA::Long LastNodeIDOnSide, - CORBA::Boolean CreatePoly) + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs) { SMESHDS_Mesh* aMesh = GetMeshDS(); @@ -1026,7 +1036,8 @@ SMESH::SMESH_MeshEditor::Sew_Error aSide2SecondNode, aSide2ThirdNode, false, - CreatePoly) ); + CreatePolygons, + CreatePolyedrs) ); } //======================================================================= diff --git a/src/SMESH_I/SMESH_MeshEditor_i.hxx b/src/SMESH_I/SMESH_MeshEditor_i.hxx index b6aeb3191..38694d9fc 100644 --- a/src/SMESH_I/SMESH_MeshEditor_i.hxx +++ b/src/SMESH_I/SMESH_MeshEditor_i.hxx @@ -165,7 +165,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Long FirstNodeID2, CORBA::Long SecondNodeID2, CORBA::Long LastNodeID2, - CORBA::Boolean CreatePoly); + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs); SMESH::SMESH_MeshEditor::Sew_Error SewConformFreeBorders(CORBA::Long FirstNodeID1, CORBA::Long SecondNodeID1, @@ -178,7 +179,8 @@ class SMESH_MeshEditor_i: public POA_SMESH::SMESH_MeshEditor CORBA::Long LastNodeIDOnFreeBorder, CORBA::Long FirstNodeIDOnSide, CORBA::Long LastNodeIDOnSide, - CORBA::Boolean CreatePoly); + CORBA::Boolean CreatePolygons, + CORBA::Boolean CreatePolyedrs); SMESH::SMESH_MeshEditor::Sew_Error SewSideElements(const SMESH::long_array& IDsOfSide1Elements, const SMESH::long_array& IDsOfSide2Elements, diff --git a/src/SMESH_I/SMESH_Pattern_i.cxx b/src/SMESH_I/SMESH_Pattern_i.cxx index 107a26eca..17c902161 100644 --- a/src/SMESH_I/SMESH_Pattern_i.cxx +++ b/src/SMESH_I/SMESH_Pattern_i.cxx @@ -297,13 +297,14 @@ SMESH::point_array* //======================================================================= CORBA::Boolean SMESH_Pattern_i::MakeMesh (SMESH::SMESH_Mesh_ptr theMesh, - const CORBA::Boolean CreatePoly) + const CORBA::Boolean CreatePolygons, + const CORBA::Boolean CreatePolyedrs) { ::SMESH_Mesh* aMesh = getMesh( theMesh ); if ( !aMesh ) return false; - return myPattern.MakeMesh( aMesh, CreatePoly ); + return myPattern.MakeMesh( aMesh, CreatePolygons, CreatePolyedrs ); } //======================================================================= diff --git a/src/SMESH_I/SMESH_Pattern_i.hxx b/src/SMESH_I/SMESH_Pattern_i.hxx index 1a3428fcc..29b5084cd 100644 --- a/src/SMESH_I/SMESH_Pattern_i.hxx +++ b/src/SMESH_I/SMESH_Pattern_i.hxx @@ -76,7 +76,8 @@ class SMESH_Pattern_i: CORBA::Long theNode001Index); CORBA::Boolean MakeMesh (SMESH::SMESH_Mesh_ptr theMesh, - const CORBA::Boolean CreatePoly); + const CORBA::Boolean CreatePolygons, + const CORBA::Boolean CreatePolyedrs); SMESH::SMESH_Pattern::ErrorCode GetErrorCode(); -- 2.39.2