[26467] | 1 |
|
---|
| 2 | #Class Triangle's triangulateio
|
---|
| 3 | mutable struct CTriangulateIO #{{{
|
---|
| 4 |
|
---|
| 5 | pointlist :: Ptr{Cdouble}
|
---|
| 6 | pointattributelist :: Ptr{Cdouble}
|
---|
| 7 | pointmarkerlist :: Ptr{Cint}
|
---|
| 8 | numberofpoints :: Cint
|
---|
| 9 | numberofpointattributes :: Cint
|
---|
| 10 |
|
---|
| 11 | trianglelist :: Ptr{Cint}
|
---|
| 12 | triangleattributelist :: Ptr{Cdouble}
|
---|
| 13 | trianglearealist :: Ptr{Cdouble}
|
---|
| 14 | neighborlist :: Ptr{Cint}
|
---|
| 15 | numberoftriangles :: Cint
|
---|
| 16 | numberofcorners :: Cint
|
---|
| 17 | numberoftriangleattributes :: Cint
|
---|
| 18 |
|
---|
| 19 | segmentlist :: Ptr{Cint}
|
---|
| 20 | segmentmarkerlist :: Ptr{Cint}
|
---|
| 21 | numberofsegments :: Cint
|
---|
| 22 |
|
---|
| 23 | holelist :: Ptr{Cdouble}
|
---|
| 24 | numberofholes :: Cint
|
---|
| 25 |
|
---|
| 26 | regionlist :: Ptr{Cdouble}
|
---|
| 27 | numberofregions :: Cint
|
---|
| 28 |
|
---|
| 29 | edgelist :: Ptr{Cint}
|
---|
| 30 | edgemarkerlist :: Ptr{Cint}
|
---|
| 31 | normlist :: Ptr{Cdouble}
|
---|
| 32 | numberofedges :: Cint
|
---|
| 33 | end #}}}
|
---|
| 34 | function CTriangulateIO() #{{{
|
---|
| 35 | return CTriangulateIO(C_NULL, C_NULL, C_NULL, 0, 0,
|
---|
| 36 | C_NULL, C_NULL, C_NULL, C_NULL, 0, 0, 0,
|
---|
| 37 | C_NULL, C_NULL, 0,
|
---|
| 38 | C_NULL, 0,
|
---|
| 39 | C_NULL, 0,
|
---|
| 40 | C_NULL, C_NULL, C_NULL, 0)
|
---|
| 41 | end# }}}
|
---|
| 42 | function Base.show(io::IO, tio::CTriangulateIO)# {{{
|
---|
| 43 | println(io,"CTriangulateIO(")
|
---|
| 44 | for name in fieldnames(typeof(tio))
|
---|
| 45 | a=getfield(tio,name)
|
---|
| 46 | print(io,"$(name) = ")
|
---|
| 47 | println(io,a)
|
---|
| 48 | end
|
---|
| 49 | println(io,")")
|
---|
| 50 | end# }}}
|
---|
| 51 |
|
---|
[26472] | 52 | using Printf #needed for sprintf
|
---|
| 53 |
|
---|
[26467] | 54 | """
|
---|
| 55 | TRIANGLE - create model mesh using the triangle package
|
---|
| 56 |
|
---|
| 57 | This function creates a model mesh using Triangle and a domain outline, to
|
---|
| 58 | within a certain resolution
|
---|
| 59 | #Arguments
|
---|
| 60 | - md is a model tuple
|
---|
| 61 | - domainname is the name of an Argus domain outline file
|
---|
| 62 | - resolution: is a characteristic length for the mesh (same unit as the domain outline unit)
|
---|
| 63 |
|
---|
| 64 | # Usage:
|
---|
| 65 | - md=triangle(md,domainname,resolution)
|
---|
| 66 | # Examples:
|
---|
| 67 | - md=triangle(md,'DomainOutline.exp',1000);
|
---|
| 68 | - md=triangle(md,'DomainOutline.exp','Rifts.exp',1500);
|
---|
| 69 | """
|
---|
[26472] | 70 | function triangle(md::model,domainname::String,resolution::Float64) #{{{
|
---|
[26467] | 71 |
|
---|
| 72 | #read input file
|
---|
| 73 | contours = expread(domainname)
|
---|
| 74 | area = resolution^2
|
---|
| 75 |
|
---|
| 76 | #Initialize i/o structures
|
---|
| 77 | ctio_in = CTriangulateIO();
|
---|
| 78 | ctio_out = CTriangulateIO();
|
---|
| 79 | vor_out = CTriangulateIO();
|
---|
| 80 |
|
---|
| 81 | #Construct input structure
|
---|
| 82 | numberofpoints = 0
|
---|
| 83 | numberofsegments = 0
|
---|
| 84 | for i in 1:length(contours)
|
---|
| 85 | numberofpoints += contours[i].nods-1
|
---|
| 86 | numberofsegments += contours[i].nods-1
|
---|
| 87 | end
|
---|
| 88 | numberofpointattributes = 1
|
---|
| 89 |
|
---|
| 90 | pointlist=Array{Cdouble,2}(undef,2,numberofpoints)
|
---|
| 91 | count = 0
|
---|
| 92 | for i in 1:length(contours)
|
---|
| 93 | nods = contours[i].nods
|
---|
| 94 | pointlist[1,count+1:count+nods-1] = contours[i].x[1:end-1]
|
---|
| 95 | pointlist[2,count+1:count+nods-1] = contours[i].y[1:end-1]
|
---|
| 96 | count += (nods-1)
|
---|
| 97 | end
|
---|
| 98 | pointattributelist=Array{Cdouble,1}(undef,numberofpoints)
|
---|
| 99 | pointmarkerlist=Array{Cint,1}(undef,numberofpoints)
|
---|
| 100 | for i in 1:numberofpoints
|
---|
| 101 | pointmarkerlist[i]=0
|
---|
| 102 | pointattributelist[i]=0.
|
---|
| 103 | end
|
---|
| 104 |
|
---|
| 105 | counter=0;
|
---|
| 106 | backcounter=0;
|
---|
| 107 | segmentlist=Array{Cint,2}(undef,2,numberofsegments)
|
---|
| 108 | segmentmarkerlist=Array{Cint,1}(undef,numberofsegments)
|
---|
| 109 | segmentmarkerlist[:].=0
|
---|
| 110 | for i in 1:length(contours)
|
---|
| 111 | nods = contours[i].nods
|
---|
| 112 | segmentlist[1,counter+1:counter+nods-2] = collect(counter+0:counter+nods-3)
|
---|
| 113 | segmentlist[2,counter+1:counter+nods-2] = collect(counter+1:counter+nods-2)
|
---|
| 114 | counter+=nods-2
|
---|
| 115 | #close profile
|
---|
| 116 | segmentlist[1,counter+1]=counter
|
---|
| 117 | segmentlist[2,counter+1]=backcounter
|
---|
| 118 | counter+=1
|
---|
| 119 | backcounter=counter
|
---|
| 120 | end
|
---|
| 121 |
|
---|
| 122 | numberofregions = 0
|
---|
| 123 | numberofholes = length(contours)-1
|
---|
| 124 | holelist = Array{Cdouble,2}(undef,2,numberofholes)
|
---|
| 125 | if numberofholes>0
|
---|
| 126 | for i in 2:length(contours)
|
---|
| 127 | xA=contours[i].x[1]; xB=contours[i].x[end-1]
|
---|
| 128 | yA=contours[i].y[1]; yB=contours[i].y[end-1]
|
---|
| 129 | xC=(xA+xB)/2; yC=(yA+yB)/2;
|
---|
| 130 | xD=xC+tan(10. /180. *pi)*(yC-yA);
|
---|
| 131 | yD=yC+tan(10. /180. *pi)*(xA-xC);
|
---|
| 132 | xE=xC-tan(10. /180. *pi)*(yC-yA);
|
---|
| 133 | yE=yC-tan(10. /180. *pi)*(xA-xC);
|
---|
| 134 | holelist[1,i-1] = xD
|
---|
| 135 | holelist[2,i-1] = yD
|
---|
| 136 | end
|
---|
| 137 | end
|
---|
| 138 |
|
---|
| 139 | #based on this, prepare input structure
|
---|
| 140 | ctio_in.numberofpoints = numberofpoints
|
---|
| 141 | ctio_in.pointlist=pointer(pointlist)
|
---|
| 142 | ctio_in.numberofpointattributes=numberofpointattributes
|
---|
| 143 | ctio_in.pointattributelist=pointer(pointattributelist)
|
---|
| 144 | ctio_in.pointmarkerlist=pointer(pointmarkerlist)
|
---|
| 145 | ctio_in.numberofsegments=numberofsegments
|
---|
| 146 | ctio_in.segmentlist=pointer(segmentlist)
|
---|
| 147 | ctio_in.segmentmarkerlist = pointer(segmentmarkerlist)
|
---|
| 148 | ctio_in.numberofholes=numberofholes
|
---|
| 149 | ctio_in.holelist=pointer(holelist)
|
---|
| 150 | ctio_in.numberofregions=0
|
---|
| 151 |
|
---|
| 152 | #Call triangle using ISSM's default options
|
---|
| 153 | triangle_switches = "pQzDq30ia"*@sprintf("%lf",area) #replace V by Q to quiet down the logging
|
---|
[26500] | 154 | #rc=ccall( (:triangulate,"libtriangle"),
|
---|
| 155 | rc=ccall( (:triangulate,"../../externalpackages/triangle/src/libtriangle.dylib"),
|
---|
[26467] | 156 | Cint, ( Cstring, Ref{CTriangulateIO}, Ref{CTriangulateIO}, Ref{CTriangulateIO}),
|
---|
| 157 | triangle_switches, Ref(ctio_in), Ref(ctio_out), Ref(vor_out))
|
---|
| 158 |
|
---|
| 159 | #post process output
|
---|
[26472] | 160 | points = convert(Array{Cdouble,2}, Base.unsafe_wrap(Array, ctio_out.pointlist, (2,Int(ctio_out.numberofpoints)), own=true))'
|
---|
| 161 | triangles = convert(Array{Cint,2}, Base.unsafe_wrap(Array, ctio_out.trianglelist, (3,Int(ctio_out.numberoftriangles)), own=true))' .+1
|
---|
[26522] | 162 | segments = convert(Array{Cint,2}, Base.unsafe_wrap(Array, ctio_out.segmentlist, (2,Int(ctio_out.numberofsegments)), own=true))' .+1
|
---|
| 163 |
|
---|
| 164 | #assign output
|
---|
[26472] | 165 | md.mesh = Mesh2dTriangle()
|
---|
| 166 | md.mesh.numberofvertices = ctio_out.numberofpoints
|
---|
| 167 | md.mesh.numberofelements = ctio_out.numberoftriangles
|
---|
| 168 | md.mesh.x = points[:,1]
|
---|
| 169 | md.mesh.y = points[:,2]
|
---|
| 170 | md.mesh.elements = triangles
|
---|
[26522] | 171 | md.mesh.segments = segments
|
---|
[26467] | 172 |
|
---|
[26522] | 173 | #post processing
|
---|
| 174 | md.mesh.vertexonboundary = zeros(Bool,md.mesh.numberofvertices)
|
---|
| 175 | md.mesh.vertexonboundary[md.mesh.segments] .= true
|
---|
| 176 |
|
---|
[26472] | 177 | return md
|
---|
[26467] | 178 | end#}}}
|
---|