2022-09-23 13:47:18 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import salome
|
|
|
|
import medcoupling as mc
|
|
|
|
from math import pi
|
2022-10-10 09:34:15 +02:00
|
|
|
import numpy as np
|
2022-09-23 13:47:18 +02:00
|
|
|
|
|
|
|
#salome.salome_init()
|
|
|
|
|
|
|
|
import GEOM
|
|
|
|
from salome.geom import geomBuilder
|
|
|
|
|
|
|
|
geompy = geomBuilder.New()
|
|
|
|
|
|
|
|
import SMESH, SALOMEDS
|
|
|
|
from salome.smesh import smeshBuilder
|
|
|
|
|
|
|
|
smesh = smeshBuilder.New()
|
|
|
|
|
2022-10-10 09:34:15 +02:00
|
|
|
from salome.kernel.logger import Logger
|
|
|
|
logger = Logger("salome.smesh.smesh_tools")
|
|
|
|
logger.setLevel("DEBUG")
|
|
|
|
|
2022-10-06 08:43:27 +02:00
|
|
|
def smesh_create_dual_mesh(mesh_ior, output_file, adapt_to_shape=True, mesh_name="MESH"):
|
2022-09-23 13:47:18 +02:00
|
|
|
""" Create a dual of the mesh in input_file into output_file
|
|
|
|
|
|
|
|
Args:
|
|
|
|
mesh_ior (string): corba Id of the Tetrahedron mesh
|
|
|
|
output_file (string): dual mesh file
|
|
|
|
"""
|
|
|
|
# Import mesh from file
|
|
|
|
mesh = salome.orb.string_to_object(mesh_ior)
|
|
|
|
if not mesh:
|
|
|
|
raise Exception("Could not find mesh using id: ", mesh_ior)
|
|
|
|
|
|
|
|
shape = mesh.GetShapeToMesh()
|
|
|
|
|
2022-10-10 09:34:15 +02:00
|
|
|
# Creating output file
|
2022-10-13 14:03:31 +02:00
|
|
|
logger.debug("Creating file with mesh: "+mesh_name)
|
2022-10-10 09:34:15 +02:00
|
|
|
myfile = mc.MEDFileUMesh()
|
|
|
|
myfile.setName(mesh_name)
|
|
|
|
|
|
|
|
|
2022-09-23 13:47:18 +02:00
|
|
|
# We got a meshProxy so we need to convert pointer to MEDCoupling
|
|
|
|
int_ptr = mesh.ExportMEDCoupling(True, True)
|
|
|
|
dab = mc.FromPyIntPtrToDataArrayByte(int_ptr)
|
2022-10-10 09:34:15 +02:00
|
|
|
mc_mesh_file = mc.MEDFileMesh.New(dab)
|
|
|
|
tetras = mc_mesh_file[0]
|
2022-09-23 13:47:18 +02:00
|
|
|
# End of SMESH -> MEDCoupling part for dualmesh
|
|
|
|
|
|
|
|
tetras = mc.MEDCoupling1SGTUMesh(tetras)
|
|
|
|
polyh = tetras.computeDualMesh()
|
2022-10-10 09:34:15 +02:00
|
|
|
|
|
|
|
## Adding skin + transfering groups on faces from tetras mesh
|
|
|
|
mesh2d = polyh.buildUnstructured().computeSkin()
|
|
|
|
mesh2d.setName(mesh_name)
|
|
|
|
myfile.setMeshAtLevel(-1, mesh2d)
|
|
|
|
|
|
|
|
|
|
|
|
for grp_name in mc_mesh_file.getGroupsOnSpecifiedLev(-1):
|
2022-10-13 14:03:31 +02:00
|
|
|
# This group is created by the export
|
|
|
|
if grp_name == "Group_Of_All_Faces":
|
|
|
|
logger.debug("Skipping group: "+ grp_name)
|
|
|
|
continue
|
2022-10-10 09:34:15 +02:00
|
|
|
logger.debug("Transferring group: "+ grp_name)
|
2022-10-13 14:03:31 +02:00
|
|
|
|
2022-10-10 09:34:15 +02:00
|
|
|
grp_tria = mc_mesh_file.getGroup(-1, grp_name)
|
|
|
|
# Retrieve the nodes in group
|
|
|
|
grp_nodes = grp_tria.computeFetchedNodeIds()
|
|
|
|
# Find all the cells lying on one of the nodes
|
|
|
|
id_grp_poly = mesh2d.getCellIdsLyingOnNodes(grp_nodes, False)
|
|
|
|
|
|
|
|
grp_poly = mesh2d[id_grp_poly]
|
|
|
|
|
2022-11-04 17:57:54 +01:00
|
|
|
# find the extra face cells, on the border of the group (lying on nodes, but outside the group)
|
|
|
|
id_poly_border = grp_poly.findCellIdsOnBoundary()
|
|
|
|
|
|
|
|
# ids of the cells in grp_poly
|
|
|
|
id_poly=mc.DataArrayInt64.New(grp_poly.getNumberOfCells(), 1)
|
|
|
|
id_poly.iota()
|
|
|
|
|
|
|
|
# cells that are really in the group
|
|
|
|
id_to_keep = id_poly.buildSubstraction(id_poly_border)
|
|
|
|
|
|
|
|
id_grp_poly = id_grp_poly[id_to_keep]
|
|
|
|
id_grp_poly.setName(grp_name.strip())
|
2022-10-10 09:34:15 +02:00
|
|
|
|
|
|
|
myfile.addGroup(-1, id_grp_poly)
|
2022-10-06 08:43:27 +02:00
|
|
|
|
|
|
|
# Getting list of new points added on the skin
|
2022-09-23 13:47:18 +02:00
|
|
|
skin = tetras.buildUnstructured().computeSkin()
|
|
|
|
skin_polyh = polyh.buildUnstructured().computeSkin()
|
|
|
|
allNodesOnSkinPolyh = skin_polyh.computeFetchedNodeIds()
|
|
|
|
allNodesOnSkin = skin.computeFetchedNodeIds()
|
|
|
|
ptsAdded = allNodesOnSkinPolyh.buildSubstraction(allNodesOnSkin)
|
|
|
|
ptsAddedMesh = mc.MEDCouplingUMesh.Build0DMeshFromCoords( skin_polyh.getCoords()[ptsAdded] )
|
|
|
|
|
|
|
|
if adapt_to_shape:
|
2022-10-10 09:34:15 +02:00
|
|
|
logger.debug("Adapting to shape")
|
2022-09-23 13:47:18 +02:00
|
|
|
ptsAddedCoo = ptsAddedMesh.getCoords()
|
|
|
|
ptsAddedCooModified = ptsAddedCoo[:]
|
|
|
|
|
2022-10-06 08:43:27 +02:00
|
|
|
# Matching faces with their ids
|
2022-09-23 13:47:18 +02:00
|
|
|
faces = geompy.ExtractShapes(shape, geompy.ShapeType["FACE"], True)
|
2022-10-06 08:43:27 +02:00
|
|
|
id2face = {}
|
|
|
|
for face in faces:
|
|
|
|
id2face[face.GetSubShapeIndices()[0]] = face
|
|
|
|
|
|
|
|
## Projecting each points added by the dual mesh on the surface it is
|
|
|
|
# associated with
|
|
|
|
for i, tup in enumerate(ptsAddedCooModified):
|
|
|
|
vertex = geompy.MakeVertex(*tuple(tup))
|
|
|
|
shapes = geompy.GetShapesNearPoint(shape, vertex,
|
|
|
|
geompy.ShapeType["FACE"])
|
|
|
|
prj = geompy.MakeProjection(vertex,
|
|
|
|
id2face[shapes.GetSubShapeIndices()[0]])
|
|
|
|
new_coor = geompy.PointCoordinates(prj)
|
|
|
|
ptsAddedCooModified[i] = new_coor
|
|
|
|
|
|
|
|
polyh.getCoords()[ptsAdded] = ptsAddedCooModified
|
|
|
|
|
2022-09-23 13:47:18 +02:00
|
|
|
polyh.setName(mesh_name)
|
2022-10-10 09:34:15 +02:00
|
|
|
myfile.setMeshAtLevel(0, polyh)
|
|
|
|
|
|
|
|
logger.debug("Writting dual mesh in :"+output_file)
|
|
|
|
myfile.write(output_file, 2)
|