Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file mesh_triangleC.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418# 1 "triangle/mesh_triangleFC.ml"(* Binding to Triangle for layout c_layout. *)openPrintfopenBigarrayopenMesh_triangle_commontypelayout=Bigarray.c_layouttypemesh=layoutttypemat=layoutMesh.mattypevec=layoutMesh.vectypeint_mat=layoutMesh.int_mattypeint_vec=layoutMesh.int_vecletlayout=Bigarray.c_layoutletdefault_switches="z"letempty_vec=Array1.createintlayout0letempty_mat0=Array2.create(float64)c_layout(0)(0)letempty_mat2=Array2.create(float64)c_layout(0)(2)letempty_mat4=Array2.create(float64)c_layout(0)(4)letempty_int_mat2=Array2.create(int)c_layout(0)(2)letempty_int_mat3=Array2.create(int)c_layout(0)(3)letcheck_pointnamepoint=ifArray2.dim1(point)=0theninvalid_arg(name^": points cannot be empty");ifArray2.dim2(point)<>2theninvalid_arg(name^": dim2 points must be 2")letcheck_point_markername~npointm=letn=Array1.dimminif0<n&&n<>npointtheninvalid_arg(sprintf"%s: dim point_marker = %d <> dim1 point = %d"namennpoint)letget_point_markername~npoint=function|None->empty_vec|Somem->check_point_markername~npointm;mletcheck_point_attributename~npointa=ifArray2.dim2(a)>0&&Array2.dim1(a)<>npointtheninvalid_arg(sprintf"%s: dim1 point_attribute = %d <> dim1 point = %d"name(Array2.dim1(a))npoint)letget_point_attributename~npoint=function|None->empty_mat0|Somea->check_point_attributename~npointa;aletcheck_segmentnames=ifArray2.dim1(s)>0&&Array2.dim2(s)<>2theninvalid_arg(name^": dim2 segment must be 2")letget_segmentname=function|None->empty_int_mat2|Somes->check_segmentnames;sletcheck_segment_markername~nsegmentm=letn=Array1.dimminif0<n&&n<>nsegmenttheninvalid_arg(sprintf"%s: dim segment_marker = %d <> dim1 segment = %d"namennsegment)letget_segment_markername~nsegment=function|None->empty_vec|Somem->check_segment_markername~nsegmentm;mletcheck_holenameh=ifArray2.dim1(h)>0&&Array2.dim2(h)<>2theninvalid_arg(name^": dim2 hole must be 2")letget_holename=function|None->empty_mat2|Someh->check_holenameh;hletcheck_regionnamer=ifArray2.dim1(r)>0&&Array2.dim2(r)<>4theninvalid_arg(name^": dim2 region must be 4")letget_regionname=function|None->empty_mat4|Somer->check_regionnamer;rletcheck_trianglenametr=ifArray2.dim1(tr)=0theninvalid_arg(name^": must have at least one triangle");ifArray2.dim2(tr)<3theninvalid_arg(name^": dim2 mesh#triangle < 3")letcheck_triangle_attributename~ntrianglea=ifArray2.dim2(a)>0&&Array2.dim1(a)<>ntriangletheninvalid_arg(sprintf"%s: dim1 triangle_attribute = %d <> dim1 triangle \
= %d"name(Array2.dim1(a))ntriangle)letget_triangle_attributename~ntriangle=function|None->empty_mat0|Somea->check_triangle_attributename~ntrianglea;aletpslg~hole~region~point_attribute~point_marker~point~segment_marker~segment=check_point"Mesh_triangle.pslg"point;letnpoint=Array2.dim1(point)inletpoint_marker=get_point_marker"Mesh_triangle.pslg"~npointpoint_markerinletpoint_attribute=get_point_attribute"Mesh_triangle.pslg"~npointpoint_attributeincheck_segment"Mesh_triangle.pslg"segment;letsegment_marker=get_segment_marker"Mesh_triangle.pslg"~nsegment:(Array2.dim1(segment))segment_markerinlethole=get_hole"Mesh_triangle.pslg"holeinletregion=get_region"Mesh_triangle.pslg"regionin(objectmethodpoint=pointmethodpoint_marker=point_markermethodpoint_attribute=point_attributemethodsegment=segmentmethodsegment_marker=segment_markermethodhole=holemethodregion=regionend:c_layoutpslg)letcreate~hole~region~point_attribute~point_marker~point~segment_marker~segment~neighbor~edge~edge_marker~triangle_attribute~triangle=check_point"Mesh_triangle.create"point;letnpoint=Array2.dim1(point)inletpoint_marker=get_point_marker"Mesh_triangle.create"~npointpoint_markerinletpoint_attribute=get_point_attribute"Mesh_triangle.create"~npointpoint_attributeinletsegment=get_segment"Mesh_triangle.create"segmentinletsegment_marker=get_segment_marker"Mesh_triangle.create"~nsegment:(Array2.dim1(segment))segment_markerinlethole=get_hole"Mesh_triangle.create"holeinletregion=get_region"Mesh_triangle.create"regionincheck_triangle"Mesh_triangle.create"triangle;letntriangle=Array2.dim1(triangle)inlettriangle_attribute=get_triangle_attribute"Mesh_triangle.create"triangle_attribute~ntriangleinletneighbor=matchneighborwith|None->empty_int_mat3|Somenbh->ifArray2.dim1(nbh)>0then(ifArray2.dim1(nbh)<>ntriangletheninvalid_arg(sprintf"Mesh_triangle.create: dim1 neighbor = %d <> \
dim1 triangle = %d"(Array2.dim1(nbh))ntriangle);ifArray2.dim2(nbh)<>3theninvalid_arg"Mesh_triangle.create: dim2 neighbor <> 3";);nbhinletedge=matchedgewith|None->empty_int_mat2|Somee->ifArray2.dim1(e)>0&&Array2.dim2(e)<>2theninvalid_arg"Mesh_triangle.create: dim2 edge <> 2";einletedge_marker=matchedge_markerwith|None->empty_vec|Somee->letn=Array1.dimeinifn>0&&n<>Array2.dim1(edge)theninvalid_arg(sprintf"Mesh_triangle.create: dim1 edge_marker = %d <> \
dim1 edge = %d"n(Array2.dim1(edge)));ein(objectmethodpoint=pointmethodpoint_marker=point_markermethodpoint_attribute=point_attributemethodsegment=segmentmethodsegment_marker=segment_markermethodhole=holemethodregion=regionmethodtriangle_attribute=triangle_attributemethodtriangle=trianglemethodneighbor=neighbormethodedge=edgemethodedge_marker=edge_markerend:c_layoutt)externaltriangle:string->(* switches *)layoutt->vec(* trianglearea *)->mat*mat*int_vec*int_mat*mat*int_mat*int_mat*int_vec*(* edge *)int_mat*int_vec*(* voronoi *)mat*mat*int_mat*mat="triangulate_c_layout"letempty_vec=Array1.createfloat64layout0(* not used => global *)(* check that all C "triexit" have been avoided. *)lettriangulate?(delaunay=true)?min_angle?max_area?(region_area=false)?max_steiner?(voronoi=false)?(edge=true)?(neighbor=false)?(subparam=false)?triangle_area?triunsuitable?(check_finite=true)?(debug=true)?verbose~pslg~refine(mesh:layoutt)=(* Check points *)letpoint=mesh#pointincheck_point"Mesh_triangle"point;letnpoint=Array2.dim1(point)incheck_point_attribute"Mesh_triangle"~npointmesh#point_attribute;check_point_marker"Mesh_triangle"~npointmesh#point_marker;ifcheck_finitethen((* Check that no point contains NaN (or infinities). Triangle
seems to go into an infinite loop with these which can easily
be confused with other difficulties. *)fori=0toArray2.dim1(point)doifnot(is_finite(point.{i,0}))theninvalid_arg(sprintf"Mesh_triangle: mesh#point.{%i, %i} is not finite"(i)(0));ifnot(is_finite(point.{i,1}))theninvalid_arg(sprintf"Mesh_triangle: mesh#point.{%i, %i} is not finite"(i)(1));done;);letswitches=Buffer.create20inBuffer.add_stringswitchesdefault_switches;(* Check for PSLG *)ifpslgthen(check_segment"Mesh_triangle"mesh#segment;check_segment_marker"Mesh_triangle"~nsegment:(Array2.dim1(mesh#segment))mesh#segment_marker;ifnotrefinethen(lethole=mesh#holeincheck_hole"Mesh_triangle"hole;letregion=mesh#regioninifArray2.dim1(region)>0then(check_region"Mesh_triangle"region;Buffer.add_charswitches'A';(* regional attributes *)ifregion_areathenBuffer.add_charswitches'a';(* area constraint *));ifcheck_finitethen(fori=0toArray2.dim1(hole)doifnot(is_finite(hole.{i,0}))theninvalid_arg(sprintf"Mesh_triangle: mesh#hole.{%i, %i} is not \
finite"(i)(0));ifnot(is_finite(hole.{i,1}))theninvalid_arg(sprintf"Mesh_triangle: mesh#hole.{%i, %i} is not \
finite"(i)(1));done;fori=0toArray2.dim1(region)doforj=0toArray2.dim2(region)doifnot(is_finite(region.{i,j}))theninvalid_arg(sprintf"Mesh_triangle: mesh#region.{%i, %i} is not \
finite"(i)(j));donedone));Buffer.add_charswitches'p';ifArray2.dim2(mesh#segment)=0||Array2.dim1(mesh#segment)=0thenBuffer.add_charswitches'c';);(* Check for refinement -- triangles *)ifrefinethen(check_triangle"Mesh_triangle"mesh#triangle;check_triangle_attribute"Mesh_triangle"mesh#triangle_attribute~ntriangle:(Array2.dim1(mesh#triangle));Buffer.add_charswitches'r';(* Check triangle_area *)(matchtriangle_areawith|Somea->ifArray1.dima<>Array2.dim1(mesh#triangle)theninvalid_arg("Mesh_triangle: dim triangle_area <> dim1 mesh#triangle");Buffer.add_charswitches'a';|None->()););(* Area constraints *)(matchmax_areawith|None->()|Somea->bprintfswitches"a%f"a);lettriangle_area=matchtriangle_areawith|None->empty_vec|Somea->a(* for refinement only *)in(* Check for a triunsuitable function *)(matchtriunsuitablewith|None->()|Somef->register_triunsuitablef;Buffer.add_charswitches'u');(* Other switches *)ifdelaunaythenBuffer.add_charswitches'D';(matchmin_anglewith|None->()|Somea->ifa<0.||a>60.then(* required: 3 min_angle <= 180 *)Buffer.add_charswitches'q'else(* Angle may include a decimal point, but not exponential notation. *)bprintfswitches"d%f"a);(matchmax_steinerwith|None->()|Somea->bprintfswitches"S%i"a);ifvoronoithenBuffer.add_charswitches'v';ifedgethenBuffer.add_charswitches'e';ifneighborthenBuffer.add_charswitches'n';ifsubparamthenBuffer.add_stringswitches"o2";ifnotdebugthenBuffer.add_charswitches'Q';(matchverbosewith|Some`V->Buffer.add_stringswitches"V";|Some`VV->Buffer.add_stringswitches"V";|Some`VVV->Buffer.add_stringswitches"VVV";|None->());(* Call triangle and build the resulting objects *)letpoint,point_attribute,point_marker,triangle,triangle_attribute,neighbor,segment,segment_marker,edge,edge_marker,vor_point,vor_point_attribute,vor_edge,vor_normal=triangle(Buffer.contentsswitches)meshtriangle_areainletmesh_out:layoutt=(make_mesh~point:point~point_attribute:point_attribute~point_marker:point_marker~triangle:triangle~triangle_attribute:triangle_attribute~neighbor:neighbor~segment:segment~segment_marker:segment_marker~edge:edge~edge_marker:edge_marker~hole:mesh#hole~region:mesh#region)andvor:layoutvoronoi=(objectmethodpoint=vor_pointmethodpoint_attribute=vor_point_attributemethodedge=vor_edgemethodnormal=vor_normalend)in(mesh_out,vor)(* Sub
***********************************************************************)letsub(mesh:mesh)?(pos=0)len=letm,n_tr,cols_tr=Mesh__MeshC.internal_sub(mesh:>Mesh__MeshC.mesh)~posleninletpoint_attribute=ifArray2.dim2(mesh#point_attribute)=0||Array2.dim1(mesh#point_attribute)=0thenmesh#point_attributeelseArray2.sub_leftmesh#point_attributeposleninlettriangle_attribute=letold_att=mesh#triangle_attributeinifArray2.dim2(old_att)=0||Array2.dim1(old_att)=0thenold_attelse(letatt=Array2.create(float64)c_layout(n_tr)(Array2.dim2(old_att))inMesh__MeshC.iteri(funipi->forj=0toArray2.dim2(att)-1doatt.{i,j}<-old_att.{pi,j};done)cols_tr;att)inextend_meshm~point_attribute:point_attribute~triangle_attribute:triangle_attribute(* Permutations
***********************************************************************)letpermute_points_name="Mesh_triangle.permute_points"letdo_permute_points(old_mesh:mesh)(perm:int_vec)inv_perm:mesh=letmesh=Mesh__MeshC.do_permute_pointspermute_points_name(old_mesh:>Mesh__MeshC.mesh)perminv_permin(* Permute the attributes *)letold_attr:mat=old_mesh#point_attributeinletattr=Array2.create(float64)c_layout(Array2.dim1(old_attr))(Array2.dim2(old_attr))infori=0toArray2.dim1(old_attr)-1doletold_i=perm.{i}infora=0toArray2.dim2(old_attr)-1doattr.{i,a}<-old_attr.{old_i,a}donedone;extend_meshmesh~point_attribute:attr~triangle_attribute:old_mesh#triangle_attributeletpermute_points(mesh:mesh)~inv(perm:int_vec)=letinv_perm=Mesh__MeshC.inverse_permpermute_points_nameperminifinvthendo_permute_pointsmeshinv_permpermelsedo_permute_pointsmeshperminv_permletpermute_triangles_name="Mesh_triangle.permute_triangles"letdo_permute_triangles(old_mesh:mesh)(perm:int_vec):mesh=letmesh=Mesh__MeshC.do_permute_trianglespermute_triangles_name(old_mesh:>Mesh__MeshC.mesh)permin(* Permute attributes *)letold_attr:mat=old_mesh#triangle_attributeinletattr=Array2.create(float64)c_layout(Array2.dim1(old_attr))(Array2.dim2(old_attr))infori=0toArray2.dim1(old_attr)-1doletold_i=perm.{i}infora=0toArray2.dim2(old_attr)-1doattr.{i,a}<-old_attr.{old_i,a}donedone;extend_meshmesh~point_attribute:(old_mesh#point_attribute)~triangle_attribute:attrletpermute_triangles(mesh:mesh)~inv(perm:int_vec)=letinv_perm=Mesh__MeshC.inverse_permpermute_triangles_nameperminifinvthendo_permute_trianglesmeshinv_permelsedo_permute_trianglesmeshperm