from OCC.Display.SimpleGui import *
from OCC.BRepBuilderAPI import *
from OCC.BRep import *
from OCC.BRepOffsetAPI import *
from OCC.BRepTools import *
from OCC.Utils.Topology import Topo
from OCC.KBE.TypesLookup import GeometryLookup, ShapeToTopology
from OCC.BRepPrimAPI import *
from OCC.gp import *
from OCC.BRepAlgoAPI import *
from OCC.SMESH import *
from OCC.StdMeshers import *
from OCC.TopoDS import *
from OCC.MeshVS import *
from OCC.ShHealOper import ShHealOper_RemoveInternalWires
from OCC.ShHealOper import ShHealOper_Sewing
from OCC.Utils.DataExchange.IGES import IGESExporter
display, start_display, add_menu, add_function_to_menu = init_display()

#Load aerofoil
aerofoil_1=TopoDS_Shape()
builder=BRep_Builder()
BRepTools().Read(aerofoil_1,str("<full path of directory containing .brep>\\airfoil.brep"),builder)

#Offset Aerofoil to create wing
aerofoil_2 = BRepOffsetAPI_MakeOffsetShape(aerofoil_1, 5000, 0.01).Shape()

#Wire of aerofoil_1
topo1 = Topo(aerofoil_1)
wi1 = topo1.wires_from_face(aerofoil_1)

#Wire of aerofoil_2
topo2 = Topo(aerofoil_2)
wi_2 = topo2.wires_from_face(aerofoil_2)

#Create loft
sections = BRepOffsetAPI_ThruSections(False, False, 0.01)
sections.AddWire(wi1.next())
sections.AddWire(wi_2.next())
sections.CheckCompatibility(True)
sections.Build()
te = ShapeToTopology()
loft = te(sections.Shape())
sections.Delete()

#Sew end aerofoils with loft
sewing = BRepBuilderAPI_Sewing()
sewing.Add(aerofoil_1)
sewing.Add(aerofoil_2)
sewing.Add(loft)
sewing.Perform()
sewed_shape = sewing.SewedShape() 
#display.DisplayShape(sewed_shape)

#create wing solid
tds = TopoDS()
solidWing = BRepBuilderAPI_MakeSolid(tds.shell(sewed_shape))
#display.DisplayShape(solidWing.Shape())

#Create bounding box(BB) for wing.
#One side of wing shall touch this box
boundingbox=BRepPrimAPI_MakeBox(13000.,10500.,10000.).Shape()

#Transform BB to position as desired.
transform = gp_Trsf()
transform.SetTranslation(gp_Vec(-2500,-5250,-10500))
gtrf = gp_GTrsf()
gtrf.SetTrsf(transform)
bbt = BRepBuilderAPI_GTransform(boundingbox, gtrf, True)

#make bounding box solid
topo3 = Topo(bbt.Shape())
bbSolid=topo3.solids()
bbsolid1=bbSolid.next()

#Cut wing from bounding box (Ideally only one cut shall work. But it gives me unexpected result.
print 'Start of Cut 1....'
cut=BRepAlgoAPI_Cut(solidWing.Shape(), bbsolid1)
print 'End of Cut 1'
print 'Start of Cut 2 ....'
cut1=BRepAlgoAPI_Cut(solidWing.Shape(), cut.Shape())
print 'End of Cut 2'

final_geom = display.DisplayShape(cut1.Shape())
display.Context.SetTransparency(final_geom, 0.7, True)

#Create Mesh : script comes from tutorial.
aeroMesh = SMESH_Gen()
aMesh = aeroMesh.CreateMesh(0,True)

an1DHypothesis = StdMeshers_Arithmetic1D(0,0,aeroMesh)
an1DHypothesis.SetLength(50.,False)
an1DHypothesis.SetLength(100.,True)
an1DAlgo = StdMeshers_Regular_1D(1,0,aeroMesh) 

a2dHypothseis = StdMeshers_QuadranglePreference(2,0,aeroMesh)
a2dAlgo = StdMeshers_Quadrangle_2D(3,0,aeroMesh)

a3dHypothesis = StdMeshers_Hexa_3D(4,0,aeroMesh)
#a3dHypothesis = StdMeshers_CompositeHexa_3D(4,0,aeroMesh)

aShape=cut1.Shape()
aMesh.ShapeToMesh(aShape)

aMesh.AddHypothesis(aShape,0)
aMesh.AddHypothesis(aShape,1)
aMesh.AddHypothesis(aShape,2)
aMesh.AddHypothesis(aShape,3)
aMesh.AddHypothesis(aShape,4)

aeroMesh.Compute(aMesh,aMesh.GetShapeToMesh())
print aMesh.NbNodes()
# Display the data
aDS = SMESH_MeshVSLink(aMesh)
aMeshVS = MeshVS_Mesh(True)
DMF=1
MeshVS_BP_Mesh=5

aPrsBuilder = MeshVS_MeshPrsBuilder(aMeshVS.GetHandle(),DMF,aDS.GetHandle(),0,MeshVS_BP_Mesh)
aMeshVS.SetDataSource(aDS.GetHandle())
aMeshVS.AddBuilder(aPrsBuilder.GetHandle(),True)
context = display.Context
context.Display(aMeshVS.GetHandle())
context.Deactivate(aMeshVS.GetHandle())
meshDisplay=display.DisplayShape(aShape)
display.Context.SetTransparency(meshDisplay, 0.7, True)

display.FitAll()
start_display()