X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSMESH%2FSMESH_MeshEditor.cxx;h=580f7371671b744a162d158e7b074a394cd8b2a3;hb=a75b6e066e559d6bb2eb946ee7fa533e44450bd0;hp=caeb8a29517d9e033e732a849eb409d5d4501b53;hpb=5acab3d3271d9516ca568577b1465693f5db96dd;p=modules%2Fsmesh.git diff --git a/src/SMESH/SMESH_MeshEditor.cxx b/src/SMESH/SMESH_MeshEditor.cxx index caeb8a295..580f73716 100644 --- a/src/SMESH/SMESH_MeshEditor.cxx +++ b/src/SMESH/SMESH_MeshEditor.cxx @@ -24,16 +24,13 @@ // Created : Mon Apr 12 16:10:22 2004 // Author : Edward AGAPOV (eap) -#define CHRONODEF #include "SMESH_MeshEditor.hxx" #include "SMDS_FaceOfNodes.hxx" #include "SMDS_VolumeTool.hxx" #include "SMDS_EdgePosition.hxx" -#include "SMDS_PolyhedralVolumeOfNodes.hxx" #include "SMDS_FacePosition.hxx" #include "SMDS_SpacePosition.hxx" -//#include "SMDS_QuadraticFaceOfNodes.hxx" #include "SMDS_MeshGroup.hxx" #include "SMDS_LinearEdge.hxx" #include "SMDS_Downward.hxx" @@ -4683,7 +4680,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, list fullList; const TopoDS_Shape& aS = theTrack->GetSubShape(); - // Sub shape for the Pattern must be an Edge or Wire + // Sub-shape for the Pattern must be an Edge or Wire if( aS.ShapeType() == TopAbs_EDGE ) { aTrackEdge = TopoDS::Edge( aS ); // the Edge must not be degenerated @@ -4973,7 +4970,7 @@ SMESH_MeshEditor::ExtrusionAlongTrack (TIDSortedElemSet & theElements, } fullList.push_back(PP1); - } // Sub shape for the Pattern must be an Edge or Wire + } // Sub-shape for the Pattern must be an Edge or Wire else if( aS.ShapeType() == TopAbs_EDGE ) { aTrackEdge = TopoDS::Edge( aS ); // the Edge must not be degenerated @@ -5599,6 +5596,7 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // Replicate or reverse elements + std::vector iForw; for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ ) { const SMDS_MeshElement* elem = *itElem; @@ -5700,7 +5698,9 @@ SMESH_MeshEditor::Transform (TIDSortedElemSet & theElems, // Regular elements - const std::vector& i = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType() ); + while ( iForw.size() < nbNodes ) iForw.push_back( iForw.size() ); + const std::vector& iRev = SMDS_MeshCell::reverseSmdsOrder( elem->GetEntityType() ); + const std::vector& i = needReverse ? iRev : iForw; // find transformed nodes vector nodes(nbNodes); @@ -5817,9 +5817,9 @@ SMESH_MeshEditor::generateGroups(const SMESH_SequenceOfElemPtr& nodeGens, if ( resElem != sourceElem ) resultElems.push_back( resElem ); // do not generate element groups from node ones - if ( sourceElem->GetType() == SMDSAbs_Node && - elems( iElem )->GetType() != SMDSAbs_Node ) - continue; +// if ( sourceElem->GetType() == SMDSAbs_Node && +// elems( iElem )->GetType() != SMDSAbs_Node ) +// continue; // add resultElems to groups made by ones the sourceElem belongs to list< TOldNewGroup >::iterator gOldNew, gLast = groupsOldNew.end(); @@ -7145,15 +7145,13 @@ void SMESH_MeshEditor::MergeNodes (TListOfListOfNodes & theGroupsOfNodes) } } // BUG 0020185: end - iRepl[ nbRepl++ ] = iCur; } curNodes[ iCur ] = n; bool isUnique = nodeSet.insert( n ).second; - if ( isUnique ) { + if ( isUnique ) uniqueNodes[ iUnique++ ] = n; - if ( nbRepl && iRepl[ nbRepl-1 ] == iCur ) - --nbRepl; // n do not stick to a node of the elem - } + else + iRepl[ nbRepl++ ] = iCur; iCur++; } @@ -9034,13 +9032,14 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, // get elem data needed to re-create it // - int id = elem->GetID(); - int nbNodes = elem->NbNodes(); - SMDSAbs_ElementType aType = elem->GetType(); + const int id = elem->GetID(); + const int nbNodes = elem->NbNodes(); + const SMDSAbs_ElementType aType = elem->GetType(); + const SMDSAbs_EntityType aGeomType = elem->GetEntityType(); nodes.assign(elem->begin_nodes(), elem->end_nodes()); - if ( elem->GetEntityType() == SMDSEntity_Polyhedra ) + if ( aGeomType == SMDSEntity_Polyhedra ) nbNodeInFaces = static_cast( elem )->GetQuantities(); - else if ( elem->GetEntityType() == SMDSEntity_Hexagonal_Prism ) + else if ( aGeomType == SMDSEntity_Hexagonal_Prism ) volumeToPolyhedron( elem, nodes, nbNodeInFaces ); // remove a linear element @@ -9073,7 +9072,7 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, } case SMDSAbs_Volume : { - switch( elem->GetEntityType() ) + switch( aGeomType ) { case SMDSEntity_Tetra: NewElem = theHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); @@ -9101,8 +9100,6 @@ int SMESH_MeshEditor::convertElemToQuadratic(SMESHDS_SubMesh * theSm, if( NewElem ) theSm->AddElement( NewElem ); } -// if (!GetMeshDS()->isCompacted()) -// GetMeshDS()->compactMesh(); return nbElem; } @@ -9201,8 +9198,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d) switch ( type ) { case SMDSEntity_Tetra: - NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], - nodes[3], id, theForce3d ); + NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d ); break; case SMDSEntity_Hexa: NewVolume = aHelper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], @@ -9245,7 +9241,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, if ( theElements.empty() ) return; // we believe that all theElements are of the same type - SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); + const SMDSAbs_ElementType elemType = (*theElements.begin())->GetType(); // get all nodes shared by theElements TIDSortedNodeSet allNodes; @@ -9322,8 +9318,8 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, if( elem->IsQuadratic() || elem->NbNodes() < 2 || elem->IsPoly() ) continue; - int id = elem->GetID(); - SMDSAbs_ElementType type = elem->GetType(); + const int id = elem->GetID(); + const SMDSAbs_ElementType type = elem->GetType(); vector nodes ( elem->begin_nodes(), elem->end_nodes()); if ( !smDS || !smDS->Contains( elem )) @@ -9333,7 +9329,7 @@ void SMESH_MeshEditor::ConvertToQuadratic(const bool theForce3d, SMDS_MeshElement * newElem = 0; switch( nodes.size() ) { - case 4: // cases for most multiple element types go first (for optimization) + case 4: // cases for most frequently used element types go first (for optimization) if ( type == SMDSAbs_Volume ) newElem = helper.AddVolume(nodes[0], nodes[1], nodes[2], nodes[3], id, theForce3d); else @@ -10731,6 +10727,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorgetVtkId(); + //MESSAGE(" vtkId " << vtkId << " smdsId " << anElem->GetID()); int neighborsVtkIds[NBMAXNEIGHBORS]; int downIds[NBMAXNEIGHBORS]; unsigned char downTypes[NBMAXNEIGHBORS]; @@ -10756,6 +10754,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector, std::vector > edgesMultiDomains; // nodes of edge --> ordered domains - std::map > mutipleNodes; // nodes muti domains with domain order + std::map > mutipleNodes; // nodes multi domains with domain order + std::map > mutipleNodesToFace; // nodes multi domains with domain order to transform in Face (junction between 3 or more 2D domains) for (int idomain = 0; idomain < theElems.size(); idomain++) { @@ -10894,76 +10896,89 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorfirst.cellId; unsigned char cellType = itface->first.cellType; - int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); - const int *downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); - const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); - for (int ie =0; ie < nbEdges; ie++) + // --- shared edge or shared face ? + if ((cellType == VTK_LINE) || (cellType == VTK_QUADRATIC_EDGE)) // shared edge (between two faces) { int nodes[3]; - int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes); - if (mutipleNodes.count(nodes[0]) && mutipleNodes.count(nodes[nbNodes-1])) + int nbNodes = grid->getDownArray(cellType)->getNodes(downId, nodes); + for (int i=0; i< nbNodes; i=i+nbNodes-1) // i=0 , i=nbNodes-1 + if (mutipleNodes.count(nodes[i])) + if (!mutipleNodesToFace.count(nodes[i])) + mutipleNodesToFace[nodes[i]] = mutipleNodes[nodes[i]]; + } + else // shared face (between two volumes) + { + int nbEdges = grid->getDownArray(cellType)->getNumberOfDownCells(downId); + const int* downEdgeIds = grid->getDownArray(cellType)->getDownCells(downId); + const unsigned char* edgeType = grid->getDownArray(cellType)->getDownTypes(downId); + for (int ie =0; ie < nbEdges; ie++) { - vector vn0 = mutipleNodes[nodes[0]]; - vector vn1 = mutipleNodes[nodes[nbNodes - 1]]; - sort( vn0.begin(), vn0.end() ); - sort( vn1.begin(), vn1.end() ); - if (vn0 == vn1) + int nodes[3]; + int nbNodes = grid->getDownArray(edgeType[ie])->getNodes(downEdgeIds[ie], nodes); + if (mutipleNodes.count(nodes[0]) && mutipleNodes.count(nodes[nbNodes-1])) { - //MESSAGE(" detect edgesMultiDomains " << nodes[0] << " " << nodes[nbNodes - 1]); - double *coords = grid->GetPoint(nodes[0]); - gp_Pnt p0(coords[0], coords[1], coords[2]); - coords = grid->GetPoint(nodes[nbNodes - 1]); - gp_Pnt p1(coords[0], coords[1], coords[2]); - gp_Pnt gref; - int vtkVolIds[1000]; // an edge can belong to a lot of volumes - map domvol; // domain --> a volume with the edge - map angleDom; // oriented angles between planes defined by edge and volume centers - int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); - for (int id=0; id < vn0.size(); id++) + vector vn0 = mutipleNodes[nodes[0]]; + vector vn1 = mutipleNodes[nodes[nbNodes - 1]]; + sort( vn0.begin(), vn0.end() ); + sort( vn1.begin(), vn1.end() ); + if (vn0 == vn1) { - int idom = vn0[id]; - for (int ivol=0; ivolGetPoint(nodes[0]); + gp_Pnt p0(coords[0], coords[1], coords[2]); + coords = grid->GetPoint(nodes[nbNodes - 1]); + gp_Pnt p1(coords[0], coords[1], coords[2]); + gp_Pnt gref; + int vtkVolIds[1000]; // an edge can belong to a lot of volumes + map domvol; // domain --> a volume with the edge + map angleDom; // oriented angles between planes defined by edge and volume centers + int nbvol = grid->GetParentVolumes(vtkVolIds, downEdgeIds[ie], edgeType[ie]); + for (int id=0; id < vn0.size(); id++) { - int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]); - SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); - if (theElems[idom].count(elem)) + int idom = vn0[id]; + for (int ivol=0; ivol(elem); - domvol[idom] = svol; - //MESSAGE(" domain " << idom << " volume " << elem->GetID()); - double values[3]; - vtkIdType npts = 0; - vtkIdType* pts = 0; - grid->GetCellPoints(vtkVolIds[ivol], npts, pts); - SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); - if (id ==0) + int smdsId = meshDS->fromVtkToSmds(vtkVolIds[ivol]); + SMDS_MeshElement* elem = (SMDS_MeshElement*)meshDS->FindElement(smdsId); + if (theElems[idom].count(elem)) { - gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); - angleDom[idom] = 0; + SMDS_VtkVolume* svol = dynamic_cast(elem); + domvol[idom] = svol; + //MESSAGE(" domain " << idom << " volume " << elem->GetID()); + double values[3]; + vtkIdType npts = 0; + vtkIdType* pts = 0; + grid->GetCellPoints(vtkVolIds[ivol], npts, pts); + SMDS_VtkVolume::gravityCenter(grid, pts, npts, values); + if (id ==0) + { + gref.SetXYZ(gp_XYZ(values[0], values[1], values[2])); + angleDom[idom] = 0; + } + else + { + gp_Pnt g(values[0], values[1], values[2]); + angleDom[idom] = OrientedAngle(p0, p1, gref, g); // -pisecond << " angle " << ib->first); + } + for (int ino = 0; ino < nbNodes; ino++) + vnodes.push_back(nodes[ino]); + edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains } - map sortedDom; // sort domains by angle - for (map::iterator ia = angleDom.begin(); ia != angleDom.end(); ++ia) - sortedDom[ia->second] = ia->first; - vector vnodes; - vector vdom; - for (map::iterator ib = sortedDom.begin(); ib != sortedDom.end(); ++ib) - { - vdom.push_back(ib->second); - //MESSAGE(" ordered domain " << ib->second << " angle " << ib->first); - } - for (int ino = 0; ino < nbNodes; ino++) - vnodes.push_back(nodes[ino]); - edgesMultiDomains[vnodes] = vdom; // nodes vector --> ordered domains } } } @@ -10998,7 +11013,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectorsecond; itdom++; int dom2 = itdom->first; - SMDS_MeshVolume *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, + SMDS_MeshCell *vol = grid->extrudeVolumeFromFace(vtkVolId, dom1, dom2, oldNodes, nodeDomains, nodeQuadDomains); stringstream grpname; grpname << "j_"; @@ -11009,7 +11024,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vectormyMesh->AddGroup(SMDSAbs_Volume, namegrp.c_str(), idg); + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(vol->GetType(), namegrp.c_str(), idg); SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); if (sgrp) sgrp->Add(vol->GetID()); @@ -11017,10 +11032,37 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector >::iterator itn = mutipleNodesToFace.begin(); + for (; itn != mutipleNodesToFace.end(); ++itn) + { + int node = itn->first; + vector orderDom = itn->second; + vector orderedNodes; + for (int idom = 0; idom GetMeshDS()->AddFaceFromVtkIds(orderedNodes); + + stringstream grpname; + grpname << "m2j_"; + grpname << 0 << "_" << 0; + int idg; + string namegrp = grpname.str(); + if (!mapOfJunctionGroups.count(namegrp)) + mapOfJunctionGroups[namegrp] = this->myMesh->AddGroup(SMDSAbs_Face, namegrp.c_str(), idg); + SMESHDS_Group *sgrp = dynamic_cast(mapOfJunctionGroups[namegrp]->GetGroupDS()); + if (sgrp) + sgrp->Add(face->GetID()); + } + + // --- iterate on edgesMultiDomains + std::map, std::vector >::iterator ite = edgesMultiDomains.begin(); for (; ite != edgesMultiDomains.end(); ++ite) { @@ -11052,7 +11094,7 @@ bool SMESH_MeshEditor::DoubleNodesOnGroupBoundaries( const std::vector4); + SMDS_MeshElement* elem = + tgtEditor.AddElement(nodes, missType, !iQuad && nodes.size()/(iQuad+1)>4); ++nbAddedBnd; + + // try to set a new element to a shape + if ( myMesh->HasShapeToMesh() ) + { + bool ok = true; + set< pair > mediumShapes; + const int nbN = nodes.size() / (iQuad+1 ); + for ( inode = 0; inode < nbN && ok; ++inode ) + { + pair i_stype = + helper.GetMediumPos( nodes[inode], nodes[(inode+1)%nbN]); + if (( ok = ( i_stype.first > 0 && i_stype.second >= TopAbs_FACE ))) + mediumShapes.insert( make_pair ( i_stype.second, i_stype.first )); + } + if ( ok && mediumShapes.size() > 1 ) + { + set< pair >::iterator stype_i = mediumShapes.begin(); + pair stype_i_0 = *stype_i; + for ( ++stype_i; stype_i != mediumShapes.end() && ok; ++stype_i ) + { + if (( ok = ( stype_i->first != stype_i_0.first ))) + ok = helper.IsSubShape( aMesh->IndexToShape( stype_i->second ), + aMesh->IndexToShape( stype_i_0.second )); + } + } + if ( ok && mediumShapes.begin()->first == missShapeType ) + aMesh->SetMeshElementOnShape( elem, mediumShapes.begin()->second ); + } } // ----------------------------------