+
+//================================================================================
+/*!
+ * \brief Set 1D sub-meshes to GModel. GMSH 1D mesh is made by now.
+ * \param [inout] _gModel - GMSH model
+ */
+//================================================================================
+
+void GMSHPlugin_Mesher::Set1DSubMeshes( GModel* gModel )
+{
+ SMESHDS_Mesh* meshDS = _mesh->GetMeshDS();
+
+ for(GModel::eiter it = gModel->firstEdge(); it != gModel->lastEdge(); ++it)
+ {
+ GEdge *gEdge = *it;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if ( !gEdge->haveParametrization())
+#else
+ if ( gEdge->geomType() == GEntity::CompoundCurve )
+#endif
+ continue;
+
+ TopoDS_Edge topoEdge = *((TopoDS_Edge*)gEdge->getNativePtr());
+ if ( !HasSubMesh( topoEdge ))
+ continue; // empty sub-mesh
+
+ gEdge->deleteMesh();
+
+ // get node parameters on topoEdge
+ StdMeshers_FaceSide side( TopoDS_Face(), topoEdge, _mesh, /*fwd=*/true, /*skpMedium=*/true);
+ const UVPtStructVec& nodeParam = side.GetUVPtStruct();
+ if ( nodeParam.empty() )
+ throw std::string("Pb with StdMeshers_FaceSide::GetUVPtStruct()");
+
+ // get GMSH mesh vertices on VERTEX'es
+ std::vector<MVertex *> mVertices( nodeParam.size(), nullptr );
+ GVertex * gV0 = gEdge->getBeginVertex(), *gV1 = gEdge->getEndVertex();
+ mVertices[0] = gV0->mesh_vertices[ 0 ];
+ mVertices.back() = gV1->mesh_vertices[ 0 ];
+ TopoDS_Vertex v01 = *((TopoDS_Vertex*) gV0->getNativePtr());
+ TopoDS_Shape v02 = SMESH_MesherHelper::GetSubShapeByNode( nodeParam[0].node, meshDS );
+ bool reverse = !v01.IsSame( v02 );
+ if ( mVertices[0] == mVertices.back() )
+ reverse = ( nodeParam[0].param > nodeParam.back().param );
+ const SMDS_MeshNode* n0 = reverse ? nodeParam.back().node : nodeParam[0].node;
+ const SMDS_MeshNode* n1 = reverse ? nodeParam[0].node : nodeParam.back().node;
+ _nodeMap.insert({ mVertices[ 0 ], n0 });
+ _nodeMap.insert({ mVertices.back(), n1 });
+
+ // create GMSH mesh vertices on gEdge
+ for ( size_t i = 1; i < nodeParam.size() - 1; ++i )
+ {
+ size_t iN = reverse ? ( nodeParam.size() - 1 - i ) : i;
+ SMESH_NodeXYZ xyz = nodeParam[ iN ].node;
+ double lc = segmentSize( nodeParam, iN );
+ // SVector3 der = gEdge->firstDer(nodeParam[ iN ].param);
+ // double lc = norm(der) / segmentSize( nodeParam, i );
+
+ mVertices[ i ] = new MEdgeVertex( xyz.X(), xyz.Y(), xyz.Z(),
+ gEdge, nodeParam[ iN ].param, 0, lc);
+ gEdge->mesh_vertices.push_back( mVertices[ i ]);
+ _nodeMap.insert({ mVertices[ i ], nodeParam[ iN ].node });
+ }
+ // create GMSH mesh edges
+ for ( size_t i = 1; i < mVertices.size(); ++i )
+ {
+ gEdge->lines.push_back( new MLine( mVertices[ i - 1 ],
+ mVertices[ i ]));
+ }
+ /*{
+ cout << endl << "EDGE " << gEdge->tag() <<
+ ( topoEdge.Orientation() == TopAbs_FORWARD ? " F" : " R") << endl;
+ MVertex* mv = gV0->mesh_vertices[ 0 ];
+ cout << "V0: " << mv->x() << ", " << mv->y() << ", " << mv->z() << ", "<<endl;
+ for ( size_t i = 0; i < gEdge->mesh_vertices.size(); ++i )
+ {
+ MEdgeVertex* mv = (MEdgeVertex*) gEdge->mesh_vertices[i];
+ cout << i << ": " << mv->x() << ", " << mv->y() << ", " << mv->z() << ", ";
+ double t;
+ mv->getParameter(0, t );
+ cout << ":\t t = "<< t << " lc = " << mv->getLc() << endl;
+ }
+ mv = gV1->mesh_vertices[ 0 ];
+ cout << "V1: " << mv->x() << ", " << mv->y() << ", " << mv->z() << ", "<<endl;
+ }*/
+ }
+ return;
+}
+
+//================================================================================
+/*!
+ * \brief Set 2D sub-meshes to GModel. GMSH 2D mesh is made by now.
+ * \param [inout] _gModel - GMSH model
+ */
+//================================================================================
+
+void GMSHPlugin_Mesher::Set2DSubMeshes( GModel* gModel )
+{
+ if ( _nodeMap.empty() )
+ return; // no sub-meshes
+
+ SMESH_MesherHelper helper( *_mesh );
+
+ std::map< const SMDS_MeshNode* , const MVertex * > nodes2mvertMap;
+ for ( auto & v2n : _nodeMap )
+ nodes2mvertMap.insert({ v2n.second, v2n.first });
+
+ std::vector<MVertex *> mVertices;
+
+ for(GModel::fiter it = gModel->firstFace(); it != gModel->lastFace(); ++it)
+ {
+ GFace *gFace = *it;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if ( !gFace->haveParametrization())
+#else
+ if ( gFace->geomType() == GEntity::CompoundSurface )
+#endif
+ continue;
+
+ TopoDS_Face topoFace = *((TopoDS_Face*)gFace->getNativePtr());
+ SMESHDS_SubMesh* sm = HasSubMesh( topoFace );
+ if ( !sm )
+ continue;
+ //_gModel->writeUNV("/tmp/befDEl.unv", 1,0,0);
+
+ gFace->deleteMesh();
+
+ bool reverse = false;
+ if ( gFace->getRegion(0) )
+ {
+ //GRegion * gRegion = gFace->getRegion(0);
+ TopoDS_Shape topoSolid = *((TopoDS_Shape*)gFace->getNativePtr());
+ TopAbs_Orientation faceOriInSolid = helper.GetSubShapeOri( topoSolid, topoFace );
+ if ( faceOriInSolid >= 0 )
+ reverse =
+ helper.IsReversedSubMesh( TopoDS::Face( topoFace.Oriented( faceOriInSolid )));
+ }
+
+ for ( SMDS_ElemIteratorPtr fIt = sm->GetElements(); fIt->more(); )
+ {
+ const SMDS_MeshElement* f = fIt->next();
+
+ int nbN = f->NbCornerNodes();
+ if ( nbN > 4 )
+ throw std::string("Polygon sub-meshes not supported");
+
+ mVertices.resize( nbN );
+ for ( int i = 0; i < nbN; ++i )
+ {
+ const SMDS_MeshNode* n = f->GetNode( i );
+ MVertex * mv = nullptr;
+ auto n2v = nodes2mvertMap.find( n );
+ if ( n2v != nodes2mvertMap.end() )
+ {
+ mv = const_cast< MVertex*>( n2v->second );
+ }
+ else
+ {
+ if ( n->GetPosition()->GetDim() < 2 )
+ throw std::string("Wrong mapping of edge nodes to GMSH nodes");
+ SMESH_NodeXYZ xyz = n;
+ bool ok = true;
+ gp_XY uv = helper.GetNodeUV( topoFace, n, nullptr, &ok );
+ mv = new MFaceVertex( xyz.X(), xyz.Y(), xyz.Z(), gFace, uv.X(), uv.Y() );
+ gFace->mesh_vertices.push_back( mv );
+ nodes2mvertMap.insert({ n, mv });
+ _nodeMap.insert ({ mv, n });
+ }
+ mVertices[ i ] = mv;
+ }
+ // create GMSH mesh faces
+ switch ( nbN ) {
+ case 3:
+ if ( reverse )
+ gFace->triangles.push_back (new MTriangle(mVertices[0], mVertices[2], mVertices[1]));
+ else
+ gFace->triangles.push_back (new MTriangle(mVertices[0], mVertices[1], mVertices[2]));
+ break;
+ case 4:
+ if ( reverse )
+ gFace->quadrangles.push_back (new MQuadrangle(mVertices[0], mVertices[3],
+ mVertices[2], mVertices[1]));
+ else
+ gFace->quadrangles.push_back (new MQuadrangle(mVertices[0], mVertices[1],
+ mVertices[2], mVertices[3]));
+ break;
+ default:;
+ }
+ }
+ } // loop on GMSH faces
+
+ return;
+}
+
+//================================================================================
+/*!
+ * \brief Set visibility 0 to already computed geom entities
+ * to prevent their meshing
+ */
+//================================================================================
+
+void GMSHPlugin_Mesher::HideComputedEntities( GModel* gModel, bool hideAnyway )
+{
+ CTX::instance()->mesh.meshOnlyVisible = true;
+
+ for(GModel::eiter it = gModel->firstEdge(); it != gModel->lastEdge(); ++it)
+ {
+ GEdge *gEdge = *it;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if ( !gEdge->haveParametrization())
+#else
+ if ( gEdge->geomType() == GEntity::CompoundCurve )
+#endif
+ continue;
+
+ TopoDS_Edge topoEdge = *((TopoDS_Edge*)gEdge->getNativePtr());
+ if ( HasSubMesh( topoEdge ) || hideAnyway )
+ gEdge->setVisibility(0);
+ }
+
+
+ for(GModel::fiter it = gModel->firstFace(); it != gModel->lastFace(); ++it)
+ {
+ GFace *gFace = *it;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if ( !gFace->haveParametrization())
+#else
+ if ( gFace->geomType() == GEntity::CompoundSurface )
+#endif
+ continue;
+
+ TopoDS_Face topoFace = *((TopoDS_Face*)gFace->getNativePtr());
+ if ( HasSubMesh( topoFace ) || hideAnyway )
+ gFace->setVisibility(0);
+ }
+}
+
+//================================================================================
+/*!
+ * \brief Restore visibility of all geom entities
+ */
+//================================================================================
+
+void GMSHPlugin_Mesher::RestoreVisibility( GModel* gModel )
+{
+ for(GModel::eiter it = gModel->firstEdge(); it != gModel->lastEdge(); ++it)
+ {
+ GEdge *gEdge = *it;
+ gEdge->setVisibility(1);
+ }
+ for(GModel::fiter it = gModel->firstFace(); it != gModel->lastFace(); ++it)
+ {
+ GFace *gFace = *it;
+ gFace->setVisibility(1);
+ }
+}
+
+/*
+ void GMSHPlugin_Mesher::toPython( GModel* )
+ {
+ const char* pyFile = "/tmp/gMesh.py";
+ ofstream outfile( pyFile, ios::out );
+ if ( !outfile ) return;
+
+ outfile << "import salome, SMESH" << std::endl
+ << "from salome.smesh import smeshBuilder" << std::endl
+ << "smesh = smeshBuilder.New()" << std::endl
+ << "mesh = smesh.Mesh()" << std::endl << std::endl;
+
+ outfile << "## VERTICES" << endl;
+ for ( GModel::viter it = _gModel->firstVertex(); it != _gModel->lastVertex(); ++it)
+ {
+ GVertex *gVertex = *it;
+
+ for(unsigned int i = 0; i < gVertex->mesh_vertices.size(); i++)
+ {
+ MVertex *v = gVertex->mesh_vertices[i];
+ if ( v->getIndex() >= 0)
+ {
+ outfile << "n" << v->getNum() << " = mesh.AddNode("
+ << v->x() << ", " << v->y() << ", " << v->z()<< ")"
+ << " ## tag = " << gVertex->tag() << endl;
+ }
+ }
+ }
+
+ for(GModel::eiter it = _gModel->firstEdge(); it != _gModel->lastEdge(); ++it)
+ {
+ GEdge *gEdge = *it;
+ outfile << "## GEdge " << gEdge->tag() << endl;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if(gEdge->haveParametrization())
+#else
+ if ( gEdge->geomType() != GEntity::CompoundCurve )
+#endif
+ for ( size_t i = 0; i < gEdge->mesh_vertices.size(); i++ )
+ {
+ MVertex *v = gEdge->mesh_vertices[i];
+ if ( v->getIndex() >= 0 )
+ {
+ outfile << "n" << v->getNum() << " = mesh.AddNode("
+ << v->x() << ", " << v->y() << ", " << v->z()<< ")"
+ << " ## tag = " << gEdge->tag() << endl;
+ }
+ }
+ }
+
+ for ( GModel::fiter it = _gModel->firstFace(); it != _gModel->lastFace(); ++it)
+ {
+ GFace *gFace = *it;
+ if ( _compounds.size() && gFace->geomType() == GEntity::DiscreteSurface )
+ continue;
+ outfile << "## GFace " << gFace->tag() << endl;
+
+ for ( size_t i = 0; i < gFace->mesh_vertices.size(); i++ )
+ {
+ MVertex *v = gFace->mesh_vertices[i];
+ if ( v->getIndex() >= 0 )
+ {
+ outfile << "n" << v->getNum() << " = mesh.AddNode("
+ << v->x() << ", " << v->y() << ", " << v->z()<< ")"
+ << " ## tag = " << gFace->tag() << endl;
+ }
+ }
+ }
+
+ std::vector<MVertex*> verts(3);
+ for(GModel::eiter it = _gModel->firstEdge(); it != _gModel->lastEdge(); ++it)
+ {
+ GEdge *gEdge = *it;
+ outfile << "## GEdge " << gEdge->tag() << endl;
+
+#if GMSH_MAJOR_VERSION >=4 && GMSH_MINOR_VERSION >=8
+ if(gEdge->haveParametrization())
+#else
+ if ( gEdge->geomType() != GEntity::CompoundCurve )
+#endif
+ for ( size_t i = 0; i < gEdge->getNumMeshElements(); i++ )
+ {
+ MElement *e = gEdge->getMeshElement(i);
+ verts.clear();
+ e->getVertices(verts);
+
+ outfile << "e" << e->getNum() << " = mesh.AddEdge(["
+ << "n" << verts[0]->getNum() << ","
+ << "n" << verts[1]->getNum();
+ if ( verts.size() == 3 )
+ outfile << "n" << verts[2]->getNum();
+ outfile << "])"<< endl;
+ }
+ }
+
+ for ( GModel::fiter it = _gModel->firstFace(); it != _gModel->lastFace(); ++it)
+ {
+ GFace *gFace = *it;
+ if ( _compounds.size() && gFace->geomType() == GEntity::DiscreteSurface )
+ continue;
+ outfile << "## GFace " << gFace->tag() << endl;
+
+ for ( size_t i = 0; i < gFace->getNumMeshElements(); i++ )
+ {
+ MElement *e = gFace->getMeshElement(i);
+ verts.clear();
+ e->getVertices(verts);
+
+ outfile << "f" << e->getNum() << " = mesh.AddFace([";
+ for ( size_t j = 0; j < verts.size(); j++)
+ {
+ outfile << "n" << verts[j]->getNum();
+ if ( j < verts.size()-1 )
+ outfile << ", ";
+ }
+ outfile << "])" << endl;
+ }
+ }
+ std::cout << "Write " << pyFile << std::endl;
+}
+*/