import os, inspect, SalomePyQt
import salome
import math
from collections import OrderedDict
sg = SalomePyQt.SalomePyQt()
from PyQt5.QtWidgets import QMessageBox


import GEOM
from salome.geom import geomBuilder
geompy = geomBuilder.New()


#***************
#begin script
shapes_for_partition = []

shape_dict = {}
for key in domain_entities:
    importedGeometry = geompy.ImportBREP(domain_entities[key])
    shapes_for_partition.append(importedGeometry)
    shape_dict[key] = importedGeometry
    geompy.addToStudy(importedGeometry, key)
	
for key in boundary_entities:
    importedBnd = geompy.ImportBREP(boundary_entities[key])
    shape_dict[key] = importedBnd
    geompy.addToStudy(importedBnd, key)

# do not generate partition,
# use MakeGlueFaces instead. It works better for non overlapping bodies.
Partition_1 = geompy.MakeGlueFaces(shapes_for_partition, 1e-07)
geompy.addToStudy( Partition_1, 'Partition_1' )


for key in domain_groups:
    group = geompy.CreateGroup(Partition_1, geompy.ShapeType["SOLID"])
    for ent in domain_groups[key]:
        dom = geompy.GetInPlaceByHistory(Partition_1, shape_dict[ent])
        geompy.AddObject(group, geompy.GetSubShapeID(Partition_1, dom))
    geompy.addToStudyInFather( Partition_1, group, key )
	
	
	
for key in boundary_groups:
    group = geompy.CreateGroup(Partition_1, geompy.ShapeType["FACE"])
    for ent in boundary_groups[key]:
        bnd = geompy.GetInPlace(Partition_1, shape_dict[ent], True)
        if geompy.NbShapes(bnd, geompy.ShapeType["FACE"]) > 1:
            extract_list = geompy.ExtractShapes(bnd, geompy.ShapeType["FACE"], True)
            for e in extract_list:
                geompy.AddObject(group, geompy.GetSubShapeID(Partition_1, e))
        else:
            geompy.AddObject(group, geompy.GetSubShapeID(Partition_1, bnd))
    geompy.addToStudyInFather( Partition_1, group, key )



###
### SMESH component
###

import  SMESH, SALOMEDS
from salome.smesh import smeshBuilder

smesh = smeshBuilder.New()

totalVolume = geompy.BasicProperties(Partition_1)
v0 = totalVolume[2]/5000 #sinle element volume
elsize = (v0*6*math.sqrt(2))**(0.33)

Mesh_1 = smesh.Mesh(Partition_1)
Regular_1D = Mesh_1.Segment()
Max_Size_1 = Regular_1D.MaxSize(elsize)
NETGEN_2D = Mesh_1.Triangle(algo=smeshBuilder.NETGEN_2D)
Length_From_Edges = NETGEN_2D.LengthFromEdges()
NETGEN_3D = Mesh_1.Tetrahedron()

smesh.SetName(Mesh_1.GetMesh(), 'Mesh_1')
smesh.SetName(Max_Size_1, 'Max Size_1')
smesh.SetName(Regular_1D.GetAlgorithm(), 'Regular_1D')
smesh.SetName(NETGEN_3D.GetAlgorithm(), 'NETGEN 3D')
smesh.SetName(NETGEN_2D.GetAlgorithm(), 'NETGEN_2D')

groups = geompy.GetGroups(Partition_1)
has_VL = False
for key in domain_groups:
    for gr in groups:
        if gr.GetName() == key:
            domGroup = gr
            break
    
    domName = domGroup.GetName()
    Mesh_1.GroupOnGeom(domGroup, str(domName))
    if group_roles[domName] == "air":
        continue

    subVolume = geompy.BasicProperties(domGroup)
    v0 = subVolume[2]/10000
    elsize = (v0*6*math.sqrt(2))**(0.33)


    Regular_1D_1 = Mesh_1.Segment(geom=domGroup)
    Max_Size_2 = Regular_1D_1.MaxSize(elsize)
    NETGEN_2D_1 = Mesh_1.Triangle(algo=smeshBuilder.NETGEN_2D,geom=domGroup)
    Length_From_Edges_1 = NETGEN_2D_1.LengthFromEdges()
    NETGEN_3D_1 = Mesh_1.Tetrahedron(geom=domGroup)
    smesh.SetName(Max_Size_2, 'Max Size_' + str(domName))
    Sub_mesh_1 = Regular_1D_1.GetSubMesh()
    smesh.SetName(Sub_mesh_1, 'Sub-mesh_' + str(domName))

    if domName in vl_params:
        #find indices of faces to ignore
        to_ignore = []
        for gr in groups:
            if gr.GetName() in boundary_groups:
                if boundary_groups[gr.GetName()][0] in vl_params[domName][3]:
                    has_VL = True
                    to_ignore.append(gr.GetSubShapeIndices()[0]) # we work with entities, there should be no more than 1 object
        Viscous_Layers_1 = NETGEN_3D_1.ViscousLayers(vl_params[domName][0],vl_params[domName][1],vl_params[domName][2],to_ignore,1,smeshBuilder.SURF_OFFSET_SMOOTH)
        smesh.SetName(Viscous_Layers_1, 'Viscous Layers_' + str(domName))

for key in boundary_groups:
    for gr in groups:
        if gr.GetName() == key:
            bndGroup = gr
            break
    
    bndName = bndGroup.GetName()
    Mesh_1.GroupOnGeom(bndGroup, str(bndName))
if not has_VL:
    sg.activateModule("Mesh")
    msgBox = QMessageBox()
    msgBox.setWindowTitle("Warning")
    msgBox.setText("Mesh has been generated without Viscous Layers. Please, add them to respective sub-meshes before sending the mesh back to CENOS!")
    msgBox.exec_()
