OpenMesh-11.0.0/0000770000174600017460000000000014620651625015431 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/0000770000174600017460000000000014620631436016134 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/tutorial_02.docu0000660000174600017460000000345314556675336021201 0ustar gitlab-runnergitlab-runner/** \page tutorial_02 Using iterators and circulators This examples shows: - How to use iterators, - How to use circulators. This example is the first version of the simple mesh smoother. Here we will introduce \em iterators and \em circulators. These two concepts provide functionality to linearly enumerate e.g. all vertices of a mesh, and to circulate around a vertex, i.e. to enumerate all its one-ring neighbors. For a more detailed description, see \ref mesh_iterators. First we have to define the mesh type we want to use. This time we use a triangle mesh instead of a polygonal mesh: \dontinclude 02-iterators/smooth.cc \skipline TriMesh_ArrayKernel \skipline MyMesh
We read the mesh to be smoothed from a file: \skipline read_mesh
One smoothing iteration is done in two steps:
  1. For each vertex: calculate the barycenter of its one-ring neighbors.
  2. For each vertex: move the vertex to the computed barycenter.
This can easily be implemented using vertex iterators. The mesh provides begin and end iterators by vertices_begin() and vertices_end(). \skipline VertexIter \skipline v_it!=v_end
For calculating the barycenter, we have to iterate through the one-ring neighborhood of the current vertex. This functionality is provided by the VertexVertexIter: \dontinclude 02-iterators/smooth.cc \skipline VertexVertexIter \skipline vv_it=
Now we can calculate the barycenters for each vertex and store them in the array cogs: \dontinclude 02-iterators/smooth.cc \skipline std::vector \skipline v_it= \until cogs.push_back \until }
After we have calculated the barycenters all that is left to do is to move the vertices to the corresponding barycenters. The complete source code is listed below. \include 02-iterators/smooth.cc **/OpenMesh-11.0.0/Doc/images/0000770000174600017460000000000014556675336017420 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/images/class-hierarchy.png0000660000174600017460000014372314556675336023222 0ustar gitlab-runnergitlab-runnerPNG  IHDR?WsRGBbKGD pHYs[tIME 99r IDATxy$}'_Qy}v 0}J@ I܇ @kwkگwZ% !!X$@Bq3}UWuWבgdWQ]U]UqT z" tL#?3CU٧;O#f=cc|ËoBG9^NUueMs8N` ҭ)v rB+}VA8ӂj/NO$r(}1ͷ2_9ΊvSƫss?  5 &;_%"Rc/̋r>S_.k~6%>)EٴW8syG`]]6aDt _/'H!"X_DlxisnQ<~V=zcj`ݻG~GI?$@߲&4P׭Q,vFCT"ИgY.m)2"/b9om{Fq2bө%ڋ=K |ƣ1ߥZe5&N &xqR g͊bTQ(s2trި OڧV=_׭e2U*)׭1ABz킠V2˪m{q* KRZUxOL[WglODt:#ĶJ|-7Jsn"}D#$8vٓ^<;Ё"DbD];KW%k$K1"[+RÓzccC&avʷL3 O[tngfPhH"~em`@tٹўe4mm(}#=#X|7 6U*ψb}w&h6B繹x9H$>R(<8 k9ol~g^Uvw5AKv|\>;{LDI331ck_.%:XUQn >'=)YKuKӕ-.$;,@_-Ou/b7om4I"*o{ՔfK[~SE.)|<ŝ"?~=d./ܑ\ǩioi jad9^mۥhq ~P8U׵-k*{b,~4VNOZνsM$>Eraq]4' Aumccl]:}Q>',ov8N٫x "s;V{y8q8UݑdkĈ2袶<Ӷ ~$?c2"%I""zѦfB}AݤCg"X?7YޒgWjDDwU z!>zr,kO$rl/}e(x[u{XNhc#C ady/FZ]vohb&01!;qfz :wZMl =ŷL-?46E[+5/B'}7oH.O+}!ӔsOĿt8zgCWv!W*0U/b[6IBK,ڿj_:1߽?nKȶ熕+i=1'j/t٩ [nx ~$?k_>Qk'x^ rУfL̹]*=J?;{m{& i 3#>ӌ)XVNb7Z}4vY׭5G-,+_oH(U8hӋ6VݒBtDׅ?/*e_dƕ?|j@Y((M3~lj~;<ڦ;wW =E ѕa-]_5\n2xJ:u6,(WxS sA׍߬,Ar}t롞;VW77gKOD ݈1ym8u/F.Lr-nIRN ٿ'oN4B=cؤxoFkg&⸢dƷuYJi?LO-.Ogfa m]1ً\?f,'^jy]?%"w (\ w /X^[O W$9DwUwkCELNDbdƥ^^KtB')!Req&3Nl$ DDM>X[JO$}6.o;G >:t˹P^$rTDqqHer%gysӗJc|{%i1 uk1Ƙ( 5;MEz<̤)g1'rG/2(=g^TFhzr}?ۈqJ~﫦h|]/ B ȁX~7sh}T~.h{T$zm>^_2|_ׇ/A?zsn_d{/QV`_M_3=b`L\:qxxGq֧iR95Qsd`*)7t"ΝdCIff_z|%ev¾`W2צm ƕDnp"NY:6%^YS-dVfn؜ Ik]a{ lֱ>iMx͛ēgg['AO5pVrNALS,åt]Vs]C7W}oB[iI˹\~wwT~ my#9Ck${O?`r~a4wD_L3;̟`"ˈ$BgvI\uz7efjq/ї|=.+NOD33_'D,vj֖,k*0^Y5A1M;,1JdAsA?e(1ݍ1 t˭ƳُOۮ[&e9XHQ6{jOkod23躆 d9iGtz=pE@oU8q~h|f.\!QR$ӫ6}F_2h' .T(yy~m=UFǫA"]dQ"тK/;nwMDcD.эEZ=.+'a$A?A> v@k*x A?Z@7`@j9G\samX=$ZcVQ 6Q @>  3۞aBzGnl{1&90"OBck8 L*"FOZՔ@D~8Z j`Q6qT\~HښjY"-5 ֪M.曶W-Y1a0(Ah1aX7LXIE{kYsr2l쓴l!玦̘uCQ6JnmeL%q`msD415]GMps0Jg"V_@U]bA _!sD49y3 j`b\ҖqQڃ  ׭RAIdIJԅ[M\iD1˜(IH˚X$P*""|qBo|ؘΏs;HU;4ŶcB $I1]?3sߖKՐL~X^<~V#dl$X|w PhS(ڷxJ&ϝ?P5 /|N_\(<Iyd2Wwx1G_,gL { h_>;{|,I33wd$)ixG0yRg)C)u6&oBBe$J(18$:߲&2&x'k_j9SzlV r6 }Q7`XF (kx;psLmǙuZC^EQu]\X덄DQk^IX.Q׭9Nc%"I>d5[ɹR~`Sm&"׭,yEccOM}$)kYMs׻^6"sXworM$JjY{4TW~䗼A2 }^oSko:Ni gSw?q,uhyׁ/t,gi8 Ӏ/VjconEQt)Rtj/U;GD-mɆٽki,NHRl{Z}0#9>{ oy7pyp̓c$o֛A_R1wh]֫hQccիb5~3JΦif ={>KK;\u=ݲs'Pˇ(~jťzTzw/RQ}䉦=޸G9.ROklJʦ£DĘ>(5=d3D$IɛR5o Ʊ~}H*uq=G NqtDf~ rnd۳^WfVlrGvj;aI$Jj%)!9۞p\Z׭[^Ӷ9-q@]?\ir\p]cl:U"X*x*IYg̩\nV8w,k"=T)1 JR:885m{:}9wlJ]ix#s㠖ޖBP5o "EGD5ik]ܱ= 3D$|A(icG4z[ڋȻ+l\ͩдm[#pPhJ623Z IDATq&sE،x MME9UNV*=^=5#5tpxZ mt 5M]?0lrʳoKEu]fks~DpTcdi:}ip76d27B^$.6](py̓8OOZnc$rzJ_6?Z362;C[UV<2eo-,3C?sׁ-m|-3b9pW.ƘV7Lٹ#ݺJDs~FV{9Rd, mL$>lD1 ꫩԅfBD$SMswR˜}XӜFO H]QL$>dYaHw[L<~f(Yt/xL˚mF]?s_y̓~Y$A#AU͉9f{d+٫5HQ3&2&JRB׏_Xx9kLO0vNjb ([V/t~DM̌l*|\Q}Q7Opu.s[ =7!~H.AA 3>}03$).I0[ف~Xӿ6gL u'Vz7ha]MQf~ϟN_*Ų9H5 0R4PHށ߃zd{P 0tA?a`[U0`oa 1cX1"XuwPpaL? `0A?A? `0A?NA? `0vA?~A? `0jA?>o9G- nV@A?  ~@19j`o^C%*qP{]Q jwޏJX0A? @0e'>aD?,Yssd\m|x i3qbDur gMAr ׭ Ԝp 6]2u:BHZ%Zt|לO+Ӻ q]jccsra=q]ò_jQ[C2X{gs†uB+}VA8 oJ]LDo]R-R~sk-p(" kŅ6E2Z28{"\-7J8Y/$73%2"~@'G ktE1ߵe e/V,v$źߴ>rVG{Kk3:AXwYY K(]g:>ľ` bwiGqn]e975H"l* 6dsl-I$ tLDw8DDD:]WjH}5IoT[@]MO*P. zۨ X ?.m_!XYB}QSv*ʁVd,䷊[>+P.bstx`%BD*)NUfaxCZ ~E":>&VR-SB*l~\$K1"[+R'$ȨY_jjN{,v$H<_Yt[BN\L׏wqV40z(hӱiAPA\AQdWYdYNG"^׭$g+FQTAd8|ܲśPQ6,gB T$.x7I쇾NKegW\xRT I $$%tTB׭@sœG+s;HU{v!8SQ6ʘ lJ$δB)x#y,AŰnM/pD>Rƈar\zFDĈW.'D8E^'ܚd7'ؙ*D 1 t|]ݝx@fHLHD ^#:(KlD*#(++?d~eC$)'ҹ*ݝbfC OPwfǖ˿n_9;Tz,ӶH.,3T<#]77|3:?oktHy`'HcF|uI mq8|x薜t켱kv/ByUjyTAO/9 ,{4JٖT&~<Ņ~of&?{nJYA<3l'YE$"Qg8Fff94ɍ':}8%wz}9c&'(;@$"zȠ{|զѽUӹ^ܗk8#lKMICgiDDOt;h=pƥ(0+i ٕ:.̈]X|(9THŝcߞ~RmWM+''o^v;};<855 px"2]1] @UjoF6{ Tz$4PEٿZ}qk[T,\n/8]?BQ|9jyIǥD^į(.5Ms2@T׭LO66esj8|Q8Ls,٫m˹-j2ye\׶W4{}>7CIJg;8\n$ehcF/;%OBXi(+5ҡgwk<7.eΥ_ ^T]ENDtB':&)S'#Чbvt,AeNYwksԾ 7h%5}i`J+'C5>Tu ,gav^"t͂0&B~z[~Ry\lfLb,45trKQ6U*ϩ6AP%);7h^\28 KNzkXIwd(?,˹d2Wzu57e} zP!;SbV{mjj(F/۞- "ƤjHR1QߩV_ V{yj˂29ZeZ]ˠqF/xoVxˍ7!U ͶwKy1RW+4F_1,.NUtD_^dB_||o~D R[>-w_VNQ8|45ﲭiۓ\P<0ړݸ7>ܬK'o ߞXCgfUQymzd5NlKReM{t腮Iic}ۤӗyzѓC[B#s;ob%:Nf8.5ݨYYDwU[_%w0i%h7O(=s.,DD*7G=YLãe-wC7ȻARYx뿧+*-)`ѯ~HgC p~$M;un+]v =UyEq;qyyâ!") B㒔Dޓ]Xd(~EPᣱbuzrKWn.#} IQAlUG:5,kzaᗪzpTP6tH8޲f3I}qFϑ>VsJQzJǎՠuS@/;: YmEul۳=? +u?4\4Ö$_Ӎ `tJ3HeUF;=K୫m{`o)?@8Ї`$ DDM~R[}`ha-I3K"^cr= 0Ybdn!.dM;ێ,w`Ba{T=K$D"'U/voU0X>%K|7YVsu=kQ쳮GJEyP.Bܚ:BlS௞>3!["i#㒔%y㝦5`ﲼav;3=ߘpn!H=N_R*=beWsh ű=+XD}M˚'I8Fo:HU99ŷLtmOyOhtάOk7_ "d#̜t'.EvjVON`H׏>"#{Lۼ?oo x_IjLW2&xcg1y_˰f`ZgjVgka!ܵ+d״l|?CQvs7]U\;UZ:&VGu2&x]ҀeJW+6'C$|gϯWzv)N^AՓ׃/ ocKGhj+=F?Tj񭄚vx#RZ}qi}(u}H׏%{s'P{0,JG^LͅG11=Í,U4[*{fznTb_a7+VX/.hD#FzY'@w ŒVb?Um?OϹtmI~_tUR1۞D(Ǵ""ǙSխ׭pXD4zRS"bL)l$i86v=fb$ 'dű d0{iq^DDܵ[!r]<6vm#rGѱKJ'綦mO/r"mS 5%綿 5ZeM5rukDr8QSYL "zҤz'\zFDbtT8_߰:^`nMg Q$"I5wCrs"Rg׵MW$[798 \#"*w\b''N7Gkӗ]<.ix"q܏|vpTc`qVf2>Tecri 9I&)l]ҝ~a;V/B]Ҝf`=U:}ip3䅍Ul6*=Vm3_ڸ3vDDwj=%y_}=EDC坯5a:\b[&x4$N+4~Bt̒ ? {$sU\1""Q[E$Ua:If%-C?1 /n;-w$Ž yBF5N_j/뚂,faWuH .ZA?e(1ݍ[zr{Rs'Mm-cgge,(8|iOD3N_Rh3[U2vp>w;w[6kY{j$!Ygf]~8٨`A?8  @-fuNB¯m?~D w!@0/e'ޫ m! ~<wޏJXA?:@@A?b}ށm0BF#V7T=Z jx=v;"~c0^[~ &ѓt5r7eE#l }%/ Z}&'oAA #8P 8^MN$r)曶W-YWS0^aLQbPi"I1T:8^{ohinV{`5탼cc?fcl9wtpD(P 8^ӴC'o ^7ڞj9"#o䉦a9jz51DTXAV c (k<$}&'oFsA @D1.Ii8 o'Dn(t@n-:OU H KRBM.t݊oLrM&DIJF"'XIJ7 Rێ3 mx,xEE5ߡ)= mE$IDn˚3UχGIRL$IGƫ5 p,ѴCOt/m3e( *ʦDL.(ldWuښJk8h "rR2y1QUE߶gϒ앺~$%AYӑȻkW^^6>#k2*lȻe9%(Uuk:}osz x-;eg?-(ԯ=H=7x:DZն#N_:59#UML/oKjH&?\,~/?Xau#dl$X|wPhS(ڷxJ&ϝ?P5 /|N_\(<Hyd2WwxWZu!/Y"ΘdEA+o<|v^ߙLRgf5xJ]?0-H4zV)yݧroOAG<~}JYA}Su?O:AgfxeR b{eyQjwޏUu#7ͷ(^H(.5Ms2@T׭LO= \ 5$)pԲ^jYnp뚆V8|0>ƷGpaH$Ӝp]q2" "k[J ]˹-j2ye\׶Wɜ۳7֟le-.oyQ:}Q>',ov8Num˚ 8Z ߒB%U^ẖ^Jd2 r/z`4/%%).7!IZq?wQd>G|ꢯkoi"=΅ݷBc5eey u"$]75u+)Z "^ѴmD$in 8Ph?׭whKKZŨ S"b=p7]z )-IJ.AКU*OQ6{uM]?\޲ ]G˿m^d۳6cRZnaL2)IJ֯E"W*=Ж떉V{CQ6.oymC1IJnAPyƒDiV*N#9BmR.wD$Lsw{`]<]t|[M X~;AefN_xuYo~&~j IDATL۞$e-k e9za5CO:0ž~۞#"QLv^uJtD41qSxi 1Nk-hT]K\H5x!;J\ lQ>GK^_zW'SS_EeޠhǩC͑^(\4{'1\>"PhS#]jAD^'h,vzKNDN ()f=Z8^-kџʽ<d{q,vjKz6vԗH54wyvѻ.oy {Ǻ{kn}' PRڣi7Ÿn#''ؒr/lpNYrZ{?Bc:N4 ,3|'tǫ~ez#j=6˚B\ȍN9l!qm-QTZU"R틚REͲB\ڸ=P`K?wRylb,v^6u{l+mb !"QkE_+ vilPXs|}4 ,3}'UNK'@rCύ`aeHk{jy]?%"w K HK;eC[#"5}z'Sw y4?fLfK "BD%Ӯ[eK K'\꘬wf/V)/Tlˢ;+gm|iJRz(R6"jLB%׭y( ICD$I6?D']ϹŹY‰VE 6fdhymjXl{V^fvh61pPhJ }eft ]4$xsSQh<6IbJGJDkըZ}!C׭af5OTU-[J (D}q>G^c39ss?"~pTv :^/KK '$"ds2!/cm_pAD[{'|'Jw-1{d9wc[vq/r_+"smgӰ$dhmUu[L=$Xf꺑҇' õFya5Ô0ҭkڡDT>;U\iyh2 6&6]hZTjTPh3c!"A試˘ eMU>;XiNDB J$(&Hw[L<~f(Yt/xL˚m^:]?s_y̓~Y$A#AU͉9f{d+٫5HQ3&2&JRB׏_Xx9Tk"7X(|?*Oaa EQV_q! gf$ ݏװ47B *:Fzƹ-Iq۞ y?PRaO`gfr$%)Jf+Z=m Θ8 -~r>P@.w5GUA?էH/ZCEw `Y4AuҨw( }iA%*A?aVU5D`-BO?~@T|1`BĈ`uA!h=>C@wqTZ[=ð x 1f37yey$yY< /pX8bWչTK[j_F*9:ѩSr?@@@@X sg`1v B?B?B?B?Jc>DkM-t@       ~~~~~~SZkjy0VJGbYT]P XnJ1      XvՆU]Vej;b(eZVo[,yi\okm. 767+{Q~B&simP(<8Z;"R-]Qm &/[K4uPxRWWֵ]v;B[jQ]-):RrIS9!ki=/5NrSNuQT:0pe 7T^LOв"a,`(M{EgI|2,\BRbxTr~OϦvםG{};ٽ""z/[sIe?Oh /RyZ}MDL363@ ǙUzv\@ {3yWDd)s O{ƿpf.ۍަoMWEQ[گ^C;#>UA CDnU* "ӎ3a4Z;šf +ev@}{B7XV0,XV29,]jb{/N7e&gF0@:{Sc }k[iqFN 7me D"GdW\=iuԹZJMi3*ݗЇwDD<[""_)IEb;iLi\U_9|K.rCLLGs !YNݜR1bm꾧_7'50;m@npɷ yH&P>R٦yju80BWyh£7FHDk6/}_NF"Gҳ[rX:wDD e^3MBR~^OF;ҘAƀZ=;y[t8|XVVyu~wr6{-aL3Qn7H eGj㖕n~ih躑;S.?90pj> 6=[ s@mo?> m)i"8)PDb6Eug5T*̪W,>."4:ݻo_;x08kYJeՐN#>X|:<rOo՗""[ތpz.Pj"rΘ=/ "T9yT:﬐|.D\8>_ڨo[FgV'OǪm俫oG.г]e ɠls =3O$弐ߛzk濫rń^+%+'c17}A{w`2 8N^@EdO'>GF0ߍT4ƴT*/l2L"qV<_Z[V۝Z̥~= ؗ5Х뇂ۊ s-$wUXhY#zNy/"ԓMcY˽$"v|5iN><57=!|2,uWDV""(,"rK}ff}{K=]wX(e6[Cc MRslkO,sΚCB.3VNo'MEq{Z,ܷxeZ0)D}S:@76rfHD&rGK_~c ͛rR'.Y愈HZ9Lܸ-E75oO̍?ŖN,}J[v'Oԟ<&(/jm l4VlOtuw&s?:94 ^U*f/d:R xғk;y'#gg|}^XFhtK+^٦s]GKj]ik3RT>j =Tx6wo/Q:@7_w2m\rWQi?_Ru^9#$刀kvǹ%n)JD˽_J |io_vCrkZl+#7v-ׁL`TE+"jXNfg ?<죞Wn|:,P*=50pLt_wn\~q,++"WCJܟJ,e ׺Z.( a{iA8V; λteԓACNe)/""熾U瑪)/IQ"W/ENtwT?5al9{suZWC_jj)FGo 6Fԟ~^k0v׌NdO*8i _˔ *QJ1XfK8;$'y(8n..`sN Rb"w7+STHP3CmX5ۋbJ\V2olb޲ޜWw\ NEz+ ÇukVW %{ۮ?G͊K&e2 1́ :tgBgZk" gܸZmlWonYs8z^ٿiFw{`/qUdu1lF~\w.=T}oD"Gԑy8}WID$ig860Ξ`/ H(tݒThjsjb+ZV*>BD\wvhh^»kEdÆZ_uI?I[VrWmXՏ[e^:U<-;t%o]]]ݑ_ݕVDDRObo;gȠ=bσ dO>u:jΞ`/ :7wo*;{W~GrwMaFPxLDL3O3,J9>~Ktzn^gfV][țN_Rգv{`opUկDV>qD;7&vmD_{v&r܏ZdI~b+>J$rl\Z+xW>"v>JE\J,v^n=7>bE@.8[D\w::(yEZmg<~b>(eڽnEljH6\.?yZmG,v|5>~n/{!%T=D.=[eW|*!$Ir-TQETܮ:ô'NݾԠwjrgFI|4()jTqGٯ=z鎼CDl{s-c_H2y7^nWDh;p(ȕJO<Rc8΄i&GSsrXL'NOJ!È 7t',_k]^(<M3Q,:ܴ=x{YXcBD䱪\Yx}%Q%7TہC; nVSִD՟' wD>Gb=ys@nK?UsrߏSmz&=0X=Y&Ȼt:o\|8aeWÇW* 7%U*L3iYr"H*v6{mdjj;x`pwjëp/b' #,bFȶO&ϭV$S:Xc{upc5}+2JM5Ǽ7.;=y;Kq2'䏦G.k;FS5kqE=y&3Uvsa/9oڵ?Tz&:VƫӿD͍bB弫ӿX{I9?ȑ؃K;1 B} U庼D B]ސ ^kr9Q*8:z:b A w !WEk%BbmN>rOcb IDATRrI.% wt]NH{X`%X-y')Х?\׶`Y|MZ6u=Tº `> >,X7p1T0j[gT)h1Na,뻼뷹E"+*iN+}TB{U"GWS.!DP ^MU`Bcd{t5Ji10o 0Z|U+3nۛM3'GJRmC clckWN=> s|UCC=jÇ(eba?_>+BÇȆ 7V=JOΝأy3ܜ;wJOS WT G'Edx34jSf²2ם67n}/<ûx^9~O(ˊeJF"y^ӌ)eZV*;V۹ H_kTt04'id2BM3vh  n4 0,Df,<`T4ze eYhJƒKf,>tpK8Yi2L3d%g9%m{7Zlk2{.oyn>:_K)4C)8qVpK ^iYIF bo._KXv50 <Ƕ7f0@*=h;eg듪IE^:mbNLd9%o5 8OGH&sM09Y?Ěcc]PjHΛV"qw`pju[I/~9кXهZ?T{&'YO!drZ;풐Jg|+g+ǿDžrvg<JY3e۹h|bӰ(eӗW驤WDT^n[xpaw5@>/F"Gy^ݟwONG=4I;Oy5꼿N_89y?hJ%?x5k{vO=k" nZ~*mZWVS #yћKݲV-nyppi&ƾػVC}ɍq[ q @6{״v ܇\yJh->X̶-uݒ 6wb {S&:`WQvpbO08TTmΊH6nY旆"R.?oÈTۛT0Z[w`qÈn^DvfZf;YVRfWEdpF_ucȱw]09%_D.~LCZ;JY .V_ UʪVG,+Ub'Ie%re޿v^8x08kYJea{pbɾW飤#liR.wE$Xnc.W]v 4s(TzfA8)P:ա~;kW_p@ gYG~0k=*;δfj~ڂH'";w~Lc!.mxoZM v4[dED_ό|^m ^d.G'^N GlDPxqRTk H)oyH&sc ⻈4~ic>Ju]O9<ԵF'qO djWkhT^5%n+]G\ X ^FAHo[aɩ$1M^#O.vhvL3D= .x\~zAX`t;," ?lW˜BFa~(O!\U(m?M/Ն*ejiĞJծf۷S듁@~Zl{աRY_wmu*@Exғk;yM=4͐UDJ-'"5X Xn{ #8S~軼k!";7&*}VҼi&B#?ռbO w _v50}ݶ'G,U=ȫ]a|F @ʊH6⓭#7Ʊ_kܶ%o-_A/5-Zw5:_JWb7׀hŧbgN_~y;pc~a.hWR [mL ޢ( ]PKur"w rki{sbĮa^38~_Tz*9R1bl0|5 k~l"yN]!D:[lL!9Q[p4:}NC8oz,>YRT}v8Zlξ,kpKcc_ qlp0ʬHy;pCDqLb)iF2?@`W'gbs.ֈ5uYwMEZ}u97U ײ[>][KD\wZnY,?ذv'~~С^v.X)"c^O(-]5k+7lHU^7ˍYzJC*y^S}-{r Ekg3Wˎ,;gtKZԻ<9:z q|ZRy_Gz?tz7ܾgz7{jٟRf4gLD,+3<)oyX㳾ut>Uz/Q+b3V?J5yk_z+"ƎPXoY@ 8m'"K4zl.wE<+ ]oq #cDJ\:ϫx^ehPhbW,{*@ H-"; mn3?1@D{?GI&pLbםutpPr2y~Kfm{Y񷷽v^Aq"Rx^EkV_*=!"}9QxmCCk]ӺZ.?[xX=3 gW,:Q+ZWm{ BjU' 85>"yHJ其Tz:߁WDT^i9`G߄B.(QkifDsB1P'NO'ۅhxc؀,oJίf2NN~uKQL.j0!ygn}wyֵx#m4Jn4z *=.q]}W]b tZ);SsA["F0RwMM};[=d}P(FDGo*"K}L=R@jXi~*~>߃`WVwP fU4SLn>+E%`#1 h?B?@@@Xusg`1v B?B?B?B?Jc>DkM-t@       ~~~~~~~`eQˡi ˕T֦    XL ziC[DpiW~Xote,QU[F*q%T&6Իewd~ՎaXM؛Y7_Ғx^0w>gL) MPJf(bǗݳv+09\)UQֲHrAH>T'Ȃe/ؙy}v=Xn/%,Y;4tݒ ][I6{'vUjBphh+M[ ؃l4iud`9/tENk> 8T$rdzt)~/E$~zm%#"XX|"=Zz0~e=ұZjSc]6jͦmh]\.?Z.?Vu#> sY5QOOF|mYbϩ|<> ͔2M3:;h"qN=۽j'>Zkgh ݠu5>Jd}&D"GЪ ۶*~?S(<—m|) n*`psaAl[ewuN[}No61=:"R,>alO$rzm"ғ"s'Xwr^:7۹DTz=Bc80Ѫzr-Eb%r-4SZWj{ݻW*0B;w~r]+V* cuLZu4viP!]Vk3䪈TY2`VO俪+%n1c\wHK%MG=XMn-.4Sɔ]S(믕}2,gvQĠJroY]tTDJ,[od•GkrsQlw@OQRc9~O(ˊeJF"y^;8xe$re% #`@ \~>8Fð òHl eRZ׆>rY+Ç+evb2ymo2͐aT4z\U:ظE`N̵3#iF F\7J믢i!ޔH8c+`[ǙL&ϲL3a!/hj޶ӉOӑaȱ[8)0~hob$rڜw&lӽdwLMuhϷLDË,V FD'&ֺntXd.zۻX(eRJ7yHJ兖ccTk@0_-NN30p8XZ:ެ;&?xn)lۛs-үzoXD53꩚6kiA\ŕhk'Gcbw򤣔lw I+1oAwyX>P"#?#ŒuqXD䱪\:1(FWGr* %$zӨڬnZR٦yju80BWٿNt*qsC=yk #*"E6{״v ܇\yJh-"RnF߸PhaDJߴXRgNGUH8|m[*=%sj>o.v с??ZZW*c/"[;d2߮u-ؘmu݂_DLCkg|`zL撉v #J]XMzSMeڙ;j'~r[] }[ q' Qv,`QU>QhE8'jhyޕ~'g/Iy&ZS255yg YCz@6G.?HAKE˯ke-"o .ڋ韛"a%g \_hnZ҆_䃓zRy[Ks(WDvgg i&[_*:wgg 1 fWpz;_ JYJGF\??3@]wvbnLg V* n}89VD*r^ƹuuOC #y#}gU'C-Rʴo:;ΨrB # XE::zS7oSqɯe?gSSOO_S:΄oJYҳ_Re%'&Z*=폙|'D0"sß3 0쑑ϕ4##7fD ZmC)}tRR-#s{37+\Πb-i~劈JD=ӒoO%b|E]-3=}F%mЦ/޼[Tz*:0}c[VzK;w~Pno>~g#7/1"҈ ~Z *|R{蟖q=;.3d2w5`zL2TO<~R5I"^ڹN͓)+ kŶZ2W͹ܩg鿚||[Zzhn[z>ᖴ|(*[TSoީ9 zVn'O 3leyK-r_e؍^KZqe`~uq&6l|ZmTD}f!,r8|Hf|` {&-kO W6ͰXVVFZʫc1qfz}@ 83mu~Tu| ++~&VuZU{ IDAT 6+Y+hylPZT ƶ7'@`C7nm{jU)_[Ry1:HD}+mj&_[lk=V_/]V؁J`p+S1//iӿ`$nLɩAʿ[9#$刀kvC--2M=#"߯VT劖Cu[R;$O>|;KnZa%?UmǿRlSnO/jx}e #Pu_7XV2{k.wm۫!gSiDugM=24tCS8}@#w~Z>ӌP{/{@D^&;?7lj&.t`j}[XEH 4RK.u' jY(?gOȫHۯ0`h3sAjT7&#1Vz͟v1+r\O&Ors7Kt3.~yW[3$"r_Sun +0OR JO 8+c;%";](Ēm9)N$k*Sxœ!"r.-h}jn )nI,vV-K"#gBĈN,vis")36=ǙVRGYugǿ`ʚF ddFRƦ|~X%@VDCsO L>~W,XʒMu8gX^a;lg"8ac=M1sag3㪌j`gBAN귌Lz7ee/jqUŕT"rYG^tN܍nJi9<ۿ4yo>`(ti4nd7d qb3?`^=Rv(t7lܦVlnV_~vS7>.x^e꧚p>%L㇑lWk&Tó⭮"@`]?6sX{%#[.5E^ܠ^ڠ0ﮍy-Q>a~|1ubS^ڠ^ڠ~:*9'E-}t/ js.7ښӔ2mKKRP57o/B=}~*+9'$PW=] u7(:Z/F'#j/F[Mպ3QTzf~4ylCutz:pgEb'?/tnsU;Yzm36vܙwKKzԮo0wQ?i=]V_(eySb>8\w*Z]JcǎsLn{vz8'_L>'7^߬O󩄜S$eșܞVR\d u-lwe/ZDrܙC0$ r%M̝|Ӟ(=NDjprϫhj;bK'69>~o0I&pLbםutpP$}2yS1"ypxK.wU<24t](E)s[]7*Ws֬'|BO7cyy*"%JLJs)0 mcق~YD$gS!Ԑ5i-jO 1~SnP˪""lۜnKIr}F%]z`pǛgJ$r?Sxk)7y^Q͈FqU4z\>pKv0q]wf3&&g[qXr ?8xM+ }#L7-XNf2NN~JE;d-U3HJb7ju|ԻL;9-h+_)j5nEf6IC°RGZ2#,Yu%2y!uQHwܓ䮒ge:)WEĀdIDɬ'ϹÊZԓޢ%j~Аc}Մqu{ݍJ4ka~0 7E"_Z3ՅckW1H؉ ք}pvju͊iƃb㇇o\l'kLJ9Ǚap;F]7oY ??JOq۩^˪X?4ᑑcjT*/gT^r)ϫF0ȅGߵme Y;ɼTzqPhsrwoV,c/cY Ǚ^`ZVz?B? %Y豮;brkDt4= K'd.*rC4o5O_AmأYTd2 "R7{ޒ9@`/: XtFNv=T;&?[,?q1e'֬d}{B?d}~@@~{T@@@@@@@VZS `RjZeJ~*kM{uB?B?B?B?B?B?B?@>)5OQ:(veZkZXfV *]q Z   ``T݀<~pB?B?@vF C  ~`7`z URGO?@@@@@@@gQ`QJQ gZk*hB?B?B?B?B?B?B?B?@@@@@@@:SZkjy0VJGbYT]P XnJ1     Sv6]@A˰+䮒0,+- j^qO)lMZ)ev F嶊Wo,8,)MPYҋBPXF Cѣ=Lmv[rvʩ:xB]waϦԚ3""煖ﴵiw@ED4z4=k_:} 3kRy9:D*ftm杺ߑ Q\^7vWN%qm%jӷAosu1sUT7>~e=9'JOf||u1yWVG+m{M/'[.fョ%<\3~mYbϩ|<>]^ӰmB s Pk_8|Aj8|3Q) GGo)y}'[wW!B}a!#c'ﳛdl8lu|`1lp_`01`@ 43==3}UUWջtt̴fު[oel#zw<`|%8}8}|p c輎=|Q7q>X{Ѕ/6J/uKy*13G/ZqtuAR߄ )QhQ[TQ ˯sn1-_mx{!j}8'[}5.>1*sb-Du70ģqvLD'6V#"jnfgۙP胊DTA$)&Wn2y&IAAx paa[D֪RQj5OfWOzd95UL@8Y $~M[_޲jŹ_i@=͇aQb3.+r|^"ҴͭY^;I=!_j^t2[ۭWVeGC|S¶[_ z<~o.7bQ6O oH$>|gƅbOL}LȲ6y!FU6׵,k[2;OV״˯͐J0&|c$WrsP*uk~DdYۃ3Щi ׭L^m|DKQ}jN8tSKO6lVfr0Z'I n?],k,km;ߐPlOB:*wt?υ%0=fw&La]W1"2>ۋ!n+չ^4bKglpz4=珵E:'L1:i ceJ Yk:w: 7!FDl4aR$Xe gWT!sO g՗\.ǟ5Rh.Ow/Qq|K?{9 ck٪i+yh綷PSD >9ǔw1`[TujrݲH݉yBQ/kִos" N矫$@Dʸ$N0:z~NM]m''׍~~Jܢi+|CJ?t^d9yE⦹sp2ymf(jwBY*uC&scژi^ZYڲZ퇓W!fM; P\^n^X-7O'y ODt[T AψkE*#,n'(t_+t8oYh{-d7/'J\џO7 Jߋ2"o.bcTƈhXwBa1Kjx OM)޲̱ĎQ(<_Oi8kBDۉ3ο6Z||C{g_Q?%{SB'-"H06-|*v(tFcc߯_vk}l1D4?JƷtR$"oq{+9> q'Wopsq:g_9^[*Z[庵háid;.B3`*v+;l`ˀ2zLWM$~"2[:lsQZuj]]Qi82u׆q̗7PyӴVxsV/Vo:Za0_1ܢ*-msu!; Q黥1ECݚvPoUueKD^2)ʾmƖ9oal&Z_sO >cc`?3ink>s[ֶ 5bv!&=1!9An(snb1c;qmgm{Riz&V*9I4,u Q$E+lu#do(C3FFneZK7ryS[ڲLs,kUe޲,kGs M=E٧l]\>6Yvm_8_wv~fG| rQa#|e}XD=krӿ 2z!TFyN_ktc~VmG_-O7]3 )itpuըK4q?a٦lu%'hF^5+L|s'"TӒva΂S†U |wUl$%۴&Ϊآ*Wk'VtSuɪ\ {ÀB̼`$outmێmV$ʚx.'<8\2$I@}-EKەX4z7i2*rV?LTd]?M6ew| ,n>ٗ7}N̠KD~s_#Rco?NDݪbt0 IF۞t]<~tVƤrZn^=ku;%b`r Yh"0o>S^{/{ԕsR*WJIkWͻgv K`v< ?6orOy2devLDov=_Z,T";H7lt5п_7t{j+-~/DžZJeGpud@9w,]z4mUjOvyV (v;^+r<~Y>APL]c-DdۙJe,uj71W*c},]dJTm'qj|,]s-Je;E{*[ߡD8tz]"1ݿ^m$tͿMnX۩TGޣM׏jTj]o_aC7ʸ9u3.c!ό hSSO{um-NCCia:}Cuw]5?soOenirZ>Umzp"NF=\< {\ki>%[B"bL ٍZzX bewL+ e8΄7ݺc7?ȹ7?:M"Tz9:%FGoz?xzu0u6T\޴knK90dyF>UijɆf}k+6+;;<,n؃mKND*btΆI?ROMB=tY]}Evg(%q:[@2*fkJVw%si,TFSTJxЧ/IH#DĹ/q ۞.G"iu{ӛ~ kxv[i8\LoдzSS[~ѩ["r]N$r/蚶u|~mgE1|fo?L|+Q}`?kW~:69w"}~DAF_s){6*Y>?o/pw]gR?ea[C_ %:PbFR!GDsiVw" "Jt[mL(*vc|x\ᖃl0&F7<ͲяLLvZ([_%]_m[O`˚buM]? 9ҕk qVlj<٣ȹx/_!"rՖ矯uVgY&A۶0mkJ$^sԴҫ!{*U,WM;15N2<;v0_{&-'tv—K,?cѝEvYVB I(AL>JW)^忴z.Ɂ"]㧓dT"Q¤K<>X#d DD.B_;r1N?,OD3_V.o15Aw /(rYStbKI$./^T9e9Ge ĖCmOɏ\H$rR׏fdL_l^C%)쥺ryc[f\h2_nm;뺖 hVWQ/PxѲnD1(FFnL.d 9_eU*; cA奁iUS~edS6Ѯv8K;/tߞI z}{Mn{Q(m{ ߉Qs#BDC} ì,u^T_{ag鵧3۽tvWp ` 3fz񶛻׆Vc'XbVJ~ژ_f"bLd<Lru-oPpccNH 5tm?\yd~YWq˫8A:O> Mzc(KWf @}>]Z{ o~έbysxymryS"qMem+]|CƾH T,S}allf}W8i ,/Gy9} `Y|'M `/' 㜣vɘ1T,pH*"]JkGP  B? B? B?  B? B? B?  B?,BsZ؝'cP !1",+({f~@@~@~~k~@~@k@~@~~@~@k0a9G-t x-19j`wC%ĸI.r݅X&xء{B? B? B? .q&OJeqۂIRTUg2UnkoB&g`W|*LqnPu뾒v]ŮD 󟸮!IΝ>vt}̿kq:>çfdb)ϒa] xϹD.hqn[ vj6brnS@@{)a?Fkԙ';K%GNM=Y.Ѕ**hJ%ù8%lV XR"*7㔥D]J3qD+;$W˯M_[+ofLr%-0$"|'||?O&zXֻĕ⋎S^Pi}$%hƾeѽd9f]uo(c /́=UˌsoSU3*Vet2.Lv Px`o#I"Ao'W'~|q&gCnCe>LLosd{T=I h|J:L#P]{DDusʈh;]~"^ ^mǹ9w]c,_j3[.&WQ]{-ʸtJ6_":KK,@ס_އh@X;qI"΄BT% $I!]?4_9N>=W c(j4>ݶ:1,F,v7AA]캥>ֽ'̦0͊W=Qe1&"5k9N!^(&,ck]椴1xM_}8f\t>9ˍb##Hqp7{\]֨y%Z%ou7۷Bպ~$EAYqMn)YKEQ5 C]g{s1@kt:֛2:MkI b"B~`CeZ<(]ۣ$86Iv2""{~`OC$J`b.~}V ;v?EYe~-k''k\TzMVxbі)ʲRUQ 5<2}5Iإcco.[C 8ΔI_>:znjiy7ii6w_?+emk7^|73q>F ϘL&?9:zks ;~GqU].oCtbBOd2\Ξ %]?4iY`𴩩'[0[~[k`\wMއΏ&{BG;^W34&Z,!ZgG >c!&*6ݐC0,Qvz]od,yZqqA 8͐ݳه|ýϖ^6+>oe8|V*9cO&98F*4 Nh>2{sGRp]4'"_2>~/Y^Jsڕh8|=>~alȇtMsZ5^$2;OQ׼5G]Vͦ09\b7%/f޼^T\׮Tr8Kqr~./pW?Ҍkwi]HS䵶8},}]%5\'ᱱ}=Ѵ˯+##ߘBgzZV;[q]3^D?H||CTuvۢ9`wLo:Gt(_׀?Ϛ4ҙ*S4#:[#/hG1 F#q`Hy/% h\^bŰemoyn60ɞ6m%ɹhP~DݴqQՁ u߮4hڊ> )~iO*uC&s\晶 Y0Xp'㽩ġc|0K][&OvyLgO LLt~~g& ",ˆٺ9}HeߌmiXYtU7p|1̮_^&=@7tؽJ4߉D1oemDP EP4s2yͮM\WxMw>ӏ/MC3?}ޙqmm;5*7+"z5S͹3KK ǯ4dh"RSs;&>y|Z*2;K;'},ݠH5 ~2q?JƷtR$"9/daǙxdĂ[޾q[ `wkuɏMND5.ƬJ'F?U}͇UlLГt^%z}[{VCK? q6Lsaao{2&EYe[^)2"ؠDizV*9I4#"IV*Y =ax wKemմ]V;Ϧ0,oUueKD^))ʾan@S!M1t^Y4S}}iEdOEU60mQ{2k(9E1v~hWYNvֶ'E1ء};0 "Q Bg*nӶ@`sfsߦ;JfqT-Qʸ<)DD'eAFmw '{btˆ(o&mFxSfDTtZaaS##ߜx02w͹rzIJaz ˓8=Z=sGǷvDuxT*yZTj]0x. ޢkj'Gz?8cT=S%-']Mզu[ZYP:]t?AOOd磸$|]Lo>n㪺簐SSOzqeH"R[>P\o\&?7贺1pVKHv&6FAC׵vm*w km._d&s{emuœ29w7Ϊꊩwca갱HԖk6RZn Rfs(7tN> )KLsG(tfL/d2wr4j 0h9j/~Dt^]s4" "@L]k;Cw bΠ|j9f-d4¯w5y'NsjnӕfY"!8\hۓk{sݹ ܡЩ^^I/G|0c Ϻi-}ZDMGqFGoeL*_{||ROvβG|yqd[0in&|OmNnmR(Fu9|%D.o v(j zr(̮uVxoh{żUnPhu8RGqXմ]l;Sn, )KهJWm{6_[0 2:UaDt 8]]Vl{C&n/Һ?~?Pŏm8EAL-Q-LZͭGKϷlkEYy}+!PFGl5wgY݆f6P5_p ӠT$5L-vUݿz`~M=nQTJ#"]?|~ 2&4I ~wZ0Qu >ND~lCij}*ɈH$2bv;k!s{cY>%-"e~DQX{DDIJ[gjɆ>Y]15T˿b |Cy+Q,viOf񭛟܉FϛM]v.8;%Bgf2wazo|>89JZB"bLo︋:Ds'g" Qܷo ˡ)3D4:zح IDATRbrM^M7ɋbl.vZ0qDk5b]t{軥s:?5.Sf'L""mDtꮝFW~6C(ze)>2&NL6,t$^2͜[kR|^ohT8|69ΤHֹnsRO&"׫ "TF}UuMΝJeG pB*bx|G{S]Dn1[I̦/7چw3Nwajϰ&WugZGs[_8;=]* 4+1d=U={(ֶs>J %qH״Ukl;+fSZo`tF+[)8:_[0fҥg-dtiإ~M{QJtFadU})̮էZuK_fg2W?>u5N:}} |.dn{uD5PM[Y**_";9?/_^ O._hs.~(KV_kͧryc}_I,'=wby~2QA]Q T*cAl-x7kYzV,vǘB$r2^cֺ{>6:z[G7]HRdZpQ 3&2&JRD׏Jn,~3wz `aYopwk>.+Mb\3v&~"0h7h!iC?69쮉`!6.u|4nK= m釽Zx_6? oYӃ{2 "P{A#ĕo5*  U"`ru-oĘPb7D$ᱱ`ёPfՆmguE_å+ދ;}@fX\4#˛|k#bPVEZp%moK?B]C=?Nyf|e ts.6,6-,ϛ;A%챡;      B?  /@~@~@~@@~@~osZ؝'cP !1.v`\w!*;A%,v19j`wC%Ĉ qܲIENDB`OpenMesh-11.0.0/Doc/images/halfedge_structure3.png0000660000174600017460000001264514556675336024101 0ustar gitlab-runnergitlab-runnerPNG  IHDRJsRGBbKGD pHYs  #utIME ( %IDATxwEڇOEfL]&I***bňʨfQPʽb\KPQqMwzܦnLLLO3U_] L(U3@ d5f}sW;h"_}B=~Ͷ,`gk[79 W)G [ cms py]瀧h 'i?׎DŦO XV&O;7zN[Z;rIrBEɗ _ !mAVAzvVgBE n+؂<=gedawEI%I)ةؓ ~;[.Em)+I؄NG<,!@/UR@' -xY g?j=g2LPl+)T^R_d w{?մLj%,'83\@kvKUbi[P$A=am?U8X˺ x-ء\ˎ UIR=!m-8$l# U2B/kK Ӓ$aHF\.ċ}N 3HH=-[p$m%YvdaJY x!i͜v`kɰ+檡\[`\-ٔ&kk6@aN oiق+Tہ|۷} ؿR\c8Y$o<\-͏#or۲ G`Cq6p}m߇Tnف7TN֕a v%B~-I`=`*䏟#lR"N ?ھT)rqmhZ|t qce[PeY k)c XVy@7s`(`s));0M 0oG@7ca>a-yn=BRc@)yRqjn}v a 5挑:] v*Jtm":PIq6U9TJRC;*ECFC%PxvZtG|ޘQXEg}iLBlRx-dp;\>{h:(gܿ\gp!@ISvjہp;qÊY5thl) ó"u)fhzXFabȱ AB.|nقb sVNLMZ=C^S[F9g볓l'ztTpmDmsb^与ӀIpc9X@"QRnpI!Z/ k=O[ 9-d1(EBL)z-hFl'[lvݟ{15ӰvDyG )k-,* ޖb]\i<;PK%(װMS(9/lXUV[D8 UK02kCy'`6" 11} LcX5R&Ga) 5Z˦BC7+G߹Xj̛}5kN j kX( /xfѼ1M2L%E53LKh =[s㕐lMՒհVck0n5xۂ!H`=EF[m1[t >L)> aـerSʭg4aP cib~~cf})E ;C[JOY&Х, LޒAG:Dhm0 / JGV>5\`:HFkXc:dULKQk a9BPkE naY DJ>;sp6֋UJ "<[aۉh'ii,4KDb:mtUK_1aFG t-;)Bl5QY-%PA@QưUKQװְG D`nY߳| ~[㙚hY `&kHÌowNrPTrD2i "SK=GafSC[M>XQ^}F bE]3K4KTq VQTUTUUl`IWatF`vM{.o~BJ C5° !9W*2me fO%t޿ l4@Tt6Y,DI90"fF)X*\݀wۻa程ɵNki1 **G[GK܍Y<Yz)<5vPlKp+Wހ$h%ts|E0{UjR6=3 1߻ԋPD׈ Fih`A ,O7,ѝ"ڠ(`oqKM`k|v9,߁7D׼-6җQ&|CȾ'] ck5ZP_(C5!*Zq4&Jˏf^LD:Ep݀Z_qAX "5j=gDעUk 5-4aKUfB~KQDj-%' 4PR*%t ~п{4 Vb[ `BKP-,m"CQB2WZua 徐pit@!aRհIWw;P0=o|vϹU*zȏSI%Gzz̰N默'Ry)eE3EY`ChXjь 9Z߫5m>Z2o un?̼Z-0 "N'Xۻ8n"B \jmk-{YzLZ0Pض`K{ ]&( ;U'E]f`1ثlA- ,t9aN;=닗F 'Fx(otp[I;j1u؂{Xc&ʈS+|v;3Dj>*Ufa0S12nEw(X=v}4;;X}Jzz/`]0]3taxJ>wh Z϶a{eyae*xs PI!fH{:3PG)}1OlbzM'iNM\:Y0ۦDL+#! Wbf5{ǵqHCZJ>,hV ߩp 3D{YOJi =ҭprښ K:VϧA']@9" RLZUIVX!ajquTQEWIan55b UV@^2!E4I*RFH!e**R+NH0!Gʢ(o (t笡Du^kbc^v贐*vb>wtν+g+lp@=37`|,0Š-Ep=^$4\IcM|+5F/@'hbydA!61s*Z7=E$0ө T#iZLry M|XXOC[x TFZ3`zdp=|M4`on1…~.. id0xĉ*JWDD=ުqt}>I6C;4K_#Ua57`F9rji)WÔDž˕I~3fGLd,ZݷJ֐#7i,,-,E/4p @RxS4Am/{pVVi-ֹ/0|qwOKw m0!Ʒ2h~ mI /kARu6\NXN;w~dkΣ!4QQgSH5+,D_us@df --*u!.=Raiչ&0&˭]l9ń 6q.oHԇ մ=@q*?)G'S&\y}Re U+4Qa,PډZE=FwKSC&?uBUm@^.~vbǞ3: aRѯ i%WKsGc8WKs'K .8Dk5wۯ\-D":j2uC3㗀 ?=!w\iO`E_w֝g'2agC) R|kk'$U1|z~vVqMo;K0\\7؂+#9!nձ;vj݉C̢QзSzzR8H{eem؎Vf+  }|Fu>HL.m)E(6qܺ{w,Fw:7C+6 fBvoҪVUq\`,d^y,}XyϪJZ[3JbkϏƙ2 ߙY<2 VSWi]ޤ*tzzC^ԢKɃ#V#?rL w!Å3'򊎴W63#_vEsGINT$}?* c?v׊|j4oͧ@0%A(TGvV~.MQ_~xtAcIq,2~U;),pHlKH$%%2R%W^$8 =|s6f91xE2ok# k4I$wCRp8M_1hBߓ-MCesCKf%KŇZ%.PoqJTp&T@,#$~v2 |auۓbZ9i'|zM[ Y6ͤN5gGo5Nk L Si^&>_V*/$&SXJ68 Mk\5[cgHlL+o4INMaz`GlELL D9uj%tiP(J|$6l0 Q*ZZQ[΢Y-u;TɿI^>Zd݄՟SEc<-|o]abAj" UUUb7Jcp!uN[U_ب kٲ91%?yM ۧBl-&X5ζ˶$:?=1[ܡ ˠ%؛= j6͞5T͠9;TYeenYOίRԺ43^9"ו6`'XkQ+:;aR,[{DEyXKk.@XV _2M-ޯFII:,P R}޿Vlh¼Jk$gd},R#Wb|l55,+i׷% ǚ+uMo~Kب*ˏOE^.U;A1A^"Xa5D:ZB@?Q<ȋK?d5CvٳQ;bF9K%6Co x7ҧXttWݱ13rD\ˣ^<ڱt)yCo>>rp5~]KG0gk;/O5d);1O%LRZi ~Owu~T΂UR0i[_wQ3fYw|III)߃ڟ*Fs&ijX]٥Whsg#}`q<Z6 ŃbW^&_Y'qrrJe ̢ӯ<aB!t]z.z@D;}?*מ~fO7j 8WhiR wv~S붖pH=rμsEDy7W PU>F#G%okymmh*˞>!vvPuJsINίI.5˳sIf~ ᨫ>ex*ߔ6qAݩQn&c'B@dsP픉„wPﻐyzRkѓzy60F=&bz82Z01NUHKTp+ ךɮ{|xaΉ>6]bZim1Wa<}@-'|YiYv"Bݵޘ{lG^_p }'on0Ds?;(ٿmn'w_ڊ&jէNU4d/aM /uO5v<*o x߁g8O}+P :i?W`+#)1+ Iٳgt^xk9}/I=G8[ ǚ9;evEl]ڍf0Sj!j}Kh_=v3`~Mm_JK4*/+?/ݻk|d⨵׿82J㶴f¿MB5Y[! (8UWi zkAx㪚fbhvY d\[CGSD]L?(هY4(zrc~lCIJ{"Fc/ڋ#B]X?X֢f|=T?n jlP92s1a>EcZ.B tX.Sʰ3^F& ̕ Q&<|JHeSPق]K~d$j$x\;ׂσF58HTі+)mCA;)z* N@Vu2Mҍ4IދXt!iwJ9aJ, <03rD.ҌD,ܲ0> Q}ѴjjÙ)sA*GQIt MR # I{ =ihuE B>qm=(UoӶ{ԑnn4:$=qBbD‹>di6TF_h@-jŇY3}/xEHD@Mj$DuOyF/Й3Ty+hT0zgTco׭  `.^NPx4c '_QiOq2}Q~7/bތq!ƃ+H7jZ-{u&Q[+=oIhw Izhwa UNj&QO mTxEɰHaeB >n+J#JVցHԷh>KcB9qImJ Q[qTB = 0ƅs+Иvu= *,D(k; 5Z N!ET C"`!6Qg!\#]_PCdv)8$`5%C_7q16>>3+%o1.?:?u\8XU&`iR=eRl8 ak6E2Xm=u,Ԑ, 2gM [qFtz=5,X 1=I*:+@Pk@) Kp&tlƪַڨٌ)S1k[HȄ< ~` O쁛5q_h_t\Hyu[{%!RM3GL%'հ!TQ£d8+.X:xpHL!hOA^/7:-,Zl-iw$Fq58^\:;[HV\+8cG11 fP `/w;Öy{~N½ڶH=!PƷ8s6L88SX?`[@$$D5]Q-b/_W`G$?3.KqBp-;^kB\-աᮮV c̴h4%wJKjȂMtݷďt|Z;pVo/SM1a c,&f` Γz=TPUxbAoWi`a Jn!-{ܗC';PPA0m VkoُG@ȩv](-QxWbY8`_>~7%,iW|l/>޽45B h@PR8 &OFQ!|a݌a2]) )_'$": NkV(n_7? jҠ2h&!S$=*d=QxEvhð|yBg;%jlMtBWW{Օ Q4f(@/3uBRBמJ٦b>c([(RmC'` @2[Ak"phz%,-)K5Wki`)1HԞ$|yUIlXV]Y"htzXL<㈢d#v.aNTY{}*%op֟WLC-H?q;SX NovJI;& Ǖ[~K 84aN7hMx,\hXGyEoSm+Հ @@eU^3;K{Έ 5jr ,zXZ PkB]8@J92kP*P]Ҩ" F]spb~q :}'Q{b\ɭ\\I-2@Kb2.OTaP!C+Q;GpĈ T6he&E@.SA.j۫J f 4eXa(x; 9lY/>"ӓPUK=]KgDڟ+R=a?eJjd@$ Eͅ05硱z̩j*&8L #mNE5ky" -@AZ Yٹ}%*YTtҞ}jiϯB x}\K*FYIc٘F$+y+d8ӂ6U$yȪ@< P vW$@'@ģ>֨Tagʑ30HE'GQ(IU"ZMnIlVC#_01g0юJH(Üǁ$qdӳrDMj!mf)FZjתa&2V P*Q!NdAdk2n2מX?Fv52+o$@ʎܠGQ ݩ  1uu{SwJOi;AI AٌDIn@zecXd"fy r%y:x8+eۧ\(5h/QSƢͰmHVi@XN(Fut7n]eKu-*n[lhz to}GL[l{&1y?@c{.CnB\CW]/Jp# nXr3<mMAF;tvygCn) +tWrAOtŕ-6yLˎLé$8hpy`~\ؓ zDjX@fa {CTڊr_Wf&qHl:a=m98ӽ[qx A" n/A}su*4$WPlDc=.l{&ѐ~IVjd,<"! 5Z\ _~FD&+7/PcU`b>Wg2q-+bͰnc@_xRVT7[ 'UxaC%*@e';r0Y8źoTij`!PXŎ qgX[ۮݜM Gzi-Z4XlRLq3pA{ nu0e]ـ&m岺cu?ӹX;^ 0'Q[JʄqǚƌRIץ;)Xe,,}ugl4`B@l,= Mڊ(cp fmب9)ڢ OeV.+HeF\/Pc]xh!dI}wZ.q._mҕx8US1;\-󶀘Xw5$pUB9?)P UA=-<6p!aj~"E Y:Eٽ|owY/8gi]şZxIic_Y#x`nLЪY,,6l xR,6Ig.+p\~UCL껻٫{q0blY1炣P ^Fj\p&YӳBns3zhH[\Vh%G~6_ Tm.GW:n;ngbAXHgef)qȮiB.ϴ٨m}\&ZPn&Gq;BQ)ܵێ|T_RvD}– sI^2f<FrT-JvʊYz\.s5&4AzU0Sa@q\5 Bgn%їON|QS=} $(d1Zo R*zxH,OXȲeEThPuP'G&麧_(ԋ bؓ+VOIՔkX )CG3)װʠi*Mrc )p{%&ɉ*\9PP9lkE##G ֜mېM&bD=EɴMܭ12 ߾aV"տQ?EGӡvSdbO">`huN6~ IkcV\CMț N:dVD7YXD~:h׿߀ eЯV~ Eg=:Hvѯ ]-Q/Xj6;BW~S(~֌8^4Iv##Qij:dC k%3LlT~ắgx?o2~waRz~uʆR4IK@Q>M#W%<[qJ Y;z93/J BRPy*rE%f͊ F%S<-]!ؙgY 5ۄ)D꯶\.͡,iFۧ/ii`B>O!&%)}jϙ%}"⣳+[EЃ*'@ǩߴb(x{p8~Y@:4TPe_rlX4N6!P7#Ē  j۶GYtrtoUmݶ%bKk*O5Z_l>PP1ôS ݤ](瑳z{bI,__%𧛘w$<}:6?v6jQV<6k)z7bD?隯/_|$Y>E@|8SX ! Bjb‘ieY'wF;U3P?f7xzi[G8a;zYR#37}~hj;rsX(t/Id۷(_'!|]HsRGNnATkOgG5ɪjĚRxx"i>鲚.;`A(%n!J5hkCKTZnezqSJK6{85lT՝ԡJL򍦼Y p/A{ %ѝp|4|}Vж4᩿Jt1^KmW68tFPkJ@lHSW[M,Y?Zrwl`=׻ν.yi}/ :i?7M^^z5jW+^FK^IWkhnU׽dV_g?uWߓ A5J8 l~ 9T ~ׂ(nv~YU1TkKWFŒ|A,/k~xƲ:T~>9(NYe[jI$!TH5unlC ؒI&dƐȯ;J> +b[ѥK<ҫ_oklƗ:D|[*?L1lM /<.9O^ύi-v_7S~W&P{V~g{;)c(A[̣4Iaj0 wsT-$ ҖSK@o ڊ[PAIiX>{EO<#r~-...H]v5{TOYkR<%'vbiAM _,nY6\F5h(Q6=n~+`gŞ▸*?Tvu`e2)3J}[f:P%씝\Դ'~xdьkz> 5$d}ʧdb5-je=zl);AY:G?{ G#;V>*xTfv5_IFRVRm۶z>fqH ?>IekȞ?th|,Ԣ1?fo{]RCg>L\~#v.4|8 2M鳚$2֜^ v©CX4[OyW(9*cyo H "9o1=Fҫ_һ<>qr!=snUV?*h_x&RY4ld\}oAXoh7nY9vlp| xT ^nqG^zt }5$ M镰~ϖ^I)Ko3j6ҶWw}-l苋*{XӽQ:-."+mV( Xkz`q9VSKZ4ʱLZc6Jpc!x=,$Yz VTmlP:iRHfV) ܯQ,XX.) r \v=b'nrɜUOYnKZVjBh?JOC 4IDAT+2/+~I $+~6 ikZP`ϛam jaڱ4z Fڶ腰Ƶh4daHI7QT6⛴JX|qYf~0KO>|T҉@ᦾZ[^Ns,xjʏNdִJS;>| [}v$fglg%= ̛7_ߨcݵ#bcb3}ZB[U'SPTjsDo3rݳo[͵͠Mݏɜ*6}JǁڎhDZnjc;Zzw?6POF%aW3)c^nqPkƒegH'+H-D\PP`m@;O֯ ț 7C$ q*~I so0 %g6_,|d飗,dS„-F\v&irfek:">|Xض]OOd rNoOOOAii&l{5Z.O+)O+Q {AɿI_JW5BT_`ş\̈́uuu6---...-+gW೔tGO_ѣG;2,ҙduoKo7ٕFZxW*?vRWZik:XevF#k;~Ytɬ l)RQ&$L3dq|ق:Ԧ4m[(5IcB8[!+zPH _~[BE6;6X[veA`]7/9ݻ|>ODN|!i,[Cۆ {[RF(GXA: |O|P{wI i.AAAALڛ?aIENDB`OpenMesh-11.0.0/Doc/images/iomanager.png0000660000174600017460000016023314556675336022076 0ustar gitlab-runnergitlab-runnerPNG  IHDR zX=sRGBbKGD pHYs.#.#x?vtIME  "iL IDATxwxUl6$zP READ)( l<""PQQDP^PғJHa7\/39kc """"""`v"""""Rp(((((((((((((((((((((((((((((((((((((ؽ]o,RDeY.ED (f\]vraq:.M#00~1i$ ""iǒ"r խ[;vx n駟?zCD@D8u˗p馛ԩ+VTGC,"..]v1s =BDģ@D$GcXbիg}Fڵ3ȵwoSOׯӧOFi"R@)Hq5tʖ-ɓ'۷/3fPEΟ?Oٲe૯rU"RP(HZp!;wz "ŋ)\0|||HMMvI"R@{@D$G5 Ʈ]>DrxrE"RP(H9<{)|b_|6[ZS`^FD 1ׯweʔɴ'r[ի֭[X1uraر#+Wfĉ9׋\H>}:eo3l0&Oc=*WF5pgΜɰTR<3-[}q 7dԩS,]RhQ>ӿ-))w}vs1f%""1 ""9uk_ѥK֭[3fy„ ԯ_ڵk{: 2T^~+^zd.KDD@DD<̲,~w,X@˖-)UCqp8{ٮW^=&O:IIIo?BDDR^zi=m۶̟?M4Ο?>ӿjn{v눈(xXBBW <<5j`ܹٮӭ[7t#G]uL2~1ydZn͐!CVÆ ]6'Nŋtؑ!CPn]V\6ΝK=x뭷ڵ+zrU->(:ue˖9~nݺ1qDZjӧOQFL4֭[3vXk-X[on6m`Y:tSN;y."a@ڭX>>>W5x\=zdN\2V"!!wEW܆eY|ٳ3f0|ptB5طo{ʄ 1bNgѢE,_-[~z石xbx HҥsכDժU0`|kTvmbccٷorpa6n#Y&G>iӦTRf͚LVXlիWgѢE<H1""93̩S]׽[0SL޽{ `,2WZmڴ1iݺueڵs~z?0cǎZ>>>06m2t:MDD̮]2~ u3_zueYϰ̙3{=|^tӧDDDd!::f۶mk *d1|7̴ Zj[O-X""5_x"*Uv@^W_q SֻPpa֬Ysڵk%>}:Cm3gΤqtv/˗/n_ײ,wX½{T\r(T6mtMw#F}#""9C`xXɒ%FyrrU=ѣl2u\ߠ޽{wK"""\2K.F1Ӯ];Μ9ݷ:eTmdoY5b͚5DEE1w\֬YCDD#kk׎ٳgg?rYBBB?~|i |}}j bS@6mʪU7oN8@g͚ŗ_~Ɍ3xWٰacƌYEjj*%JzYAIR2wYEʕeۗ$ *~ O?ĉ,^{ Я_ 맦R|y_w†H[DD`֬Y :cx׀ |}} eܸqWb!%%P*UĆ ] WX)Weq e%&&^zQn]6mJV֭6l~)±cǮm=@DDB <#$''ul׳,I&ʜ9sA/:u^nJBB~n6lM,N8EvsyG,ǏS\9zͪUXl:ur}뮻̙3N˲9sz?DDr݂%".5Fk1Sr1nfN:6'Hk\;wdh|_sI m!CSOQjU *-ŊɓԩSǽ%Ki_i=>>>WϜ9~퀀 m /nH"XE`` +WI&3{lVXaØ={v}ӢE ̙^7555#""tCݻ֭,=nnL>}2vL<?~ܜ?,]Ԅۛ/f={bŊyV̑#GNrJv ӣGSdInwn 殧o߾0f2ׯ7/3gy7 `j"""̠AL:u `BCCoSO=e5kf`>sQc1O?ԩS͆ oaLb>Ç%Kmݺ 2aaapN6]4 YfYff믿67۶m3xbs=ߏN:.]z.M+"fdE$got{oŋC 9r$6-Y=vW>krJС111ݗ>gݺuDEEѹsg/QFtԉѣGgzr9tw8,Y2ep7 ڵkg@cfD3@D$(HNǃ>ȩS ;գ[nY{@D4]DDrbŊ/ǻw;J}""(HR~}fΜIBTRӸqc}b/"i,U1ٓvڱ~z6mĹs N:[2eED(U\H"oߞgX~y[t J MDDDDDD>2ex)(@D$4jĉX\'Npmy)(@D$ǔ(QrrJ\\ɨQHNNC۱DD%j#"9?SN,Xc ey2TBB(|ǨDDr1޽{_p!3f,5nDr c ))))R>MD Q8rӸqc2p{k֬p[Zhtn,&n7nӸqcڶmKժUbu"p?ޠA6l؀eYMRDL\\)1(Qƍ~LCDEDDDDDD uH""Y۱8q"E]m6oޜ<Ӳ.]p]waYBH""={^z8^|E^gرTZm_w^H?N2eXlZ*C""R0(#)S s̡xl߾crӻwo}k,@k>Lr8q/"/^y<92]DD|IJ,ƌC9u ̙300k,,X5mcСǏhѢۮƎΝ;P9Ŋc֭爈HYDD8wp9r;3Exb6l]/75^{Ϟ=3g//zDDD9Gogڵ>td7/4j%Krԩ<7H""XEڵc[U;ѰaCԩ2yd@=!""Hj|Ϟ=???C&MSNy▫ ?>'x[o8o&""9@DD$HLLK.Ջ&Oի 7pu=K&Mشi̞=PoH^1 ""WcժUlA͚5Yv-aaa#;qĉ9I6mꫯ )@D$Qe\ꤤ$~aΝeY75k$&&Aq)֭˨QDDr) B0WԩS4h:t`ѢE\mڵt҅h*VȊ+ԓ$"(x|Y6m޽{ b޼ykNڇ͛7租~?dڿ""ͣ[n\߿_ v8iӆ$Tݻ 2\ :u7|þ}iz6mJbb" 4 "" M^.""ޡk<+zMrr2jbÆ *T`ѢEt IDDC= ""׈eYhтݻ̴iؽ{7AAA.pvtؑ(7n̯?g4]) Wcvҥ*T+WRvm?΀4 \;,,5kL^ر#)))^PD`QAM6Ok.ʕ+h7zCٳg]6/&88e˖ \{[n!>>r?SbEzB駟fĉՋӧLDR\TF;?̙3Ո#Nc9~+@DDӧOSre^u1/L6 MԼ5@RJ裏u] P)Up5>'L@2e8z({/vmU'pv{+WĔ)S^:GDDD-+p56Ϝ9C 9r$̙3yaȏ6mJll,w}7J*zED% BɆWct[nua-\… ѣԮ]˗SdI|s4iB.]>cƍ }ر#qqqԬYݻwST)z+WҢE J(ɓ'ruMcc{ԭ[m۶eX.""Wtdf? ڵ+IIIT^۷cۙ?zCDDxFO?Dhh(Vĉ 8In_e8^4i""eYՋ-ZpE^y=JҥE.ׯǎVZ]`.] h^(Hjn޼bŊ1{l*VȾ}xu?%Q|yvs=G\\mڴ8N/W(";i813qЫW/>sG\ѣGiڴ)ǎ#88krM7FӧUQQQ.\5kp7(ӧf`vc""(Hjc7n/ .TPPF N'~~~DFFRpao"Ri {eBcӦM rMU^TKrr2aaa=ZH""7i$&>> (|G̘1͛7c^|DEEy,Q|… 4hЀ'|w}7|C@@usv|$&&r}PD Əh^)x4DDWƬYӧM6e*TH5c/wޤРA{J(cSD H,%66>}Ô)S駟 !:uFll,~;7odɒ|""z@D$s}ra6l@Jعs' 븎ٙ3g2p@RRR;Yh!!! |M= "g>?1pwӰaC,bҤI9rDCr-qٷo_)Y$W&445k֨7DD5Hm:ȿ IDAT6ׯ@`` O'Ȓc:u*Yf\RDZK@qu!**mI x2LE-"WDDrWSq]˕xشiz+aaa9s/W'"r""eYTV>,Yڵk xr tܙ|pBCC9x %Kru"y0a>,N]2w\|}}""z@D#\ ǨQ8‡Hqv<3?ϟvR\ADD<"""f̘eY?~<Hp`x饗/3֭yPD:tD= "nߨVʴ{uԫW@j׮*E$;III߿H֬Y÷~랚RׯaÆ^PD3[\cРAL:CNSeʔv"r.dnalܸYfj* m:+j@>#6nݽ1G$<ϙ={61e˖be"(t:50U "r-(cLW4);䰪ܾ4̓m}+ȩm]stm tGNطW~0)yPR9 n Lzk))^n}4eO嗝p8x`R2-;w.ޟe5ׯA֍2QqLLEv|?L~e+Vn4[:Sl,˄ t:3-Rݻy~ql<9A||2Ἁ{ZPʙ~~*U}oXvknчB2-;w"o;?jnƴ2lˇ> Ynk̘AY[X1`Pbԩ_f(;Νc۶m.utF4hP3m1e'$$$eZ=F/] [4d)R$8my)AZju[k0Op:7"80ժU%<*ᙷ#(Hg ѤIu*T,AFpf=͞k;3c u GJVf-'dOۖnf˶>L9menp/8R3mjYcvl.K>Je^e[XٿW"*96ƕCY {S0dNYIoR=퍪BW:q/s'_ײˏvt2+V u3cۺ{us,Rٲ8ɇ@$o3n )"kz< Ǻ?G<ƹ+ƩHb["]ؚ~}EZ+NC!L8B `v!"ׄޒwY‡&)|`Y8(|H>g&61$"y%bE>$߳,9 d9CC H_{ɏtCtSTT>3}Hg +Vc6.c޼ y_v;\6<_ͪU8r._,ҥKӠAڵkG]c8t0EJ$1 %""*Uxؿ={d1H>Z0R;s se2DS,]{JDr 65>}ݻ}G]A`Y~/ ޮD$G)d6fk8Vc kWoMX>0bO߇LjOX f ,!kCRR U'K1-+otK>A'Ŝ;OPk?3fx:|>p8IHLntRtq4GM ,q82ep*^1 TTEf |l:n:vdL Ŋnp88s6>;Ҿ%_%$c@Jˏ< "ߟq-SWҗg߯E[ ӑ1*e ~~aY I%pSyjDoo/Y]={  sXV@Z?lk=MLD~X-7^򚼾q: x!}c:-nadpA.bݽBI-Թ9 5hX(lF~q*ƑDVӢ՝ԩӅ]Ѳ,[6p3B̞6/KLP@V_Ų,#9s&`Q̘5>F3.*,ˢK'X`?v?o,83~wĩQ*YT< y`R)Z0>(Rk "&e46Z/Z=F@ԙmT/})^<;砓'Rt1]KDqsm?N3hzg}J ΁8/RbiU>ރGcxJ5H!ec;[ 8Ig|=Ą$3} y'#..?`pƹWWyvT_^;[ouҤq]}]*ȴ-INEv%=Ƥ6 <C-Μ>KDqB9δFnN@?8ި˖}=ڰi^Fl6«ߍө1o"_>~(%Po6`l< w/3Pu.̺wp\tcSR_8[ń7>a\U4ԓGnDG_wI3 hc6уeOȽGͦKk5|"6&/Ov)"yȿ7}xNpmu35jT`˳x/?յc\JBƲ,NCBBRvKкu;o!^bYNPP gУ\S,X6[|ؼyy IJ,N:'zNz=В "1 0ПZkf^f1oINNq?v`!&"_>6әi/v d^?:_> Ѥ-!!>={gڲuo,)oL|17^ܹ?bgX@ Ϗ:C5>N!Νe΃֏v/o?i.̲(S ~!`Kw9$>53?YC|l` ̙8^yk> dž]5[IIAjlvSǸ=1 әvn#G 11l~$&&uYW~mzޘ8+| l`Y;v*Su/OGsiz]S?vppM^ wIuik- }Hmn=GY0p`i]z>{SOO+-4l==:J|{w29y,'OM&u~Ν6+֏-={#oNfy& `:)Z4>cns1Ӯf{Ӧ>o4ov M?wvmoO?vfsI?^~b__k soun1ժU4uwk1[!^,]c>vm72E4u k>.<~}f9l~̤7Gl*V,mBC o1fi|G]cK=M7U7^sF,49vt} 9_K_g%i9rwۦZj. `yo"yҍ7@=RpH!UHxxUf=t%J\2ٲ,RӅʣ`,=.~y1`Ze0'z6m XEVo||rB*ׁ1iid03˲ضWv<]G*Qp0]}=sJו8ӽG+yXc^^Gdb,;e _l+&'} &}̆1@aai-<:`~#N cQ`ݟP&'ԕ^'* fw -Rmo^ϥ88Sp&cc\_z/1h5Hcfѳs4mx|2}bD ܹg㛪M7Z^ʐ%*" " ,){ ([,(K,dUdSJIyHZk۴|?*MnrO;ssB9'"Ҝp?sϖ#qϿ,_s2/1&5\riǏ_5ό/kշdͱ)#04znO޶k4>c8ӡ{rAÞ!,߹YU+'3 \CÍ{4'RJn,I6b?{>fck9{[Ŀ.[<'[\ 9wD˔,Y$YQr:(J*yzxr<_Nv̥KL-?ք(Y0Aa?iܸ&!!DGмHy3a2!FTt `x?2yrztGBփMmfIy a/OھLw^O*o Bp?ŋJeF(ڶmM} ;4!v=h>-:|?{-LISTp)v:L3μb 6|Ac&&G2?*I;'owI='T'H|E:f;'q*= ;l#::~4u'ԫWRBRs0שZ'>35kV"ҥM&>WV~ixΝ":pzbP'/qJ!,Hϟ0 %صo xynk׌v^ 2Η;J)y:*QD2ԮULJ|ФID_m@;vz0erG-Mhܸ7Q]ן|$ER`~|}g9)Km5Fu_MtԜ͛3}JXɓ>॔E&#Udd4qVQPCQ|ԽAW._ymn:kw@ܱ. RJItlOG,V" ;)S &qqvى?liO#q]:Ҿu1Qi]-]\ܺ勻{^i}0G e  o^Kg 0"#$Yz!,נ|I{ca\z/Ԡw~<Þm-i||'.JūjGZM5apRru[zRD!Fo4yi&v1vEeQ:u9ͩc##XvHkt=F㔙B(3Ki&HsZZSdQ#᧝ %G}@@gNbତLk˼ABnZpr!`xqey؋\x DS| nܸGv;R㺀e&X{JK7ޭey; a〉:11|^Bptڮfu+ @GJ `![&%ClNL-իWT"̘:^~֙98DAH1Ng{/SDa&NZ t$&!:;=%X#*2wLoN4x:z+4‰֭Zd øq0b@ Cu:wj=&FFDѥ8[yIP!عn s76~~mhr ⹁fι3?q,9# .h<t3YWފ͡Z>d}z6r\LBJI``.Y8v"wnΆpmAcGӳfB %WpQm>!>#BVP3,[>t?@Ξ!&ĮGsײ d ͛gӦ}f^!Vexoe4||0vb}ܙh޹ϙW1uΟ<ܼy>a_R^h" k?>}'S|qKo?Ip]| خ/ՒۿʈlI]gtԜo <7-+Wn@hha >nێxt3#}٬Q0hn|͏o*B[V `-=ù3q";~+kBB氻GSNOv.R%=ڵkڵKu֭5R|ف̙={RNNNPpRٸi 3S,b Gl@jc[\| ~ڵ*s?N/[}>V&\xQXQtɟ#v{7 ȵQ.\MfQwR:u[85]G{ߟrȖ-e-+n.DFF/5'Qp[H) ĻPSOX2APP(eʵ!(=2:P+ۉ1dl@XX<=qqqM0nb@16̠w~[7oψS jUfIN;SPܼu_7϶7[I"^M{,`6sGҦMLOv6%&}xDGEBEoڴDu~5 vHa/s'<"[|}"F+Wnd Ss\|vKaÈ[,_6J$g=L^-V'O]ft=08о`fo/Of3buvlh >|rJQxzƙGi{=CB^9S'si6gQf\E BBùsǏnixyC+XT?_gGxv!4z[^᯿N3iR":ƈ#+Y6 |qsu&"2Hl08S`c:un;3:(̞G<xiC??a U+ݻ~T^_Mj9B"!gׂ#4%1s%u. ڒSMXd;i[KQ2 Xz%@mX.۶LX↖i.̞?"h՟o] 3C[L1Ö*)qvv=5iL9i{u=d> $WقcMj[g#ۧn|ϋd|EɩT(Jݻ{h+J(W֋rڻOKfKc,3:s{ww"iH6Il:0:& kGn&fn8^"E $tEQRmƌU >%{{C^ nFмEi&J,wv>Q~epsƍػh*;|T#YRڻOͅ+po.zrU ae֞s޲,EQN RrKSYL>,P"NN,D!P%Q(JN*TR^ɕT(Cܸٻda׿ wQ%CDQ%4`b(e1%wQ(((YF JtuZ49ze@EQ cH\%˩+#}SNEɒ%X`sՕuڳVqunb(z~J(J/*I?թ}Çx,]4ށ8p@֭[z?2I|8;(4)\(?(vN ohUҥ6mBuP*(Y6AA`` P @ҡ?~CҩS'4M|GDEYV>}4.]sIEMMٻdfPi&UfbX*IWWW~'̙8q"˖- !?|hdʔ)#H)A@SeEyZH)AsPsEPŊcʹmۖ… f[r\6mJ*)Sw}? $ERnV=+((3g2tPc>>>+WGR^=>sK;2wRӠiӦܿÇIHHH`BCC9~MeQI2Eu]U% :;vp}ZlIu[lR>*IS鉋 ~<<<ȓ'm%I)iܸ>Ŋzػ(d)%;7EWEIs1b^u)ܹ3cر\|%K3NSNMݻwc2hҤ nnnY\Osoo(&c]I$:RJ8yd 34Td6d4VZ9?#CW_gW_U@2 @)0)%DGG3l0ڶmKӦMMX* .so;sTˆ4M˓Z*ݾ)EEcv}TuZY{W=mػ>!2"ESr9g+KUFU6Y 5kdƌt%^ <|`zaϢ:*I'Ah=^vm *i֬Dhh8aan +{;)R+USEJ4&N\̘1='4՛d2˨#Lr*4-uuYG%_BN<Ɉ#1bD6n@ٲe~e0{'''ƌC`` KFAtt4+Wd͚5ԩSE͕-޽'w-f*(Jf*ZH!O+y/%#Gc_nR=`pt=3̊b9̛c.Lv\1vU}]+˗ڵkSF |dɓ'4h B*U1b7njJL]Ry IDATdIn'$**[xcmylVߍuDF^}.#=e7PTKG !+z`mi}|9#ժUz$%Rb73a|_lIdd4>3odg%sѤI6*:֯_;czyyhѢx۵kAIBN- t:]0/c}OQRt^o wjy < UѼ#ίZ*фb7>~|w`=׮PǦ_ӧ3l0TlA419HFǒVIJjNݭ[{lyP-J6ݍc>=,Xжڹs000͛۩t @ҡ۷]R^=&OLӦM ,ݻgb>Nb!48}X׳<];L5Oτ㔕X31iHޢdR|-ef%o/ *o^oپ};6l`ƍlذ}v=޽{NI?5$O?0`&L؁A{XzZ5 u](ϗ_asOr۲e([N%H΁?OPtd;BXF 1c-Μ@j^ͼծ 7 KBtRz͚5N:{T^ƍgA s/uuNqa61H)qtt$44FQti-ZK/*vcS\\wdSyr&hɴ ɺsM_}%QZ=ۿ}|$BMRD&޽{xbnܸ;w;wrq6mDv\ wbJF4B 4MSJh9>PBIKG#$4ooo5TMɾJ/dwtTKt;uӧOwI6RHųtӥCbcPվ+t ^ au&k) >?%g"NKvSN6mڤovTtL:J*QD J(AJ>}z*C4uVAP%m߾ӴiS5jDHHHYlJ{!X`裏XdI=z4Æ cҤIGDQEGJrՕ _bbx* D!19㞡=26) @6O=ӢkN0x()`رI>HÆ U.$_tҴlْ+鉔.^֭[WTXի㽱};կ4G0xܺqe0q|_FٲSTa{)< ф`؈l ORriBBٹ0~NO>HsdqfF ´/C暌qg|xR @2)%+W۴k׎U&hStO!,^TUwNzT @lE ,[~Oe1 ? zMz^96ի(\%J-MƵkܩ9;eػ(c-"$8, ƕ.]}/d"+㽱:5W=qeF7RTQ])#FʞWu qllڴ@ vEmٹ0U=\FWׯjB>sfΜ 1c8t 4`ǎjՊwy~%}Ԍd!X`SL!UK!< o&6lȂR>bbsM W沶ԮݍO7tR èP$>׷⌻gcǟrZl;HyNRkܼy?ѲiӘ㳙/sm >EEŐRI)s˗oxTV!ms4hZjr؉e'ntr)h\pqem mY9y2&.aDGpͤŔ0~MSH%@"Efb!lCyud0NQ208ҫDBN7X| Rpn'O7kZt[]; ī`S7pq}nF +Hsۻ!ժUڰ, iM0ԓ2ڰ|/X ypM<n~Xĥnn)enOf83k4A]FĮ1َUөk&:wp8=Q^5KwIojM&JyV-ѭ[+ *@ժY4:vF`Acԩy*I$Gcƹ4j͠ѺU#q)a_'LY[ʩcy/h|6oO1i61er>25^9\Ò{pLuw#&Ӑf4ų]g$>}"5S!'J3k$E$>0%xyyepi%}Z5Q@0W/Hr;ap端!Ӹބ¼ysfڿ,Y_uY&/ࡂT:~EN×joY~6 apʂxq]=w{&МW%QQߍنC=:ݔ[u\Asg%-[t3rC9q}nNdd4ܴ<~`L&g]cH '-yt]G:͚`i=ʥlڲe7q-= BAb8o _ZmZV\}Æy#-o$.#yeDd谯Yl,RJn޼س<7o}ٜ3) n&((EQ (J.'d۶ԪUwý#n9ӹӧ>xbkL07EK)# ½{iؠti4)_[5|2H!+Wm~jz*iPs!:BS|L6JzU1 77gnܸO*e?zt}J)/u4o ˕ ""> u7._ɐ!u)Sӱc3+. Kmnhݪ_}"Ebt/B6m"OW xg.eKL풍R3ԮU̜9?Pf%znKk'8kwyy7@ٴ+FOTT4..N>߫pqqBJ2u9ybt/<`̝;1c_ETT4c.fḻ猔֎:N8ʪ E `8ޅe,^Nܸq&F/Glni]s7f6=M4۾RBI"pO?"44ZA|DIem 4S_7Y&gk.<@FYz RLff БfcuA,7x6m_ һj$ G&'873vLd@J\Xat#뗙 n 2"u=v%,^4*}XrBeP.T8B~uxRB_V"Yl,WLc5|5k 4lP?,%kC?;_01}̝70"1G-={7nܥS{o{*PRA+śI N!iRb 鋳kK\L7ҍS%Q#988O||R OB %eJ-s/c(sRk;b ӡsh2!x*QEQl-_Ux]hpX7CQ%'QYEQr(W.JStQHy $f Z4gH>W'gg{$WpxzzK/mY{ Cɗ/JbWN( {P.`=Y..JruT¥KP9PǪUry Fٲe?>b*ztuݶJձc8}4^^^nGǧorvJN I5M@}>Jΐ{eTU2Q J\9<DDDu}~!+ojHuHS>}l@tknJ%[Rٳg-{nOa=4((W^y'''ʜ/_]v%{!ؼy3EM:!K,a…#T *U"22 GXXJ*T\9OJx9vo텅'F͚5ٸqzRWR6&|oq^(YHΝy0ךûPd_s!GV.Gfݻ^;&UAP)%@:gz.``&|c;&&!CPtiϾ}0Y=:0}ta׮]|̝;7huqUׯ?J5 +uLJٳg3w\{)QG~.FDFFr)~m\2c̙xxxMu?GWQ;Ԫ )Y&؍byZys?GĘ ˊbHB*K=!Xn]-UTSNjՊ^x!m,kR얖RRjܑ c4(U5 #lζd% t&N1c^`T.k%MɏDf#.Ŷmy0NPb_;/uu+YGssxpu:rΜJ3RpzdlyG˖-i2_~]l=XTT.\VZY]\MMBOg}SNQ\9*VU-~ooomԨQ#rʌ3ɑ 韙+ ɤinR2^3s׼,lZak?gKZEjՊ.H)nG@34UzB<3gs!88޽{tR'DX|.XбcG\/$VH'F,uBqzinE)D&IAZH.^Ȏ;8r$''g9wիWw<>}4 .tuEJ@)..իW… U4g0T_LE)QRSs|(r3Ξ=SO=EժU=MӲ<7=.NcʋP(R0j׮ٳs>aZA ꂕ7oQFYBPB\^`6@QJw7CP u+B>}T|8s 9nO?I\⬐E)!w0u@rJ.[|}}IMMurdşJ@alٲ%8!}e˖urdg+]CQg1 n#)q9*UŋUƀCڵ뮻X|993e˖aZ5O ު"(%`bWWuD :AJ޽{BPJF?B-[ƟlOV՟QQEQn]r"7EĢEV|BGTTs̡zH) 䩧ʕ+4laЎ;h֬?Ci^W(5kZ 0\(7 ߟzQqUŕ3pv@H/#F`Ĉ>|_e˖9qwwB V<9n IG)AMC;mlټ#OѸ5XdtRvmK/_dI)r +W&>>_*Ƀjժq \ڵk9r$$%eI))[,ӦMcȐ!.60.][o… 4i-y$7BmI0 ]NbԪYQ(%UgذF`BKӦu\RĤP~}Ν븉{7.^͚5RJe*""Ţ`0܄@FΧ~ʼy\MK/<O>*=ӛbccݝ2e^(JeT b)JI퉦iXQFDRgt>,]i߾=B~7Z*+Vcǎ!n_ٵªѥKgWP;u C)رqnxNC% 0fKdd$۶mʕ+4o///Z̘13fXBqS"EYQJreoj}s6U(\7퍷7KfPHT| 3f@44M㯿`۶m#M6ĸ8jblGZTnLݬ)jg& ͚KGynқGQ TzQre&MD||R |W111xyy!`x{{[u\)BP7#N ?' T|s>ixqf? +ŋpL&Zlɱc`Ȑ!TT H> 63gr,X@\\Æ slr ͚5c̙N)VЍdu!v+Nf/60URJT/,{qA!&G}T J@AJI=}{Eltڕ`8K/*i qߟbY/¤$%%:b3O'DS$уdٰaRJf36m0 ;wʘE)0щ8qa(4$55ՁK5j`ݎ$$cٳ!Yz\TOן?NNNUEQEE-ZJ*z:? @9y0@~[0; 8%Sg0Eq"((44we 2SNRԕ.\@͚55j㹽{R^=5jO raۮ]rᢚebWc|3`ru%}AS *œ'={a̛7O0-[8t_}`O`` eʔ݅Q!Pgt). 0y:1W GP@ޘ(JitL2űR0: 70l0N8A۶m'iӧk֬u,^؉*Jtl6QLiB,' ͦ: XR.dYuU-$RJyټys]N\\m۶e…ԫWZ**Ƀ^x!s'O5tڵBRjݏ}!DuuuSncW Rhk|-j-gÏ\J$aÆDGGwaX,"##ILL䮻bʕ.P H>5i{zBJJ &w%K\@(NX5쟿Uu/$Gn#"""}iٲ%ᙞW- :aٲeTP+ұcG8poooᮻR'((-Ju:vk:|=z4Zl޼L&qqq={YHсnSMҊR<`o6W(J1q?ί͖#$>>E_ V>|̝;_l޼___zɖ-[T\H||P$ À(JR2}tN>͉'HJJrTR:uE_*ɇ_ݻ; 6iZ5((-*Jhhh!Ԙn!Cڵud+Vq\)RpSle&RQJUtpu%VLL ۷WGS H>1 ˇ~HTT{vl}j (lPY4?N|YآtR[ ꂕRJ6lH`` VZbݻ77nl63sLf͚pE)&Lj^E)ILfU ӡCYf9)C% 4p@tݾ"qz+ĺu\Yg(%Hz5k2zhj֬c7+777'GU?4-ˠ$G !hPߋU\(N 7VS]SEoÙbNRr=]ӯ&Qyɹ[3Vt(H%dp{3g=AgRJ0GTe^=ye"1IX6(N XLѿ_'/|7=Vn f>aH*ɧsfy.ʕ+O;;Aaoj扔+qt4fx$, >E;ص{%*`]INNe,_{uД4ׯ}9n_7tbTşJ@bŊDEE1k,NJ&MYjgϦB KO 7~ =<+-ZA`ZU])T!t)_~ًfO8v ~IмMyCž|Xy [ɴWv fqQtJI!%l MŅ W82~ry&kVL^=8To:Dݺu1:uJ͂UTOƍcoߞ/i&Enݺ̞=W_}5Ywj"Zt<~qLzn1..(g6S3 Μ9C۶m taœJ@al߾5ki0Ν;=NnmJ3ѯq8sK-K+!%_u몙 J@ر#/RJ91\KqpǏgĉ}Lwwwg}~1sL*V~xX=,X/yqN|rRB7zֱ03&\*l-E {]J=lb6>濲Gw;L#-וpBhP IDAT#0YͿx<_@/Myܞ=*r]P?^0ޟRJ~w*Wo?#?2f#ww"}R"4-[~chڴ6K=Oz,:Ψh߾1/;ً/hEu-'I9z d]LŢHZ+Rr9 Ie5Ϟg%pO|rL)xc& R;Ovk0Dz&`b m\N@fusREY֭3bCQd lٲ2qDBBBHJJb0l0"##iӦ,GV/dk<7i/Ah& P_`j,Ÿ2PJ_uQ,W\2tIQ= Ɏ oR)%O}W:'On]ۆ[盵?9%&!gDoxi34  BLBF뙞O.uETJaYgt]'juLQhe> Q\eXV-1X1"뺣Kb(<0nui6U7,u8s:Vm#5(˓0Y򻸹L CbڰZmٖÜbu#SW ʣaz]2gj5k05zZWg:c?5k0}ttW_}ŹsiҤ,vT;wl63i$͛c=]wJ&!Hi)4k@U`gl1=[R+ &KS}6Sda`ȩ0y~Dzkrs'VuGr]:yjX^a_V?ML~q1͚OgcS@i0yQ@}ђS'#LCvߋ{䣏6 4TjCc_׿y aRs(' ۰qn臗^aw':B),$L}זO?۔(ժk嗽l6wz=0$>4/FTv7Uи*dolx-3_\ 1ʖǮ(Z*7Hk=g%øV+WVOV)%:pF||INӍ,Y%BYXp!zofz#&Ky9Hd" 6md' ;Vn|i~OoO*U*xm`x=DZ0xDDdw#ubeT C)[ ׬ 3޽5A-[,QNUߴĬ$|Juu%S{{y%#-Zܑe]_!**||Z~IM-K+˾X}@-ˣ}l|z#-~0iQn7&ҫϓ\/ʕ B4 }gQJgo,/z>0ɠw~"O <L`˼o/r޼OX~m)GH||"[AuSZ5* 7CESүYp5]L;B7ɇ())jPfM~7m4ן ŌJ@n… ԪU+ˉ'E9sE)%Ah.]+싣e^=>Bl QfeĬʽ/? K01>fqZ,ao<1^RR*Nܶ9sz0BRD_A82R<\]x}ƌCP>b3;A͖>3KXn7;P%[l63I)Zcsg`Ho&/Ǝ4o^wߝLD~FJW_o`I/a{pl&н[+?T Ƣ%_gUX,]2R!22sW]v[9=>a[#Npp .F׾{v9z[ٴ}m AдIm6~gز$ I9^'OdoM2xН,yg2]Қ*Tdd$zb1QFP\9>Cο $X,xyyeX" ,;O^۠a !%?O>~}3}[6F3~~ٜ߲'X͵zxѸQ-RRUNһ\_}IKJRn5/*4бclU)Jv; 3^yʕ3nX1&ffWؗ< Me m = Ŝi޽qFe:?Z q?/ ~,aƩW8ɩ̘=Y՚[[6vMfK4Ϳ|KRJbҦ+O9t7Se2`vɢExwhժ#Gߟ_~UV$uBl6V5)e#Uɥ u5e{U0>h9:`n\R75m;˞n<15};Sk1GAbB2`]cfh&GjUfYɶCf_^^]ׯf_̐}JBAJԭH𡯩]*B{ػf'0폱Y(}DFfViu<ݥusL1DFFŵ _;ϒ%/Rfe~t&hɉsyqh6{y԰ǂ6hלyw"ڔ׿+ubܸo“!>@RRQm8p0Yx{s厽UEgi %ڏvO4oV I08"&}nf|Kgq91L:uݻwO3|>S֬YZ@ Z8y$7krBJ)HN+.Ch߯Æ׋͛cۏ;/PA d5 Ci^x~4oV|ŋHNIit>aC{5eWs)[>q¯ާyxyyo2 ˃wߋ* }ˮ}Z4$IC9r &xטG {z^]kk9v,aPj'^3TD u\Fg,_Rh߾Fв|iSҫwl֒`4{_{_/|_GKFyI1 '˗ԩ)姟5EncT Ͱ e@׮{?p=97Wɧ31hp7nC, 8? Gu,Z ;X8q^[ZC=yQV,ØfpT$ \uTcus u+_|1Y> 5Ʈ]x{34m>qΜ7>ر|G?C|Vyz8[7/Sپ>pkwl74k1:y TZ4=FsQ6o'Pl?*>oyg5>>ybn;: ȴ>ȨQr\+D!XJEPnĠA 7oίzӯ`ۅ]dd$fXjC-լ^PZp;h&r,uOI~ `ri4!W:-Z5#)YHySzuRrEJ/ q56__@V S CF:Hqpԯ$~e˖|J`$:^o 0@Py;\ "8WfT6DG_c&lݶ<;SSw y >^1ܪl6zDDD{DDD0dǹZfM:fÔ6{NҾyxxC=;/,fϞUP1I)xR\gK*;]4Kf6|\{ O/52T׸Qm)׎N5_/o*^71$fxSjڏRj]QRiٲ-[ֻѸ`2V^JnӶi _68@VV}d2v^fXSyzBgr~`P7}aT#LXXh I 2iݱɨ/xZֱujWM۞< %Pn 4`{nN:E&M+0`+B,J@]vz7 4JԨQD(Jдi-:c(ʍL&֭˓O>ɺu#))+Vpz-J.͑#ŌJ@"a:V)JIҥS\( )%3f̠K.L4 Cݺu)UO<QQQDDDLuREQEQJ@={gϞՀ§Z@EQb0(ygt|.PGS (J~׻: EQDLXXW(JuRE)"ZPQJUk(J!R- Jc_ۤ(J bbh\(dG% J#`9q⊫CQI,a:EQ?R R$%'ۊP{KwZ#+H[ -> "8s^lSQE):T(. D̼2c;0Y˖iS'3c2FJ -)Rr;3`4j4 ar/REQdSSk ryBӈJ^Ҿ]#BʔbwѬ -R=\`iL*|ә  CO|=(WPV?oHݦ/-p*UbJZ@ɤTғѣkwKLL<6rtrwwʡ GBI _N<&oD+ ne*ФI#W8FۻGނɗ'#Lj&uΝP@Eq2]7wajt֒oK^퐆"nbj\OMOFB{Ogӭ)1WJ)%{vu9JISXB!bQ R$yzz`2+qmD]bƑŧ+'PǧR-Vmա(RRbI)ի++:b_ޗbKk&N8Ǒ#u4F*X*pf&**\8nHCrj#蘫j4X6':LLUzS3r~JܹKM?>}l6!LniJF)% ,V-ss񳠙t9 SM˝jvfA g/wi_BBҵՉ1$""Nqy2lKHHbs2W4,qaW{Oq'qٯ럢(BE0QV*Vo~^IDATjS ЮB37۷ ⵊCwoV~<[i0dX;6^'4 tzDŽ 1 hG c6#&3ɹt6\ԗs)?| B4=fiB0|N'Rbbc ;?TP'OOŊwRe(+ٻ2H Fz2Y k}ЧB —6$(; @ŊݩXNZ9ƃ'b4 yң8ƌy/VH)yo:_6@sCcg>fou`iUævdWTғ3g. `RBwbٰqX~MKV|G>tq$Q)~-Lf<=`4?=h  =n'P(k.X$RO%/mޭXދ#H{E85ŊgK,)/y d2ѭGk%eŌ ƎGҸ;˙S 5Bq)a21ӻ=CwEw瞻itފ˗ӣ|.ND ko=+3ٸqzdx}>k+wvtRRJM$uG Ju.͉܆S&3IIKb,|^\6h~_y~sk6K6{yy Lyq1g,u`{]mt6~ZMZ%wL>̖-[]R زu/_kHi:cv篔TTfMqg>ƥ)U?(]G7 BBYfWYyd`a۟j 2C׮gTR!' uҥ3=gNJʗ  5 Fƥ [Z\ a2\z;+JE)b- Ith0-g^Ė/'Nrg@<`ӫ/^KYG 񚠠 y Pߕ4G}}|-Is7JZ43Iձc()]-ժpc[ΝޢczͶfb6[d"t@'M6aZbBB23kM4-D}7(((߭&..QuUKQǟ$:&.Ӷ]17/)k+TβMJ'~SOޗi{;^c8V@A|.O@?&]Ѷm wRfF^Ńm̞5ΰ~'5jT3 q CN//b.otnmҜ -kyUbH% Jt Bvu(.~7_ߎ g;-jpﺥ^lYL۰*u?ѻS4!nu OgvI)'&T:PcU IREnyxn"Μ:wk~V %G6E^mlٖ ZMS1RȽv>K)/'xb_N ?n#T9fɏZ5~<6 .^`.~JMһS ڝ# [Wh8p^y8q<6t^Jؼwx&/ШX1#z{Z߇q{Nb={eGΥP׿~z\{ GLU [|T׺=oã>ϝ}&d@ D"AeETY`UXK(}- RTBB b,**jhXD !$f&܄Dɝ<<] N WOe,NK1(ռ{Qu 2:CA{b00a=?).tA߾^yao Tdwn3evs}%DE!u]_HIIӎ)+dh[I|3TUd.[ʿ }~#Z $ VkHZ~{'3~.@qu.=%N[ڼKK=H$M(ѷYi<& D_.z*())*PUd)ZE$JJ ,ر<:x ?&Tɒ2@JŖw lTU!jxII5X!$<zlT^WUU[=P?&j0tz ЦM2ӧBEE4^xь-ײd`gEuZ!(ӁaWQ0c1c*1k?/0^ S^^vi {cEB`ߞjzrc2B%7*+r9/_x>+@͚a|](\tɹ݅>42zͼ]qs ȣ+qbqV$/݃HKs^ !)AVbƴ+(Z eB?tm|k֭pDsk5׬Y)SD8"_.8?994ᡇNw+\ݫ)S Y/H@fY2OcPLНc (-  _.h@ 6ʎw^-Ԧ*ғC`Zi[Ғ2pad]^]{g#DZTSA>O<8wvQBDɉmb7c'()i:+ ?j en$j{Baߩ㪪p:HKsk]H7|uoYUQVu_@{l|z"dw6The6Mu˚ԞEo:jiRJ0/Qy4 L|^oU)t@HKsk:Ԛu*\N{3u+ӎ6ɰۭ\.\cv& n$$8ÎMv'jщ?8-͊d\߉ NOw>^~/RXh@Ν#PTUU@NN |z>m22㾕LdN@8t]P<5XU\/] UhizYB5W=*6@I?lÅ\..@%QPk6q\>/j.QQQ#,Q͏p"zX,P3p"Wx `㧱,?MuJD3k$d#iii̊axv;Vz~!}:tuA7g(&k @R^^=!B H޽cj=D]~{wo1Zyu(Ƶm^D: "2Ȼ<8HGbx -[]&Λ0aBzd֬Y_z饍|26 !yfx=GJ χۇ^[vm#jQ}B[1g|tpoߎ ,@jjjŠ#!!Ż=:ȉæM`hZGz/ze:t:uuܸq8p`-s& iii׿{ҥҥKQRRZ֭[1f 4ےϏt0/22# DJ1c]_|,m8ȑ#۳gO,>|гgOlذ!4"V,2J[uV >\wh1of,[hZYS0t~ (XKtt!DQQrssqرE V 1|Q7̨Q;F:չsg^yyy%Pw3"0tdqJd@nl͚5 ׯǩS"R~;̜93f 6oތ~;v숙GpcܹP%wf D>EH@#bn4&s?3߀F:Vcx'e˖:YJJ &M{n;.y1`1Xuvx)L#1H"+ W'0uH*;̧Hbur5 2q2rPLRb_[|~)>I)sG!\ dggMZNcLĒ%oAbfx0uT( )%r [3@qQ*,oo]w-qI1K{gmi]@e2/C܁ѣGjRW!%ُѣzb3QL RBX=̞=65$& ՂI5kR1iHIv V˫tc2)ZJ7w:-:5 $$<m63̦𛏍}G(N%<>|TUg\ ħJ OObjҝWEZezΏo+Ep4.*+}t˩_@UQY?jŬ3s#RV'3.$N@d¡;x<}].l꧲O WOϏ@@˥RBXM6yt@/O\l`]@eU:WHUhu{@ haRϛsbpȹ,Ϋ:bK D@ɩ>(v1fN8?,Y0["lE 3V|GNewkY~lxsT$%^Xomq̫B ֬و}j`޼ـ o>| ϿzAw^w l0l6m =1`z ;}W^0|ظqwۭN{]JɧV ߆Nwr^>:;n';Ͻ:dU7}GUUL6:CtСnayӄM[{xUX`**:W;^=aƒ%/<-͊ᄅztyL@(njҙԔy}yy.uAƋ/ϛѸ """""2 G""""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""0!"""""?`QIENDB`OpenMesh-11.0.0/Doc/images/inheritance.gif0000660000174600017460000000236214556675336022404 0ustar gitlab-runnergitlab-runnerGIF87a,ڋ޼H扦ʶ L ĢL*̦PI9Lu\/۬ҭdxr.~yNw#xP8Hs8BdP# Ud2I2JjӺ*R"RkuI7ddliy얊k}],(B7´p?0tw~Mh0 VQ!}'vh I*h]o:El/U+'v0mj'T)Oڨj5Ԭr}հbZq6ڵlۖv*ɸo-c.z[",Qj/z3vbެ 2̑7ƑzH15UեY;uvT`i}hݻyxXpGÉox\fr˕n =M6cz{i;xk7}s'w~q:W3#E#8|EG{g>95P t_ }<芁 GsP4T(džDcBfաM̨bGD%w:5$.Bdwdv6JyNTԣ+? tلSDWeœQ^(9PY hG Yi$K7jŦp}Bgc7ho^)ᦡ*͉1o&gkdJ@ gNtZ*#]ֹh񤟙ikI1l WմT;+4FeY=B]˖a'+/ /x ߁p 7#Y`fgq!:r%q2)2-21535cw39[s=s >nJ/ kԴI-հY֬iרymؤٞ1qB}筬2,%WJm ,j"H~S')s7ߨtjg(}YQיe,#GV[r49ϖRjcf._QJ26|2UX{ϒN,M@]oDA*S7>̷*Чk{jo7|04fL1sdP2|LĄ] /Rh,l _p4 ;OpenMesh-11.0.0/Doc/images/om-format.png0000660000174600017460000005733214556675336022042 0ustar gitlab-runnergitlab-runnerPNG  IHDRsRGBbKGD pHYsB-6tIME b[ IDATxy\TsgFPDwkd\ mӦI,OljMM&>I,F *BPqGQ *0lw03_qsw~sΗDz,A˲\E QAJ A?!k2 HoۋV AC (-APZB (-Ai!J A J APZB>;Z~غs Z-Ai!J A @{&_^TyZsP4 }D1w~XqHi嚆4 RިpѲ'wδ_ѐ66,xiCZƕ_us9ßZ4|UCLj飴j*mgmkZk\d}V_̷}o:!ј@cV\*{/T:$& ߪ4ۅvnޯuu~޻ $(-?ucx6x0\6UIHlZ=~>1?uָǕQ0a$%$m=7ZWwlyjpTIaI B/Humoh[7@Ƅ hHKNc [H`/6˦Kٛu J/[baMbXu|:4y!Q3-ZRr J)!Yd$B2 N?D*n+m', uwXpS!&]K7{Y&AOy\I^nrvpUJM[^o`u5CC?ЃʫV.3 :isCҬ t^{*>=˩NJlȤyЌc-]zK\`Av$tZZ˥&^0@R EidcueQZwN64bDUnծ !9;ccu0X8BimB30ˬd'g7 X:%85NYh0!g{~h3 ~sB7]g%T}m)nݯ=.0UbFvt`,9F-.^ Ai :)'U >:r}}Kr#$\b\YwE~($<* * gOsS"wf48>>j8X%2F(:ٟJ놠 [_RDٹo*RB@ᢹg2&9uIz\uJ"#"" (u|}r0٘/nWDLDlU' Y7Gtpw7?v#:BdWVfuOMt8ď/j$뺗BJ(U{~RJ/(S_{lt, ! 4, ;bR&Nƕ}wڨF.&bѲܱu>7}XAb]o":L'ˎ7Q*yk'uAƺҼs? Cdǧ?WocZrB (-Ai!J A J APZB >/AC C▍V APZBC<E QvZ2Z.pܻ~^oV AC (-APZB ^/1c_V AC J APZB t#":L8^hV)&L 4b|l &+)\Ӑ&CR.9Zb2+Ɔ< mH˸Bn.'~SKԗWjH ^Bj*mgmkZk\d}V_̷}o:!ј@cV\*{/T:$& ߪ4ۅvnޯuu~޻ dJc)Qx6x0\6UIHlZ=~>1?uָǕQ0a$%$m=7ZWwlyjpTIaI B/Humoh[7@Ƅ hH8BKNc [H`/6˦Kٛu J/[baMbXu|:4y!Q3-ZRr J)!Yd$B2 N?D*n+m',LtB~,<byؕDy5!k2%~&gLXt5UJ V'* ^="s=jY1詓;8ߑ>$M絧SѳT(oݎL8B*[\|#RE[*j-zLI6MӒ]Tu9ѡ0ZdN#MT\ZޠOS>=VߺXHPvzd]f>K7+ A 4q/v=q֏us%81s(Uw[8gk'}j#X"C%Ǩޥ<'(-+:)'U >:r}}Kr#$\b\YwE~J ($<* * gOsS"wf48>>j8X%2F(:ٟJ65:BydDQ^=ƗTy ˤa_\o%=KfiTH =;#D4%qA\oX*RO@x,*h#0Ιydcڿػ^!2Vibg?wRRbliL*<3jvྂ#%+67p#{gdWVfu?Q梳Q\1) ʋfmSV#jahYmB2o+6_lʹP@D dٱF:J%}z֟t}1G$ B{R?Q|b@_}*ӹ[o,RoQ'w^Naj~NW^}4nނzY6wSs҄?riD/*Vm 3TgŁOX W bS_4vxVwA-yg+DG.Yn(fUrbE'Vvss qP9ZkA1P91iرJgi0:BĬX5ضPZ~rӍs:!nR(ri6Tg|տGO?=um20M wvb!/h_9"홏PWdpqX|3)J:B`qu3_wag7OvIK Kn`H&#5v}$-ׄeŞ=e\RJ9N{h &0y63ISän7-0ɍVtuL@i8>P}k]O&*)1=Nd6 n`}ѿo1K)${nAJ@„(}-DZ_5&ʿ۵v/X53SI _Z gZXWB aD|ލ PVH5:B%Xݿʹ׷,f!{LksHklζK~=w\rk.5im,@g=EΘ0!މܾϏci6Rp-snW+7H~O~C3}=% =Xc'vPehyYq½P( V`%/7O$)bR;!Ǎ6GKf?$"BJX}`lܱ|%#¶rv~񞒷k̙GG!~HoZ8BJ4gxip }/;Ȁ{j_3/ ゾ4)<5av&XBTG1C.[>T'yxz]]k /!D"Ƞb(sox(-! J APZB (-Ai!BAi!J APZ (-APZB (-Ai!J A H#x 6hUW.Aep <BPxJ _]A'A (-Ai!BAi!J APZ (-APZB ([8 B|Qy ]@BYrJ ~P](-Ai! tWҺ'Bi!W _]@ZB (-Ai!J A J APZB (-Ai!BAi!J APZ (-A0Rמ(* C 8B5r&Em/ C !D (-Ai!J A>{;G9 ZBAPZB (- aEW:EJ`0az\Iz痋WZiH!B) -ˊM1Z|~Z~L ncÂG6e\i!U7?kKW5Di!w_53nrжSTy5.2߾|avϯ۾7uhL1Y+XҽJp o\Gs;7dY׺:?2 u_౔Gq`YD-)dZAo! l'ȟX"[7Wؕ6t&@Bi!?‚ J1<H\xȚ̐5 zMrg?rKKWj:wޚxv9T^rY`IMKHtfepSYNuR*dnG&̓fk!w.q]>ّYhG"x-eKMda&|&Ri.*ǺPZHWtwQt&rcvWo')o`QZ]F,$(;~Jvk|zv{3SS䛕 Yy v;8Ǻ9a,tc ]2LQqUO*1D;:LGijE8KQ KyuOPZHWLuSO{o+}u,2 G&FIĸBˋX72PIN'x_UT2v2涧 Dip||qPK|]ePt? W?mKkt(rɈ&k%{//eC:ӗI`Jz 4&}V ={hwFx5iKジč߰T*YYT@ѬG`37ƴwB&"d"b>Ϻ'~*Ң2$c%&UVky2Qg}GKVloGt[ɵ;@+ FɈ鯬<~xܩ'l:lg~-s1jExLϭ6ޘW]oQ]g6 u>r㟱3dŦi (Rq9Z>->WJ\Qͪ#ŎNBN"E ir3ťzbxrbc d:`tYHkmftB*ܴQsvl6R)H݋6v{d` B^оsZE35I|SKfR$hu W '+rf.jno-^Wwy;>ܲMF9kHZ ދ={ʸH4sDQ䡝'L, a\mf'1.nˇI]n;/Z`3v?Iq|ֺLTSrcz7m0ٟݰ;^ͣcdRI? < w-QJZ{!:DkLG׷k^{RkfIϴ(.d=׷> @IktKT](io7$X$B~ ֌myV{=_-]j" (.$6,봎e"T\Ɵ(Ƅ_ZF+ .uqRD$ 9q%}odsy. 賫gB>rϴ?lOElmۈ"y#CϴKV\q~AZ5CNﳲ5{2A]B#̌4H[slν[κe^ M[? @q’dޜ IDAT3RH3T&`A/[?g Mf- @.&"fJ?wo-Jhs=orD!%%,/wm&_saa[wr srF{m x̧TO3N#H\+>( V`%/7O$)bRC;Z3}:a~k+W+E ~Hbbutᐙt䠨PXyC7B~?=]Z65ޛc?" >Iw<"-G뿂ϕ8j#9L SFo&B(?gbHy?roC1LIW,LglS7qRv7ߛB/53CL/O(-_3kJ+4J^wa`nU+L +)\Ӑ&CR.9Z˧Ţ4(KM|ۗs[0hL֊+Vt귃z0@Ţ67F(uJ (0BĒfχa ̫Z<^^8.>B=*Z`ŵ_ -\^N1^:>q`YD;XZ]r1@l2h 9p*28%!t@f!XZH1B%arݻmZ˥&^0DT,J @ğ bԢjU1WVmT,J X8\05Z.Mtճۛi,'߬L4X.X37 L(-d`[ 4Cl)nyQuR1no,!4cE72x\\-3VVr{gzVTEi!w&|P>HoZ8BJ4gx ;y[QCw|^,vԾf3n S_Kゾ4H {Xb /+>-Q xDdֲI^{W5]4Z_h򩐡}(Qď/j$G%zOcՑsBBSɉ0єhGoqηB2o+6_lʹP@D dٱF:J%d>.*翓*7;؋)p}.AXXh`kM޸l,|TL\2RJHV- d6O,x+E :  ]a\CL6r1(wHNXV;p5:B4DFlgDB)%F{heg`دYnO6UnotJpj|2`a4 B>OR!nggX70_^XZJ)1`uqXI@ZDrLT5;p@Jp{-mG[I g1jau(F-忺'=F(lVQ"nj 1XD_$,>;T)o۫߶WYd%/=LpqeǗnTZ"fhs'E7.vyjC&p>K5wA<FIN^_UT2v2涧 D&#QAM.u1B!xUicP™]>V7ofebrЬf ;M 9i[ o7ywܑr,hL4R!%<.{Ў j\qaTJ >!2-*YXngn=,ib{LDD[}ŸuO;֒x_T8>g6 pr7Զ8d6?Y)]o%h'8%#5+s6柬먗ĨE1=vvxc^u^G=u wJ)1Wi-p +6l4ڸ`Y2q0kF=eu0r1&厝v-$s}nFj&L Dt0-N;KoTN .XW_wa~[6w!S1sUHŝ~t_;e|۱ KML"&;/:6W~l})'+X0ai TDUfo?Wo7X` 1yV.:u1. w8Yg3٘` PQ攠w4Hq.*dwfg9 7V]P}W۠gTg=;w%ws_ո}OLM.ؽ6-"|wz;H9|cLUS{ns}wYʫʫɇLjxRYXŗ}xl~Bo4.ߢNK?j!4$&~;Go63*/|zy'_JFOu:aZ>-[m\[}|_%+ >=m !tyۼӖ5vbl҄73Üƞ"x D|ބV|2tfrlthV<xmǫ'}xkfФQq4tqvvlp(;9~1R%r>+-$Dߒ4 ++jZ:=H?[$G tq8 $68'\Ji.%W?Jc8B:hVdfȚLœthfj i\ҥ&O56<϶twY;Jˋph<گs,ؕT2mNܙ[*D^c:Mߋ \[r%v_-;@kipZ_m3ϥk֘3/gP;?֫N&@:|6_usIkɁζKz5۹mf:glc~n RHymfs4j{lE];-Xp Hmx2נuzC] r3|6h,Z y61m/.율2}OF `KxO0EnZF+3UKJ^R&ZS!5j_nL|eA@kv#pz4iy%Ut" ]9wOҗ͐'-(?'ndmF#m  U \.P1_5C)#%?8`dqA8)> iQ:ѩX?yn|anf7N#o0ϫ|SDA;c *t9wnͥv~ϜܘrWnĻ_~}TqڒB#%Ӫ=Xmy)Ύh` y!Ϝvd$Tz{UBz>5H=j*PD(TvjNn +䞡s]QdBJ<7?tKX5eeNhm&=! `Jty>_?Dߵ5xZS}F罼 !3}|>ȉVk[Mu5ڄ 8\p톖XHdĘ1m[!3_Oݰh (1bёȖ|K(Nǧ;"\Rg TΟ8BdrE>숙c۫L;lᐙ1$*j0Y*|$VZ>uF?V tҺ+V J  p\dPRsÌZr_B"KsαqP9ZkA1P91iرbɺ;I=Ug5H%#~ħ?P)%>rrKGQ4';wU@z#a{nd LY3_o_{-\ۓtAYtq? ]QsvUj X@z#@?yZ8hu W '+6X#`“Jv#TQ_ŻbYw%S}f.zCk!1K)iǯYvbNӂeAi0@!%O, Npb]XEO|tc GcJ9νFN4?Q\5Clb eMJ ?:$ZsSutBUSt])+px`Mc Ɋ܎JbCXz#zq#J`wo-Z'S\%B˒ԏ07 72Yp}bBrOo1]QgGXQQZȠbQawj]G14!-kGt3#xkNcٹoWJؙh(ۂ'Mb\\cn2Pc彑$xl^0dc O}N{~[`W㋍|b?8Rؑj{QZNPQ3 em Pj4P'ؙCO`I͑[<^w: XGiE#Ä;O \!bq}Dx'DZ2[m>g6 pr7Զ8d]fMZp֠!t"Q,1"gZ_30\%ȊM;q4gn^ ϛ/7z  `(y4+fip/y-y Q }2d"1+i4J hI$.T p2qHrsT٧sې^lX ڗwNHq{J@dp+nj߶ Ŗ) x &h22V[}K@k9&[_Vm-Ss0lf; 8Mysېm7cdft!rJ˵>T)kmHLqE uff*IH+\Vϴ6ďO">(+$npST6,h4P$B~ْbTDɉ8FYâjx0vI?ݥ9ZʭƽDFVV_j^t0BG O&2,&&>5:.xPq>i=nl_헊p|K]e\}ԧ= is뒸ᒾ72UعqLxsz_~-=G&O~lҋ+6.2~ZYzOsÜl>mDuc gZ˥{r+8MtsdqY}gl\^"g@eJ2uZfebcsӒ3 `!ّOfF|->wv A Y̫$}y '>n|RXrrFj xc | x;(w ֿb8l74Pn(1*ߤ7aO,yۃ%ئR[|%#yZm(óIЙO%gfG^p==:fZ3Mnnh) ɈJF#ů>235:/ [f OS+nlgY{Nl{;ChĊ+GJk-4FfeŦ;Ϯ ˿BGO }?ãS19x]JFE ' =el;ӝu-s/ݺ. )~]U7~`|:'ߎ8<}&CgAX??o;{.Rtl4P#D!yC9QS7n NoP!l=H/ y*+s}Mrg?rS'R .X^K B##g8z™o (-dcw[KtyaA#卝}ּq&n4P0J}d 77[uHP;HWx1 U /J2W5%ev< -eKMda&6FjR [u9PdREa%,g\f ]j" r?hRl=H9,yC;3߫m*EshuT]oYa[0^, O:9Tc*w|r3Zgo0{j!䝠,Wg-$;N-Mtճۛi,'߬L4X3gi\@< W 70g옃?HT}: S| 1 _+7V % q3tW^;~jKq7?GJh5юUMNk#ʫ6Qs;yd-͕1L/WN>d^2t5kZIm\oP%#a69*s73 ;<4)NӸBΥ=^vFudn!Sgn m|{slQ8t}=-^V\l=czpc7,J)' DFEVEP4bpI% fWٔ#ϣ8q*\PZ=B P䷗8wj;RvsG{7c.[M*U3^BIDAT/WNJ B)Xtō۞ \qِe`;L|m٣F:JU(\[-,e>|X`Autp;`APZ (-Ai!xĿw-! :iq A?B"J APZ (-APZB (-Ai!J A J APZB (-Ai!BAi!J APZ>) nӏV |APZH_uBi!J T& J APZ=(- PZՅwBZB (-Ai!J A J APZB (-Ai!Һx p)j!(-%?ՅB2@wJ A!({B?+guPZH@+ wBZB (-Ai!J A J APZB (-Ai!BAi!J APZ (-A0Rמ(* C 8B5r&Em/ C !D (-Ai!J Ad!Gps h; (-APZ2@@;-Äˋ*Zuf2aB(/+)\Ӑ&CR.9Zb2+Ɔ< mH˸Bn.'~SKԗWjH ^Bj*mgmkZk\d}V_̷}o:!ј@cV\*{/T:$& ߪ4ۅvnޯuu~޻ dJclx6x0\6UIHlZ=~>1?uָǕQ0a$%$m=7ZWwlyjpTIaI B/Humoh[7@Ƅ hH8BKNc [H`/6˦Kٛu J/[baMbXu|:4y!Q3-ZRr J)!Yd$B2 N?D*n+m',LtB~,<byؕDy5!k2%~&gLXt5UJ V'* ^="s=jY1詓;8ߑ>$M絧SѳT(oݎL8B*[\|#RE[*j-zLI6MӒ]Tu9ѡ0ZdN#MT\ZޠOS>=Vߺ\i+-;T)o۫߶WYd%/=LpqeǗnTZ"fhs'E7.vyjC&p>K5wA<FIN^_UT2v2涧 D&#QAM.u1B!xUicP™]>V7ofebrЬf ;M 9i[ o7ywܑr,hL4R!%<.{Ў j\qaTJ >!2-*Ypngn=,ib{LDD[}ŸuO;֒x_T8>g6 pr7Զ8d6?Y)]o%h'8%#5+s6柬먗ĨE1=vvxc^u^G=u wJ)1Wi-p +6l4ڸ`Y2q0kF=eu0r1&厝v-$s}nFj&L Dt0-N;KoTN .XW_wa~[6w!S1sUHŝ~t_;e|۱ KML"&;/:6W~l})'+X0ai TDUfo?Wo7X` 1yV.:u1. w8Yg3٘` PQ攠w4Hq.*dwfg9 7V]P}W۠gTg=;w%ws_ո}OLM.ؽ6-"|wz;H9|cLUS{ns}wYʫʫɇLjxRYXŗ}xl~Bo4.ߢNK?j!4$&~;Go63*/|zy'_JFOu:aZ>-[m\[}|_%+ >=m !tyۼӖ5vbl҄73Üƞ"x D|ބV|2tfrlthV<xmǫ'}xkfФQq4tqvvlp(;9~1R%r>+-$Dߒ4 ++jZ:=H?[$G tq8 $68'\Ji.%W?Jc8B:hVdfȚLœthfj i\ҥ&O56<϶twY;Jˋph<گs,ؕT2mNܙ[*D^c:Mߋ \[r%v_-;@kipZ_m3ϥk֘3/gP;?֫N&@:|6_usIkɁζKz5۹mf:glc~n RHymfs4j{lE];-Xp =;o& ܽ*^*AAA^^ֵszz]ݞ=ikٶ+(\T(xf1!@"$>Ld;}bu'>eJ"N5tƱE'Ye'K^IQw"WxfP}ߊ:GFyͮ0_&"dϵ/ ߗʷ;6-)Y>?؇[7-o}uw4.7lA.P0k 5ycQ<:9!wƽ۬۳bLWrٰf['- "cok]"!0L+*&=ZQdB` ߕ]/H]0[bV^. _cVdR8UKPnrt9}LF8'AN5qJ %ڒlhTJmlߜٙi톐ڦpnn?ZH?:uC.ߕ| .(άThz8hhF07l&D׃QfIf-F-GFk@ q8S2T RRCrؘD>0D A{Uk7A RV_}nl ?]^Sդ)p0rֆ:'nDҏ6^?^]+Q9+qD;G-X+ i=Q =A80YI ᐌg!䞋pH?fQ P i!hB/_LǂIfº'2d m!k&rɓir)1M&%=hӚL.1?]Q6t: FKC Zr&Et'֜'u(J~7W<߲[T|z+eJJT?HZ1ĺ-]oKp^OjR=zmEl.QÄ-s |Ŭ8/.n5ݱ; \?Pck!F{w(9x͒7*Ԥz 1) =}Pd0浻9 K7p1%Rd#ڜ0&f)L$w1eyBB؏A=Mܿ33&^#݃* ~ЭxOUD],O[V6{-1V9Je׈RCJb,#4j!{}]RUTQ0"X#xs H2]>hB3Y>b3>l$-sz6f1![`Cc]NA.ƃniqZ&lG>/k&+N8R&e`,)xMw1ΩVtf]L ^xO~}d[5d >QECo$-#nZ ]},kk/gBYOƣCҚ^Yj*$DpIw'K+U_`FahW$_7ZrE<,3p2eTA a  ,t4yҪnEcb6bzT ޜ]HWђVK>\Xjka=@0B1WUmKJRA<>2hUXt)w^aS$ 1lٱȈPOr,iLTZO:;;e t^ 5:+HS_qOuoh\lhKDBUcA謓Y6mN VoÙܥ_J9fx8&}8 B"m N׎._55- *^ (eV*dOVM:M&˔D\ k\fQg31Y/n#g@9t1Q%:6HKK~}B xn$>\EQnƌq'>GWR=]h˯ J羓wGpZWd +$6M_9EvoV{^B cL+{[5޹MaBo^9/0h'3lzw:r-8 EAj"H%Av 0(5dӕF޽΀7vsm߿Ge Nݐoa病7upc$y:-.?GN&}!?}x7'b7 5IP}e:R-/fg yN y8nSY'Ѽq.v^ɡU:ɘ'GuR?G_ 3m7=]Z U҈ y N!9lLfzqfzGlQ;q n"ՉѥHz>G촥9zZ3~4gfLpW 4*01?9e|p[8yNfѿ.Ͻt[2kx6SvfOr?qr|Fl;SƉpwb+wgp)?rȩR\H;pe&/uI1esvȲAPح"1Lݶ53 1۫- *ʢu5 ?1Ÿ WPZW};_v:7օ#Չ{ߟmoma5J5?5`˫V)gQ"&(j`[3xMjV"eUut$P1/3*OdIxMkA/Xphݗ1|t$4tLޝN/ɮR0MNu%xjNH|)T%`sc$Z <81?M$*ȝ}߇DoK,/RZ6yL, jGYYZ p#2%S@7`?8 Q a%$}/?,ց:?cJ~wھ;+gTA, @d$UWԊ'תweRЃaB`"$-60ci$N!6x2p)IziI%|u@:QXjz'.9Ps V8 &UѨse@]%l~w|ڭ"i!DXqecB>p8e11pcҔzgeB帼*=lIH4Zg'Zct9^qcDsY6?K/qJRȅGm?"若WYRnX5,3fbp"` ⹂ bk |,az|wg& ͚'V_)~bKt_leH47"Kqk2Cv}@ !@ $-I @B cbtAϵ4!D nBH^ "6@B=uK ?aIENDB`OpenMesh-11.0.0/Doc/images/mesh.flip.png0000660000174600017460000001134614556675336022021 0ustar gitlab-runnergitlab-runnerPNG  IHDR&>sRGBbKGD pHYsodtIME 6 tEXtCommentCreated with GIMPWAIDATxݿoaϣ%Cn xKhK3vi*t/NYK7 PYLdR 4< -Jp/ɷ>")Z!cccccIIII0&0&0&0&0&}!`RJ?y^_$։$(\%X׵΃1"hƵ'@';2pnj-6IsŐLanuj!$5_3Rdsg6Z?qZgg vLJ)CG3~$ۍC_0&0&ypw1^ ;>w$[N!c/l ЩOwVܼ{&~jcVIm; =,h2oQpXF:MVCG돒 u}~$ML$cVZ~k} γ,ɶ]J^fo_^;./γ8|ȐLZ])I cL"0;ǘD`|Oe cL"0EhtcyI>0BcLxǘD`@uc <$#4:xǘD`@ucR`@ucFhtcyIyIh`@1&y7&yǘyǘ#4:1 1 <Ƥ <Ƥb`yǘD`@uޘD`@ucR`@ucR`FhyIFhGIFht^IFht^1&Fh@ucR`@yc@u^IFht^1&Fht^1&t^uޘytޘD`yycyIAhyIAhGݙC 0$Oˈÿ-]RlR^RǾ*z:\><:oL"0B^^keeOIz${:~ΣsPHokZm)er‘Bu^IAhX ܬ8M?ɋ$ZkYuvaf$>NyWI$7{I.y:J2}nt7&okWII&2l'[uuZJ%y>ي?ogs*Ks$kI-:6/>sLnpjLvJn`3^\|K[ycR`syMK)7=b~9qA{dІc/{E7}nt?-0Ou|mP) >~`2CC:, =~Ӆ8n|ף5~ϰ/$Wytޘocm{ܮ呹|+F]\::oL Bs(w8n$R1(t7&fh>Ž32۸spv=;FycR`üc $ϲ*~ݜ#R'Dž&yUJ^<1)0Cݟ _y{/q7&KI|ytޘytޘFh@ycR`@h@AOuL B::oL B<:oL BcPΣƤЀ΃ IycR`@ycR`@h@cQIAh7&1(AycR`@h@T:1)0 ƤA :B:NIAh7& JytH:߉1)0A! :oL pd?1)0`PbH%<irL ICt;?1)0`PbHw3& J I{?1)0`PbHICnuL @;J)RJ_``I$ym-syQ)u7I^&y]JySJjshm_RRc(/̗- W?H7{"?H2Nm?^s$jSG_$/'|\^֥_$Z}{]mL_+~V/1vteykڦmucLls޾c%|aоÅm[Nvs?}ө?ryy*L&v݃w>&qoI0&ww㫯O~o!9^ro~p(|]-aE 駻~AcOO;}>}]~2w$o6c+#-8.]LR^f`7N|o Z8j ::pf W_:$Ǜ]=۲_;TW?߲zYRWY'g2ɯmmÌ7Iz$v~ejс{;Ņl?m a@$m0_`޹]0I?'auK;Q:1p{cܞnaP/cB$%Ο=0$1(v΄Ѐ!A tgrF I J{?;3#4`HbPwgv I JtϔЀ!A : gzƄ I JycRh#١AA` I JycRh#YWΨ 0`PB$<:D? JycRhGISYϼ 0`PB1)4 0pj?; 0`PB:B:ΟRBA :oL <:oL cHΣƤЀ΃Οژttޘytޘytޘyt^OqL ::oL <:oL <:oL #01)4B΃B:B:B:B <:1)4 1)4 1)4 1)4 1cL <:oL <:oL <:oL"4<:1)4 :1)4 1)4 1)4B#0Σ$B#0:B:B:B#4<:oL"4:1)4:1)4 :Ƥ 0Σ$B#0cL cL 1 1 <Ƥ <Ƥ:::oL"4:oL"4:1)4:1)4t^1&y7&yǘyǘc :cL cLrǘDh@uޘDh@ucRh<4cL cLrǘDh@ucRh@uc<$B#0:BpǘDh@uc <$B#0:<\h@1& <$BARkuxo0J)IIOZo(:?`"Ӗ^/{ZkyI>&4IzIOXqM=ǘCB$7$Rkй4w7γL[ ɴ蜟l1$Ӿb7(d;7IviO<ЙCO9q$8$dtƮ `L`Lp@c ӫoW쪦o( S#Ħڀp0_}6OM [׭ބf=DwD(3 B& !J"I ("*X#J!E))8$D G)IFCY@G(bHՄhz-UBDH<򇝻)$A98 mj$!棐ftLtJ&d3wVЊ$XĝQB;pʓ#S鮼B4HvY'JL+'g@IhA<ì( wF = -rjޟmj!]wJ§:=qaBGCaՐ;<8|#wB^԰3|<.p(" d trJ(  C8,lA=lqBM B&<4DԼKћGC4tAG.bTE5 =FB, /-_"4AdRݯ$‹ ޥ<-P3É/13|sJ Td3Odtyb, dL vL(CUzEX:/pJGjKv1,N b(Qe!)p f!)Vq m (G1c3AaX*TC8v->iP*(\ˇb=Gp JG 9/Ɠ|P(OB `T#WT5c`P)X4Wb|@stbd`LO $ P@ʠ !HyI$j[23)M]Gz`猅5 Ȓr(-ebTFТAU 4D  C@BUzaХ@H'Y ؤ(2n(x$?y|iez>mRN&r!+);wYu!@ ]l!HFfvsd10X` Yf O;\FS\p EѶއ.ly1&dR@eB X`(dzBBa`<Th8jN@H>hE1!(ZXln-w:A/S%mDɕq1A|!ɨOЃx"<WI @+Z8<:"Kf|)da1 @)k$).kD(༮*B&l)CC5wp P"K ɰ32;O,1׺ӓʷ]l=H p1]Uv3!Ⱦks[:5BV0xH.lǓ |]d@XT/DJFR/ %5w 2SANH _v6ΧEd!IdkOT@sN@[; NvF0P@TbtkC2HA %>*l"nD/xM"4K?Oql * 0F%Wdcਦ׽pD?c ; X h# \l!Bb/Q Ri<T^gZ 8R (xuI]t"RMsL nXOHVnB? 3 ]~xw GA|U' rR 4+jt'ZzZXr! g P 3 Fb&RVf'XB>0W 3{P`mz2{-PcQbCc_ }s#. .(XԈXۈ. > ]   ؎Ȏ(Hx󸏱@ 1G%P= C0@*$bP(Ȗv \R^fTn'&l"t uc')(8d"(OBu,b^Po<3v$FLGrd" ` P #Z #SN RIZ`SWYR) \)09q &1}Xy q)uPb*| =j  oP@w2Nx[` {/g=oW "doc 'H'̐ C 0gQ ĠB! @!sP}沌@ .`.șiٜ)ɜi !CljI1Q giސ h { mb`&n mU) ^ S p @џ^ 陞J  3TUIYFSwr+`9Zm *` WkEp 1Z6ԗ>B7ޙj.s.> o:u RK&P A a@ q 0;Z>)|oO0 "tPgZ x:]G1h&s$ 'C.qwy)q|8a" ~ 1|r J<޲2@JXtak٩2^JQp&<'j+@L:zn  ~~_H [k ^ +Kp0[{۰۰۱ K{\N , TSp$)&[(K_}ܷ~ @R#XzHC Zzj.{t0b+P pt@0됶nom0r{prmව }K{{[ykՠ;jkKbK +Pj˶+c+}~[f{{nr3@8! Ж+Ȼۼ;[{ܛҫ [O#:0S;J`S1S#aYcYayۿ<˿ ?2Vj:$ j īw2 @J +k¾!⠵t@jnl.:_!<17!;K6 I<P:7z!8̫ëSK L@ &@)K'alJPkni6ۺ! @QxPu HA` @Q L3@ W|z6å' u o  RAv.`V(̥,aŀ ` 0u   l؀̨ @ ! ʯ, ,| t9Q y]pF0m|̠@A Lb# 4V7q _a/Ώ a` P&  9g id\  -ȿ6",In& R ` 3:ԯ!B'L6q I ) ̰poؘ9+lbj)5īmKopQ" P@AkmƷ|VK)YK Ql}&@l k ̍ t8+"՜ ե- M0P Эʱ]J}٘] },ېy̠ Mܠ >+컥*|ͷM  Mu .Q Aڀ@ /MM| N o/ q Z `Š ߟڱtڍ' 5-2 Ǒ&nSn@7m _k`m=8!ӼpGL/`~ =Ba| PŰ޻Ժ5=Z`& ^p]Mpq33Wj ݌ ^}s =Q^žxjظZI}o xP;P&̭.*A&^ȶ@ o Ů k @ !8֍ሬ|>Y!M_=4'P k.6Q)O4جo FwI |11,p3a^s& bnm_}nNجao)aC,a &b^^m|=O -^n.0A/Y/k A̠^ ֬M o; o /Ž<>O4F_  ɦ Ѥ@@О=m MaP -^ĘQF=~RȎ:֭"GRpQhݘ5?M=}jS|!HA>ȌSx\\Pb0VX3ѡv,c.!thZEW^Çm RSM `W1H*Ԫaĉ-_k%f"h»)3Bȹj$aQ5gf"02(F\ٴʏɣ%%/ë\{rm9A{#3u`rXb,bo9eA.rBH ?-ӆlBo#싙0,n0BbN-ڢE+91ưD5<":PQF @*P2 (|d2(k 4IS@RbސM<.t,K$OJ)Ą3.Xhύn73bܐgC%Ԣ'' HH&JG l# , =GꐫluT82q7(Y|$4 M1رi2CHL,Uil$D[ӨL5Qr(.6*be,z"+sqP1K;>/T4`ᱚhe,R.d*mA5|ڙً_U& xoNH؍֮;|(+ؽ&Ulą: ʕ掛7#{Բh gM^);Ң:p`*|72. cXW#޼*&^HF2HA>$ PP1c_Q  tT:$[jO1n #X1-*R ;p7mk='Zԃd=Ϙ5|V]q dx/~"&ʿ`>Cry+.5>h ̼!F6Պ4FVc[St}RV)|jL3FG %r Ny 9Pq%df0c!p0&0 7M$`8$  =Vm#IE!V Pڷ!Hv!Hx^އE&4aI: `~BUn} 7*P RIAȓxfB&zWЊV#AP!0PC)pq:GIK8'yH};.o)7#uȓğ /d0+ NvxD $?yW|5oD 1@/z!AG}T~B@ߑo}+_ɐr~]=={& 1A#W1J/>j|}N,!I ؀V 0;HMȀU5@с h@h@ @ @A"@.yr'@AzhA'8,A ܻh)  A$%AwpAJt*.A!@p.,0@#Ҕ>#p/7qpf @H\ LLtpNÏOpuQy?C8hΑ!0@U?d]hOSҎh o Q-Kg@X8h7FK5"@rS蹘H*DQF[Ʉ9eՌSHU(}V{)Gtu` hjUQGT'NU9]SSVUVhWx݈Ջ(z@,=ڃd툾SP`8Ӟ+pH,85f%WVXHi؊8?@=z{j\Oe9PxSyTRRe)БuXjÍXPh U8 eVgX`)pX88UeV *+ê; $FTht +(W@@H0pb@wu(:SREH"KpUUN1≀Ĩ\1uTMQ r0r݈֏ e jaTSXIrKs ?0 c(;DV-5]`Ӳx^ێO XT ]LU+ `8{(݄lh>K"be`c:f-87]V }]<@`qZ I]( Z Vo9+&B׌5{49%c8 "(HpN^_hۈ_at:3 *WdR 2YBM3`X]CH k` a?wr*Ak#?X]൨bk#ACGd@(rXd?0(SNE.$扎-ΐ;p6tdP[ȸ8\ <HXBDc;hbdަk-b^Wp 1p." :8 !<h,'ވ(.qy.pzvgxgxn%xF۠/IgxNh2Q-6,x\pp0cÐ`lafXfgA$@Z 9]ЂQ rpY[^g8o6& j5eEtF3r@ٲ8䲸1Ad)jXkr@3ƛ`X1H@ "X! CQÅ|\8;׵%Yy6P?08ߏ[f"jYj@"X P Y2f* } | g1* VnjSj !Τ਺d0 1 @VȄL [u «4V QH5y@^p<i6i;Б&jbHWdFDW]]R8qXtq"dR`C{ ю97)-C-Bmӧ`T&lmT=6dZ`hn1 !+Sh! b H M! s'd gҤ`pr )IA*92A/=) ʙE+-/u-/=S:t. ,t*S *T: !4Apҙ:I5I}댣~S*A!6pUF3a;e+ᜱSoǽouDAٲ4;5Dy ԲnY&rtBHb;h :P2216bAehCU k; չCv+ͤO)A;XqI2d^3HJa"*P f(H <(CS5iDarAa{S`? =c5XA4omAS #aVrIaoEFpJԝ9 ΁ TN*hYƀ PV a 'SPұh%l &v`e|J +h M0ȄYꈧHbD*4Pep QilV e@'f!|Sc47\$BBX\{1sdCQ8H-Em:L5QqVF5l#cV['5D_.[k(j,tbh d Vl#RP\gfBXDŽ v~؇nE =hC;fR9roMIJ贴a% QҶLCO񨧾 Iz AA T,Z>#m#{҉J>8`}=NQC F$T?*ȣulfU ^ efFvĊȆ Y2Qv^=ի(A@6 C!d&<@6\4 iTA&%R)"=H8>EkgIaJiZUTmqY b@P.\Q5$nEK |*ZǮF7 ZhE5ȅ]Ӆ(8!ݯ60P |#Oa P0scE9~B8&EpACtQ& 4l%qϗʮeAh%+>a <(bMo'hHJe) -%lh)@o4*j9cq-Q mݚw%//NJvV߫Z?oZ ~ŕDb5eހ r!u-r 1; 1>_Jd Q Fo@S~0|1!PmPt16Ɖ 9"!!L11EЋ>[-@}5m/\kv~o= pnPBr1~< h l|VAK++4ڪ  6*a`f07*``#M/>6<&Sc ի-ĀR}:nk$ݠ5>_F@afC+BK @ nɪ` 6**kʻWmlz6A-eD~q|< mn~Pn`0^I.B,ڔxF% E[qC4[ܝY*Cە9[)= ͎ĹTr)ׇ1B<`n4mZXY[@`rE`_ Z08^ htar<=W7ŬA#x !0/HQ<(CM_40i *DH #B"][P(hŷ-Dq;÷>!=!\m#'@" jT]L< 8:c.Q# P/f0uje'>t`qUlm`X [4(W%Wr^r :pi)^VAbޟa6BACF #܈Xa`SL)BH:)PcP u7=EBSWW`]jॵ| bЕA"(܈^.AC΢(d">BPh2[h,BP2ChC/ JeY1U[ey 0X5&Df 3Eg )4DPbl#">@-!S&S&@~妵e[KIPDM&BȜYD~#.CCJV%j!~-p^FvG2Gn+dC> 4V]dSԂ-"c;AF$aUL>ASkt(ShHUdRB&E-(Ş0Buœؑl^>r6B< P.5dB؆m^7Z$>؍/:fÄ.J 2K.ABӷvK> A42:D`099i TeFiNpuxhP4fR Vy9Mu w!&zzR{.Xv.P+C\`āC]Tfn@wnܣĄ. ֒8-]KJ=玸/33?C3(tjJ- .S&(dT'F4:)+0hXZSA6hl< Ef܂ ~^r0upʰ /0xF2?  : \/bF_tP&b$kl\.go1w11@1励11`B@1c1k_.%1 1!!c|o uiCcLP*뚡DZzP‚8)2**2+2`A/HC,Kp-.-2.//m-,r+*'32/)r,r--?B/CA003773,K8G.3993: 3s,2s733-r؆B30pRt/{77p(1B<ȭQ>F-h{/I5ABЦAT\tB(2oDc$ԂKׂ$Dn#'0PH:AXB`APAs` C- -9xBC0^W@Dw iAX4RIFoZ4,HCI{0Gׂ>8BD)ʵhm&APD4,0l?5)|B)츀69'<`g=ow=}1`YZ;A CƛIfWC=bA(_;}~0^1eB?$:to* >`~]RFғ- 2ԶJ+aƔ9fM1gOcuPKC5(H :a` ]IUN!uEk\ >P3D Ac6JzTcGa \ "+C$g;T.MuS: ]\DW%Q I@1-7Hr`x-l oBXТ50jS_X5*4Q(?:K$ x@wn(4=dNqA ~($2 6z2z$H0p @mk9C?XYBXܢ.G厥HayҠuHR` ) p6"W?l6~2$)ޖ !vd$ym0x/0 dPCUC`@g9#Abש&d5< +@VJVVX!UT0 ;! vFk3.B62dhA8R!G^2G6o1msP d#2lPD>  E j -wI @9.s{PGi:` (E~..^gXӂ)SI0vδzh VtL8P2=XlJ, B\KQ*p`4 'U@cC>ERa6@c(-Utl&Lhu(E\ &> iqk^6$"os`9Q=bT]TA'a5CĴ|6~6B-k |AA^"?*A%$2f8$.94@$ /C p 2wrBtYx Ԡbb!(K}X4r#v*3ZV^Wm~Fy4g~!CQ.U#4;qJ 1a*!s* ~?3""]N&(BPzB}q*n(t(g žo*epxBʑw%,DXW*v6AJn;@j=/!!8W"ᘉQt$ 2qq|)3(6 UnV!j8m xVYc S( z`N $J$Nq7$tAdT? Т}_r Tas! a  ð6AluvыT* Os**rrcR5eU2e<|Yܠ5 yx* `{)^"*Xa9FZ0w֙Bb̮ :$$>Y3QW*t_j.{r- v paZ9Y,!C85K/a $pr..w(T `KNpj! b-@ %Y+ZYl׎I dimdz`; `iYϢ6Ӛ@|$*>[z!⚳1Eb Naja ^A0y*v#b^G!\MZ$"[O%1m”פ!S٩U"` bMLMM t 󐣚o5o%σڊ1k7Cbza! 2pl*@b?QY#2KFvZ\!OC.z amϳ>B;[S f,!6"w_6L7&*+|}d jwV͛@KM$Ȳ!e:NmSaڀA4VY\;C#ʇ F:Ta@Ó? b-lw$ej/*D-7H@) rN7B2;iD6ەt-zAPRjv%L}s15AĩB r;I"`0 9|oB/Aɗq# E<*X_:]3G;z)>A|ej5 t6ax ^w9\u'f{;kѓ7\^=}U,U4?y?m^|#gb_ˇמ~oʞ5L1|!>~B??gn!;{ _3_A?- _gzuYXnj(3o^ӢyUfǞdk_Vk\k.Ѣb,DJ_lykYN9)?+M <0… :4i*r+ZhpZқB "q9 L.()*Dǖ'gClުlg]\zҊ&婧R%2("mbР>+i&ɐ(N(UI䊡Z% 붷e~Pc5ʻjbQA c,,Z_fhAK i(p6Wn]n]=iXV=o6S-ONί豷ecy62%0ZТ 伥 C7'%EZڬr/26aMLpX_y@!XwQ<8:E)B{k&5tM+"`J@`m -d XBUؤ+ Jѡm*4֜urCv0D @AGH`f\a0 2FB-wY&` x#-H BDYAl#h4b!lJL0&,0AhLB bPc:.Y 4' 4(0l$r|@1aly;bT*B) Z i)?9o T)Ɍ(@k(Buě48x^xFfBĹ΂L"&1!SfaF.^1fL:d6cޕ(!brx C`IVq7Ԡ?N-e eqQ N}R`i/X-T83}DC[ ]8c[q D8pEO?8j.@"߫$ǂС9Ui]tق޵ #()Wgء^ZCqB@S`#^51Z(lOA 2ЫtA 3Jˌzv@%U89+aB>Y\lJ:`b=jXA -C< ,`P v;- 1`ńaKx0V`tHa/q 4X1^a 9 |XpCl hX$הaxZ B @ @b@(Ap`Zt`>d> c6$tA=\bN/QbdMQ0 $dG ! ?D>BѵZؠP5 W pPP b|y3"g7y(~\x#zJpPxm|-kh;X`Fn!l `2vX]8^! 1X(Q ]l1* #d-(<!w0@04#GwS&!ptAPh,C<*( Ye˰P!vD$ xA -ͅ O,* A6 E@3v Ihe^NgH WPY:kSTV=F,"H8 p;H',a5t-bq̂D h!G$ $`@]. khC&:ԈQ$檵MPCL@H @p YaќnP w 7uGxާz|m@Gv1q j] J@ d ~lyFcTm >pp!m!cm!E &)2A>PE7v\>w@`n JXoQ%KW> cZԠS8. H~W3H}rrb7gE;(35WUfĐav ` Pg9E0cY` 6P@[{&j0v 0\>ȁ}gr5R@ #HSxj^vd85b;A_eHEb40w",Py2 ;.uOX{jrZoo `/ qvKh1Boh Ug}} Pg'~ x/-c~ B@0$ wG uO0v Aa]PMB<Y׀ ]@t1Q#q0p ANw-idTx0@+Q>)2jbRRX.WMג?puoaU Oxh,j& pQ < KP@ nw8}U q,c@]+FS0"@=` p'PMw|Bg V)ptd`}d u~p>[a Agaw>M5; ؒǛᛅhQ`_;XyA "2" PaFmSE)f)B~UU ʅ or{u gxu q  HQ-hA) Na s!s`UzhW8 h{EzVg BFaqUX {&\ }PY `Vyv  "B@V6 j PxJg u` cP4<4ɳ P2E&Ep '@PF}wPǧ }P"" j# PM; E`7 "p0Y봭 G52t~ CćQD[H"p@ t CKPUg S"@[^F`;@F@"B[s `k )6U<%ZƱ t`='V$m#Ca!kw=C8# A !+<4Aekmy%:PaulYClal8+q4¾<;Î;p ,PȉPyXy 8e^C|\P;RVm,)%Z!(` -,ƒF"ACAL3@%m'M , 0-1M27M35]9}; <;+1I+(Pà%ٷ 9:S@ EB Ȥ9 _CȤd-^m@^]mmgi?,pCl~Ll -ُDYٛٝX١-ڣMڥٿ{ ړ-- D sņ 0ۦ -ܿMܢ]۵1yqy,;[*!e k̹ 4ޞvfK q |Rlj3m&݈18{ɍaM6j16H#%>"n"`\ 5n79;`A C0`X`j@LTcQ.SNUnWY[Z^c@cp d>0\ q.sNunr^ycS@6B@  `臎艮苎v |SDՐp`١. ۤ. ^걍꫾۴ ه"T@룽ܽ.Mn=뾽 ž~خ^ڇގټPp:ߎ #0oo  /00#0?D(! !$/')+-&o+.@7/6=\8A3/EoG6נ( 6_ 0UOWoY[S_J<%erfk"8q/sOum{}_;OpenMesh-11.0.0/Doc/images/src/0000770000174600017460000000000014556675336020207 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/images/src/iomanager.tex0000660000174600017460000000327514556675336022703 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \usetikzlibrary{calc,trees,positioning,arrows,chains,shapes.geometric,% decorations.pathreplacing,decorations.pathmorphing,shapes,% matrix,shapes.symbols,positioning} \tikzset{ kiste/.style={ rectangle, rounded corners, % fill=black!10, draw=black, very thick, text width=10em, minimum height=3em, text centered}, kkiste/.style={ rectangle, rounded corners, % fill=black!10, draw=black, very thick, text width=7em, minimum height=2em, text centered}, } \begin{document} \begin{center} \begin{tikzpicture} \node[kiste](IOM) at (0,0) {IOManager}; \node[kiste,rotate=90](PD) at (-5,-4) {Persistent Data}; \node[kiste,rotate=-90](DS) at (5,-4) {Data Structures}; \path[fill=yellow!20,rounded corners,draw=black!50, dashed] (-3.5,-2) rectangle (-0.5,-6); \path[fill=yellow!20,rounded corners,draw=black!50, dashed] (.5,-2) rectangle (3.5,-6); \node[] at (-2,-2.5) {Reader/Writer}; \node[kkiste] at (-2,-3.5) {OBJ}; \node[] at (-2,-4.25) {$\vdots$}; \node[kkiste] at (-2,-5.25) {Custom file format}; \node[] at (2,-2.5) {Importer/Exporter}; \node[kkiste] at (2,-3.5) {OpenMesh}; \node[] at (2,-4.25) {$\vdots$}; \node[kkiste] at (2,-5.25) {Custom data structure}; \path [draw,thick,>=latex,<->] (-0.1,-0.6) -- (-2,-1.9) {}; \path [draw,thick,>=latex,<->] (0.1,-0.6) -- (2,-1.9) {}; \path [draw,thick,>=latex,->] (-4.4,-3.8) -- (-3.6,-3.8) {}; \path [draw,thick,>=latex,<-] (-4.4,-4.2) -- (-3.6,-4.2) {}; \path [draw,thick,>=latex,->] (4.4,-3.8) -- (3.6,-3.8) {}; \path [draw,thick,>=latex,<-] (4.4,-4.2) -- (3.6,-4.2) {}; \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.flip.tex0000660000174600017460000000246614556675336022627 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \usepackage{color} \definecolor{VCI}{RGB}{55,91,64} \begin{document} \begin{center} %\colorbox{VCI}{ \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, edge/.style={draw,white,thick}, redge/.style={line width=3pt,color=red!50!white} ] \begin{scope}[xshift=-5cm] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \draw[edge] (V1) to (V2) {}; \draw[edge] (V1) -- (V3) {}; \draw[redge] (V1) -- (V4) {}; \draw[edge] (V2) -- (V4) {}; \draw[edge] (V3) -- (V4) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \end{scope} \draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6); \node[above] at (0, 4.2) {\textcolor{white}{\textbf{Flip edge}}}; \begin{scope}[xshift=5cm] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \draw[edge] (V1) to (V2) {}; \draw[edge] (V1) -- (V3) {}; \draw[redge] (V2) -- (V3) {}; \draw[edge] (V2) -- (V4) {}; \draw[edge] (V3) -- (V4) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \end{scope} \end{tikzpicture} %} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.to.from.tex0000660000174600017460000000111414556675336023246 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=black,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.collapse.tex0000660000174600017460000000720114556675336023467 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \usepackage{color} \definecolor{VCI}{RGB}{55,91,64} \begin{document} \begin{center} %\colorbox{VCI}{ \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, edge/.style={draw,white,thick}, hedge/.style={->,>=latex,shorten >=5pt,draw,white,very thick}, redge/.style={line width=3pt,color=red!50!white} ] \begin{scope}[yshift=-3.6cm] \begin{scope}[xshift=-4cm,x={(1.4,0)},y={(0,1.4)}] \coordinate (V1) at (-1,1); \coordinate (V2) at (-1,3); \coordinate (V3) at (0,0); \coordinate (V4) at (0,2); \coordinate (V5) at (0,4); \coordinate (V6) at (1,3); \coordinate (V7) at (1,1); \draw[edge] (V1) -- (V2) {}; \draw[edge] (V2) -- (V4) {}; \draw[hedge] ([xshift=-2pt]V4) -- ([xshift=-2pt]V3) {}; \draw[hedge,color=red!50!white] ([xshift=2pt]V3) -- ([xshift=2pt]V4) {}; \draw[edge] (V3) -- (V1) {}; \draw[edge] (V4) -- (V6) {}; \draw[edge] (V6) -- (V7) {}; \draw[edge] (V7) -- (V3) {}; \draw[edge] (V2) -- (V5) {}; \draw[edge] (V5) -- (V6) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \node[vertex] at (V5) {}; \node[vertex] at (V6) {}; \node[vertex] at (V7) {}; \end{scope} \draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6); \node[above] at (0, 4.2) {\textcolor{white}{\textbf{Collapse edge}}}; \begin{scope}[xshift=4cm,x={(1.4,0)},y={(0,1.4)}] \coordinate (V1) at (-1,1); \coordinate (V2) at (-1,3); %\coordinate (V3) at (0,0); \coordinate (V4) at (0,2); \coordinate (V5) at (0,4); \coordinate (V6) at (1,3); \coordinate (V7) at (1,1); \draw[edge] (V1) -- (V2) {}; \draw[edge] (V2) -- (V4) {}; \draw[edge] (V4) -- (V1) {}; \draw[edge] (V4) -- (V6) {}; \draw[edge] (V6) -- (V7) {}; \draw[edge] (V7) -- (V4) {}; \draw[edge] (V2) -- (V5) {}; \draw[edge] (V5) -- (V6) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V4) {}; \node[vertex] at (V5) {}; \node[vertex] at (V6) {}; \node[vertex] at (V7) {}; \end{scope} \end{scope} \begin{scope}[yshift=3.6cm] \begin{scope}[xshift=-4cm,x={(1.4,0)},y={(0,1.4)}] \coordinate (V1) at (-1,1); \coordinate (V2) at (-1,3); \coordinate (V3) at (0,0); \coordinate (V4) at (0,2); \coordinate (V5) at (0,4); \coordinate (V6) at (1,3); \coordinate (V7) at (1,1); \draw[edge] (V1) -- (V2) {}; \draw[edge] (V2) -- (V4) {}; \draw[hedge,color=red!50!white] ([xshift=-2pt]V4) -- ([xshift=-2pt]V3) {}; \draw[hedge] ([xshift=2pt]V3) -- ([xshift=2pt]V4) {}; \draw[edge] (V3) -- (V1) {}; \draw[edge] (V4) -- (V6) {}; \draw[edge] (V6) -- (V7) {}; \draw[edge] (V7) -- (V3) {}; \draw[edge] (V2) -- (V5) {}; \draw[edge] (V5) -- (V6) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \node[vertex] at (V5) {}; \node[vertex] at (V6) {}; \node[vertex] at (V7) {}; \end{scope} \draw[->,>=latex,thick,white] (-1.5, 4) arc (105:75:6); \node[above] at (0, 4.2) {\textcolor{white}{\textbf{Collapse edge}}}; \begin{scope}[xshift=4cm,x={(1.4,0)},y={(0,1.4)}] \coordinate (V1) at (-1,1); \coordinate (V2) at (-1,3); \coordinate (V3) at (0,0); %\coordinate (V4) at (0,2); \coordinate (V5) at (0,4); \coordinate (V6) at (1,3); \coordinate (V7) at (1,1); \draw[edge] (V1) -- (V2) {}; \draw[edge] (V2) -- (V3) {}; \draw[edge] (V3) -- (V1) {}; \draw[edge] (V3) -- (V6) {}; \draw[edge] (V6) -- (V7) {}; \draw[edge] (V7) -- (V3) {}; \draw[edge] (V2) -- (V5) {}; \draw[edge] (V5) -- (V6) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V5) {}; \node[vertex] at (V6) {}; \node[vertex] at (V7) {}; \end{scope} \end{scope} \end{tikzpicture} %} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.io.tex0000660000174600017460000000246414556675336022302 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,white,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=red!60!white}, boedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=blue!60!white} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \path[boedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[roedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {}; \path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {}; \path[boedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {}; \path[roedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {}; \path[roedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {}; \path[boedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {}; \path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; %\draw[->, thick] (-0.4,3) arc (0:320:20pt); \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.outer.tex0000660000174600017460000000225314556675336023025 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=black,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[roedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \path[roedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {}; \path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {}; \path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {}; \path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {}; \path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {}; \path[roedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {}; \path[roedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \draw[<-,>= latex,thick] (3.3,3) arc (0:320:94pt); \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.normal.tex0000660000174600017460000000224114556675336023154 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=black,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {}; \path[oedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {}; \path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {}; \path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {}; \path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {}; \path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; %\draw[->, thick] (-0.4,3) arc (0:320:20pt); \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.inner.tex0000660000174600017460000000225314556675336023002 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=black,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,black,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,black,thick,color=red} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \path[roedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \path[oedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {}; \path[roedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {}; \path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {}; \path[roedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {}; \path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {}; \path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; \draw[->,>= latex,thick] (-0.4,3) arc (0:320:20pt); \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/src/mesh.opp.tex0000660000174600017460000000246014556675336022465 0ustar gitlab-runnergitlab-runner\documentclass{minimal} % Tikz \usepackage{pgf} \usepackage{tikz} \begin{document} \begin{center} \begin{tikzpicture} [ vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, vertex/.style={draw=none,circle,fill=white,minimum size=2pt}, oedge/.style={->,>=latex,shorten >=6pt,draw,white,thick}, roedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=red!60!white}, boedge/.style={->,>=latex,shorten >=6pt,draw,thick,color=blue!60!white} ] \coordinate (V1) at (-3,3); \coordinate (V2) at (0,0); \coordinate (V3) at (0,6); \coordinate (V4) at (3,3); \path[oedge] ([yshift=3pt]V1) to ([yshift=3pt]V2) {}; \path[oedge] ([yshift=-3pt]V2) to ([yshift=-3pt]V1) {}; \path[boedge] ([yshift=3pt]V1) -- ([yshift=3pt]V3) {}; \path[roedge] ([yshift=-3pt]V3) -- ([yshift=-3pt]V1) {}; \path[oedge] ([xshift=2pt]V3) -- ([xshift=2pt]V2) {}; \path[oedge] ([xshift=-2pt]V2) -- ([xshift=-2pt]V3) {}; \path[oedge] ([yshift=3pt]V2) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V2) {}; \path[oedge] ([yshift=3pt]V3) -- ([yshift=3pt]V4) {}; \path[oedge] ([yshift=-3pt]V4) -- ([yshift=-3pt]V3) {}; \node[vertex] at (V1) {}; \node[vertex] at (V2) {}; \node[vertex] at (V3) {}; \node[vertex] at (V4) {}; %\draw[->, thick] (-0.4,3) arc (0:320:20pt); \end{tikzpicture} \end{center} \end{document} OpenMesh-11.0.0/Doc/images/mesh.outer.png0000660000174600017460000001512114556675336022220 0ustar gitlab-runnergitlab-runnerPNG  IHDR)'QBsRGBbKGD pHYsodtIME  6yCtEXtCommentCreated with GIMPWIDATxAhkZrU\} :r@t()Apq#FQgB7>PPPo$i&{4={ַr{!P.@)R! B@ !BH!B%7t$\[RRGRk_Ͻsz=|:-%M{ f5?7GVC@0RGVƼ{jڅW^~Ƨ PPـ~ѵWky3I]C)?-IKyH;;zKZ@ ZC֌HdcB(D]ӔH~SӴʰƒߗR$b> .l0+ry[zJl ҉MDVа(嶦(@?BgcvLR$ RZs=܈dzZJPjug2$ gTUrZ$?Pj6RtRJrZ 3]BlS[ d@}1vS] 6m/^'$)+f PչAjfRvs5TCVT'SYkHJ f<@}1T/bϺ; %[  fOR<&4P~m_z-!Մ<TLPy~PjG0R~rtSutRIڱʷʾR帨P Pޱf+F)NAƒ7P>)Z@J0U*_\e3Ci:@¾qfB/r*jM5zԐ$@yf2y PUs] z)Bjgm)RVT@4R^}TJ1YUdEʓ{I$SkwI e7I2r"W6P"rjME)+9(@U#bvS9B 7EMjM% \T 8(T,Nj i^WU MU)uQ P%樢sS18& *TTP*aG517~U;E\T) D!3j(sS͆m߮jZ1PJe*v)=IPj*Wu*'ճ7P@ʊ87U(V!_2؋R /CvU8"_-skKen*HET+TeyR!eVGF(Vjf%!_N'),=6, TTtBIeCfڱA @!@,M%ul<$뤺g TϾL hT/sSC*z*K) Z18)Ջ5S^}^夢G(^u*TYTT;sS:=BjgT !UGUR9TFxe80o 5rR$ڛJ]WP%N!e0h )޵H),ű *pSPPRԾ!2kJTeI(*qT|T;XCPR*mPPU fB A5S9uN n ko z1%[vI,z1'Լ0j vT#z J?Q|ng0 {/w7^ ЫA5]p{;rR ׁhrst&靤.T A!? VR;JT9Kui^T ~urBsTEgjo_NEjeI?z* u%u>쟥[so I$}lomV霻CNk%SՐZ<AB_~T%[hιz Ncv974\'gٽ/rJ+g>H֙}RfeT"?~_Vl=^6G]yӖc|D҉{??XO[.W Oy 5mswePCB|[97ޏ 'sU™e'η] Bh IjU3U %eWoG!n)nBȦe?e;Ja!T+U[HMV>ځs]ܕ򭳪yuRr}&-$}~P!:8 NWfevbC;B?5)ӱsN@(18]X+&C)Mu*۰/'iVTv/zW,ŷQ!\<|{'[z`vZute{f:+WM`Q!撾pCûn&ۿӯh+/A0JϞ za쭤_'EHy|W?tپ q7 9NCZq7LJwUƓBh;@e7Hؑ]B/Ժ/v@E)ۇy&i||xBijߐʴ*uڟao/.BjߐZR֙YPi.NJzR@TzN usޅ ؎n&ˠ<toHe3ߕNÁLJwT@}C*twQb_ )@ܩPjN*|i,@Tڀ*RsmB@ ξJPeAWFCP,Hj B*=RsNιΦ]7B*'TG% R/L%$P@ʔoRP@Nj1 J*agNSi@%ƅIsS*B HmҮmT@;VR ( lٶ-sI]X/RۺN, T@Ux@ZTy)@Hs.S^/ xU1SUXD'P@JR9T@=s\pS;f;)z1w fCjjdԃP!pB AET U.sP!佟ڇU0AmBp/@jPն„~@ᤞ 2cj:pT@5'ܓ } (,Z#P@9M*BryPT @dP(>Fv3*#"l=BQGtTpS B : @tTpS @ĜTjn GPNJsS)t0 @ e7GBo*Ttޏ솸HB/ӛm(9RlrT %)974.%GyWP(H JRv PP( N @MMs(9׳㰒9*j)}fI ,EB ٟ?B?u}gSt8*j B7/P@**PsBIM\RK %A%rT I-槲T @Bh)@P!e4PM' !TQ(T-T#S8*D_s /2y'P+b ]KR68'Hm!2Pkos½*$5TQ_t P7508lP%*$MC%7)6g@.҄& @Ta^Ґ2yr U@ ():unj!Ԟ^ٍRPTN*PJz|AP+5os /ơj>iB#mTR/@=/Tz:*RPB&Q _.PE*/֬ɀj@55G"z}=5PR@UL?g_ut/.$ Ow}S!48. TP2ԣKI:KKHmsnnr@>ꇶC&gqz) = ̦S5=U&R.gՎ*#@3~p(<~)KַmM_£g|6ޕފGk5u~m+o}:fm~|?{&)ujS *QI?']L>YcIæ{Qz;~iO 9!G{ [X6G˾H~ڵpR]UXJYjG彟{?S^rVg|Nt@{ D IF ϔ*GUh[yabj+g?Pٻsфڗh+_k*?ct|7u479P_T)_.sWl3I ûV8͕H s)>c)?^LJwu|a8-SrR){sUR>M)GUhrNjmw|xwmI,4R^^*>娂{tνwy眗~\חC.@?(\Ɪ( sxZTKFFW$R2v|xWXLf\M ½oPP"G`C|tZO~^ʓuc >ۖuvCf퀔j~3 VI:PO_zon3h9bS: "dVLJwozoIPsg<%RUªPQuKpKE$Yr}d tʷ :Zk3` SNCj m=䬲\7M{vgS61c җ1oIٶc>q ! @ m4VX Il @նoi,a2>/w kRhOΥk, YŴa#|VoQѵZ& ?Z0Wp+X )-  k}0g HjU]{yrBSmB9 -)kܶ]s^pK3B  !#$5AT %OuH£0[ 0&Izii *Zq_3`\! 0[UZV8;)k7$B%)vA@)R! B@ !BH!B)R!B5T+ gIENDB`OpenMesh-11.0.0/Doc/images/inheritance-simple.png0000660000174600017460000001472114556675336023714 0ustar gitlab-runnergitlab-runnerPNG  IHDRJsRGBbKGD pHYsjtIME  AwQIDATx{T՝ǿ}ow33CFEL]-G%*+n6$Ԋ&T ʺZ%@>XWtP] # 30=w`L7Os?wGJ. NE'B PtB(:T<%DDF3^nc{P͊؛dtұ9.PtB PtB(:!ކP)6=J`x \آju%͐ ҩM 1{#zP0,]lJEq?;K/?9 /0-ڂ9&&$no|/C%>gh"2`)mnhwk%AեkcrS-(\`zfPHݿ51 YѢEf/ LlWNjuL.2G?~`no*'Ukb.8GC%Ʋx>Y9A9>ɐ" G?LI}6LpQK,Pms4֠Fj r@;Xߕ'h:G⸫i{z҈\hdCB> !oq>l'05a^'uYHZE_`) IOZ@١'L2n}Q`` -y,3Xʚ8K ,.xNyu2^hHaX ̆޿7rx5a;lt:m0BJC<"[%|v=ULと\o:_n:p@`eDhC|•:mNnѯg6T+'L?lPvgOOw8Հ WM(:6B^fP).2· .;m4ש/$5Z_΀olǻiتIKI#_[4Vޕ#t3E[Fzh/w$|x'-4dYX&]{""-Kȝ``!d}(j*d?Ƨb?tcYGk;twqT䎇ѮzjǠ' {-HjBfK\sKΝoAfܣjYgw݃Tk"8.Ԣ[-p..h'N>|#ҮH 97l5d4͖%e;~dڜ $5;oAlX}rsn>x֭IoXs>ma̷]=$Jܐr$5aDe [u)A//DRު ϗPppG)~487(Aq>jsR'vɿTofp+VHjˆzJA0ɐ)~|N܍k} aUܧylcYGp1"FFOM[tC ݞ7;7A6[n~i{dojۥ`~h5pSwPjeo5rؚ[yTrysJ٪u'=ݛ\Sd73tSwgT?)8v&e/z), a{ybwF܄鱘g!CǝQ]+OQcXsM]{*.G+b/bu0k=5)hr_C{wȩ~yп;S?-9tF@ZoZ?_\{T$8`, ˞,yc9FOM^V-nlN ~veFS\۝C3;t%X@;x'M l;i|@IOۇڮcdHHWߦKF-hׅPtB PtB(:!GOˋ&2ґʇJGE'NE'B PtB(:!PtB(:!NE'rdQ:RQ:RQ:B(:PtB(:!NE'B 脢B PtB(:!#ґˣt".;PtB(:3B)=E'B sN>E'Bљ@(:PtNE'33!w W}ΈNE'B E'B PtB(:!NE'NE'B 9uID լIF'cBE'NE'B A{_)Zx7M ʧ3S+U%XH@Gj~/Gqip-FUڠ`Y儩K/cõ2k*Sc@+ c%⒐Gb>EDD`)mnLhS4l1SO\b&,Iq@(z_w#W/&`ѠS4[(z?>Wfv` ,1;s`,v?0 b_BbOF_KaCe=mXX61!}V^ȴD> "#^V=m;].}m C4=Z-hNzժ02,'LgxO/2۔/0Sd -=Q`oR)o%M[m';R]je\v@ۈ)lŇi|S_Hj.75a&/%|o pz?F4'w)(Hќ}\K }掠)L`ޔ އ\+7mꟷǼei}"7lp`!{~5~=я ,I`Y^ӡ\9/-nڕN0oq7$گXG>( n[׳`iݸ[%Xl@?]UٲAl?<ݏ BfjAlX}rsn>x֭IoXՓUDR{Cގ֖$8D7]g< sk/By 4{[Vz;2v1_1mq[=އKCF/|E9_ֵ+r_aɯ:|)qqpEH־yB6lչ%?'^h -6b;V~k]:ŏF1S0·<?F/ǖwDf,SS܈'oLgf wnwF4_OI1(&2ŏ3ؓݨ |;rCpj#W~fP}1WV 0@=oewF܄鱘g!CǝQ]+ 1a ,&~T}_ x4-R%i5~ZXuPh& 1~{))=Kɡ{wȩ~yп;S?-9tF@ZoCޜԵ1P28m*,A=/c݊?erXO7<$#I:_~Ս ]99,hksؒK,LƦ8cm`|޲ ;F̳(db{& W(qv^i,wy6]W$ಞ G$[+ *){tB E'B PtB(:!NE'NE'B |=|T>|N(:!NE'B PtB(:PtB(:!NE't(x)D-x<0KN(:!ΌPtJO Pt\O Ptf)sN(:!0?ÀB L>{g3B PtB PtB(:!NE'B E'RWH~ լIF'cBE'NE'B ARѽ Cn5E_)oJ1M:%V%9^r85ҮGˆ`Y儢?9 /0-|SSyx';ui4.n fn #Ɍe[M^.0a ^NeʋIX4h6^L,!0c)sNO9EFBK'T7:@e!1|Hsas)o}!WE1('0~l~ X8/5i4AU`5$~,v>KQ eXp[,$ /椧M T'L2n}Q`` -y,eFkkXb`%wuaMXIezNڧfb,̳Rlϯj g]hթx>3x *FAW!g)xNmŗ[PX;P+peNۧ[mXwh/w^H[m';R]je\v@ۈ)lŇi|S_Hj./z2ϝ؎wӰUzSGOS隣]wvd.4%#siX(zPL;\Y%oYFp_ ,)Ez} ?/9x=+7ðlk.{[P.#sxt3|C4wnRLjщ-zJft-`p2Z|تlYb ^IN)}ʘF؂( 6a> 7Wamb$7Q,uppG)~487(Aq>8/2+q)4$Cq{T܍+E(GcXծ3&wz}}/0?mA|H| Ar3x {dWC.ŭCGؚ[yTryx~oUuT6қ {K4} 枟9[(`GJB`tvgnM(y>~ܥbMAt&0l"'ΊÌ>MEIᰨ}k/ᅂ.<>JXy.||aGEm3\NAclBR+LžӛEx4g7S} [AnȚg$`E+ \/q?3y•)kB`(5pU <3|)aZRhpv&DpOaeƹ•5pE ~޸SQx̓akP3WpuasGGĹ^pmI^ JPWk~1ϧ $H]hBh}\J P+fP= Ņ"e##ŒvA?ãp}ၬ&aC`IaVްƇ$_ v 'DŽփ\ܕ6鵢a; ~^*¸9, TL7va}7VWQ1\_'%pG| )+ð6m'Q;y7}a mXQ My l$ K=/Npa+[\p?!b5>,-ڋoƆ >\ myxa;*a߮n| rX-'J1^e-|xχ#vu򉰊\w[ lN:M3֓|<ӳ6zc!o&mL< Hbv{0'oWb(b ~uupCpea]/vDX\3*EX%ʻEla9NT[\T"y7#;Œl^D8g!ROևÝãprL8) ອ[gތaW8? R'nn8{V4=_ET0TsòYE+cGXUoy 8% 5Z` j1vHaNޮ4][+<zzzKX 9^QǨnq$%qvcA `gR]Xrh`FX\ƆYqƶ?:ãpe ۸%aiK3d(g8/Q.`b09n{.6wR rvNL.pu7d{a-h~ah#a|>q7ž'twư> g|zᬱ"mpjnݢmp[Ე>c6ooW' q8&jr;h0poWXIzbF{2D+}samMJl6\(K6pSmnƹ6FCͶ/wHּwg=m:Yї^7sԋ{OmZ8%s:|˞?c¾{N?lrppLT [ylǶdܚ-3~=Y{J춬h!7ʫz5ࢩSP~ h9  HQӑ)2 ,\1A PܧX~Az˳20H5TQTTT[QuhLj%e@cկ ^EՒʀhMa9Ւʀ!-jE E E E(*HeHR}-樕a~?)jʪ LRs;TBL>GuBsȡAje(r9pC=P * jCe({k$!uje8(yȢ6!(]ى \QAG D,\wUŪr(qAa^GE4$̝?K睯AEѐ E E(*HE(*HE(*He'ӀL}rp_T|JG'YG~)jCe ΘI&u/xQQ85/z0wRpDAw}x$ ~L-Z}8v\Ã~"pvc7䵵= |?EEќ߶rt7; HXKbU5.48V Ȯbx0k%pw=ɻ>Đ5bq12?awC#T5߬"ˋ"TBYXw6Z|At.P~6~!WEx\x?l3<ыxhbRQp^*ԄМ}\Ëᡬa$)q8/F*_x8g)å)8:&ĀU>>cx`rmlbϧ)tOj*E~(g \e^n|xBz*([A{/qip\kpGp`D9a 7 @lD/ ”z~sl#ìBnt[u>.ܜmd="ϰ(yDĘ 3rJ~M9s R8װb켡=##Z7 tN  Oy`1V[c)?Af,j,9/+Q /^%>=XZתl Jk|'vر?6. 1o18')$ڕE9hI1C-WREM7p;kG?ʇêlcIjIe@8d;clSd(Z(*HEQA* RQA* RQA* RQA*NZN:p0B- k\ K[Ӑh(*HE(*HE(*HE(*HEQA*CKp̸ZI6>ײ}ՔU9 _ ;i؇JM9PAM ZCg`Cl_Rߍq`Txm;E{wo/)*!.0!9-}~^Qcൢ _i /b.Juup{z/M QZW߯|2Wm1;HagSh k^oTb%vmp`?ZxL0 zO`bc_2ϦSy2.+}Zb04y֚5 sn`{aRfeâ6t>SϦ\e?p[afN]B?Λ!Yb\#2[-;)ܼ RF`SYvc@_ú{]U0!"D0 VT(4폈 u>V*!Y bx?)z߆O&BjԸ߲"\OK7ꄶ63IX7*ãpGP{>{:pUJ=mx$ lt ([`upca~rw`Wc؅z n6. E8<*,JBQ4⍎7|}s poWa:w)[D% pSj1n϶U&mpzߑPAӳ9yh75)um GFY*O M$mxų5xB u<^gn[DgZo25M6C4(/?|[В3. ǃ0d49P qfNյqx̓ÿ:z|ey}`E?^^e -c9å)Ý^߫AM*8='pcaZR84JoOtsfa'M{UƻјtqS- {0ޅ) $|Nx3[}2V6<:%m3|g܂ 'ǥQG;Q=M²=c6?[[ |@j7~ Og8; |xjFְ!k`r+rphȰڷ|5b^-vWg|1e-O ~<|:NZx&n_wvl%1;ҕoPA^lZ^ugpay2}Ûe{ކn3āVmcY|yaB{cǛV SWk|{Jo2yk]ʈwVpT2 4/maƢRѢFQ+LN_8[  vLq'5%!7{!E E E E(*HeHRu00ZIҹ`ӛ+b&o9Ї+DsC-jE E E E(*HehRu0S8wj%e@xaeף1뀘R@63|DQEQEQEQE kEfIENDB`OpenMesh-11.0.0/Doc/images/mesh.normal.png0000660000174600017460000000603714556675336022360 0ustar gitlab-runnergitlab-runnerPNG  IHDRۤsRGBbKGD pHYsodtIME  -%tEXtCommentCreated with GIMPW zIDATxkwϷTbz*xP&A "HU Rv!x\O7?9Ƌz٠Q;P[Bzdgәd&;IzÒ3U)ePJO$GK$ߓxIv\ ,neMI^IZki6%ɇs\ Rh?*k ld"ߨLR6fmooZ2 .r)oT&f<-,Xz9w IR~{Q(,P9wdr/yRJy,ʳ=<]Q)H.`T2c/Q9sr(gҿL7C 'Ilk{9l*,!*كimEPy&,\"\EP*pX>, \*p* \"E`*pXE=G.`T"@. Tz \"E` \EP,P\", \.` TA. T@*p*p X"EP,P\E` \.` T"@.p T@Ep* X"*P \,P\.`.`@Ep T@EpK`.`,P\ .=* X"B\n ,P\@Ep Tಶ@Ep Tv@Ep T6@Ep TyX".*zYX"/.*zTnd;N{/aie#$ZȈ*\^Kvv~ty\l{ Hύ˽$/M}UJ=,P.KrINڧw{ T2Z70.ZnH+,07>|Bcz*qi sPyRJBEZ .7ݕ.kh 3;6t{;Ib\Y_J$$9Et/^($O/4,x.cOi5w3pdz6BGIϠ2haJ2}v$=eQ;7X$oja)<ūI&ɜqSe?ɖG\;vvR a)7MZ둧ˢ-ʤRA#e/a^ށ˷ܽVXK OJp ˲mxHWK7 eמ|еWnIo]{,{䃌o4EZA6+>wvvop}Hʠ$sl!TbeX+kgr׌`E(mۓ<]ז][),t'7:]tFyvAd~;Ƕ3~A;WsC+Y/e<5!Y?\XkM4\JR;L$_ Ik^F]9,S`?EZ2h/HfNkSۓ;}>upY$-Jڭ7ۓ9ۯ|\FeΝr#RY`"-ʢ{Ku/byrHMXd׀y i}QqXڜ0Sz"*]$ν-g"*]e2pTNOAe=Pʈ%\X.JQ$,pTAe}Q4,pTAePY X"d^uF".ROQY;X".RQY[X".JPY{X".JP5EP \[ʭ. X".Tz \EP \*`*P9,pTA,pTA,pTA,*`*P \EP \. X".p@,pT@E` T*` \* \.P.P XEp@,p T"@E` T*`\"* \z T"@E` TEp, .P.PX\* \ T"@E`Kwq X,p..PE*Kq) K)"hU(`dr;{isk$9l&CE`3Z$Lr?I9 ,T̼,j$v4T-]&QE+[$Yh!T,Kwsi#w~RJn#ǥy|dО+_O$ߜ޿(}.JQ_˖$yQS'7}Ծޱ )Nl$y2APr˟C,${GS`,\K>t-N3+$EC=EC H極{,:}2ﳼ%TqdĢL/Y hQ˻yv^'IXa+#-:jxܼgdĢK^%x\^B8EK!I`$H$HX$EX$E" ,"IkgnIENDB`OpenMesh-11.0.0/Doc/images/mesh.inner.png0000660000174600017460000000765114556675336022206 0ustar gitlab-runnergitlab-runnerPNG  IHDRsRGBbKGD pHYsodtIME  <牬tEXtCommentCreated with GIMPWIDATxO#i۴ .f"t nTD$^!‚,(O BQ$^;x䰇]AxS®It ]x&ՙ$LO:a=t'oLDD888888888Q:!BSRWR*429N ^[AC_՚O̬ǣT?ƒwlbfĜ0A~[b@5s w#5FT}; I """p 35UB3p-&;|$*+$BW ȮUG*ȱL$<!.yTʍBk3;w/I3oVPzyhߓ{E$wXҏ2rHrȁ_Kǒ^Rix /Hxu%} F@?y8[7?ð͈ C6g0 !4V sÐ Yu߯j4s@a!=Jj*ZF B~a8 Q~ෙn|@U(JG Q0zh+&R8PF ˣ_..kqu@U!ß%GMHÏ|j *2=bx.(jKRo{ȑZyӜ@e~SpzX+T`@@@P x    j p p p ppppp`p`p`p `p `p ```` ` ` ` ` ` ` ``)          v8888888DY8"@@@@q @Q* a/!%鿖SIS3k8T BCA?447I.* Dv3BhK};(9<+å/:04@mDmp(0 }C?Ha}$CQm Õ If+ٙ`6ޯӊE[df>pB&@40_-?ٰWܰkG~5|Pb!*q/Y}q +/=3}:WzͮVy ^ePMe9Ӫ#IWf"קjPQpbRm'@\Hz9^GppK*D g+n28z J_*=)vՓ՜TM ܒKI}}&x%ޠ{Тs9$a% Q(؈A~&Dͨt8la(j욏m-4 jDqkC ٵQzζ(mkL%C`> ^ !'J_<IbV58W{|BQ!8!!<}p,IaP{R j{9!*09t8WUYa!7:B0A|c}piLUÁ>䕠>lC>}F;=3}SU9ٜwʪMoc߽;CIީTe$gsADҷEuT&LR׵*"s=r άFTt|!LN_wsiDw㤠@pڏPۋٕ}lJ:eO'ՎJ7ҋHK;೒ޓZNky^ةLk=q((] >VudfIaj2uHޒ$}ENp[Qd ?L y}kH6 H{"ÐCwiWx聊ö/ f6c3Hg1T5NkRa8ĜC~cBᧅ❣0<8M_QDON2zpC6t@˧> DnY8EP8d+~S}6Y#  <=WP$ |UgO$g/v0j' PuQ>x_L`K;aaM&(,cCсËExacI}jOP] #!0#v3`<%8ĸTRk_gP}Ad_LP8JlC"Z>?`%bկ&nL~iEY%P ?q׎Dܵ/xdf=3{@x_ `'EbCCO|^.4l4-~CI=3;u v~yn_6'hTT '-JqY^9 =:{Gaf@蚔~aV0LwMV`u;8*Ӄ^f CppppLB      %飯?L ` ` ` ` ` ` ` ` `ǵ?Q888888888@8@8@808080808888@8@8@8@8@8@@@@@0@``````` p` p` p` p @ @ @ @   q  @DQKQ]II-v~/鋒~7z@wIj*w|ۆ+IHzMRT% %w>Fu8PU@R^(\?L?8P㞤SI~ذ %TC8NC9}&T PcS @~jS-`!~߬>x1A=!t~BX#%5}KZ!F^]`^x^sBh|^]zuüyג.rOMy*Dv!uǗfk%f9JOu8Pŀ7ҡВ40!&8Puh3V?V4?s|G}C@@Dz2P~:dÑ#ȁ*;rƁfZx\\+!9PF5`@E\Hj+]$XDDV8888888888Q?;K(L>CȑC.pӰLd)peuUJ3ZbIEֳd28-\ؘ7w:%4qdUw5XbiƬѰyTCc˫w,[7m qm|ܿCX,N){q`Vs["<rJ;8ccXOيO9b ~>7 "S7+mb锲E-eMNU%.446?5qЂcX,J,v9Ba7gas|շZ, lްj}M` h9Lb)O-0NG8`wsQjhlyuncbY? إXIU /f%׭ب݆Ez0<(8E+Go9-]вCcXMy΢ʽ/:VCVâ/~|RbKKy4# O3ml95[bl.γguNc]ֶ~@cAߘz8%8.=|S&mZ\;I\g5,h]X,`YCm"0{JH7b j}aXܭgDnz̧GLbX8317LEĖ ~5&"՞%?Hl#;Ω\>8bHׁ=.l9B%~@DU;(!hU;=AƘ7G; ("U~ϒ55ܧ,yRhauMW7<n=Wn:XUTꪊ_f Gwpt8 n}$ K6Z7OU}PU/5Ȇ],s~mw[K|lے%Ű&7SWߔ7lo^ʺ})(Z늝,K8+،>Vvi$S)$p̬R\Vn""ۤ1PR(W \Wߔb'U'Ճ!8.? uCGV2lk%"|4JĎ7[)PUn ђ!W e}'[^a)gꛢuMGTUX]gwN(Dn#*NMŗ)1!ش/y]qhUUU?<%αg1 Xۋ5V(1 6X㼺&b|%v*7k?NY," -A GH8Co oOۺd(Up!n{s~C<(u$Xjེ[ob䐊sxKJD.\~>xJ8Gѫw1 iA;)60 FD~g{^{ĔZT7ͪoJe;` (`|`#u]уHpT$=|] $yqγ<ۿȳ=Kxm9Ϟ;hR" ުo)>;rPgW/Չ_btꪊcFn3A G J  tmɮuc:ra"rX$"ϊ|Y-"7D`>'E}FD"򢈜¦6-"'34 "";n4nC>.uchseA^DsE"йE#yZDhK'"""kEK'""rԋȇ"RD>EO~ԧۅ2p1p{PW>hﮗH9o+,!pB$H$DZ]Vտ5*Ӯ;l`/U}sg8SULg,,x6p18„w&rv!"_ejr8 ;ʙ:9@IB׺v= QZMU}8³O嘰3T.UVReE_^no#{l6B'"0ѯ VWS7z3pkf@m/9JdU]\_u4&;TW3&(?qN04=8j`%U}VWU 1sFTU\cш>mpg`BO4!g;$WTdoo_UNUY} 8100鹚s?j-"> l|Y˄+<.nFw 㙡p>?{$G`RpɞW';)XcdETGIḺc36+ soJR n% l@Kww9,Wg$A3vpnK6]k;,loE?^^$}ƴ1+dcH زɼ yΞE?d?u3_t~Yļ2J?&h[҆wwaV]1ӲgFjWhl5dRr]16Lchg1uu'_Um"̱Lmg( I])|? bj|]VҖc.g{Ps܁0벝9xӞLRd,1&Mރ_.t!4%p+C}v_;<+"-CS? 'kk*Rj,r311ݹ5cdb6`Ґދηm@?~lcsoD&گĸYrQA82Ԇb9tuJv9t_҉f~gRJ9&㱴#"-#gs9Uk?׽7qVfK,r8E;KrTY`dmMtu .cik,23(vjR)+kEg,*he!Ύ{;XGc2InLB뮪K0b|/k(#sIbucW21%zkB_No~="]p Xdp`s3IM4!0tܦLmΜ&tOtXc_n2gh SDz:kB2 脎+ 1na<WeTeUM;ښ1eƂ>]Mo ]Ivop%B܊}+|l{+>.-_*W {jI!LrkWֳzUs1O o,_, ɬCmMyʬ}+>jGs1wOJjREXd_L)?ljyu y5ԧ8Wӊ17g{AUsΥ6ϼ,#5.]ST U^UxJMcG7]8TZ[Sʳn֧;ZćTr("IxU2{"a /<yHv.8Xpτٝ}K}JzUkLNdYǻT>=xs2smh T65=XY"5u?od/UҴ8Kant޷Q icgv97EU]舴7l*ꔒ ~x[1Ckk*o<7\zڸWBHq9<Pc&E$~)W9ȹJў|jR[b(bw_< ${|_x)3gJJ= 13Nlwfq?M~Z[SښʯZߵMoT-n*xY$Xcˋ`ܕ)b[4J! @umMe2>{㬥{*]@`4]Bpv9Δ:z„JECUaJ'c8.X0n['9{`L6#tLFs-qrUF<9v7[#Ə\_Ly,{{~ODPbdޏOçMGuGqRX G`^X viN|<0CǾ/8~kb9Wc|ůeqNU!3N:`E\ݲyYՎfi9IDATݨ["m߹/4Nt )"`fZhLI;t'8?;vpFͿAb}.j?$ٞW)tɭM#DEښ]2> J&oVGs #%Ɯ#M|J ̌sUx/g _9}ctc X?T'LjRe?['uw:'OYؗQ0qȬL{ 8q[s>y(BglXR[Χo"dzѣLJ2nb {1Ve t+Dc|-ˆ~"憁-ײb)s|gQy6} ȕJdRK.˻8^U&>'kzwEfz %.ΗfYc\mETaIep{W~\!X,2`v[짷r3h cdo{KX,6WS z&'kuq=X, PsVZ^)IŌ^Bd"[aX,PRqivf(TLVDY#{c3NhX,^J. =ښ-όZCXLf͚4&'b%pɉ;)>܄\ uN?Œ19{9s̖A!P0G"GXaX,~Xq8qذ5[ت]*܅(5_ r?xw\O[,Kάsnۛf5&0e c z-zEYsT]7\8=&lcZ,KڬcNv% A}Tر#+h8ԎjUmMe] רLd';#=s)eeHS)MS\+*w |bdMًs3k*_v28ꂤײ]'DNqFlX,Sfv3VeCY yI'=`)uqfDVX,͜-eb+@8[,KlX,Ċb+@8[,KlX,Ċb+@8[,KlX,Ċb+@? dkIENDB`OpenMesh-11.0.0/Doc/images/halfedge_structure2.png0000660000174600017460000001051014556675336024065 0ustar gitlab-runnergitlab-runnerPNG  IHDRW#OsRGBbKGD pHYs  #utIME ;(|0nIDATx۶H@AeI.-P}E7E I۾(mDmgUeo(@ĈމjR\EWryBRZXZt7JwE;M<&,9Dz@o0rA+˸Az'Y @r\VK&e",܎{`{3Ev\~^GJM_XK@%GqXfjlw? % QZ&;)DZR0{S(ܶmK,@ѸF8NW"\v`6t듍"` `!jX* *pqYaj,|\WQtZ*KS3Ud!ֱ::e\-S\= ,p &Xp\\=8W)W;cI\]€G\$xW7c1"v pLKpE޴*.8y|jǣdfv& 8,vJĵnWK}V\MvXqu%y~"r\jǶc}O\qI&7NOڿrM\SB\M!qťR';צ*xo2-ˋUy R&P7Ibb@T=kQu"tnzSTnԿ`MUTKvİZWDv긎VQW,L7Kj+'FUĕ/?G Ha` uD5Q?vZT12̥(!aj;^܁eK,|;sF4b4 qe >WF Š &kp}SU\iF -.'`z@\ '5W&є6c0nĕA\j,g JF`3+N&uqqW9ZW&rI}lx_z+KX ,&{z+ l4*<%mG>Mjr \cOb:,L,:͖DS5vONBQѦa5믣߉0bXS'ʤf4ore{}=NNv&W> ^;+E=Ҳ3'%T0cKl7Kʀ9w |`kD6eZUNd+Eā~[h=y3cj"-j0[Hjn KJxGʋ$WDvОDZ-쯚{~x- +$nR߷xWmT2hSD6"++ + ++ + ++ ++ a m~o \)ֳ0r#S+7J&AqEHA\װ^kZW VW O J@\)VS++} iZNB &W 4 \X L +}V8~O.)Q`סC:bR~P<1F\z5ߦ]8>""{WAԌiVdWL * GUPq5jJu)lU@\DTq}+n=x,e2.c9%؊+ O߂͙ Ѭ;7U,+?u&&p[ qjqhX"EXWVKJ+„qEX Šr؉q尿y+.?LWo.+. Me\ ĕ'v\Wi-g!yBnQ Ӊ2 nξ2%c(+|b8~'n-&W u% q , A\ ⊩L͈+KsW\S3+GW0="++,Óg+T S(.cP̀ɕf}߄qe)UaWO " $KMw&W1BXV, NB؂+Ҭ"PڪP\ mv"h ++ + ++ PѦPH}~ק~>>qe~ \jhSo|6JK8?zĕa])BgS".i ȡYT,ޑj:J ʿRdI@DΧXqE\$` YdKm+2aMyV܆*LK֯*X BKwX3qe%NWs v>r|f9g$Srm񊲉U\02 w~NlZyBˤIRϧP~Zw\aکť+뢩oV^\IX\ + 8E[@mҝ5`a5o>bF\a5IRRZ kk.ŕ EzWˍ倇}M T +ZA\cgzE\!+H#͋\V>GYΛ @iٻfY!*NOWh~ryBk:;breٓCXa}iM\ Ràէ"0}XGy+,];Ohfj&W\VS@\Wt'W: ߉H\T ܸ<߿kM+FF\"ĽUV#aE\.t5^N;r@;ipiz4nre6.߉lض܀ɕ=j]*jrEIGd?QT{a{,*{]uy#kI`+BkFY-2N8Nd&WDuuwX5\ 3.KϓٛQ]bru{Zqa}:E枨U\q}z1Vqa}^ﷷ>"ai^ X֫𕎬[ĕI:ۥq9,GZJY5PTo`W="ff\gȊ+F~ԬI-+/xeyۍ-"+[hQ*ÙXKʢQM l2Yqe%S˛䊸jO,n۶_`לM?j {~fߊ%@yWKȞWQ,|ocr\-"{۫[Je R?q-VqFGkDX*WSTX*W ST&(?Wϵ@O=dIENDB`OpenMesh-11.0.0/Doc/images/rwth_vci_rgb.jpg0000660000174600017460000003142514556675336022607 0ustar gitlab-runnergitlab-runnerJFIF,, XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmCC1  WhZHېsG׬}3x^O~'}Io/')ҵnӨ޴7831vaݫ~mz# ۨ\':mYG=ÖWTNF枓vT~8ۣвclޣe~o~} |B5煞1tk{ շsvca+fdt ȲzkkC=Y?8}1׏SWIٽh/o'|+cXIg]o)_;l&Rs}xx [zOG[^ٮ76{& ܧbB(;oCG=kb ➣i"Poe lW.$p(ځ$ۑC,O~gfɛֹiZI~Dj-(4Ԩj-ʹ FI4:s2 UnY$:FVRpM֤lUARѼVˢЖNO@P zNٚպj6zѐs2Mk`:,l1uHA V5PwzKHU MJ*fׇ ]AucGe@fQk%,evx)Ҿ~=UHXVZ$&0P͐E+4,)~rj}ON^i`:=hҝkVY27HhllLYY :T~\C7YZ 5-۟krstI 4 6?dQuY/!kXh 8yZJ[>d唂4"CJf3kA؀|Ů |n&PƳ !+SP7d5-iZXm%\H߬բF_qc(Uo,Ms5;sS##FG|1;ŐeE&ƕ>t4Z zk'Ydteτ F] _ A]00SVr湳kO[gh+$TiV:oOet"2J8k|CJE&c5trf (#Nԟe (my  :=E>\⹊F|OJ !1"#2AQaq 3BR5r$@bstP?'GFU`m4~㈦IC0j?69eg'ؗ^WM']Jvٽ0L֙f=!^tԵЛúS7{}rWnVL!gQoP=ѸI&5ámЃ Uvwln睠ö2LNc`gp&,N햃δs`JTЧFeLd5Z)vS< ͙̤ȴ EVV:,OъeLJd4@QAS1on JRݖy8\ ;ӻ덙[i#kmE;Bi=32#[I` k+r`zĻ Nl T39 u+ZA^\K;Wjfd摣DQ[/&u!PE -fl<흫l_lYs9xAїbmRK )#>C~W6Ί JǨ릦ݦ7a6iu^Y?!qG ?"ELTq!Hܯ>W-я-[66K ߍn5;Ugc3%iKQB}m~ߏ'̶>v~%-n+^_6dz efB٥y9JBīhњӼ(֩C-j|q;1GI$ B;5f ?W_2)ZE¦@*µ;b@ٹ\݌6tבQBD|1 9jq#ͥZβܑ+oV? |54dj+vW/{Ž #QJi 6C.an;u Uɜ L”|ijW8yv2j_֯Ǟ戥iXb߰{A !1"AQ2a #$R3Bbqru6@PSVds?!:ޞb&eďfí6|GfPQJ3j( Yvbإs36W5JÒon2T|)$6@{` 7㗘MsKXif)RkU <›j3F3֕t޷:5-zs)e7ֈE,nC״w~SWCrmTaƪXD4;j[on"05q+IЌ*>cljƦ;5[M=Q|>Caѐ w>epI.[Q2Skx @/N4 mz0/܏aACJӸ8coNrBWo%~>(hYJHo$a 6H-]b<ܞI13BKbKV6kWoM=&4އsYm}䌓k{ir:#[i]@L_;?[Pl/9~Dk!rP%ɦ~2_ uJYܨ@' ġs2U-[ٹn=TQ\ t(qV|?C_ӫu#=ޱ=:Yjii0ǖN@Z{ x-=8 |8>dC8TIDV&R)KQr3kmv xr* qNNZn mm{5+*g/9,wk_Q\ҭS/7\on#k#BqCa,rJe Ԥ;$+˕9{EIHQ g3A(z$܍JR9]5ok1+Ė)o JTZ֌*J%,7Sv#o,6 XH }N>Ro}J)Iqe*j-HFѥ!Hyg pZM1yZEIjȚFi^(:l [jhgOyuUUue-!ds=My)iS=dS9zB} ږQڂ2luҕ1=ƝԪ,GpũȰbi*ة(q?|,# F/k6q*#%Ήܷ@.>I>ӆjduO-jbZtC~Ti ̖'+ڧ1!+SjO]>}LJ0&Su+[ CjN rVU†cߊ'IXH=4\9aK3NQk*ZMn 'l^hڂmo;e{nX"JKwokXy pVj S%5R\zL pjlAd-6My*So8/s}E;p99[8m^U E{mrU2 xwo +Ip2 WA=}|JYq^<=Ngi=-R꤭!Jirau%j(8dd.`нVԕutQz*>pn\g Q}9[3HC| mJS)EЃG~JC( \WWSNy>_*3n^C2NM}U'H'uӋ,@dV}ʏ&:tZuwmb/V\yʽhmm'aR̨5T:, d~(ޡNuk}nͫwqH bEgQC[eGcY@:Wd޼3WoEoD[+_VKYHP }pm)HX]ϼH<+KǂIE>%vfU';#!1AaQq @P?!|@{ݎ?m!1<ưKQcoRˀj{d }şZQK+[lZY (Lޮ٠jհTQr*Qs9!q%;ԐoH*|%{S g5]ɊpW< ݏE{.l&$w}`2H>=-k[tyL.#h&#QCH$45g(ՌRg_&%w.5 XW pK 퓏4ܭU-bѭ- |1ʻaT4>JNn3PMõpXlIJeT9R!0:")Ꚙ*h zMU jsD\8rv_OPUS `(DɈ)}FQD`-܅.E"?I ͶO*8Y]ju@M, [.Ŕ 8a<`:@p..N鏷l]wGfYCa)(+7:V31";=ѕ_ ~50a͜ &j\-p'm6.`&!1AQaq @P?KBV8-`"~HTiBBp6kzĽ0-O8޷& 8 (ؚ?%1[3㍜ń4 <ƠPa  trkFi U@ưDx? oL mAIΜwU4]@/GtG!${׈$aUgq{ g_B#V*>WH4߳"N`h9W )2 7mm:Ʃ\B*[ R9Tر%=PiuN_`P-GXs@qk;A!i!9NDСCֽbҡ /&b . C∘H "^3-( md>E a]< hbA@j=v|Q@uDJKbǹGAŜb9ExRvQ8`*d&8%Ts#x eR Ȟ"ÌnRI4ߎPuP9 +)5"N'HӪ$1A{A!?B/$ %.=5*. 4"䢕"N#6({w!)0M>\M!! ^FIi)3uFjt%iY,CCBCF@Ee`:_b@! ic)MD[` ֨WCh `$L˩1ֲ1JZ^Vx0 !GU`Od0(Х!Gd](bj);!E.Vx[ NjwmSh 'GdTjE_OV;w#!1aAQ q@P?H)lH%Е7a1|)p)0GJH P*$I_D|  Mqj" Pиe]]Bm{Ea{+ m¼y0DstУq{d{tYl>NJ !R.ItBx4=8VRjB,72`fݲ;Wc)$B*X[\H xB@_(tD8qD x)'n#ʋhn 0)ume@H?څǗT7R=GGVuIh#}UQ`hw}!{H\3{Os> XB3!G?8g*o.?&1SyzUEA!"sEO3UĴ^3Sq%UDp$SQ$Г>@y& xtPD^9z_T J;j` Wu$*#N`֌p3ԀCV8rqSg'Xۢ^K\bٜ`f~(hR 3 K3:@ਂC>#p^U|]R(Z.|'^WYsEK:ƂͨG}##kKK]ׁG O`Bd J"Ns󄖓O/8OpenMesh-11.0.0/Doc/images/diagrams.sxi0000660000174600017460000003042514556675336021741 0ustar gitlab-runnergitlab-runnerPKwz)0Xmimetypeapplication/vnd.sun.xml.impressPKwz)0ϣ[[-Pictures/10000000000000200000002000309F1C.pngPNG  IHDR DPLTE3f333f3333f3ffffff3f̙3f3f333f333333333f33333333f33f3ff3f3f3f3333f33̙33333f3333333f3333f3ffffff3f33ff3f3f3f3fff3ffffffffffff3ffff̙fff3fffffff3ffffff3f333f3333f3ffffff3f̙̙3̙f̙̙̙̙3f3f̙333f3̙333f3fff̙fff3f̙̙3f̙3f̙3f333f3333f3ffffff3f̙3f3fOIDATxc'F*U0RU<4IENDB`PKwz)0 content.xml]ݒSn?fzkgzgf+3;Lo*A@ ?I"#pƕNctttttpqH%~YI0t#og~[_g)Z|"wa:w0şo>^1 R19BZʾ_WI9ϿΤYv?K՛cuvIbDǨ,$} D!ǴSΝT)M0**J۶y!B[1 w;5qR%F0D: cpi_u7&J<Wc6-X/=hys"Pswk̊Nd}D,CvE٥s:Nٻ;t<򆕳'ܔ-`1=(!iqRhĬԎIhzUn^ldARy&qީ2Z :w3ݽqFNL> !$'. ,%s Yi ̓ʥCg0.kF 66<eϔk_or{_}{PZSN}- hL3{#`q 9c29Ø}L,.&P,n,U*-䛵eP{joV (L Nv]C˶mWnRC8r;s) ޳r@է! J?ABoR l2s agh|8U#Gܭ',6DVFT؝hf&!QŁRzFtxEf쁨aF>P7> iew!-E:Jx'i (ʘa!3m٪Afg"ҜrDqѭ^T=DZG|QWs#-KWŦ>M<6P>2j(ꀽ:UV5Cc56mĒVMXH%.Mz:`NUcŰm'fu)fmFY ,&~]\9e}N@MgpG$W4elբf rld3hrr. z$rɗb?=BWaBWaj/GjVH2MG/X1 ܱYQNi󋤧T _q Y8zN\UP}dpA Tג%gP_Qrz*B$R~UczY:W=7{38(`,LqT@b8YV` YނTjVGþJ‡c?\pQ'5i$^;k֘eo⩜aQ'faQ=/0`GKtqa}z!# z{ఀaۜ+V(q Ք)sķ(mPj ? ZtXZOmu DzߗAu3pY3V\Ă7/rw[H>HϫPK!/?wPKwz)0 styles.xml]͒۸)67J$EI㭵g*;veƩ5EpIj~|C/O@ȑF#9Fn4O~x-#} q;x??ҵC_|2PGO?1! W͕?_%xh_ʀ?ng~t /8.F#o![ MF j732hٌC;!k `q$)n8|>;nP*˽_kY`%A1%qb 5eƴ nWUqߦk6qd;;9v3Xj]ck _?d7 ~v͒s8<ׯ\B临O>ڀ"h'' QHM<m'$Ew҂%q?\T+v WP>ju&JQle 3?rZ 4ziCͰ7 9$[i+7nAofb%k[w#] ߱6,C3Z&0G<I9q(@! 72]i ]f-eZ 1-4/Eh%޺ lP Cr7P ^ܺ 28ޱсꔶ6oȉhVØLL1tCSMsN2UiDձcj gc@\6DEcO5B eL?sm\aT)}<ӸUMj]WI2LMLwF!UEtE?y/ CH$T=蘘Es5`CwcZZ)œ;X /KrCӖhza ֮ sˆ.$ C%a& n$DdT]a Z s .OŃ#d4]| rp&:D›~z%\cşQ@$S!(_~崲N&A \(^(e>ӊUE6 8 Z}*K9EKY*KKī, 1L}u0a."/XB[|00wP "npyNe ruCC5^x|x))ݢKtRzcmxBSRp:, + Uq;r6tH["/yWgy`Ee;ucT&JSFV"T&?eL, T,WSKi794ZQ?±z0_PY(4E0!^/㤥2be*b M6wL[mLERȔGtcZNÎOѳL>HPAks'_H Q:S) %q O%1\'hK=-X ^'mqm7H|*`X)_b$"fb/t<1:LG^H[tkvZ $AJu$dؔV-mi&d茶>4Z}s_Vkg{*O}|_;~ON3II>Ww j e 9=k{݌U=vF"]w94~ʀoSg6i-_~:?8l/y8XOvmT|>+@Tw] (rXރ`=|{0߃$uci}pivTfB7,nphۥŠE쪅[ &5lҪimjriVJ]|CPH4ַҳ"7cxz#ȭGn=r[xMϚm}Ϻ(d¦Q  = n{jVX/gPjKh>ː6 zf*dV`.}筇XFpְ6{`v7F\nNy"]jfdZ8PicIT>xC>)mY,̥!016oJj&:jJYDףOoq]\0*H] y9/6U4/$ mCY0SebIW(A4ͼEBѺ[zEȋ μHA\Vc~!|&!6OUdTR8BNL%`B+ =ѴQӮ+(g]&;A3a3SMX?i|lc|`JV[Jc(hzzA![ T"&I賴+Rkڅb.m}7.S*/;n1D"^6*8bݎs̚he|wǍCx{xjuqCx sUo!jDhmC}|$2Uk|sk:8.o8صѯ!AQbEE.G;᥶PGIU:_U|>8~ܮWx=#m\'-tXyepyS{lcѶ~T 3QR1 nr yrT[qLǜ AҸ|%Saֿ"4A.4%l9Va[-}xʗqɔ;a.7q-",.=+HI=➔B5ٵrRE7kg)(}>~aG#|aթ;&PB^sZ4wctUHC.@=jJ3ISs_R,Ӣ<~z;Tݟj5bԪ׈{#qG=wqZ ;♑GL@xY s F@AJRz҃ )=H)])ݗj2qm:~$ƏT5ꩋPgh/ q}NՈyPw"zx{=^^{?MLŧazݍc^fW^\ fc74S`_i74՟;|ʵn'tn=܉&4ǂr3G3{ٙ{Y+'ӵӄOeJwLQ2&ܔ4$~Ɣ!Yѱi'?v2bzpOn< E3É9}f3D557$*V嘕| f#S2Q|8;sSh2R$Ͼ/%Qѧù8 OpenOffice.org 1.1.0 (Linux)Abhijit Sovakar2004-01-07T13:47:022004-01-09T16:19:47de-DE17P1DT9H26M16SPKwz)0 settings.xmlZ[W:~?YZ`:-P@"6HIJa:-=kC!%WJ鸨 sѹ˿wpҭ#Ms!#4 ʑyErǔ9ZV jܬ TQ r}]hIU2ܻPU*x/rXTWJ#ȇax~dKJEjע<2 o׍-JAQ|gM\GCW?&fxF0ܘHIj^h ROYW'*QT,^@ނ<#3|^β7 rڗU@{ Ƀ3-1 >gb&(r^Yΐc{l(嚳f7%&>x $ AϏD^[)fO&<K ۗL4] @l } `DYʀ3 1:5\D]Z$]ҦT:M_7]<(XoDJr~_ӥ+GmZZ@sUϡ:Tb1jPLwU>,Fnշ>&甉r ;%x2IM6ټte.UA40Ck6刏9 ӵ~hF6ix1iePhMy;69de.ܒ.3`;:S5tur\i_AyAݏaA^3=)^S{kZgAEN֖yzC'p!LPF}2KccO?~LI\AWM)uHC5ۄӾ8,CL&`;)KrCVޓi0"s Wԅ%է`sVj u#اt f02,sCAC(˳V:穖R-̅fiʧ_bmH6 {% !bi\? $j-; :ij?lu3 6`y'4r]-dDl9gF)]`7q0X<)o9r{!; PN7ށ! Dv"IGR]IHtz1 ŞD\8So)O?l" A&\'$)]9 xAy(v#XȚC ݝf=p gJXBk:$!Kf@l;NZ̽_q5nc2*Eǚ?FUuMߚ-.u8h/EOӇf_7d,v~iQ/E0{"dy[Ey_pwrZnc?t3پZ [Uoa(~u~Z?}♐{S_N92Z\:DdlQMjڳfkPoh6tf6/뽝LA~yZ4zA۸Eh4ڷh[K;%iTE[ms/Ʌ6hUc8q{Q|)h1ҬP5mPַ#ƴ$f5jIiq^鬃f]3e͌H"A5(uJUl$‹MiwU3%.櫅*ȳ?)Ic:2<|ߠ\'C~plCJ\ܦx'PK<lPKwz)0XmimetypePKwz)0ϣ[[-EPictures/10000000000000200000002000309F1C.pngPKwz)0!/?w content.xmlPKwz)0&󏱵 styles.xmlPKwz)0##"meta.xmlPKwz)0q}і<) &settings.xmlPKwz)0<l-META-INF/manifest.xmlPKJ/OpenMesh-11.0.0/Doc/images/mesh.collapse.png0000660000174600017460000002722314556675336022672 0ustar gitlab-runnergitlab-runnerPNG  IHDRsRGBbKGD pHYsodtIME ^tEXtCommentCreated with GIMPW IDATx]l]~*('"̓:$Dɓ:tR"Tυ>W7#E58Htr._B`ԫS+SdԠdd``&ˋ笳O]]Z{}?px>]ݧ{׮kծ]{/p=6 a a a a a Wls %$֒ [@V_Xj#i_uml혏sm$ͼ3Ʈi0-$21 mEIMg;HƮ!+Iĕ6s>JT~V5 As-[>N^:mԈj.ָeck#=0v֬O@+Nl9-1bbci%-j 6ց6Vw$q1٘t1_#7/3alcR+6ց6֟Jz!i% k;2TҭGe566SZ^%鉸Q|pْڊj1X/UI+$jF53W]T+ԢJ\ kQ%R*q%GH-ĕFU W}T+ԢJ\ kQ%R*q%GH-ĕFU W}T+ԢJ\ kQ%R*q%GH-ĕFU W}T+ԢJ\3kJoD\UiXS|A t=vdߴD5LšrT+@TSjqec&U ՄǭٙWWJT+̣c\{1;U UJX*qyTskc;f6Q%Q%WG5:cfU UJX*qjQr\{DDVJ\JT^;&Q%ڗι'ܣss+~Ⱦ9@T+a%ĵ9t㽿y$ $ +n㥤UھGUUzFS笼ygl"Uz+G\s2۶YMi{ڂsCT(fιE~$if_2Y~cPFR_{g}~u1i;pYo?TKsۗh\s6?9kOgt;N$yIvtIo~Jz^Ҵ}oy sM$==> I;VҨo m6+<2sbƶoxDQm;%-*lsna3A0۵U/߽~Ysdfp u W$MuLjN3^;&Q@\s*XT% ٵ-M/-TOBqҕPԼ}a^D~Qy~ֻ KT*\{D^fԞ]2ga+ʞo<4 ~s~az}&i~#/9tX9ŁAs9q QE6quMT9g ڞ#I' %-m|\eթ0o]&I?#w}矓{c'/tP_ۓGf~ljM ~,7o}gOΰ1]X*A'3ơ=+;{_p/X\Av>#5j++;OhgOl,Mʳa;*lI6[|e6>nhO߽l%KDoIꞛ.Z#]i$/2qI/jk;?Y.TxL bjjYvվ޽g_M8c7V EXhm/Ys2D+PZV߰ī/,F.Ǘ6qҰޠK͘Q|㠔M cdP3c.i",8_:~͞{\}2۔mS.@2BXO9%ˡ>|K`?ii?W^y1 *N0D$N/s}xŖ{1Kkr;]^/(pG$3ei[mAl,9ZʺmZުu͋K?emT}Irתҹl/Ugm;S];ι~{*ڞLKeDħ Gߓ ;gk;TNGOzB({LuTٖ[leM7ƬjcM){u #'$-K+';#>5x3^<؇.sM8j]lsI_}.:zx hcV#OW4z]B“%zN! Du2Si:~,4?(xǜ~Kp?&S^MI?'`9zw}?ĵݨw>{~|)6yYӃaT۷|#. V>Ҕ6~Uk qm) Zp/_D"J\"lZtNK\j}3ӼR~l8^>ͳqF"~}o{d!@a q53{1o%JTǧ%D\7;qm@X+Q1k%qVWKaW DVk4襲Ո+Q"Xc|f8W D& LX#+QVY&-ǕلuLX[+QOX~820am)DrJXO& LX[+Q +uMX+QGX>mLn6W 0k%g-ֆJTSºH⾫Wܵ'眼ΉbB.̽k ƏsX^ENF\&Ϗ럑Ejh$iQZ'GgI.K,WII;KTae9ZXtH}> [ @0k%g.ӍjޞeaXY>Eʿa=MY.̱|tLz6`zᬕ& LXc&PCXEa=}%s` a9+y$Uym{?cs1k%V_&ϟn+,E~.oj4*"Z,,$x}K/}I6 V; LX/k&P!,wh^=Hι[>,wo^Kb@YkcE T kZ&k!{*y92&{fph֚Xѹe`z>|K '1; LXo"~>mY+r\2$]Kq\$MK ։!eڹe`fWXsZ20aHe` Zsx k]& LX Yk; LX ΰvy9" +;krp痁 +..w~@20ag]Zb@arp"ե +?krp6kY&., LX YkY-VH#)/g LX r)/ LX Yk-VH').g LX ). LX YkJY.VH+)-g LX )- LX Yk .VH/),g LX !), LX YkY/KU G3I#I>KZz<^9K*O%͜s%-K2|L,/%}9$i)iߴ{4[l/4vM/l^C@ӎw'@hATj ר6n5}2Q/[3vD54iЙJz<2X<[&t9#Q=sΰxvpgOEՎF5dCAd|dE s8h`3Ƴ[<X4jbČU?7MYm>bF~ cQCU[ m~1:aC@nb[ncVt"řp@L-.ҊcXב6ns^wfQ {~[(bk_A9]Al5t\}|EnbYnuyo6ߗ4ܚ"*\ ]?\Vc 2hݑ+/!9_c7Z5ڵC5d릮w2Vp?1es\ްѨ>p\+8<}Qz眛bS<&6vbjֶʵ^Hߴ {`'l\0$:hj#m^;kQ|TwbٸIYn0Nn-09];k՘"A+QkqvpghJ\*@\k2p*Q:ĕĵƖSja%D rp#E5W JVcM-dJ\*@\+ZX2pQM*ĕĵRXX2pQM.ĕqK/$J\*@\Z/|e.D5ٰW ׃arEդJ\*@\w~-_jKQM>ĕug_ZT;VJT3X>2pڙW I~ITD:s|pKu&3*&Ze920Q%u_^D@3cg]&뼴Ure`JXJZˑ%}D6=s]HZʋ*f?X&.QJ\- LT k;qݾfIT]e`z:g+`;4kIS/7D@cף{r[I,,'OHbAT kqKXҟs!#I*Hz#K=76) Kf~{gb"@*oxXO+ ι6P1u8ֳœUj"Pg,s ac,+v}ܑH:q `ژEU1;-d#*\00g@hpc=um/FۋDܑ8ƮGI#7Hz!6=kHzyd:#"n%T%$X>k{⬻TYF5k8n=߱k[;kr뽟D2nM$={uc}LuXᦏι[ @֨BT%ihc6s%% [@c+I_1Ϲ2cm·.š G6gA[5j,` "أkT7aml]Ay-+66 /iI@Xf(^2 61X\ja=ܣkIM6[m/1ahq*tkc\>1$mCm"NuBvU͎|ڌjy nnي>g6Zk x۸*IsN. 96nsגl"5WEJ\UJX*qZT+a>@jQ%5WEJ\UJX*qZT+a>@jQ%5WEJ\UJX*qZT+a>@jQ%5WEfTJ\UaXS*q{9׫v$J\ZTsU&;gQ%QMx.W윝*q*q%D<9;g'J\J\ +Q%2jNqΙET+@T+a%@Q!W9*q*q%DD5v9W9*q*q%DDfzIT+@TktzDqtkqEvKSܓs9`ι~d_}{H9D5ݸJ4+Qe~ԗd^{7al% +nߥsn$id%H}ydO!\;VJ\ϨMU^3f ĵa%ƶ]{>S$ $-ȋ97uY|}ndIٗ$$y760%m$%mw6~[{|}n>\3Ҿǃ+%n\a ?or"KdvtIo~Jzk߷MKKn|AIxSo߷sރsnD(N^+fveJC>uN IDAT[Ep7r:QE63WgO 7 l(dڞa! v?*3#>Qm=_dfj6 `{8>hn IEүvjhP7j;v5JQmm' 0ocv6A+||.x 8٣[7?~+;Ga=0SQk;\#"ϐa Mś/lV^Uy#3^t_NbʮQ߈ 8icqOCgKgU~K/G3'ȬiPz<^WOc5s@EK脯{RD&8iU_zj@]_t&Z{itEĹe,7 -DR 9~m]=X pO6Ł*8(rJ9hśTqYojL穽mG Ȫ_.Y0ɨ4\pAFW[ mϔGU?AvM kqc~(Yjjm:֕$~OYu{ழ}iʦulᵃͧV^cXe@ıZ_ҏ2cm} IHToS(Ш[i,"U1oR(G~فkѐ}Kӗ4Jx bVpgH\[}爡 ^6l&o_,b(BKב=>q+|JkXWㇸ[?7>E }̖`Wc>f<QsH ,{Q-D)ѽm܎2#-E51L-NW7~SogF\[j "I+Qp&+"DЋx'kn>*u).-Q%ĕ9,L}X+Q+Rja%D D5&VJTJTS{ĕĕVJTJ\sja%D DW fդJ\*@\*a%DqpT;VJTJT +q%kکW WJX+Qq\N5UUJ\*CT;֮ƕĕVJTdלEXW WJX+Qq\sjVaM5D )5רfJTלeXS+Qb\sja=D@q%5ָU)ƕ(JTWJX+Qb\*a2D@q%5ʸU)ƕ(JTWJX+Qb\*a2D@q%5ʸU)ƕ(JTWJX+Qb\*a2D@q%bԋsNs74ԗޯ*ꜻq9wm744Ʈ~ET kqIvβs_IE `A MsKIKgD6?)ܬ/髒#/UشO1QQ= ϱ* l.ژt1칉I/y`@hbck#'%@ 3Ku 'z0;sZqghcaŇ5of@ݱh&#M-k 6ց6Vfl.i*1k=ו. ھGnmI_ԛV\oڇRP/< uk~"*c\ I=E{{չY3xjْׅX6a1U +~(i{. WqTT+a%pWb xhdT+aiZ$&IG6gާuILR*q%m{H&ĕ1c vk;߲qt!ĕQ%wT+aJ\ + W DV qGV ĕQMCq%@T+aJ\ + W DV ĕ2jNq%@T+aJ\ +v>*q%@T+aJT;W DV ĕQ%+aJ\ +UJXq%@T+aJ\ +Ut>*q=v/ǒޯe$ƒ>u5[>ƒq=HZyD:%=Y\v?}Yz Uιdh _?ι-6N-9֒GT[p}KWe)馩\5c%. ڱDIҡsソe!D1g`AT[I73K\M=p$ι)KkD0%}QjbH6]\_cT⼃Ȉ 8iq4id&fÚ؉hVAa&CǍ/'R%eXO+Pa=e4 D+.ú5XŶs<&pbk_K\NYog]HZs?'b~Z6q^nsW;f'K^ 65&\4=MSStw$zgJG2qcj@VG릞fj_9^hޝ,f@ŕs>GIk)F. nжkgظ4QOkI/sE_3Wv_͛\U ;L{{-ĵ;)K[iqd8"8* C\[*ca%D+q%J\*VJTƏU ĕa%DMX+QJ\*VJTYU ĕa%DUXs+QJ\*VJT5U ĕa%D@X;W U ĕk'JTW Uad\*VJT5U ĕ=6J4v=VsIҗÏs# 㺒4}<4/*VԏU X\I69QŠg*>'|zGd*V8s]HZ*dױV׹V: aEzι>Q\ιW_ɟ$g+hbMI?+i}WD+K:~{-y}Vq s60cP_޿d3V6y! +;LkV춨y +>Wx)C3g@8+ "#7]zbgzq,$ݰ+\&ھ6-`+ + + a a:D+olIENDB`OpenMesh-11.0.0/Doc/images/mesh.inout.png0000660000174600017460000000626314556675336022227 0ustar gitlab-runnergitlab-runnerPNG  IHDRadsRGBbKGD pHYsodtIME  A-tEXtCommentCreated with GIMPW IDATxOhaPHK! iфBV -PcP@:Tx(=U&q =6tɡK BǴPL;tW&aAf4ӌlK ؖ_~y\jYH$H$MU)d+Z ~х?:IvιyQTtUPl\rZ릣rMEG(WFd Q$/\֠&#$Z{IP-X&J)RJ?_'9cQlecv}h3] _J)UAe91aݾy,++yg٬M,2Y~$t>_Z?2q$[BMl<a/%ZkisLt:7\gZ?hRμJS+gyAC0xŪy{6}S!AeA$z݋F%IvJ)N`TrQ%~q)Q(zQ^oa^JI ZYq` TQxa(sѿ ڻrj,˗%e?N^o#N~dPѲf=X T7j U TA,PP"eNA T*@P, P@E@,PP"eq T*@%,PP", P@E@*@YBP, P",`(`T@(@ T*@ X*@ XQ P(`A( T"@(@*@X* X,P,` PE` P@( T"@( T*@X*@,P,`Y*T"@( T"*@X ,w,PrGaYhT"@(e!Q,KB*@ @( T"-),s PŃenQ%*@XC(bòi~`Id=ׯt{)eH(LF,Ik#Ho2bf%YkP׃e_nC(duRRaiZJKr>E ,Z^~å3G(̧B֗o\c/ *4Xnkfti0pGI~"]4[K)$$G7A׀vC3ϒ]^\D%E ,?'/1'٭-(I(t}7L^Io0jACN~;WR\d͌ԏ2ZWatð?MƫnR Yk=Ԑf6+2nWk=ǑʴӖwjEwܽ1TS= kܽ1TmS@Vo *S-t2\]43zHiqA]TFkK[LlxH%yym?rj ,b2ˌ>*k ( Z$I'9[J>/M<EPYnX'9jMۯLg^'o A,cX'y~^61*Ó "啩$I'd6J9 /64EwAEW岾Rݳ@iK]*`:,ڿQP2c*`9ɯRcÏiPNF{^ZkZe윋ܻwO9瑇Iޫ>$HA~G%ټ庖&{-9*KR~/~+>rM;<ɞ5M^c:(iSIEF*z/I<)Yk=tdW{"GsD(e-'>3[jyv.I$H$Hҹ{.4RV'鵛Ij|XG)dk۵[@ s7Z-M95YbնdD9ʃs2g5^dDYY$HIѲW_|nĩZJkfS)3\ķiOj<+5f=Õ W'I~ھ[J l?zu?)ͿZ|=l4s4KQz[F_4@ƍsgc&{~-z)eF'sIGucv|;;;ޞ'4:dx^{ Cln7}^IǑY;WH#$k孷~8F 4yGdvwWN?-h 2'd9$+RN,4OݶWJSJY@3iXF(륔)$c8)FB sH(9jh 3s-N6ZY9Uk- pmNm`dYGI#`]Mښs_'4yUkQl\42!3 & sQ4 h4>2 F؀F@˃ l@#FA6d`#@ 2h sy h4|4 lFd`A6 d`2h 2 h4 l@4 l6d`#@6 d2h #؀2 h4l@F`6 d`#@F d2 h #؀2@4l@6`6 d@F d؀2 h #؀2l@4l2 h #؀2l@4lK d@FY2l.4l@fI@F d%Ǧ@F d$t6Bt6Ŧ@F66  dcs2bd-z)egK)=#Hs$m__h #]$$ 2a3ֳw@Fpl60j)e4. vZ$-@FhlZʢj:4.|1pRSDd67{ΏMfo~֧dess-Ó[ +4mb?a/ ӥ6{'ɧIb)$YIrRFgWF}l?ݿä4p-^B`j3Ikzr'82I'r~h;eMV!ISbn$;X49{ub?8᥹΍͝vz;f3ujNX_nu}^'~\ F}c dFmRvkf)WD 描qԩ?փ74L>4^Xb^̺ET09OYO~+HP)׮"}r֨f{h`6փvvAq|*to!#Tlj\OMNk^uFSMjZnzAVMz6ه@VV~F$D>d o' F:BFI]RZy-LBK$+us#|k|gt$?J^s)$/Ox~c$О^6)U%7n!h"6IƔmlZwMF`ӟmP:_>C=F] Ht99qU9h4FU&G5JI&y `qG5k.țAIF4F %h,h$:I$Fh$ 4@# 4II$Hh$=B=qNIENDB`OpenMesh-11.0.0/Doc/images/inheritance.fig0000660000174600017460000000124414556675336022402 0ustar gitlab-runnergitlab-runner#FIG 3.2 Landscape Center Inches Letter 100.00 Single -2 1200 2 2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 1 1 2.00 120.00 240.00 2550 3900 2550 3300 2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 1 1 2.00 120.00 240.00 2550 2700 2550 2100 2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 1500 1500 3600 1500 3600 2100 1500 2100 1500 1500 2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 1500 2700 3600 2700 3600 3300 1500 3300 1500 2700 2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 1500 3900 3600 3900 3600 4500 1500 4500 1500 3900 4 1 0 50 0 0 25 0.0000 4 255 990 2475 1950 Kernel\001 4 1 0 50 0 0 25 0.0000 4 345 1500 2550 3150 PolyMesh\001 4 1 0 50 0 0 25 0.0000 4 255 1290 2550 4350 TriMesh\001 OpenMesh-11.0.0/Doc/images/class-hierarchy2.png0000660000174600017460000014156214556675336023303 0ustar gitlab-runnergitlab-runnerPNG  IHDRO<<sRGBbKGD pHYs(tIME 85Wt IDATxw?s=aEP F%B,-OcL{% `A " wc`( :k_<ߝgegf  c[]3G;@Gw5$b~q ljf0x?#!KCc[M%Z89pQ`y$8`cPsM-@?\Yn `֚֘. ,(Fk?n[]9o~l}`AJK/:NӖ~HkYn0P0 @}٩ߗ!;,+r@&3oחRQ #0\T2p /"P~ǽ('Jl` RA7ZˏMof?Solv֗Lm(<6#8}o EU YuPЂqSOE L \q=b }7e~I3U?4ו)J'wc| Э-ɕؤ2֤%% BJ" mqJA(/l쒒ج`We<~x`$82J0ֈQ ';RTESZG"+x>T p-\Wkf $ΎHRJBJI*FNZHdp Vr\ti{\'U]+֥fhPpQ9 F{O~Yn}aOrϲ6-pLu}eOdU?xkK 8/x88SwjGeSra. aB35myR0p Jrߥ2Ji\n֚ḩR*)v k)1 cS;uHG"Crڱ_cZ'dmNg]8tTp@GS-`3TPA&.\u.p (. ğzrT_0>Pf)~QG HRtwUzKl{" 6瀛R- yAənd(\p{ yr5 <@NW 6Q<`inRO$.>R7N8d!:8z98jN c=TՅNC~jڊ>XV7Hm;8lv U<Xik/+C8Vo>? w[ֶ!>_0]_%v8.fQE_ / —䭵lDQ\Dg>>?I/u>#'OWZ:(7&WEn. p-%_Q7*Jh'PQKz<$8I<3k)WN((cDŹuSԻ^ZK($`M+ pd|a(Q,&M)k)8O˅"<!ky0)V Rgχ/lګ9ݕcJJ%玮{pXv;:I55/`L~ 855}t}0t\WBOYnqS)m"סݵm#r_2)[eU;47(dkj^޶7Yq\i饧RSB06,oemu5'<5մW~.i:n!gԇ,7oeYfUחubݚ8<~2IqG"t*ﴡ܌tI_2XV5B2ϯ/S/l $iߞX܁㤸orYwRjn:#3Us5bl&K|@(ԧO.7^qm"6/yI\7z6bROіb4ရ7^hg)7(@:zCpf)yGF%)Vڍ ?u' x{a%{[V_z $¬z:*8!8Gp!-k}_4*:N,?op"qtd 8\BE"Cbi.46 zD8Ef!px|Xv Ms}PIU>S8.?0uUpB!竴"aTPߵB4zɚ-?ʲ&DwȐzQ,۬iKFu7ͭ`5S!~) ơ(t0A+W O\,E#x=7V:ENWYa%=Bèi/g(.-3#;1n^DCR*Qd@$m@)n Tɞ1'9o-G~ Dk `Qqb8RYf0О_0vvsěV z Xזr@煭7;OgY^]&@zK,\q]o[CJ:Er[2x+xOxs kϋebJ8 Mk‹J(XaԾ{}(t8pl`^c)tS8]S|`x!`4?/5 8Z[V8ބ^ `<ۗDbys+Kffa0i7te[ e3(γ'kY0Ìd9fx YS6k#II1 `0G{ `0`0@>- ;8Yȩ$@G@Y{3gw+JΟMGr>Ql,a@X2C'r˕X>B!n嵬꾡 s7)t\P e/ cc"|)틒Gw8GMss;U]֞88$ ݲ {cQh!3 7IQ*.{x!˭ӓs](9ĕ6 [3Tg0{|_W׿LU]@!)JUu.Ծ7kzJeަUBK2عu}٥ mXw4 c`0SrszvzΉņB/2-PvPN%c^3z@lvz)Dws[*_BLFy**n/u}5D1Ei?Z Ǹ>B]ݛ [B@3ִ%%_+DQ,E0wJ}IP8|ROۮH7<y !ҫDmWw״Xv(J[|[φB}~^Ӗ@"P%Wuuo".VE'#FӖd).<0A 4g ˭xYnuw.Tm;`6;K |9TA@mX`0`|RO^:w|y"߰>b Lfrk׵t_n_/ M[/)]_. B)ӓɱ 4]#svf ܓ]4.LJFӖ!`YY[u#8昩eOZ(J{UjjoeC6l1ꡫ!4Y ' }DY;XemF"C5mmXqu}NL ЭC&3eeaR{*mD4 rO6;k χ\ 'se&3y@F|8ꭙcy8NyUW?H"\Lm?Zs:K7\E{k:\EȩMsc IMl;Gھ g?SJ&ǥKJnp5xTO) 甔 ٶ>ݛr_M[E1Q&Ny޲.K$.ug_}A8βn6m9P cuqRFrV>,˪yɻЦ̴baSj1 NOHy <@I&~Юs\nmԼ RsR8߹4$܌5aǛ)u4;K4_8' cブU5;apxRBlv uZ8;b Bo'(J 2N}ܷ8.ءпt4ϯ}Nf{8Hն]'BBtz6m8/_9-c]Kv؉%%ú7Fi:َdž>G8-ݶnS'߻/ɱ^gvw̵/du#L'$ fv Tl,NORT} yy7|da)_f㤧 X>_%XR;Nߥ}[$E6;/I%_p;)lv`Yn(XɪpxyJU]?'9U}=!\<>1ڂ\nm8I*/3 M[WEQ -taX[m՟~` ci1͍MB~>_Uuen2'翾Y5uqH8lv|~޽]147=#emG ualinPӖs]= xmzE{ߪ}LfzWc,k{_Yn;+w1O>P%Oyʮt.mɛ$b)S7@&Ls=9CӾ #|W3R O:AH >ZHRyk>\^~rnIZ63͍u/1C+YpS>3" %C7ۖts>?F5ҮinޤiK(QnIӖԴG|D⒯^J&v0ϻ﫞ِu`|^z.k#X3Z:'J1 `wTu0ǩGuEF.%3dg1-'b"L&ǯi# y'9|3o,W߄\W=ƶ'x`dvȲm&,`1a0p cK dպ B˗d"C'(^Pmm;ea94״uPx>2 Oo/;麾r!!5\8o G&ضW'vM~۲UuaGJIj1AU%hjYދ'[Zmf29.`x26v|}.7,Vfg!=dfs9EFJ&}zKRuuo竬մUYugΏ|tr]UdrzYnG'N̆{iK{Ъ_|PQ6o~h|(4uen45丕 !6AӖvk8ގ[nYw5ދ f4\bu':QM,)j*5 ~iT1#.]{,o#GƁ2HRRlcCr]ʮhGk7ߊbiRu-P%r)jJalXE*־R4ʹ,Woq2r4Pj>fL JmX֝ʥ뫖Pu5)nFtv\磏սjeEe{RFhsQ^[Zֶ<2{m(@iKwm yyl]"5 9NYST ׺%ճ-]iKv/=Cjq3Ei[ v}.rvBĺFbo2 e.6,)u-=No*"V7Yl:BۢrŢ1~ MBEK}N29` IFlvMq}4zfFC-PF,qE#Dд% iԸLs?y-gv!bIy6rۛrK|{}Wx in|VF8Q;8x&oB(χ{|,+I-n5ery_]_әRA(Qݬ9ԑVJJ~zC8Ο@W\77Npx@ݗcq2ӎ6+-x0!zAn]Ij6_xpy4zʆr|Bn"d>RY8<Io{ֲ}p\`.OK\H (/[}ou3w=L"o]CZE]Dt(6M7ʎ*/Fmn٢Xr%%x^d8.@d̑.y4r(&!Kkj^e]a[RHR Z2Гɱm[k+2m"r_uXәKB}~izuZ>?>1 IDATy cŢؔwܼZIj1FӖ Vn~ !}74(&iЮegb">f TRV7_4͎-~烝"M b/ %FT$+7uwh ۲DWWW<[ͬ  L|w^7{IWH`IRt}s=%ygo?%9nBx>S. ]B$F}!_Q:$=_ \8W"Ŧ}m!gت@C\ޭK~L|~ޝEi7M[dMA(;|'i[ B鄺w6ދm-zRbGG"'?O {+3χ@Yns!v|cY~Q,4!k-;-!5M#Qlr!]؊rToKSv-!`|St '+JZJV"tU9NfE{uպf*J]x.} $Qۮ@2*ejY+%iI@azncEũbgLDN'4mَ}F#;>>bx/}\חA;=ǁ@Lsӥ]fw~R!O;wAQ:|MKܰDHK|~tH9J[6۽@-=s.IVMBjEpS>Ǎؔ_? 8P3(.i^|px0#';:QLJ}xTЉ-kx^VS<`ƪQ]f6Djj^p}c;KNto1^D!,>%W-D`099>ԶO={սB>_ٙ_Totvpxѫ}qr`; \sO0M! Ʈn8NkCս3;|.AlOY/cY[?`0L+Jۭc8,š[uG"]?uqH:qk^:gp?Tȓڀ̭ՍR#` 9F(Ɓñ&`0L3  g:`0L` `0G&G&`0 g=Z8j(I`0#8 8hx-:fa:`0,}٬YBg0 ƑEO& q#{g`k`0LA2),`0 S `0Bg0 :`0  1 2On!xNZʺ!  τ^pk#Wk 3 `~Srn5đxw~_3t`0Bg0>!9@Kfh3g8T>+%=Dk9!b9 <g+^Eٺ8 àO=Fw'D:[jڲ!~iBeA,ω^6{8Wal, qTl艺,RG, }x6=ʲ~~ c<~AwS'h~֌CA|:J@08B]Fז<0d<%Xhe(ݿB&AEg_q/;b豇c8M̥,V;4|dM< y>;BAmC{i~QKm;y\Lf\Jˊ03 lj1bdezJu/O1*(El'F Vi^G_.ĥ"Xqh*M[xT8< Ī|b;=FO*UE"Ti*i(EiK&ǿJem186߅U(2nb*B*تHdpqj .m+-8_ ﱇ>#'t8_ ī3. HVT^m4PeY[Aۺ.z>ۅUPR^|QZ:"(UUܲ*-"8lvTY&pB{oළć#-y/#j0B8p_2}g}^ڮ<4Ez<WcDK3>puhK;W<dןK'F?u(tI|~aᤲ˻q\Z~kx|x`U; p))ܺ5fO0 mz,vx²F#"|in8_Դ%KK.I}9@ BdmoGuǙ9\ Y< ?_^M F;lvJ 2-3IOrk?rTu4B78NO>?gzi{VAYn_UO%D<=%;lֿO8]BTux/oXTbyCcSu}4'@ yS(ޤe|i>m_8*VR2t/r};Mτ/ƺi!҇WSE|P!iPjWh{8w^[$;aF$!X~:'ӓF;Nf:@t]mR&3qj4z1lh`Sdu.;FtBUųy @?>@ok^\Hm`FȢ=D0ʿ` Bߥ(R{Padw5pH~d bs;\ h/ok /ύE} <!PR)c$ ^W֎&2M&_k|~o-n$U M$. qRsBI`Gv]I$2xDiA)X/j@|'dOD  Xwi"10'r(׆d@06rKt}u,W[EHL.|7;{ɧG4m]ғ\WT Us̓ca9ηDWiott_N U'=Gne>?ڛ)5GQR<0ܐ}ݱdi.|Rb;%"p\ tm8<< BgtP06InM͎F ){"$PEgƆK!vgiȓ"9.POފnUtol6( Z)M[20^#F"Cp\hQW ~>_?hA`Lss.ņFpM_P_ց}9`<X!#I{Dem~2u٦MC'DoHJ͹uqGvBUQ<Oa[٨x~/|22qI>WQBJ,10 |nQu}e'w'Dz*ZǵҍW v}&MFnYub cC~LJwVrEV&"*eGk8wQl']_s\jE M BCYnLfIM29n1$U{ |ӥu$_y3'WW?`L'N-FRS]\?~c(N{grln[-kۖNdǿpAEiUwĈ -lh`4 Ppm _hQ1;0ߢf{CCIrcG"d5ϼ0uF3ND' 8Z7mx@ Kc( ],z>?g"qqqa݃veE^e x;Dg9NJv/(_^WvA3 }_Ef-inXd(׵] xv-|8ٹu:SUn.hں-V6;muPե&M|:lJ)t'󘑔:7涋'in {V;Ga26 c5 cgCDz|7q (uJMxsgxٛץ(2~S_-tk@wFE\g~̛}Pj'}~ohtȥQW]ՂP0~y26<0o[3_2ǩ xvt(X#x0B0*I9$]km{( }v.tr9NMʶRj,}c|!\Vv( ǝ'ұTW-fg嶝yaSjTQl \>ց3W@ Q9r4Plś|c Zф&/&6PK rW(?~Q螗E1'?rPGwYQ*gx>?ox"qBAM%p1!˜M5>ѕ {Ј@c^LJwسVQl^U9.=$,u!)Ӣ3$KM rlPC-9ί]O$F^FC" '8NS*qN+V$󡍺X윓 =%G)*72DVv()9W. <΄Ã6,sĥCD{<,˭CEwޫ@YkOJ$./O$F фȏr눢Ck g#c"/{ݖX2{*E+ޛ4@7+qvyx/D90}=%iY ܔ !;fOֽ .0Þ`$h5=7'L0PfE^/g*g3qs\`wЕoY۞}vEI׿Ij3 [)Jc]_yui)eG(`Zؐմo.KE.T_?v&ev[ہiC(T5\nxEip,a(6qM& g|I\*~ㅛ@WǺ78f5zMnw۩'5A()rAhߝd&g"SSod|6X]1%YP脙<!eu{=u,{!J@C[/^hG~FWYfY7ս19qR2p6;m]4zf-@jڊa<i.˭Vb#{zQ!ive"'t_L_>7(tx|HV&5`.tIn8ݤ"֢/{nJS0Ckl`Eױ~<4T)z"L4(4 T;]gKR˛T t!Ը z_- {wpрJD/lPKͬb귄#SOvLʊdmP&ʴX?Hb}Gy#]m!"Ԭߩo!!,!RjFx;l(EiŜlڅV*?4,`۠( mRC4zZlvOP?dӜ--)f>߱sYۮQhlvD`f{pi/yvkAU]:| ep?kt}upx@ضk 2);)jӬJK7p촚 M"4>2N$l.-&#r_rNnG٥ Lm+I64$ Ʈn8NS@3\cz `>SL3vm`0l3a#b`03t_b0Yྑx@xQ_{_B)z_z.k#^d? ]/, 0%M+(>BVt*V˰<Ǟ BY aFÃ>7?8{a[Fud))65{s@#!$ٖ@Woyн习ݮ_(J/})ߤx,Z6<7Xɚ~0EC:9%%w`a: =Ef1K;Nfs`9I$.,s0{O&e3"-Q5m >_8NQG?Y7B]J}m/~jҢ`lnY[?lY[oR47)$Yny ķ|kMӖuulw+lnי^{MA磟* ደ'&J}\Ӗ\@!.r?kR7ܛϭ`oԴPdG"'g.747n3͍47q?IqXl(ZM[rem,,z9>pxP,Uq2]~u?f2S<D(gz29n+:KJ#n6u8dhIj9~)Wve(;&;"@q钒Z c(%NI?y! G҂lZX@Q:Klc c˪,Dž*սE/ѴuM\χ -+Juuou}(]_Vq|ƚgLs i'jڊMs#D1`9lvV>Qlv!UN3hi%r-(w$x {wĭ[>t4|]WG$28J}$S_ `x,vtMal,la?aBU+UuaWɽ _'lrIjAH[[-ch麾aw4ܥ옡 Zֶ!|06<`M"˭inXN3 6x<oWtz Zg.4CAQ aXU IDATֲj״>gì*?S9et* * 16T5D1jƟ%jƒX **(* 4i .}Yz9e<90^hYf\2ʹ>Q,HR~&M!⵶]21ۑ]ٱtw*xRn9!WɄH QRsWաEl{yXDx>th2Ƀ!\o]_f&t]_ ׍/{u<̉^~a$9jmr3n(n4f$~JY8 4͍C w?/hʿN@QnX W BdiV [Tu葄@k81|}uHI:<`_|^ewɲv8.8tzu/UM$fAB^I*~4N6Tu_m~LqUWem@E0xhg]/X 7R օώ^~q0xhL Yuin(nw]w}eе|]_}y3Ms u47mrhP=kWdZ A èn$uy+yW(4BybF;vCKHNѠiֱyu'DEK6Eiwjڊ6xiIYvW:=[^i<No;NGv\Pڔz5ƣzK J^Mh}K gm3`9y< :M\fQjvvfӴ@Ji<@p/@Ućon:*R*)iJ9^lD9N=[K/nٽ5m<'\7!.>*[f em먳2S7JvEH &J "X[L^PhhM\yt}qqyѴ}eTެkK(?lqW RաGq?^x,w"9x{ant˪Ҧ.nilM;Wfh_G{;BKhv5@ݖ~*eoFy"d7L}ump?yjjz*?bè8Ҳ(z$u*8vmˈ}*+~\әҘG]WznJD>7䦦iEM[銳]Px%Pզ8S+F ^8}Ӣx2QJRMl|N/]yw) LsK(_ɬ|LKMsM]k(ʀt&̒%tin&!/(}FE.[p8JQOjnF#Wd^1i'?FQ_LEYSVN~@#?o su}MHX_&M[5 n5 _:XUrGMs=] aWnPTtELmYZUK憗6} !Dp tt? aTD\6́h=H|LfINNW+/Υ}!CN/ r4K9<47O.[Kv͂P޶ID^>1"<}Q29Iem-3[V|f"&Tu/O+4Y1#ų]oljzc8NCQkHɶڻy>8*8LfoZ> Vp!by~?fضJRg@+khTu Xine cUO.w>} s{l r} 0drԅ QinwuLfIE'xq29\?;-^|Q ɏ/G\ R nvXQ,:@#j=4MzAbc({!P! MyQU?"tj+-PQ, bqH&g(.\inq#PpO3OytqzΒThb~glfaTŶk̺.Gvvp[V ;-KԴzfSl.Hem;L7/h/C9N|)uj{.`?^Lx&$ϼl)unz{"=eۍ{B4l((*t}ɩgUuiuuɅk~G,k{m~0r= o)0 L'AW 3UuqՊ}`6 ̒3/&b񧂐w*Y9]V U7zYyF&h+WzdOjEinyÞg-8I+;$:}è:=Yr$jw,wmY8i /wqύXte!Dxʶkb: |ϲ6Mִeb%l}S岸,w2ǩ~sېѾW"Fjm>/G=9c p=u6uETz[<ᣙe7j>_x>pmPDuh k2:qWa^z?CQޖJ_>Yp7C/hjz} ?:!;>spnN>E(4nW(Idoއ1}-t}nnhxpx9qO1ӬL8uVK?+qNL ~j}>bjdl ~jsibl{G=Za0Ag0#|p]u``͇0k%x԰G /0i>Dvi#;t`0 ~vd0Ur  c [ז`0}8(Ø:`0}`Df or S`0> SdWJ`0}sd`09xD3 cB؅G>[ or(w`0 crL lXȝ`0 f `0`0 t`0̠3  :`0D 0rPg:E=ݢdll7/xUa0:+gxZk-߈Hx̠3,`0 3 `0 B T2qz1!-E{;Ti%^0e Y lӬz|//lg\bS gnr-gdՋ8S!x% +Be_}oZaTd7Rg ^ ENi &]OpSI :uST4<Ϻn*|<~0*PjoZ]3i_bՊ?!=4LK"0ps0c :D'5mhB>_[870:\:2Y DsrB/Z.c$2Be,z} =|^ BdY8LU?"I- 8N]S˥5&+{~W".TuȅTEXUz,w_Dd{ “Fr qLQ/IXe0~:$EXh'B"ceD ȹ n &z`x0BV><[@܀y*L׾P6_{ #a6ݥ1/ၛ]qrW@p(r!sU<7 n wi +Bv>"|l^c=/3>_ْx;TuJpzG `m8A^@{%!JԬ K ^^>#9z!҇g mG$yTjn~y%P m%"M[y6>.~l'i9_KTu è-ƿhۮ(Z a~ȷUu譂P6ͪ M1ͪ \-Ș&:M(5ވŦ2`DtCe @u! E ={[\Dp8k/MQ<!(/l528u(6FB nIRvaPܝx8CqLpG(1>]ցs^pJ œ40&̢cbMqg`O.,c/ǩOr/7Wes]sY=&=(jlF<`JTjn<{M8/$ɬZ3 }:J }yó酗gtc4mUKa͹UVge#IeTXOLzuK\3oSkoڒnJ-/[ Ѵc`Y5b jMJVFEaT v̫m^ !`nVcM[~k:x03?.>cm d`Iv4ym [?ӭZ"N=(f,`cP$6fvHA)*i69kOn؜@%XjowHѲ򮲳O 7.|biP&]U_"R ߇ 79Nh>tv?kj>qd5@*PXxDm4t&1k,(J*TjvSD}8.(}Fś- ` @wwm{YH|5au NkwB`nή@]9/?:NC祟KҫhnA5|J-9c 0 VHn2\A>:w^srT8hg)b B< aP$'d >M`{{ F2P΄!4!--frzYc=u)\C OzV=6:\7h[;N#Ws}c:rՠ?he`p_`VkB{m׬ol|aMEQ,$D>òhǽix9M9ÓdA\P"1ܩ6nZ(B%!R&{Q2qErP6*`"݅W?:GPn߶ػhj:6bc%( l(L1yE))I۵H--3]lڥXho<&8<`r*/:5|?_CϟR`uSy>)IŢ\7qb^)ÿmf̢QoT ^@IRq 6x>ŷM+';N,]K$f pQtiN?MhQ{~"?RHҥ-rI'!bUZ!FSkCIb{HR4z%iMHOٵGpwbtm( +;N^5no^{|~P`  r=Pvg4趽Pږ(#;>.ljK^~9!O'G18NL06<y?F}2pqJRҔem[qTup&ϑUu6 m7ʿBI/è#N]7ivVinaY~Yq?|^IJ<"I]TAbi IDATsqQ\-E*`cƯj.P{Uzͣo'Y?C%>"en<_%(]AAygQgPn1Hb rAEOx< \ |_F7Rsk 0)]_=jnbː g|gַ/<8pemn IRnlRgr~ b(*ʀMf@vMhl( P`7bQao Xh%m)5VCﯯG]2h3LЦsDr5fR]ˉb)EsxR kl-& 2؝ /?s \FO!j4mS~oJRoR ӯh|;[Ȏ!n`4J1r?nJd_3M@"A`&%Xde2M_. I Y!}Z@#HS;l Xg| 4k ldn;K^! X&* # z;FV`ܛXaF9\[yl0*{e<$?.^(|qcE3i<_OOgw}۠;zO7 4h~Hw8P萮|mpLyTq1~0Ŭ2?A'(V55y Y<ϐ4˿ǻnfScY+mRu?`uuO|߲`0G^zYow<qJ)e!eM>UF\C$K`(B8η˙8N?G4z| D.r]AU{")36t)=CeXThbQYAB$u. ', G;JRiY4z$(=$sY~|7minzFOe@IeW Mʆ3AIZFX(Bq\^F\&eиPw8L"cQPpV[FX&]bڅC#8N)PY4zJ=R%N,2Qb@^n/²;ȉpxRχx>P٭?2Q,*?xמn+ҲKӎhH B< e[igFOi"8W,3al ee>_ﲂsʤ2B2I*.+(8ݐm=i_c`oƶw!ŢMj-!"k+߳ .in$8K!?mWAJ*5]_ ЏMs*I*D~#IV66 򹔺:f@*5]K4UR>&[~a+(gzQN {aTyt9؅Q1q)bx^Ҳj5rヮyGq {R{}*5cY3k 9N9M~,qJ`^_1Lf-4TcKt%ۮw)kڪ#OupxmKBV,ŒYFɹ/nYJ͝S "XWI2%kN*<)Kt}헞gytσzjJQjd뒜$=JMr@?ź^Z;SNcY+2RsE:hI08vt:wln>Hύ.,ٍw!t~%'_ :ھR!ny&|IY9q={ՌXMsK9}8̢gb 2)v]%@>_^bm =j[&@V8u'|e>>5F\Ma}^wz@`]Y0*yQdV V47_,3~?ƆbӬ,`P>'Zi+!DtzS?̳yy5}lZA[֍ q¦݄6MC'ӆQ4+W@s,(/2-bX!P"}7Y=a?_ i+ZѧM"I%oɆQ~d>la۵b#^1<8˪.4͍;;;v<ж3r1 ׁRl}h||4zXq꣔zpU& ]7RωD 6%3wnk|0 1&3e2M3)'0s^4z̺'bMqҳćܥ$uRwaT h絵?)IR~xko9Id.[%9ü98)cY<ޝn(4tzU0è|WJ榡> \f{8kH"M[^N/ J Zֶ$RA(uߔ- *qݤW,szD"Ǽ8m L|i+7+˽6$< ܥPj~ZWD $~WR󣂐׍q-*آy K rp +*vxɧ=X .{qI Az^SS%fWjڗ:Xs&lQSWD@Q>_wƍjKw(i+l{>$@2M9CQؔ9Kc%N7hQJKsgN&gC34)Ls3(u;gʖ,x~vK$!v[kta+3ylbۮIMs[PՁ'kں2QjqpxƒGSS>CE9l@yX]kGo=,Lfh-ko3Wj%A:hg]Ulklf;N'f*GuJvϲv8Fw9hM$rU]Lf w(}(>/BHhp0EKadBpL?AWAJJP`%$Xw |$8𑺺iZyߒ5p1vc~g%3u2$=i`}ӫqV&|;JCÖ/Pi_,>ͩ#}KR ,M[xPhYHR1Ls3DkQqwVT.QMM3ƫjw+I=@29K<8](sEv@`U3_RBTۄm"9z+VC{i+ɝ1{5M^Z\!@WKRggM^zin p/p}"1+N|jAdK3Yz~+`;h&گeEy>P!I]%O:m5Y~[q~+TU5w!b)&CXO<>̒Us7@Q@2$V 8 ̉3EKF-,睟z$u]8mzPBMJ‹q{@&bM,m ydrXP8|èjL$r<Npx&I7FU qʧ<]{ex>84FOѓƚ x^]/˽@|Fk4!B*oc4zPBkZ;|PdRP0em/)(r!_}emO:ԲלpN](Cc bJRɳoIRbIr!<|,w "nΐgKRDŽqP _EG"GN.b}dBy$u)8<<"y_BvpB@?=|rx_]L9H 8\;w]s_ RTd'>Ϻ"?^w;3;TuǍ^Z'yF=zySExmoаl(L) oB8<0Bg-ŏ:NøD' Դ]\76!hhxau3%Vw'!xfrłPp!=06,8ijzu Pj2̢q͚Ffƺχ BPQ,z=mYՐ?v]!dzF]7MQ767O*JW5mǑq~]/ֶwwyEQm㚚ޜr|wTZihx77Rvw29;[UBWnY[kz| 31Ÿ(}=&b27:cT R{X6 bѮ :/066u}ZC-yy2,2YӖ6 r,w.w FRdl&M[-/bI E[.M2@3mP `[kHɲjzbDƯ(H8zdh緬HdRo]_#-o[0xH4)Jɉćﶽ'=o* yaIRm۵)V@~ÒOdi $|Ӎʮ%XU!\J,6eP:8D*5|,6 iVB M69( wwiu(6džHjsl$Z[rrr:]>,H< :J.m#__K45ޒG~zuy삞[Xr@&d#7<'_8/~p Xm"qK@K81?0M e2_5(BÛ_Ƚ;f۳:~?AŦN>(]J}=/~ByAߢm;y̠3Kd?ОY?ip6`|Kt|&l2˃- `0 3 `0K~*Lfj# 㗂쮌#Klpq_/^ دَga_.l `0m350Ag0}l1}#S3   7ل9`0}m :22a!ww  3`0}Ah :`01Xx+`$\0dWKX`0 ƾ ~ٰ;`0̠3 ``0 3 `0Ag0 t`0{;t`sDxtP?ľGk21`0 &-uoc!w`0Ag0 c?B#$8onC?=½Ekw~(n/~|` s#y>m$t0hn~\Q ;"N?dwzm7׌FvG`Q,<5Z빖 ɟB6tt lpuDrLevo|@D|'x]xV<LiOUOgL`:D JRy>0 ?`/8;YJu8A<[9;{-Ʀ z~f΋{Kyߍȫv8upVǴw 0i(>bM{=ϸiػW)S\Lq~3E&'5P@ Clk*&ꙶ]Wӟ_Nϗ&jcNł%ސ[y:}&5Jͻ)nYۮfFÖ: cApHxw9XzX&$*Jq1ow6`vq\`k~l#NFԺ;+ `t6uH` Tc {4)NPjq(I*YK!ݖq\MP-Iժ:Xld0BjUuІ`ZFO!Z;U|~'257#,vB(e%tTj\I*-l9(X5!| D1Ӄä!HI*}| ^5Oa4=9NTz(v&8Z{,ǟr>+I*]F\qr(3rw9WMX I=A8~%:C=jBjQ,VMeL{J:9W\% Ǟ&Ie늿;SJ#g^`5@nK'!M5 K>LQU?{'EyLz"HUi "V,ع] IDATأF[$XѠ7TTPTGqwwfgg1{rJ /ݙgyfv|9\,ap?f4W)a8Je8La/ߢ C1:+e :dR ]aE"ˁrǨ;a*iu&/0\`0bxPY:B Ñ*ó% bQa^/e;,Tn+whZ~Ƅq9sO4zڮʲ=lYMM[JJ\ ys>_Ѷ׽_s}V^ݟ(Lߝs X{u&-iZLj>ݰ>_s̵qν~ev.a\rwOWIxӲV2tWh 2/2&G>_}0cl|EEZ8l'ƪL 2 {? }Kcsuc=!JXN4ereoQ|ߛƲ\(^Jfݔ˭˭; WpxOtтYS3l_V>z|L~"rE1*B߿m۸ Q8g[.xM:eY4:x m7z*5}( ~dr}`YS .40kY SSҟU[S -de'NUl{޳&{[!c suE&u{S,6 w\S^bw^jXTmHb pSܘ8dс$Df897kddl!ER?{ nf\h=Cu9Oyu_( x%n!/Rjj=Tv疕5EZsN!m3'&߶[߶mܧUɌ7rEB7ec뗗̻E:rEi^&3]:!&딖9!8qQj:˭y.Ș uSC-BHCi˭&ϮRsÆqmکNR~܁mo o`3^/)\7f^_E.mQzi:u垗)|W%{%fSնnᲊmY+w:5b;Зu`KlӦ퍯mij_X_lvޡn̜/oe˭LpaY_8cx@{8Hq9űH{M/r%w. fkjŁXo(*#UҧhGpa`)ֿJKO?OJEzwN\7ݓJeev8. b֙梿CHkƤ Kϣrk$L-5˦YW6_eK 1VN[vkjk_BQۙ̂#uۭ;=sd^mozYwڶqi.`ӳgdbA@`drnqFYaޏ-GӺMGL3Y M<4Ŷ7.<(ϴoKg֤36~[]75,B(6rL~2B&3PhTCîܑ'w#ZWFV׻躩wsoeůAs]7Yԓ Ie}l{4~yYn9u*TMsG7}M嫫ILBNyע @ =Ñ5 1|Jq B > d # =jXn7\%w st`Rё~y%Rb>Α.asmtmx{z?zt{G][ 1{{dbYi]J@$2T 1\<>rKK˭w{=]ԹO~PhRvtt#tTCʶ* 0~J}zCZsUG̫7f(YFӁgkx|4qd^AIɘ=\7 ٶ7|8x^e,>%0YL~2вs~H|v,tzNm(dr^ݞ34oEi56\ p#RmT*ۘhfF !}#SB! !BB! !BBN!& f*)PvZ9.qQ$Ѿ$BȾ˩v". RʝBB)B!װ¿S@'B+GǏQ@' ZxiQpN!4#5:!o)B!}tB!">@:!|g2Oh[Bه=3?"w54tB!E9r'B(B!:!B(B!:!ϠQo8@a BvĨvitB!{ej_t BN! BN! BtB!P@'BtB!P@'B(B!:!B(B!:!BB! !BB!;è !Ai7ʾw3mQF֍s`jEo.k5!d?J>SlO)ߙC;!BB!{z{4F_l|]Z?Za ]L@sozS0&܋=P vХQ"b>Ï`65 j.,I9 w_^2o|(C {_vrGx&:I.0Ωpi7>yiV}MREʹm^pLs-cǢwl/{իca ]]m8$@?c_a TY.PrvGgcU`cR Yߖ4t`$Eiy>m S5odZqxr j01yP 0!νM?x"QCU\.?>FI*Ƿ~ Ic:)9/_\\|d@pJbWsZ`pTlYZQlMiV]ܸyT|~ཬ_'#yӳ攔!x6lbS-@F$@f( (- Uyi +XS4AD A9 oOM囮gd $5.l;,"ervL -"'{W}/FSk8R60&W V(m^DFoj@". >n~/ T}cRX$*fg7Q6sROֳ~?@Ї틌iU`T?FOlӰ>eCAЪMauEEKwc4z81q cMB(|ɘT%*]@UۋQT1&V)JPۊ״.ݻVb*N4zbɏ LsR$j{@I)s$*]?(^ B*ATAϩjcW EC}*AЫt$Ei۲aZ[U1&VIR*Y. IZ>mo >%OS׸nrI(4Q|kU 1~ CiHg}lNtڈ=?wǩ9E+gԌ3O8շ FU;^o:rEi5'į[`,ẑ,FntzζF囩[F"Ș-uW2ͥ1 w緞(dޚ|5%-cRʶ7ݰ0^ _f__i]S3,B7;]x95%zǩc@9Դ.ϻntzNǩ58kTb)|d'/ R3蟡А ?h+~Td[Ƥֱm,oLsMQǩiCgؼ'<ϮUƅz[QZϹL&UZiV c{l{Cus7o~|F|_w |z܆ XӰܿpfU,k{E'-s]7p~[T1a}u8sM KJNUQqƘ^SSh>xŅ޲VtQ.N$\]frn Ĺ=x\7uS[ٶ@`5 9~94<f( zGwrѪ?qZp״M~@"Of'3f9?)$Gëe #GEeD)] st9sP ߛޞ1Iݽu3obd!u3z'jk_32%0&2&ҦĊ+AK:PX)LףFHdL7ӶJ/~lCjU\aSǩ[NOJӺ~gZHR:ݲVA!۶=v(tdEi}i.˭=/tzʝbGlh8my ,kY@\zsw{JR cr@cf!m-BT8|+͹v8|)@A|홦mo|ZqwF.FuKarRc2+96䧪:yX=oY' U*Q5=f)Gi wr(bErfu#Ā߅oEqּz$9iS+/aUC6R/LM$:Y֪,iiH];ڵ!T:s눶mѰ܋}NS(rG59v l{ԌsT4ǩҴ.)Ml:=XVᠿUB:߽0]xM(4A3EӬPS3&yR-HRE 6Q[<@7G+J;GtY |m}٪tAЖjǁ`LNdۛRӮI1?2"˘-KT?Re{o<>?} 8=ZZלrE@OͰQⷄڈ~/t8L^<4.#o ֮$OacU 9- ]q?Rf(]Q]! Oѻ̀i=ŒgObYnB:=M@[EAQ bUJޫ}y^Q?:@6[,WS1ernM(d%+A0zos٪韅1UI詂`ܓ.zF"`pJF*Ĺtzn}rqjjq^LvlC@w8[}nA?w̝-GC6-k9]97WYn\+gBC7JRI.[3V%g~ߚ}i.AU;M,kDEi#rv Ppa](F&Ɣ;T;⟈cRKEi˛.3T1Q ?"IϥӳѴ΋t?e9pY,c]+LeO|c]/gJο] )9GT2b^-^/eܜP@߫,e1pi 0=\i+=ZgD Q[J7{^iAЮ0>m{{UcLs%F(Jۇ,ku1q(c23Ŷ7= e V=NNfܖDx86?,ߪFua;10,kQIQDҋDF=RRrTjڡS Uma֭O =䫑1_&K\7\8|ԜeNSaybnf o7W3uIl2ωb3ć.eegfεp]u\4:ja.k~V#Q'zɩ%a+Rmr5ZzV?Tצ3ZsJKO|uVpD?4~n;̍9 >o|'=erᑷlF(#z&gSBC?@(!,9XlNAJ 7ѻs|EAtBH4"@M@!P@'BtB!P@'BGُX@6D>fN! !RbtBBvg!`NU ! BN! BN!P@'BtB!At!dѯ]|"{]T1k_pL]BȾn j B!yt BMkҼf  !y Tx5tB!S(?Bi¿~ SB!;s5R| P3:! 4 w5 tB!Kԓ ! RG `!5 !<]aF)wB!:!B(B!:!B(B! m{]nGo5Gܒ]`)k}$T9?srҒ4|U+_,,kRhB Ô_-(S+'3 TFC{Zs% 7(lzYٙmb.m1iudÌI/ԯ&1|~CeYcKKO{7[[R캙{}3rE"#M$&}͹w(;Nll<UV,:#I97ǧ鞗 xpxey1S=6=UPtz8I*(L&?vڛeegJ vw\7SydO. +eMj)wk<SsǨ;~>R㘜 `\ `aL A_v ZppXថ" Q˥OHLLjZctWya[:, KM; Tj] jZrZs,-A{cYk)9=9DEiX.jP4:}YʠY/ ڲ\ N[~N:u76@v$ e87`Llo+v喟sb¼ÿ|-;β# \.zi.S?疦mf TՎy\+bZ[˃A=AݘJ8yA3eYnyA*5Ph(]u.퐒Z@&3z͖\޹«rϳ)=.̻Q ~PLfѹ8Ƥ}bwKU;LdL]n5S[U?Q .7^2> Ie2TcD18:"=n,`Y+NL$&oĘ hZ|5cdB0c2k\x4ε2CThaK`t 8~! / Z:uq[M ņ2D'8~UpEAͶ %[{yV7$9Ӳeۛ.d\Zzʆwf b|i=I]E.tǩc~ ?12ӓ-Wj1ƾt?mɘ-p緙N1]Qq̿P׻L~JͅKR:uu][nyz7x^~v֑)lwu >Ͷ7|aF'|r&cЍ~ݍ\;Ynm TW?4![sv6u~ںwzWkO@Ӻ7͝osҴ\.Դ.G?zi.+|)I۪i8u87 s\2l8NE'wXlh,+O$[]Orys\n,MiԬZpаy:_8Ѝröw '8S/eW=S,c Ǫ SH@ue`^YM\,z e h;qwt?hZmob֢&EiUԓxFeew$E )2F ;kk߼`sA =!HRiN/#8nO[|TjQ .Epvڭ3g[nr*vhts5;f&͘Z Z,(m=I*ZVvJK8U#U7A32{$xsÇa]pgerO#IWUT\R^cB#~5`vj)wjS9[>5eb;. xi.6T"Af2ݫ0ed-rMY,#ib)OЀvpgc6 ,-Vw ׭{fy,P]; //;0&~pڣw``LԢ?廍*rLs]z梱\ƔFf~,I%3LsʋWT\oZNf_\T A8I>$>E&3^CQ[n oEX֪ՊLf^pߔۅs߂K+ZrɩȩԌeb$6 rLfnp+/y%AП +$|~%!T:JJU[9A?B{spSh-D0V" 2 QmD?!F@P谛 T>Mٔu}20R:oI#SOeo״.s=/=ZUg_V_|.~$ULN{Oپ/u% [W7~z]ݛ T8L2Mੂo>xJځtOaxh28Ne-֢WBgbpm"ѣnw,pR0|,`l_F!=W{$S_R3;Nb} 4\0Y߽+Z]eRv./Ϳߧ?~RJ 凣hmޭ_Ϟ y, +|ŝ FӖ8[}V[KǶTx>oٿ۲붽O? o]w,ɌdziO2`j<շ°begJeA>ex[9+WJkr$ݤ,愤U$:ccG3T3Er{'r .e0mI?/H9ǑSzPi )6:$II ]|Ia:txo:`:  >5Tಗ&v& dR-ԏ/ @ m>ZBNq]:: tt@ ~b&ǺHi9ITb}lݡVIENDB`OpenMesh-11.0.0/Doc/images/halfedge_structure.gif0000660000174600017460000000575114556675336023777 0ustar gitlab-runnergitlab-runnerGIF87aW,Wڋ޼kzH扦 L׳JLᆯ.L*5ⰕDԪ:y&c a.}S+s=W'WhxE%8Yg(ih yjiJ++U Vk;(Ak,kZ|,\( mM|B}ǭ M.+b[]Nz^/3o/wV < s:lNZL4/rczgPʓ"H3c\ S:Q܉ȥ@'(Ƙ*TlS9O }HjS)6ԺիM`iǵ,OӪUٷE]Iظi\(᥍}Yrel clrfcOKcخ;v# Swʽ5WBp{9V{.}UuB쳋 _\e36f=AGb?/y'i܀DW]p *h.p UZeуg{ hb^݉]Z,n"T҃a<&8^CϏ$y*pV4甓-g^w~eʡUzd\{ Tkz쥉{ӿgѷ_-|Co`_8)Gĝ~}'rtܗ%rp?ߞO?;Qk), /o\H*b%ܠ& v0 ad*l [x2P&/dh*/H!uQBt!#"mJ\RjoA1d" +>ZTȤ/1f\cIhF2d1XD#7n$rT85⑌;#Hǭ2;c y׳ 2R XF̐xdpErd& IO%%JSNܣ$:HIDUN[%U2jiLN2 1/KhU)KY'&!!KjPfMr6тN}-̛QD$nYY!9;}ڑ=Pu f@Ьjh$ˆ. 6(ѬLT) *6Sm'^at-RMH.X4|(=<婴etW|;Lm<2[{+R M+!1։_ԑ+~Թ5xD6r<weI/p dB8XcF\IVfy:#Se*Th4u:FNO1ԣJE ۩V)a.{gFwnu-@oҖ@R;aogU`K㴶?TxAͪZ NѦn$E?ֳYvJ74- *vfvG]19iFx:Ji_wo98]k;A%TJF6 |_~YǴVy;Mׅ(z]`t%~ɠu]>qJ͠P3U&a3]_GԿivOeƪշI?^aw]n./u~~z{=|gw~ƆQUFr|m-[96-g_ NBCi~x3[k>;-"'=)_0RYɫ{f"`Z7>ܛ]~7(SU_;:x{yf7?f&{zF#^!# y| B=|"}#/B}RHC&.8$‚KCx"A+?7a,G8g} 6X>1>HE(W>"yуGaA2!E~WeH6,a&,qQcӇؐ20Qx#؈x`#(4Ӷ?ӈXsR2vj׊X(W1M?4j4fՋaV:r%wӉp6Qo]4 wҘfuV[эƂюi\Mb~]iEj[!hbPymHEeY`v$lU&y y *")@$i5P;OpenMesh-11.0.0/Doc/tutorial_05.docu0000660000174600017460000001423214556675336021201 0ustar gitlab-runnergitlab-runner/** \page tutorial_05 Using standard properties This example shows: - How to add and remove a standard property, - How to get and set the value of a standard property. As we already have seen, we can bind additional data to the mesh entities by means of properties. %OpenMesh provides a set of so-called standard properties. Unlike the custom properties these have some special features and a different interface, which are the matter in this tutorial. The following table lists all available standard properties and the suitable entity for which it can be used.
  Vertex Face Edge Halfedge
Color X X X  
Normal X X   X
Position (*) X      
Status X X X X
TexCoord X     X
To add a standard property to an entity simply use the appropriate request method, e.g. \c request_face_normals(). The only exception is the position (*). It cannot be added because it is permanently available, hence it cannot be removed as well. In this example we -# add vertex normals to a mesh object -# load a file -# check if the file provides vertex normals and calculate them if not -# move every vertex one unit length along its normal direction -# print the resulting positions to std::cout Let's start with adding vertex normals to the mesh: \dontinclude 05-std_properties/properties.cc \skipline request_vertex_normals In a similar manner we can request the other standard properties. For example the face normals: \skipline request_face_normals We need them to calculate the vertex normals with \c update_normals(), if the file didn't provide any. But we can do more with standard properties. We can verify if the mesh has already the property vertex normals \dontinclude 05-std_properties/properties.cc \skipline has_vertex_normals \until } And after usage we remove them again \skipline release_vertex_normals But, what happens if for example the vertex status property has been requested twice? Then the first release does nothing, but the second one will remove it. The standard properties have a reference counter, which is incremented by one for each request and decremented by one for each release. If the counter reaches 0 the property will be removed from memory. As we have seen in the table above, we have 9 dynamically requestable properties. The request functions as defined in OpenMesh::Concepts::KernelT are:
  • request_edge_status()
  • request_edge_colors()
  • request_face_colors()
  • request_face_normals()
  • request_face_status()
  • request_face_texture_index()
  • request_halfedge_status()
  • request_halfedge_normals()
  • request_halfedge_texcoords1D()
  • request_halfedge_texcoords2D()
  • request_halfedge_texcoords3D()
  • request_vertex_colors()
  • request_vertex_normals()
  • request_vertex_status()
  • request_vertex_texcoords1D()
  • request_vertex_texcoords2D()
  • request_vertex_texcoords3D()
Added properties can be released by the following functions:
  • release_edge_status()
  • release_edge_colors()
  • release_face_colors()
  • release_face_normals()
  • release_face_status()
  • release_face_texture_index()
  • release_halfedge_status()
  • release_halfedge_normals()
  • release_halfedge_texcoords1D()
  • release_halfedge_texcoords2D()
  • release_halfedge_texcoords3D()
  • release_vertex_colors()
  • release_vertex_normals()
  • release_vertex_status()
  • release_vertex_texcoords1D()
  • release_vertex_texcoords2D()
  • release_vertex_texcoords3D()
A property's existance can be tested with
  • has_edge_status()
  • has_edge_colors()
  • has_face_colors()
  • has_face_normals()
  • has_face_status()
  • has_face_texture_index()
  • has_halfedge_status()
  • has_halfedge_normals()
  • has_halfedge_texcoords1D()
  • has_halfedge_texcoords2D()
  • has_halfedge_texcoords3D()
  • has_vertex_colors()
  • has_vertex_normals()
  • has_vertex_status()
  • has_vertex_texcoords1D()
  • has_vertex_texcoords2D()
  • has_vertex_texcoords3D()
which return true if a property has been requested before and is available. The status property is used for marking geometry elements i.e. as selected or deleted. See \ref tutorial_07b for further information. Now we know how to add and remove standard properties, but how do we access them? Again we need the mesh object. Unlike the custom properties, where we accessed one with the mesh member function \c property(), for each standard property the mesh provides a get and a set method. We have used one pair of get/set methods already in the previous three tutorials, where we computed a new location for the vertex position. Here we move all vertices a unit length along their normal direction: \dontinclude 05-std_properties/properties.cc \skipline MyMesh::VertexIter \until { \skipline mesh.set_point \skipline } The get-methods take an entity handle and return the value of the desired property, and the set-methods require an additional parameter to pass the new value to the property. According to the table not every pair of get/set-methods apply to every entity. For example a face has normally no texture coordinates, hence a call to \c mesh.texcoord2D( _face_handle ) will result in an error when compiling the code. Since we know how to add/remove/access standard properties, one further question remains. What data types do they have? And are there more hidden secrets? The next tutorial (\ref tutorial_06) will give the answer. The complete source looks like this: \include 05-std_properties/properties.cc */ OpenMesh-11.0.0/Doc/operations.docu0000660000174600017460000001054114556675336021214 0ustar gitlab-runnergitlab-runner/** \page mesh_operations Some basic operations: Flipping and collapsing edges In this section you will learn about some basic operations on a mesh that %OpenMesh already provides. Comprising the flipping of edges in a triangle mesh as well as collapsing edges by joining the two adjacent vertices. \li \ref op_flip \li \ref op_collapse \section op_flip Flipping edges in triangle meshes Considering two adjacent faces of a triangle mesh, there exist exactly two different configurations of the inner edge. Calling the function OpenMesh::TriConnectivity::flip(EdgeHandle _eh) will flip the specified edge to its opposite orientation as shown in the illustration below. \image html mesh.flip.png "Flipping edges in a triangle mesh" So, the following snippet of code shows how to use this in your applications: \code TriMesh mesh; // Add some vertices TriMesh::VertexHandle vhandle[4]; vhandle[0] = mesh.add_vertex(MyMesh::Point(0, 0, 0)); vhandle[1] = mesh.add_vertex(MyMesh::Point(0, 1, 0)); vhandle[2] = mesh.add_vertex(MyMesh::Point(1, 1, 0)); vhandle[3] = mesh.add_vertex(MyMesh::Point(1, 0, 0)); // Add two faces std::vector face_vhandles; face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[0]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[3]); mesh.add_face(face_vhandles); // Now the edge adjacent to the two faces connects // vertex vhandle[0] and vhandle[2]. // Find this edge and then flip it for(TriMesh::EdgeIter it = mesh.edges_begin(); it != mesh.edges_end(); ++it) { if(!mesh.is_boundary(*it)) { // Flip edge mesh.flip(*it); } } // The edge now connects vertex vhandle[1] and vhandle[3]. \endcode \section op_collapse Collapsing edges In this section you will learn how to collapse edges such that the two adjacent vertices join. %OpenMesh provides the function OpenMesh::PolyConnectivity::collapse(HalfedgeHandle _heh) to perform this operation. This will collapse the from-vertex (remeber that halfedges are directed) to the to-vertex of the halfedge as illustrated below. Note that collapsing edges might cause topological inconsistencies to your mesh. You should verify consistency after collapsing edges by calling OpenMesh::PolyConnectivity::is_collapse_ok(). \note You have to request status attributes in order to use the collapse and delete functions! \image html mesh.collapse.png "Collapsing will always be performed in the direction the halfedge points to." A simple code example related to the illustration might look like this: \code PolyMesh mesh; // Request required status flags mesh.request_vertex_status(); mesh.request_edge_status(); mesh.request_face_status(); // Add some vertices as in the illustration above PolyMesh::VertexHandle vhandle[7]; vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, 1, 0)); vhandle[1] = mesh.add_vertex(MyMesh::Point(-1, 3, 0)); vhandle[2] = mesh.add_vertex(MyMesh::Point(0, 0, 0)); vhandle[3] = mesh.add_vertex(MyMesh::Point(0, 2, 0)); vhandle[4] = mesh.add_vertex(MyMesh::Point(0, 4, 0)); vhandle[5] = mesh.add_vertex(MyMesh::Point(1, 1, 0)); vhandle[6] = mesh.add_vertex(MyMesh::Point(1, 3, 0)); // Add three quad faces std::vector face_vhandles; face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[3]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[5]); face_vhandles.push_back(vhandle[4]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[6]); face_vhandles.push_back(vhandle[5]); mesh.add_face(face_vhandles); // Now find the edge between vertex vhandle[2] // and vhandle[3] for(PolyMesh::HalfedgeIter it = mesh.halfedges_begin(); it != mesh.halfedges_end(); ++it) { if( mesh.to_vertex_handle(*it) == vhandle[3] && mesh.from_vertex_handle(*it) == vhandle[2]) { // Collapse edge mesh.collapse(*it); break; } } // Our mesh now looks like in the illustration above after the collapsing. \endcode */ OpenMesh-11.0.0/Doc/CMakeLists.txt0000660000174600017460000000053414556675336020716 0ustar gitlab-runnergitlab-runnerinclude (VCIDoxygen) IF (DOXYGEN_FOUND) # Add a documentation install target vci_create_doc_target(doc-install) if (TARGET doc-install) vci_copy_after_build (doc-install "${CMAKE_BINARY_DIR}/Build/${VCI_PROJECT_DATADIR}/Doc/html" "${CMAKE_INSTALL_PREFIX}/${VCI_PROJECT_DATADIR}/doc/html") endif() ENDIF(DOXYGEN_FOUND) OpenMesh-11.0.0/Doc/Tutorial/0000770000174600017460000000000014556675336017756 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/05-std_properties/0000770000174600017460000000000014556675336023246 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/05-std_properties/properties.cc0000660000174600017460000000347014556675336025756 0ustar gitlab-runnergitlab-runner#include // -------------------- #include #include typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; int main(int argc, char **argv) { MyMesh mesh; if (argc!=2) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; } // request vertex normals, so the mesh reader can use normal information // if available mesh.request_vertex_normals(); // assure we have vertex normals if (!mesh.has_vertex_normals()) { std::cerr << "ERROR: Standard vertex property 'Normals' not available!\n"; return 1; } OpenMesh::IO::Options opt; if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt)) { std::cerr << "Error loading mesh from file " << argv[1] << std::endl; return 1; } // If the file did not provide vertex normals, then calculate them if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) ) { // we need face normals to update the vertex normals mesh.request_face_normals(); // let the mesh update the normals mesh.update_normals(); // dispose the face normals, as we don't need them anymore mesh.release_face_normals(); } // move all vertices one unit length along it's normal direction for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { std::cout << "Vertex #" << *v_it << ": " << mesh.point( *v_it ); mesh.set_point( *v_it, mesh.point(*v_it)+mesh.normal(*v_it) ); std::cout << " moved to " << mesh.point( *v_it ) << std::endl; } // don't need the normals anymore? Remove them! mesh.release_vertex_normals(); // just check if it really works if (mesh.has_vertex_normals()) { std::cerr << "Ouch! ERROR! Shouldn't have any vertex normals anymore!\n"; return 1; } return 0; } OpenMesh-11.0.0/Doc/Tutorial/CMakeLists.txt-internal0000660000174600017460000000054614556675336024336 0ustar gitlab-runnergitlab-runnerinclude (VCICommon) include_directories ( ../../.. ${CMAKE_CURRENT_SOURCE_DIR} ) set (targetName MyOwnProject) # collect all header and source files vci_append_files (headers "*.hh" .) vci_append_files (sources "*.cc" .) vci_add_executable (${targetName} ${headers} ${sources}) target_link_libraries (${targetName} OpenMeshCore OpenMeshTools ) OpenMesh-11.0.0/Doc/Tutorial/11-smart_handles/0000770000174600017460000000000014556675336023021 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/11-smart_handles/smooth.cc0000660000174600017460000000370314556675336024645 0ustar gitlab-runnergitlab-runner #include #include #include #include #include using MyMesh = OpenMesh::TriMesh; int main(int argc, char** argv) { // Read command line options MyMesh mesh; if (argc != 4) { std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl; return 1; } const int iterations = argv[1]; const std::string infile = argv[2]; const std::string outfile = argv[3]; // Read mesh file if (!OpenMesh::IO::read_mesh(mesh, infile)) { std::cerr << "Error: Cannot read mesh from " << infile << std::endl; return 1; } { // Add a vertex property storing the laplace vector auto laplace = OpenMesh::VProp(mesh); // Add a vertex property storing the laplace of the laplace auto bi_laplace = OpenMesh::VProp(mesh); // Get a propertymanager of the points property of the mesh to use as functor auto points = OpenMesh::getPointsProperty(mesh); // Smooth the mesh several times for (int i = 0; i < iterations; ++i) { // Iterate over all vertices to compute laplace vector for (const auto& vh : mesh.vertices()) laplace(vh) = vh.vertices().avg(points) - points(vh); // Iterate over all vertices to compute the laplace vector of the laplace vectors for (const auto& vh : mesh.vertices()) bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh)); // update points by substracting the bi-laplacian damped by a factor of 0.5 for (const auto& vh : mesh.vertices()) points(vh) += -0.5 * bi_laplace(vh); } } // The laplace and update properties are removed from the mesh at the end of this scope. // Write mesh file if (!OpenMesh::IO::read_mesh(mesh, outfile)) { std::cerr << "Error: Cannot write mesh to " << outfile << std::endl; return 1; } } OpenMesh-11.0.0/Doc/Tutorial/04-stl_algorithms/0000770000174600017460000000000014556675336023232 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/04-stl_algorithms/smooth.cc0000660000174600017460000000235014556675336025053 0ustar gitlab-runnergitlab-runner#include #include // -------------------- OpenMesh #include #include // -------------------- #include "smooth_algo.hh" // ---------------------------------------------------------------------------- #ifndef DOXY_IGNORE_THIS struct MyTraits : public OpenMesh::DefaultTraits { HalfedgeAttributes(OpenMesh::Attributes::PrevHalfedge); }; #endif typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; // ---------------------------------------------------------------------------- int main(int argc, char **argv) { MyMesh mesh; // check command line options if (argc != 4) { std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n"; return 1; } // read mesh from stdin if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) ) { std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl; return 1; } // smoothing mesh argv[1] times SmootherT smoother(mesh); smoother.smooth(atoi(argv[1])); // write mesh to stdout if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) ) { std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl; return 1; } return 0; } OpenMesh-11.0.0/Doc/Tutorial/04-stl_algorithms/smooth_algo.hh0000660000174600017460000000355014556675336026072 0ustar gitlab-runnergitlab-runner#include #include #ifndef DOXY_IGNORE_THIS template class SmootherT { public: typedef typename Mesh::Point cog_t; typedef OpenMesh::VPropHandleT< cog_t > Property_cog; public: // construct with a given mesh explicit SmootherT(Mesh& _mesh) : mesh_(_mesh) { mesh_.add_property( cog_ ); } ~SmootherT() { mesh_.remove_property( cog_ ); } // smooth mesh _iterations times void smooth(unsigned int _iterations) { for (unsigned int i=0; i < _iterations; ++i) { std::for_each(mesh_.vertices_begin(), mesh_.vertices_end(), ComputeCOG(mesh_, cog_)); std::for_each(mesh_.vertices_begin(), mesh_.vertices_end(), SetCOG(mesh_, cog_)); } } private: //--- private classes --- class ComputeCOG { public: ComputeCOG(Mesh& _mesh, Property_cog& _cog) : mesh_(_mesh), cog_(_cog) {} void operator()(const typename Mesh::VertexHandle& _vh) { typename Mesh::VertexVertexIter vv_it; typename Mesh::Scalar valence(0.0); mesh_.property(cog_, _vh) = typename Mesh::Point(0.0, 0.0, 0.0); for (vv_it=mesh_.vv_iter(_vh); vv_it.is_valid(); ++vv_it) { mesh_.property(cog_, _vh) += mesh_.point( *vv_it ); ++valence; } mesh_.property(cog_, _vh ) /= valence; } private: Mesh& mesh_; Property_cog& cog_; }; class SetCOG { public: SetCOG(Mesh& _mesh, Property_cog& _cog) : mesh_(_mesh), cog_(_cog) {} void operator()(const typename Mesh::VertexHandle& _vh) { if (!mesh_.is_boundary(_vh)) mesh_.set_point( _vh, mesh_.property(cog_, _vh) ); } private: Mesh& mesh_; Property_cog& cog_; }; //--- private elements --- Mesh& mesh_; Property_cog cog_; }; #endif OpenMesh-11.0.0/Doc/Tutorial/07b-delete_geometry/0000770000174600017460000000000014556675336023521 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/07b-delete_geometry/delete_geometry.cc0000660000174600017460000001627414556675336027220 0ustar gitlab-runnergitlab-runner/* ========================================================================= * * * * OpenMesh * * Copyright (c) 2001-2015, RWTH-Aachen University * * Department of Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * *---------------------------------------------------------------------------* * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * * * 1. Redistributions of source code must retain the above copyright notice, * * this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. Neither the name of the copyright holder nor the names of its * * contributors may be used to endorse or promote products derived from * * this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= */ #include // -------------------- OpenMesh #include #include #include #include // ---------------------------------------------------------------------------- struct MyTraits : public OpenMesh::DefaultTraits { }; typedef OpenMesh::PolyMesh_ArrayKernelT MyMesh; // ---------------------------------------------------------------------------- // Build a simple cube and delete it except one face int main() { MyMesh mesh; // the request has to be called before a vertex/face/edge can be deleted. it grants access to the status attribute mesh.request_face_status(); mesh.request_edge_status(); mesh.request_vertex_status(); // generate vertices MyMesh::VertexHandle vhandle[8]; MyMesh::FaceHandle fhandle[6]; vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1)); vhandle[1] = mesh.add_vertex(MyMesh::Point( 1, -1, 1)); vhandle[2] = mesh.add_vertex(MyMesh::Point( 1, 1, 1)); vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1)); vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1)); vhandle[5] = mesh.add_vertex(MyMesh::Point( 1, -1, -1)); vhandle[6] = mesh.add_vertex(MyMesh::Point( 1, 1, -1)); vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1)); // generate (quadrilateral) faces std::vector tmp_face_vhandles; tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[0]); tmp_face_vhandles.push_back(vhandle[1]); tmp_face_vhandles.push_back(vhandle[2]); tmp_face_vhandles.push_back(vhandle[3]); fhandle[0] = mesh.add_face(tmp_face_vhandles); tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[7]); tmp_face_vhandles.push_back(vhandle[6]); tmp_face_vhandles.push_back(vhandle[5]); tmp_face_vhandles.push_back(vhandle[4]); fhandle[1] = mesh.add_face(tmp_face_vhandles); tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[1]); tmp_face_vhandles.push_back(vhandle[0]); tmp_face_vhandles.push_back(vhandle[4]); tmp_face_vhandles.push_back(vhandle[5]); fhandle[2] = mesh.add_face(tmp_face_vhandles); tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[2]); tmp_face_vhandles.push_back(vhandle[1]); tmp_face_vhandles.push_back(vhandle[5]); tmp_face_vhandles.push_back(vhandle[6]); fhandle[3] = mesh.add_face(tmp_face_vhandles); tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[3]); tmp_face_vhandles.push_back(vhandle[2]); tmp_face_vhandles.push_back(vhandle[6]); tmp_face_vhandles.push_back(vhandle[7]); fhandle[4] = mesh.add_face(tmp_face_vhandles); tmp_face_vhandles.clear(); tmp_face_vhandles.push_back(vhandle[0]); tmp_face_vhandles.push_back(vhandle[3]); tmp_face_vhandles.push_back(vhandle[7]); tmp_face_vhandles.push_back(vhandle[4]); fhandle[5] = mesh.add_face(tmp_face_vhandles); // And now delete all faces and vertices // except face (vh[7], vh[6], vh[5], vh[4]) // whose handle resides in fhandle[1] // Delete face 0 mesh.delete_face(fhandle[0], false); // ... face 2 mesh.delete_face(fhandle[2], false); // ... face 3 mesh.delete_face(fhandle[3], false); // ... face 4 mesh.delete_face(fhandle[4], false); // ... face 5 mesh.delete_face(fhandle[5], false); // If isolated vertices result in a face deletion // they have to be deleted manually. If you want this // to happen automatically, change the second parameter // to true. // Now delete the isolated vertices 0, 1, 2 and 3 mesh.delete_vertex(vhandle[0], false); mesh.delete_vertex(vhandle[1], false); mesh.delete_vertex(vhandle[2], false); mesh.delete_vertex(vhandle[3], false); // Delete all elements that are marked as deleted // from memory. mesh.garbage_collection(); // write mesh to output.obj try { if ( !OpenMesh::IO::write_mesh(mesh, "output.off") ) { std::cerr << "Cannot write mesh to file 'output.off'" << std::endl; return 1; } } catch( std::exception& x ) { std::cerr << x.what() << std::endl; return 1; } return 0; } OpenMesh-11.0.0/Doc/Tutorial/02-iterators/0000770000174600017460000000000014556675336022211 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/02-iterators/smooth.cc0000660000174600017460000000333414556675336024035 0ustar gitlab-runnergitlab-runner#include #include // -------------------- OpenMesh #include #include typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh; int main(int argc, char **argv) { MyMesh mesh; // check command line options if (argc != 4) { std::cerr << "Usage: " << argv[0] << " #iterations infile outfile\n"; return 1; } // read mesh from stdin if ( ! OpenMesh::IO::read_mesh(mesh, argv[2]) ) { std::cerr << "Error: Cannot read mesh from " << argv[2] << std::endl; return 1; } // this vector stores the computed centers of gravity std::vector cogs; std::vector::iterator cog_it; cogs.reserve(mesh.n_vertices()); // smoothing mesh argv[1] times MyMesh::VertexIter v_it, v_end(mesh.vertices_end()); MyMesh::VertexVertexIter vv_it; MyMesh::Point cog; MyMesh::Scalar valence; unsigned int i, N(atoi(argv[1])); for (i=0; i < N; ++i) { cogs.clear(); for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) { cog[0] = cog[1] = cog[2] = valence = 0.0; for (vv_it=mesh.vv_iter( *v_it ); vv_it.is_valid(); ++vv_it) { cog += mesh.point( *vv_it ); ++valence; } cogs.push_back(cog / valence); } for (v_it=mesh.vertices_begin(), cog_it=cogs.begin(); v_it!=v_end; ++v_it, ++cog_it) if ( !mesh.is_boundary( *v_it ) ) mesh.set_point( *v_it, *cog_it ); } // write mesh to stdout if ( ! OpenMesh::IO::write_mesh(mesh, argv[3]) ) { std::cerr << "Error: cannot write mesh to " << argv[3] << std::endl; return 1; } return 0; } OpenMesh-11.0.0/Doc/Tutorial/01-build_cube/0000770000174600017460000000000014556675336022271 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/01-build_cube/build_cube.cc0000660000174600017460000001330114556675336024674 0ustar gitlab-runnergitlab-runner/* ========================================================================= * * * * OpenMesh * * Copyright (c) 2001-2015, RWTH-Aachen University * * Department of Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * *---------------------------------------------------------------------------* * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * * * 1. Redistributions of source code must retain the above copyright notice, * * this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. Neither the name of the copyright holder nor the names of its * * contributors may be used to endorse or promote products derived from * * this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= */ #include // -------------------- OpenMesh #include #include // ---------------------------------------------------------------------------- typedef OpenMesh::PolyMesh_ArrayKernelT<> MyMesh; // ---------------------------------------------------------------------------- // Build a simple cube and write it to std::cout int main() { MyMesh mesh; // generate vertices MyMesh::VertexHandle vhandle[8]; vhandle[0] = mesh.add_vertex(MyMesh::Point(-1, -1, 1)); vhandle[1] = mesh.add_vertex(MyMesh::Point( 1, -1, 1)); vhandle[2] = mesh.add_vertex(MyMesh::Point( 1, 1, 1)); vhandle[3] = mesh.add_vertex(MyMesh::Point(-1, 1, 1)); vhandle[4] = mesh.add_vertex(MyMesh::Point(-1, -1, -1)); vhandle[5] = mesh.add_vertex(MyMesh::Point( 1, -1, -1)); vhandle[6] = mesh.add_vertex(MyMesh::Point( 1, 1, -1)); vhandle[7] = mesh.add_vertex(MyMesh::Point(-1, 1, -1)); // generate (quadrilateral) faces std::vector face_vhandles; face_vhandles.clear(); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[3]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[7]); face_vhandles.push_back(vhandle[6]); face_vhandles.push_back(vhandle[5]); face_vhandles.push_back(vhandle[4]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[4]); face_vhandles.push_back(vhandle[5]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[5]); face_vhandles.push_back(vhandle[6]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[6]); face_vhandles.push_back(vhandle[7]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[7]); face_vhandles.push_back(vhandle[4]); mesh.add_face(face_vhandles); // write mesh to output.obj try { if ( !OpenMesh::IO::write_mesh(mesh, "output.off") ) { std::cerr << "Cannot write mesh to file 'output.off'" << std::endl; return 1; } } catch( std::exception& x ) { std::cerr << x.what() << std::endl; return 1; } return 0; } OpenMesh-11.0.0/Doc/Tutorial/07-traits/0000770000174600017460000000000014556675336021510 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/07-traits/smooth.cc0000660000174600017460000000625314556675336023337 0ustar gitlab-runnergitlab-runner#include #include // -------------------- OpenMesh #include #include #include struct MyTraits : public OpenMesh::DefaultTraits { // store barycenter of neighbors in this member VertexTraits { private: Point cog_; public: VertexT() : cog_( Point(0.0f, 0.0f, 0.0f ) ) { } const Point& cog() const { return cog_; } void set_cog(const Point& _p) { cog_ = _p; } }; }; typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; typedef OpenMesh::TriMesh_ArrayKernelT<> MyMesh2; // --------------------------------------------------------------------------- #define SIZEOF( entity,b ) \ std::cout << _prefix << "size of " << #entity << ": " \ << sizeof( entity ) << std::endl; \ b += sizeof( entity ) template void print_size(const std::string& _prefix = "") { size_t total=0; SIZEOF(typename Mesh::Vertex, total); SIZEOF(typename Mesh::Halfedge, total); SIZEOF(typename Mesh::Edge, total); SIZEOF(typename Mesh::Face, total); std::cout << _prefix << "total: " << total << std::endl; } #undef SIZEOF // --------------------------------------------------------------------------- int main(int argc, char **argv) { MyMesh mesh; // check command line options if (argc < 4 || argc > 5) { std::cerr << "Usage: " << argv[0] << " [-s] #iterations infile outfile\n"; exit(1); } int idx=2; // display size of entities of the enhanced and the default mesh type // when commandline option '-s' has been used. if (argc == 5) { if (std::string("-s")==argv[idx-1]) { std::cout << "Enhanced mesh size statistics\n"; print_size(" "); std::cout << "Default mesh size statistics\n"; print_size(" "); } // else ignore! ++idx; } // read mesh from stdin std::cout<< " Input mesh: " << argv[idx] << std::endl; if ( ! OpenMesh::IO::read_mesh(mesh, argv[idx]) ) { std::cerr << "Error: Cannot read mesh from " << argv[idx] << std::endl; return 0; } // smoothing mesh argv[1] times MyMesh::VertexIter v_it, v_end(mesh.vertices_end()); MyMesh::VertexVertexIter vv_it; MyMesh::Point cog; MyMesh::Scalar valence; unsigned int i, N(atoi(argv[idx-1])); std::cout<< "Smooth mesh " << N << " times\n"; for (i=0; i < N; ++i) { for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) { cog[0] = cog[1] = cog[2] = valence = 0.0; for (vv_it=mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) { cog += mesh.point( *vv_it ); ++valence; } mesh.data(*v_it).set_cog(cog / valence); } for (v_it=mesh.vertices_begin(); v_it!=v_end; ++v_it) if (!mesh.is_boundary(*v_it)) mesh.set_point( *v_it, mesh.data(*v_it).cog()); } // write mesh to stdout std::cout<< "Output mesh: " << argv[idx+1] << std::endl; if ( ! OpenMesh::IO::write_mesh(mesh, argv[idx+1]) ) { std::cerr << "Error: cannot write mesh to " << argv[idx+1] << std::endl; return 0; } return 1; } OpenMesh-11.0.0/Doc/Tutorial/12-predicates/0000770000174600017460000000000014556675336022321 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/12-predicates/predicates.cc0000660000174600017460000000403614556675336024757 0ustar gitlab-runnergitlab-runner #include #include #include #include #include #include using MyMesh = OpenMesh::TriMesh; bool is_divisible_by_3(OpenMesh::FaceHandle vh) { return vh.idx() % 3 == 0; } int main(int argc, char** argv) { using namespace OpenMesh::Predicates; // for easier access to predicates // Read command line options MyMesh mesh; if (argc != 4) { std::cerr << "Usage: " << argv[0] << " infile" << std::endl; return 1; } const std::string infile = argv[1]; // Read mesh file if (!OpenMesh::IO::read_mesh(mesh, infile)) { std::cerr << "Error: Cannot read mesh from " << infile << std::endl; return 1; } // Count boundary vertices std::cout << "Mesh contains " << mesh.vertices().count_if(Boundary()) << " boundary vertices"; // Selected inner vertices std::cout << "These are the selected inner vertices: " << std::endl; for (auto vh : mesh.vertices().filtered(!Boundary() && Selected())) std::cout << vh.idx() << ", "; std::cout << std::endl; // Faces whose id is divisible by 3 auto vec = mesh.faces().filtered(is_divisible_by_3).to_vector(); std::cout << "There are " << vec.size() << " faces whose id is divisible by 3" << std::endl; // Faces which are tagged or whose id is not divisible by 3 auto vec2 = mesh.faces().filtered(Tagged() || !make_predicate(is_divisible_by_3)).to_vector(); std::cout << "There are " << vec2.size() << " faces which are tagged or whose id is not divisible by 3" << std::endl; // Edges that are longer than 10 or shorter than 2 OpenMesh::EProp longer_than_10(mesh); for (auto eh : mesh.edges()) longer_than_10[eh] = mesh.calc_edge_length(eh) > 10; std::cout << "There are " << mesh.edges().count_if(make_predicate(longer_than_10) || make_predicate([&](OpenMesh::EdgeHandle eh) { return mesh.calc_edge_length(eh) < 2; })) << " edges which are shorter than 2 or longer than 10" << std::endl; } OpenMesh-11.0.0/Doc/Tutorial/CMakeLists.txt-external0000660000174600017460000000036014556675336024336 0ustar gitlab-runnergitlab-runnercmake_minimum_required(VERSION 3.25) project(OpenMesh-Example) find_package(OpenMesh) set (targetName MyOwnProject) add_executable (${targetName} build_cube.cc) target_link_libraries(${targetName} PRIVATE OpenMeshCore OpenMeshTools) OpenMesh-11.0.0/Doc/Tutorial/03-properties/0000770000174600017460000000000014556675336022372 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/03-properties/smooth.cc0000660000174600017460000000344114556675336024215 0ustar gitlab-runnergitlab-runner#include #include #include #include #include using MyMesh = OpenMesh::TriMesh; int main(int argc, char** argv) { // Read command line options MyMesh mesh; if (argc != 4) { std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl; return 1; } const int iterations = argv[1]; const std::string infile = argv[2]; const std::string outfile = argv[3]; // Read mesh file if (!OpenMesh::IO::read_mesh(mesh, infile)) { std::cerr << "Error: Cannot read mesh from " << infile << std::endl; return 1; } { // Add a vertex property storing the computed centers of gravity auto cog = OpenMesh::VProp(mesh); // Smooth the mesh several times for (int i = 0; i < iterations; ++i) { // Iterate over all vertices to compute centers of gravity for (const auto& vh : mesh.vertices()) { cog[vh] = {0,0,0}; int valence = 0; // Iterate over all 1-ring vertices around vh for (const auto& vvh : mesh.vv_range(vh)) { cog[vh] += mesh.point(vvh); ++valence; } cog[vh] /= valence; } // Move all vertices to the previously computed positions for (const auto& vh : mesh.vertices()) { mesh.point(vh) = cog[vh]; } } } // The cog vertex property is removed from the mesh at the end of this scope // Write mesh file if (!OpenMesh::IO::read_mesh(mesh, outfile)) { std::cerr << "Error: Cannot write mesh to " << outfile << std::endl; return 1; } } OpenMesh-11.0.0/Doc/Tutorial/08-io_options/0000770000174600017460000000000014556675336022365 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/08-io_options/io_options.cc0000660000174600017460000002040214556675336025055 0ustar gitlab-runnergitlab-runner#include #include // -------------------- OpenMesh #include #include #include // ---------------------------------------------------------------------------- using namespace OpenMesh; // ---------------------------------------------------------------------------- typedef TriMesh_ArrayKernelT<> MyMesh; // ---------------------------------------------------------------------------- #define CHKROPT( Option ) \ std::cout << " provides " << #Option \ << (ropt.check(IO::Options:: Option)?": yes\n":": no\n") #define CHKWOPT( Option ) \ std::cout << " write " << #Option \ << (wopt.check(IO::Options:: Option)?": yes\n":": no\n") #define MESHOPT( msg, tf ) \ std::cout << " " << msg << ": " << ((tf)?"yes\n":"no\n") // ---------------------------------------------------------------------------- void parse_commandline( int _argc, char **_argv, MyMesh& _mesh, IO::Options &ropt, IO::Options &wopt ); void usage_and_exit(int xcode); // ---------------------------------------------------------------------------- int main(int argc, char **argv) { MyMesh mesh; IO::Options ropt, wopt; // -------------------- evaluate commandline parse_commandline( argc, argv, mesh, ropt, wopt ); // -------------------- read mesh if ( ! IO::read_mesh(mesh,argv[optind], ropt)) { std::cerr << "Error loading mesh from file " << argv[optind] << std::endl; return 1; } // -------------------- show options std::cout << "File " << argv[optind] << std::endl; std::cout << " is binary: " << (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n"); std::cout << " byte order: "; if (ropt.check(IO::Options::Swap)) std::cout << "swapped\n"; else if (ropt.check(IO::Options::LSB)) std::cout << "little endian\n"; else if (ropt.check(IO::Options::MSB)) std::cout << "big endian\n"; else std::cout << "don't care\n"; std::cout << " provides VertexNormal" << ( // strange layout for doxygen ropt.check(IO::Options::VertexNormal) ? ": yes\n":": no\n"); CHKROPT( VertexColor ); CHKROPT( VertexTexCoord ); CHKROPT( FaceNormal ); CHKROPT( FaceColor ); // -------------------- mesh stats std::cout << "# Vertices: " << mesh.n_vertices() << std::endl; std::cout << "# Edges : " << mesh.n_faces() << std::endl; std::cout << "# Faces : " << mesh.n_faces() << std::endl; // -------------------- show write options std::cout << "Selected write options:\n"; std::cout << " use binary: " << (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n"); std::cout << " byte order: "; if (wopt.check(IO::Options::Swap)) std::cout << "swapped\n"; else if (wopt.check(IO::Options::LSB)) std::cout << "little endian\n"; else if (wopt.check(IO::Options::MSB)) std::cout << "big endian\n"; else std::cout << "don't care\n"; std::cout << " write VertexNormal" << (wopt.check(IO::Options::VertexNormal) ? ": yes\n":": no\n"); CHKWOPT( VertexColor ); CHKWOPT( VertexTexCoord ); CHKWOPT( FaceNormal ); CHKWOPT( FaceColor ); // -------------------- show mesh capabilities std::cout << "Mesh supports\n"; MESHOPT("vertex normals", mesh.has_vertex_normals()); MESHOPT("vertex colors", mesh.has_vertex_colors()); MESHOPT("texcoords", mesh.has_vertex_texcoords2D()); MESHOPT("face normals", mesh.has_face_normals()); MESHOPT("face colors", mesh.has_face_colors()); // -------------------- write mesh std::cout << "Write mesh to " << argv[optind+1] << ".."; if ( !IO::write_mesh( mesh, argv[optind+1], wopt ) ) { std::cerr << "Error" << std::endl; std::cerr << "Possible reasons:\n"; std::cerr << "1. Chosen format cannot handle an option!\n"; std::cerr << "2. Mesh does not provide necessary information!\n"; std::cerr << "3. Or simply cannot open file for writing!\n"; return 1; } else std::cout << "Ok.\n"; return 0; } // ---------------------------------------------------------------------------- void parse_commandline( int _argc, char **_argv, MyMesh& _mesh, IO::Options &ropt, IO::Options &wopt ) { int c; while ((c=getopt(_argc, _argv, "bhsBF:LMSV:X:"))!=-1) { switch(c) { // -------------------- read options // force binary input case 'b': ropt += IO::Options::Binary; break; // force swapping the byte order, when reading a binary file case 's': ropt += IO::Options::Swap; break; // -------------------- write options // Write binary variant of format if possible case 'B': wopt += IO::Options::Binary; break; // case 'F': for(size_t i=0; optarg[i]; ++i) switch(optarg[i]) { case 'n' : wopt += IO::Options::FaceNormal; break; case 'c' : wopt += IO::Options::FaceColor; break; } break; // Use little endian when writing binary data case 'L': wopt += IO::Options::LSB; break; // Use big endian when writing binary data case 'M': wopt += IO::Options::MSB; break; // Swap byte order when writing binary data case 'S': wopt += IO::Options::Swap; break; // case 'V': { for(size_t i=0; optarg[i]; ++i) switch(optarg[i]) { case 'n' : // dont't change layout!! wopt += IO::Options::VertexNormal; break; case 't' : wopt += IO::Options::VertexTexCoord; break; case 'c' : wopt += IO::Options::VertexColor; break; } break; } // -------------------- request mesh' standard properties case 'X': { char entity='\0'; for(size_t i=0; optarg[i]; ++i) switch(optarg[i]) { case 'v': case 'f': entity = optarg[i]; break; case 'n': switch(entity) { case 'v': _mesh.request_vertex_normals(); break; case 'f': _mesh.request_face_normals(); break; } break; case 'c': switch(entity) { case 'v': _mesh.request_vertex_colors(); break; case 'f': _mesh.request_face_colors(); break; } break; case 't': switch(entity) { case 'v': _mesh.request_vertex_texcoords2D(); break; } break; } break; } // -------------------- help case 'h': usage_and_exit(0); default: usage_and_exit(1); } } if ( _argc-optind != 2) usage_and_exit(1); } // ---------------------------------------------------------------------------- void usage_and_exit(int xcode) { std::ostream &os = xcode ? std::cerr : std::cout; os << "Usage: io_options [Options] \n" << std::endl; os << " Read and write a mesh, using OpenMesh::IO::Options\n" << std::endl; os << "Options:\n" << std::endl; os << "a) read options\n" << std::endl << " -b\n" << "\tAssume input file is a binary file\n" << std::endl << " -s\n" << "\tSwap byte order when reading a binary file!\n" << std::endl; os << "b) write options\n" << std::endl << " -B\n" << "\tWrite binary data\n" << std::endl << " -S\n" << "\tSwap byte order, when writing binary data\n" << std::endl << " -M/-L\n" << "\tUse MSB/LSB byte ordering, when writing binary data\n" << std::endl << " -V{n|t|c}\n" << "\tWrite vertex normals, texcoords, and/or colors\n" << std::endl << " -F{n|c}\n" << "\tWrite face normals, and/or colors\n" << std::endl; os << "c) Mesh properties\n" << std::endl << " -Xv{n|c|t}\n" << "\tRequest vertex property normals|colors|texcoords\n" << std::endl << " -Xf{n|c}\n" << "\tRequest face property normals|colors\n" << std::endl; exit(xcode); } // end of file // ============================================================================ OpenMesh-11.0.0/Doc/Tutorial/10-persistence/0000770000174600017460000000000014556675336022520 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/10-persistence/generate_cube.hh0000660000174600017460000000404614556675336025636 0ustar gitlab-runnergitlab-runner#ifndef GENERATE_CUBE_HH #define GENERATE_CUBE_HH template size_t generate_cube( MeshType& mesh ) { typedef typename MeshType::VertexHandle VertexHandle; typedef typename MeshType::Point Point; typename MeshType::VertexHandle vhandle[8]; vhandle[0] = mesh.add_vertex(Point(-1, -1, 1)); vhandle[1] = mesh.add_vertex(Point( 1, -1, 1)); vhandle[2] = mesh.add_vertex(Point( 1, 1, 1)); vhandle[3] = mesh.add_vertex(Point(-1, 1, 1)); vhandle[4] = mesh.add_vertex(Point(-1, -1, -1)); vhandle[5] = mesh.add_vertex(Point( 1, -1, -1)); vhandle[6] = mesh.add_vertex(Point( 1, 1, -1)); vhandle[7] = mesh.add_vertex(Point(-1, 1, -1)); // generate (quadrilateral) faces std::vector< VertexHandle > face_vhandles; face_vhandles.clear(); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[3]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[7]); face_vhandles.push_back(vhandle[6]); face_vhandles.push_back(vhandle[5]); face_vhandles.push_back(vhandle[4]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[4]); face_vhandles.push_back(vhandle[5]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[1]); face_vhandles.push_back(vhandle[5]); face_vhandles.push_back(vhandle[6]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[2]); face_vhandles.push_back(vhandle[6]); face_vhandles.push_back(vhandle[7]); mesh.add_face(face_vhandles); face_vhandles.clear(); face_vhandles.push_back(vhandle[0]); face_vhandles.push_back(vhandle[3]); face_vhandles.push_back(vhandle[7]); face_vhandles.push_back(vhandle[4]); mesh.add_face(face_vhandles); return mesh.n_vertices(); }; #endif OpenMesh-11.0.0/Doc/Tutorial/10-persistence/fill_props.hh0000660000174600017460000000572414556675336025223 0ustar gitlab-runnergitlab-runner#ifndef FILL_PROPS_HH #define FILL_PROPS_HH #include #include "int2roman.hh" template bool fill_props( Mesh& _m, OpenMesh::VPropHandleT _ph, bool _check=false) { static float a[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f }; for(typename Mesh::VertexIter it=_m.vertices_begin(); it != _m.vertices_end(); ++it) { const float v = a[it->idx()%9]; if ( _check && !(_m.property( _ph, *it ) == v) ) return false; else _m.property( _ph, *it ) = v; } return true; } template bool fill_props( Mesh& _m, OpenMesh::EPropHandleT _ph, bool _check=false ) { for( typename Mesh::EdgeIter it=_m.edges_begin(); it != _m.edges_end(); ++it) { const size_t n = it->idx(); const bool v = ((n&(n-1))==0); // true for 0,1,2,4,8,.. if (_check && _m.property( _ph, *it ) != v) { std::cout << " eprop_bool: " << n << " -> " << _m.property(_ph, *it ) << " != " << v << std::endl; return false; } else { _m.property( _ph, *it ) = v; std::cout << " eprop_bool: " << n << " -> " << v << std::endl; } } return true; } template bool fill_props(Mesh& _m, OpenMesh::FPropHandleT _ph, bool _check=false) { for( typename Mesh::FaceIter it=_m.faces_begin(); it != _m.faces_end(); ++it) { const int n = (it->idx()) + 1; _m.property( _ph, *it ) = int2roman(n); } return true; } template bool fill_props( Mesh& _m, OpenMesh::HPropHandleT _ph, bool _check=false) { T v; static float a[9] = { 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f }; static float b[9] = { 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f }; static float c[9] = { 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f, 2.2f }; static float d[9] = { 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 1.1f, 2.2f, 3.3f }; static double values[9] = { 0.1, 0.02, 0.003, 0.0004, 0.00005, 0.000006, 0.0000007, 0.00000008, 0.000000009 }; for( typename Mesh::HalfedgeIter it=_m.halfedges_begin(); it != _m.halfedges_end(); ++it) { const int n = it->idx(); v = it->idx()+1; // ival v = values[n%9]; // dval v = ((n&(n-1))==0); // bval v.vec4fval[0] = a[n%9]; v.vec4fval[1] = b[n%9]; v.vec4fval[2] = c[n%9]; v.vec4fval[3] = d[n%9]; if ( _check && _m.property( _ph, *it ) != v ) return false; else _m.property( _ph, *it ) = v; } return true; } template bool fill_props( Mesh& _m, OpenMesh::MPropHandleT _ph, bool _check=false) { for( typename Mesh::FaceIter it=_m.faces_begin(); it != _m.faces_end(); ++it) { const size_t idx = it->idx(); if ( _check && _m.property( _ph )[int2roman(idx+1)] != idx ) return false; else _m.property( _ph )[int2roman(idx+1)] = idx; } return true; } #endif OpenMesh-11.0.0/Doc/Tutorial/10-persistence/int2roman.cc0000660000174600017460000000246714556675336024752 0ustar gitlab-runnergitlab-runner#include #if defined(OM_CC_MIPS) # include #else # include #endif #include "int2roman.hh" std::string int2roman( size_t decimal, size_t length ) { assert( decimal > 0 && decimal < 1000 ); const size_t nrows = 4; const size_t ncols = 4; static size_t table_arabs[ nrows ][ ncols ] = { { 1000, 1000, 1000, 1000 }, { 900, 500, 400, 100 }, { 90, 50, 40, 10 }, { 9, 5, 4, 1 } }; static char *table_romans[ nrows ][ ncols ] = { { "M", "M", "M", "M" }, { "CM", "D", "CD", "C" }, { "XC", "L", "XL", "X" }, { "IX", "V", "IV", "I" } }; size_t power; // power of ten size_t index; // Indexes thru values to subtract std::string roman = ""; roman.reserve(length); for ( power = 0; power < nrows; power++ ) for ( index = 0; index < ncols; index++ ) while ( decimal >= table_arabs[ power ][ index ] ) { roman += table_romans[ power ][ index ]; decimal -= table_arabs[ power ][ index ]; } return roman; } OpenMesh-11.0.0/Doc/Tutorial/10-persistence/persistence.cc0000660000174600017460000002050514556675336025356 0ustar gitlab-runnergitlab-runner#include #include #include // -------------------- OpenMesh #include #include #include // -------------------- little helper #include "generate_cube.hh" #include "stats.hh" #include "fill_props.hh" // ---------------------------------------------------------------------------- // Set to 1 to use an PolyMesh type. #define UsePolyMesh 1 // ---------------------------------------------------------------------------- using namespace OpenMesh; // ---------------------------------------------------------------------------- typedef TriMesh_ArrayKernelT<> TriMesh; typedef PolyMesh_ArrayKernelT<> PolyMesh; #if UsePolyMesh typedef PolyMesh Mesh; #else typedef TriMesh Mesh; #endif // ---------------------------------------------------------------------------- #ifndef DOXY_IGNORE_THIS struct MyData { int ival; double dval; bool bval; OpenMesh::Vec4f vec4fval; MyData() : ival(0), dval(0.0), bval(false) { } MyData( const MyData& _cpy ) : ival(_cpy.ival), dval(_cpy.dval), bval(_cpy.bval), vec4fval(_cpy.vec4fval) { } // ---------- assignment MyData& operator = (const MyData& _rhs) { ival = _rhs.ival; dval = _rhs.dval; bval = _rhs.bval; vec4fval = _rhs.vec4fval; return *this; } MyData& operator = (int _rhs) { ival = _rhs; return *this; } MyData& operator = (double _rhs) { dval = _rhs; return *this; } MyData& operator = (bool _rhs) { bval = _rhs; return *this; } MyData& operator = (const OpenMesh::Vec4f& _rhs) { vec4fval = _rhs; return *this; } // ---------- comparison bool operator == (const MyData& _rhs) const { return ival == _rhs.ival && dval == _rhs.dval && bval == _rhs.bval && vec4fval == _rhs.vec4fval; } bool operator != (const MyData& _rhs) const { return !(*this == _rhs); } }; #endif // ---------------------------------------------------------------------------- typedef std::map< std::string, unsigned int > MyMap; // ---------------------------------------------------------------------------- #ifndef DOXY_IGNORE_THIS namespace OpenMesh { namespace IO { // support persistence for struct MyData template <> struct binary { typedef MyData value_type; static const bool is_streamable = true; // return binary size of the value static size_t size_of(void) { return sizeof(int)+sizeof(double)+sizeof(bool)+sizeof(OpenMesh::Vec4f); } static size_t size_of(const value_type&) { return size_of(); } static std::string type_identifier(void) { return "RegisteredDataType"; } static size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) { size_t bytes; bytes = IO::store( _os, _v.ival, _swap ); bytes += IO::store( _os, _v.dval, _swap ); bytes += IO::store( _os, _v.bval, _swap ); bytes += IO::store( _os, _v.vec4fval, _swap ); return _os.good() ? bytes : 0; } static size_t restore( std::istream& _is, value_type& _v, bool _swap=false) { size_t bytes; bytes = IO::restore( _is, _v.ival, _swap ); bytes += IO::restore( _is, _v.dval, _swap ); bytes += IO::restore( _is, _v.bval, _swap ); bytes += IO::restore( _is, _v.vec4fval, _swap ); return _is.good() ? bytes : 0; } }; template <> struct binary< MyMap > { typedef MyMap value_type; static const bool is_streamable = true; // return generic binary size of self, if known static size_t size_of(void) { return UnknownSize; } // return binary size of the value static size_t size_of(const value_type& _v) { if (_v.empty()) return sizeof(unsigned int); value_type::const_iterator it = _v.begin(); unsigned int N = _v.size(); size_t bytes = IO::size_of(N); for(;it!=_v.end(); ++it) { bytes += IO::size_of( it->first ); bytes += IO::size_of( it->second ); } return bytes; } static size_t store(std::ostream& _os, const value_type& _v, bool _swap=false) { size_t bytes = 0; unsigned int N = _v.size(); value_type::const_iterator it = _v.begin(); bytes += IO::store( _os, N, _swap ); for (; it != _v.end() && _os.good(); ++it) { bytes += IO::store( _os, it->first, _swap ); bytes += IO::store( _os, it->second, _swap ); } return _os.good() ? bytes : 0; } static size_t restore( std::istream& _is, value_type& _v, bool _swap=false) { size_t bytes = 0; unsigned int N = 0; _v.clear(); bytes += IO::restore( _is, N, _swap ); value_type::key_type key; value_type::mapped_type val; for (size_t i=0; i(mesh); // should display 8 vertices, 18/12 edges, 12/6 faces (Tri/Poly) mesh_stats(mesh); // print out information about properties mesh_property_stats(mesh); std::cout << "Define some custom properties..\n"; OpenMesh::VPropHandleT vprop_float; OpenMesh::EPropHandleT eprop_bool; OpenMesh::FPropHandleT fprop_string; OpenMesh::HPropHandleT hprop_mydata; OpenMesh::MPropHandleT mprop_map; std::cout << ".. and registrate them at the mesh object.\n"; mesh.add_property(vprop_float, "vprop_float"); mesh.add_property(eprop_bool, "eprop_bool"); mesh.add_property(fprop_string, "fprop_string"); mesh.add_property(hprop_mydata, "hprop_mydata"); mesh.add_property(mprop_map, "mprop_map"); mesh_property_stats(mesh); std::cout << "Now let's fill the props..\n"; fill_props(mesh, vprop_float); fill_props(mesh, eprop_bool); fill_props(mesh, fprop_string); fill_props(mesh, hprop_mydata); fill_props(mesh, mprop_map); std::cout << "Check props..\n"; #define CHK_PROP( PH ) \ std::cout << " " << #PH << " " \ << (fill_props(mesh, PH, true)?"ok\n":"error\n") CHK_PROP(vprop_float); CHK_PROP(eprop_bool); CHK_PROP(fprop_string); CHK_PROP(hprop_mydata); CHK_PROP(mprop_map); #undef CHK_PROP std::cout << "Set persistent flag..\n"; #define SET_PERS( PH ) \ mesh.property(PH).set_persistent(true); \ std::cout << " " << #PH << " " \ << (mesh.property(PH).persistent()?"ok\n":"failed!\n") mesh.property(vprop_float).set_persistent(true); std::cout << " vprop_float " << (mesh.property(vprop_float).persistent()?"ok\n":"failed!\n"); SET_PERS( eprop_bool ); SET_PERS( fprop_string ); SET_PERS( hprop_mydata ); mesh.mproperty(mprop_map).set_persistent(true); std::cout << " mprop_map " << (mesh.mproperty(mprop_map).persistent()?"ok\n":"failed!\n"); std::cout << "Write mesh.."; if (IO::write_mesh( mesh, "persistence-check.om" )) std::cout << " ok\n"; else { std::cout << " failed\n"; return 1; } std::cout << "Clear mesh\n"; mesh.clear(); mesh_stats(mesh, " "); std::cout << "Read back mesh.."; try { if (IO::read_mesh( mesh, "persistence-check.om" )) std::cout << " ok\n"; else { std::cout << " failed!\n"; return 1; } mesh_stats(mesh, " "); } catch( std::exception &x ) { std::cerr << x.what() << std::endl; return 1; } std::cout << "Check props..\n"; #define CHK_PROP( PH ) \ std::cout << " " << #PH << " " \ << (fill_props(mesh, PH, true)?"ok\n":"error\n") CHK_PROP(vprop_float); CHK_PROP(eprop_bool); CHK_PROP(fprop_string); CHK_PROP(hprop_mydata); CHK_PROP(mprop_map); #undef CHK_PROP return 0; } // end of file // ============================================================================ OpenMesh-11.0.0/Doc/Tutorial/10-persistence/stats.hh0000660000174600017460000000065714556675336024210 0ustar gitlab-runnergitlab-runner#ifndef STATS_HH #define STATS_HH template void mesh_stats( Mesh& _m, const std::string& prefix = "" ) { std::cout << prefix << _m.n_vertices() << " vertices, " << _m.n_edges() << " edges, " << _m.n_faces() << " faces\n"; } template void mesh_property_stats(Mesh& _m) { std::cout << "Current set of properties:\n"; _m.property_stats(std::cout); } #endif OpenMesh-11.0.0/Doc/Tutorial/10-persistence/int2roman.hh0000660000174600017460000000020114556675336024744 0ustar gitlab-runnergitlab-runner#ifndef INT2ROMAN_HH #define INT2ROMAN_HH #include std::string int2roman( size_t decimal, size_t length=30 ); #endif OpenMesh-11.0.0/Doc/Tutorial/06-attributes/0000770000174600017460000000000014556675336022367 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Tutorial/06-attributes/attributes.cc0000660000174600017460000000472214556675336025072 0ustar gitlab-runnergitlab-runner#include #include // -------------------- #include #include #include #ifndef DOXY_IGNORE_THIS // Define my personal traits struct MyTraits : OpenMesh::DefaultTraits { // Let Point and Normal be a vector of doubles typedef OpenMesh::Vec3d Point; typedef OpenMesh::Vec3d Normal; // Already defined in OpenMesh::DefaultTraits // HalfedgeAttributes( OpenMesh::Attributes::PrevHalfedge ); // Uncomment next line to disable attribute PrevHalfedge // HalfedgeAttributes( OpenMesh::Attributes::None ); // // or // // HalfedgeAttributes( 0 ); }; #endif // Define my mesh with the new traits! typedef OpenMesh::TriMesh_ArrayKernelT MyMesh; // ------------------------------------------------------------------ main ---- int main(int argc, char **argv) { MyMesh mesh; if (argc!=2) { std::cerr << "Usage: " << argv[0] << " \n"; return 1; } // Just make sure that point element type is double if ( typeid( OpenMesh::vector_traits::value_type ) != typeid(double) ) { std::cerr << "Ouch! ERROR! Data type is wrong!\n"; return 1; } // Make sure that normal element type is double if ( typeid( OpenMesh::vector_traits::value_type ) != typeid(double) ) { std::cerr << "Ouch! ERROR! Data type is wrong!\n"; return 1; } // Add vertex normals as default property (ref. previous tutorial) mesh.request_vertex_normals(); // Add face normals as default property mesh.request_face_normals(); // load a mesh OpenMesh::IO::Options opt; if ( ! OpenMesh::IO::read_mesh(mesh,argv[1], opt)) { std::cerr << "Error loading mesh from file " << argv[1] << std::endl; return 1; } // If the file did not provide vertex normals, then calculate them if ( !opt.check( OpenMesh::IO::Options::VertexNormal ) && mesh.has_face_normals() && mesh.has_vertex_normals() ) { // let the mesh update the normals mesh.update_normals(); } // move all vertices one unit length along it's normal direction for (MyMesh::VertexIter v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it) { std::cout << "Vertex #" << *v_it << ": " << mesh.point( *v_it ); mesh.set_point( *v_it, mesh.point(*v_it)+mesh.normal(*v_it) ); std::cout << " moved to " << mesh.point( *v_it ) << std::endl; } return 0; } OpenMesh-11.0.0/Doc/Concepts/0000770000174600017460000000000014556675336017731 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/Concepts/MeshKernel.hh0000660000174600017460000005243714556675336022323 0ustar gitlab-runnergitlab-runner/* ========================================================================= * * * * OpenMesh * * Copyright (c) 2001-2015, RWTH-Aachen University * * Department of Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * *---------------------------------------------------------------------------* * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * * * 1. Redistributions of source code must retain the above copyright notice, * * this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. Neither the name of the copyright holder nor the names of its * * contributors may be used to endorse or promote products derived from * * this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= */ //============================================================================= // // Kernel Concept // //============================================================================= #error this file is for documentation purposes only //== NAMESPACES =============================================================== namespace OpenMesh { namespace Concepts { //== CLASS DEFINITION ========================================================= /** \ingroup mesh_concepts_group This class describes the minimum interface a mesh kernel has to implement (because the resulting mesh will rely on this interface). This is the template class the actually holds the mesh kernel implementation. All functions marked as internal should only be used by the mesh class (that inherits the kernel). The mesh may then provide wrapper functions that provide the same functionality. \todo Check, if the member list is complete. */ template class KernelT { public: /// \name Mesh Items //@{ /// Derive this type from the FinalMeshItems typedef typename FinalMeshItems::Vertex Vertex; typedef typename FinalMeshItems::Halfedge Halfedge; typedef typename FinalMeshItems::Edge Edge; typedef typename FinalMeshItems::Face Face; typedef typename FinalMeshItems::Point Point; typedef typename FinalMeshItems::Scalar Scalar; typedef typename FinalMeshItems::Normal Normal; typedef typename FinalMeshItems::Color Color; typedef typename FinalMeshItems::TexCoord TexCoord; typedef typename FinalMeshItems::VertexHandle VertexHandle; typedef typename FinalMeshItems::HalfedgeHandle HalfedgeHandle; typedef typename FinalMeshItems::EdgeHandle EdgeHandle; typedef typename FinalMeshItems::FaceHandle FaceHandle; //@} /// \name Kernel Iterators //@{ /// This type depends on the container type in use. typedef SomeIterator KernelVertexIter; typedef SomeIterator KernelConstVertexIter; typedef SomeIterator KernelEdgeIter; typedef SomeIterator KernelConstEdgeIter; typedef SomeIterator KernelFaceIter; typedef SomeIterator KernelConstFaceIter; //@} /// \name Constructor/Destructor //@{ /// Default constructor KernelT() {} /// Destructor ~KernelT(); //@} /// Assignment operator KernelT& operator=(const KernelT& _rhs); /** Reserve memory for vertices, edges, faces. * * Reserve memory for the mesh items vertices, edges, faces. Use * this method if you can estimate the memory consumption, for * instance in algorithm expanding the mesh. Depending on the * underlying array type you might be better of using this method, * then letting the array type decide when to increase the * capacity. For instance the STL vector class \c std::vector (used * in the supplied ArrayKernelT) doubles the capacity if it is * exhausted. This might lead to an memory allocation exception, * though an smaller increment would be enough. */ void reserve( size_t _n_vertices, size_t _n_edges, size_t _n_faces ); /// \name Handle -> Item. //@{ /// Translate handle to item (see also OpenMesh::PolyMeshT::deref()) const Vertex& vertex(VertexHandle _h) const { return deref(_h); } Vertex& vertex(VertexHandle _h) { return deref(_h); } const Halfedge& halfedge(HalfedgeHandle _h) const { return deref(_h); } Halfedge& halfedge(HalfedgeHandle _h) { return deref(_h); } const Edge& edge(EdgeHandle _h) const { return deref(_h); } Edge& edge(EdgeHandle _h) { return deref(_h); } const Face& face(FaceHandle _h) const { return deref(_h); } Face& face(FaceHandle _h) { return deref(_h); } //@} /// \name Item -> Handle //@{ /// Translate item to handle VertexHandle handle(const Vertex& _v) const; HalfedgeHandle handle(const Halfedge& _he) const; EdgeHandle handle(const Edge& _e) const; FaceHandle handle(const Face& _f) const; //@} /// \name Get the i'th item //@{ /// Get the i'th item VertexHandle vertex_handle(unsigned int _i) const; HalfedgeHandle halfedge_handle(unsigned int _i) const; EdgeHandle edge_handle(unsigned int _i) const; FaceHandle face_handle(unsigned int _i) const; //@} /// \name Delete items //@{ /** Delete all items, i.e. clear all item containers. * The properties will also be removed from the mesh */ void clear(); /** Delete all items, i.e. clear all item containers. * The properties will be kept */ void clean(); /** Remove all items that are marked as deleted from the corresponding containers. \note All handles (and indices) to any entity (face, vertex, edge, halfedge) created before garbage collection will be out of sync with the mesh, do not use them anymore! See also \ref deletedElements. \note Needs the Attributes::Status attribute \note This function may not be implemented for all kernels. */ void garbage_collection(); /** Remove the last vertex imidiately, i.e. call pop_back() for the VertexContainer. */ void remove_last_vertex() { vertices_.pop_back(); } /** Remove the last edge imidiately, i.e. call pop_back() for the EdgeContainer. Used e.g. by the add_face() method of PolyMeshT */ void remove_last_edge() { edges_.pop_back(); } /** Remove the last face imidiately, i.e. call pop_back() for the FaceContainer. Used e.g. by the add_face() method of PolyMeshT */ void remove_last_face() { faces_.pop_back(); } //@} /// \name Number of elements //@{ /// Returns number of vertices size_t n_vertices() const; /// Returns number of halfedges (should be 2*n_edges()) size_t n_halfedges() const; /// Returns number of edges size_t n_edges() const; /// Returns number of faces size_t n_faces() const; /// Is the vertex container empty? bool vertices_empty() const; /// Is the halfedge container empty (should be the same as edges_empty()). bool halfedges_empty() const; /// Is the edge container empty? bool edges_empty() const; /// Is the face container empty? bool faces_empty() const; //@} /// \name Vertex connectivity //@{ /// Get an outgoing halfedge of a given vertex HalfedgeHandle halfedge_handle(VertexHandle _vh) const; /// Set the outgoing halfedge handle of a given vertex void set_halfedge_handle(VertexHandle _vh, HalfedgeHandle _heh); /// Get the coordinate of a vertex const Point& point(VertexHandle _vh) const; /// Get the coordinate of a vertex const Point& point(const Vertex& _v) const; /// Set the coordinate of a vertex void set_point(VertexHandle _vh, const Point& _p); /// Set the coordinate of a vertex void set_point(Vertex& _v, const Point& _p); //@} /// \name Halfedge connectivity //@{ /// Get the vertex the halfedge points to VertexHandle to_vertex_handle(HalfedgeHandle _heh) const; /** Get the vertex the halfedge starts from (implemented as to-handle of the opposite halfedge, provided for convenience) */ VertexHandle from_vertex_handle(HalfedgeHandle _heh) const; /// Set the to-vertex-handle of the halfedge void set_vertex_handle(HalfedgeHandle _heh, VertexHandle _vh); /** Get the face the halfedge belongs to. \note The handle is invalid if the halfedge is a boundary halfedge */ FaceHandle face_handle(HalfedgeHandle _heh) const; /// Set the face the halfedge belongs to void set_face_handle(HalfedgeHandle _heh, FaceHandle _fh); /// Get the next halfedge handle HalfedgeHandle next_halfedge_handle(HalfedgeHandle _heh) const; /** Set the next halfedge handle. \note If the previous halfedge is also stored (see OpenMesh::Attributes::PrevHalfedge) then this method also has to set this link) */ void set_next_halfedge_handle(HalfedgeHandle _heh, HalfedgeHandle _nheh); /** Get the previous halfedge of the given halfedge. The implementation should take care of an existing OpenMesh::Attributes::PrevHalfedge attribute. */ HalfedgeHandle prev_halfedge_handle(HalfedgeHandle _heh) const; /// Get the opposite halfedge HalfedgeHandle opposite_halfedge_handle(HalfedgeHandle _heh) const; /// Counter-clockwise rotate the given halfedge around its from vertex HalfedgeHandle ccw_rotated_halfedge_handle(HalfedgeHandle _heh) const; /// Clockwise rotate the given halfedge around its from vertex HalfedgeHandle cw_rotated_halfedge_handle(HalfedgeHandle _heh) const; /// Get the edge the current halfedge it contained in EdgeHandle edge_handle(HalfedgeHandle _heh) const; //@} /// \name Edge connectivity //@{ /// Get the first or second halfedge of the given edge HalfedgeHandle halfedge_handle(EdgeHandle _eh, unsigned int _i) const; //@} /// \name Face connectivity //@{ /// Get a halfedge belonging to the face HalfedgeHandle halfedge_handle(FaceHandle _fh) const; /// Set one halfedge of the face void set_halfedge_handle(FaceHandle _fh, HalfedgeHandle _heh); //@} public: // Standard Property Management /// \name set/get value of a standard property //@{ // vertex const Point& point(VertexHandle _vh) const; ///< Get position void set_point(VertexHandle _vh, const Point& _p); ///< Set position Point& point(VertexHandle _vh); ///< Convenience function const Normal& normal(VertexHandle _vh) const; ///< Get normal void set_normal(VertexHandle _vh, const Normal& _n); ///< Set normal const Normal& normal(HalfedgeHandle _heh) const; ///< Get normal of the to vertex of the given Halfedge (per face per vertex normals) void set_normal(HalfedgeHandle _heh, const Normal& _n); ///< Set normal of the to vertex of the given Halfedge (per face per vertex normals) const Color& color(VertexHandle _vh) const; ///< Get color void set_color(VertexHandle _vh, const Color& _c); ///< Set color const TexCoord1D& texcoord1D(VertexHandle _vh) const; ///< Get texture coordinate. void set_texcoord1D(VertexHandle _vh, const TexCoord1D& _t); ///< Set texture coordinate. const TexCoord2D& texcoord2D(VertexHandle _vh) const; ///< Get texture coordinate. void set_texcoord2D(VertexHandle _vh, const TexCoord2D& _t); ///< Set texture coordinate. const TexCoord3D& texcoord3D(VertexHandle _vh) const; ///< Get texture coordinate. void set_texcoord3D(VertexHandle _vh, const TexCoord3D& _t); ///< Set texture coordinate. const TexCoord1D& texcoord1D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords) void set_texcoord1D(HalfedgeHandle _hh, const TexCoord1D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords) const TexCoord2D& texcoord2D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords) void set_texcoord2D(HalfedgeHandle _hh, const TexCoord2D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords) const TexCoord3D& texcoord3D(HalfedgeHandle _hh) const; ///< Get texture coordinate of the to vertex for the current face (per face per vertex texcoords) void set_texcoord3D(HalfedgeHandle _hh, const TexCoord3D& _t); ///< Set texture coordinate of the to vertex of the given Halfedge (per face per vertex texcoords) const StatusInfo& status(VertexHandle _vh) const; ///< Get status StatusInfo& status(VertexHandle _vh); ///< Get status // halfedge const StatusInfo& status(HalfedgeHandle _vh) const; ///< Get status StatusInfo& status(HalfedgeHandle _vh); ///< Get status const Color& color(HalfedgeHandle _heh) const; ///< Get color void set_color(HalfedgeHandle _heh, const Color& _c); ///< Set color // edge const Color& color(EdgeHandle _eh) const; ///< Get color void set_color(EdgeHandle _eh, const Color& _c); ///< Set color const StatusInfo& status(EdgeHandle _vh) const; ///< Get status StatusInfo& status(EdgeHandle _vh); ///< Get status // face const Normal& normal(FaceHandle _fh) const; ///< Get normal void set_normal(FaceHandle _fh, const Normal& _n); ///< Set normal const Color& color(FaceHandle _fh) const; ///< Get color void set_color(FaceHandle _fh, const Color& _c); ///< Set color const StatusInfo& status(FaceHandle _vh) const; ///< Get status StatusInfo& status(FaceHandle _vh); ///< Get status //@} /// \name Dynamically add standard properties //@{ /// Request property void request_vertex_normals(); void request_vertex_colors(); void request_vertex_texcoords1D(); void request_vertex_texcoords2D(); void request_vertex_texcoords3D(); void request_vertex_status(); void request_halfedge_status(); void request_halfedge_normals(); void request_halfedge_colors(); void request_halfedge_texcoords1D(); void request_halfedge_texcoords2D(); void request_halfedge_texcoords3D(); void request_edge_status(); void request_edge_colors(); void request_face_normals(); void request_face_colors(); void request_face_status(); void request_face_texture_index(); //@} /// \name Remove standard properties //@{ /// Remove property void release_vertex_normals(); void release_vertex_colors(); void release_vertex_texcoords1D(); void release_vertex_texcoords2D(); void release_vertex_texcoords3D(); void release_vertex_status(); void release_halfedge_status(); void release_halfedge_normals(); void release_halfedge_colors(); void release_halfedge_texcoords1D(); void release_halfedge_texcoords2D(); void release_halfedge_texcoords3D(); void release_edge_status(); void release_edge_colors(); void release_face_normals(); void release_face_colors(); void release_face_status(); void release_face_texture_index(); //@} /// \name Check availability of standard properties //@{ /// Is property available? bool has_vertex_normals() const; bool has_vertex_colors() const; bool has_vertex_texcoords1D() const; bool has_vertex_texcoords2D() const; bool has_vertex_texcoords3D() const; bool has_vertex_status() const; bool has_halfedge_status() const; bool has_halfedge_normals() const; bool has_halfedge_colors() const; bool has_halfedge_texcoords1D() const; bool has_halfedge_texcoords2D() const; bool has_halfedge_texcoords3D() const; bool has_edge_status() const; bool has_edge_colors() const; bool has_face_normals() const; bool has_face_colors() const; bool has_face_status() const; bool has_face_texture_index() const; //@} public: // Property Management /// \anchor concepts_kernelt_property_management /// \name Property management - add property //@{ /// Add property. /// @copydoc OpenMesh::BaseKernel::add_property() template void add_property( [VEHFM]PropHandleT& _ph, const std::string& _name = "" ); //@} /// \name Property management - remove property //@{ /// Remove property template void remove_property( [VEHFM]PropHandleT& ); //@} /// \name Property management - get property by name //@{ /// Get property handle by name template bool get_property_handle( [VEHFM]PropHandleT& ph, const std::string& _n ) const; //@} /// \name Property management - get property //@{ /// Get property template PropertyT& property( [VEHF]PropHandleT _ph ); template const PropertyT& property( [VEHF]PropHandleT _ph ) const; template PropertyT& mproperty( MPropHandleT _ph ); template const PropertyT& mproperty( MPropHandleT _ph ) const; //@} /// \name Property management - get property value for an item //@{ /// Get value for item represented by the handle. template T& property( VPropHandleT _ph, VertexHandle _vh ); template const T& property( VPropHandleT _ph, VertexHandle _vh ) const; template T& property( EPropHandleT _ph, EdgeHandle _vh ); template const T& property( EPropHandleT _ph, EdgeHandle _vh ) const; template T& property( HPropHandleT _ph, HalfedgeHandle _vh ); template const T& property( HPropHandleT _ph, HalfedgeHandle _vh ) const; template T& property( FPropHandleT _ph, FaceHandle _vh ); template const T& property( FPropHandleT _ph, FaceHandle _vh ) const; template T& property( MPropHandleT _ph ); template const T& property( MPropHandleT _ph ) const; //@} public: /// \name Low-level adding new items //@{ /** Add a new (default) vertex. \internal */ VertexHandle new_vertex(); /** Add a new vertex with a given point coordinate. \internal */ VertexHandle new_vertex(const Point& _p); /** Add a new vertex (copied from the given one). \internal */ VertexHandle new_vertex(const Vertex& _v); /** Add a new edge from \c _start_vertex_handle to \c _end_vertex_handle. This method should add an edge (i.e. two opposite halfedges) and set the corresponding vertex handles of these halfedges. \internal */ HalfedgeHandle new_edge(VertexHandle _start_vertex_handle, VertexHandle _end_vertex_handle); /** Adding a new face \internal */ FaceHandle new_face(); /** Adding a new face (copied from a \c _f). \internal */ FaceHandle new_face(const Face& _f); //@} // --- iterators --- /// \name Kernel item iterators //@{ /** Kernel item iterator \internal */ KernelVertexIter vertices_begin(); KernelConstVertexIter vertices_begin() const; KernelVertexIter vertices_end(); KernelConstVertexIter vertices_end() const; KernelEdgeIter edges_begin(); KernelConstEdgeIter edges_begin() const; KernelEdgeIter edges_end(); KernelConstEdgeIter edges_end() const; KernelFaceIter faces_begin(); KernelConstFaceIter faces_begin() const; KernelFaceIter faces_end(); KernelConstFaceIter faces_end() const; //@} private: // --- private functions --- /// copy constructor: not used KernelT(const KernelT& _rhs); }; }; //============================================================================= } // namespace Concepts } // namespace OpenMesh //============================================================================= OpenMesh-11.0.0/Doc/Concepts/MeshItems.hh0000660000174600017460000001615014556675336022154 0ustar gitlab-runnergitlab-runner/* ========================================================================= * * * * OpenMesh * * Copyright (c) 2001-2015, RWTH-Aachen University * * Department of Computer Graphics and Multimedia * * All rights reserved. * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * *---------------------------------------------------------------------------* * * * Redistribution and use in source and binary forms, with or without * * modification, are permitted provided that the following conditions * * are met: * * * * 1. Redistributions of source code must retain the above copyright notice, * * this list of conditions and the following disclaimer. * * * * 2. Redistributions in binary form must reproduce the above copyright * * notice, this list of conditions and the following disclaimer in the * * documentation and/or other materials provided with the distribution. * * * * 3. Neither the name of the copyright holder nor the names of its * * contributors may be used to endorse or promote products derived from * * this software without specific prior written permission. * * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * * ========================================================================= */ //============================================================================= // // Mesh Items Concept // //============================================================================= #error this file is for documentation purposes only //== NAMESPACES =============================================================== namespace OpenMesh { namespace Concepts { //== CLASS DEFINITION ========================================================= /** \ingroup mesh_concepts_group The mesh items class encapsulates the types VertexT, HalfedgeT, EdgeT, and FaceT. \see VertexT, HalfedgeT, EdgeT, FaceT */ struct MeshItems { /** Interface for the internal vertex type. This minimal interface must be provided by every vertex. It's up to the mesh kernel (or the items used by the mesh kernel) to implement it. All methods marked as internal should only be used by the mesh kernel. */ template class VertexT { public: /// Re-export the template argument Refs. This \b must be done! typedef Refs_ Refs; /// Default constructor VertexT(); /// Get an outgoing halfedge HalfedgeHandle halfedge_handle() const; /// Set the outgoing halfedge link void set_halfedge_handle(HalfedgeHandle _eh); }; /** Interface for the internal halfedge type. This minimal interface must be provided by every halfedge. It's up to the mesh kernel (or the items used by the mesh kernel) to implement it. All methods marked as internal should only be used by the mesh kernel. */ template class HalfedgeT { public: /// Re-export the template argument Refs. This \b must be done! typedef Refs_ Refs; /** Get the vertex the halfedge point to. \internal */ VertexHandle vertex_handle() const; /** Set the vertex the halfedge point to. \internal */ void set_vertex_handle(VertexHandle _vh); /** Get the face this halfedge belongs to. \internal */ FaceHandle face_handle() const; /** Set the face this halfedge belongs to. \internal */ void set_face_handle(FaceHandle _fh); /** Get the next halfedge inside this face. \internal */ HalfedgeHandle next_halfedge_handle() const; /** Set the next halfedge inside this face. \internal */ void set_next_halfedge_handle(HalfedgeHandle _eh); }; /** Interface for the internal edge type. This minimal interface must be provided by every edge. It's up to the mesh kernel (or the items used by the mesh kernel) to implement it. All methods marked as internal should only be used by the mesh kernel. */ template class EdgeT { public: /// Re-export the template argument Refs. This \b must be done! typedef Refs_ Refs; /** Store two halfedges. \internal */ Halfedge halfedges[2]; }; /** Interface for the internal face type. This minimal interface must be provided by every face. It's up to the mesh kernel (or the items used by the mesh kernel) to implement it. All methods marked as internal should only be used by the mesh kernel. */ template class FaceT { public: /// Re-export the template argument Refs. This \b must be done! typedef Refs_ Refs; /** Compile-time-tag: is this face a triangle? Should be typedef'ed to either GenProg::TagTrue or GenProg::TagFalse */ typedef GenProg::TagTrue IsTriangle; /// Run-time test: is this face a triangle? static bool is_triangle(); /// Get the number of vertices of this face. unsigned char n_vertices() const; /** Set the number of vertices of this face. \internal */ void set_n_vertices(unsigned char _n); /// Get a halfedge that belongs to this face. HalfedgeHandle halfedge_handle() const; /** Set a halfedge that belongs this face. \internal */ void set_halfedge_handle(HalfedgeHandle _eh); }; }; //============================================================================= } // namespace Concepts } // namespace OpenMesh //============================================================================= OpenMesh-11.0.0/Doc/decimater.docu0000660000174600017460000001073114556675336020767 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page decimater_docu Mesh Decimation Framework The mesh decimation framework has 3 building blocks. -# \ref DecimaterAlg -# \ref DecimaterMod -# \ref DecimaterHnd \section DecimaterAlg The decimation algorithm The decimater (OpenMesh::Decimater::DecimaterT) provides the decimation algorithm, while the decimation modules provide the computational part. The modules compute a priority value due to some error metric, which is used by the decimater to feed a priority queue. The lower the error value, the more a potential collapse moves to the front of the queue. The one with the lowest error will always be the candidate for the next collapse. This implementation does a halfedge collapse, hence simply collapsing one vertex into another connected by a halfedge. \note The decimater ignores all 'locked' and 'deleted' vertices (see OpenMesh::Attributes::StatusBits) \attention The decimater sets temporarily the status bit 'tagged' and clears it after usage regardless of a previous state. \section DecimaterLock Block vertices from beeing touched by the Decimater You could mark vertices as locked, which should not be modified by the decimater. \code // That might be already requested mesh_->request_vertex_status(); // Get an iterator over all halfedges Mesh::HalfedgeIter he_it, he_end=mesh_->halfedges_end(); // If halfedge is boundary, lock the corresponding vertices for (he_it = mesh_->halfedges_begin(); he_it != he_end ; ++he_it) if (mesh_->is_boundary(*he_it)) { mesh_->status(_mesh->to_vertex_handle(*he_it)).set_locked(true); mesh_->status(_mesh->from_vertex_handle(*he_it)).set_locked(true); } \endcode \section DecimaterMod Decimating Modules The vertex to be removed is determined by a decimation module, which has to be derived from OpenMesh::Decimater::ModBaseT. The framework supplies already a few decimation modules. But it's very easy to build your own (\ref OpenMesh::Decimater::ModBaseT). The most important function of a decimation module is OpenMesh::Decimater::ModBaseT::collapse_priority(). It takes an OpenMesh::Decimater::CollapseInfoT describing a potential halfedge collapse, and returns a value due to some error metric. The error value is used by the decimater to feed a priority queue. Collapses with low error will be executed first, and those with large error later. Of course a module computing the error quadric is provided (OpenMesh::Decimater::ModQuadricT). This framework allows to use more than one decimation module with some restrictions. Since the error value is always normalized and sometimes very difficult to compare to other metrics, the framework allows only one non-binary module, i.e. a module computing a float value. Every further module must be a binary module, i.e. collapse_prioerity() returns OpenMesh::Decimater::ModBaseT::LEGAL_COLLAPSE or OpenMesh::Decimater::ModBaseT::ILLEGAL_COLLAPSE. In the algorithm the binary modules are evaluated first. If the evaluated collapse passes the test, then the non-binary module contributes to the decision step. In some cases the module does not contribute anything to the decision engine of the decimater, but instead, e.g. simply collects information, while the decimater does it's work. For instance the module OpenMesh::Decimater::ModProgMeshT collects information from all collapses that have been done. This information can be used to generate progressive meshes as described in "Progressive meshes", Hoppe, 1996. Provided decimation modules(Binary: B, Continuous: C, Special: X): - OpenMesh::Decimater::ModAspectRatioT (B,C) - OpenMesh::Decimater::ModEdgeLengthT (B,C) - OpenMesh::Decimater::ModHausdorffT (B) - OpenMesh::Decimater::ModIndependentSetsT (B) - OpenMesh::Decimater::ModNormalDeviationT (B,C) - OpenMesh::Decimater::ModNormalFlippingT (B) - OpenMesh::Decimater::ModProgMeshT (X) - OpenMesh::Decimater::ModQuadricT (B,C) - OpenMesh::Decimater::ModRoundnessT (B,C) \section DecimaterHnd Module Handles Similar to properties the modules are represented outside the decimater by module handles. Before using the decimater a non-binary module must be registrated with the decimater. See \ref DecimaterExa. \section DecimaterExa Basic Setup The following small example show the basic steps to setup up a decimater: \include decimater.cc */ OpenMesh-11.0.0/Doc/tutorial_12.docu0000660000174600017460000000347614556675336021207 0ustar gitlab-runnergitlab-runner/** \page tutorial_12 Filtering ranges with predicates This examples shows: - How to use predicates to filter which elements of a mesh you want iterate over In the previous tutorial we discussed already that the ranges returned by functions like all_vertices(), voh_range() or outgoing_halfedges() provide a few helpful methods such as avg() or to_vector(). Another interesting method is filtered() which requires as argument something that can be called for an element of the range and returns a bool. The resulting range will then only iterate over elements for which the filter returs true. The filter can be a lambda, a function pointer, a property manager holding a bool property, or a functor object such as the predicates defined in . The predefined predicates can check the status of a mesh element and test if they are boundary. With their help you can for example count all boundary vertices: \dontinclude 12-predicates/predicates.cc \skipline Count boundary vertices \until boundary vertices Predicates can be composed using the operators ||, &&, and !. This enables you to specify precisely which elements you want process in your loop, e.g. inner vertices that are selected: \skipline Selected inner vertices \until std::cout << std::endl As mentioned above, the filter argument can be anything returning a bool for a given input, e.g. a function pointer: \skipline Faces whose id is divisible by 3 \until faces whose id is divisible by 3 However, function pointers, lambdas etc are not composable. Fortunately, you can use make_predicate to turn them into composable predicates: \skipline Faces which are tagged or whose id is not divisible by 3 \until faces which are tagged or whose id is not divisible by 3 Below is the complete source code: \include 12-predicates/predicates.cc --- */ OpenMesh-11.0.0/Doc/tutorial_build.docu0000660000174600017460000000472614556675336022063 0ustar gitlab-runnergitlab-runner/** \page tutorial_build_internal_apps How to create your own project inside OpenMesh In this tutorial we will explain, how to create a new app inside the source code of %OpenMesh and compile it with the CMake build system. We assume, that you have already downloaded the %OpenMesh source files as well as installed the CMake build tools. If you only want to use OpenMesh from your program, please refer to the tutorial \ref tutorial_build ! There are quite few steps to follow to successfully add your own application to the build tree: \li Go to OpenMeshRoot/src/OpenMesh/Apps and create a new directory, say "MyOwnProject" \li Now create a new file called "CMakeLists.txt" containing the following lines: \include CMakeLists.txt-internal (Remember to replace "MyProjectName" with whatever you have chosen as your project's name. Note: If you don't want to use *.hh and *.cc as your C++ source file suffices, you'll have to change this, too, because CMake won't build your sources otherwise. \li Create your source files as for example explained in the previous tutorial (\ref tutorial_01) and save them in the same directory. \li Add \code add_subdirectory (MyOwnProject) \endcode to OpenMeshRoot/src/OpenMesh/Apps/CMakeLists.txt (note: You can either add this line right after the other projects or at the end of the file). \li Create a directory called "build" in OpenMesh's root directory. Change to the newly created directory and call \code cmake .. \endcode and \code make \endcode That's all. Your project will now be built. \page tutorial_build How to create your own project using OpenMesh and cmake In this tutorial we will explain, how to create a new app using a pre build or installed %OpenMesh library. We assume that you already donwloaded and installed OpenMesh or compiled and installed it. \li Create a folder in which you want to place the source code of your application. \li Create a file called CMakeLists.txt containing the following lines: \include CMakeLists.txt-external \li We assume, that your source code is in build_cube.cc. You can take the code from \ref tutorial_01 \li Create a build directory \li Run cmake inside the build directory. The source directory is the directory with the new CMakelists.txt file. \li If cmake can't find OpenMesh, Set the cmake variable OpenMesh_DIR to the installed OpenMesh directory and add share/OpenMesh/cmake \li Go to the build directory and compile your application using the generated build files **/ OpenMesh-11.0.0/Doc/holefiller.docu0000660000174600017460000000100714565347650021146 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page holefiller_docu Mesh Hole Filler \section HoleFillerAlgo The holefilling algorithm The holefiller (OpenMesh::HoleFiller::HoleFillerT) provides a hole filling algorith based on the Filling Holes in Meshes paper by Liepa in 2003. \code // Initialize holefiller OpenMesh::HoleFiller::HoleFillerT filler(mesh_); // Execute the algorithm and fill all holes filler.fill_all_holes(); \endcode */ OpenMesh-11.0.0/Doc/compiling.docu0000660000174600017460000001747714556675336021031 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page compiling Compiling OpenMesh \section compilers Tested compilers %OpenMesh has been successfully tested for the following operating systems / compilers. This is only a list of tested compilers. More might be supported but are not tested. Make sure that your compiler supports at least C++11
Linux gcc >= 6.3
clang >= 3.3
Windows Microsoft Visual Studio 2015
Microsoft Visual Studio 2017
Tested MacOS X Compilers XCode
\section req_libs Required libraries (Only if you want to build the included Apps) Install the following external libraries / frameworks if you want to use the included Applications:

Qt5https://www.qt.io/download

\section build_systems Chosing build system %OpenMesh can be built using the cmake build system.

\section sec_compiling_unix Unix \subsection linux_using_cmake Compiling OpenMesh using CMake In order to compile %OpenMesh, create a directory named e.g. "build" in OpenMesh's root directory. Change to the newly created directory and type

cmake ..            ## Generates the appropriate Makefiles
make                ## Builds the project

\warning If your compiler does not support c++11 natively, you might have to enable it by changing the cmake call to:
cmake .. -DCMAKE_CXX_FLAGS=-std=c++98 You can choose the build type by using cmake with the flag
-DCMAKE_BUILD_TYPE=(Debug|Release) The default is: Release
Other flags are:
-DBUILD_APPS=OFF to disable build of applications and
-DCMAKE_INSTALL_PREFIX=<path> to specify the install path.
When calling make install cmake will install %OpenMesh into this directory using the subdirectories lib/include/bin. CMake builds both shared and static under Linux. Everything will then be build in the Build subdirectory containing the libraries in lib and the binaries in bin. There are some additional targets:
doc: Builds the Documentation
doc-install: Builds the Documentation and installs it

\note When you link against the static libraries of OpenMesh and get the error "can not be used when making a shared object; recompile with -fPIC" you need to add "-fPIC" to the CMAKE_CXX_FLAGS. (This is usually added automatically) \section sec_compiling_windows Windows \subsection windows_using_cmake Compiling OpenMesh using CMake Building OpenMesh on Windows requires cmake to generate the project files for Visual Studio.
  • Get Visual Studio ( 2015-2017 )
  • Extract %OpenMesh source code.
  • Get all required libraries and install them ( including headers! ).
  • Download and install cmake: www.cmake.org.
  • Start the cmake gui and open the %OpenMesh toplevel directory as source directory
  • Choose a build directory (e.g. create a directory called "build" in OpenMesh's root folder)
  • Click on configure .... If any libraries are left unconfigured, you can adjust the path manually. Rerun configure until everything is configured correctly.
    Attention: Some build variables are only visible in advanced view mode. Select Visual Studio 9 (2008), Visual Studio 10(2010), Visual Studio 11 (2012), Visual Studio 12 (2013) (Depending on your version) as generator.
  • Click generate to create the visual studio project files
  • You can now find a Visual Studio solution file (OpenMesh.sln) in the build directory you chose in cmake
  • Now you can build %OpenMesh from within Visual Studio using the newly created project file.


\section sec_compiling_macosx MacOS X To compile OpenMesh, you need cmake on your system which is the minimal requirement to build OpenMesh. We recommend using homebrew (https://brew.sh/index_de) for installing additional packages required for compiling OpenMesh or other projects. After installing homebrew, you can use the following command to install cmake:
brew install cmake            ## cmake generates the makefiles

Optional libraries which can be used to build OpenMesh:
brew install googletest            # Required to compile the included tests
brew install qt            # Required to compile the included UI example apps

Download and install required libraries as stated above. You can download %OpenMesh's sources from www.openmesh.org or check out the latest repository via GIT (Recommended to get the latest version of OpenMesh):
https://gitlab.vci.rwth-aachen.de:9000/OpenMesh/OpenMesh.

\subsection mac_using_cmake Compiling OpenMesh using CMake We recommend you to use CMake >= 3.7 as build system. This can also easily be installed via Homebrew as well as the Qt >= 6.2 library which is used for some example applications in %OpenMesh.
Once installed, change to %OpenMesh's root directory and create a directory named e.g. "buildDebug" (assuming you want to build with debug symbols).
Then type in the following command to initially set up the build environment:

cmake ..            ## Generates the appropriate Makefiles

Note: If the build directory is not a subdirectory of %OpenMesh's root folder, replace ".." with %OpenMesh's absolute (or relative) path. In order to manually set specific build variables, just type:

ccmake .            ## Configure build environment

This opens the CMake configure tool. Change the CMAKE_BUILD_TYPE variable to "Release" in order to prepare build for release configuration. Now, when everything is set up, just type:

make                ## Build %OpenMesh

And optionally:

make doc            ## Build %OpenMesh's documentation

The mac application bundle will be found under "Build" in the recently created build folder. It automatically contains all needed shared objects (libs, fonts, textures, etc.). CMake builds both shared and static under MacOS X. **/ /** \page compiling_tests Compiling OpenMesh unit tests %OpenMesh comes with a set of unittests for all platforms. In order to run these tests, you need to enable the cmake flag OPENMESH_BUILD_UNIT_TESTS. You also need GoogleTest on your machine. Configure the cmake variables in OpenMesh to point to your GTest include dirs and libraries (check the Advanced button in cmake, if you don't see these options). Than run cmake and build OpenMesh. Afterwards you should have a Unittests subdirectory in your binary build folder. This directory includes the unittest executables and several test files for input and output checks. You can run the executables directly, but make sure, that the working directory is the directory where the executables are. **/ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/mesh.docu0000660000174600017460000011510414556675336017766 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page mesh_first_to_read Notes on template programming Please note, that %OpenMesh makes heavily use of C++ templates, generic programming and all that stuff (see \ref mesh_cpp). Therefore read this section carefully (else you get lost in the reference manual):

There is no such thing like the %OpenMesh class

The library provides a set of classes ( 99% templates ;-) ), where the inheritance relationship is given by template parameterization. You might ask: "What the heck is that?" It means, a parent class is passed as a template argument to another class: \code class P1 { } class P2 { } template class B : public Parent {} typedef B fooB1; typedef B fooB2; \endcode Voila, we have created two different types of B. Depending on the interface, the public member elements, provided by \c P1 or \c P2, \c fooB1 and \c fooB2 might have different behaviours or even different interfaces! But if \c P1 and \c P2 have the some interface or at least a common interface, then from programming point of view there is no difference using \c fooB1 or \c fooB2. And this is all about. %OpenMesh defines an interface concept for the kernel which is documented in \ref OpenMesh::Concepts::KernelT. As long as the kernel provides this the class handling polygonal meshes \c OpenMesh::PolyMeshT can use any kernel.

Therefore documentation resides in two spaces

-# Associated with the class/struct (as usual) -# In a concept class in cases like the example code above. Hence, if you want to know what a mesh type has to offer refer to OpenMesh::Concepts::KernelT, OpenMesh::PolyMeshT, OpenMesh::TriMeshT. */ //----------------------------------------------------------------------------- /** \page mesh_features Features and Goals of OpenMesh The main features of the underlying data structure are: \li No restriction to triangles meshes, handle general polygonal meshes. \li Explicit representation of vertices, halfedges, edges, and faces. \li Efficient access to the one-ring neighborhood of a vertex. \li Ability to handle non-manifold vertices (like two faces meeting in only one vertex). The goals/features of the C++ implementation are:
  • Flexibility:
    • Choose suitable types for scalars and coordinates (e.g. float, double, exact arithmetic and two-, three-, or n-dimensional points).
    • Enhance each item type by your own attributes/properties, like e.g. adding a normal vector or a \c FaceHandle to class \c Vertex.
  • Efficiency:
    • Avoid the overhead of virtual inheritance and virtual function calls.
    • Resolve as many type/attribute dependencies as possible at compile-time instead of testing for attributes at run-time (e.g. normal vectors for faces).
  • Type-safety for handles, no type-casting (*): Vertices, (Half-)Edges, Faces know each other and their corresponding handles. (*) Since version 0.10.0 the Microsoft VisualC++ compiler is supported. Due to the compilers inaptitude to process forwards on template functions correctly, the type-safety had to be given up to some extend. Though under the hood void pointers are used, the casting is done within the mesh, and the user transparently uses his handles as before.
    As soon as the compiler adheres to the C++ standard the type-safe version will be restored.
*/ //----------------------------------------------------------------------------- /** \page mesh_cpp Some words on the C++ implementation If one takes a look at the goals and features section it soon becomes obvious that these goals cannot be achieved using trivial C++ features only. We make heavy use of templates, (partial) template specialization, generative and generic programming, and the STL. This may be a challenge for you as well as for your compiler, as these are quite late features of the C++ language. While knowledge of generative programming is only necessary if you want to create your own mesh kernels or extend iterators or similar types, you will \b NOT need it for simply using these things. Nevertheless working knowledge of C++ and basic knowlege of templates is required. To get into this stuff we recommend the following books: \li Bjarne Stroustrup, The C++ Programming Language , \li Matthew H. Austern, Generic Programming and the STL: Using and Extending the C++ Standard Template Library , \li Andrei Alexandrescu, Modern C++ Design: Generic Programming and Design Patterns Applied , \li Krzysztof Czarnecki, Ulrich Eisenecker, Generative Programming: Methods, Tools, and Applications . */ //----------------------------------------------------------------------------- /** \page mesh_hds The Halfedge Data Structure This section describes the underlying data structure that is used to store the mesh entities (items) vertices, edges, faces, and their connectivity information. There are many popular data structures used to represent polygonal meshes. For a detailed comparison of them refer to the papers at the end of this section. The data structure used in this project is the so called halfedge data structure . While face-based structures store their connectivity in faces referencing their vertices and neighbors, edge-based structures put the connectivity information into the edges. Each edge references its two vertices, the faces it belongs to and the two next edges in these faces. If one now splits the edges (i.e. an edge connecting vertex \c A and vertex \c B becomes two directed halfeges from \c A to \c B and vice versa) one gets a halfedge-based data structure. The following figure illustrates the way connectivity is stored in this structure:
\image html halfedge_structure3.png
  • Each \b vertex references one outgoing halfedge, i.e. a halfedge that starts at this vertex (1).
  • Each \b face references one of the halfedges bounding it (2).
  • Each \b halfedge provides a handle to
    • the vertex it points to (3),
    • the face it belongs to (4)
    • the next halfedge inside the face (ordered counter-clockwise) (5),
    • the opposite halfedge (6),
    • (optionally: the previous halfedge in the face (7)).
Having these links between the items, it is now possible to circulate around a face in order to enumerate all its vertices, halgedges, or neighboring faces. When starting at a vertex' halfedge and iterating to the opposite of its previous one, one can easily circulate around this vertex and get all its one-ring neighbors, the incoming/outgoing halfedges, or the adjacent faces. All this functionality is encapsulated into the so-called circulators , described in \ref mesh_iterators. \attention In order to efficiently classify a boundary vertex, the outgoing halfedge of these vertices must be a boundary halfedge (see OpenMesh::PolyMeshT::is_boundary()). \attention Whenever you modify the topology using low-level topology changing functions, be sure to guarantee this behaviour (see OpenMesh::PolyMeshT::adjust_outgoing_halfedge()) While one does not need to store the previous halfedge (7) explicitly, because it can be derived from the links to the next halfedges, one may do so for the sake of performance. In fact, the previous halfedge is stored by default (OpenMesh::DefaultTraits). Using traits and attributes the previous halfedge can removed, to gain memory. This kind of mesh customization is explained in \ref mesh_type. While the halfedge-based structures usually consume more memory than their face-based counter-parts they have the following important advantages: \li It is easy to mix faces of arbitrary vertex count in one mesh. \li We now have an explicit representation of vertices, faces, \em and edges/halfedges. This becomes extremely useful if one has to store data per edge/halfedge since this can easily be modelled by member variables of these types (see \ref mesh_type). \li Circulating around a vertex in order to get its one-ring neighbors is an important operation for many kinds of algorithms on polygonal meshes. For face-based structures this leads to many if-then branchings, the halfedge structure provides this funcionality without conditional branching in constant time. References S. Campagna, L. Kobbelt, H.-P. Seidel, Directed Edges - A Scalable Representation For Triangle Meshes , ACM Journal of Graphics Tools 3 (4), 1998. Lutz Kettner, Using Generic Programming for Designing a Data Structure for Polyhedral Surfaces, in Proc. 14th Annual ACM Symp. on Computational Geometry, 1998. */ //----------------------------------------------------------------------------- /** \page mesh_hierarchy Conceptual Class Hierarchy Since there is no such thing as a %OpenMesh class and the library makes heavy use of C++ template, we show the inheritance graph of OpenMesh::TriMesh_ArrayKernelT as proxy for all possible mesh types. Please note! Most of the inheritence relationships are realized by template parameterization! Therefore some of the inheritance links are not documented in a inheritance graph in the reference. This picture shows the overall concept. \image html class-hierarchy2.png \section ch_kernel Building the kernel -# The BaseKernel defines the basic operations on properties like add/remove/access. -# Next the AttribKernelT adds the standard properties all associated methods. -# Finally the ArrayKernelT provides the methods to add/remove/access the mesh items vertices, (half-)edges, and faces. The base class is passed as a template parameter, since depending on the underlying storage type the AttribKernel might change. \section ch_complete Building the mesh -# The PolyMeshT inherits from the kernel and provide all necessary methods to work with polygonal meshes. -# Finally we derive TriMeshT from PolyMeshT to have an specialization for triangle meshes. Looks simple, but it isn't - it's a bit more complicated: \include build-trimesh.cc To generate the actual mesh type the helper template class \c TriMesh_ArrayKernel_GeneratorT is used. It takes the traits in a template argument and passes it to \c FinalMeshItemsT to get the final type of the mesh items (MeshItems). The \c MeshItems defines the types for Point, Normal, Color, TexCoord, Vertex, and for all mesh items. With the help of \c MeshItems create the type of the \c AttribKernel, which defines the apropriate standard properties for the items. Finally use \c AttribKernel and \c MeshItems to create the mesh kernel type \c MeshKernel. It's quite a way to get a kernel . As long as the created kernel follows the kernel concept (\ref mesh_kernels_group), we can easily create now the mesh. Here we use now \c TriMeshT to create the final mesh type \c Mesh. */ //----------------------------------------------------------------------------- /** \page mesh_type Specifying your MyMesh This section will show how to build your own custom tailored type \c MyMesh. As we have seen in the section on goals and features there are some parameters to be specified for a mesh. This is done in the following four steps:
  1. Choose between triangle mesh and general polygonal mesh.
  2. Select the mesh kernel
  3. Parameterize the mesh by a so-called \em Traits class. You can add arbitrary classes to the mesh items, specify the types \c Scalar, \c Point, \c Normal and \c Color, and use predefined attributes like \c Attributes::Normal and \c Attributes::Color.
  4. Dynamically bind data to the mesh or the mesh entities (vertex, (half-)edge, face) using \em custom \em properties.
We will explain these four parameterization steps and give a code example at the end of this page.

\section sec_select_face_type Polygonal or Triangle Mesh? This decision is quite simple: Whenever possible choose the triangle mesh. The restriction to triangular faces usually leads to more efficient algorithms (e.g. rendering triangles is much faster than rendering arbitrary polygons). Additionally some algorithms are only implemented for triangle meshes while triangle meshes inherit the full functionality of polygonal meshes. For a list of them refer to the following links. \see OpenMesh::PolyMeshT \see OpenMesh::TriMeshT

\section sec_select_kernel Choosing the right kernel The mesh kernel specifies how the mesh entities (vertices, (half-)edges, faces) are internally stored. In fact the entities are kept in so-called properties. A property itself provides an array like interface. The kernel defines the corresponding handle types, i.e. the way items reference each other. Since the properties have an array like interface the handles are represented internally as indices. The default kernel is \c ArrayKernelT. Which is good for most situations. But depending on the application a different kernel would be better. E.g. the OpenSG integration has been realized be replacing the kernel by a custom kernel, since OpenSG provides already array like properties, which could be reused for the intergration. In case of a an OpenSG environment one might be better off using \c OSG_Kernel::ArrayKernelT. \see \ref mesh_kernels_group

\section sec_select_traits Mesh Traits While the last two sections only have chosen from a list of predefined meshes or kernels, respectively, we now come to the user-defined customization. The resulting mesh \c MyMesh will provide the following types:
  • The point and scalar type: \c MyMesh::Point and \c MyMesh::Scalar.
  • The mesh items: \c MyMesh::Vertex, \c MyMesh::Halfedge, \c MyMesh::Edge, \c MyMesh::Face.
  • The handle types: \c MyMesh::VertexHandle, \c MyMesh::HalfedgeHandle, \c MyMesh::EdgeHandle, \c MyMesh::FaceHandle.
While the handle types are fixed, the other types can be customized. Each mesh type (see \ref mesh_types_group) can be parameterized by a so-called \em traits class. Using this mechanism one can
  1. change the coordinate type \c MyMesh::Point and the resulting scalar type \c MyMesh::Scalar == \c MyMesh::Point::value_type,
  2. change the normal type \c MyMesh::Normal
  3. change the color type \c MyMesh::Color
  4. use predefined attributes like normal vector, color, texture coordinates, ... for the mesh items.
  5. add arbitrary classes to the mesh items.
All these customizations are encapsulated in one class \c MyTraits, that is used as template argument to the mesh, e.g. \code struct MyTraits { // your customization }; typedef PolyMesh_ArrayKernelT MyMesh; \endcode The rest of this section explains the construction of this traits class, its application to the mesh will be the topic of the next section. For each mesh entity one can control the predefined attributes to be attached by a traits class using some convenience macros, e.g. \c OpenMesh::VertexAttributes and \c OpenMesh::VertexTraits for vertices. The default traits class looks like this: \include traits0.cc Please note that for example \c VertexTraits is a define concealing a template declaration. The actual template class name is \c VertexT, which is further simplified to a specific type \c Vertex at a later stage during the construction of the mesh kernel. Because the traits classes always have to provide the template classes \c VertexT, \c HalfedgeT, \c EdgeT, \c FaceT, and the types \c Point, \c Normal, \c Color, and \c TexCoord one should derive this class from the default implementation \c DefaultTraits. In this case you will only have to define the classes or types you want to override or substitute.
\subsection sec_change_point Changing the Point type Changing the type that is used to store the point coordinates as well as the normal vectors can simply be done by defining this type in the traits class. The following code changes the coordinate type in order to use \c double instead of \c float. \include traits1.cc Using the OpenMesh::VectorT class you can easily plug in any scalar type for the use in point coordinates, e.g. some exact arithmetic. You can also exchange the whole class representing points as long as it provides the same interface as the OpenMesh::VectorT class.
\subsection sec_add_attributes Adding Predefined Attributes There are some pre-defined attributes that can be appended to the mesh items. These global attributes are defined in the namespace OpenMesh::Attributes. The advantage of these attributes is that they are registered at the items they are added to. Therefore algorithms can check for these attributes at run-time as well as at compile-time. This is important if you want to implement algorithms acting on different meshes, that may or may not have e.g. normal vectors per vertex/face. Adding these predefined attributes is quite simple. You provide an unsigned int in the traits class, whose bits control whether or not a certain attribute should be attached or not. If you want to add a normal vector to your vertices and faces, and also want to have color information for vertices, the code would look like this: \include traits5.cc Internally each mesh item contains an \c enum defining the integer \c Attributes (containing the bits of used attributes OR'ed together). From its set/unset bits you can see whether a certain attribute is used. OpenMesh provides the macro OM_Check_Attrib for doing this: \code if (OM_Check_Attrib(MyMesh::Vertex, Normal) do_something_with_normals(); \endcode These run-time checks may not be sufficient in some cases. You can also check for attributes at compile-time and instantiate the correct functions by using function overloading. The class \c GenProg::Bool2Type maps true/false information to two different types, \c Bool2Type and \c Bool2Type. An example that draws OpenGL normals if they are available would look like this: \include draw_normals.cc Especially the compile-time checking for attributes is extremely useful because it does not generate any unnecessary code and does not perform expensive tests at run-time. \see OpenMesh::DefaultTraits \see OpenMesh::Attributes \see OpenMesh::GenProg
\subsection sec_add_traits Adding User-Defined Elements You can also add arbitrary types/elements/methods to the mesh items by providing a corresponding traits class for these items. Adding some index to the \c Vertex class is easily done by \include traits2.cc The macro \c VertexTraits hides some ugly template stuff. In fact, it is defined as \code #define VertexTraits template struct VertexT : public Base \endcode hence the traits class actually looks like this: \include traits3.cc You have to keep this in mind when you want to define constructors for your vertex type or when you want to derive the vertex type from other classes. The template argument \c Base provides access to the mesh handles and to the \c Point and \c Scalar type by its member class \c Refs. Adding a \c MyMesh::FaceHandle to the vertex class can therefore be implemented like this: \include traits4.cc Adding elements to other mesh items works in the same manner.
\subsection sec_algo_traits Using traits defined by algorithms From version 0.10.3 on algorithms can define traits/attributes they require and the user can merge these traits into his own traits. A more elegant way is to use dynamic properites, which can be added/removed during runtime by the algorithm. This is the preferred way to attach custom data to the mesh. An example for an algorithm as well as the application using traits is given in \ref tutorial_06.

\section sec_properties Dynamic Properties From version 1.0 on %OpenMesh provides dynamic properties. Instead of using traits to bind data at compile time algorithms or the application can use dynamic properties. Similar to entities the properties are accessed and manipulated via handles. An example for an algorithm as well as the application using properties is given in \ref tutorial_03 and \ref tutorial_04.

\section sec_traits_example Final Implementation Example Consider an application where we just want to render triangle meshes. This means we will select the triangle mesh and the \c ArrayKernelT. Faces that are not triangles will automatically be tesselated into triangles. Because we only display meshes and do not dynamically add or remove items, we can just use the \c ArrayKernelT. All mesh-kernel combinations are predefined in the directory %OpenMesh/Mesh/Types. Refer to \ref mesh_types_group for a complete list of them. For our example we use the \c TriMesh_ArrayKernelT and parameterize it by our \c MyTraits class. We will need face and vertex normals and e.g. for color coding vertex curvature, i.e. vertex color. \include mymesh.cc That's it. */ //----------------------------------------------------------------------------- /** \page mesh_eigen Specifying an OpenMesh using Eigen3 vectors This section will show how to build your own custom mesh type using Eigen3 vectors for points, normals or other entities. First of all you need to include the Eigen header shipped with OpenMesh: \code #include \endcode This header contains the external functions and vector traits used by OpenMesh. Afterwards you can specify your mesh: \code struct EigenTraits : OpenMesh::DefaultTraits { using Point = Eigen::Vector3d; using Normal = Eigen::Vector3d; using TexCoord2D = Eigen::Vector2d; }; using EigenTriMesh = OpenMesh::TriMesh_ArrayKernelT; EigenTriMesh mesh; \endcode Now you can use mesh as any other OpenMesh while using Eigen vectors as the underlying data type. \note OpenMesh uses stl vectors for storing its data. This might lead to errors regarding memory alignment with sse instructions: http://eigen.tuxfamily.org/dox/group__TopicStlContainers.html You might need to define -DEIGEN_DONT_VECTORIZE */ //----------------------------------------------------------------------------- /** \page mesh_members Where do I find a list of all member functions ? The following picture shows the (simplified) conceptual inheritance diagram for the %OpenMesh classes. \image html inheritance-simple.scaled.png The basis for all meshes is the corresponding \c MeshKernel, taking care of the internal storage of the mesh items (vertices, (half-)edges, faces). This kernel is inherited by the \c PolyMeshT, i.e. the general polygonal mesh, adding higher level functionality. For specialization purposes the class \c TriMeshT is derived from \c PolyMeshT and overrides some member functions or adds functions only suitable for pure triangle meshes. In most cases a class (e.g. \c PolyMeshT) gets the class it should derive from (e.g. the mesh kernel) as a template parameter. The documentation class OpenMesh::Concepts::MeshKernel::KernelT lists the minimal interface a mesh kernel must provide. Special kernels may provide some more functionality, in this case refer to this kernel's documentation (see \ref mesh_kernels_group). Therefore your mesh provides the pubic member functions of
  • The mesh kernel.
  • The general polygonal mesh.
  • The specialized triangle mesh (if you use a TriMesh instead of a PolyMesh).
\see OpenMesh::Concepts \see OpenMesh::Concepts::KernelT \see OpenMesh::PolyMeshT \see OpenMesh::TriMeshT */ //----------------------------------------------------------------------------- /** \page mesh_io Read and write meshes from files This section explains the methods used to read a mesh from a file or write it to a file. The corresponding functions are defined in the namespace OpenMesh::MeshIO. This section is divided into three steps. Step one will give a short example on how to use the %OpenMesh IOManager, step two will give some background information on how IOManager works and finally step three will show you how to add your own modules to IOManager. A tutorial with more information regarding file IO can be found here: \ref tutorial_08 \section mesh_io_quick Step 1 - IOManager quick start For a quick start you can copy the following code directly to your project. \note
  • If you link statically against OpenMesh, you have to add the define OM_STATIC_BUILD to your application. This will ensure that readers and writers get initialized correctly.
  • IOManager uses the filename extension to determine which reader/writer to use. I.e. if passing "inputmesh.obj" as filename parameter, the OBJ-File reader/writer will be used to parse/write the file.
\include mesh_io.cc

\section mesh_io_theory Step 2 - The theory behind IOManager Usually mesh reader and writer routines are written directly against the data structure and the respective file format they support. This approach has the main disadvantage that targeting a different data structure or adding another file format leads to duplication of code. IOManager acts as an interface between persistent data on one side and an arbitrary data structure on the other side by means of reader/writer and importer/exporter modules. This is illustrated by the following diagramm : \image html iomanager.png
Persistent data of arbitrary format is first interpreted by a reader module. The data is then passed - by means of a specified interface - to an importer module for the target data structure. The process for writing data is analogous. The IOManager controls the entire process. Reader/Writer modules are invisible to the user. Importer/Exporter however have to be specified explicitely as they are specific to a data structure. The complete separation of data structure and persistent data makes it especially easy to maintain existing code and to extend funtionality at both ends as will be shown in step three. \see OpenMesh::IO::_IOManager_

\section mesh_io_extend Step 3 - How to extend IOManager \subsection mesh_io_extend_fileformat Adding support for a new file format Adding support for a new file format involves adding a reader and writer module. Reader modules are classes derived from OpenMesh::IO::BaseReader. The part of the interface that you usually have to define is shown below. \include BaseReader.hh Based on the file extension or the header information the IOManager decides which reader module to use. The reader then parses the format and the information will be passed to the target data structure be means of a class derived from OpenMesh::IO::BaseImporter. Writer modules are derived from OpenMesh::IO::BaseWriter and work the same way as reader modules.
\subsection mesh_io_extend_datastruct Adding support for a new data structure As we have already seen, Importers receive information from the reader modules. Reader modules pass information through a specified interface : \include BaseImporter.hh The Importer is then responsible for filling the target data structure. Exporting information from a data structure is a little bit more involved than importing data to it. The writer modules must be able to iterate over all vectors/texcoords/faces. Therefore an exporter has to provide these iterators : \include BaseExporter.hh There might be the need for the exporter to cache data from the structure it refers to. The update() function should be called at the beginning of each BaseWriter::save() method and it should make sure that cached information is up to date. For further information you are encouraged to take a look at the modules provided by %OpenMesh which can be found in the IO subdirectory. */ //----------------------------------------------------------------------------- /** \page mesh_iterators Mesh Iterators and Circulators - \ref it_iters - \ref it_iters_h - \ref it_iters_skipping - \ref it_circs - \ref it_circs_h \section it_iters Iterators The mesh provides linear iterators (that enumerate vertices, halfedges, edges, and faces). These can be used to easily navigate through a mesh. Each iterator \c XYZIter also exists in a const version \c ConstXYZIter. All iterators are defined in the namespace OpenMesh::Iterators. They are template classes that expect a mesh as template argument to be fully specified. You should use the iterator types provided by the mesh itself, i.e. \c MyMesh::VertexIter instead of \c OpenMesh::Iterators::VertexIterT. The iterators are: \include iterators.cc The corresponding \c const counterparts are \arg \c ConstVertexIter, \arg \c ConstHalfedgeIter, \arg \c ConstEdgeIter, \arg \c ConstFaceIter. The linear iterators are conformant to STL iterators. For a description of their interface see OpenMesh::Concepts::IteratorT. When using iterators, use the pre-increment operation (++it) for efficiency reasons. \deprecated While it is possible to use \c handle() to get the handle of the item referred to by the iterator, this function is deprecated. Simply dereference the iterator instead. \subsection deletedElements Deleted Elements If no elements of a mesh are marked as deleted, the indices provided by \c idx() are consecutive numbers from 0 to number of elements-1 (in the case of vertices this would be from 0 to n_vertices()-1). However, note that this is not the case when elements are marked as deleted and OpenMesh::ArrayKernel::garbage_collection() has not yet been called. After garbage_collection() has been called the elements are reorganized and their handles and iterators are guaranteed to be consecutive numbers again. OpenMesh uses a lazy deletion scheme to avoid unnecessary updates to the data structure. The halfedge data structure will always be updated directly to ensure that following algorithms will have the correct iterator setups. So if you delete a face, The face itself will still exist but the halfedges which are now located at the hole will be updated directly, which means that circulators on the adjacent vertices will not come across the face anymore. If an edge is deleted, the adjacent faces will be removed as well (flagging them deleted and updating the surrounding halfedges). The edge itself will also be flagged as deleted. Again the circulators will not see the deleted primitives anymore. For a vertex, all adjacent faces and edges are deleted with the schemes above and the vertex flagged as deleted. The iterators, going across vertices edges and faces will still enumerate all primitives (including deleted ones). Except if you use the skipping iterators, which will skip deleted primitives. The circulators always only enumerate primitives which are not deleted. \note
  • If you delete elements on the mesh, they will still be enumerated by the standard iterators. To skip deleted elements, use the \ref it_iters_skipping
  • An iterator to an item usually needs more memory than a handle of an item. To store many references to an item, it is therefore better to use handles.
\section it_iters_h How to use iterators in OpenMesh This example shows how to iterate over all faces of a mesh: \code MyMesh mesh; for(MyMesh::FaceIter f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it) { std::cout << "The face's valence is " << mesh.valence( *f_it ) << std::endl; } \endcode \section it_iters_skipping Skipping Iterators All iterators are also available as skipping iterators. If elements are deleted on a mesh, the standard iterators go over all elements, even deleted ones(which are available until a garbage_collection is done). The skipping iterators ignore these elements. You can retrieve a skipping iterator by calling one of the following functions: \arg \c vertices_sbegin(), \arg \c edges_sbegin(), \arg \c halfedges_sbegin(), \arg \c faces_sbegin() The ends for these iterators are equal to the standard iterator ends (e.g. \c vertices_end() ). \section it_circs Circulators %OpenMesh also provides so called Circulators that provide means to enumerate items adjacent to another item of the same or another type. For example, a \c VertexVertexIter allows to enumerate all vertices immediately adjacent to a (center) vertex (i.e. it allows to enumerate the so-called 1-ring of the center vertex). Analogously, a \c FaceHalfedgeIter enumerates all the halfedges belonging to a face. In general, \c CenterItem_AuxiliaryInformation_TargetItem_Iter designates a circulator that enumerates all the target items around a given center item. The constructor of a circulator is of the form \c Circulator(MeshType mesh, TargetHandle center_handle), i.e. it takes a mesh and the handle of the item to circulate around. The circulators around a vertex are: \arg \c VertexVertexIter: iterate over all neighboring vertices. \arg \c VertexIHalfedgeIter: iterate over all \em incoming halfedges. \arg \c VertexOHalfedgeIter: iterate over all \em outgoing halfedges. \arg \c VertexEdgeIter: iterate over all incident edges. \arg \c VertexFaceIter: iterate over all adjacent faces. The circulators around a face are: \arg \c FaceVertexIter: iterate over the face's vertices. \arg \c FaceHalfedgeIter: iterate over the face's halfedges. \arg \c FaceEdgeIter: iterate over the face's edges. \arg \c FaceFaceIter: iterate over all edge-neighboring faces. The circulators around an edge are: \arg \c EdgeVertexIter: iterate over the edge's incident vertices. \arg \c EdgeHalfedgeIter: iterate over the edge's halfedges. \arg \c EdgeFaceIter: iterate over the edge's incident faces. Other circulators: \arg \c HalfedgeLoopIter: iterate over a sequence of Halfedges. (all Halfedges over a face or a hole) All circulators provide the operations listed in CirculatorT, which are basically the same as the iterator funtions. \note Circulators are similar to bidirectional iterators and therefore they have the bidirectional_iterator_tag. However, the bidirectional requires that the attribute OpenMesh::Attributes::PrevHalfedge is available. Otherwise it is just a forward iterator. \deprecated While it is possible to use \c operator \c bool(), which returns true, as long as the circulator hasn't reached the end of the sequence, this function is deprecated. Use the function \c is_valid() instead. %OpenMesh provides the following functions (defined in OpenMesh::PolyConnectivity) to get circulators around a specified center item: \include circulator_functions.cc Additionally to the normal circulators there exists some for each direction (clock-wise, counterclock-wise). Those circulators might be slower than the normal one, but the direction of circulation is guaranteed. You can get these types of circulators by adding the infix "ccw" or "cw" to the function used to request the circulator of an item after the underscore. Example: \code VertexVertexIter vvit = mesh.vv_iter(some_vertex_handle); // fastest (clock or counterclockwise) VertexVertexCWIter vvcwit = mesh.vv_cwiter(some_vertex_handle); // clockwise VertexVertexCCWIter vvccwit = mesh.vv_ccwiter(some_vertex_handle); // counter-clockwise \endcode It is also possible to convert a cw circulator to a ccw circulator and vice versa. For this purpose, each circulator provides a constructor taking the other circulator as input. If a cw circulator is converted, the ccw circulator points on the same element as the cw circulator pointed on, but the direction for the increment and decrement changed.\n The conversion is only valid for valid circulators. The resulting circulator from a invalid circulator is still invalid, but might behave in a fashion not expected by normal iterators. Example: \code VertexVertexCWIter vvcwit = mesh.vv_cwend(some_vertex_handle); VertexVertexCCWIter vvccwit = VertexVertexCCWIter(vvcwit); //conversion of an invalid circulator --vvcwit; //is valid now (if the range >= 1) ++vvccwit; //can still be invalid \endcode CW and CCW circulators requires that OpenMesh::Attributes::PrevHalfedge is available. \note For every circulator there also exists a constant version. To make use of these constant circulators just add the prefix
"Const" to the type specifier and add the prefix "c" to the function used to request the circulator of an item. Example:
\code ConstVertexVertexIter cvvit = mesh.cvv_iter(some_vertex_handle); \endcode \note When constructing Circulators from iterators, make sure you don't create a circulator of an deleted element(e.g. FaceVertexiter of a deleted Face), as this will lead to unpredictable behaviour. Using skipping iterators for iterating over the elements and creating circulators from them is safe as they don't contain deleted elements. \section it_circs_h How to use circulators in OpenMesh The following code example now shows how to enumerate the 1-ring of each vertex: \include circulators.cc Enumerating all halfedges adjacent to a certain face (the inner halfedges) is accomplished as follows: \code MyMesh mesh; ... // Assuming faceHandle contains the face handle of the target face MyMesh::FaceHalfedgeIter fh_it = mesh.fh_iter(faceHandle); for(; fh_it.is_valid(); ++fh_it) { std::cout << "Halfedge has handle " << *fh_it << std::endl; } \endcode */ //----------------------------------------------------------------------------- /** \defgroup mesh_property_handle_group Mesh Property Handles All custom properties are represented by the property handles. The handle mechanism allows to add arbitrary data to the mesh items. It stores the value type (by construction) and a 'reference' to the property. Use the mesh object to access the property values. \see OpenMesh::PropertyT, OpenMesh::BaseKernel, OpenMesh::Concepts::KernelT, \ref tutorial_03, \ref tutorial_04, \ref tutorial_09 */ //----------------------------------------------------------------------------- /** \defgroup mesh_kernels_group Mesh Kernels This group holds all mesh kernels. Since %OpenMesh makes heavily use of templates especially in the kernels, there's no direct inheritence relationship of the kernel classes. For a conceptual overview of the inheritance graph see \ref mesh_hierarchy. For a list of available methods see OpenMesh::Concepts::KernelT. \see \ref mesh_hierarchy, OpenMesh::Concepts::KernelT */ //----------------------------------------------------------------------------- /** \defgroup mesh_types_group Predefined Mesh Types This group holds all the predefind mesh types, i.e. all combinations of triangle/polygonal mesh and the set of kernels. */ //----------------------------------------------------------------------------- /** \defgroup mesh_concepts_group Interface Concepts Since for many classes no virtual inheritace is used one can't enforce a specific interface by pure virtual functions. Therefore these interfaces will be described in this group. Everyone implementing e.g. a new mesh kernel should at least implement the OpenMesh::Concepts::Kernel concept. */ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/tutorial_03.docu0000660000174600017460000001223314556675336021176 0ustar gitlab-runnergitlab-runner/** \page tutorial_03 Using (custom) properties This examples shows: - How to add and remove custom properties - How to get and set the value of a custom property In the last example we computed the barycenter of each vertex' neighborhood and stored it in an array. It would be more convenient and less error-prone if we could store this data in the mesh and let %OpenMesh manage the data. It would be even more helpful if we could attach such properties dynamically to the mesh. Custom properties can be conveniently created and attached to meshes by creating an object of type OpenMesh::PropertyManager. A PropertyManager manages the lifetime of the property and provides read / write access to its values. You can use the typedefs VProp, HProp, EProp, FProp, and MProp in order to create a PropertyManager attached to vertices, halfedge, edges, faces and the mesh respectively. Each of these takes as template argument the type of the property value that is attached to each element (e.g., \p int, \p double, etc.). We differentiate between two kinds of properties. Named and temporary properties. Temporary properties are created by just providing the constructor with a mesh on which the property should be created. These properties will be removed as soon as the PropertyManager goes out of scope. If in addition to the mesh a property name is provided, a named property will be created which will stay alive even after the PropertyManager goes out of scope. If a PropertyManager is given a name of an already existing property, it will provide read and write access to the same property. Finally, an optional first parameter can be given containing a value that will be used to initialize the property for all elements if the property is freshly created (i.e. always for temporary properties, and only the first time a specific name is used). Here are a few examples of how to create and access mesh properties: \code // Add a temporary mesh property that stores a double value for every vertex auto temperature = OpenMesh::VProp(mesh); OpenMesh::VertexHandle vh = ...; temperature[vh] = 1.0; // The temperature property will be removed from the mesh when the handle reaches the end of the scope. // Obtain an existing property that stores a 2D vector for every halfedge // (or create that property if it does not exist already) and initilize it with the Vector(1,1)) auto uv = OpenMesh::HProp(mesh, "uv", OpenMesh::Vec2d(1,1)); OpenMesh::VertexHandle heh = ...; std::cout << temperature[heh][0] << " " << temperature[heh][1] << std::endl; // Obtain an existing mesh property (or create that property if it does not exist already) // containing a description string auto desc = OpenMesh::MProp(mesh, "desc"); *desc = "This is a very nice mesh."; \endcode --- ## Code Example In this example, we will store the \c cog value (see previous example) in a vertex property instead of keeping it in a separate array. To do so, we first add a (temporary) property of the desired element type (OpenMesh::VertexHandle) and value type (\c %MyMesh::Point) to the mesh: \dontinclude 03-properties/smooth.cc \skipline VProp Enough memory is allocated to hold as many values of \c %MyMesh::Point as there are vertices. All insert and delete operations on the mesh are synchronized with the attached properties. Once the property is created, we can use it to compute the centers of the neighborhood of each vertex: \skipline mesh.vertices \until cog[vh] /= valence \until } Finally, we set the new position for each vertex: \skipline mesh.vertices \until mesh.point \until } Below is the complete source code: \include 03-properties/smooth.cc --- ## Property Lifetime In the above example, we chose to use VProp without a name. This causes the created property to automatically be removed from the mesh as soon as we leave the scope of the associated handle variable \c cog. If, instead, a property is desired to survive its local scope, it should be created with a name. For example: \code auto face_area = OpenMesh::FProp(mesh, "face_area"); \endcode At a later time, we can access the same property by using the same name. If we want to make sure, that we access a property that has already been created earlier, we can use hasProperty() to test whether a mesh has the desired property: \code if (OpenMesh::hasProperty(mesh, "face_area")) { // Property exists. Do something with it. auto valley = OpenMesh::FProp(mesh, "face_area"); } else { // Property does not exist. Do something else. } \endcode --- ## Low-Level Property API The property managers VProp, HProp, EProp, FProp and MProp are the convenient high-level interface for creating and accessing mesh properties. Beneath these convenience functions, there is also a low-level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh's add_property(), get_property(), remove_property(), and property() functions and several property handle classes (OpenMesh::VPropHandleT, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT, OpenMesh::FPropHandleT, OpenMesh::MPropHandleT). --- */ OpenMesh-11.0.0/Doc/tutorial_06.docu0000660000174600017460000000620114556675336021177 0ustar gitlab-runnergitlab-runner/** \page tutorial_06 Using mesh attributes and traits this example shows how to change the data type for positions, normals, colors, and texture, In the previous tutorial (\ref tutorial_05) we learned to use standard properties by calling the appropriate \c request method. Unlike the custom properties, where the user specifies the data type by passing the type to the handle (e.g. \c MyMesh::FPropHandleT< int>), the data types of the standard properties are defined by so-called mesh traits. With traits we can customize and extend the mesh data structure. We can do this by changing two important features -# changing data type for positions, normals, colors, and texture coordinates -# extend mesh entities Vertex, Face, Edge, and Halfedge (see tutorial '\ref tutorial_07') Let's start. Every custom traits should derive from the default traits \dontinclude 06-attributes/attributes.cc \skipline struct MyTraits As mentioned, we can change the basic data types for the basic types \c MyMesh::Point, \c MyMesh::Normal, \c MyMesh::Color, and \c MyMesh::TexCoord. We can use the provided vector class or we use a different one from another library. Here we simply replace the default type \c OpenMesh::Vec3f (defined in the \c OpenMesh::DefaultTraits) for positions and normals with \c OpenMesh::Vec3d \skipline Vec3d \skipline Vec3d (In general it's better to have the same scalar type for the point and normal vector, for instance \c double in this case. Otherwise we have to cast quite a lot depending on the implementation of the vector class.) Be aware that these settings overwrite the ones of the parent traits class! As we usually derive from the DefaultTraits let's have a close look. Actually the struct \c OpenMesh::DefaultTraits is merely empty. It solely defines the types for \c Point, \c Normal, \c TexCoord, and \c Color and one attribute, that we used implicitly all the time: \skipline HalfedgeAttributes The attribute \c PrevHalfedge is different, as it does not control a property. Yet it has a great impact on the resulting mesh type, as it adds additional information to the halfedge structure. The impact is twofold: -# fast access to previous halfedge -# increase of memory consumption Using this feature depends highly on our needs. One situation where the previous halfedges are quite handy, is the mesh member function add_face(). The execution time for the member function drops dramatically, when the information about the previous halfedge is available. Usually we want to have this information. But if not, because we must save memory, we can easily remove it with \skipline HalfedgeAttributes Then we need 8 bytes less per edge, which can be quite a lot as one can derive from the Euler formula (\f$V-E+F=2 (1-g)\f$), that for a regular triangle meshes with genus \f$g=0\f$ the number of edges \f$E\f$ is approximately three times the number of vertices \f$V\f$: \f$ E \approx 3 \cdot V\f$. The complete source looks like this: \include 06-attributes/attributes.cc */OpenMesh-11.0.0/Doc/tutorial_01.docu0000660000174600017460000000440214556675336021173 0ustar gitlab-runnergitlab-runner/** \page tutorial_01 First Steps - Building a cube This small example shows: \li How to declare your type \c MyMesh, \li How to add vertices and faces to a mesh, \li How to write a mesh using the IO functions. For each program the first step is to define your type \c MyMesh. %OpenMesh supports general polygonal meshes (faces are polygons with varying number of vertices) as well as specialized triangle meshes (all faces are triangles). In this example we want to build a cube from six quadrangles, therefore we choose the polygonal mesh. %OpenMesh also supports different mesh kernels, specifying how all the vertices, edges, and faces are stored internally (see also \ref mesh_kernels_group). However, the storage must provide an array like interface. For the tutorial we use the supplied ArrayKernel. The predefined combinations of TriMesh/PolyMesh and the kernel are contained in \c %OpenMesh/src/OpenMesh/Core/Mesh, we use the PolyMesh_ArrayKernelT. \dontinclude build_cube.cc \skipline PolyMesh_ArrayKernel \skipline MyMesh Now since we have declared our type \c MyMesh, we only have to add 8 vertices and 6 quadrangles to build a cube. Adding a vertex is done using the add_vertex method. It gets a coordinate and returns a handle to the inserted vertex. We store all handles in an array, since we need them for specifying the faces. \skipline vhandle[0] \until vhandle[3]
In order to add a face to the mesh, we have to build a vector holding the handles to the face's vertices. This vector is passed to the \c add_face method. The following block will create a face from the first four vertices: \skipline face_vhandles \until add_face
The orientation of the face is defined by the order in which the vertices are given: If you look at the frontfacing side of the polygon, then the vertices are in counter-clockwise order. After creating all of the six faces, we want to write the resulting mesh to standard output. %OpenMesh provides some basic input/output methods in the namespace OpenMesh::IO: \skipline write_
To use the IO facility of %OpenMesh make sure that the include MeshIO.hh is included first. \dontinclude build_cube.cc \skipline MeshIO \until PolyMesh_ArrayKernel
The complete source looks like this: \include build_cube.cc **/ OpenMesh-11.0.0/Doc/mainpage.docu0000660000174600017460000000747214556675336020623 0ustar gitlab-runnergitlab-runner/** \if OPENMESH_INTERNAL_DOC \mainpage OpenMesh Documentation \else \page OpenMeshDoc OpenMesh Documentation \endif \image html OpenMesh_text_128.png Welcome to the %OpenMesh documentation. %OpenMesh is a generic and efficient library that offers data structures for representing and manipulating polygonal meshes. It is a powerful tool for handling polygonal meshes. Due to its inherent generative structure it allows the user to create mesh types which are custom tailored to the specific needs of the application. The user can either supply his own data structures for representing vertices, edges and faces or he can conveniently use the predefined structures of %OpenMesh. Additionally %OpenMesh offers dynamic properties allowing the user to attach and detach data to the mesh during runtime. Here you can find information on how to build projects using the %OpenMesh library as well as further information on mesh handling in %OpenMesh. The tutorials explain how to use %OpenMesh by demonstrating real code examples. \section openmesh-python OpenMesh Python Bindings We also provide python bindings for %OpenMesh. You can find them here:
https://gitlab.vci.rwth-aachen.de:9000/OpenMesh/openmesh-python \section iov Building OpenMesh In this section all necessary information on how to build projects using %OpenMesh is given. \li \subpage compiling \li \subpage compiling_tests

\subpage mesh_docu We provide a short overview over the functionality of the %OpenMesh library and some additional concepts in \ref tutorial. Additionally, we explain the most important topics of %OpenMesh in the following sections: \li \ref mesh_features \li \ref mesh_hds \li \ref mesh_iterators \li \ref mesh_navigation \li \ref mesh_io \li \ref mesh_operations \li \ref mesh_hierarchy The %OpenMeshTools library that contains some useful tools for i.e. mesh processing: \li \subpage tools_docu

\subpage tutorial This section is supposed to introduce the basic concepts of %OpenMesh. \li \ref mesh_type \li \ref tutorial_01 \li \ref tutorial_build \li \ref tutorial_build_internal_apps \li \ref tutorial_02 \li \ref tutorial_03 \li \ref tutorial_04 \li \ref tutorial_11 \li \ref tutorial_12 \li \ref tutorial_05 \li \ref tutorial_06 \li \ref tutorial_07 \li \ref tutorial_07b \li \ref tutorial_08 \li \ref tutorial_09 \li \ref tutorial_10

\subpage additional_information \li \ref mesh_first_to_read \li \ref mesh_cpp \li \ref mesh_members \li \ref naming_conventions \li \ref mesh_speedup \li \ref om_changelog \page mesh_docu Using and understanding OpenMesh \li \subpage mesh_features \li \subpage mesh_hds \li \subpage mesh_iterators \li \subpage mesh_navigation \li \subpage mesh_io \li \subpage mesh_operations \li \subpage mesh_hierarchy \li \subpage mesh_type \li \subpage mesh_eigen \page additional_information Additional Information on OpenMesh \li \subpage mesh_first_to_read \li \subpage mesh_cpp \li \subpage mesh_members \li \subpage naming_conventions \li \subpage mesh_speedup \li \subpage om_changelog **/ OpenMesh-11.0.0/Doc/subdivider.docu0000660000174600017460000000232514556675336021172 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page subdivider_docu Sudivision Tools \section OM_Subdivider_Overview Overview The %OpenMesh library provides a few tools for uniform and adaptive subdivision: -# Uniform subdivision -# OpenMesh::Subdivider::Uniform::LoopT -# OpenMesh::Subdivider::Uniform::Sqrt3T -# OpenMesh::Subdivider::Uniform::ModifiedButterflyT -# OpenMesh::Subdivider::Uniform::InterpolatingSqrt3LGT -# OpenMesh::Subdivider::Uniform::CompositeT -# OpenMesh::Subdivider::Uniform::CatmullClarkT -# OpenMesh::Subdivider::Uniform::MidpointT -# Adaptive subdivision -# OpenMesh::Subdivider::Adaptive::CompositeT -# Simple subdivision -# OpenMesh::Subdivider::Uniform::LongestEdgeT \section OM_Subdivider_Usage Usage The subdividers directly work on an OpenMesh. The following example shows how to use them: \code #include // Initialize subdivider OpenMesh::Subdivider::Uniform::CatmullClarkT catmull; // Execute 3 subdivision steps catmull.attach(mesh_); catmull( 3 ); catmull.detach(); \endcode */ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/tutorial_09.docu0000660000174600017460000000521114556675336021202 0ustar gitlab-runnergitlab-runner/** \page tutorial_09 Using custom properties (old style) This small code example shows how to attach and access additional properties on a mesh. Note that this is an old style of using properties. Nowadays you should use the OpenMesh::PropertyManager instead. When you want to add an additional properties you have to attach it to a primitive of the mesh. You can attach to verticies, halfedges, edges, faces or to the mesh itself. Use the add_property function: \code // for each vertex an extra double value OpenMesh::VPropHandleT< double > vprop_double; mesh.add_property( vprop_double ,"Vertex property name"); // for each halfedge an extra int value OpenMesh::HEPropHandleT< int > heprop_int; mesh.add_property( heprop_int ,"Halfedge property name"); // for each edge an extra float value OpenMesh::EPropHandleT< float > eprop_float; mesh.add_property( eprop_float ,"Edge property name"); // for each face an extra double value OpenMesh::FPropHandleT< double > fprop_double; mesh.add_property( fprop_double ,"Face property name"); // for the mesh an extra string OpenMesh::MPropHandleT< string > mprop_string; mesh.add_property( mprop_string , "Mesh property name "); \endcode Accessing to the property is available via the property function. This function gets the property handle (created above) and a handle (e.g. to a vertex or a face): \code // Write something to a face property: mesh->property( , ) = ; // E.g. for (f_it=mesh->faces_begin(); f_it!=mesh->faces_end() ; ++f_it) { mesh->property( fprop_double , *f_it ) = 0.0; } \endcode As you can attach properties to the mesh, you might want to add a property in one function and access it in another, where the handle is not yet available. You can retrieve the required handle in the following way (Note that the handles are accessed by their name and type): \code // Specify handle type (Double face handle in this case): OpenMesh::FPropHandleT< double > fprop_double; // Try to get handle with the given name. if ( !mesh_.get_property_handle(fprop_double,"Face property name") ) { std::cerr << "Unable to retrieve property! " << std::endl; return } // If we reach this point, we have a valid handle. \endcode The properties can be removed by calling remove_property: \code // Remove the property mesh->remove_property(fprop_double); \endcode A useful function to see all properties on the mesh is: \code // Print all available properties mesh->property_stats(); \endcode A useful class for handling properties and their lifetime is the OpenMesh::PropertyManager. */ OpenMesh-11.0.0/Doc/misc.docu0000660000174600017460000000211314556675336017760 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page naming_conventions Naming Conventions The following naming conventions are used for the %OpenMesh code: Files: \li \c MyClass.cc for C++-Implementation of class \c MyClass \li \c MyClassT_impl.hh for Header only C++-Implementation of template class \c MyClass \li \c MyClass.hh for C++-Header of class \c MyClass Classes: \li Class names start with a capital letter: \c MyClass \li Class templates end with \c T: \c MyClassTemplateT Variables: \li One leading underscore for parameters in function-calls: \c _var \li One trailing underscore for member-variables: \c var_ \li Two trailing underscores for static member-variables: \c var__ Functions: \li Words are separated by underscores: \c my_function() Accessing members: \li To get the member \c xxx_ use const& xxx() const \li To set the member \c xxx_ use void set_xxx(arg) **/ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/tutorial_main.docu0000660000174600017460000000340214556675336021676 0ustar gitlab-runnergitlab-runner/** \page tutorial Tutorials (code examples) The %OpenMesh mesh library is a powerful tool for handling polygonal meshes. Due to its inherent generative structure it allows the user to create mesh types which are custom tailored to the specific needs of the application. The user can either supply his own data structures for representing vertices, edges and faces or he can conveniently use the predefined structures of %OpenMesh. Additionally %OpenMesh offers dynamic properties allowing the user to attach and detach data to the mesh during runtime. This document is supposed to introduce the basic concepts of %OpenMesh. In this tutorial we will introduce the %OpenMesh library by means of simple examples. The first one just builds a polygonal mesh representing a cube and writes the result to standard output. The following examples develop a simple mesh smoother: Recall that the immediate neighbors of a vertex are called the 1-ring of this vertex. It is well known that a polygonal mesh can be smoothed by repeatedly replacing each vertex' position by the center of gravity (cog) of its 1-ring. The basic smoother will \li read a polygonal mesh from standard input, \li compute the cog of the 1-ring of each vertex, \li replace each vertex' position by its cog and finally, \li write the mesh to standard output.
  1. \subpage tutorial_build
  2. \subpage tutorial_01
  3. \subpage tutorial_02
  4. \subpage tutorial_03
  5. \subpage tutorial_04
  6. \subpage tutorial_11
  7. \subpage tutorial_12
  8. \subpage tutorial_05
  9. \subpage tutorial_06
  10. \subpage tutorial_07
  11. \subpage tutorial_07b
  12. \subpage tutorial_08
  13. \subpage tutorial_09
  14. \subpage tutorial_10
*/ OpenMesh-11.0.0/Doc/speedup.docu0000660000174600017460000000142614556675336020500 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page mesh_speedup Some Notes on how to speedup OpenMesh On this page we collect some hints which can be used to speedup OpenMesh. This list is not complete, so if you have additional hints, just tell us.
  • Visual Studio
    • The prebuild binaries we ship are not compiled with full optimization enabled. You can build it yourself with full optimization. ("Full Optimization" (Project setting: C/C++ ->> Optimization) ). Please remember that you than have to build everything with this flag to avoid incompatibilities.
*/ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/tutorial_11.docu0000660000174600017460000000715714556675336021206 0ustar gitlab-runnergitlab-runner/** \page tutorial_11 Using Smart Handles This examples shows: - How to use Smart Handles and ranges to navigate on the mesh - How to use Smart Ranges So far we have used methods such as halfedge_handle(), next_halfedge_handle(), prev_halfedge_handle(), oppopsite_halfedge_handle(), face_handle(), to_vertex_handle(), and some others, to navigate on that mesh. These functions are defined on a mesh and require as input a handle to an element of the mesh, such as VertexHandle or HalfedgeHandle. In the following example we iterate over all vertices of a triangle mesh and for each vertex we create a list of the vertices that lie opposite of the edges in the ring around the vertex: \code // iterate over vertices of the mesh for (auto vh : mesh.vertices()) { std::vector opposite_vertices; // iterate over all outgoing halfedges for (auto heh : mesh.voh_range(vh)) { // navigate to the opposite vertex and store it in the vector opposite_vertices.push_back(mesh.to_vertex_handle(mesh.next_halfedge_handle(mesh.opposite_halfedge_handle(mesh.next_halfedge_handle(heh))))); } } \endcode For a more concise way of navigating OpenMesh provides smart handles, OpenMesh::SmartVertexHandle, OpenMesh::SmartHalfedgeHandle, OpenMesh::SmartEdgeHandle, and OpenMesh::SmartFaceHandle. Smart handles are smart, because they know to which mesh they belong. This allows them to provide functions for navigating the mesh allowing us to write the above code much simpler: \code // iterate over vertices of the mesh for (auto vh : mesh.vertices()) { // iterate over all outgoing halfedges std::vector opposite_vertices; for (auto heh : vh.outgoing_halfedges()) { // navigate to the opposite vertex and store it in the vector opposite_vertices.push_back(heh.next().opp().next().to()); } } \endcode The ranges of OpenMesh that are returned by functions like voh_range() or outgoing_halfedges() all provide a few methods than can simplify some calculations (see OpenMesh::SmartRangeT). One example is the to_vector() method which convertes the range of elements into a vector containing the elements. All of these methods take a functor as argument (sometimes optional) which is called for each element of the range. With this, the above code can also be implemented like this: \code // iterate over vertices of the mesh for (auto vh : mesh.vertices()) { // create lambda that returns opposite vertex auto opposite_vertex = [](OpenMesh::SmartHalfedgeHandle heh) { return heh.next().opp().next().to(); }; // create vector containing all opposite vertices auto opposite_vertices = vh.outgoing_halfedges().to_vector(opposite_vertex); } \endcode --- ## Code Example In this example, we will use bi-laplacian smoothing on a mesh. We store the \c laplace vector which is the vector pointing from a vertex to the center of gravity of its neighboring vertices in a vertex property. \dontinclude 11-smart_handles/smooth.cc \skipline laplace \skipline laplace To compute the center of gravity, i.e. the average position, we use the avg() method of the range of 1-ring vertices and pass in a PropertyManager acting as functor returning the corresponding point of a vertex. \skipline points \until avg(points) Similarily we compute the update vector as the laplace of the freshly computed laplace vectors by simply exchanging the points property manager with the laplace property manager. \skipline Iterate \until bi_laplace Finally, we apply the update after damping it by a factor of -0.5. \skipline update points \until bi_laplace Below is the complete source code: \include 11-smart_handles/smooth.cc --- */ OpenMesh-11.0.0/Doc/tutorial_08.docu0000660000174600017460000001443414556675336021210 0ustar gitlab-runnergitlab-runner/** \page tutorial_08 Using IO::Options This example shows: - How to control the behaviour of \c Mesh::IO::read_mesh(), - How to control the behaviour of \c Mesh::IO::write_mesh(). The class \c OpenMesh::IO::Options can be used when reading/writing a mesh. It controls the behaviour of the reader/writer modules by means of enabled/disabled bits in a bitset. The class provides an interface for enabling, disabling and verifying the bits in the set. We distinguish between -# mode bits - control binary reading/writing - Options::Binary - Options::MSB - Options::LSB - Options::Swap (MSB|LSB) -# property bits - controls which standard properties to read/write - Options::VertexNormal - Options::VertexTexCoord - Options::VertexColor - Options::FaceNormal - Options::FaceColor - Options::FaceTexCoord - Options::ColorAlpha - Options::ColorFloat - Options::Custom These bits have different effects when reading or writing. The file format itself is selected by the extension of the filename. Please take into account, each mesh has to request the standard property before loading with the corresponding option. For instance, if you enable Options::VertexNormal, your mesh has to request vertex normals. Otherwise, they will not be written into the mesh. \note Face Tex Coords will not be saved as a property per face, but as a property per halfedge. Therefore, you have to request the "halfedge_texcoords2D" property The OBJ-reader can also read information about the textures in the *.mtl file, if available. These texture information (includes texturename and index) will be saved in the property of type: \code OpenMesh::MPropHandleT< std::map< int, std::string > > \endcode with the name: \code "TextureMapping" \endcode This property will be automatically created, if textures were found. There is no other option you have to define for reading texture information beside of the request of the property.\n Additionally, the OBJ loader writes the texture index per face, if the property "face_texture_index" is requested. The texture index is the same index as the index written in the texture mapping. So, it is possible to get the name of the texture from a face via its texture index over the texture mapping property to the texture name. But remember, you have to request the face texture index property first before loading the mesh. Below in the table you can see what options are suported by which reader/writer (it is possible that the data format can support more). ASCII is not a real option and will be selected, if binary was not defined.
Reader/Writer Feature Support List
Format/OptionASCIIBinaryMSBLSBSwapVertexNormalVertexColorVertexTexCoordEdgeColorFaceNormalFaceColorFaceTexCoordColorAlphaColorFloatCustom
OBJx xx *)x xxx
OFFxx x xxx x xx
PLYxxxx xxx x xxx **)
OM xxxxxxxxxx (\ref tutorial_09 )
STLxxxx
VTK ***)x
\*) can read the non-standard extension vertex colors (floats only): \li defined with vc (e.g. used by meshlab) \li colors encoded in a vertex line (v followed by 6 values) \**) only vertex and face properties with fundamental types. Take into account, that you don't have to request these custom properties before loading. \***) no reader exists The program does not more than providing a command line based interface to select the option bits for reading/writing and to request mesh properties. Hence illegal combinations are possible and will result in a failure of the program. (The input file won't be damaged in this case, but be careful where you put the ouput file!)
Reading meshes
When reading a file the mode bits are used to give the reader an advice or hint. Depending on the format we can help the reader to interpret the data correctly. First of all we can tell it that the file contains binary data. \dontinclude 08-io_options/io_options.cc \skipline ropt += IO::Options::Binary Further on we can ask the reader two swap the byte-order. \skipline ropt += IO::Options::Swap (Both can be done via the command line with the options -b and -s, respectively.) By default the geometry and the topology is restored from the file. The file might contain more, especially it could provide normals or texture coordinates. We can examine the property bits after reading to find out what else is available: \dontinclude 08-io_options/io_options.cc \skipline ropt.check(IO::Options::VertexNormal) If a property bit is set it does not mean, that it has been restored as well. The property must have been requested prior reading the file. (The demo program offers the command line option \c -Xv[nct] and \c -Xf[nc] to request vertex and face properties.)
Writing meshes
When writing the mesh the mode bits apparently control whether to use the binary variant and the desired byte-ordering. For example, if we choose binary mode and want to swap the byte order, we set \skipline wopt += IO::Options::Binary \skipline wopt += IO::Options::Swap If the format does not specify the byte order the system byte order is used. If the format does not support binary storage, the mode bits are ignored. If the format supports storing additional information, which are conform with the standard properties, we can use the property bits to tell the writer what we would like to have stored. If we would like to store the vertex normals we simply set \skipline wopt += IO::Options::VertexNormal Finally we can write the data to the file \dontinclude 08-io_options/io_options.cc \skipline write_mesh The method returns false on error, which might have three different reasons: -# the option is not supported by the choosen format -# a selected standard property is not available -# a 'system' error like - could not open the file due to access rights - disk space exhausted during write - ... The complete source looks like this: \include 08-io_options/io_options.cc */ OpenMesh-11.0.0/Doc/html/0000770000174600017460000000000014556675336017117 5ustar gitlab-runnergitlab-runnerOpenMesh-11.0.0/Doc/html/logo_align.css0000660000174600017460000000012314556675336021740 0ustar gitlab-runnergitlab-runner #projectlogo { padding-right:64px; right:0px; position:absolute; } OpenMesh-11.0.0/Doc/html/vci_footer.html0000660000174600017460000000050514556675336022145 0ustar gitlab-runnergitlab-runner
Project $projectname, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .
OpenMesh-11.0.0/Doc/tutorial_07.docu0000660000174600017460000000311514556675336021201 0ustar gitlab-runnergitlab-runner/** \page tutorial_07 Extending the mesh using traits This examples shows: - How to extend the behaviour of entities using traits. In the previous tutorial we used attributes and changed the type of the data types \c Point, \c Normal, \c TexCoord, and \c Color. But we can do even more with traits. We can change the behaviour of the mesh entities \c Vertex, \c Face, \c Edge, and \c Halfedge. One goal in the design was a highly customizable data structure. Using the traits technique makes it possible. We pick up the smoother again and show an alternative way to implement it. Now we place the necessary data and the functions in the vertex itself \dontinclude 07-traits/smooth.cc \skipline MyTraits \until }; Note the definition of the vertex entity. We use the supplied define \c VertexTraits (which resolves in a rather inconvenient template definition). Similary we can use the defines \c FaceTraits, \c EdgeTraits, and \c HalfedgeTraits to extend these entities. Now we enhanced the vertex, with the additional member variable \c cog_, and the get/set-method pair to access the new member. As before we compute in a first loop the barycenters for all vertices and store the information at the vertices \skipline mesh.data(*v_it).set_cog In the second pass we set the new position of each vertex \skipline mesh.data(*v_it).cog It looks neat, but on the other hand we can't remove the data anymore as we could do with properties! By using traits one creates a 'static' configuration, which can't be changed during runtime. The complete source looks like this: \include 07-traits/smooth.cc */OpenMesh-11.0.0/Doc/smoother.docu0000660000174600017460000000330614556675336020672 0ustar gitlab-runnergitlab-runner//----------------------------------------------------------------------------- /** \page smoother_docu Smoother Tools \section OM_Smoother_Overview Overview The %OpenMesh library provides tools for smoothing Triangle- and Polymeshes -# Smoother: -# OpenMesh::Smoother::SmootherT -# OpenMesh::Smoother::LaplaceSmootherT -# OpenMesh::Smoother::JacobiLaplaceSmootherT \section OM_Smoother_Usage Usage The smoothers directly work on an OpenMesh. The following example shows how to use them: \code #include // Initialize smoother with input mesh OpenMesh::Smoother::JacobiLaplaceSmootherT smoother(mesh); smoother.initialize( Tangential_and_Normal, //Smooth direction C0) //Continuity // Execute 3 smooth steps smoother.smooth(3); \endcode \section Options \subsection Continuity \li C0: shape is continuous, but not the tangent \li C1: shape and tangent are continuous \li C2: preserves curvature \subsection Component \li Tangential: Smooth in tangential direction \li Normal: Smooth in normal direction \li Tangential_and_Normal: Smooth in tangential and normal direction \subsection localError Local Error By default, this option is disabled. You can set local max. local errors (absolute or relative) via following functions: \code void OpenMesh::Smoother::SmootherT::set_relative_local_error(Scalar _err); void OpenMesh::Smoother::SmootherT::set_absolute_local_error(Scalar _err); void OpenMesh::Smoother::SmootherT::disable_local_error_check(); \endcode */ //----------------------------------------------------------------------------- OpenMesh-11.0.0/Doc/doxy.config.in0000660000174600017460000035226414556675336020747 0ustar gitlab-runnergitlab-runner# Doxyfile 1.9.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). # # Note: # # Use doxygen to compare the used configuration file with the template # configuration file: # doxygen -x [configFile] # Use doxygen to compare the used configuration file with the template # configuration file without replacing the environment variables: # doxygen -x_noenv [configFile] #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the configuration # file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = OpenMesh # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = @CMAKE_CURRENT_SOURCE_DIR@/images/rwth_vci_rgb.jpg # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = @CMAKE_BINARY_DIR@/Build/@VCI_PROJECT_DATADIR@/Doc # If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096 # sub-directories (in 2 levels) under the output directory of each output format # and will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to # control the number of sub-directories. # The default value is: NO. CREATE_SUBDIRS = NO # Controls the number of sub-directories that will be created when # CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every # level increment doubles the number of directories, resulting in 4096 # directories at level 8 which is the default and also the maximum value. The # sub-directories are organized in 2 levels, the first level always has a fixed # numer of 16 directories. # Minimum value: 0, maximum value: 8, default value: 8. # This tag requires that the tag CREATE_SUBDIRS is set to YES. CREATE_SUBDIRS_LEVEL = 8 # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, # Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English # (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, # Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with # English messages), Korean, Korean-en (Korean with English messages), Latvian, # Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, # Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, # Swedish, Turkish, Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = @CMAKE_SOURCE_DIR@ \ @CMAKE_SOURCE_DIR@/src # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = @CMAKE_SOURCE_DIR@ \ @CMAKE_SOURCE_DIR@/src # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = YES # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = YES # If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be # interpreted by doxygen. # The default value is: NO. JAVADOC_BANNER = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # By default Python docstrings are displayed as preformatted text and doxygen's # special commands cannot be used. By setting PYTHON_DOCSTRING to NO the # doxygen's special commands can be used and the contents of the docstring # documentation blocks is shown as doxygen documentation. # The default value is: YES. PYTHON_DOCSTRING = YES # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:^^" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". Note that you cannot put \n's in the value part of an alias # to insert newlines (in the resulting output). You can put ^^ in the value part # of an alias to insert a newline as if a physical newline was in the original # file. When you need a literal { or } or , in the value part of an alias you # have to escape them by means of a backslash (\), this can lead to conflicts # with the commands \{ and \} for these it is advised to use the version @{ and # @} or use a double escape (\\{ and \\}) ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice # sources only. Doxygen will then generate output that is more tailored for that # language. For instance, namespaces will be presented as modules, types will be # separated into more groups, etc. # The default value is: NO. OPTIMIZE_OUTPUT_SLICE = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, # VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files). For instance to make doxygen treat .inc files # as Fortran files (default is PHP), and .f files as C (default is Fortran), # use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. When specifying no_extension you should add # * to the FILE_PATTERNS. # # Note see also the list of default file extension mappings. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 0 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 # The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use # during processing. When set to 0 doxygen will based this on the number of # cores available in the system. You can set it explicitly to a value larger # than 0 to get more control over the balance between CPU load and processing # speed. At this moment only the input processing can be done using multiple # threads. Since this is still an experimental feature the default is set to 1, # which effectively disables parallel processing. Please report any issues you # encounter. Generating dot graphs in parallel is controlled by the # DOT_NUM_THREADS setting. # Minimum value: 0, maximum value: 32, default value: 1. NUM_PROC_THREADS = 1 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. EXTRACT_PRIV_VIRTUAL = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If this flag is set to YES, the name of an unnamed parameter in a declaration # will be determined by the corresponding definition. By default unnamed # parameters remain unnamed in the output. # The default value is: YES. RESOLVE_UNNAMED_PARAMS = YES # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = YES # With the correct setting of option CASE_SENSE_NAMES doxygen will better be # able to match the capabilities of the underlying filesystem. In case the # filesystem is case sensitive (i.e. it supports files in the same directory # whose names only differ in casing), the option must be set to YES to properly # deal with such files in case they appear in the input. For filesystems that # are not case sensitive the option should be set to NO to properly deal with # output files written for symbols that only differ in casing, such as for two # classes, one named CLASS and the other named Class, and to also support # references to files without having to specify the exact matching casing. On # Windows (including Cygwin) and MacOS, users should typically set this option # to NO, whereas on Linux or other Unix flavors it should typically be set to # YES. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_HEADERFILE tag is set to YES then the documentation for a class # will show which file needs to be included to use the class. # The default value is: YES. SHOW_HEADERFILE = YES # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = OPENMESH_INTERNAL_DOC # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. See also section "Changing the # layout of pages" for information. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = NO # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as documenting some parameters in # a documented function twice, or documenting parameters that don't exist or # using markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # If WARN_IF_INCOMPLETE_DOC is set to YES, doxygen will warn about incomplete # function parameter documentation. If set to NO, doxygen will accept that some # parameters have no documentation without warning. # The default value is: YES. WARN_IF_INCOMPLETE_DOC = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong parameter # documentation, but not about the absence of documentation. If EXTRACT_ALL is # set to YES then this flag will automatically be disabled. See also # WARN_IF_INCOMPLETE_DOC # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS # then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but # at the end of the doxygen process doxygen will return with a non-zero status. # Possible values are: NO, YES and FAIL_ON_WARNINGS. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # See also: WARN_LINE_FORMAT # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # In the $text part of the WARN_FORMAT command it is possible that a reference # to a more specific place is given. To make it easier to jump to this place # (outside of doxygen) the user can define a custom "cut" / "paste" string. # Example: # WARN_LINE_FORMAT = "'vi $file +$line'" # See also: WARN_FORMAT # The default value is: at line $line of file $file. WARN_LINE_FORMAT = "at line $line of file $file" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). In case the file specified cannot be opened for writing the # warning and error messages are written to standard error. When as file - is # specified the warning and error messages are written to standard output # (stdout). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @CMAKE_CURRENT_SOURCE_DIR@/.. # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: # https://www.gnu.org/software/libiconv/) for the list of possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # Note the list of default checked file patterns might differ from the list of # default file extension mappings. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, # *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C # comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, # *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.cc \ *.hh \ *.docu # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = @CMAKE_CURRENT_SOURCE_DIR@/Examples \ @CMAKE_CURRENT_SOURCE_DIR@/../src/OpenMesh/Tools/Test \ @CMAKE_CURRENT_SOURCE_DIR@/../src/OpenMesh/Apps/Unsupported \ @CMAKE_CURRENT_BINARY_DIR@ # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = .svn \ CVS \ Debian64 \ *.moc.cc \ footer.hh # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # ANamespace::AClass, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/Examples \ @CMAKE_CURRENT_SOURCE_DIR@/Tutorial # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = *.cc \ *.hh \ *.txt # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = @CMAKE_CURRENT_SOURCE_DIR@/images # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: # http://clang.llvm.org/) for more accurate parsing at the cost of reduced # performance. This can be particularly helpful with template rich C++ code for # which doxygen's built-in parser lacks the necessary type information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS # tag is set to YES then doxygen will add the directory of each input to the # include path. # The default value is: YES. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_ADD_INC_PATHS = YES # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = # If clang assisted parsing is enabled you can provide the clang parser with the # path to the directory containing a file called compile_commands.json. This # file is the compilation database (see: # http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the # options used when the source files were built. This is equivalent to # specifying the -p option to a clang tool, such as clang-check. These options # will then be passed to the parser. Any options specified with CLANG_OPTIONS # will be added as well. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. CLANG_DATABASE_PATH = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = NO # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = @CMAKE_CURRENT_SOURCE_DIR@/html/vci_footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = @CMAKE_CURRENT_SOURCE_DIR@/html/logo_align.css # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a color-wheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use gray-scales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML # page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_MENUS = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: # https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To # create a documentation set, doxygen will generate a Makefile in the HTML # output directory. Running make will produce the docset in that directory and # running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy # genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag determines the URL of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDURL = # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # on Windows. In the beginning of 2021 Microsoft took the original page, with # a.o. the download links, offline the HTML help workshop was already many years # in maintenance mode). You can download the HTML help workshop from the web # archives at Installation executable (see: # http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo # ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the main .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location (absolute path # including file name) of Qt's qhelpgenerator. If non-empty doxygen will try to # run qhelpgenerator on the generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine tune the look of the index (see "Fine-tuning the output"). As an # example, the default style sheet generated by doxygen has an example that # shows how to put an image at the root of the tree instead of the PROJECT_NAME. # Since the tree basically has the same information as the tab index, you could # consider setting DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = ALL # When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the # FULL_SIDEBAR option determines if the side bar is limited to only the treeview # area (value NO) or if it should extend to the full height of the window (value # YES). Setting this to YES gives a layout similar to # https://docs.readthedocs.io with more room for contents, but less room for the # project logo, title, and description. If either GENERATE_TREEVIEW or # DISABLE_INDEX is set to NO, this option has no effect. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. FULL_SIDEBAR = Yes # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 300 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email # addresses. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. OBFUSCATE_EMAILS = YES # If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg # tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see # https://inkscape.org) to generate formulas as SVG images instead of PNGs for # the HTML output. These images will generally look nicer at scaled resolutions. # Possible values are: png (the default) and svg (looks nicer but requires the # pdf2svg or inkscape tool). # The default value is: png. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FORMULA_FORMAT = png # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # With MATHJAX_VERSION it is possible to specify the MathJax version to be used. # Note that the different versions of MathJax have different requirements with # regards to the different settings, so it is possible that also other MathJax # settings have to be changed when switching between the different MathJax # versions. # Possible values are: MathJax_2 and MathJax_3. # The default value is: MathJax_2. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_VERSION = MathJax_2 # When MathJax is enabled you can set the default output format to be used for # the MathJax output. For more details about the output format see MathJax # version 2 (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 # (see: # http://docs.mathjax.org/en/latest/web/components/output.html). # Possible values are: HTML-CSS (which is slower, but has the best # compatibility. This is the name for Mathjax version 2, for MathJax version 3 # this will be translated into chtml), NativeMML (i.e. MathML. Only supported # for NathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This # is the name for Mathjax version 3, for MathJax version 2 this will be # translated into HTML-CSS) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. The default value is: # - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 # - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # for MathJax version 2 (see # https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # For example for MathJax version 3 (see # http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): # MATHJAX_EXTENSIONS = ams # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: # http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /