))Q6zRQJE@GM5pxb)~HR+PnmbVu7UYI49$er34@&;<$ z9#SP$;aXRNU#EfQ@|Rod<#OiJ{Iw;Ttuin1#C%t(`JJtN^496$;k8i}ohfw|Z3y`T z+J&~3&X`{Qw6{raNcuEigD+I-4!AW7I2QgRc=!ARGv>`4*Yb#5sNFQbzsa@CA6VjY z*Vp@(d9?*GcU6y-x6{0^d}?e-2GuSz89WUI16aL$hCtB{m%qjp^e)4Uxf$UrL40Q9nDATCRL7FxkojTou~Vk(qLD)gG;<2*Mxd^LzBKf {L=T(%zQz!Av_DYoYjlUaF6~WO$t1cl>oU>as?Am93z^(#^Nc31j#*Rv z@{D;Z0kq@WfLni6a?PbGVb&K|`c9?e?ewjYo|j5Q^&&4}pd0NqYf9&N(l_6wu(O<{ z?l1(QDvUk4QD*_$8pf^2sLWI-1qVz^4{WnCFJ?<~er+W?Hobb~1ueVfk!^=E)nQ@9 zkzuD-aKqY_JHi92qT83b% WV6bV#_RdH&!q6dFu4nmR$eLsSD0f)!)0^>midw)L-wb zt-~S+2SRR`a=a1R8ps~$kYZl5IV+#s8Ew_fC3ItY)mQQ?S;}Eid31)GHj0W-^||ub z8RcRZ7?0gWQw$V)3mZZM<-N1+Nx68jR9wA@xQ4i3^z+SHGCZqbL@jZ{ko7e}mFiot zirV;2W>@WG$7|OX+1bKPSj}R8)9i{PvP}|exeML2m`W@)*<_cDZVeGD+OAvcH};ZQ z^^#d(x`TD@nh@W+N%8XyM3Y?(vGVS%yAu~mhLp~0tx>Gf2*Y3 SlaW zepntSOS!MM(Os|EdfVdORUgri$X} &sk8k$o!;@GlVVNGX5xac{+wvD|O+^X6r(#y$Y(A_N@G(lCbUA#{v zK)L18ta$u^M#!?h)WAGy4aLlbR91g3a;Oj&F+L|Mz1uxfwJc!XMi_PmmX5t*SlQ0l z&8VC_-2|Ia)#+tBRkmb$1$VM0gtfJnW5ueKd*UpO9- Hetj+Mq=qKA!HCBgjJJcvj2O+B z-h4z}9o=LmHDu(vs(rzxdZ>m5Z=?2T+5%H*2haFqkzZzEodwHSHx@)%P9@n{v&kQU zm>AjAUD@*T@2ThI#j`(xr?o3QjSa*KJ%JrB*V}83OHxKypKi=z&=>MyZC3fijn(cz zv!;H?VROpAr)3^xEHiY?p~X#JxT_5uZEVgGk7}REo)c{hR~wowaj-cR?WiTHWtcUG zTp_Mw^cSLq&DnZLq32PE!dz0VI#IbCwwyK7+Mzm0-zbcQuB6x8jbV2^ubL)b@>#Ua zhIn2D@+j)_D$pE $D+ZsJcA@Z=ry{UIfi&`>JcbArV-Q3&T65PhD==DAq0A zF;W_f 5U0ZgWDrVeQ&C7L?Yg~A_uigh$s)`$HSD<~Iki@r{r7-ME!VSS dBgIk&6=f?ZEyA@MCXM|+J**emvU5{QkzaT?DE{!8o9mpansAm*D4EhwbE%4 zYzPWTmj=8DPGatak-- ZDqzskA{WYd<<#G%^8t4<|_M35g>BW z!DPf+n&S5_;b*l$*?8l-MzWlnc9rdvrLZe;jyUFv{k6x)Q)ODJc&d!d#O;*Vo2vhG zFk22CNnKAUV=@a>M U#3E%jw1+q_N{h8ZI2k?L6H3)NKz+{>VD zkF7IOHF3u*qC3=jnwDiggngo#TnwA|G08!*8KxK*j(4P}!uAx|3EcKHE*h75kRC}r z;2{R%!sK+T9G%`M>~DaR ~w*t||Zhr+O>wp#acQ^V;kZ^`Y;8t)Exa9HdL zd2yhhgbdr~<*)oYCa%?PJmp}xtD9A!EyI@loy-nH# lFu`)t+-? +1}VpY7BO~Mq+Y;r6IMG;$r8^M z51(3A?or7=7X+O-LvEELc1_IX(|yDK^P@MtWG2IsZB1-4Wag~9v+RcYT_oLzO0SaV zwa3J;h-`7GmgXYhtqFUP$CboR-nuI?4_imiSs=6RdMctBG1E|0@AoVb$1{da&0e{G z&AsHmktK)YuBgx1_tb`}fZvA {8%Ia^szsbV zsdVx<>`;_?k>u)~vt;I}-X>3@icb!_brKI(wL9cak`vO^YFANcN*-{>q D3KzI&3RmH=3Ktk^3RmGV3l}(Q2v=cSgsVtXxQf~?TwtUrTt&wwTwtdoTt$CF zxWH9IxQf~$TwtLgTt#gZE^yHluA*ZVE-=&-uA*ZWE^yQkuA;UG*KkeY8s2u{0wYb~ z8h&iT1$H{ZHT-V~7r1H&*YLIo7g%Tr*YGw97r1B&*YIN%E-=&-uHnZlT;Ql7T*KQS zTr^G_)_S8CopQMu7)frWd<2|QCuhIKWhDvcKsuI?^O6iLlEfE%jEhTNZZx@Fap}jf zq=PcMDdSA#nRb{eQo18)XURIJlpB@sfi(^*?g0Na71w&Y{i z_RY7HcZub2y0;C{Z}a@m6;8c*nztsg=-McqzGUyrsK|7krplnll@f1YsYu93I9WDI z=~E>xs;^)f&W>%1scuqz?y6{pK>KNkak)f}rKcG&62z(!wjr9%o=403Z(Phu9Q}&c z^*^};W;i_2x(fbgzj#Vvl64jS&AJK`&X?g8HN#dWx~^te*iP~8s#{uW6q!Hv=`$*3 zlr0=LZ8}e>GA!?imS@phHyKe5BNFyJ%A$Y`m(@{}MZxekuqb5F4A3Zx!o=erZ3V6} zYP6y#@mNI1G8zDmj%5;o-txB_)~)ld>LFKeoqoo`3GT+kflTfomt@W!xb0m >D<6HY?NI@#bTzwy~G=CN@DhT;R3C~i8YO=xlpTcV$l_ai?j+CC7fVUc(_*K z#OuyZIpHyzb(iTP8QjnBH&Xth@_wM<`16wvQbzJDI;Q)13Zxt7uZaVQxpY!O#{p~Z z4os%I1}fp|E%A~L2Y_#Yi|tFr{exu1j4Dv&>qi xGLCSm*RoB3s9mDJ>vh >P)!kW=S>afsFe@c?kr*gt|KgxN*xcwz*j1b1EosB1SiB$8ft%bb zYl+`A5$9|P>vT|-2EnV4zaSUyU*aFio6Y?KWU3Ovipv*CIB?-W6@W7dnNP#u3=0oz zIY0>)$Xw22qdn;aB0|Ud3l6n@MA#(wJ)eG$9QWhzg2;C(_Lhy7zKL%8-V$tdUXF-S zU7R->m>tNbmQhTqnk6Wb;{4GfUjV-}h8wDI=Zz+!9yzzc;)2mr8yb*+imQJ}EYc{P zSS#D=Z$!p0Yyx@IoYb%;LPWrY{$%z@N^GHnHr3b &(9dn;wZlb$* zRoP|N%hTMY)Ex{WSEw2}Z@3B-_RwYbnlLid63&IpP^E%8DH-xCkz^H6a(DI(`)IH1 z*s{BJ5GAI`J xPTpM$vs8EnU89_U;Zo gotYJL{@TJora8(oj36c<9aidX=+Z=E<@!dCurMLU(@nOWu~+f}+;o_O`> zBV!oP7r_IN|EJ1;?@LG-lrJTn
wD z36R4zj_&u0&}Nd+yQC2@3 OO0Y89L{I5|!47;GH znTP-W4kAdB6%{1g#e$@PPLi!T*)Gb7C9W9IlO!uDOty=K|LZP_AZ`+~D5p0ZV;75( z?PAgYx{F20&Z2zC-li^!MGYJX+A3uo(N$X1aJMPkBMvIWhM7?7IO)#F=5+#mMiF@J zA@P(l+hk;rCW7Hh9E?-5jRFi9vP~SOQ?re_oQ7-@yNZ7ohsSW`MVUjnBmns-&_Loz zk~x-j0_KIs&KwIW0rR4^GUv*j62kvBRFUBT@hc#NVYqV7tPd&kTwXO1fF X11%Z%HUU1EVPU(_kTHu&Li &GEZrviCklo0p5%SAUUKpLmu)q$T%3Xp4_V?pYj+lK`#BS&N>6&(;L=@r^(Bu zdxaa9qA1i(s9vy0rC34$l_U IARw89pdM{U@J+Cn_~-c(7J?k%;RiZ zzN{Uj0^J9QA)=WA{I(j`kEzYX9B?+lB*MzT7A#}bY_gB#CXeDwBM9FFqDd@;ZOmg( zehQ)@gA%VI)B@(YUS5`odog2Gc%T=!o%0WtMX!POqzc190*bB1$v8bY;Hq;6UEbwQ zxX+gOu-8VjuL7RvC~gJG7gm8$5P?xQRF@oVkz)3$$eEN(&9i!Sfg26^8X!j+mQ!Jq z5!Pfdi6M5iULJSDvr`2$aIgWW?WC03a?R5aH`1{2*=J8(xRy>gtM1saOl7n6neE2z z08K}D9nv8ukhUo4IccNKM%-0TM6^?Kr4^ibuxv@eTpIS$S&~VjM~ngwEsCOzbtSw^ z>LZ|4LVy~eHI%Fva xV19C178XeM7%&`FY9Yg;~;X(QwtMInDf9y#!h!-RA(z z6jE&PPdq;!>wz!}$v5SSm0)^{6We|q>QqnDsPR_Yu4(>vu!KnFPeEVR<_PIBTq~ zscf^Zsf^b(gcaKsUBg+#YlR4#Hfn{x31VwFW;RwCs}(BSt`(93#WidP<}O| YjS+~Wx3HG*l260L=vu)-X&(c)2Kc^;u>|wk)SA!Q2lgta(#IH77W=MUd z C5Qp%r(MEmVlP9GxNlk$hI84 z&*%0asKDV>;qefx8AYj)5Sz^BaJv=xvJp(Q$PGbc&PJilc 9 +sgXQ&(|UA=c^*axx7%PVl{U>!q>^705!Lw?s2B9WJe;Ci?o z?lw=%5Af` Z>i1lptPSr@2Lg7sQpwl#22g+ zmZh@1jSgm1sR_9gREIIqqy%NLl*;JC5UCU0JWW^m?>2f8u=Rb#<7_z`2^(=I0P9ia zA`*OQb5s_}o`0Zx4c@T2v1I#(0jiX$9+LpL?nm| x zZl2-~2V%R0P-pE!<%j8>w9K%bxE~!L+)a^5A6v> ?^5XuiDRu@~5qjvD@JT{e;s$NLJ zTZSG)2&a}(MmEKK;%1ANTk(DQepNZTc*`S;cvnWRB)_+L&e^kD qrO zDT}^wXPFLXN<2WS>}pD_P3Dz09f)N7)l}sd{33{|rP %yQ1zHDeSH2O~jUdXa_4tMPnk&{yLVK~q(` zOLkN|r5-CJ{?fZ{F0HXLdp~B;r!VQ*IQp~%ne@f6^KL1#wC)UEB#)cD%p3IAha;J~ z%0{TR3OsZsZ57H-a-<=`eH3ZfqJxE09~vTrn=wXtqg|1K=YMlwSINm)n^|__thzXf z%mEiHc_WdOipB|Lu2hsN)Sqs#;0QIBvXE7PrbV;skj#wA#mYmp-i_B9WSm|pV?u(? zR6hEv>{!ZzkUZGtO0PR!QP7 mAG8x-gNi#5G>;vpAl_b%#4aq%@;a|KqyX!; zgNrwYOOAM@P{D=2i(te?_q_q>{fJ_h^xl9G6aMVL(XQApl}{EZo=Hf8hgtRDwgnq>~@;`$s*Wyix?p2 1ZhO4v3UO z8HGXDX{nQ5QScs`cgBKL)yY#o&X24UASolU45u6X#6`f6OD`+v@U+vZ(~R$ycog?V zI*sEH#nM3}KT+pTt?ICFL|9PNR@M^T;+QO#gEfg6E%6vK648OBe7n^ecDY4}7#T3a zO+YEAoUla*8yPZ6&?26wpWuymt&S{YwZ){>$#<9Q?@a33#hrINMgq;wFBwW#3^lm) zBo4wDpgo=JY&N `VNiVjgSJ;OQWqRWEw4Qb}U>=*B{* z`y`UI-$YMB^*GV4MHvcmAC*w@$}NgZx%^U!2D^?FS@x;` QiU=x$o9O9I6u}YW102g) -FBoT488v^vP1?A>enpM;*t9Jxh?BK%s!DC~mt>OQjbR; 9lp>dD6tgrL}4Yxf23ccCTCtWqT(XgnUpzJW$dYo{7>8p z)u=C*>JxQ|LmpcAa?`s-YXNg*BuKad8VnsI6?9j-F-@V3?EG3a3~=#Cvqm`^0j;Z6 zcY6-89!X6z9JS(w ^Gq{x}{CL32^(t{cNdU%Q5dlmntkc}405q*uO8s|+2Bd4a3 z4ERU}8q}M3Bm?0Jf@6jjC@vf=mTfT))M|AkF6ko+2~Ri~Mx;V$IUSib1aQ}=sI9Q= z8Z69}`RDy9&$e} a;Hp;YsAP2w{ )0V`70RfNtClgZ+6gU1)~XzK>Rlk3TZSyN7y PQsG6wn >!nRk7z6#aeQ1mS^z>Us$AY+Y@GtXG1n0U*n92r5Ud3=;tbzE+mRd>!2Z&R6N zZmBFX-A`?#$4ml uKXwb7t}#Ty9y`%E2<3gC;67c_U6}?AhCoOM*=FcJRqB8 z1Ox|NKpQM2e&}n1RYzLu7iQH(aj@)@>VYv63^nTxP&PRPw7|++>L#g#I)4(yR3c~T z MVhX$VTIv3iL<~-nNxDRd!T~Y!;qK3?OB(+E`{CZG&{wsJZ~C zE>j@Oh*PmSwdwr7Dav0d{WnGTVN_H&@Whw+*QlP(pV|nlM;{@i%pqkd{>UF)8U3SR zG@kaA|4C0Vccd-AduaB+@|M+IanlJ`epPZjb84(I=9hm-4M(g#g#YkYjUU-*IMSv6 z=AsQ%gA4p5;A*9-GjTbhA)eRDCsR{YjW{{35hBk|Q5COVU0(vj(_H>?YrQOnX24vQ z=rqlYXQ67N^>9qashfs z48CgM^h|j>T`4SMH2iX}x(mL+NYb=q_K3098=E-XJj?V6 HV%z2z9g1?z+Zljw3u zg!ra0%C@<`ZC*!tFtWU75R@84JWBoiJWrz#59P-7xsQaw7LBh)9d=_=%Ceb*&B;x0 zNSt_voz93!4n^F%lzCEF#fy~36#huryiRV9Rq)gs4r2g0jq!7NKQ6mrW3Q@?GhgMQ zK^Ph$Lq+;K8a*fhpd7MF ZxD~zIO+omRN8)7Lz2>mfOi>_s9Ci8gt`)Je{LaftI=7~$>@s&{A)io|Q zPlq;)IvmRf;i0Jim8_;HjGabWjtih&K^zBAg07qiByun`X5L9>uVh%(rmMy>gEwpn zZoBG6g}N^BEEq{aG{J!Wsw!W|RBU>e@F%Yk01&r?&{_Ex0Eaf}GS3w^9RzDqw<@+B z5TO=(GZ>B&QD$9Mr_~N3^g+SO!*K`8a>^`AFNj4REVF8350(exum|T;i2VN*b5LWh zv@sexMsWfK93ziV=&1$=1yLj2l=VqYlt)km-F3^0C>teivS}O9X|e z!JWgasRF4PGr}R59fpxqdg?%B+nSB6H~LZ)jfufZ)M}PgCh88yAS7y($)Ve86;1)! zv8qvpsdfU|$FC&G3B59=noAsBNr-d^a_fw)JvmrIjfUCiNd}cAnO)lG4T~3w4edr7 zA$h7wW|fi|KZI_w83p-manOB~$U=~ihVx2zeaIf$EsI+_DgA{`U&%Yx4X(Ed6i;J} zjtL4+kB`V*RlG8xfYfW`xqv}&bp(q~XSQu+H_ZBdNpFSw)~U?vYebr_hXWwMr}dr{ zrZ+H+7^t%6a@7o?iE|p=;MG$% 7rR^blZx;tZ_` z4+_^oJ<{v77>KZ*@om!w@zZKK9VDsz2B(a!XXGfzE)uy)TfS8JG`%^d9`}Y6Z;$d@ zzs8nxZp81Rbu{CX^1~{&eH3i@*)=Vzps$wh^&0c#V0~M@RISV$;udOl@n#t=&g@95 zNH3^b)I;JSy2`^*VM vEBhf;<~{G9u(t&sd(lQkS=~@MCooAF;s+dk_C0kPa4!sWB3*I zB@5-2FNcz10Qof7a{#xvaA7xT*j1q?3XsCx(3wGw=|PN0$*AVAuNE_LHq9fB$XC{j z)M>-ZwU01V+$z**RTS$CSdj@3!}2u{!}LasA~B15D 5 zj%l ^76OkhPYHL$nzDt+=XZ(WpwCqvk15;nNMbfk71NXJjxdLl(~#iCA-WNyyMX} zozB>ek*TyMZ*lLck4TNmO-_&CQSn 2rEjpar9K WcM|`&e&kF1HT%$(3OH^KWr28iRkV|Z2-rvTJV6vUM+r`V{Ahw!(hoJ* z=z$~EDH|}Yh#%6tbYvz+q;gUuEH3s0fuzDDC2=7! &% &C1_BOIj)F%2WfTT)DHMdLfmna zQfJ`)Hm;0DBa=je(I}Zbbc;seWB^+ 4unQ zxVXtm8LAwb4(d{pmMTQas`2)Oj=TU9WQj+WZjoIXEi5AiX|%?HM5%U>N6zH6o>eJd z$}zGD&8qttW}`g(t%u628$M`$Os=8>eeDWSt~%m>bYsWe=+U#1EN9i$IGg-(VH<7k zWO- ;>=Nu&7h{E_&hK>DL#1pX)--QWuZ z{DIQqqR|cV_rs ;X3R4GAi*QZjY~&62ogbDKaXvKgT5^p!iLiS%4M8XhT|wS)(#yyRI8f! z`>s?dL5IyMY)IQA;6auksaunOT cO-m_n67u2+KAf{u!p0V h7#!?ss`t8)fwl|? zpE}L4h}%N)&}9(RLf7i3(Z`Nji%$R^Tipqbbi@uE JFBqu6xh@yLxU4XvZapkt(&f
oV8YYPn{o^ff}+^^kepLaHPUxex$j0Qz85D4L}q7xFb27NWtCo9Bo$uL<*{ zTaW5=5L3$gj|o*gjTb8l9clg2xQQ8|uohC+KaeZ#8Rf#`VVGD#g+Tb0!$N2^C59zc zpc-mdJj=*0`h%~*R5cX_O!X&6n`v~a44CRqo(5CZRBDW9r2Bf4tHDw=)qNujBtrv} z6#d0u^5Yi`Qi! C*r!f!mwR6dZcybd}Q7f&=lk2{&mmQUuO@FGW= zvAv5w6zg2xgo6g!m$}7AE0Ax4+PiF=*WrkqOX+zTmY5eK?fhD^zBLo)hBy+r9gf;T zbGMaDC8)%s4teCW&w#~QgUsn_fs{B{YZNUsVI@Q4Le|*=l|1fSl^@%4PAOj8fDPO* zq^xuZFw2Ha%O91WH)K{pe%^@u!nnek9 KU?j<}6h?2C6xz&PeFcBAi5)#13z!OM0@fm~T>gy>C zC8z!A7M)qQ@k>=GDnlx|Lc+VzE9s~@1+SIIdb?RDO|2}iLuzJOnA@!hInWJ2x$Eu0 zK@#36c=K}_-HfNHOUR{Zmm-_M8RddocF8eNWkYm|GLUj2_{%VcoH`PQ7F|Cg@g-RO zGOMSGjg`CB4NuFun*Ct_QQS&rY0udLYhFuy{9JkQz=0BcUkw)XWh0& zlPjjWzJ^KD7!pEARNQJyazx_p#`V% +@u4Vw)xyh&`TTum3vYGzNJG_?(lCxp%! zpDc>T#WjVIqjtJ*JDWp)>CGz8cw&MB?RZWKqVmxF;^5Y(X(+#8*~ 7C{+c7GN z-jiNa6wcy>$uvu%-L1RoCe=MzdqD2DV?2 TJHKiW&4;r;-dp&eK_^c*<=CU%XlR!Y(1Z)h2A z#<>yh%)^3gX$=2v8vKJx6LYo2ZI0 @_?@Xm|!_E+)z_^G8sU9M6Q1{RBrGNGiv zMbNOqKGogN?SpRkSPk=)by`;!sdz %!(EpI6*9uciL2oO|c`r}@TYqoEa40 z4UIG*1c%&R3rpHXuLuSV>(8Op9a-sAw_;YiDC?tJvxJ*OOWv3xStb<9Ak!y? hnimtSB=FVQTrUbV}DNs+dM87E-KakEpTvg3*V(C!dl_v-4 zqcfDSFFlEAWl>3H`KV3P4fJduUKvk)YeYmGSG+uR0ES9d)w*~!NMKB|B1&xJxL0kh z$Oib1hg2?G=460b$gg%7?zM5|EXVdv!g5WF3a+;iSSWU@@NLt0oYt_FRHDRQK3P`V z4qir)j;L1|PF-Tae!3`&s^CqGnxF}5u3IT78x_F04ang#0)$>MzE6?=9dX|ku43n@ zHI#f!VDWS$E&K9`w >Jg-(NJk zF-@`icaV5CNhc5 >zlpO`2U0{SW^W-#peo$ztaVA7P;~;^RV3yr(}obUYYbz=rR*WyPQ_*P zc905&M53?)gGi5uxy-WpdU-sp0> oXl&O54vt=uv9`Q=e5={4P7?W+L@B21GS zUmytNNW3HmHG!xlRx-c*q1T3Z2$c>3{KFOT@!Zvm!y@#VJdZAdhje2Grzw8iuH~oe zM(WiPe+EtSD?LnMRFWSktKu5jZ3$uUlVVzaF{`Dw%!EJSiU2=WVA2aF!j%KhE9@5~ zS8*`c7OvfC>V KtN~){rTV%>y@|8c6FS4&htDQv#CF zD>kZGwV~l~SV&mnZOsuW%v`R~vdm+alnh*hj3(KsWT9Y!qhmD_LoPW{E^LtaU%5H$ z<2Vg6wT@V|rDRb)2*pgKa3kMkQ5 z-!ncx$Za{i>1FRdOV3_-MkKjT;j#3QoFY83g2^XKBp62a2cAC0|Kl!-;T{zaXOIak z!Ht^4rxS4@#ttYOxjLC#G*R~mS5L>;H@&>7F-ARPml1w~Pzc^?>7fKY2DZ7|V#0yh zIBtaLnPfC@?zWgn9xtABAaCxrm|$WS)sDf!>mLcji1w)ID6bVKm5 E()H^JXkKqiTA%7w{^haj{`&7M v_8?tv=oPNUx2R;<|2MDa+OgEMmYD{vGI3nzDS ztT$f#YNF~0EF*FRyx91ZhTkTPLw=C2Me>W-$f=J2#pyO6?!rojNF;#LFbUE9`{%oYA~<3+tT~am2*pTZly_gc5GMyj z$fBe$X!6@W4`I}uv@nY{X$oPG7NrCjg_I7ZIw(d#aUQt(RLin}zp+*hWr#GWBsA$D zr4_)tGMGlG!pRrL;FiN=sM0Tr>Z_=FWGKd11ZYIP&x1r+Z}njA6T_f{YLBiK30X%P zYpgQ4xsl;-;Kp-(v*EhJb;Mb9<-vIt4$6r01;xHHikcPy5I}?6xTpbKS3qwI6n-=* zYMCniR>K;*Mrx#sSTrZ~U%Imhv_nzzWZjyn0jO3O_Hvh-0Ma^ozy>`&u>%UbyUI7*3PWL1fJ@2kpBYYsk?(~c>jKnH*x->?w0*H+_^tbxt zQu>H|f5z-mb}uzer7ot5M#TG!b#8JRA?cE3Pts2*zub+)?AFWjC`q}IX2BgsVV*}; zJ{ipPn_~IlE-B1#*=UU{eJR^G;2i>)N)X)bLw5iCgPw)6XHZ3i4n)6@hV z^4rA`s~<~>-ror~!IhB*9#uwywgNjV;H8_0GyoxLs_+;LMIo2QyUaHO4>gAeQd$rK zxY5j&VbtS*m!iSM)V&l@44z;`mscWS&5BiTIKqTjOWK3(66grrSgKD(u%#fetVjO# zD#|6PBBfiw^T=ZC4}P5*LM?0%Bi+e|R#w7>gWK7A4~bC4CCeLIw$p!=WR|eiKPyCv zZ(5;cep#$UXxs;={YD9`(Xa;RqS0l=EB6yXmC9e}UV(=~>J^BP(bMMy-ov8NGtVl! zVg3Q`)iiB-RmHYnEL$n|7L0^8z17C-&8o}PX1YmhBr|{O=`%gsrVXiVnk-ZaVdg}c z3TD+SPuAJ)0OGSe+fb7^U$NT&)u5EBQR}}`5H!zV5 zqm?{}N@s+mZuA(^k)c9yBxXp?6=mS+Fyz|==Lll}P= ?(brKmOfVj_$MqgoYinPH_o1&q2V45<=U zG6=?0^jteXwwtmU<<>T$3~S4#fh9oJmK)E$qPAF3PakDHNDTpG+A 23Wpf zfQ`rrx_T?EBgrpMt%7bQBV_5>I1`CFrTIdDn<80NP;-&pUl~mVfI)37Vu8L!V_l65 zgCLHTt4oSktWfOpPUNVfFhZ4h4AR&FH(yby7#ezF8tGR?Bg1tGEqe`J(ruYSm(bEr zQkBGCg|mnoh}4jF)9IaO5k@As!9a6T&p+xEb4JoqnM;*cN-rk5A|5d%mb!RmDRcl` z6UWwR&=dtvm51Gxcm}2Goba+S*=^&d$~aYVqwL$HxXEd_DqfVtTMjFeQdbQ+7XQ|z z4Fwk_D%FaMv#LER9f_ vI%V4U$c+vcJ1tat1ww)9?m#BE zOM3Ew1IOr;jlX!Re*QzR7 MRVU{5Xg1PB?%L*Q<}rECxO7NS3Gj`CaY+31jjRdaFt`r0={5jQ&Xli>yNot*C7bB`)S7Jg1JydMNe(Jar*QJ%UpfqO*mBlP zr#gf(#b2q3j!0L+XcY-e6zC) Hb7!k^fHGau<1TV$ zYc_uH2By+eXA_a0@2`zPmdY5Ix3VxVFYow(fE!Eny=ek9DbZIJQCBjbrha IR*ysHC Ypc;MsZcVnl#L^+}6S?cnnLablD!c$AVDB_&4= zYDyfN_JU2)(wH Qsl4Z4)BI% ~JSnSFl#%(CQVb{-{)2Yx>{&HpJ%Kh>%XW-EqFI@0QfK{&|2bCif zgri+qo?JRhQQB4P$}<`y11J%_N;^grzF7Bk(5uoToyq?qTp_JUnI6;5YNk=;BKIo7 zHcqP;buXr^aq*unQd_mdKzfah;Yyab%0cfaaplH$lPa>L$I@AwS$5;Bx;X8HH#q{h zEJ5lkDa9l4iBmnf5+AO@BFjv7 HdU?3Y1z{8qo@#bL^?f_}d)G;>3d3?(YyY3g z0y?X$bHpPPs!1p&+TdkbJEa19HqX3}hKdf2WPQXlzj#hv{ARCAfJsz6&qzo98D*rX zlyq+;MvRnru1G~en{;OmBic36J%r+HAq&&0VZa%Ui01|UJfx=TY4Y`SrqfQk-&0ad z_S<#uwrr J;*eEm_>yxiHN_Nz zW0O>SH1j6CNvL%xokFM9?3N?tZ&UZ;ZrQZsfzhVODvw;J(cxoZE=o_4B`qDuUeP-! z{JH?NMs>tERxK g`Kwg$vr*Z^HS?B9_7RBv^ok}be`FwW4fMS{YWmR)!CIl}1Z&6QfG-tXb^SnRl zfKZX#(1*$+QJP!kgIykXBflnHg*;{sOex*I&>jR;OH5M?n?a-HRgYHW9; d+YQ zycx8g 1sfNJ#2O9*vyMCK--2NlgoV$GUMTML``{x&yhFGV9AjXONYkMQy;8) zaVtv5qG6XgB&CpHb`o {`^($o`^aD(det>&B=Vg1%<`CidVokf~kKZu{*2r08sC zozq!Qy?YJ063K#S$BuVmCF*{qPI-@P>1BB#gj_ykK>%kcEYx&PCZdv$TIZB!`&JzY zUN&`hQk|ERrNKwK-@bdbY;i*OYF|FwFr`-86P;jMmI_cx^Ys)ieB??Yr4`+fyu8Rt zq%)-a;=S0Ia9uW4Xg1;eHrd96Yb;zGL~GY{{J@;p{cTOS)0!i-ul=BxT0|>7@*2EX z>3c943}Lm;1-Z(ux9 >HGhDuah8_7B9SgWa2nCurHg$u@~$mG(>)q-k^U z7qOn2gjfFFmAJxGNnBY_m?~M2bSY9{BZfSL`$a*;3|%ysN;~;+hxCpzy~Cw9IyK{$ zzB_~WeoGf2pFC~K_m6{CdJ$Jr;mq{ZqVN$NN@8javbW#*HFHph_i^|TkpRHKOtC50 z+X}#D!L93KiE~T!eD|Y^zZCp%{iXWC`mMF=5#6F&r!T5w8K~V>EuTPQJgw8Ni{75% z$gSh$32G@OB-nAP D&x1wkC0> 5V>>P@c&bD5{9VgZqp|!|LlRr?jqE_|2_Yg}e3q z^7k5hMN)EBk==MOavJ9dXp!64)0sqwOc0iW?hyb9P3)s7e(BNX(8ae*^Pb?_Q?|UD z%`Dqm8YqfYCa(I*`xbZaXEpFqMUlrkznyuwOo1B?)Y&_m2-18odFjzqd>VgB z!woAOf|qrs7+U$k=;6rsw2-eDsCT|O_3*+{?Z@}x6jx7bxS}epBRwOXpyu@rP>N_H zftp=8H$l<);$b#y>4*XwUqc7y`&)WI2zD$`l>tg=?F1G*qlG)B$n|!<(OA7n`n}50 zMNVtw5FZZ|rA`p?eMZ9_S6B?0ncpwn3qrclKv5VtfxYpw^^?SuAV8G{9aU#mImCP+ z#D+`vS{6OZ6l4AmWyOca0!0zg m<`DCZ&lkufzBMm!VoWa#gU{vdKa zp7)`lNg2EGK!K2XGB_EG3BHVd`U~T#Jb7{~J4F%SP7h0cIuWS3!F%srJtR_Ed_m)! zP?Pob<+UYb8fs)q^&9Yh=9@r1^E<$DB9)-|+3g=X>h+w4E~zSFDmShzBajN$UCaUD z?_UW!5h#j=bO!Kq8g@cqePPO_^g)wqR>q{qovp}A5>A6M)Jzi!k^K*MYhq+ 73nMoS+;ym>8vQopK6j?rXb}5HT{7fDX%K^s|X|O5DA8ol;2}9@`Xs@{T4&E z4YrYRMBB9G$sdhyI%ye jxOcI<8_?HJo#_(ij~6onsdcGe3pGPl07QoHr9r81>bFlOwamUf(`+7c2` z5>cDZsvPF&rf<0GnA9aqIdU+i08RrO>QY%z_*=vf;b?%3Lx*g}5ySK>3s}ghsrq$L zI?`IhKCA6Jvw&-QMQOl^5JzBYjVk0}4)CbD+(Zkrnq#+vkuT6*<;LHZc2Sa~``_C< zZJMn6vQSXfd1yTaMC)KkGB&g!;MBS7+9uT1w&8^U^D>xqtj>Pj3rE##oVVFOJ0%)s zXE5tno)B#qXl-ndM8gcF^u8^2EJQ1+xyO?Y6Em1gl5GTNZDg}I1%&_#emS`D2eOO7 zi?r+e(O<-v>rGl=Tun3E3?i+uUi+0uHX4g6g;)f6v4wm=56B5ML6jr(LPhsD4bHKS zfOzJ>=EFkDP-9hP `szVx *%yu8JHOovA HLa?}VKu#g4ch9uW;hAk(4qLeh!X4f z%+T42g{_yR;s`VV`94ET914u>bGqe8OQ(tf&IA;2Xf#UOlHzey)q#cRi8!_}QQ?aL zjs!$}EU-SWyLMECX(+;2MI`vffgsLMD^R6QV1m}J-aTD?z4B+V_t!h>BBtnTb Zn%cR1@XGCG)rbD&aE9caS zm zHYdt8L#66e%gp7!{cnT4tF*j99A0j*vv;gw-4pDE>6Bte$F1L8y=(ycCt!G>&U7Yl zi#t2>y=5>$=*25ZQ8UvYY&Q&k29f^kS0j6NWuc|ar2BEosXY1hl{o!!f0$F*dmhZx zrY{HaXDN`{flMH )ltmJi>D$WfK4tJwa&|db-Uc^?$DV(8Bj0K}3ja#PD|KN-% z)3;bpR5kwel{c&da~~h)*5;inL-CSfp2+v=Or3nd^gfVV54d4Wg0BiaS9tQkBjC4* zZ2~ngp;o(xI$t$^OZxGSOWlr?d-HsOoA_qyluW!1Pbg{Kafi3zo`U|%@PvZyUAR+l zik^drGl(2Nr_K-q@3~j#H= AKA$tNr)i5Aad^^f ziIT%;&TIT528`~Yk7UEHj;2%?(m{F?)=wS9j3E5!KEH xS}1Ac>+Y8OFE?ao?EnA( literal 0 HcmV?d00001 diff --git a/chinese.ts b/chinese.ts new file mode 100644 index 0000000..b0b780b --- /dev/null +++ b/chinese.ts @@ -0,0 +1,7084 @@ + + + + diff --git a/datafile/datafiledsr.cpp b/datafile/datafiledsr.cpp new file mode 100644 index 0000000..8059e48 --- /dev/null +++ b/datafile/datafiledsr.cpp @@ -0,0 +1,1021 @@ +#include "datafiledsr.h" + +#include "main.h" + +DataFileDsr::DataFileDsr(): + m_HeadSpacingIndex(0) +{ + memset(&m_62HeadData, 0, sizeof(DsrHeadEx62)); +} + +DataFileDsr::~DataFileDsr() +{ +} + +void DataFileDsr::initFile(const QString &fullPathName) +{ + clear(); + QFileInfo file(fullPathName); + if (file.exists() && file.isFile()) + { + m_fileFullPathName = fullPathName; + m_fileName = fullPathName; + if(g_emMacType == MACHINE_FIVEHEADPRECISIONSEWING) + { + updateFileVersionTo6_2(); // 文件头中新增2048的数据 + } + } + else + { + qDebug() << "Init file failed path =" << m_fileFullPathName; + } +} + +//检查dsr文件版本,非5.2以上版本和错误格式返回-1 +int DataFileDsr::checkDsrVersion() +{ + loadFile(); // 如果数据未读取,重新读取 + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + qDebug("dsr size less then headsize"); + return -1; + } + DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); + float ver = *((float*)(&dsrHead->verCode)) + 0.1; + if(ver < DSR_VERSION_5) //5.x以下版本 + { + return -1; + } + + if(ver >= DSR_VERSION_6_3) //6.3版本 + { + if(size <= (int)(sizeof(DsrHead63))) + { + qDebug() << "dsr size less then headsize"; + return -1; + } + } + + size -= dsrHead->dataBegin; + if (size <= 0) + { + qDebug("dsr dataBegin err"); + return -1; + } + int stepsize = size/sizeof(DsrStep); + if (stepsize <= 0) + { + qDebug("dsr data size err"); + return -1; + } + if (stepsize > PATTERN_LARGE_NEEDLES)//128万针 + { + qDebug("dsr data size big"); + return -2; + } + + return stepsize; +} + +// 转换为绝对数据 +void DataFileDsr::convertDataToEmbAbs() +{ + m_embAbsData.clear(); + + getDsrMinMax();//读取dsr源文件 + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + qDebug("dsr size less then headsize"); + return; + } + DsrHead * dsrHead = (DsrHead *)(m_fileData.data());//头文件的结构体 + size -= dsrHead->dataBegin; + + if (size <= 0) + { + qDebug("dsr dataBegin err"); + return; + } + int stepsize = size/sizeof(DsrStep); + if (stepsize <= 0) + { + qDebug("dsr data size err"); + return; + } + DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); + + // 绝对坐标数据 + DataDs16FileHead dhead; + memset(&dhead, 0, sizeof(DataDs16FileHead)); + + QByteArray absData;//绝对坐标 + absData.clear(); + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + DsrStep * dsrDataPtr = dsrDataBeg; + DsrStep * dsrDataPtrTemp = dsrDataBeg; + + int maxX = S32_MIN; + int maxY = S32_MIN; + int minY = S32_MAX; + int minX = S32_MAX; + + int stepidx = 0; + int runflag = 0; + BYTE ctrl,attr; + BYTE lastStatus = DATA_END_OLD; //上一针的状态; + double xfactor ; + double yfactor ; + double rfactor ; + if (dsrHead->xyUnit == 0) // 0:单位0.1mm; 1: 0.01mm; 2: mm + { + xfactor = DSR_EMB_DATADIRX*10; + yfactor = DSR_EMB_DATADIRY*10; + } + else if (dsrHead->xyUnit == 2) + { + xfactor = DSR_EMB_DATADIRX*100; + yfactor = DSR_EMB_DATADIRY*100; + } + else + { + xfactor = DSR_EMB_DATADIRX; + yfactor = DSR_EMB_DATADIRY; + } + if (dsrHead->rUnit == 0) // 0:单位0.36度; 1: 0.036度; 2: 度; 3, 1/10000弧度; + { + rfactor = 2*PI*10 * DSR_EMB_DATADIRR; + } + else if (dsrHead->rUnit == 1) + { + rfactor = 2*PI * DSR_EMB_DATADIRR; + } + else + { + rfactor = DSR_EMB_DATADIRR; + } + + int ax,ay,ar; + ax = ay = ar = 0; + int headSpacingIndex = 0; //机头间距索引 + + //都减去第一个点坐标,并转换为中间数据 + for (int i = 0; i < stepsize; i++) + { + ctrl = dsrDataPtr->ctrl; + attr = dsrDataPtr->attr; + ax = dsrDataPtr->dx; + ay = dsrDataPtr->dy; + ar = dsrDataPtr->dr; + + if (ctrl == DATA_PAUSE_OLD) // 暂停 + { + ctrl = DATA_PAUSE; + } + if (ctrl == DATA_ANGLE_OLD) // 拐点 + { + ctrl = DATA_ANGLE; + } + if (ctrl == DATA_CUT_OLD) // 剪线 + { + ctrl = DATA_CUTTRD; + } + if (ctrl == DATA_END_OLD) // 结束码 + { + ctrl = DATA_END; + } + if (ctrl == DATA_CHGND_OLD) // 换色功能码 + { + ctrl = DATA_CHGND; + } + +#if(1) + //判断是否要改变第一针的属性 + if(ctrl == DSR_JUMP) + { + if (runflag == 0) + { + runflag = 1; + } + runflag++; + } + else if(ctrl == DSR_SEWING)//第一针不转换为跳针 + { + if ((runflag == 0 || runflag > 3) && (i > 0)) // 第一个运针是入针 + { + ctrl = DATA_OFFSET; + runflag = 1; + } + //else if (i == 0 && ddx == 0 && ddy == 0) // 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs + else if (i == 0) // 20230511 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs + { + int count = 0; + do + { + dsrDataPtrTemp++; + if (dsrDataPtr->ctrl == DSR_JUMP) + { + count++; + if (dsrDataPtrTemp->dx == 0 && dsrDataPtrTemp->dy == 0) // 空跳,直接变成跳针 + { + count += 2; + } + } + else + { + break; + } + }while(1); + if (count >= 3) + { + ctrl = DATA_OFFSET; + runflag = 2; + } + else + { + runflag = 1; + } + } + else + { + runflag = 1; + } + } + else if (ctrl == DATA_CHGND) // 换色 + { + runflag = 10; + } + else + { + runflag = 0; + } +#endif + + //附加动作定义 记录每个针步的机头间距索引(机头间距表中对应的位置) + //缝纫动作结束,索引增加,起始为0 + //上一针为缝纫或剪线,这一针不是缝纫和剪线,则增加索引 + if(((lastStatus == DATA_SEWING || lastStatus == DATA_CUT_OLD ||lastStatus ==DATA_CUTTRD) + && (ctrl != DATA_SEWING && ctrl != DATA_CUT_OLD && ctrl != DATA_CUTTRD + && ctrl != DATA_END_OLD && ctrl != DATA_NULL))) + { + headSpacingIndex++; +// qDebug()<<"index add to ====================:"<+ +BrokenLineDialog ++ ++ Form ++ + ++ + 1 ++ + ++ Broken Line Prompt +断线提示 ++ +ClothingMac ++ ++ HMI Configuration +界面配置 ++ ++ Interface debug mode +界面调试模式 ++ ++ Delete configure file +删除配置文件 ++ ++ Machine parameters +机器参数 ++ ++ Work parameters +工作参数 ++ ++ Flip style +翻转式样 ++ ++ normalP:0;nRight90P:1;nRight180P:2;nRight270P:3;mirrorP:4;mRight90P:5;mRight180P:6;mRight270P:7 ++ + ++ Rotation angle +旋转角度 ++ ++ Template recognition device ++ + ++ No device:0;Bar code:1;Coding hole:2;Multiple files:3 ++ + ++ X frame sensor coordinates ++ + ++ + + + + + + + + + + + + + + + + + + + + + + + mm +毫米 ++ ++ AnchorX +定位点X ++ ++ AnchorY +定位点Y ++ ++ startX +起始点X ++ ++ startrY +起始点Y ++ ++ Y frame sensor coordinates ++ + ++ Spindle parking sensor angle +主轴停车传感器角度 ++ ++ Lift sensor coordinates ++ + ++ Angle of spindle hook sensor ++ + ++ Spindle jog parking angle ++ + ++ X movable area negative boundary ++ + ++ X movable area positive boundary +X可移动区域正边界 ++ ++ Y movable area negative boundary ++ + ++ Y movable area positive boundary +Y可移动区域正边界 ++ ++ X Sewing area negative boundary ++ + ++ X Sewing area positive boundary +x可缝纫区域正边界(X+) ++ ++ Y Sewing area negative boundary ++ + ++ Y Sewing area positive boundary +y可缝纫区域正边界(Y+) ++ ++ XY start stop speed ++ + ++ + + + + + + mm/s +毫米/秒 ++ ++ XY zero running speed ++ + ++ XY simulate running speed ++ + ++ XY movement acceleration ++ + ++ + mm/s2 ++ + ++ XY brake acceleration ++ + ++ XY manual movement speed 1 +xy手动移动速度1 ++ ++ XY manual movement speed 2 +xy手动移动速度2 ++ ++ XY manual movement speed 3 +xy手动移动速度3 ++ ++ XY maximum moving speed ++ + ++ Spindle start stop speed ++ + ++ + + + + + + + + + + + + r/min +r/min ++ ++ Spindle zero reset speed ++ + ++ Spindle running speed ++ + ++ Spindle running acceleration ++ + ++ + + r/ss ++ + ++ Spindle brake acceleration ++ + ++ sewing maximum speed ++ + ++ Spindle zeroing compensation angle ++ + ++ X gap compensation ++ + ++ Y gap compensation ++ + ++ Sewing main shaft working speed +主轴缝纫工作转速 ++ ++ Spindle cutting speed ++ + ++ Spindle needle return speed ++ + ++ Spindle start slow speed ++ + ++ Reverse equivalent spindle speed ++ + ++ Sewing frame movement mode ++ + ++ XY continuous:0;XY intermittent:1 ++ + ++ Sewing frame start angle ++ + ++ Sewing frame steadiness angle ++ + ++ Slow stitch at beginning ++ + ++ + + Needle ++ + ++ Needle action, thread loosen allowed ++ + ++ + + + + + + + + + + + + + + + + + Not allow:0;allowed:1 ++ + ++ Needle action,tight bobbin spring allowed ++ + ++ Needle action, catch upper thread allowed ++ + ++ Cut thread allowed ++ + ++ Do not trim:0;Automatic:1;Last trimming:2;Data trimming:3 ++ + ++ Trimmer cutting angle ++ + ++ Trimming completion angle +缝纫动框起始角度 ++ ++ Thread cut, upper thread loosen allowed ++ + ++ Thread cut, tensile thread allowed ++ + ++ Thread cut, catch upper thread allowed ++ + ++ Thread cut, presser foot lift allowed ++ + ++ Stitch detect if thread broken ++ + ++ Thread brake detection, main shaft angle ++ + ++ Bobbin change reminder function +换梭芯提醒功能 ++ ++ Not enabled: 0;Delay reminder by length:1;Count by number of slices:2;Immediately reminder by length:3 ++ + ++ Bobbin thread length +底线长度 ++ ++ Bobbin thread correction per stitch ++ + ++ Bobbin change as per sewed pieces ++ + ++ + times +次 ++ ++ Oiling mode selection ++ + ++ No oil:0;Oiling by time:1;Oiling by stitches:2;Oiling continously:3 ++ + ++ Oiling interval by needle stitch ++ + ++ Oiling interval by working time ++ + ++ + + s +s ++ ++ Needle Oiling sustained time ++ + ++ Stop position selection after work complete ++ + ++ Current:0;Start:1;Anchor:2;Feeding:3;Offset:4 ++ + ++ Valid flag for offset point coordinates ++ + ++ + invalid:0;X is valid:1;Y is valid:2;XY is valid:3 ++ + ++ Offset point coordinate X +偏移点坐标X ++ ++ Offset point coordinate Y +偏移点坐标Y ++ ++ Threading point coordinate valid symbol ++ + ++ Threading point coordinates X +穿线点坐标X ++ ++ Threading point coordinates Y +穿线点坐标Y ++ ++ Production preset +产量预设 ++ ++ Delay after pneumatic frame off ++ + ++ Sewing acceleration ++ + ++ Trimming frame displacement +剪线动框位移 ++ ++ Automatic move to threading point allowed ++ + ++ Large presser foot action allowed ++ + ++ Sewing move head up down ++ + ++ Moving basket Loose line +移框松线允许 ++ ++ Moving basket Clamp line +移框夹线允许 ++ ++ Software limit XY move allowed +软件限位XY移动允许 ++ ++ Number of Needle hooks ++ + ++ Trimming frame direction ++ + ++ No:0;left:1;Forward:2;Right:3;Backward:4 ++ + ++ Spindle corner speed +主轴拐角转速 ++ ++ Minimum speed deviation angle +降速最小偏差角度 ++ ++ Early speed reduction ++ + ++ Delayed speed step ++ + ++ Secure input light curtain allows +安全输入光幕允许 ++ ++ Safety input pressure allowed +安全输入气压允许 ++ ++ Pneumatic frame off ++ + ++ + Penumatic frame on ++ + ++ ms ++ + ++ Loop work allowed +循环工作允许 ++ ++ Shuttle Oiling sustained time ++ + ++ Sewing operation speed 1 ++ + ++ Sewing operation speed 2 ++ + ++ Sewing operation speed 3 ++ + ++ Change the sewing needle count value ++ + ++ Enable +使能 ++ ++ Disable +失能 ++ ++ JogP +正转 ++ ++ JogN +反转 ++ ++ Zero +归零 ++ ++ Open +打开 ++ ++ Close +关闭 ++ ++ Up ++ + ++ Down ++ + ++ Extend ++ + ++ Back ++ + ++ Combine ++ + ++ Separate ++ + ++ X to move motor +X向移动电机 ++ ++ Y to move motor +Y向移动电机 ++ ++ Spindle motor +主轴电机 ++ ++ Needle motor +针电机 ++ ++ Shuttle motor +梭电机 ++ ++ Lifting motor +升降电机 ++ ++ Frame ++ + ++ Big foot ++ + ++ Middle foot ++ + ++ Buckle the bottom line +扣底线 ++ ++ Top and bottom lines ++ + ++ Lower scissors to cut thread +下剪刀剪线 ++ ++ Sandwich line +夹面线 ++ ++ Elastic thread +松紧线 ++ ++ Elastic thread 2 ++ + ++ Laser control ++ + ++ Laser blow ++ + ++ Oil ++ + ++ Headlamp ++ + ++ Sewing Blow +缝纫吹气 ++ ++ Hookline ext ++ + ++ Hookline open and close ++ + ++ Sewing machine head lifting +缝纫机头升降 ++ ++ Spindle clutch ++ + ++ Pen ++ + ++ All to zero +全部归零 ++ ++ Needle shuttle reset ++ + ++ Back thread ++ + ++ Back offset ++ + ++ Back shuttle ++ + ++ Back work ++ + ++ Set anchor ++ + ++ Back anchor ++ + ++ + Back start +回起始点 ++ ++ Forwrak or back ++ + ++ Bottom count reset ++ + ++ HeadLifting +机头上升 ++ ++ ThreadCut +手动剪线 ++ ++ ProcessReset +流程复位 ++ ++ Simulated +模拟缝纫 ++ ++ Signal +传感器信号 ++ ++ Action +控制动作 ++ ++ HMIUpgrade +界面升级 ++ ++ MCUpgrade +主控升级 ++ ++ ParaImport +参数导入 ++ ++ ParaExport +参数导出 ++ ++ SoftwareSet +软件设置 ++ ++ Authorization +软件授权 ++ ++ Network +网络管理 ++ ++ Time +时间设置 ++ ++ Version +版本信息 ++ ++ Root +超级用户 ++ ++ Select +花样选择 ++ ++ Para +花样参数 ++ ++ Import +花样导入 ++ ++ Export +花样导出 ++ ++ Delete +花样删除 ++ ++ OperatPara +操作参数 ++ ++ ActionSet +动作设定 ++ ++ SpeedPara +速度参数 ++ ++ LimitPara +限位参数 ++ ++ MCPara +机器参数 ++ ++ Start button 1 +启动按钮1 ++ ++ Pause button 1 +暂停按钮1 ++ ++ Air pressure detection 1 +气压检测1 ++ ++ Security input 1 +安全输入1 ++ ++ X zero position +X零位 ++ ++ Y deceleration +Y降速 ++ ++ X positive limit +X正限位 ++ ++ Y positive limit +Y正限位 ++ ++ Sewing machine head 1 lifting upper limit +缝纫机头1升降上限位 ++ ++ Lower lifting limit of sewing machine head 1 +缝纫机头1升降下限位 ++ ++ Sewing spindle 1 needle - parking space +缝纫主轴1针-停车位 ++ ++ Sewing shuttle 1- parking space +缝纫旋梭1-停车位 ++ ++ Sewing machine head 1 - surface thread breakage inspection +缝纫机头1-面线断检 ++ +ControlActionWidget ++ ++ Form ++ + ++ Control action +控制动作 +控制动作 ++ ++ Control action < Auxiliary function +控制动作 < 辅助功能 +控制动作 < 辅助功能 ++ ++ PageNums: 1/1 ++ + ++ + + + + + + + + + + + TextLabel ++ + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PushButton ++ + ++ pageNum: +页数: ++ ++ The machine is about to move, please pay attention to safety! +机器即将运动,请注意安全! ++ ++ All to zero +全部归零 ++ +DebugInfoDialog ++ ++ Dialog ++ + ++ PageNums: 1/1 +页数:1/1 ++ ++ DebugInfo: ++ + ++ pageNum: 0/0 +页数: 0/0 ++ ++ pageNum: +页数: ++ +FileSelectDialog ++ ++ Dialog ++ + ++ PageNums: 1/1 +页数:1/1 ++ ++ pageNum: +页数: ++ +FiveHeadPrecisionSewing ++ ++ HMI Configuration +界面配置 ++ ++ Interface debug mode +界面调试模式 ++ ++ Delete configure file +删除配置文件 ++ ++ Machine parameters +机器参数 ++ ++ Work parameters +工作参数 ++ ++ + + + + + + + + + + + + + + + + + + mm +毫米 ++ ++ Left +左边 ++ ++ Front +前边 ++ ++ X movable area positive boundary +X可移动区域正边界 ++ ++ Y movable area positive boundary +Y可移动区域正边界 ++ ++ X Sewing area Negative boundary +X可缝纫区域负边界 ++ ++ Y Sewing area Negative boundary +Y可缝纫区域负边界 ++ ++ sewing work speed +主轴缝纫工作转速 ++ ++ + r/min +r/min ++ ++ Bobbin thread length +Bottom line length +底线长度 ++ ++ Refueling method selection +加油方式选择 ++ ++ Head 4 shuttle refueling +Refueling needles interval +机头4 梭加油 ++ ++ Refueling duration +加油持续时长 ++ ++ Production preset +产量预设 ++ ++ Sewing machine head 2 - surface thread breakage inspection +Thread trimming moving frame direction +缝纫机头2-面线断检 ++ ++ Pin 1 motor +针1电机 ++ ++ Shuttle 1 motor +梭1电机 ++ ++ Spindle 2 motor +主轴2电机 ++ ++ Pin 2 motor +针2电机 ++ ++ Shuttle 2 motor +梭2电机 ++ ++ Spindle 3 motor +主轴3电机 ++ ++ Pin 3 motor +针3电机 ++ ++ Shuttle 3 motor +梭3电机 ++ ++ Spindle 4 motor +主轴4电机 ++ ++ Pin 4 motor +针4电机 ++ ++ Spindle 5 motor +主轴5电机 ++ ++ Pin 5 motor +针5电机 ++ ++ Shuttle 5 motor +梭5电机 ++ ++ Head 1 Elastic thread +机头1 松紧线 ++ ++ Head 2 Elastic thread +机头2 松紧线 ++ ++ Head 3 Elastic thread +机头3 松紧线 ++ ++ Head 4 Elastic thread +机头4 松紧线 ++ ++ Head 5 Elastic thread +机头5 松紧线 ++ ++ Head 1 blow +机头1 吹气 ++ ++ Head 2 blow +机头2 吹气 ++ ++ Head 3 blow +机头3 吹气 ++ ++ Head 4 blow +机头4 吹气 ++ ++ Head 5 blow +机头5 吹气 ++ ++ Head 1 trim +机头1 剪线 ++ ++ Head 2 trim +机头2 剪线 ++ ++ Head 3 trim +机头3 剪线 ++ ++ Head 4 trim +机头4 剪线 ++ ++ Head 5 trim +机头5 剪线 ++ ++ Head 1 needle refueling +机头1 针加油 ++ ++ Head 2 needle refueling +机头2 针加油 ++ ++ Head 3 needle refueling +机头3 针加油 ++ ++ Head 4 needle refueling +机头4 针加油 ++ ++ Head 5 needle refueling +机头5 针加油 ++ ++ Head 1 shuttle refueling +机头1 梭加油 ++ ++ Head 2 shuttle refueling +机头2 梭加油 ++ ++ Head 3 shuttle refueling +机头3 梭加油 ++ ++ Head 5 shuttle refueling +机头5 梭加油 ++ ++ Head 1 lifting +机头1 升降 ++ ++ Head 2 lifting +机头2 升降 ++ ++ Head 3 lifting +机头3 升降 ++ ++ Head 4 lifting +机头4 升降 ++ ++ Head 5 lifting +机头5 升降 ++ ++ X Sewing area positive boundary +x可缝纫区域正边界(X+) ++ ++ Y Sewing area positive boundary +y可缝纫区域正边界(Y+) ++ ++ Zero position coordinate of head 2 +机头2零位坐标 ++ ++ Zero position coordinate of head 3 +机头3零位坐标 ++ ++ Zero position coordinate of head 4 +机头4零位坐标 ++ ++ Zero position coordinate of head 5 +机头5零位坐标 ++ ++ Xy continuous moving box:0;Xy intermittent moving frame:1 +xy连续动框:0;xy间歇式动框:1 ++ ++ Thread cutting allowed +剪线允许 ++ ++ No. of stitch detect if thread broken +Number of thread breakage detection needles +断线检测针数 ++ ++ Bobbin change reminder function +Change shuttle core reminder function +换梭芯提醒功能 ++ ++ Not enabled:0;Delay reminder by length:1;Count by number of slices:2;Immediately reminder by length:3 +do not enable this feature:0;Count delay reminders by length:1;Count by number of pieces:2;Prompt immediately based on length:3 +不启用该功能:0;按长度计数延迟提醒:1;按片数计数:2;按长度立刻提醒:3 ++ ++ Count of shuttle change pieces +换梭片数计数 ++ ++ Times +次 ++ ++ not refueling:0;Intermittent refueling according to worktime:1;Intermittent refueling according to the number of working stitches:2;Continuously refueling:3 +不加油:0;按工作时间间歇加油:1;按工作针数间歇加油:2;持续不停加油:3 ++ ++ Interval between refueling stitches +加油针数间隔 ++ ++ + + second +秒 ++ ++ Software limit: xy movement +软件限位:xy移动 ++ ++ Automatic sewing speed regulation +Sewing speed reduction mode +缝纫降速 ++ ++ Circular working function +循环工作功能 ++ ++ Duration of shuttle refueling +梭加油持续时长 ++ ++ Sewing and blowing time +缝纫吹气时间 ++ ++ X to move motor +X向移动电机 ++ ++ Y to move motor +Y向移动电机 ++ ++ Head moving motor +机头移动电机 ++ ++ Spindle 1 motor +Spindle motor +主轴1电机 ++ ++ Shuttle 4 motor +Shuttle motor +梭4电机 ++ ++ Lock frame cylinder +锁框气缸 ++ ++ Flap control +翻板控制 ++ ++ Barcode testing +条码测试 ++ ++ Signal +传感器信号 ++ ++ Action +控制动作 ++ ++ HMIUpgrade +界面升级 ++ ++ MCUpgrade +主控升级 ++ ++ ParaImport +参数导入 ++ ++ ParaExport +参数导出 ++ ++ Network +网络管理 ++ ++ Time +时间设置 ++ ++ Version +版本信息 ++ ++ Root +超级用户 ++ ++ Select +花样选择 ++ ++ Para +花样参数 ++ ++ Sewing motion frame method +缝纫动框方式 ++ ++ Sewing hook angle +缝纫勾线角度 ++ ++ All spindle zero positions +所有主轴 零位 ++ ++ Allow for needle starting and thread loosening +起针松线允许 ++ ++ Allow for loose thread during thread cutting +剪线时松线允许 ++ ++ Allow needle withdrawal during thread cutting +剪线时退针允许 ++ ++ Cutting and parting angle +剪线分线角度 ++ ++ Thread trimming completion angle +剪线完成角度 ++ ++ Automatically thread back points during sewing +缝纫时自动回穿线点 ++ ++ Allow for loose lines when moving boxes +移框时松线允许 ++ ++ Starting angle of sewing frame +缝纫动框起始角度 ++ ++ Continuous angle of sewing frame +缝纫动框持续角度 ++ ++ Zero All +全部归零 ++ ++ All Spindle Hook Lines positions +所有主轴 勾线 ++ ++ All spindle jogs positions +所有主轴 点动 ++ ++ AllSpleHook +AllSpindleJogs +所有主轴勾线 ++ ++ Spindle thread cutting speed +主轴剪线转速 ++ ++ Allowing for wire clamping during wire cutting +剪线时夹线允许 ++ ++ Number of stitches for surface thread clamping +面线夹线针数 ++ ++ Head 1 ThreadCuttingAction +机头1 剪线动作 ++ ++ Head 2 ThreadCuttingAction +机头1 剪线动作 ++ ++ Head 3 ThreadCuttingAction +机头3 剪线动作 ++ ++ Head 4 ThreadCuttingAction +机头4 剪线动作 ++ ++ Head 5 ThreadCuttingAction +机头5 剪线动作 ++ ++ Head 1 Clamp wire +机头1 夹线 ++ ++ Head 2 Clamp wire +机头2 夹线 ++ ++ Head 3 Clamp wire +机头3 夹线 ++ ++ Head 4 Clamp wire +机头4 夹线 ++ ++ Head 5 Clamp wire +机头5 夹线 ++ ++ All_Zero +全部归零 ++ ++ Front_Back +快进快退 ++ ++ AllSpleZero +所有主轴零位 ++ ++ AllSpleJogs +所有主轴点动 ++ ++ N/S_Proof +针梭校对 ++ ++ MU_Canl +makeupCanl +取消补缝 ++ ++ Makeup1 +makeup1 +机头1补缝 ++ ++ Makeup2 +makeup2 +机头2补缝 ++ ++ Makeup3 +makeup3 +机头3补缝 ++ ++ Makeup4 +makeup4 +机头4补缝 ++ ++ Makeup5 +makeup5 +机头5补缝 ++ ++ AMShaftRun +所有主轴研车 ++ ++ Setting +软件设置 ++ ++ Authorize +软件授权 ++ ++ ThCutAct1 +机头1剪线 ++ ++ AnchorX +定位点X ++ ++ AnchorY +定位点Y ++ ++ startX +起始点X ++ ++ startrY +起始点Y ++ ++ Coordinate of threading point X +穿线点坐标X ++ ++ Coordinate of threading point Y +穿线点坐标Y ++ ++ ThCutAct2 +机头2剪线 ++ ++ ThCutAct3 +机头3剪线 ++ ++ ThCutAct4 +机头4剪线 ++ ++ ThCutAct5 +机头5剪线 ++ ++ SetStart +定起始点 ++ ++ ProcReset +流程复位 ++ ++ Simulate +模拟缝纫 ++ ++ HeadLifting +机头上升 ++ ++ GoFeedt +回穿线点 ++ ++ Back start +回起针点 ++ ++ Import +花样导入 ++ ++ Export +花样导出 ++ ++ Delete +花样删除 ++ ++ OperatPara +操作参数 ++ ++ ActionSet +动作设定 ++ ++ SpeedPara +速度参数 ++ ++ LimitPara +限位参数 ++ ++ MCPara +机器参数 ++ ++ Start button 1 +启动按钮1 ++ ++ Pause button 1 +暂停按钮1 ++ ++ Jog button 1 +点动按钮1 ++ ++ Open frame button 1 +开框按钮1 ++ ++ Manual operation button 1 +手动按钮1 ++ ++ Be ready button 1 +就绪按钮1 ++ ++ Key button 1 +钥匙按钮1 ++ ++ Air pressure detection 1 +气压检测1 ++ ++ Security input 1 +安全输入1 ++ ++ Template in position 1 +模板到位1 ++ ++ Template in position 2 +模板到位2 ++ ++ MOTOR_ALM1 +电机报警1 ++ ++ MOTOR_ALM9 +电机报警9 ++ ++ MOTOR_ALM17 +电机报警17 ++ ++ MOTOR_ALM25 +电机报警25 ++ ++ MOTOR_ALM33 +电机报警33 ++ ++ MOTOR_ALM41 +电机报警41 ++ ++ X zero position +X零位 ++ ++ Y zero position +Y零位 ++ ++ X deceleration +X降速 ++ ++ Y deceleration +Y降速 ++ ++ X positive limit +X正限位 ++ ++ Y positive limit +Y正限位 ++ ++ Sewing machine head 1 lifting upper limit +缝纫机头1升降上限位 ++ ++ Sewing machine head 2 lifting upper limit +缝纫机头2升降上限位 ++ ++ Sewing machine head 3 lifting upper limit +缝纫机头3升降上限位 ++ ++ Sewing machine head 4 lifting upper limit +缝纫机头4升降上限位 ++ ++ Lower lifting limit of sewing machine head 0 +缝纫机头0升降下限位 ++ ++ Lower lifting limit of sewing machine head 1 +缝纫机头1升降下限位 ++ ++ Lower lifting limit of sewing machine head 2 +缝纫机头2升降下限位 ++ ++ Lower lifting limit of sewing machine head 3 +缝纫机头3升降下限位 ++ ++ freedom from error +没有错误 ++ ++ Not powered on +没有上电 ++ ++ + Insufficient air pressure +气压不足 ++ ++ + Safe Area Intervention +安全区域介入 ++ ++ + The usage deadline has expired +使用时限已到 ++ ++ Filling data error +填充数据错误 ++ ++ + Working status not allowed +不允许工作状态 ++ ++ control error +控制错误 ++ ++ Motion control chip version error +运动控制芯片版本错误 ++ ++ Waiting for button to lift timeout +等待按钮抬起超时 ++ ++ FPGA reset error +FPGA复位错误 ++ ++ Peripheral not ready +外设未就绪 ++ ++ Transmission data error +传输数据错误 ++ ++ Program version error +程序版本错误 ++ ++ Production completed +完成产量 ++ ++ forward limit +正向限位 ++ ++ Reverse limit +反向限位 ++ ++ Motion alarm +运动报警 ++ ++ Motion limit +运动限位 ++ ++ Exercise emergency stop +运动急停 ++ ++ + Motion parameter error +运动参数错误 ++ ++ + Machine parameter error +机器参数错误 ++ ++ + Input parameter error +输入参数错误 ++ ++ The file is correct +文件正确 ++ ++ Waiting for files +等待文件 ++ ++ Zero successfully +归零成功 ++ ++ Zero error +归零错误 ++ ++ + Coordinate system error +坐标系统错误 ++ ++ + Target position out of range +目标位置越界 ++ ++ + X forward limit +X正向限位 ++ ++ + X reverse limit +X反向限位 ++ ++ + Y forward limit +Y正向限位 ++ ++ + Y reverse limit +Y反向限位 ++ ++ + No Data +无数据 ++ ++ data error +数据错误 ++ ++ + Spindle not in zero position +主轴不在零位 ++ ++ + Rotary shuttle not in zero position +旋梭不在零位 ++ ++ Needle shuttle out of sync +针梭不同步 ++ ++ Rotation out of sync +旋转不同步 ++ ++ The scissors are not returning to their original position +剪刀不在回位 ++ ++ + Machine head not in high position +机头不在高位 ++ ++ Machine head not in low position +机头不在高位 ++ ++ Light curtain intervention +光幕介入 ++ ++ + Broken surface thread +面线断线 ++ ++ Bottom line disconnection +底线断线 ++ ++ + Head lifting timeout +机头升降超时 ++ ++ + Replacing the shuttle core +更换梭芯 ++ ++ Abnormal feeding pressure roller +进料压辊 异常 ++ ++ Abnormal discharge pressure roller +出料压辊 异常 ++ ++ Abnormal discharge and pressing +出料压料 异常 ++ ++ Tensioning device abnormal +张紧装置 异常 ++ ++ Abnormal cloth clamping device +夹布装置 异常 ++ ++ Edge cutting motor blocked +边切电机 阻塞 ++ ++ Cross cutting motor abnormality +横切电机 异常 ++ ++ Password set successfully +密码设置成功 ++ ++ Password setting failed +密码设置失败 ++ ++ Needle motor alarm +针电机报警 ++ ++ Shuttle motor alarm +梭电机报警 ++ ++ X motor alarm +X电机报警 ++ ++ Y motor alarm +Y电机报警 ++ ++ Needle motor reset failed +针电机归零失败 ++ ++ Shuttle motor reset failed +梭电机归零失败 ++ ++ X motor reset failed +X电机归零失败 ++ ++ Y motor reset failed +Y电机归零失败 ++ ++ Slave board communication timeout +从板通讯超时 ++ ++ X motor not in zero position +X电机不在零位 ++ ++ The safety door is not closed +安全门未关闭 ++ ++ The machine head is not in a safe area +机头不在安全区域 ++ ++ Template not in place +模版不到位 ++ ++ Moving up motor limit on head 1 +机头1上移动电机 限位+ ++ ++ X negative limit +X负限位 ++ ++ Y negative limit +Y负限位 ++ ++ Moving down motor limit on head 1 +机头1下移动电机 限位+ ++ ++ Sewing needle parking space 1 +缝纫针停车位1 ++ ++ Sewing needle parking space 2 +缝纫针停车位2 ++ ++ Sewing needle parking space 3 +缝纫针停车位3 ++ ++ Embroidery spindle zero position 9 +绣花主轴零位9 ++ ++ Embroidery spindle zero position 10 +绣花主轴零位10 ++ ++ Sewing spindle 1 needle - parking space +缝纫主轴1针-停车位 ++ ++ Sewing shuttle 1- parking space +缝纫旋梭1-停车位 ++ ++ Sewing shuttle 2- parking space +缝纫旋梭2-停车位 ++ ++ Sewing shuttle 3- parking space +缝纫旋梭3-停车位 ++ ++ Sewing shuttle 4- parking space +缝纫旋梭4-停车位 ++ ++ Sewing machine head 1 - surface thread breakage inspection +缝纫机头1-面线断检 ++ ++ Sewing machine head 3 - surface thread breakage inspection +缝纫机头3-面线断检 ++ ++ Sewing machine head 4 - surface thread breakage inspection +缝纫机头4-面线断检 ++ ++ Sewing thread trimming return 1 +缝纫下剪线回位1 ++ ++ Sewing thread trimming return 2 +缝纫下剪线回位2 ++ ++ Sewing thread trimming return 3 +缝纫下剪线回位3 ++ ++ Sewing thread trimming return 4 +缝纫下剪线回位4 ++ +GLOBAL ++ ++ Resolution +分辨率 ++ ++ Language +语言 ++ ++ Machine type +机器类型 ++ ++ Product type +产品类型 ++ ++ Year +年 ++ ++ Month +月 ++ ++ Day +天 ++ ++ Hour +时 ++ ++ Minute +分 ++ ++ Second +秒 ++ ++ Communication method +通讯方式 ++ ++ Network:0;SerialPort:1 +网口:0;串口:1 ++ ++ Chinese:0;English:1 +中文:0;英语:1 ++ ++ Server IP settings +Gateway server IP settings +服务器IP设置 ++ ++ Server port settings +Gateway server port settings +服务器端口设置 ++ ++ Local IP settings +本地IP设置 ++ ++ Local port settings +本地端口设置 ++ ++ 001 McHighSingleQui:0;002 FiveHeadPrecisionSewing:1;003 ClothingMac:2;004 multineedlerotary:3 +001 高速单针机:0;002 五头精密缝:1;003 服装机:2;004 多针旋梭:3 ++ ++ Is there a Richpeace logo +是否有富怡标志 ++ ++ Factory expects delivery time +工厂预计交货时间 ++ ++ Debugging progress +调试进度 ++ ++ ProductNull: +无: ++ ++ Whether there is a Automatic shuttle change function +是否有自动换梭功能 ++ ++ Parameter is classified +参数是否分类显示 ++ ++ HMI decrypt +界面解密 ++ ++ Gateway connection method +网关连接方式 ++ ++ Serial port:0; Network port:1 +Serial port1:0;Serial port2:1;Network port:2 +串口:0;网口:1 ++ ++ Input rack number +机架号输入 ++ ++ Network settings +网络设置 ++ +HeadSpacingSheetDialog ++ ++ Dialog ++ + ++ PageNums: 0/0 +页数:0/0 ++ ++ Sub title ++ + ++ Sub title < Title ++ + ++ pageNum: +页数: ++ ++ PageNum: 0/0 +页数: 0/0 ++ ++ + + + Prompt +提示 ++ ++ + USB flash drive is not detected! +未检测到优盘! ++ ++ Export successful +导出成功! ++ ++ Import successful! +导入成功! ++ +HighSingleQui ++ ++ HMI Configuration +界面配置 ++ ++ Interface debug mode +界面调试模式 ++ ++ Delete configure file +删除配置文件 ++ ++ Machine parameters +机器参数 ++ ++ Work parameters +工作参数 ++ ++ Flip style +翻转式样 ++ ++ normalP:0;nRight90P:1;nRight180P:2;nRight270P:3;mirrorP:4;mRight90P:5;mRight180P:6;mRight270P:7 ++ + ++ Rotation angle +旋转角度 ++ ++ + + + + + + + + + + + + + + + + + + + + + + mm +% ++ + ++ Step size +针步大小 ++ ++ Reinforcement method +加固方式 ++ ++ Tight locking:0;Reinforced locking:1 +密针锁针:0;加固锁针:1 ++ ++ Reinforcement needles +加固针数 ++ ++ pin +针 ++ ++ Reinforcement frequency +加固次数 ++ ++ Angle correction offset +角度修正量 ++ ++ Angle correction x positive +角度修正X正 ++ ++ Angle correction x negative +角度修正X负 ++ ++ Angle correction y positive +角度修正Y正 ++ ++ Angle correction y negative +角度修正Y负 ++ ++ Left +左边 ++ ++ Front +前边 ++ ++ Automatic shuttle changing device +自动换梭装置 ++ ++ + + + + + No:0;Have:1 +无:0;有:1 ++ ++ Infrared device +红外装置 ++ ++ + + + + Normally closed:0;Normally open:1 +正常关闭:0;正常打开:1 ++ ++ Pneumatic device +气压装置 ++ ++ Power-on device +上电装置 ++ ++ Safety door device +安全门装置 ++ ++ Manual and automatic button device +手自动按钮装置 ++ ++ X movable area positive boundary +X可移动区域正边界 ++ ++ Y movable area positive boundary +Y可移动区域正边界 ++ ++ X Sewing area Negative boundary +X可缝纫区域负边界 ++ ++ X Sewing area Positive margin +X可缝纫区域正边界 ++ ++ Y Sewing area Negative boundary +Y可缝纫区域负边界 ++ ++ Y Sewing area Positive margin +Y可缝纫区域正边界 ++ ++ Encoder coefficient molecule +进料编码器系数分子 ++ ++ Zero tangent distance +零切距离 ++ ++ Feeding device +进料装置 ++ ++ Crosscutting device +横切装置 ++ ++ Cloth clamping device +夹布装置 ++ ++ Tensioning device +张紧装置 ++ ++ Edge cutting device +边切装置 ++ ++ sewing work speed +主轴缝纫工作转速 ++ ++ + + + r/min +r/min ++ ++ Spindle Back needle speed +主轴回针转速 ++ ++ Sewing moving frame +缝纫动框方式 ++ ++ Continuous:0;Intermittent:1 +连续:0;间歇式:1 ++ ++ Sewing acceleration and deceleration mode +缝纫加减速方式 ++ ++ No acceleration or deceleration:0;Xy sine acceleration and deceleration:1 +无加速或减速:0;XY正弦加速度和减速度:1 ++ ++ Sewing machine head rotating manner +缝纫机头旋转方式 ++ ++ Continuous rotation:0;Xy intermittent rotation:1 +连续旋转:0;XY间歇旋转:1 ++ ++ Sewing head deceleration mode +缝纫机头加减速方式 ++ ++ No acceleration or deceleration:0;Intermittent acceleration and deceleration:1 +无加速或减速:0;间歇加减速:1 ++ ++ + + + + + + Not allow:0;Allowed:1 +不允许:0;允许:1 ++ ++ Cut lines allow +剪线允许 ++ ++ Equal ratio ++ + ++ Thread loosening is allowed during thread cutting +剪线时松线允许 ++ ++ During thread cutting, the stay wire is allowed +剪线时拉线允许 ++ ++ Thread clamping is allowed during thread cutting +剪线时夹线允许 ++ ++ It is allowed to lift the presser foot during thread trimming +剪线时提升压脚允许 ++ ++ Lifting machine head thread cutting is allowed during thread cutting +剪线时提升机头剪线允许 ++ ++ The thread clamping of the lifting head is allowed during thread cutting +剪线时提升机头夹线允许 ++ ++ It is allowed to hook the thread at the foot of the presser during thread cutting +剪线时在压脚下勾线允许 ++ ++ Needle withdrawal allowed during thread trimming +剪线时退针允许 ++ ++ Buckle the thread allowed during thread trimming +剪线时扣线允许 ++ ++ Number of broken wires +断线检测针数 ++ ++ + Needles +针 ++ ++ Change bobbin Reminder function +换梭芯提醒功能 ++ ++ Not:0;Delay reminder by length:1;Count by number of slices:2;Immediately reminder by length:3 +未启用:0;按长度划分的延迟提醒:1;按切片数计数:2;按长度立即提醒:3 ++ ++ Bottom line length +底线长度 ++ ++ Number of shuttles +换梭片数计数 ++ ++ times +次 ++ ++ Refueling method selection +加油方式选择 ++ ++ No:0; According to working hours:1; According to the number of working stitches:2; Persistent refueling:3 +不加油:0;按工作时间间断加油:1;按工作针数间歇加油:2;持续加油:3 ++ ++ Refueling needles interval +加油针数间隔 ++ ++ Refueling duration +加油持续时长 ++ ++ + + s +s ++ ++ Parking position selection after completion +完成后停车位置选择 ++ ++ Current:0;Starting:1;Anchor:2;Feeding:3;Offset:4 +当前点:0;起始点:1;定位点:2;上料点:3;偏移点:4 ++ ++ Offset point coordinate valid flag +偏移点坐标有效标志 ++ ++ + Invalid:0;X is valid:1;Y is valid:2;XY is valid:3 +无效:0;X有效:1;Y有效:2;XY同时有效:3 ++ ++ Offset point coordinate X +偏移点坐标X ++ ++ Offset point coordinate Y +偏移点坐标Y ++ ++ Threading point coordinate effective mark +穿线点坐标有效标志 ++ ++ Threading point coordinates X +穿线点坐标X ++ ++ Threading point coordinates Y +穿线点坐标Y ++ ++ Production preset +产量预设 ++ ++ Trimming frame displacement +剪线动框位移 ++ ++ Automatic threading back point is allowed during sewing +缝纫时自动回穿线点允许 ++ ++ Lifting and lowering of frame crossing machine head in sewing room +缝纫间越框机头升降 ++ ++ Moving basket Loose line +移框松线允许 ++ ++ Moving basket Clamp line +移框夹线允许 ++ ++ Frame moving and automatic frame pressing allowed +移框自动压框允许 ++ ++ Allowed to move frame and thread +移框扣线允许 ++ ++ Software limit XY move allowed +软件限位XY移动允许 ++ ++ Thread trimming moving frame direction +剪线动框方向 ++ ++ Fixed frame:0;Left:1;Forward:2;Right:3;Backward:4 +不动框:0;向左:1;向前:2;向右:3;向后:4 ++ ++ Spindle corner speed +主轴拐角转速 ++ ++ Minimum speed deviation angle +降速最小偏差角度 ++ ++ Auto Zero after power on +开机自动归零 ++ ++ Automatic drawing is allowed +自动拉料允许 ++ ++ The opposite side is allowed when feeding +进料时对边允许 ++ ++ Allowing distribution during feeding +进料时展布允许 ++ ++ Medium cutting is allowed during feeding +进料时中切允许 ++ ++ During feeding, it is allowed to cut across the edge +进料时中切对边允许 ++ ++ The thread loosening is allowed when the head is lifting +机头升降时松线允许 ++ ++ Secure input light curtain allows +安全输入光幕允许 ++ ++ Safety input pressure allowed +安全输入气压允许 ++ ++ Safe input power-on signal allowed +安全输入上电信号允许 ++ ++ Safe input emergency door allowed +安全输入安全门允许 ++ ++ Manual and automatic safe input +安全输入手自动允许 ++ ++ Loop work allowed +循环工作允许 ++ ++ Shuttle refueling duration +梭加油持续时长 ++ ++ + Replace the punch count value +更换冲头计数值 ++ ++ Starting angle of sewing frame +缝纫动框起始角度 ++ ++ Trimming completion angle +缝纫动框起始角度 ++ ++ Spindle parking sensor angle +主轴停车传感器角度 ++ ++ Spindle thread cutting speed +主轴剪线转速 ++ ++ Enable +使能 ++ ++ Disable +失能 ++ ++ JogP +正转 ++ ++ JogN +反转 ++ ++ Zero +归零 ++ ++ Open +打开 ++ ++ Close +关闭 ++ ++ X to move motor +X向移动电机 ++ ++ Y to move motor +Y向移动电机 ++ ++ Spindle motor +主轴电机 ++ ++ Needle motor +针电机 ++ ++ Shuttle motor +梭电机 ++ ++ Lifting motor +升降电机 ++ ++ Lower scissors to cut thread +下剪刀剪线 ++ ++ Buckle the bottom line +扣底线 ++ ++ Elastic thread +松紧线 ++ ++ oil +加油 ++ ++ headlamp +照明灯 ++ ++ Sewing machine head lifting +缝纫机头升降 ++ ++ Sandwich line +夹面线 ++ ++ Shuttle changing device grabbing +换梭装置抓取 ++ ++ Shuttle changer swing +换梭装置摆动 ++ ++ Shuttle changer rotation +换梭装置旋转 ++ ++ Sewing Blow +缝纫吹气 ++ ++ AllToZero +全部归零 ++ ++ BackThread +回穿线点 ++ ++ BackOffset +回偏移点 ++ ++ BackZero +回零点 ++ ++ CountReset +底线计数清零 ++ ++ OutputReset +产量清零 ++ ++ NeedZeroPos +对针零位 ++ ++ ShutZeroPos +对梭零位 ++ ++ Signal +传感器信号 ++ ++ Action +控制动作 ++ ++ HMIUpgrade +界面升级 ++ ++ MCUpgrade +主控升级 ++ ++ ParaImport +参数导入 ++ ++ ParaExport +参数导出 ++ ++ SoftwareSet +软件设置 ++ ++ Authorization +软件授权 ++ ++ Network +网络管理 ++ ++ Time +时间设置 ++ ++ Version +版本信息 ++ ++ Root +超级用户 ++ ++ Select +花样选择 ++ ++ Para +花样参数 ++ ++ Width +宽度 ++ ++ Height +高度 ++ ++ Allow for needle starting and thread loosening +起针松线允许 ++ ++ Needle and thread clamping allowed +起针夹线允许 ++ ++ Do not trim:0;Automatic thread trim:1;Finally trim:2;Data trim:3 +Do not trim: 0;Automatic thread trim:1;Finally trim:2;Data trim:3 +不剪线:0;自动:1;最后剪线:2;数据剪线:3 ++ ++ Sewing speed reduction mode +缝纫降速模式 ++ ++ Auto:0;Param:1;Not:2 +自动:0;参数:1;不降速:2 ++ ++ Front_Back +快进快退 ++ ++ N/S_Proof +针梭校对 ++ ++ HeadLifting +机头升降 ++ ++ ThreadCut +手动剪线 ++ ++ ProcessReset +流程复位 ++ ++ Simulated +模拟缝纫 ++ ++ Import +花样导入 ++ ++ Export +花样导出 ++ ++ Delete +花样删除 ++ ++ OperatPara +操作参数 ++ ++ ActionSet +动作设定 ++ ++ SpeedPara +速度参数 ++ ++ LimitPara +限位参数 ++ ++ MCPara +机器参数 ++ ++ Start button 1 +启动按钮1 ++ ++ Pause button 1 +暂停按钮1 ++ ++ Air pressure detection 1 +气压检测1 ++ ++ Security input 1 +安全输入1 ++ ++ X zero position +X零位 ++ ++ Y deceleration +Y降速 ++ ++ X positive limit +X正限位 ++ ++ Y positive limit +Y正限位 ++ ++ Sewing machine head 1 lifting upper limit +缝纫机头1升降上限位 ++ ++ Lower lifting limit of sewing machine head 1 +缝纫机头1升降下限位 ++ ++ Sewing spindle 1 needle - parking space +缝纫主轴1针-停车位 ++ ++ Sewing shuttle 1- parking space +缝纫旋梭1-停车位 ++ ++ Sewing machine head 1 - surface thread breakage inspection +缝纫机头1-面线断检 ++ +ImportHPGL ++ ++ Encrypted file parsing error! ++ + +MainWidget ++ ++ Richpeace Embroidery Control System +富怡绣花控制系统 +富怡绣花控制系统 ++ ++ 2021/03/08 8:37:16 ++ + ++ + + + + + + + + + + + + + PatternSet +花样设置 ++ ++ Assist +辅助功能 +辅助功能 ++ ++ ParaSet +参数设定 +参数设定 ++ ++ Shortcut +快捷功能 +快捷功能 ++ ++ Main +主界面 +主界面 ++ ++ 4999 ++ + ++ XPlatForm-RP-HMI-L1910-V210713 ++ + ++ + + Root +超级用户 ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + shortcut ++ + ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + assist +辅助功能 ++ ++ Pattern +花样设置 +花样设置 ++ ++ + + + + + + + + + + + + + TextLabel ++ + ++ + + + + + + + + + + + + + labelParaType ++ + ++ Forward or back +快进快退 +快进快退 ++ ++ Init windows... +初始化窗体... ++ ++ Init communication... +初始化通讯... ++ ++ Connnecting... +Status:Connnecting... +连接中... ++ ++ + Connected +Status:Connected +已连接 ++ ++ + + Not connected +Status:Not connected +状态 +未连接 ++ ++ Ready +Status:Ready +已就绪 ++ ++ Working +Status: Working +工作中 ++ ++ + Pattern para +花样参数 ++ ++ Prompt +提示 ++ ++ Loading patterns, please wait... +正在加载花样,请等待... ++ ++ Setting workable area +设置可工作区域 ++ ++ + + Parameter setting +参数设置 ++ ++ Pattern selection +花样选择 ++ ++ Pattern import +花样导入 ++ ++ Pattern export +花样导出 ++ ++ Pattern delete +花样删除 ++ ++ Richpeace Quilting Control System +富怡绗缝控制系统 ++ ++ Quilting Control System +绗缝控制系统 ++ ++ FileName +文件 ++ ++ Index +索引 ++ ++ StartPoint +起始点 ++ ++ LocatePoint +定位点 ++ ++ Range +范围 ++ ++ Position +位置 ++ ++ Production +产量 ++ ++ Pattern setting > Pattern selection +花样设置 > 花样选择 ++ ++ Auxiliary function > Sensor signal +辅助功能>传感器信号 ++ ++ Auxiliary function > Control action +辅助功能 > 控制动作 ++ ++ Accessibility > Software setting +辅助功能 > 软件设置 ++ ++ Accessibility > Network Manage +辅助功能 > 网络管理 ++ ++ Accessibility > Time setting +辅助功能 > 时间设置 ++ ++ Accessibility > Spindle test +辅助功能 > 主轴研车 ++ ++ + + Accessibility > Root +辅助功能 > 超级用户 ++ ++ Pattern setting > Pattern import +花样设置 > 花样导入 ++ ++ Pattern setting > Pattern export +花样设置 > 花样导出 ++ ++ Pattern setting > Pattern delete +花样设置 > 花样删除 ++ ++ Simulated sewing +模拟缝纫 ++ ++ Normal operation +正常工作 ++ ++ Undefined error, +未定义错误, ++ ++ Pattern setting > Head spacing +花样设置 > 机头间距 ++ ++ Pattern setting > Pattern para +花样设置 > 花样参数 ++ ++ Limit parameter +限位参数 ++ ++ Speed control parameters +速度参数 ++ ++ Action settings +动作设定 ++ ++ Operating parameters +操作参数 ++ ++ Machine parameters +机器参数 ++ ++ Parameter setting > +参数设置 > ++ ++ Parameter setting > Parameter setting +参数设定 > 参数设定 ++ ++ Sensor signal +传感器信号 ++ ++ Control action +控制动作 ++ ++ + Accessibility +辅助功能 ++ ++ Time setting +时间设置 ++ ++ Spindle test +主轴研车 ++ +MainWidgetFunction ++ ++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Prompt +提示 ++ ++ + + + USB flash drive is not detected! +未检测到优盘! ++ ++ The program is corrupted, please re-upgrade after replacing the program! +程序已损坏,请更换程序后重新升级! ++ ++ The file format is wrong, please select again! +文件格式错误,请重新选择! ++ ++ + File size not match, invalid file! +文件大小不匹配,无效的参数文件! ++ ++ Data check error, invalid file! +数据校验错误,无效的参数文件! ++ ++ Parameters imported successfully! +参数导入成功! ++ ++ File head not match, invalid file! +文件头不匹配,无效的参数文件! ++ ++ Parameter Import +参数导入 ++ ++ Auxiliary Function > Parameter Import +Parameter Import < Auxiliary Function +辅助功能 > 参数导入 ++ ++ + + + MC Upgrade +主控升级 ++ ++ Auxiliary Function > MC Upgrade +MC Upgrade < Auxiliary Function +辅助功能 > 主控升级 ++ ++ Error Log +错误日志 ++ ++ Auxiliary Function > Error Log +辅助功能 > 错误日志 ++ ++ Breakage Log +断线日志 ++ ++ Auxiliary Function > Breakage Log +辅助功能 > 断线日志 ++ ++ Debug Info +调试信息 ++ ++ Auxiliary Function >Debug Info +辅助功能 > 调试信息 ++ ++ ErrorLog +错误日志 ++ ++ Auxiliary Function > ErrorLog +辅助功能 > 错误日志 ++ ++ + ssid is empty! +ssid为空! ++ ++ + Settings require screen restart to take effect! +设置需要重启屏幕才生效! ++ ++ IP input +IP输入 ++ ++ Journal exported successfully! +文件日志导出成功! ++ ++ Journal exported failed! +文件日志导出失败! ++ ++ Password input **** +密码输入 **** ++ ++ reset parameters password successfully logged in! +重置参数密码成功登入! ++ ++ Whether to exit the program? +是否退出程序? ++ ++ Simulated sewing +模拟缝纫 ++ ++ Whether to switch working status +是否切换工作状态 ++ ++ Manual thread cutting +手动剪线 ++ ++ makeup sewing +索引 ++ ++ Head lifting and lowering +机头升降 ++ ++ Head lifting +机头上升 ++ ++ Set anchor point +定定位点 ++ ++ Back shuttle pos +回换梭位 ++ ++ Needle shuttle adjust +针梭校对 ++ ++ AllSpindleZeroPositions +所有主轴零位 ++ ++ AllSpindleHookLines +所有主轴勾线 ++ ++ AllSpindleJogs +所有主轴点动 ++ ++ NeedleShuttleProofreading +针梭校对 ++ ++ AllMainShaftRun +所有主轴研车 ++ ++ HMI Upgrade +界面升级 ++ ++ Parameters exported successfully! +参数导出成功! ++ ++ All to zero +全部归零 ++ ++ + + + + + + + + + + + + + + + + + + + + The machine is about to move, please pay attention to safety! +机器即将运动,请注意安全! ++ ++ + All to reset +流程复位 ++ ++ Whether to reset the output? +是否重置产量? ++ ++ If all process to reset? +是否全部流程复位? ++ ++ Spindle jog +主轴点动 ++ ++ Spindle rotate angle +主轴旋转角度 ++ ++ Back work point +回工作点 ++ ++ Back to origin +回原点 ++ ++ Set start point +Set embroidery point +定起绣点 ++ ++ + Whether to set the current point as the start point? +是否将当前点设置为起绣点? ++ ++ Back anchor point +回定位点 ++ ++ File bytes are 0, please check the file! +文件字节为0,请检查文件! ++ ++ Back embroidery point +回起绣点 ++ ++ Set offset point +定偏移点 ++ ++ Whether to set the current point as the offset point? +是否将当前点设置为偏移点? ++ ++ Back offset point +回偏移点 ++ ++ Border check +边框检查 ++ ++ Trim +剪线 ++ ++ Whether to set to change a shuttle automatically? +是否设置自动换一个梭? ++ ++ The machine is about to cut the thread, please pay attention to safety! +机器即将剪线,请注意安全! ++ ++ Failed to initialize wlan0! +初始化wlan0失败! ++ ++ Failed to search for WiFi list. Please try again later! +搜索wifi列表失败,请稍后重试! ++ ++ dynamic +动态 ++ ++ static +静态 ++ ++ Failed to obtain IP. Please check the settings! +获取IP失败,请检查设置! ++ ++ WIFI ++ + ++ Auxiliary Function > WIFI +辅助功能 > WIFI ++ ++ Lower cutter +下剪线 ++ ++ The scissors are about to move, please pay attention to safety! +剪刀即将动作,请注意安全! ++ ++ Simulate frame +空走边框 ++ ++ Process reset +流程复位 ++ ++ The machine is about to reset, please pay attention to safety! +机器即将流程复位,请注意安全! ++ ++ The machine is about to oil! +机器即将加油! ++ ++ Goto zero pos +框架归零 ++ ++ Set work range +定工作范围 ++ ++ If automatically set work range? +是否自动定工作范围? ++ ++ Manual oil +手动加油 ++ ++ Bottom line detection +底线检测 ++ ++ Face line detection +面线检测 ++ ++ Exit successfully! +成功退出! ++ ++ Shuttle count reset +Shuttle change +梭盘计数复位 ++ ++ The machine is about to change the shuttle automatically! +机器即将自动换梭! ++ ++ System info +版本信息 ++ ++ Is the bottom line count reset? +Is the bottom line count reset ? +是否底线计数复位? ++ ++ Are you sure to ManualSwitch? +Are you sure to ManualSwitch? +是否手动工作状态切换? ++ ++ Are you sure to AutoSwitch? +Are you sure to AutoSwitch? +是否自动工作状态切换? ++ ++ Undefined error, +未定义错误, ++ ++ Password input * +Password input ※ +密码输入 ※ ++ ++ Password input ** +Password input ※※ +密码输入 ※※ ++ ++ Is the version restored? +是否版本恢复? ++ ++ Modify the first level password +修改一级密码 ++ ++ The two passwords are inconsistent! +新密码和确认密码不一致! ++ ++ Password reset complete! +密码修改成功! ++ ++ Do you delete the configuration file? +是否删除配置文件? ++ ++ The settings take effect after restarting the interface! +重启界面后设置生效! ++ ++ Import csv file successful! +成功导入csv文件! ++ ++ Do you delete the csv file? +是否删除csv文件? ++ ++ Reset succeeded! +重置成功! ++ ++ Whether to enter debug mode? +是否进入调试模式? ++ ++ whether to exit debug mode? +是否退出调试模式? ++ ++ Please log in to super user again! +请重新登录超级用户! ++ ++ Is the pattern clear? +是否花样总清? ++ ++ Delete complete! +删除完成! ++ ++ Whether to shut down the computer? +是否关闭计算机? ++ ++ Production statistics +生产统计 ++ ++ No connection +未连接 ++ ++ Warrant +授权 ++ ++ Total number of patterns processed: +总共加工花样数量: ++ ++ Total number of embroidery: +总刺绣针数: ++ ++ Pattern name: +花样名称: ++ ++ Pattern break line num: +花样断线次数: ++ ++ Head +机头 ++ ++ break line num: +断线次数: ++ ++ Day +天 ++ ++ Hour +时 ++ ++ Minutes +分钟 ++ ++ The remaining available time of the machine is +机器剩余可用时间为 ++ ++ Failed to upgrade the main control system! +主控系统升级失败! ++ ++ Failed to send data file! +发送数据文件失败! ++ ++ The main control system has been successed, waiting until machine restart +主控系统升级成功,请等待机器重启 ++ ++ System will restart %1 s later +系统将在 %1 秒后重启 ++ ++ The data file is send successfully! +数据文件发送成功! ++ ++ Main control system is being upgraded... +主控系统升级中... ++ ++ Auxiliary Function > HMI Upgrade +辅助功能 > 界面升级 ++ ++ Auxiliary Function > Production statistics +辅助功能 > 生产统计 ++ ++ Data file sending... +数据文件发送中... ++ ++ Password input +密码输入 ++ ++ Setting workable area +设置可工作区域 ++ ++ + + The password is wrong,please re-enter! +密码错误,请重新输入密码! ++ ++ HMI decrypt +界面解密 ++ ++ The interface program is licensed, and then take effect after restarting, please restart manually! +界面程序授权成功,重启后生效,请手动重启! ++ ++ Password error, interface program authorization failed! +密码错误,界面程序授权失败! ++ +McHeadDialog ++ ++ Dialog ++ + ++ + + + + + + + PushButton ++ + +MultiNeedleRotary ++ ++ HMI Configuration +界面配置 ++ ++ Interface debug mode +界面调试模式 ++ ++ Delete configure file +删除配置文件 ++ ++ Machine parameters +机器参数 ++ ++ Work parameters +工作参数 ++ ++ startX +起始点X ++ ++ + + + mm +毫米 ++ ++ startrY +起始点Y ++ ++ + + r/min +转/分钟 ++ ++ Sewing main shaft working speed +主轴缝纫工作转速 ++ ++ Main shaft zero reset speed +主轴归零转速 ++ ++ Main shaft running speed +主轴运转转速 ++ ++ + XY zero reset speed +xy归零运行速度 ++ ++ + + + + mm/s +毫米/秒 ++ ++ XY manual movement speed 1 +xy手动移动速度1 ++ ++ XY manual movement speed 2 +xy手动移动速度2 ++ ++ XY manual movement speed 3 +xy手动移动速度3 ++ ++ Work head selection 1 +工作头选择1 ++ ++ + Not allow:0;allowed:1 ++ + ++ Work head selection 2 +工作头选择2 ++ ++ Production preset +产量预设 ++ ++ + No. of stitch detect if thread broken +断线检测针数 ++ ++ Needle ++ + ++ + Bobbin thread length +底线长度 ++ ++ Bobbin change reminder function +换梭芯提醒功能 ++ ++ Not enabled:0;Delay reminder by length:1;Count by number of slices:2;Immediately reminder by length:3 +不启用该功能:0;按长度计数延迟提醒:1;按片数计数:2;按长度立刻提醒:3 ++ ++ Secure input light curtain allows +安全输入光幕允许 ++ ++ Safety input pressure allowed +安全输入气压允许 ++ ++ Safe input power-on signal allowed +安全输入上电信号允许 ++ ++ Safe door allowed ++ + ++ X to move motor +X向移动电机 ++ ++ Y to move motor +Y向移动电机 ++ ++ All spindle zero positions +所有主轴 零位 ++ ++ All Spindle Hook Lines positions +所有主轴 勾线 ++ ++ All spindle jogs positions +所有主轴 点动 ++ ++ All_Zero +全部归零 ++ ++ Front_Back +快进快退 ++ ++ AllSpleZero +所有主轴零位 ++ ++ Signal +传感器信号 ++ ++ Action +控制动作 ++ ++ HMIUpgrade +界面升级 ++ ++ MCUpgrade +主控升级 ++ ++ ParaImport +参数导入 ++ ++ ParaExport +参数导出 ++ ++ Setting +软件设置 ++ ++ Authorize +软件授权 ++ ++ Network +网络管理 ++ ++ Time +时间设置 ++ ++ Version +版本信息 ++ ++ Root +超级用户 ++ ++ Para +花样参数 ++ ++ Select +花样选择 ++ ++ Import +花样导入 ++ ++ Export +花样导出 ++ ++ Delete +花样删除 ++ ++ OperatPara +操作参数 ++ ++ ActionSet +动作设定 ++ ++ SpeedPara +速度参数 ++ ++ LimitPara +限位参数 ++ ++ MCPara +机器参数 ++ ++ Start button 1 +启动按钮1 ++ ++ Pause button 1 +暂停按钮1 ++ ++ Jog button 1 +点动按钮1 ++ ++ Open frame button 1 +开框按钮1 ++ +NumerInputDialog ++ ++ Dialog ++ + ++ C ++ + ++ (0~3000)rmp ++ + ++ Number input +数字输入 ++ ++ ← ++ + +ParameterSetDialog ++ ++ Dialog ++ + ++ PageNums: 1/1 +页数:1/1 ++ ++ Sub title ++ + ++ Sub title < Title ++ + ++ Repetitions +反复绣 ++ ++ + pageNum: +页数: ++ ++ HMI Configuration +界面配置 ++ ++ Root > HMI Configuration +超级用户 > 界面配置 ++ ++ Machine parameters +机器参数 ++ ++ Work parameters +工作参数 ++ ++ Root > Machine parameters +超级用户 > 机器参数 ++ ++ Input +输入 ++ ++ Root > Work parameters +超级用户 > 工作参数 ++ ++ Local port settings +本地端口设置 ++ ++ + Local IP settings +本地IP设置 ++ ++ IOT Configuration +物联网配置 ++ ++ Root > IOT Configuration +Root >IOT Configuration +超级用户 > 物联网配置 ++ ++ Network Settings +网络设置 ++ ++ IOT Configuration > Network Settings +IOT Configuration >Network Settings +物联网配置 > 网络设置 ++ ++ Repetitions : 0 +反复次数:0 ++ ++ Server IP settings +服务器IP设置 ++ ++ Server Port settings +服务器端口设置 ++ ++ Local Port settings +本口端口设置 ++ ++ Board IP settings +主板IP设置 ++ ++ Board port settings +主板端口设置 ++ ++ + + Root +超级用户 ++ ++ + + Accessibility > Root +辅助功能 > 超级用户 ++ ++ + + + + + Network error +网络错误 ++ ++ + + read parameter... +读取参数中... ++ ++ + + No connection +未连接 ++ ++ + + + + + + Prompt +提示 ++ ++ + The settings take effect after restarting the interface! +重启界面后设置生效! ++ ++ + Network settings are completed, re-establish after reboot +网络设置完成,需重启后重新建立连接 ++ ++ The time setting is completed and will take effect after restart +时间设置完成,重启后生效 ++ ++ Unreasonable time setting, please reset +时间设置不合理,请重新设置 ++ ++ Time setting failed, please reset +时间设置失败,请重新设置 ++ ++ Connection mode changes, take effect after the reboot! +连接方式改变,重启界面后生效! ++ ++ Whether to recover the default parameters for the board? +是否恢复为主板默认参数? ++ +PassWordDialog ++ ++ Dialog ++ + ++ Password +密码 ++ ++ 9 ++ + ++ 1 ++ + ++ 2 ++ + ++ ← ++ + ++ 3 ++ + ++ 6 ++ + ++ 8 ++ + ++ C ++ + ++ 0 ++ + ++ 5 ++ + ++ 7 ++ + ++ 4 ++ + ++ Prompt +提示 ++ ++ IP settings are unreasonable! +IP设置不合理! ++ +PatternManageWidget ++ ++ Form ++ + ++ PageNums: 0/0 +页数:0/0 ++ ++ Sub title < Title ++ + ++ Sub title ++ + ++ + 1000.0 ++ + ++ W ++ + ++ 500.0 ++ + ++ 999 ++ + ++ H ++ + ++ 1000000 ++ + ++ Y ++ + ++ X ++ + ++ 800.0 ++ + ++ dst ++ + ++ C ++ + ++ N ++ + ++ pageNum: +页数: ++ ++ + + + + + Prompt +提示 ++ ++ Over 1.28 million stitches, can not be imported! +针数超过128万,不能导入! ++ ++ Format error, can not be imported! +格式错误,不能导入! ++ ++ This file already exists! +此文件已存在! ++ ++ Rename +重命名 ++ ++ Importing +正在导入 ++ ++ Exporting +正在导出 ++ ++ Import complete +导入完成 ++ ++ Export complete +导出完成 ++ ++ USB flash drive is not detected! +未检测到优盘! ++ ++ Whether to delete the pattern? +是否删除花样? ++ ++ Operation screen +操作屏 ++ ++ USB +优盘 ++ ++ + + Pattern Import +花样导入 ++ ++ + + Pattern Import < Pattern setting +花样导入 < 花样设置 ++ ++ Pattern Export +花样导出 ++ ++ Pattern Export < Pattern setting +花样导出 < 花样设置 ++ ++ new folder +新文件夹 ++ ++ This folder already exists! +此文件夹已经存在! ++ +PatternSelectWidget ++ ++ Form ++ + ++ Name: +花样名: +花样名: ++ ++ N ++ + ++ H +C ++ + ++ W ++ + ++ + X ++ + ++ + Y ++ + ++ Width +宽 ++ ++ NeedleNum +针杆数 ++ ++ Name +名称 ++ ++ Height +高 ++ ++ Pattern Select +花样选择 +花样选择 ++ ++ Pattern Select < Pattern Setting +花样选择 < 花样设置 +花样选择 < 花样设置 ++ ++ PageNums: 0/0 ++ + ++ PageNum: 0/0 +页数: 0/0 ++ ++ pageNum: +页数: ++ ++ Prompt +提示 ++ ++ The number of stitches of the selected pattern has reached the upper limit (2 million stitches), and it cannot be embroidered! +所选花样针数已达上限(200万针),不可绣作! ++ +PromptDialog ++ ++ Dialog ++ + ++ Prompt +提示 ++ ++ ID: ++ + ++ Password: +密码: +密码: ++ ++ ID ++ + ++ DecryptInfo +解密信息 ++ ++ DecryptInfo: +解密信息: +解密信息: ++ ++ Spindle angle: +主轴角度: +主轴角度: ++ ++ deg +度 +度 ++ ++ New Password: +密码: +新密码: ++ ++ Confirm Password: +解密信息: +确认密码: ++ ++ X + +X + ++ ++ X - +X - ++ ++ Y + +Y + ++ ++ Y - +Y - ++ ++ Board +主板 ++ ++ Build Time: +编译时间: ++ ++ Unlimited time +无时间限制 ++ ++ Time has run out +时间已用完 ++ ++ Day +天 ++ ++ Hour +时 ++ ++ Minutes +分钟 ++ ++ ID: %1 + ++ + ++ Password: %1 + +密码: %1 + ++ ++ Time: %1 +时间: %1 ++ ++ Warrant +授权 ++ ++ HMI decrypt +界面解密 ++ ++ Spindle angle rotation +主轴角度旋转 ++ ++ New Password input +设置新密码 ++ ++ Confirm Password input +确认新密码 ++ +QObject ++ ++ (0x0002)Insufficient air pressure +Insufficient air pressure +(0x0002)气压不足 ++ ++ (0x0003)safe area error +safe area error +(0x0003)安全区域介入 ++ ++ (0x0004)Expiration of use +Expiration of use +(0x0004)使用时限已到 ++ ++ (0x0005)Driver alarm +Driver alarm +(0x0005)驱动器报警 ++ ++ (0x0006)Fill data error +Fill data error +(0x0006)填充数据错误 ++ ++ (0x0007)Not allowed to work +Not allowed to work +(0x0007)不允许工作状态 ++ ++ (0x0008)Control error +Control error +(0x0008)控制错误 ++ ++ (0x0009)Motion control chip version error +Motion control chip version error +(0x0009)运动控制芯片版本错误 ++ ++ (0x000A)Waiting for button to lift timeout +Waiting for button to lift timeout +(0x000A)等待按钮抬起超时 ++ ++ (0x000B)FPGA Reset +FPGA Reset +(0x000B)FPGA复位 ++ ++ (0x000C)Peripheral Device not ready +Peripheral Device not ready +(0x000C)外设未就绪 ++ ++ (0x000D)Transmission data error +Transmission data error +(0x000D)传输数据错误 ++ ++ (0x000E)Program version error +Program version error +(0x000E)程序版本错误 ++ ++ (0x000F)Complete output +Complete output +(0x000F)完成产量 ++ ++ (0x0010)Positive limit +Positive limit +(0x0010)正向限位 ++ ++ (0x0011)Negative limit +Negative limit +(0x0011)反向限位 ++ ++ (0x0012)Motion alarm +Motion alarm +(0x0012)运动报警 ++ ++ (0x0013)Motion limit +Motion limit +(0x0013)运动限位 ++ ++ (0x0014)Emergency stop +Emergency stop +(0x0014)运动急停 ++ ++ (0x0015)Motion parameters error +Motion parameters error +(0x0015)运动参数错误 ++ ++ (0x0016)Machine parameters error +Machine parameters error +(0x0016)机器参数错误 ++ ++ (0x0017)Input parameters error +Input parameters error +(0x0017)输入参数错误 ++ ++ (0x001A)Not in work status error +Not in work status error +(0x001A)不能工作状态 ++ ++ (0x001B)Prohibited frame moving state +Prohibited frame moving state +(0x001B)禁止移框状态 ++ ++ (0x001F)Zero success +Zero success +(0x001F)归零成功 ++ ++ (0x0020)Return to zero error +Return to zero error +(0x0020)归零错误 ++ ++ (0x0021)Coordinate system error +Coordinate system error +(0x0021)坐标系统错误 ++ ++ (0x0022)Target position out of bounds +Target position out of bounds +(0x0022)目标位置越界 ++ ++ (0x0023)X Positive limit +X Positive limit +(0x0023)X正向限位 ++ ++ (0x0024)X Negative limit +X Negative limit +(0x0024)X反向限位 ++ ++ (0x0025)Y Positive limit +Y Positive limit +(0x0025)Y正向限位 ++ ++ (0x0026)Y Negative limit +Y Negative limit +(0x0026)Y反向限位 ++ ++ (0x002B)Safety door error +(0x002B)开盖报警,安全门错误 ++ ++ (0x002C)Entering the light curtain 1 +Entering the light curtain 1 +(0x002C)光幕1介入 ++ ++ (0x002D)Entering the light curtain 2 +Entering the light curtain 2 +(0x002D)光幕2介入 ++ ++ (0x0040)None data +None data +(0x0040)无数据 ++ ++ (0x0041)Data error +Data error +(0x0041)数据错误 ++ ++ (0x0042)Graphics out of range +Graphics out of range +(0x0042)图形超出范围 ++ ++ (0x0050)Spindle is not in zero position +Spindle is not in zero position +(0x0050)主轴不在零位 ++ ++ (0x0051)Rotary hook is not in zero position +(0x0051)旋梭不在零位 ++ ++ (0x0054)Scissors are not in position +Scissors are not in position +(0x0054)剪刀不在回位 ++ ++ (0x0056)Nose not in low position +(0x0056)机头不在低位 ++ ++ (0x0058)Thread is broken +Thread is broken +(0x0058)断线 ++ ++ (0x0059)Bottom thread disconnected +Bottom thread disconnected +(0x0059)底线断线 ++ ++ (0x005D)Execution command timed out +Execution command timed out +(0x005D)执行命令超时 ++ ++ (0x005F)Head lifting timeout +(0x005F)机头升降超时 ++ ++ (0x00F0)Change the bobbin +Change the bobbin +(0x00F0)更换梭芯 ++ ++ (0x00F1)Replace bobbin A +Replace bobbin A +(0x00F1)更换梭芯A ++ ++ (0x00F2)Replace bobbin B +Replace bobbin B +(0x00F2)更换梭芯B ++ ++ (0x00F3)The machine is in the state of replacing the bobbin +The machine is in the state of replacing the bobbin +(0x00F3)机器处于更换梭芯状态 ++ ++ (0x002E)Insufficient air pressure +(0x002E)气压不足 ++ ++ Normal stop +(0x0100)Normal stop +正常停止 ++ ++ Find zero success +(0x0101)Find zero success +归零成功 ++ ++ work pause +(0x0102)work pause +工作暂停 ++ ++ End of work +(0x0103)End of work +工作结束 ++ ++ Work done +(0x0104)Work done +工作完成 ++ ++ Complete production +(0x0105)Complete production +完成产量 ++ ++ (0x0106)Execute success +Execute success +(0x0106)执行成功 ++ ++ (0x0107)Execute false +Execute false +(0x0107)执行失败 ++ ++ (0x0108)wait file +wait file +(0x0108)等待文件 ++ ++ (0x0109)change the bobbin +change the bobbin +(0x0109)更换梭芯 ++ ++ (0x010A)Execute finish +Execute finish +(0x010A)执行完成 ++ ++ (0x010B)Execute runnibng +Execute runnibng +(0x010B)执行过程中 ++ ++ Enable +使能 ++ ++ Disable +失能 ++ ++ JogP +正转 ++ ++ JogN +反转 ++ ++ Turn +转动 ++ ++ Zero +归零 ++ ++ Open +打开 ++ ++ Close +关闭 ++ ++ Ascending +上升 ++ ++ descending +下降 ++ ++ Trim +剪线 ++ +SensorInputWidget ++ ++ Form ++ + ++ + Sensor +传感器信号 ++ ++ PageNums: 1/1 ++ + ++ pageNum: +页数: ++ +SetWorkArea ++ ++ Form ++ + ++ Prompt +提示 ++ ++ X + +X + ++ ++ X - +X - ++ ++ Y + +Y + ++ ++ Y - +Y - ++ +SystemManageDialog ++ ++ Dialog ++ + ++ PageNums: 1/1 ++ + ++ + Update +升级 ++ ++ 192.168.2.196 ++ + ++ StaticIP +静态IP ++ ++ DynamicIP +动态IP ++ ++ *Before setting the static IP, you need to first set the dynamic IP. After the dynamic IP is set, you need to return to this interface to continue setting the static IP +设置静态IP前需要先设置动态IP,动态IP设置完成后需要返回此界面继续设置静态IP +设置静态IP前需要先设置动态IP,动态IP设置完成后需要返回此界面继续设置静态IP ++ ++ pageNum: 0/0 +页数: 0/0 ++ ++ pageNum: +页数: ++ ++ Do you want to clear the journal? +是否清空日志文件? ++ ++ Do you want to export journal? +是否导出日志文件? ++ ++ + + + Prompt +提示 ++ ++ The upgrade needs to restart the program. Do you need to restart to upgrade? +升级需要重新启动程序,是否重启进行升级? ++ ++ Do you want to clear the production statistics? +是否清空生产统计? ++ +WordsInputDialog ++ ++ Dialog ++ + ++ Words input +字符输入 ++ ++ Name: +名称: ++ ++ ← ++ + ++ old +旧名称 +action; + } + + lastStatus = ctrl; + absItem.ctrl = ctrl; + absItem.attr = attr; + absItem.ax = ax * xfactor; + absItem.ay = ay * yfactor; + absItem.ar = ar * rfactor; + + if (absItem.ax > maxX) + { + maxX = absItem.ax; + } + if (absItem.ax < minX) + { + minX = absItem.ax; + } + if (absItem.ay > maxY) + { + maxY = absItem.ay; + } + if (absItem.ay < minY) + { + minY = absItem.ay; + } + + absData.append((char*)(&absItem), sizeof(DsAbsItem)); + + stepidx++; + dsrDataPtr++; + } + + m_HeadSpacingIndex = headSpacingIndex; + qDebug()<<"m_HeadSpacingCount = headSpacingIndex =" < dx * xfactor - minX; +// int begY = dsrDataPtr->dy * yfactor - minY; + int begX = dsrHead->startX; + int begY = dsrHead->startY; + int anchorX = dsrHead->anchorX; + int anchorY = dsrHead->anchorY; + + int newstepnum = stepidx; // 转换后的数据长度 + + // 文件头转换 + QString name = getFileFullName(); + int namelen = name.size(); + if (namelen > HEAD_NAME_STR_LEN) + { + namelen = HEAD_NAME_STR_LEN; + } + memcpy(dhead.fileName, name.data(), namelen); // 文件名称 + dhead.dataSize = newstepnum*sizeof(DsAbsItem); // 数据字节数 + dhead.itemNums = newstepnum; // 数据项个数 + dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 + dhead.bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小 + dhead.dataChecksum = calcCheckSum32((u8 *)(absData.data()) , absData.length()); // 数据累加校验和 + dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) + u32 fileID = 0; + fileID = calcCheckSum32((u8 *)(absData.data()) , absData.length()); // 原始数据累加校验和 + dhead.fileid = fileID; //中间数据的 fileid = + + dhead.anchorX = anchorX; // 定位点坐标X + dhead.anchorY = anchorY; // 定位点坐标Y + dhead.beginX = begX; // 数据起点坐标X + dhead.beginY = begY; // 数据起点坐标Y + dhead.beginR = 0; + dhead.minX = minX-minX; + dhead.maxX = maxX-minX; + dhead.minY = minY-minY; + dhead.maxY = maxY-minY; // 轮廓范围,使用重新计算之后的值 + + // 保存文件头到数组中 + m_embAbsData.append((char *)(&dhead), sizeof(DataDs16FileHead)); + + // 保存数据到数组中 + m_embAbsData.append(absData); +} + +// 生成预览图片 +int DataFileDsr::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw) +{ +#if(1) + if(reDraw == 0)//图片存在则不重画 + { + // 图片是否存在,存在则返回 + QString previewPath = getFileFullPathName() + ".preview.png"; + QFile imageFile(previewPath); + if (imageFile.exists()) + { + return 0; + } + } +#endif + + int newimgflag = 0; + QImage * pImage; + int width, height; + if (pImg == NULL) + { + width = DSR_PREVIEW_WIDTH; + height = DSR_PREVIEW_HEIGHT; + pImage = new QImage(width, height, IMAGE_TYPE); + newimgflag = 1; + } + else + { + pImage = pImg; + } + + width = pImage->width(); + height = pImage->height(); + + if (width <= DSR_PREVIEW_SIDE*2 || height <= DSR_PREVIEW_SIDE*2) + { + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + qDebug("preview img too small"); + return -1; + } + + memset(pImage->bits(), 0x00, pImage->byteCount()); + + QPainter painter(pImage); + QColor backcolor(255, 255, 255, 0); // 透明背景 + + // 背景 + QPen pen; + pen.setWidth(penwidth); + pen.setColor(backcolor); + painter.setPen(pen); + painter.setBrush(backcolor); + painter.drawRect(0, 0, width, height); + + getDsrMinMax(); + // 图形 + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + qDebug("dsr size less then headsize"); + return -1; + } + DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); + size -= dsrHead->dataBegin; + if (size <= 0) + { + qDebug("dsr dataBegin err"); + return -1; + } + int stepsize = size/sizeof(DsrStep); + if (stepsize <= 0) + { + qDebug("dsr data size err"); + return -1; + } + + DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); + + // 图形显示区域 + int dpminx = DSR_PREVIEW_SIDE; + int dpmaxx = width - DSR_PREVIEW_SIDE; + int dpminy = DSR_PREVIEW_SIDE + DSR_PREVIEW_SIDE; + int dpmaxy = height - DSR_PREVIEW_SIDE; + + // 计算缩放系数 + double factor, temp; + factor = (double)(abs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 + temp = (double)(abs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按轮廓计算,最小能够放下重复次数个图形 + if (temp >= factor) // 使用较大的缩放系数 + { + factor = temp; + } + + // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) + int dpx = (int)((dpminx+dpmaxx)/2 - (((m_maxX+dsrHead->startX)+(m_minX+dsrHead->startX))/factor)/2); + int dpy = (int)((dpminy+dpmaxy)/2 - (((m_maxY+dsrHead->startY)+(m_minY+dsrHead->startY))/factor)/2); + + // 显示花样图形 + BYTE ctrlByte; + //BYTE attrByte; + QColor sewcolor = QColor(Qt::green); + pen.setColor(sewcolor); + painter.setPen(pen); + + double datposx, datposy; + int curx, cury, prex, prey; + curx = cury = prex = prey = 0; + + DsrStep * dsrDataPtr = dsrDataBeg; + + for (int i = 0; i < stepsize; i++) + { + // 读入一个针步数据 + ctrlByte = dsrDataPtr->ctrl; + //attrByte = dsrDataPtr->attr; + + prex = curx; + prey = cury; + + datposx = dsrDataPtr->dx + dsrHead->startX; + datposy = dsrDataPtr->dy + dsrHead->startY; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (DSR_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (DSR_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + if(i == 0) + { + dsrDataPtr++; + continue; + } + + if ( ctrlByte == DSR_SEWING || + ctrlByte == DSR_EMB || + ctrlByte == DSR_CUTTING || + ctrlByte == DSR_LASER || + ctrlByte == DSR_JUMP) + { + painter.drawLine(prex, prey, curx, cury); + } + else + { + //qDebug("other type=0x%x", ctrlByte); + } + + dsrDataPtr++; + } + + // 保存成文件 + QString preview = getFileFullPathName(); + if (saveflag != 0 && preview.isEmpty() == false) + { +#if (1) + preview += ".preview.png"; + pImage->save(preview, "png"); +#endif + } + + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + + return 0; +} + +DsrHead *DataFileDsr::getDsrHead() +{ + if(m_fileData.size() <= 0) + { + loadFile(); // 如果数据未读取,重新读取 + } + + DsrHead * head = NULL; + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + return head; + } + + head = (DsrHead *)(m_fileData.data()); + return head; +} + +void DataFileDsr::moveDataBeginPonit(s32 left, s32 front) +{ + if((u32)m_embAbsData.size() > sizeof(DataDs16FileHead)) + { + DataDs16FileHead *dhead = (DataDs16FileHead *)( m_embAbsData.data()); + dhead->beginX += left; + dhead->beginY += front; + dhead->maxX += left; + dhead->minX += left; + dhead->maxY += front; + dhead->minY += front; + } +} + +//dsr文件头中新增2048的拓展 用于存机头间距参数 +void DataFileDsr::updateFileVersionTo6_2() +{ + qDebug()<<"exec DataFileDsr::updateFileVersionTo6_2()"; + //1 读出数据 + //2 判断文件版本 + //3 插入数据 + //4 修改头文件信息 文件版本 和 数据起始位置 + + QFile file(m_fileFullPathName); + qDebug()< verCode)) + 0.1; + DWORD begin = dsrHead->dataBegin; + qDebug() << "file Version:" << ver; + qDebug()<< "dsr file data beign:" << begin; + + if(ver < 5.2 && begin != (sizeof(DsrHead) + sizeof(DsrHeadEx62))){ + file.remove();//删除文件 + QFile newFile(m_fileFullPathName); + if(newFile.open(QIODevice::ReadWrite | QIODevice::Truncate)){ + + QByteArray newFileBuffer; + + //添加原先的文件头 + newFileBuffer.append(oldFile.left(begin)); + qDebug()<<"append(oldFile.left(begin))" < dataBegin = sizeof(DsrHead) + sizeof(DsrHeadEx62); //3072 + qDebug()<<"newDsrHead:"< dataBegin; + + //添加数据区 + newFileBuffer.append(oldFile.right(oldFile.size() - begin)); + qDebug()<<"oldFile.right(oldFile.size() - begin)" < dataBegin; + + BYTE* pCryFactors = (BYTE*)(&dsrHead->dataBegin); + BYTE* pData = (BYTE*)((m_fileData.data() + dsrHead->dataBegin)); + + DsrCryption cry; + cry.InitDsrCryptionCtrl(-1, dsrHead->cryWord, pCryFactors); + + int rslt = cry.DeCryption(pData, size); + + if (rslt == 0) + { + dsrHead->cryWord = 0; + } + } + + return; +} + +void DataFileDsr::saveFile() +{ + QFile wrfile(m_fileFullPathName); + if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when wirte, path =" << m_fileFullPathName; + return; + } + else + { + wrfile.write(m_fileData); + wrfile.close(); + } +} + +//写入定位点或起绣点到文件中 +void DataFileDsr::writePointToFile(int x, int y, int flag) +{ + if(m_fileData.size() <= 0) + { + return; + } + + DsrHead * pDsrHead = (DsrHead *)(m_fileData.data()); + if(flag == 0) + { + pDsrHead->startX = x; + pDsrHead->startY = y; + } + else + { + pDsrHead->anchorX = x; + pDsrHead->anchorY = y; + } + + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_fileData); + wfile.close(); + +#ifdef Q_OS_LINUX + system("sync"); +#endif +} + +void DataFileDsr::writePatternParaToFile(DsrHead *head) +{ + if(m_fileData.size() <= 0) + { + return; + } + + memcpy(m_fileData.data(),(char*)head,sizeof(DsrHead)); + + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_fileData); + wfile.close(); +} + +QString DataFileDsr::getFileFullPath() +{ + QFileInfo file(m_fileFullPathName); + return file.absoluteFilePath(); +} + +QString DataFileDsr::getFileFullName() +{ + QFileInfo file(m_fileFullPathName); + return file.fileName(); +} + +QString DataFileDsr::getFileName() +{ + QFileInfo file(m_fileFullPathName); + return file.completeBaseName(); +} + +QString DataFileDsr::getFileSuffix() +{ + QFileInfo file(m_fileFullPathName); + return file.suffix(); +} + +int DataFileDsr::getStitchNums() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return pDsrHead->itemNums; +} + +int DataFileDsr::getDatWidth() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return (pDsrHead->maxX - pDsrHead->minX); +} + +int DataFileDsr::getDatHeight() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return (pDsrHead->maxY - pDsrHead->minY); +} + +int DataFileDsr::getMaxX() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return pDsrHead->maxX; +} + +int DataFileDsr::getMinX() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return pDsrHead->minX; +} + +int DataFileDsr::getMaxY() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return pDsrHead->maxY; +} + +int DataFileDsr::getMinY() +{ + if(m_embAbsData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pDsrHead = (DataDs16FileHead *)((m_embAbsData.data())); + return pDsrHead->minY; +} + +int DataFileDsr::getBeginXYAndAnchorXY(int &beginX, int &beginY, int &anchorX, int &anchorY) +{ + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + return -1; + } + + DsrHead * pDsrHead = (DsrHead *)((m_fileData.data())); + DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + pDsrHead->dataBegin)); + + anchorX = pDsrHead->anchorX; + anchorY = pDsrHead->anchorY; + //起始点坐标等于定位点+起始点+第一针的坐标 + beginX = pDsrHead->anchorX+pDsrHead->startX+dsrDataBeg->dx; + beginY = pDsrHead->anchorY+pDsrHead->startY+dsrDataBeg->dy; + + return 0; +} + +int DataFileDsr::getStepNums() +{ + int stepNums = m_HeadSpacingIndex +1; + return stepNums;//个数为index加一 +} + +void DataFileDsr::set62ExHead(DsrHeadEx62 data) +{ + m_62HeadData = data; +} + +DsrHeadEx62 &DataFileDsr::get62ExHead() +{ + return m_62HeadData; +} + +int DataFileDsr::checkFileCryption() +{ + int encryption = 0; + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + qDebug("dsr size less then headsize"); + return -1; + } + DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); + size -= dsrHead->dataBegin; + if (size <= 0) + { + qDebug("dsr dataBegin err"); + return -1; + } + int stepsize = size/sizeof(DsrStep); + if (stepsize <= 0) + { + qDebug("dsr data size err"); + return -1; + } + + if (dsrHead->cryWord != 0) + { + encryption = 1; + } + + return encryption; +} + +void DataFileDsr::getDsrMinMax() +{ + loadFile(); // 如果数据未读取,重新读取 + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DsrHead))) + { + qDebug("dsr size less then headsize"); + return; + } + + DsrHead * dsrHead = (DsrHead *)(m_fileData.data()); + + size -= dsrHead->dataBegin; + if (size <= 0) + { + qDebug("dsr dataBegin err"); + return; + } + + int stepsize = size/sizeof(DsrStep); + if (stepsize <= 0) + { + qDebug("dsr data size err"); + return; + } + + DsrStep * dsrDataBeg = (DsrStep *)((m_fileData.data() + dsrHead->dataBegin)); + DsrStep * dsrDataPtr = dsrDataBeg; + m_maxX = S32_MIN; + m_maxY = S32_MIN; + m_minY = S32_MAX; + m_minX = S32_MAX; + + BYTE ctrlByte; + + long curPitX = 0; + long curPitY = 0; + + int i = 0; + do + { + if (i < stepsize) + { + ctrlByte = dsrDataPtr->ctrl; + + if ( ctrlByte == DATA_EMB || + ctrlByte == DSR_SEWING || + ctrlByte == DATA_OFFSET || + 0 ) + { + curPitX = dsrDataPtr->dx; + curPitY = dsrDataPtr->dy; + } + dsrDataPtr++; + i++; + } + else + { + break; + } + + if (curPitX > m_maxX) + { + m_maxX = curPitX; + } + if (curPitX < m_minX) + { + m_minX = curPitX; + } + if (curPitY > m_maxY) + { + m_maxY = curPitY; + } + if (curPitY < m_minY) + { + m_minY = curPitY; + } + + }while(1); + + return; +} diff --git a/datafile/datafiledsr.h b/datafile/datafiledsr.h new file mode 100644 index 0000000..17897dc --- /dev/null +++ b/datafile/datafiledsr.h @@ -0,0 +1,205 @@ +#ifndef DATAFILEDSR_H +#define DATAFILEDSR_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "math.h" +#include + +#include "dsrcryption.h" +#include "machine/comm/datadef.h" +#include "machine/comm/crc16.h" + + +#define DSR_PREVIEW_SIDE (15) // 留边大小 +#define DSR_PREVIEW_WIDTH (156) // 默认预览图区域宽度 +#define DSR_PREVIEW_HEIGHT (164) // 默认预览图区域高度 + +#define DSR_VERSION_5 5.00f +#define DSR_VERSION_6_3 6.30f + +typedef struct strDsrHead +{ +// 0x00 十六进制表示 + DWORD verCode; // 文件版本 LSB + DWORD cryWord; // 加密字 + BYTE reserved1[8]; // 保留 8 字节 +// 0x10 + DWORD dataBegin; // 数据起始 LSB + DWORD stepSize; // 数据字段大小 + DWORD xyUnit; // 长度数据单位 + DWORD rUnit; // 角度数据单位 +// 0x20 + DWORD stitches; // 针数 LSB + DWORD fileID; // 文件id,和智能识别有关 = 0, 不能识别 + BYTE reserved2[8]; // 保留 8 字节 +// 0x30 + s32 rangeNx; // 范围 -X LSB + s32 rangePx; // 范围 +X LSB + s32 rangeNy; // 范围 -Y LSB + s32 rangePy; // 范围 +Y LSB +// 0x40 + long startX; // 起点坐标X LSB + long startY; // 起点坐标Y LSB + long anchorX; // 定位点X LSB + long anchorY; // 定位点Y LSB +// 0x50 + u8 reserved3[0x54-0x50]; // 保留字节 +// 0x54 + u8 rotateStyle; //旋转式样 + u8 horizontalStyle; //水平翻转式样 + u8 verticalStyle; //垂直翻转式样 + u8 rotateAngle; //旋转角度 + u8 reinMode; //加固方式 + u8 reinNeedles; //针数 + u8 reinNum; //次数 + s16 normalStep; //针步大小 + s16 angleCorrOffset; //角度修正量 + s16 angleCorrPosX; //角度修正量X正 + s16 angleCorrPosY; //角度修正量Y正 + s16 angleCorrNegX; //角度修正量X负 + s16 angleCorrNegY; //角度修正量Y负 + int scanX; //X向宽度 + int scanY; //Y向高度 + int left; //左边 + int front; //前边 +// 0x77 + BYTE reserved4[0x100-0x77]; // 保留字节 +// 0x100 + u8 reserved5[0x200-0x100]; //BYTE // 保留字节 +// 0x200 + u8 reserved6[0x400-0x200]; //BYTE + +}__attribute__ ((packed)) DsrHead; + +//dsr6.3版本的文件头扩展 +typedef struct strDsrHead63 +{ + //0x00 + u8 switchTable2[0x200-0x000]; //BYTE // 换色表2(扩展色序设定表),512个字节 + //0x200 + u8 towelHighTable[0x600-0x200]; //BYTE // 毛巾高度设定表, 支持1024个高度设定,每个字节对应一个高度等级(0,非有效高度。1--11, 有效的高度等级) +}__attribute__ ((packed)) DsrHead63; + + +//dsr6.2版本得文件头扩展 +typedef struct +{ + //支持128个表,每个表包含16个字节. + HeadTable headEnableSpacing[128]; +} DsrHeadEx62; + + +typedef struct strDsrStep +{ + BYTE ctrl; // 控制字节 + BYTE attr; // 属性字节 + WORD action;// 附加动作 + s32 dx; // X绝对偏移 + s32 dy; // Y绝对偏移 + s32 dr; // R角度 +}__attribute__ ((packed)) DsrStep; + + +//----------------------------------------------- + +#define DSR_NULL 0x00 // 文件结束 +#define DSR_SEWING 0x01 // 缝纫数据 +#define DSR_OFFSET 0x02 // 偏移数据 +#define DSR_CUTTING 0x03 // 切刀数据 +#define DSR_LASER 0x04 // 激光数据 +#define DSR_DRAWING 0x05 // 记号数据 +#define DSR_SEWING_R 0x06 // 第二缝纫数据 + +#define DSR_PAUSE 0x08 // 暂停 +#define DSR_ANGLE 0x09 // 拐点 +#define DSR_CUT 0x0A // 剪线 +#define DSR_JUMP 0x0B // 跳针 +#define DSR_EMB 0x0D // 绣花 +#define DSR_CHGND 0x0E // 换色 + +#define DSR_END 0x10 // 结束码 + +//----------------------------------------------- + +#define DSR_EMB_DATADIRX (-1) // X向数据坐标与下位机坐标系统的差异 +#define DSR_EMB_DATADIRY (-1) // Y向数据坐标与下位机坐标系统的差异 +#define DSR_EMB_DATADIRR (1) // R向数据坐标与下位机坐标系统的差异 + +#define DSR_SHOWDIRX (-1) // X向显示坐标和数据坐标的差异 +#define DSR_SHOWDIRY (1) // Y向显示坐标和数据坐标的差异 + +class DataFileDsr +{ +public: + DataFileDsr(); + ~DataFileDsr(); + +public: + void initFile(const QString & fullPathName); + int checkDsrVersion();//检查dsr文件版本,非5.2和6.3版本和错误格式返回-1 + void convertDataToEmbAbs(); // 转换为绝对数据 + //是否保存 //笔宽 + int createPreviewImage(QImage * pImg = NULL, int saveflag = 0, int penwidth = 1, int reDraw = 0); // 生成预览文件 + DsrHead *getDsrHead(); + void moveDataBeginPonit(s32 left, s32 front); //移动数据起始点 + void updateFileVersionTo6_2(); //更新文件版本至6.2 + +public: + void clear(); + void loadFile(); + void saveFile(); + void writePointToFile(int x, int y, int flag = 0);//写入起始点到文件中 + void writePatternParaToFile(DsrHead *head);//将花样参数配置写到文件中 + inline const QString & getFileFullPathName() const {return m_fileFullPathName;} // 文件路径名称 + inline QByteArray & getFileData() {return m_fileData;} // 得到文件数据 + inline QByteArray & getEmbAbsData() {return m_embAbsData;} // 得到转换后的数据 + QString getFileFullPath(); // 文件所在目录 + QString getFileFullName(); // 文件名称(包括扩展名) + QString getFileName(); // 文件名称(不包括扩展名) + QString getFileSuffix(); // 文件扩展名 + + int getStitchNums();//得到数据的针数 + int getDatWidth();//得到数据的图形宽度 + int getDatHeight();//得到数据的图形高度 + int getMaxX();//得到数据最大X+ + int getMinX();//得到数据最小X- + int getMaxY();//得到数据最大Y+ + int getMinY();//得到数据最小Y- + int getBeginXYAndAnchorXY(int &beginX, int &beginY, int &anchorX, int &anchorY); + + int getStepNums(); //获取换色数 + + void set62ExHead(DsrHeadEx62 data); + DsrHeadEx62 & get62ExHead(); + +protected: + QString m_fileFullPathName; // 文件路径 + QByteArray m_embAbsData; // 转换后的绝对坐标数据 + +private: + QByteArray m_fileData;// 文件数据内容(原始数据) + QString m_fileName; // 文件路径 + +public: + DsrHeadEx62 m_62HeadData; //6.2版本附加文件头数据 + +private: + int m_minX; + int m_maxX; + int m_minY; + int m_maxY; + int m_HeadSpacingIndex; //五头精密缝 机头间距表列数index + +private: + int checkFileCryption();//检查dsr文件是否加密 + void getDsrMinMax(); +}; + +#endif // DATAFILEDSR_H diff --git a/datafile/datafiledst.cpp b/datafile/datafiledst.cpp new file mode 100644 index 0000000..8b22b63 --- /dev/null +++ b/datafile/datafiledst.cpp @@ -0,0 +1,934 @@ +#include "datafiledst.h" + + +DataFileDst::DataFileDst() +{ +} + +DataFileDst::~DataFileDst() +{ +} + +void DataFileDst::clear() +{ + m_fileFullPathName.clear(); // 文件路径 + m_fileData.clear(); // 文件数据内容 + m_embAbsData.clear(); // 转换后的数据 +} + +void DataFileDst::initFile(const QString &fullPathName) +{ + clear(); + QFileInfo file(fullPathName); + if (file.exists() && file.isFile()) + { + m_fileFullPathName = fullPathName; + m_fileName = fullPathName; + qDebug()<<"m_fileFullPathName 1"< = 0) + { + ctrl = ds4Item.ctrl; + attr = ds4Item.attr; + + if ( ctrl == DATA_SEWING || + ctrl == DATA_OFFSET || + 0 ) + { + if(ctrl == DATA_OFFSET) + { + jumpNeedleNum++; + } + + dx = ds4Item.dx * DATAFACTOR; + dy = ds4Item.dy * DATAFACTOR; + + if ((attr & 0x80) != 0) + { + dx *= -1; + } + if ((attr & 0x40) != 0) + { + dy *= -1; + } + } + + memcpy(&(pData[stepidx]), &ds4Item, sizeof(Ds4Item)); + stepidx++; + } + + dstDataPtr++; + i++; + } + else + { + break; + } + }while(1); + + //qDebug()<<"Ds4Item end"; + //再将相对坐标转换为绝对坐标---开始 + ds4Data.append((char *)pData, stepidx*sizeof(Ds4Item));//相对坐标字节数组 + u32 fileID = 0; + fileID = calcCheckSum32((u8 *)(ds4Data.data()) , ds4Data.length()); // 原始数据累加校验和 + + QByteArray absItemAry; + absItemAry.clear(); + + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + u8 ctrlByte; + u8 attrByte; + int ddx, ddy; + + m_maxX = S32_MIN; + m_maxY = S32_MIN; + m_minY = S32_MAX; + m_minX = S32_MAX; + + Ds4Item * pDs4Data = (Ds4Item *)(ds4Data.data()); + Ds4Item * ds4DataPtr = pDs4Data; + + int begX = dstHead->startX;//起始点 + int begY = dstHead->startY; + int begR = 0; + int anchorX = dstHead->anchorX;//定位点 + int anchorY = dstHead->anchorY; + + s32 ax = 0;//第一个点 + s32 ay = 0; + s32 ar = 0; + + Ds4Item * ds4DataTemp = (Ds4Item *)(ds4Data.data()); // ljs + + int ds4StepSize = ds4Data.size()/sizeof(Ds4Item); + + int runflag = 0; + + int delStepNum = 0; // ljs + + for (int i = 0; i < ds4StepSize; i++) + { + // 读入一个针步数据 + ctrlByte = ds4DataPtr->ctrl; + attrByte = ds4DataPtr->attr; + ddx = ds4DataPtr->dx * DATAFACTOR; + ddy = ds4DataPtr->dy * DATAFACTOR; + + if ((attrByte & 0x80) != 0) + { + ddx *= -1; + } + if ((attrByte & 0x40) != 0) + { + ddy *= -1; + } + ddx *= DST_EMB_DATADIRX; + ddy *= DST_EMB_DATADIRY; + + ax += ddx; + ay += ddy; + //ar = atan2(ddy,ddx) * 10000; + double tar = atan2(ddy,ddx); + ar = (tar * 10000+0.5*(tar>0?1:-1)); + + if(ctrlByte == DATA_OFFSET) + { + if (runflag == 0) + { + runflag = 1; + } + runflag++; + } + else if(ctrlByte == DATA_SEWING)//第一针不转换为跳针 + { + if ((runflag == 0 || runflag > 3) && (i > 0)) // 第一个运针是入针 + { + ctrlByte = DATA_OFFSET; + runflag = 1; + } + //else if (i == 0 && ddx == 0 && ddy == 0) // 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs + else if (i == 0) // 20230511 第一针,入针,向后扫描,如果有连续的三个跳针,则将第一针入针转换为跳针 ljs + { + int count = 0; + do + { + ds4DataTemp++; + if (ds4DataTemp->ctrl == DATA_OFFSET) + { + count++; + if (ds4DataTemp->dx == 0 && ds4DataTemp->dy == 0) // 空跳,直接变成跳针 + { + count += 2; + } + } + else + { + break; + } + }while(1); + if (count >= 3) + { + ctrlByte = DATA_OFFSET; + runflag = 2; + } + else + { + runflag = 1; + } + } + else + { + runflag = 1; + } + } + else if (ctrlByte == DATA_CHGND) // 换色 + { + runflag = 10; + } + else + { + runflag = 0; + } + + //中间数据 + absItem.ctrl = ctrlByte; + absItem.attr = attrByte & ~(0x80|0x40); + absItem.ax = ax; + absItem.ay = ay; + absItem.ar = ar; + + if (ax > m_maxX) + { + m_maxX = ax; + } + if (ax < m_minX) + { + m_minX = ax; + } + if (ay > m_maxY) + { + m_maxY = ay; + } + if (ay < m_minY) + { + m_minY = ay; + } + + absItemAry.append((char*)&absItem,sizeof(DsAbsItem)); + + ds4DataPtr++; + } + + //int newstepnum = ds4StepSize; // 转换后的数据长度 + int newstepnum = ds4StepSize-delStepNum; // 转换后的数据长度 ljs + + //qDebug()<<"DsAbsItem end"; + + //再将相对坐标转换为绝对坐标---结束 + //qDebug()<<"dhead begin"; + // 文件头转换 + QString name = getFileFullName(); + int namelen = name.size(); + if (namelen > HEAD_NAME_STR_LEN) + { + namelen = HEAD_NAME_STR_LEN; + } + QByteArray array = name.toLocal8Bit().data(); + int asize = array.length(); + memcpy(dhead.fileName, array, asize); // 文件名称 + dhead.dataSize = newstepnum*sizeof(DsAbsItem); // 数据字节数 + dhead.itemNums = newstepnum; // 数据项个数 + dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 + dhead.bytesPerBlk = MAX_EXDP_LEN; // 数据内容划分块大小 + dhead.dataChecksum = calcCheckSum32((u8 *)(absItemAry.data()) , dhead.dataSize); // 数据累加校验和 + dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) + dhead.fileid = fileID; + //qDebug()<<"dhead 1"; + + dhead.anchorX = anchorX; // 定位点坐标X + dhead.anchorY = anchorY; // 定位点坐标Y + dhead.beginX = begX; // 数据起点坐标X + dhead.beginY = begY; // 数据起点坐标Y + dhead.beginR = begR; // 数据起点坐标R + dhead.minX = m_minX-m_minX; + dhead.maxX = m_maxX-m_minX; + dhead.minY = m_minY-m_minY; + dhead.maxY = m_maxY-m_minY; // 轮廓范围,使用重新计算之后的值 + + //qDebug()<<"m_maxX"< startX = x; + pDstHead->startY = y; + } + else + { + pDstHead->anchorX = x; + pDstHead->anchorY = y; + } + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_fileData); + wfile.close(); +} + +void DataFileDst::writePatternParaToFile(DstHead *head) +{ + if(m_fileData.size() <= 0) + { + return; + } + + memcpy(m_fileData.data(),(char*)head,sizeof(DstHead)); + + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_fileData); + wfile.close(); +} + +int DataFileDst::checkDstFile() +{ + loadFile(); // 如果数据未读取,重新读取 + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DstHead))) + { + qDebug("dsr size less then headsize"); + return -1; + } + + size -= sizeof(DstHead); + int stepsize = size/sizeof(DstStep); + if (stepsize <= 0) + { + qDebug("dst data size err"); + return -1; + } + + if (stepsize > PATTERN_LARGE_NEEDLES)//128万针 + { + qDebug("dsr data size big"); + return -2; + } + + return stepsize; +} + +DstHead *DataFileDst::getDstHead() +{ + if(m_fileData.size() <= 0) + { + loadFile(); // 如果数据未读取,重新读取 + } + DstHead *head = NULL; + + int size = m_fileData.size(); + if (size <= (int)(sizeof(DstHead))) + { + return head; + } + + head = (DstHead *)((m_fileData.data())); + return head; +} + +void DataFileDst::moveDataBeginPonit(s32 left, s32 front) +{ + if((u32)m_embAbsData.size() > sizeof(DataDs16FileHead)) + { + DataDs16FileHead *dhead = (DataDs16FileHead *)( m_embAbsData.data()); + dhead->beginX += left; + dhead->beginY += front; + dhead->maxX += left; + dhead->minX += left; + dhead->maxY += front; + dhead->minY += front; + } +} +//----------------------------------------------------------------------- + +// 生成预览文件 +int DataFileDst::createPreviewImage(QImage * pImg, int saveflag, int penwidth, int reDraw) +{ +#if(1) + if(reDraw == 0)//图片存在则不重画 + { + // 图片是否存在,存在则返回 + QString previewPath = getFileFullPathName() + ".preview.png"; + QFile imageFile(previewPath); + if (imageFile.exists()) + { + return 0; + } + } +#endif + + int newimgflag = 0; + QImage * pImage; + int width, height; + if (pImg == NULL) + { + width = DST_PREVIEW_WIDTH; + height = DST_PREVIEW_HEIGHT; + pImage = new QImage(width, height, IMAGE_TYPE); + newimgflag = 1; + } + else + { + pImage = pImg; + } + + width = pImage->width(); + height = pImage->height(); + if (width <= DST_PREVIEW_SIDE*2 || height <= DST_PREVIEW_SIDE*2) + { + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + qDebug("preview img too small"); + return -1; + } + + memset(pImage->bits(), 0x00, pImage->byteCount()); + + QPainter painter(pImage); + QColor backcolor(255, 255, 255, 0); // 透明背景 + // 背景 + QPen pen; + pen.setWidth(penwidth); + pen.setColor(backcolor); + painter.setPen(pen); + painter.setBrush(backcolor); + painter.drawRect(0, 0, width, height); + + // 图形 + //qDebug()<<"convertDataToAbs defore"; + convertDataToAbs(); // 转换为绝对坐标数据 + //qDebug()<<"convertDataToAbs end"; + + // absdat数据 + int size = m_embAbsData.size(); + if (size <= (int)sizeof(DataDs16FileHead)) + { + qDebug("2 data less then head size"); + return -1; + } + DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_embAbsData.data()); + int datasize = size - sizeof(DataDs16FileHead); + if (datasize <= 0) + { + qDebug("absdat dataBegin err"); + return -1; + } + int stepsize = datasize/sizeof(DsAbsItem); + if (stepsize <= 0) + { + qDebug("absdat data size err"); + return -1; + } + DsAbsItem * pData = (DsAbsItem *)(m_embAbsData.data() + sizeof(DataDs16FileHead)); + DsAbsItem * absDataPtr = pData; + //-------- + + // 图形显示区域 + int dpminx = DST_PREVIEW_SIDE; + int dpmaxx = width - DST_PREVIEW_SIDE; + int dpminy = DST_PREVIEW_SIDE; + int dpmaxy = height - DST_PREVIEW_SIDE; + + // 计算缩放系数 + double factor, temp; + if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) + { + return -1; + } + + factor = (double)(fabs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 + temp = (double)(fabs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按x计算的缩放系数 + + if (temp >= factor) // 使用较大的缩放系数 + { + factor = temp; + } + + // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) + int dpx = (int)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); + int dpy = (int)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); + + // 显示花样图形 + u8 ctrlByte; + int dx; + int dy; + + double datposx, datposy; + int curx, cury, prex, prey; + + datposx = pAbsHead->beginX; + datposy = pAbsHead->beginY; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (DST_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (DST_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + absDataPtr = pData; + + QColor embcolor = QColor(Qt::green); + pen.setColor(embcolor); + painter.setPen(pen); + + for (int i = 0; i < stepsize; i++) + { + // 读入一个针步数据 + ctrlByte = absDataPtr->ctrl; + + if ( ctrlByte == DATA_SEWING || + 0 ) + { + prex = curx; + prey = cury; + + dx = absDataPtr->ax; + dy = absDataPtr->ay; + + datposx = dx; + datposy = dy; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (DST_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (DST_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + if(i != 0) + { + painter.drawLine(prex, prey, curx, cury); + } + } + + + //如果连续两步都是跳针,则过滤掉 + else if (ctrlByte == DATA_OFFSET) + { + DsAbsItem * JumpAbsDataPtr = pData; + JumpAbsDataPtr = absDataPtr - 1; + u8 beforectrlByte = JumpAbsDataPtr->ctrl; + + JumpAbsDataPtr = absDataPtr + 2; + u8 nextctrlByte = JumpAbsDataPtr->ctrl; + + prex = curx; + prey = cury; + + dx = absDataPtr->ax; + dy = absDataPtr->ay; + + datposx = dx; + datposy = dy; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (DST_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (DST_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + pen.setColor(embcolor); + painter.setPen(pen); + + if(beforectrlByte == DATA_OFFSET || nextctrlByte == DATA_OFFSET) + { + //该针上下两针都是跳针则不画线 + } + else + { + if(i != 0) + { + painter.drawLine(prex, prey, curx, cury); + } + } + } + + absDataPtr++; + } + + // 保存成文件 + QString preview = getFileFullPathName(); + if (saveflag != 0 && preview.isEmpty() == false) + { +#if (1) + preview += ".preview.png"; + pImage->save(preview, "png"); +#endif + } + + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + + return 0; +} + +#define EMB_DST_DAT_DIRX (-1) // X向DST数据坐标和绝对数据坐标的差异 +#define EMB_DST_DAT_DIRY (1) // Y向DST数据坐标和绝对数据坐标的差异 + +// 针步转换 +int DataFileDst::changeDstStep(DstStep * pDststep, Ds4Item & ds4step) +{ + int dx, dy; + u8 c1, c2, c3; + u8 ctrl, attr; + + if (pDststep == NULL) + { + return -1; + } + + c1 = pDststep->c1; + c2 = pDststep->c2; + c3 = pDststep->c3; + + dx = 0; + dy = 0; + + if ((c1&0x08) != 0) { dx -= 9; } + if ((c1&0x04) != 0) { dx += 9; } + if ((c1&0x02) != 0) { dx -= 1; } + if ((c1&0x01) != 0) { dx += 1; } + if ((c2&0x08) != 0) { dx -= 27; } + if ((c2&0x04) != 0) { dx += 27; } + if ((c2&0x02) != 0) { dx -= 3; } + if ((c2&0x01) != 0) { dx += 3; } + if ((c3&0x08) != 0) { dx -= 81; } + if ((c3&0x04) != 0) { dx += 81; } + + if ((c1&0x10) != 0) { dy -= 9; } + if ((c1&0x20) != 0) { dy += 9; } + if ((c1&0x40) != 0) { dy -= 1; } + if ((c1&0x80) != 0) { dy += 1; } + if ((c2&0x10) != 0) { dy -= 27; } + if ((c2&0x20) != 0) { dy += 27; } + if ((c2&0x40) != 0) { dy -= 3; } + if ((c2&0x80) != 0) { dy += 3; } + if ((c3&0x10) != 0) { dy -= 81; } + if ((c3&0x20) != 0) { dy += 81; } + + if (c3 == 0xF3 && dx == 0 && dy == 0) + { + ctrl = DATA_END; // 结束 + } + else if ((c3&0xc3) == 0x03) // 运针 + { + ctrl = DATA_SEWING; + } + else if ((c3&0xc3) == 0x83) // 偏移 + { + ctrl = DATA_OFFSET; + } + else if ((c3&0xc3) == 0xC3) // 换色 + { + ctrl = DATA_CHGND; + } + else if ((c3&0xc3) == 0x43) // 开关亮片码 + { + qDebug("Sequin switch, not support, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST + return -2; + } + else + { + qDebug("not know dst step, c1=0x%x, c2=0x%x, c3=0x%x", c1, c2, c3); // 不合法的DST + return -3; + } + + // 添加针步 + attr = 0; + + dx *= EMB_DST_DAT_DIRX; // X向显示坐标和数据坐标的差异 + dy *= EMB_DST_DAT_DIRY; // Y向显示坐标和数据坐标的差异 + + if (dx < 0) { attr |= 0x80; } + if (dy < 0) { attr |= 0x40; } + + ds4step.ctrl = ctrl; + ds4step.attr = attr; + ds4step.dx = abs(dx); + ds4step.dy = abs(dy); + + return 0; +} diff --git a/datafile/datafiledst.h b/datafile/datafiledst.h new file mode 100644 index 0000000..0c17f34 --- /dev/null +++ b/datafile/datafiledst.h @@ -0,0 +1,157 @@ +#ifndef DATAFILEDST_H +#define DATAFILEDST_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "math.h" +#include + +#include "machine/comm/datadef.h" +#include "machine/comm/crc16.h" +#include "datafile/dataoperat.h" + +#define DATAFACTOR 10 //dst绝对坐标数据转换为ds16前需要扩大10倍 + +#define DST_EMB_DATADIRX (-1) // X向数据坐标与下位机坐标系统的差异 +#define DST_EMB_DATADIRY (1) // Y向数据坐标与下位机坐标系统的差异 + +#define DST_SHOWDIRX (-1) // X向显示坐标和数据坐标的差异 +#define DST_SHOWDIRY (1) // Y向显示坐标和数据坐标的差异 + +#define DST_PREVIEW_SIDE (15) // 留边大小 +#define DST_PREVIEW_WIDTH (156) // 默认预览图区域宽度 +#define DST_PREVIEW_HEIGHT (164) // 默认预览图区域高度 + +// dst文件头 +#pragma pack(1)//设定为1字节对齐 +struct DstHead +{ +// 0 + char la[20]; + char st[11]; + char co[7]; + char xp[9]; + char xn[9]; + char yp[9]; + char yn[9]; + char ax[10]; + char ay[10]; + char mx[10]; + char my[10]; + char pd[10]; + char sub; + char reserved1[3]; + +// 128 + u8 rotateStyle; //旋转式样 + u8 horizontalStyle; //水平翻转式样 + u8 verticalStyle; //垂直翻转式样 + u8 rotateAngle; //旋转角度 + u8 reinMode; //加固方式 + u8 reinNeedles; //针数 + u8 reinNum; //次数 + s16 normalStep; //针步大小 + s16 angleCorrOffset; //角度修正量 + s16 angleCorrPosX; //角度修正量X正 + s16 angleCorrPosY; //角度修正量Y正 + s16 angleCorrNegX; //角度修正量X负 + s16 angleCorrNegY; //角度修正量Y负 + int scanX; //X向宽度 + int scanY; //Y向高度 + int left; //左边 + int front; //前边 + + // 163 + u8 reserved2[256-163]; //BYTE + +// 256 + s16 reserved3; + +// 258 + int anchorX; //定位点 + int anchorY; + +// 266 + s32 startX; //起始点 + s32 startY; + +// 274 + u8 reserved4[512-274]; //BYTE // 保留字节 +}; +#pragma pack(1)//恢复对齐状态 + + +// 针步数据 +typedef struct strDstStep +{ + u8 c1; ////BYTE + u8 c2; ////BYTE + u8 c3; ////BYTE +}__attribute__ ((packed)) DstStep; + + +class DataFileDst +{ +public: + DataFileDst(); + ~DataFileDst(); + +public: + void initFile(const QString & fullPathName); + int createPreviewImage(QImage * pImg = NULL, int saveflag = 0, int penwidth = 1, int reDraw = 0); // 生成预览文件 + void convertDataToAbs(); // 转换为绝对坐标数据 + void writePointToFile(int x, int y, int flag = 0);//写入起始点到文件中 + void writePatternParaToFile(DstHead *head);//将花样参数配置写到文件中 + void writeOffsetXYMoveToFile(s32 EnFlag,s32 offsetX,s32 offsetY); + int checkDstFile();//检查dst文件是否正确 + DstHead * getDstHead(); + void moveDataBeginPonit(s32 left, s32 front);//移动数据起始点 + +public: + void clear(); + void loadFile(); + void saveFile(); + inline const QString & getFileFullPathName() const {return m_fileFullPathName;} // 文件路径名称 + inline QByteArray & getFileData() {return m_fileData;} // 得到文件数据 + inline QByteArray & getEmbAbsData() {return m_embAbsData;} // 得到转换后的数据 + QString getFileFullPath(); // 文件所在目录 + QString getFileFullName(); // 文件名称(包括扩展名) + QString getFileName(); // 文件名称(不包括扩展名) + QString getFileSuffix(); // 文件扩展名 + + int getStitchNums();//得到数据的针数 + int getFileid();//得到fileid + int getDatWidth();//得到数据的图形宽度 + int getDatHeight();//得到数据的图形高度 + int getMaxX();//得到数据最大X+ + int getMinX();//得到数据最小X- + int getMaxY();//得到数据最大Y+ + int getMinY();//得到数据最小Y- + int getBeginXYAndAnchorXY(int &beginX, int &beginY, int &anchorX, int &anchorY); + +protected: + QString m_fileFullPathName; // 文件路径 + QByteArray m_embAbsData; // 转换后的绝对坐标数据 + +private: + QByteArray m_fileData;// 文件数据内容(原始数据) + QString m_fileName; // 文件路径 + +private: + double m_minX; + double m_maxX; + double m_minY; + double m_maxY; + +private: + int changeDstStep(DstStep * pDststep, Ds4Item & ds4step); + +}; + +#endif // DATAFILEDST_H diff --git a/datafile/datafilequi.cpp b/datafile/datafilequi.cpp new file mode 100644 index 0000000..bda5045 --- /dev/null +++ b/datafile/datafilequi.cpp @@ -0,0 +1,1014 @@ +#include "datafilequi.h" + + +DataFileQui::DataFileQui() +{ + clear(); +} + +void DataFileQui::convertDataToEmbAbs(s16 flag) +{ + m_absData.clear(); + getQuiMinMax(); + + QuiFileHead head; + + // 图形数据 + int i, datasize, idx; + BYTE ch1, ch2; + WORD tmpls,lsdata; + double deltx1, delty1, deltx2, delty2; + double threex[4], threey[4]; + s16 nmstep; + + double factorx, factory, unitmuti; + memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead)); + unitmuti = getMutiUnit(head.unit); + + double scanx = head.scanX * unitmuti; // 宽度 + double scany = head.scanY * unitmuti; // 长度 + + if (scanx < 1) + { + scanx = 1; + } + if (scany < 1) + { + scany = 1; + } + + // 计算缩放系数 + factorx = (double)((m_maxX-m_minX) / (scanx)); + factory = (double)((m_maxY-m_minY) / (scany)); + + if(factorx == 0){factorx = 1;} + if(factory == 0){factory = 1;} +// factorx = 1; +// factory = 1; + + if(flag != 1) + { + factorx = 1; + factory = 1; + } + + nmstep = head.normalStep * unitmuti; + if(nmstep == 0) + { + nmstep = 200; //单位0.01mm(2mm) + } + + i = sizeof(QuiFileHead); + datasize = m_quiFileData.size(); + + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + //将第一个点加进来 + absItem.ctrl = m_firstPoint.ctrl; + absItem.ax = m_firstPoint.x / factorx; + absItem.ay = m_firstPoint.y / factory; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + + while(i < datasize) + { + // 图元类型 + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + tmpls = (unsigned short) (ch2 * 256) + ch1; + + if(tmpls == 0xffff) // 结束 + { + break; + } + + switch(tmpls) + { + case QUI_TYPE_LINE: // 直线 + case QUI_TYPE_STEP: // 跨步 + case QUI_TYPE_HSTEP: // 翻头跨步 + { + //增加剪线 + if(tmpls == QUI_TYPE_STEP || tmpls == QUI_TYPE_HSTEP) + { + if((u32)m_absData.size() >= sizeof(DsAbsItem)) + { + memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); + absItem.ctrl = DATA_CUTTRD; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + } + } + + // 点个数 + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + lsdata = (unsigned short)ch2 * 256 + ch1; + + if (lsdata > 1) + { + // 第一个点 + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + deltx2 = (ch2 * 256.0 + ch1)/factorx; + + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + delty2 = (ch2 * 256.0 + ch1)/factory; + + for(idx = 1; idx < lsdata; idx++) // 其余的点 + { + deltx1 = deltx2; + delty1 = delty2; + + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + deltx2 = (ch2 * 256.0 + ch1)/factorx; + + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + delty2 = (ch2 * 256.0 + ch1)/factory; + + // 处理直线 + calcLine(deltx1, delty1, deltx2, delty2, nmstep, m_absData, tmpls); + } + if (idx != lsdata) + { + break; + } + } + break; + } + case QUI_TYPE_ARC: // 三点圆弧 + { + for (idx = 0; idx < 3; idx++) + { + // 点x + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threex[idx] = (ch2 * 256.0 + ch1)/factorx; + + // 点y + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threey[idx] = (ch2 * 256.0 + ch1)/factory; + } + + calcCurve(threex, threey, nmstep, m_absData); + + if (idx != 3) + { + break; + } + break; + } + case QUI_TYPE_BES: // 贝塞尔曲线 + { + for (idx = 0; idx < 4; idx++) + { + // 点x + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threex[idx] = (ch2 * 256.0 + ch1)/factorx; + + // 点y + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threey[idx] = (ch2 * 256.0 + ch1)/factory; + } + + // 处理贝塞尔曲线 + QList splineListXY;//拟合后的点 + splineListXY.clear(); + getBezierPointList(threex, threey, nmstep,splineListXY); + + QList splitListXY;//均分后的点 + splitListXY.clear(); + if(splineListXY.size() > 0) + { + getCurvePointFillLine(splineListXY,nmstep,splitListXY,0,OBJECT_STITCHLEN_NEW_SAMALL); + } + + //添加贝塞尔曲线数据点 + for(int i = 0; i < splitListXY.size(); i++) + { + memset(&absItem,0,sizeof(DsAbsItem)); + + deltx1 = splitListXY[i].x(); + delty1 = splitListXY[i].y(); + + absItem.ctrl = DATA_SEWING; + absItem.ax = deltx1; + absItem.ay = delty1; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + } + //calcBezier(threex, threey, nmstep, m_absData); + + if (idx != 4) + { + break; + } + break; + } + default: + break; + } + } + + //生成绝对坐标数据的文件头 + creatAbsHeadAndAr(); +} + +void DataFileQui::creatAbsHeadAndAr() +{ + DataDs16FileHead dhead; + memset(&dhead, 0, sizeof(DataDs16FileHead)); + + int stepSize = m_absData.size()/sizeof(DsAbsItem); + if(stepSize <= 0) + { + return; + } + + DsAbsItem * absDataPtr = (DsAbsItem *)(m_absData.data()); + + double minX, maxX, minY, maxY; + minX = S32_MAX; + maxX = S32_MIN; + minY = S32_MAX; + maxY = S32_MIN; + + double prex,prey,curx,cury,dx,dy,ar; + prex = prey = curx = cury = dx = dy = ar = 0; + + //取反并求最大最小值 + for (int i = 0; i < stepSize; i++) + { + absDataPtr->ax *= QUI_DATADIRX; + absDataPtr->ay *= QUI_DATADIRY; + + curx = absDataPtr->ax; + cury = absDataPtr->ay; + + if(curx > maxX) + { + maxX = curx; + } + if(curx < minX) + { + minX = curx; + } + + if(cury > maxY) + { + maxY = cury; + } + if(cury < minY) + { + minY = cury; + } + + absDataPtr++; + } + + absDataPtr = (DsAbsItem *)(m_absData.data()); + double begX = absDataPtr->ax;//起始点 + double begY = absDataPtr->ay; + int begR = 0; + + //求dr并将每点坐标都减去第一点坐标 + for (int i = 0; i < stepSize; i++) + { + curx = absDataPtr->ax; + cury = absDataPtr->ay; + + dx = curx - prex; + dy = cury - prey; + + double tar = atan2(dy,dx); + ar = (tar*10000+0.5*(tar>0?1:-1)); + absDataPtr->ar = ar; + + prex = curx; + prey = cury; + + //将每个坐标都减去起始点坐标 + absDataPtr->ax -= begX; + absDataPtr->ay -= begY; + absDataPtr->ar -= begR; + + absDataPtr++; + } + + //增加结束码 + if((u32)m_absData.size() >= sizeof(DsAbsItem)) + { + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); + absItem.ctrl = DATA_NULL; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + stepSize++; + } + + m_maxX = maxX-begX; + m_minX = minX-begX; + m_maxY = maxY-begY; + m_minY = minY-begY; + + //生成文件头 + dhead.maxX = maxX; + dhead.maxY = maxY; + dhead.minX = minX; + dhead.minY = minY; + dhead.beginX = begX-minX;//起始点减去最小值 + dhead.beginY = begY-minY;//起始点减去最小值 + dhead.beginR = begR; + dhead.anchorX = 0; + dhead.anchorY = 0; + dhead.itemNums = stepSize; + dhead.dataSize = stepSize*sizeof(DsAbsItem); // 数据字节数 + dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 + dhead.dataChecksum = calcCheckSum32((u8 *)(m_absData.data()) , dhead.dataSize);; // 数据累加校验和 + dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) + dhead.fileid = dhead.checkCrc; + m_absData.insert(0,(char*)&dhead,sizeof(DataDs16FileHead)); +} + +void DataFileQui::getQuiMinMax() +{ + QuiFileHead head; + memcpy(&head, m_quiFileData.data(), sizeof(QuiFileHead)); + + int i, idx, datasize; + unsigned char ch1, ch2; + unsigned short tmpls, lsdata; + double deltx, delty; + double threex[4], threey[4]; + + int first = 0; + double minx, maxx, miny, maxy; + + minx = S32_MAX; + maxx = S32_MIN; + miny = S32_MAX; + maxy = S32_MIN; + + i = sizeof(QuiFileHead); + datasize = m_quiFileData.size(); + while(i < datasize) + { + // 图元类型 + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + tmpls = (unsigned short) (ch2 * 256) + ch1; + + if(tmpls == 0xffff) // 结束 + { + break; + } + + switch(tmpls) + { + case QUI_TYPE_LINE: // 直线(折线) + case QUI_TYPE_STEP: // 跨步 + case QUI_TYPE_HSTEP: // 翻头跨步 + { + // 点个数 + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + lsdata = (unsigned short)ch2 * 256 + ch1; + + if (lsdata > 1) + { + for(idx = 0; idx < lsdata; idx++) // 点 + { + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + deltx = (ch2 * 256.0 + ch1); + + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + delty = (ch2 * 256.0 + ch1); + + if (first == 0) + { + m_firstPoint.x = deltx; + m_firstPoint.y = delty; + if(tmpls == QUI_TYPE_LINE) + { + m_firstPoint.ctrl = DATA_SEWING; + } + else + { + m_firstPoint.ctrl = DATA_OFFSET; + } + first = 1; + } + + if(deltx > maxx) + { + maxx = deltx; + } + if(deltx < minx) + { + minx = deltx; + } + + if(delty > maxy) + { + maxy = delty; + } + if(delty < miny) + { + miny = delty; + } + } + if (idx != lsdata) + { + break; + } + } + } + break; + case QUI_TYPE_ARC: // 三点圆弧 + { + for (idx = 0; idx < 3; idx++) + { + // 点x + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threex[idx] = (ch2 * 256.0 + ch1); + + // 点y + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threey[idx] = (ch2 * 256.0 + ch1); + + if (first == 0) + { + m_firstPoint.x = threex[0]; + m_firstPoint.y = threey[0]; + m_firstPoint.ctrl = DATA_SEWING; + first = 1; + } + } + if (idx != 3) + { + break; + } + + if(isThreePointOnALine(threex, threey) >= 1) // 3点共线 + { + // printf("three point on a line\n"); + if(threex[0] > maxx) maxx = threex[0]; + if(threex[1] > maxx) maxx = threex[1]; + if(threex[2] > maxx) maxx = threex[2]; + if(threex[0] < minx) minx = threex[0]; + if(threex[1] < minx) minx = threex[1]; + if(threex[2] < minx) minx = threex[2]; + + if(threey[0] > maxy) maxy = threey[0]; + if(threey[1] > maxy) maxy = threey[1]; + if(threey[2] > maxy) maxy = threey[2]; + if(threey[0] < miny) miny = threey[0]; + if(threey[1] < miny) miny = threey[1]; + if(threey[2] < miny) miny = threey[2]; + } + else + { + // printf("before GetArcMinMax\n"); + // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); + getArcMinMax(threex, threey, &minx, &maxx, &miny, &maxy); + // printf("after GetArcMinMax\n"); + // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); + } + } + break; + case QUI_TYPE_BES: // 贝塞尔曲线 + { + for (idx = 0; idx < 4; idx++) + { + // 点x + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threex[idx] = (ch2 * 256.0 + ch1); + + // 点y + if (i >= datasize){break;} + ch1 = m_quiFileData.at(i++); + if (i >= datasize){break;} + ch2 = m_quiFileData.at(i++); + threey[idx] = (ch2 * 256.0 + ch1); + + if (first == 0) + { + m_firstPoint.x = threex[0]; + m_firstPoint.y = threey[0]; + m_firstPoint.ctrl = DATA_SEWING; + first = 1; + } + } + if (idx != 4) + { + break; + } + + getBezierMinMax(threex, threey, &minx, &maxx, &miny, &maxy); + } + break; + } + } + + if (first == 0) + { + minx = 0; + maxx = 0; + miny = 0; + maxy = 0; + + m_firstPoint.x = 0; + m_firstPoint.y = 0; + m_firstPoint.ctrl = 0; + } + + m_minX = minx; + m_maxX = maxx; + m_minY = miny; + m_maxY = maxy; + + return; +} + +int DataFileQui::checkFileHead() +{ + if (m_quiFileData.size() >= (int)sizeof(QuiFileHead)) + { + QuiFileHead * pHead; + pHead = (QuiFileHead *)(m_quiFileData.data()); + + if (pHead->normalStep < 1) + { + pHead->normalStep = 40; + } + + if (pHead->miniStep < 1) + { + pHead->miniStep = 40; + } + + if (pHead->scanX < 1) + { + pHead->scanX = m_maxX - m_minX; + } + + if (pHead->scanY < 1) + { + pHead->scanY = m_maxY - m_minY; + } + + QFile wrfile(m_fileFullPathName); + if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + return -1; + } + else + { + wrfile.write(m_quiFileData); + wrfile.close(); + } + } + + return 0; +} + +double DataFileQui::getMutiUnit(int unit) +{ + double unitmuti; + if (unit == 0x00) // 0x00: 0.1mm; + { + unitmuti = 10; + } + else if (unit == 0x01) // 0x01: 1/1000inch; + { + unitmuti = 2.54; + } + else if (unit == 0x02) // 0x02: 0.04mm + { + unitmuti = 10; + } + else + { + unitmuti = 1; + } + return unitmuti; +} + +void DataFileQui::initFile(const QString &fullPathName) +{ + clear(); + QFileInfo file(fullPathName); + if (file.exists() && file.isFile()) + { + m_fileFullPathName = fullPathName; + } + else + { + qDebug() << "Init file failed path =" << m_fileFullPathName; + } + loadFile(); +} + +void DataFileQui::clear() +{ + m_firstPoint.x = 0; + m_firstPoint.y = 0; + m_firstPoint.ctrl = 0; + + m_minX = INT32_MAX; + m_maxX = INT32_MIN; + m_minY = INT32_MAX; + m_maxY = INT32_MIN; + + m_fileFullPathName.clear(); // 文件路径 + m_quiFileData.clear(); // 文件数据内容 + m_absData.clear(); // 转换后的数据 +} + +void DataFileQui::loadFile() +{ + QFile rdfile(m_fileFullPathName); + if(!rdfile.open(QIODevice::ReadOnly)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + m_quiFileData = rdfile.readAll(); + rdfile.close(); +} + +int DataFileQui::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw) +{ +#if(1) + s16 existFlag = 1; + + if(reDraw == 0)//图片存在则不重画 + { + existFlag = 0; + // 图片是否存在,存在则返回 + QString previewPath = getFileFullPathName() + ".preview.png"; + QFile imageFile(previewPath); + if (imageFile.exists()) + { + return 0; + } + } +#endif + + int newimgflag = 0; + QImage * pImage; + int width, height; + if (pImg == NULL) + { + width = QUI_PREVIEW_WIDTH; + height = QUI_PREVIEW_HEIGHT; + pImage = new QImage(width, height, IMAGE_TYPE); + newimgflag = 1; + } + else + { + pImage = pImg; + } + + width = pImage->width(); + height = pImage->height(); + if (width <= QUI_PREVIEW_SIDE*2 || height <= QUI_PREVIEW_SIDE*2) + { + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + qDebug("preview img too small"); + return -1; + } + + memset(pImage->bits(), 0x00, pImage->byteCount()); + + QPainter painter(pImage); + QColor backcolor(255, 255, 255, 0); // 透明背景 + // 背景 + QPen pen; + pen.setWidth(penwidth); + pen.setColor(backcolor); + painter.setPen(pen); + painter.setBrush(backcolor); + painter.drawRect(0, 0, width, height); + + // 图形 + //qDebug()<<"convertDataToAbs defore"; + convertDataToEmbAbs(existFlag); // 转换为绝对坐标数据 + //qDebug()<<"convertDataToAbs end"; + + // absdat数据 + int size = m_absData.size(); + if (size <= (int)sizeof(DataDs16FileHead)) + { + qDebug("2 data less then head size"); + return -1; + } + DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_absData.data()); + int datasize = size - sizeof(DataDs16FileHead); + if (datasize <= 0) + { + qDebug("absdat dataBegin err"); + return -1; + } + int stepsize = datasize/sizeof(DsAbsItem); + if (stepsize <= 0) + { + qDebug("absdat data size err"); + return -1; + } + DsAbsItem * pData = (DsAbsItem *)(m_absData.data() + sizeof(DataDs16FileHead)); + DsAbsItem * absDataPtr = pData; + //-------- + + // 图形显示区域 + int dpminx = QUI_PREVIEW_SIDE; + int dpmaxx = width - QUI_PREVIEW_SIDE; + int dpminy = QUI_PREVIEW_SIDE; + int dpmaxy = height - QUI_PREVIEW_SIDE; + + // 计算缩放系数 + double factor, temp; + if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) + { + return -1; + } + + factor = (double)(fabs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 + temp = (double)(fabs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按x计算的缩放系数 + + if (temp >= factor) // 使用较大的缩放系数 + { + factor = temp; + } + + // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) + double dpx = (double)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); + double dpy = (double)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); + + // 显示花样图形 + u8 ctrlByte; + double dx; + double dy; + + double datposx, datposy; + double curx, cury, prex, prey; + + datposx = pAbsHead->beginX; + datposy = pAbsHead->beginY; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (QUI_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (QUI_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + absDataPtr = pData; + + QColor color = QColor(Qt::green); + pen.setColor(color); + painter.setPen(pen); + + for (int i = 0; i < stepsize; i++) + { + // 读入一个针步数据 + ctrlByte = absDataPtr->ctrl; + + prex = curx; + prey = cury; + + dx = absDataPtr->ax; + dy = absDataPtr->ay; + + datposx = dx; + datposy = dy; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (QUI_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (QUI_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + if(i == 0) + { + absDataPtr++; + continue; + } + + if ( ctrlByte == DATA_SEWING) + { + painter.drawLine(prex, prey, curx, cury); + } + else + { + //qDebug("other type=0x%x", ctrlByte); + } + + absDataPtr++; + } + + // 保存成文件 + QString preview = getFileFullPathName(); + if (saveflag != 0 && preview.isEmpty() == false) + { +#if (1) + preview += ".preview.png"; + pImage->save(preview, "png"); +#endif + } + + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + + return 0; +} + +QuiFileHead *DataFileQui::getQuiHead() +{ + if(m_quiFileData.size() <= 0) + { + loadFile(); + } + + QuiFileHead *head = NULL; + + int size = m_quiFileData.size(); + if (size <= (int)(sizeof(QuiFileHead))) + { + return head; + } + + head = (QuiFileHead *)(m_quiFileData.data()); + return head; +} + +void DataFileQui::writePatternParaToFile(QuiFileHead *head) +{ + if(m_quiFileData.size() <= 0) + { + return; + } + + memcpy(m_quiFileData.data(),(char*)head,sizeof(QuiFileHead)); + + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_quiFileData); + wfile.close(); +} + +void DataFileQui::moveDataBeginPonit(s32 left, s32 front) +{ + if((u32)m_absData.size() > sizeof(DataDs16FileHead)) + { + DataDs16FileHead *dhead = (DataDs16FileHead *)( m_absData.data()); + dhead->beginX += left; + dhead->beginY += front; + dhead->maxX += left; + dhead->minX += left; + dhead->maxY += front; + dhead->minY += front; + } +} + +int DataFileQui::getStitchNums() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->itemNums; +} + +int DataFileQui::getDatWidth() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return (pHead->maxX - pHead->minX); +} + +int DataFileQui::getDatHeight() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return (pHead->maxY - pHead->minY); +} + +int DataFileQui::getMaxX() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->maxX; +} + +int DataFileQui::getMinX() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->minX; +} + +int DataFileQui::getMaxY() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->maxY; +} + +int DataFileQui::getMinY() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->minY; +} diff --git a/datafile/datafilequi.h b/datafile/datafilequi.h new file mode 100644 index 0000000..5b8e435 --- /dev/null +++ b/datafile/datafilequi.h @@ -0,0 +1,130 @@ +#ifndef DATAFILEQUI_H +#define DATAFILEQUI_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "math.h" +#include +#include "stdint.h" + +//#include "vectorsqrt.h" +#include "machine/comm/datadef.h" +#include "machine/comm/crc16.h" +#include "datafile/dataoperat.h" + +#define QUI_DATADIRX (1) // X向数据坐标与下位机坐标系统的差异 +#define QUI_DATADIRY (-1) // Y向数据坐标与下位机坐标系统的差异 +#define QUI_DATADIRR (-1) // R向数据坐标与下位机坐标系统的差异 + +#define QUI_SHOWDIRX (1) // X向显示坐标和数据坐标的差异 +#define QUI_SHOWDIRY (-1) // Y向显示坐标和数据坐标的差异 + +#define QUI_PREVIEW_SIDE (15) // 留边大小 +#define QUI_PREVIEW_WIDTH (156) // 默认预览图区域宽度 +#define QUI_PREVIEW_HEIGHT (164) // 默认预览图区域高度 + +typedef struct tagQuiltingFileHead +{ + char id[4]; // 0x00—0x03; 标志:=="RICH" + char name[8]; // 0x04—0x07; 文件名 + unsigned char reserve1[4]; // 0x0C—0x0F; 保留 + unsigned char ver; // 0x10; 版本号 + unsigned char unit; // 0x11; 单位 0x00: 0.1mm; 0x01: 1/1000inch; 0x02: 0.04mm;0x03: 0.01mm + unsigned char type; // 0x12; 类型, 0x00: 多针机英制; 0x01: 多针机公制; 0x10: 单头机英制; 0x11:单头机公制 + unsigned char reserve2[11]; // 0x13—0x1D; 保留 + unsigned short HStep; // 0x1E—0x1F; 水平方向针距 单位:0.1mm(绘制用,多针机) + unsigned short leftRightLen; // 0x20—0x21; 左针右针距离 单位:0.1mm(绘制用,多针机) + unsigned short VStep12; // 0x22—0x23; 第1 2排针距 单位:0.1mm(绘制用,多针机) + unsigned short VStep23; // 0x24—0x25; 第2 3排针距 单位:0.1mm(绘制用,多针机) + + // 排针每个字节:XXXX XXXX + // 针位n (0x00:无针,0x01:右针, 0x10:左针,0x11:左右针) + unsigned char arrayNeedle1[48]; // 0x26—0x55; 第1排排针(绘制用,多针机) + unsigned char arrayNeedle2[48]; // 0x56—0x85; 第2排排针(绘制用,多针机) + unsigned char arrayNeedle3[48]; // 0x86—0xB5; 第3排排针(绘制用,多针机) + unsigned char rotateStyle; // 0xB6; 旋转式样 + unsigned char rotateAngle; // 0xB7; 旋转角度 + unsigned char reinMode; // 0xB8; 加固方式 + unsigned char reinNum; // 0xB9; 次数 + unsigned char reserve3[4]; // 0xBA—0xBD; 保留 + unsigned short angleCorrOffset; // 0xBE ; 角度修正量 (中间数据后,可以修改,拐角补偿,单针机和多针机,新加-hhy) + unsigned char angleCorrPosX; // 0xC0 ; 角度修正x正(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned char angleCorrPosY; // 0xC1 ; 角度修正y正(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned char angleCorrNegX; // 0xC2 ; 角度修正x负(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned char angleCorrNegY; // 0xC3 ; 角度修正y负(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned char stepQui[2]; // 0xC4—0xC5; 跨步绗缝 + unsigned char reinNeedles; // 0xC6; 加固绗缝针数(中间数据后,可以修改,终点有跨步的才加,单针机和多针机) + unsigned char rollaYUpDn; // 0xC7; 罗拉补偿y上下(中间数据后,让图形闭合,可以修改,多针机) + unsigned char rollaYRev; // 0xC8; 罗拉补偿y预留 + unsigned char normalStep; // 0xC9; 针步大小(中间数据前,可以修改,单针机和多针机) + unsigned char miniStep; // 0xCA; 最小针步 + unsigned char reserve4[4]; // 0xCB—0xCE; 保留 + unsigned char saddleRatio[2]; // 0xCF—0xD0; 鞍架比例 + unsigned char rollaRatio[2]; // 0xD1—0xD2; 罗拉比例 + unsigned char reinQuiNeedleHigh; // 0xD3; 加固绗缝针数高字节 + unsigned short left; // 0xD4—0xD5; 左边 (中间数据后,可以修改,改变起始点,单针机) + unsigned short front; // 0xD6—0xD7; 前边 (中间数据后,可以修改,改变起始点,单针机) + unsigned short scanX; // 0xD8—0xD9; 缩放X (中间数据前,可以修改,单针机和多针机) + unsigned short scanY; // 0xDA—0xDB; 缩放Y (中间数据前,可以修改,单针机和多针机) + unsigned short totalOutput; // 0xDC—0xDD; 本花样累计总产量 + unsigned short currentOutput; // 0xDE—0xDF; 本花样当次产量 + unsigned short serWorkLa; // 0xE0-0xE1; 连续作业前留边 + unsigned short serWorkLb; // 0xE2-0xE3; 连续作业后留边 + unsigned char stepCompUpDn; // 0xE4; 跨步补偿y上下(多针机专业)(中间数据后,可以修改,多针机) + + unsigned char reserve6[27]; // 0xE5—0xFF; 保留 + +} __attribute__ ((packed)) QuiFileHead; + +class DataFileQui +{ +public: + DataFileQui(); + +protected: + QString m_fileFullPathName; // 文件路径 + QByteArray m_absData; // 转换后的绝对坐标数据 + QByteArray m_quiFileData;// 文件数据内容(原始数据) + +private: + double m_minX; + double m_maxX; + double m_minY; + double m_maxY; + QuiPoint m_firstPoint; + +private: + void creatAbsHeadAndAr();//生成绝对坐标数据文件头及ar + void getQuiMinMax(); + int checkFileHead(); + double getMutiUnit(int unit); + +public: + void initFile(const QString & fullPathName); + void clear(); + void loadFile(); + void convertDataToEmbAbs(s16 flag = 1); + int createPreviewImage(QImage * pImg = NULL, int saveflag = 0, int penwidth = 1, int reDraw = 0); // 生成预览文件 + inline const QString & getFileFullPathName() const {return m_fileFullPathName;} // 文件路径名称 + inline QByteArray & getEmbAbsData() {return m_absData;} // 得到转换后的数据 + QuiFileHead *getQuiHead(); + void writePatternParaToFile(QuiFileHead *head);//将花样参数配置写到文件中 + void moveDataBeginPonit(s32 left, s32 front);//移动数据起始点 + +public: + int getStitchNums();//得到数据的针数 + int getDatWidth();//得到数据的图形宽度 + int getDatHeight();//得到数据的图形高度 + int getMaxX();//得到数据最大X+ + int getMinX();//得到数据最小X- + int getMaxY();//得到数据最大Y+ + int getMinY();//得到数据最小Y- +}; + +#endif // DATAFILEQUI_H diff --git a/datafile/datafilequix.cpp b/datafile/datafilequix.cpp new file mode 100644 index 0000000..f2774a3 --- /dev/null +++ b/datafile/datafilequix.cpp @@ -0,0 +1,1297 @@ +#include "datafilequix.h" + + +DataFileQuix::DataFileQuix() +{ + clear(); +} + +void DataFileQuix::convertDataToEmbAbs(s16 flag) +{ + m_absData.clear(); + getQuixMinMax(); + + QuixFileHead head; + + // 图形数据 + u32 i, datasize, idx; + unsigned char ctrl, tmpls; + + u8 c1, c2, c3, c4; + u32 lsdata; + double deltx1, delty1, deltx2, delty2; + double threex[4], threey[4]; + s16 nmstep; + + double factorx, factory, unitmuti; + memcpy(&head, m_fileData.data(), sizeof(QuixFileHead)); + unitmuti = getMutiUnit(0); + + double scanx = head.scanX * unitmuti; // 宽度 + double scany = head.scanY * unitmuti; // 长度 + + if (scanx < 1) + { + scanx = 1; + } + if (scany < 1) + { + scany = 1; + } + + // 计算缩放系数 + factorx = (double)((m_maxX-m_minX) / (scanx)); + factory = (double)((m_maxY-m_minY) / (scany)); + + if(factorx == 0){factorx = 1;} + if(factory == 0){factory = 1;} +// factorx = 1; +// factory = 1; + + if(flag != 1) + { + factorx = 1; + factory = 1; + } + + nmstep = head.normalStep * unitmuti; + if(nmstep == 0) + { + nmstep = 200; //单位0.01mm(2mm) + } + + i = sizeof(QuixFileHead); + datasize = m_fileData.size(); + + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + //将第一个点加进来 + absItem.ctrl = m_firstPoint.ctrl; + absItem.ax = m_firstPoint.x / factorx; + absItem.ay = m_firstPoint.y / factory; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + + while(i < datasize) + { + // 功能控制字 + if (i >= datasize){break;} + ctrl = m_fileData.at(i++); + + // 图元类型 + if (i >= datasize){break;} + tmpls = m_fileData.at(i++); + + // 附加控制字 + if (i >= datasize){break;} + m_fileData.at(i++); + if (i >= datasize){break;} + m_fileData.at(i++); + + if(ctrl == 0x00) // 结束 + { + break; + } + + switch(tmpls) + { + case QUI_TYPE_LINE: // 直线 + case QUI_TYPE_STEP: // 跨步 + case QUI_TYPE_HSTEP: // 翻头跨步 + { + //增加剪线 + if(tmpls == QUI_TYPE_STEP || tmpls == QUI_TYPE_HSTEP) + { + if((u32)m_absData.size() >= sizeof(DsAbsItem)) + { + memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); + absItem.ctrl = DATA_CUTTRD; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + } + } + + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + if (lsdata > 1) + { + // 第一个点 + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double x = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + deltx2 = x/factorx; + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double y = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + delty2 = y/factory; + + for(idx = 1; idx < lsdata; idx++) // 其余的点 + { + deltx1 = deltx2; + delty1 = delty2; + + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + x = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + deltx2 = x/factorx; + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + y = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + delty2 = y/factory; + + // 处理直线 + calcLine(deltx1, delty1, deltx2, delty2, nmstep, m_absData, tmpls); + } + + if (idx != lsdata) + { + break; + } + } + break; + } + case QUI_TYPE_ARC: // 三点圆弧 + { + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + if(lsdata != 3) + { + break; + } + + for (idx = 0; idx < lsdata; idx++) + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double x = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + threex[idx] = x/factorx; + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double y = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + threey[idx] = y/factory; + } + + calcCurve(threex, threey, nmstep, m_absData); + + if (idx != 3) + { + break; + } + break; + } + case QUI_TYPE_BES: // 贝塞尔曲线 + { + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + if(lsdata != 4) + { + break; + } + + for (idx = 0; idx < lsdata; idx++) + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double x = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + threex[idx] = x/factorx; + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double y = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + threey[idx] = y/factory; + } + + // 处理贝塞尔曲线 + QList splineListXY;//拟合后的点 + splineListXY.clear(); + getBezierPointList(threex, threey, nmstep,splineListXY); + + QList splitListXY;//均分后的点 + splitListXY.clear(); + if(splineListXY.size() > 0) + { + getCurvePointFillLine(splineListXY,nmstep,splitListXY,0,OBJECT_STITCHLEN_NEW_SAMALL); + } + + //添加贝塞尔曲线数据点 + for(int i = 0; i < splitListXY.size(); i++) + { + memset(&absItem,0,sizeof(DsAbsItem)); + + deltx1 = splitListXY[i].x(); + delty1 = splitListXY[i].y(); + + absItem.ctrl = DATA_SEWING; + absItem.ax = deltx1; + absItem.ay = delty1; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + } + //calcBezier(threex, threey, nmstep, m_absData); + + if (idx != 4) + { + break; + } + break; + } + case QUI_TYPE_SPLINE: // 样条 + { + QList quiListPoint;//样条拟合前的点集合 + quiListPoint.clear(); + + // 点个数 + if (i >= datasize){break;} + unsigned char c1 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c2 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c3 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + for(idx = 0; idx < lsdata; idx++) // 点 + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double x = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + deltx1 = x/factorx; + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + double y = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + delty1 = y/factory; + + QPointF point(deltx1,delty1); + quiListPoint.append(point); + } + + QList splineListXY;//拟合后的点 + splineListXY.clear(); + if(quiListPoint.size() <= 0) + { + break; + } + getSplineNew(quiListPoint,splineListXY); + + // 均分 + QList splitListXY;//均分后的点 + splitListXY.clear(); + if(splineListXY.size() > 0) + { + getCurvePointFillLine(splineListXY,nmstep,splitListXY,0,OBJECT_STITCHLEN_NEW_SAMALL); + } + + //添加样条曲线数据点 + for(int i = 0; i < splitListXY.size(); i++) + { + memset(&absItem,0,sizeof(DsAbsItem)); + + deltx1 = splitListXY[i].x(); + delty1 = splitListXY[i].y(); + + absItem.ctrl = DATA_SEWING; + absItem.ax = deltx1; + absItem.ay = delty1; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + } + + if(idx != lsdata) + { + break; + } + break; + } + default: + break; + } + } + + //生成绝对坐标数据的文件头 + creatAbsHeadAndAr(); +} + +void DataFileQuix::creatAbsHeadAndAr() +{ + DataDs16FileHead dhead; + memset(&dhead, 0, sizeof(DataDs16FileHead)); + + int stepSize = m_absData.size()/sizeof(DsAbsItem); + if(stepSize <= 0) + { + return; + } + + DsAbsItem * absDataPtr = (DsAbsItem *)(m_absData.data()); + + double minX, maxX, minY, maxY; + minX = S32_MAX; + maxX = S32_MIN; + minY = S32_MAX; + maxY = S32_MIN; + + double prex,prey,curx,cury,dx,dy,ar; + prex = prey = curx = cury = dx = dy = ar = 0; + + //取反并求最大最小值 + for (int i = 0; i < stepSize; i++) + { + absDataPtr->ax *= QUIX_DATADIRX; + absDataPtr->ay *= QUIX_DATADIRY; + + curx = absDataPtr->ax; + cury = absDataPtr->ay; + + if(curx > maxX) + { + maxX = curx; + } + if(curx < minX) + { + minX = curx; + } + + if(cury > maxY) + { + maxY = cury; + } + if(cury < minY) + { + minY = cury; + } + + absDataPtr++; + } + + absDataPtr = (DsAbsItem *)(m_absData.data()); + double begX = absDataPtr->ax;//起始点 + double begY = absDataPtr->ay; + int begR = 0; + + //求dr并将每点坐标都减去第一点坐标 + for (int i = 0; i < stepSize; i++) + { + curx = absDataPtr->ax; + cury = absDataPtr->ay; + + dx = curx - prex; + dy = cury - prey; + + double tar = atan2(dy,dx); + ar = (tar*10000+0.5*(tar>0?1:-1)); + absDataPtr->ar = ar; + + prex = curx; + prey = cury; + + //将每个坐标都减去起始点坐标 + absDataPtr->ax -= begX; + absDataPtr->ay -= begY; + absDataPtr->ar -= begR; + + absDataPtr++; + } + + //增加结束码 + if((u32)m_absData.size() >= sizeof(DsAbsItem)) + { + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + memcpy((char*)&absItem,m_absData.data()+m_absData.size()-sizeof(DsAbsItem),sizeof(DsAbsItem)); + absItem.ctrl = DATA_NULL; + m_absData.append((char*)&absItem,sizeof(DsAbsItem)); + stepSize++; + } + + m_maxX = maxX-begX; + m_minX = minX-begX; + m_maxY = maxY-begY; + m_minY = minY-begY; + + //生成文件头 + dhead.maxX = maxX; + dhead.maxY = maxY; + dhead.minX = minX; + dhead.minY = minY; + dhead.beginX = begX-minX;//起始点减去最小值 + dhead.beginY = begY-minY;//起始点减去最小值 + dhead.beginR = begR; + dhead.anchorX = 0; + dhead.anchorY = 0; + dhead.itemNums = stepSize; + dhead.dataSize = stepSize*sizeof(DsAbsItem); // 数据字节数 + dhead.bytesPerItem = sizeof(DsAbsItem); // 每项占的字节数 + dhead.dataChecksum = calcCheckSum32((u8 *)(m_absData.data()) , dhead.dataSize);; // 数据累加校验和 + dhead.checkCrc = calcCrc16((u8 *)(&dhead), HEAD_FIX_INFO_LEN); // 前面6个字段的CRC校验,(6个字段分别为:文件名称,字节数,项个数,每项字节数,每块字节数,数据累加和的CRC校验值) + dhead.fileid = dhead.checkCrc; + m_absData.insert(0,(char*)&dhead,sizeof(DataDs16FileHead)); +} + +void DataFileQuix::getQuixMinMax() +{ + QuixFileHead head; + memcpy(&head, m_fileData.data(), sizeof(QuixFileHead)); + + u32 i, idx, datasize; + unsigned char ctrl, tmpls; + u8 c1, c2, c3, c4; + u32 lsdata; + double deltx, delty; + double threex[4], threey[4]; + + int first = 0; + double minx, maxx, miny, maxy; + + minx = S32_MAX; + maxx = S32_MIN; + miny = S32_MAX; + maxy = S32_MIN; + + i = sizeof(QuixFileHead); + datasize = m_fileData.size(); + while(i < datasize) + { + // 功能控制字 + if (i >= datasize){break;} + ctrl = m_fileData.at(i++); + + // 图元类型 + if (i >= datasize){break;} + tmpls = m_fileData.at(i++); + + // 附加控制字 + if (i >= datasize){break;} + m_fileData.at(i++); + if (i >= datasize){break;} + m_fileData.at(i++); + + if(ctrl == 0x00) // 结束 + { + break; + } + + switch(tmpls) + { + case QUI_TYPE_LINE: // 直线(折线) + case QUI_TYPE_STEP: // 跨步 + case QUI_TYPE_HSTEP: // 翻头跨步 + { + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + if (lsdata > 1) + { + for(idx = 0; idx < lsdata; idx++) // 点 + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + deltx = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + delty = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + if (first == 0) + { + m_firstPoint.x = deltx; + m_firstPoint.y = delty; + m_firstPoint.ctrl = ctrl; + first = 1; + } + + if(deltx > maxx) + { + maxx = deltx; + } + if(deltx < minx) + { + minx = deltx; + } + + if(delty > maxy) + { + maxy = delty; + } + if(delty < miny) + { + miny = delty; + } + } + if (idx != lsdata) + { + break; + } + } + } + break; + case QUI_TYPE_ARC: // 三点圆弧 + { + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + if(lsdata != 3) + { + break; + } + + for (idx = 0; idx < lsdata; idx++) + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + threex[idx] = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + threey[idx] = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + if (first == 0) + { + m_firstPoint.x = threex[0]; + m_firstPoint.y = threey[0]; + m_firstPoint.ctrl = ctrl; + first = 1; + } + } + if (idx != 3) + { + break; + } + + if(isThreePointOnALine(threex, threey) >= 1) // 3点共线 + { + // printf("three point on a line\n"); + if(threex[0] > maxx) maxx = threex[0]; + if(threex[1] > maxx) maxx = threex[1]; + if(threex[2] > maxx) maxx = threex[2]; + if(threex[0] < minx) minx = threex[0]; + if(threex[1] < minx) minx = threex[1]; + if(threex[2] < minx) minx = threex[2]; + + if(threey[0] > maxy) maxy = threey[0]; + if(threey[1] > maxy) maxy = threey[1]; + if(threey[2] > maxy) maxy = threey[2]; + if(threey[0] < miny) miny = threey[0]; + if(threey[1] < miny) miny = threey[1]; + if(threey[2] < miny) miny = threey[2]; + } + else + { + // printf("before GetArcMinMax\n"); + // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); + getArcMinMax(threex, threey, &minx, &maxx, &miny, &maxy); + // printf("after GetArcMinMax\n"); + // printf("minx=%.2f,maxx=%.2f,miny=%.2f,maxy=%.2f\n", minx, maxx, miny, maxy); + } + } + break; + case QUI_TYPE_BES: // 贝塞尔曲线 + { + // 点个数 + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + if(lsdata != 4) + { + break; + } + + for (idx = 0; idx < lsdata; idx++) + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + threex[idx] = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + threey[idx] = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + if (first == 0) + { + m_firstPoint.x = threex[0]; + m_firstPoint.y = threey[0]; + m_firstPoint.ctrl = ctrl; + first = 1; + } + } + if (idx != 4) + { + break; + } + + getBezierMinMax(threex, threey, &minx, &maxx, &miny, &maxy); + } + break; + case QUI_TYPE_SPLINE: // 样条 + { + QList quiListPoint;//样条拟合前的点集合 + quiListPoint.clear(); + + // 点个数 + if (i >= datasize){break;} + unsigned char c1 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c2 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c3 = m_fileData.at(i++); + if (i >= datasize){break;} + unsigned char c4 = m_fileData.at(i++); + lsdata = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + for(idx = 0; idx < lsdata; idx++) // 点 + { + //点x + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + deltx = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + //点y + if (i >= datasize){break;} + c1 = m_fileData.at(i++); + if (i >= datasize){break;} + c2 = m_fileData.at(i++); + if (i >= datasize){break;} + c3 = m_fileData.at(i++); + if (i >= datasize){break;} + c4 = m_fileData.at(i++); + delty = (c4 << 24) + (c3 << 16) + (c2 << 8) + (c1); + + QPointF point(deltx,delty); + quiListPoint.append(point); + + if (first == 0) + { + m_firstPoint.x = deltx; + m_firstPoint.y = delty; + m_firstPoint.ctrl = ctrl; + first = 1; + } + } + getSplineMinMax(quiListPoint, &minx, &maxx, &miny, &maxy); + } + break; + } + } + + if (first == 0) + { + minx = 0; + maxx = 0; + miny = 0; + maxy = 0; + + m_firstPoint.x = 0; + m_firstPoint.y = 0; + m_firstPoint.ctrl = 0; + } + + m_minX = minx; + m_maxX = maxx; + m_minY = miny; + m_maxY = maxy; + + return; +} + +int DataFileQuix::checkFileHead() +{ + if (m_fileData.size() >= (int)sizeof(QuixFileHead)) + { + QuixFileHead * pHead; + pHead = (QuixFileHead *)(m_fileData.data()); + + if (pHead->normalStep < 1) + { + pHead->normalStep = 40; + } + + if (pHead->scanX < 1) + { + pHead->scanX = m_maxX - m_minX; + } + + if (pHead->scanY < 1) + { + pHead->scanY = m_maxY - m_minY; + } + + QFile wrfile(m_fileFullPathName); + if(!wrfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + return -1; + } + else + { + wrfile.write(m_fileData); + wrfile.close(); + } + } + + return 0; +} + +double DataFileQuix::getMutiUnit(int unit) +{ + double unitmuti; + if (unit == 0x00) // 0x00: 0.1mm; + { + unitmuti = 10; + } + else if (unit == 0x01) // 0x01: 1/1000inch; + { + unitmuti = 2.54; + } + else if (unit == 0x02) // 0x02: 0.04mm + { + unitmuti = 10; + } + else + { + unitmuti = 1; + } + return unitmuti; +} + +void DataFileQuix::initFile(const QString &fullPathName) +{ + clear(); + QFileInfo file(fullPathName); + if (file.exists() && file.isFile()) + { + m_fileFullPathName = fullPathName; + } + else + { + qDebug() << "Init file failed path =" << m_fileFullPathName; + } + loadFile(); +} + +void DataFileQuix::clear() +{ + m_firstPoint.x = 0; + m_firstPoint.y = 0; + m_firstPoint.ctrl = 0; + + m_minX = INT32_MAX; + m_maxX = INT32_MIN; + m_minY = INT32_MAX; + m_maxY = INT32_MIN; + + m_fileFullPathName.clear(); // 文件路径 + m_fileData.clear(); // 文件数据内容 + m_absData.clear(); // 转换后的数据 +} + +void DataFileQuix::loadFile() +{ + QFile rdfile(m_fileFullPathName); + if(!rdfile.open(QIODevice::ReadOnly)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + m_fileData = rdfile.readAll(); + rdfile.close(); +} + +int DataFileQuix::createPreviewImage(QImage *pImg, int saveflag, int penwidth, int reDraw) +{ +#if(1) + s16 existFlag = 1; + + if(reDraw == 0)//图片存在则不重画 + { + existFlag = 0; + // 图片是否存在,存在则返回 + QString previewPath = getFileFullPathName() + ".preview.png"; + QFile imageFile(previewPath); + if (imageFile.exists()) + { + return 0; + } + } +#endif + + int newimgflag = 0; + QImage * pImage; + int width, height; + if (pImg == NULL) + { + width = QUIX_PREVIEW_WIDTH; + height = QUIX_PREVIEW_HEIGHT; + pImage = new QImage(width, height, IMAGE_TYPE); + newimgflag = 1; + } + else + { + pImage = pImg; + } + + width = pImage->width(); + height = pImage->height(); + if (width <= QUIX_PREVIEW_SIDE*2 || height <= QUIX_PREVIEW_SIDE*2) + { + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + qDebug("preview img too small"); + return -1; + } + + memset(pImage->bits(), 0x00, pImage->byteCount()); + + QPainter painter(pImage); + QColor backcolor(255, 255, 255, 0); // 透明背景 + // 背景 + QPen pen; + pen.setWidth(penwidth); + pen.setColor(backcolor); + painter.setPen(pen); + painter.setBrush(backcolor); + painter.drawRect(0, 0, width, height); + + // 图形 + //qDebug()<<"convertDataToAbs defore"; + convertDataToEmbAbs(existFlag); // 转换为绝对坐标数据 + //qDebug()<<"convertDataToAbs end"; + + // absdat数据 + int size = m_absData.size(); + if (size <= (int)sizeof(DataDs16FileHead)) + { + qDebug("2 data less then head size"); + return -1; + } + DataDs16FileHead * pAbsHead = (DataDs16FileHead *)(m_absData.data()); + int datasize = size - sizeof(DataDs16FileHead); + if (datasize <= 0) + { + qDebug("absdat dataBegin err"); + return -1; + } + int stepsize = datasize/sizeof(DsAbsItem); + if (stepsize <= 0) + { + qDebug("absdat data size err"); + return -1; + } + DsAbsItem * pData = (DsAbsItem *)(m_absData.data() + sizeof(DataDs16FileHead)); + DsAbsItem * absDataPtr = pData; + //-------- + + // 图形显示区域 + int dpminx = QUIX_PREVIEW_SIDE; + int dpmaxx = width - QUIX_PREVIEW_SIDE; + int dpminy = QUIX_PREVIEW_SIDE; + int dpmaxy = height - QUIX_PREVIEW_SIDE; + + // 计算缩放系数 + double factor, temp; + if ((dpmaxx - dpminx) <= 0 || (dpmaxy - dpminy) <= 0) + { + return -1; + } + + factor = (double)(fabs(m_maxX - m_minX)) / (dpmaxx - dpminx); // 按x计算的缩放系数 + temp = (double)(fabs(m_maxY - m_minY)) / (dpmaxy - dpminy); // 按x计算的缩放系数 + + if (temp >= factor) // 使用较大的缩放系数 + { + factor = temp; + } + + // 计算显示参数,按照图形的实际位置显示(数据坐标零点对应图形中心) + double dpx = (double)((dpminx+dpmaxx)/2 - ((m_maxX+m_minX)/factor)/2); + double dpy = (double)((dpminy+dpmaxy)/2 - ((m_maxY+m_minY)/factor)/2); + + // 显示花样图形 + u8 ctrlByte; + double dx; + double dy; + + double datposx, datposy; + datposx = datposy = 0.; + double curx, cury, prex, prey; + curx = cury = prex = prey = 0; + + datposx = pAbsHead->beginX; + datposy = pAbsHead->beginY; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (QUIX_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (QUIX_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + absDataPtr = pData; + + QColor color = QColor(Qt::green); + pen.setColor(color); + painter.setPen(pen); + + for (int i = 0; i < stepsize; i++) + { + // 读入一个针步数据 + ctrlByte = absDataPtr->ctrl; + + prex = curx; + prey = cury; + + dx = absDataPtr->ax; + dy = absDataPtr->ay; + + datposx = dx; + datposy = dy; + + curx = (datposx) / factor + dpx; + cury = (datposy) / factor + dpy; + + if (QUIX_SHOWDIRX == -1) + { + curx = (width)-curx; + } + if (QUIX_SHOWDIRY == -1) + { + cury = (height)-cury; + } + + if(i == 0) + { + absDataPtr++; + continue; + } + + if (ctrlByte == DATA_SEWING) + { + painter.drawLine(prex, prey, curx, cury); + } + else + { + //painter.drawLine(prex, prey, curx, cury); + //qDebug("other type=0x%x", ctrlByte); + } + + absDataPtr++; + } + + // 保存成文件 + QString preview = getFileFullPathName(); + if (saveflag != 0 && preview.isEmpty() == false) + { +#if (1) + preview += ".preview.png"; + pImage->save(preview, "png"); +#endif + } + + if (pImage != NULL && newimgflag == 1) + { + delete pImage; + } + + return 0; +} + +QuixFileHead *DataFileQuix::getQuixHead() +{ + if(m_fileData.size() <= 0) + { + loadFile(); + } + + QuixFileHead *head = NULL; + + int size = m_fileData.size(); + if (size <= (int)(sizeof(QuixFileHead))) + { + return head; + } + + head = (QuixFileHead *)(m_fileData.data()); + return head; +} + +void DataFileQuix::writePatternParaToFile(QuixFileHead *head) +{ + if(m_fileData.size() <= 0) + { + return; + } + + memcpy(m_fileData.data(),(char*)head,sizeof(QuixFileHead)); + + QFile wfile(m_fileFullPathName); + if(!wfile.open(QIODevice::WriteOnly | QIODevice::Truncate)) + { + qDebug() << "open file fail when read, path =" << m_fileFullPathName; + return; + } + + wfile.write(m_fileData); + wfile.close(); +} + +void DataFileQuix::moveDataBeginPonit(s32 left, s32 front) +{ + if((u32)m_absData.size() > sizeof(DataDs16FileHead)) + { + DataDs16FileHead *dhead = (DataDs16FileHead *)( m_absData.data()); + dhead->beginX += left; + dhead->beginY += front; + dhead->maxX += left; + dhead->minX += left; + dhead->maxY += front; + dhead->minY += front; + } +} + +int DataFileQuix::getStitchNums() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->itemNums; +} + +int DataFileQuix::getDatWidth() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return (pHead->maxX - pHead->minX); +} + +int DataFileQuix::getDatHeight() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return (pHead->maxY - pHead->minY); +} + +int DataFileQuix::getMaxX() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->maxX; +} + +int DataFileQuix::getMinX() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->minX; +} + +int DataFileQuix::getMaxY() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->maxY; +} + +int DataFileQuix::getMinY() +{ + if(m_absData.size() <= 0) + { + return 0; + } + + DataDs16FileHead * pHead = (DataDs16FileHead *)((m_absData.data())); + return pHead->minY; +} diff --git a/datafile/datafilequix.h b/datafile/datafilequix.h new file mode 100644 index 0000000..1c941c3 --- /dev/null +++ b/datafile/datafilequix.h @@ -0,0 +1,118 @@ +#ifndef DATAFILEQUIX_H +#define DATAFILEQUIX_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "math.h" +#include +#include "stdint.h" + +//#include "vectorsqrt.h" +#include "machine/comm/datadef.h" +#include "machine/comm/crc16.h" +#include "datafile/dataoperat.h" + +#define QUIX_DATADIRX (1) // X向数据坐标与下位机坐标系统的差异 +#define QUIX_DATADIRY (-1) // Y向数据坐标与下位机坐标系统的差异 +#define QUIX_DATADIRR (-1) // R向数据坐标与下位机坐标系统的差异 + +#define QUIX_SHOWDIRX (1) // X向显示坐标和数据坐标的差异 +#define QUIX_SHOWDIRY (-1) // Y向显示坐标和数据坐标的差异 + +#define QUIX_PREVIEW_SIDE (15) // 留边大小 +#define QUIX_PREVIEW_WIDTH (156) // 默认预览图区域宽度 +#define QUIX_PREVIEW_HEIGHT (164) // 默认预览图区域高度 + +typedef struct tagQuixFileHead +{ + char id[7]; // 0x0000~0x0006; 标志:=="RICH" + char name[1]; // 0x0007; 文件名 + unsigned char reserve1[6]; // 0x0008~0x000D; 保留 + unsigned char rotateStyle; // 0x000E; 旋转式样 + unsigned char rotateAngle; // 0x000F; 旋转角度 + unsigned int left; // 0x0010~0x0013; 左边 (中间数据后,可以修改,改变起始点,单针机) + unsigned int front; // 0x0014~0x0017; 前边 (中间数据后,可以修改,改变起始点,单针机) + unsigned int scanX; // 0x0018~0x001B; 缩放X (中间数据前,可以修改,单针机和多针机) + unsigned int scanY; // 0x001C~0x001F; 缩放Y (中间数据前,可以修改,单针机和多针机) + unsigned int normalStep; // 0x0020~0x0023; 针步大小(中间数据前,可以修改,单针机和多针机) + unsigned int reinMode; // 0x0024~0x0027; 加固模式(中间数据后,可以修改,终点有跨步的才加,单针机和多针机) + unsigned int reinNeedles; // 0x0028~0x002B; 加固针数(中间数据后,可以修改,终点有跨步的才加,单针机和多针机) + unsigned int reinNum; // 0x002C~0x002F; 加固次数(中间数据后,可以修改,终点有跨步的才加,单针机和多针机) + unsigned int angleCorrPosX; // 0x0030~0x0033; 角度修正x正(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned int angleCorrPosY; // 0x0034~0x0037; 角度修正y正(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned int angleCorrNegX; // 0x0038~0x003B; 角度修正x负(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned int angleCorrNegY; // 0x003C~0x003F; 角度修正y负(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned int stepQuiCorrection; // 0x0040~0x0043; 跨步绗缝修正(中间数据后,可以修改,拐角补偿,单针机和多针机) + unsigned int rollaComp; // 0x0044~0x0047; 罗拉补偿(中间数据后,让图形闭合,可以修改,多针机) + unsigned short angleCorrOffset; // 0x0048~0x0049; 角度修正量 (中间数据后,可以修改,拐角补偿,单针机和多针机,新加-hhy) + unsigned char reserve2[6]; // 0x004A~0x004F; 保留 + unsigned int HStep; // 0x0050~0x0053; 水平方向针距 单位:0.1mm(绘制用,多针机) + unsigned int leftRightLen; // 0x0054~0x0057; 左针右针距离 单位:0.1mm(绘制用,多针机) + unsigned int VStep12; // 0x0058~0x005B; 第1 2排针距 单位:0.1mm(绘制用,多针机) + unsigned int VStep23; // 0x005C~0x005F; 第2 3排针距 单位:0.1mm(绘制用,多针机) + // 排针每个字节:XXXX XXXX + // 针位n (0x00:无针,0x01:右针, 0x10:左针,0x11:左右针) + unsigned char arrayNeedle1[48]; // 0x0060~0x008F; 第1排排针(绘制用,多针机) + unsigned char arrayNeedle2[48]; // 0x0090~0x00BF; 第2排排针(绘制用,多针机) + unsigned char arrayNeedle3[48]; // 0x00C0~0x00EF; 第3排排针(绘制用,多针机) + unsigned int firstPullLen; // 0x00F0~0x00F3; 一次拉料长度 + unsigned int secondPullLen; // 0x00F4~0x00F7; 二次拉料长度 + unsigned int triplePullLen; // 0x00F8~0x00FB; 三次拉料长度 + unsigned char reserve3[4]; // 0x00FC~0x00FF; 保留 + unsigned char reserve4[768]; // 0x0100~0x0400; 保留 + unsigned char reserve5[3072]; // 0x0401~0x1000; 保留 + +} __attribute__ ((packed)) QuixFileHead; + +class DataFileQuix +{ +public: + DataFileQuix(); + +protected: + QString m_fileFullPathName; // 文件路径 + QByteArray m_absData; // 转换后的绝对坐标数据 + QByteArray m_fileData;// 文件数据内容(原始数据) + +private: + double m_minX; + double m_maxX; + double m_minY; + double m_maxY; + QuiPoint m_firstPoint; + +private: + void creatAbsHeadAndAr();//生成绝对坐标数据文件头及ar + void getQuixMinMax(); + int checkFileHead(); + double getMutiUnit(int unit); + +public: + void initFile(const QString & fullPathName); + void clear(); + void loadFile(); + void convertDataToEmbAbs(s16 falg = 1); + int createPreviewImage(QImage * pImg = NULL, int saveflag = 0, int penwidth = 1, int reDraw = 0); // 生成预览文件 + inline const QString & getFileFullPathName() const {return m_fileFullPathName;} // 文件路径名称 + inline QByteArray & getEmbAbsData() {return m_absData;} // 得到转换后的数据 + QuixFileHead *getQuixHead(); + void writePatternParaToFile(QuixFileHead *head);//将花样参数配置写到文件中 + void moveDataBeginPonit(s32 left, s32 front);//移动数据起始点 + +public: + int getStitchNums();//得到数据的针数 + int getDatWidth();//得到数据的图形宽度 + int getDatHeight();//得到数据的图形高度 + int getMaxX();//得到数据最大X+ + int getMinX();//得到数据最小X- + int getMaxY();//得到数据最大Y+ + int getMinY();//得到数据最小Y- +}; + +#endif // DATAFILEQUI_H diff --git a/datafile/dataoperat.cpp b/datafile/dataoperat.cpp new file mode 100644 index 0000000..2d3a1af --- /dev/null +++ b/datafile/dataoperat.cpp @@ -0,0 +1,2304 @@ +#include "dataoperat.h" + +int isThreePointOnALine(const double threex[],const double threey[]) +{ + double k0,k1,k2; + + if (fabs(threex[0]-threex[1]) < 1e-6 + && fabs(threex[0]-threex[2]) < 1e-6 + && fabs(threex[2]-threex[1]) < 1e-6 + && fabs(threey[0]-threey[1]) < 1e-6 + && fabs(threey[0]-threey[2]) < 1e-6 + && fabs(threey[2]-threey[1]) < 1e-6 ) //三点几乎重合 + { + //printf("1.IsThreePointOnALine\n"); + return 1; + } + else if ((fabs(threex[0]-threex[1]) < 1e-6 && fabs(threey[0]-threey[1]) < 1e-6) + || (fabs(threex[0]-threex[2]) < 1e-6 && fabs(threey[0]-threey[2]) < 1e-6) + || (fabs(threex[2]-threex[1]) < 1e-6 && fabs(threey[2]-threey[1]) < 1e-6) ) + { + //三点间,有2点几乎重合 + if (fabs(threex[0]-threex[2]) < 1e-6 && fabs(threey[0]-threey[2]) < 1e-6) + { + //如果是两边2个点几乎重合,则将第2个点坐标->第3个点 + return 2; + } + else + { + //printf("2.IsThreePointOnALine\n"); + return 1; + } + } + else if (fabs(threex[0]-threex[1]) < 1e-6 + && fabs(threex[0]-threex[2]) < 1e-6 + && fabs(threex[2]-threex[1]) < 1e-6 ) + { + //三个点,X的差距极小 + //printf("3.IsThreePointOnALine\n"); + if (threey[0] < threey[2]) + { + if (threey[1] > threey[2]) + { + return 2; + } + } + else + { + if (threey[1] < threey[2]) + { + return 2; + } + } + return 1; + } + else if (fabs(threey[0]-threey[1]) < 1e-6 + && fabs(threey[0]-threey[2]) < 1e-6 + && fabs(threey[2]-threey[1]) < 1e-6 ) + { //三个点,Y的差距极小 + // printf("4.IsThreePointOnALine\n"); + if (threex[0] < threex[2]) + { + if (threex[1] > threex[2]) + { + return 2; + } + } + else + { + if (threex[1] < threex[2]) + { + return 2; + } + } + return 1; + } + else if (fabs(threex[2]-threex[1]) >= 1e-6 + && fabs(threex[2]-threex[0]) >= 1e-6 + && fabs(threex[1]-threex[0]) >= 1e-6 + && fabs(threey[2]-threey[1]) >= 1e-6 + && fabs(threey[2]-threey[0]) >= 1e-6 + && fabs(threey[1]-threey[0]) >= 1e-6 ) + { + k0 = (threey[2]-threey[1])/(threex[2]-threex[1]); + k1 = (threey[2]-threey[0])/(threex[2]-threex[0]); + k2 = (threey[1]-threey[0])/(threex[1]-threex[0]); + + if(fabs(k0-k1) < 1e-6 && fabs(k1-k2) < 1e-6) + { + //三个点,2点之间的斜率差极小 + //printf("5.IsThreePointOnALine\n"); + if ( (threex[0] < threex[1] && threex[1] < threex[2] ) + || (threex[0] > threex[1] && threex[1] > threex[2])) + { + } + else + { + return 2; + } + + return 1; + } + else + { + //printf("6.IsThreePointOnALine\n"); + return 0; + } + } + else + { + //printf("7.IsThreePointOnALine\n"); + return 0; + } +} + +int getArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr) +{ +#if 0 + double x20, x21, xh0, xh1, y20, y21, yk0, yk1; + double x2y20, x2y21, xnyn, ykn; + + double xx0,xx1,xx2; + double yy0,yy1,yy2; + xx0=x[0]; + yy0=y[0]; + xx1=x[1]; + yy1=y[1]; + xx2=x[2]; + yy2=y[2]; + + if(fabs(xx0-xx1)<1e-6) + { + yc=(yy0+yy1)/2; + xc=(xx0*xx0-xx2*xx2+yy0*yy0-yy2*yy2+2*yy2*yc-2*yy0*yc)/(2*xx0-2*xx2); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else if(fabs(xx0-xx2)<1e-6) + { + yc=(yy0+yy2)/2; + xc=(xx0*xx0-xx1*xx1+yy0*yy0-yy1*yy1+2*yy1*yc-2*yy0*yc)/(2*xx0-2*xx1); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else if(fabs(xx1-xx2)<1e-6) + { + yc=(yy1+yy2)/2; + xc=(xx1*xx1-xx0*xx0+yy1*yy1-yy0*yy0+2*yy0*yc-2*yy1*yc)/(2*xx1-2*xx0); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else if(fabs(yy0-yy1)<1e-6) + { + xc=(xx0+xx1)/2; + yc=(yy0*yy0-yy2*yy2+xx0*xx0-xx2*xx2+2*xx2*xc-2*xx0*xc)/(2*yy0-2*yy2); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else if(fabs(yy0-yy2)<1e-6) + { + xc=(xx0+xx2)/2; + yc=(yy0*yy0-yy1*yy1+xx0*xx0-xx1*xx1+2*xx1*xc-2*xx0*xc)/(2*yy0-2*yy1); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else if(fabs(yy1-yy2)<1e-6) + { + xc=(xx1+xx2)/2; + yc=(yy1*yy1-yy0*yy0+xx1*xx1-xx0*xx0+2*xx0*xc-2*xx1*xc)/(2*yy1-2*yy0); + r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc)); + } + else + { + x20=xx0*xx0-xx1*xx1; + xh0=2*xx0-2*xx1; + y20=yy0*yy0-yy1*yy1; + yk0=2*yy0-2*yy1; + + x21=xx1*xx1-xx2*xx2; + xh1=2*xx1-2*xx2; + y21=yy1*yy1-yy2*yy2; + yk1=2*yy1-2*yy2; + + x2y20=x20+y20; + x2y21=x21+y21; + + xnyn=x2y20; + ykn=yk0; + + x2y20 *= xh1; + yk0 *= xh1; + + x2y21 *= xh0; + yk1 *= xh0; + + yc = (x2y20-x2y21)/(yk0-yk1); + xc = (xnyn-yc*ykn)/xh0; + + xx0 -= xc; + yy0 -= yc; + + r=sqrt(xx0*xx0+yy0*yy0); + } + +#else + + double a, b, c, d, e, f; + double xc, yc, r; + + if (isThreePointOnALine(x, y) >= 1) + { + return -1; + } + + a = 2 * (x[1]-x[0]); + b = 2 * (y[1]-y[0]); + c = x[1]*x[1] + y[1]*y[1] - x[0]*x[0] - y[0]*y[0]; + d = 2 * (x[2]-x[1]); + e = 2 * (y[2]-y[1]); + f = x[2]*x[2] + y[2]*y[2] - x[1]*x[1] - y[1]*y[1]; + + xc = (b*f-e*c)/(b*d-e*a); + yc = (d*c-a*f)/(b*d-e*a); + r = sqrt((xc-x[0])*(xc-x[0])+(yc-y[0])*(yc-y[0])); +#endif + + *pxc = xc; + *pyc = yc; + *pr = r; + + return 0; +} + +int getArcMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy) +{ + double k, xc, yc, r; + int beg = 0; + int mid = 0; + int end = 0; + double minx, miny, maxx, maxy; + + getArcCenter(x, y, &xc, &yc, &r); + // printf("cx=%f, cy=%f, r=%f\n", xc, yc, r); + // 区分象限和方向 + k = (x[0]-x[1])*(x[2]-x[1]) + (y[0]-y[1])*(y[2]-y[1]); // 向量 01 和 向量 21 的夹角的余弦的符号-- + // > 0 小于90度 向量夹角小于90度, 说明弧是大于半圆 + // < 0 大于90度 向量夹角大于90度, 说明弧是小于半圆 + // = 0 90 度 向量夹角等于90度, 说明弧是半圆 + + if (x[0] > xc && y[0] > yc) // 起点在第一象限 + { + beg = 1; + } + else if (x[0] < xc && y[0] > yc) // 起点在第二象限 + { + beg = 2; + } + else if (x[0] < xc && y[0] < yc) // 起点在第三象限 + { + beg = 3; + } + else if (x[0] > xc && y[0] < yc) // 起点在第四象限 + { + beg = 4; + } + else if (fabs(y[0]-yc) < 1e-6) // 起点在x轴上 + { + if (x[0] > xc) + { + beg = 5; // x正半轴 + } + else + { + beg = 6; // x负半轴 + } + } + else if (fabs(x[0]-xc) < 1e-6) // 起点在y轴上 + { + if (y[0] > yc) + { + beg = 7; // y正半轴 + } + else + { + beg = 8; // y正半轴 + } + } + else + { + printf("this is an new selection for first point\n"); + } + + if (x[1] > xc && y[1] > yc) // 中点在第一象限 + { + mid = 1; + } + else if (x[1] < xc && y[1] > yc) // 中点在第二象限 + { + mid = 2; + } + else if (x[1] < xc && y[1] < yc) // 中点在第三象限 + { + mid = 3; + } + else if (x[1] > xc && y[1] < yc) // 中点在第四象限 + { + mid = 4; + } + else if (fabs(y[1]-yc)<1e-6) // 中点在x轴上 + { + if (x[1] > xc) {mid = 5;} // x正半轴 + else{ mid = 6; } // x负半轴 + } + else if (fabs(x[1]-xc)<1e-6) // 中点在y轴上 + { + if (y[1] > yc) // y正半轴 + { + mid = 7; + } + else { mid = 8; } // y负半轴 + } + else + { + printf("this is an new selection for second point\n"); + } + + if (x[2] > xc && y[2] > yc) // 终点在第一象限 + { + end = 1; + } + else if (x[2] < xc && y[2] > yc) // 终点在第二象限 + { + end = 2; + } + else if (x[2] < xc && y[2] < yc) // 终点在第三象限 + { + end = 3; + } + else if (x[2] > xc && y[2] < yc) // 终点在第四象限 + { + end = 4; + } + else if (fabs(y[2]-yc)<1e-6) // 终点在x轴上 + { + if (x[2] > xc) {end = 5;} // x正半轴 + else{end = 6;} // x负半轴 + } + else if (fabs(x[2]-xc)<1e-6) // 终点在y轴上 + { + if (y[2] > yc){ end = 7;} // y正半轴 + else{end = 8;} // y负半轴 + } + else + { + printf("this is an new selection for third point\n"); + } + + minx = S32_MAX; + maxx = S32_MIN; + miny = S32_MAX; + maxy = S32_MIN; + + switch (beg) + { + case 1: // 起点在第一象限内 + { + switch (end) + { + case 1: // 终点在第一象限内 + case 5: // 终点在x正半轴上 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("1 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + case 6: // 终点在x负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else // 半弧 + { + printf("2 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 3: // 终点在第三象限内 + if (mid == 2 || mid == 6 || mid == 7 || (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2])) // 逆时针方向 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (mid == 4 || mid == 5 || mid == 8 || (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2])) // 顺时针方向 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else + { + printf("3. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 4: // 终点在第四象限内 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("4. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + default: + break; + } + + break; + } + case 2: // 起点在第二象限内 + { + switch (end) + { + case 1: // 终点在第一象限内 + case 5: // 终点在x正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else // 半弧 + { + printf("5. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + case 6: // 终点在x负半轴上 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("6. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 3: // 终点在第三象限内 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("7. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 4: // 终点在第四象限内 + if (mid == 3 || mid == 6 || mid == 8 || (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2])) // 逆时针方向 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (mid == 1 || mid == 5 || mid == 7 || (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2])) // 顺时针方向 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else + { + printf("8. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + default: + break; + } + break; + } + case 3: // 起点在第三象限内 + { + switch (end) + { + case 1: // 终点在第一象限内 + if (mid == 4 || mid == 5 || mid == 8 || (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2])) // 逆时针方向 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (mid == 2 || mid == 6 || mid == 7 || (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2])) // 顺时针方向 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else + { + printf("9. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("10. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + case 3: // 终点在第三象限内 + case 6: // 终点在x负半轴上 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("11. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + case 4: // 终点在第四象限内 + case 5: // 终点在x正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("12. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + default: + break; + } + break; + } + case 4: // 起点在第四象限内 + { + switch (end) + { + case 1: // 终点在第一象限内 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("13. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + if (mid == 1 || mid == 5 || mid == 7 || (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2])) // 逆时针方向 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (mid == 3 || mid == 6 || mid == 8 || (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2])) // 顺时针方向 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else + { + printf("14. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 3: // 终点在第三象限内 + case 6: // 终点在x负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("15. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 4: // 终点在第四象限内 + case 5: // 终点在x正半轴上 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("16. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + default: + break; + } + break; + } + case 5: // 起点在在x正半轴上 + { + maxx = xc + r; + + switch (end) + { + case 1: // 终点在第一象限内 + case 4: // 终点在第四象限内 + if (k > 0) // 大半弧 + { + minx = xc - r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("17. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else // 半弧 + { + printf("18. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 3: // 终点在第三象限内 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("19. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 5: // 终点在x正半轴上 + printf("20. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + break; + + case 6: // 终点在x负半轴上 + minx = xc - r; + if (y[1] > yc) // 逆时针 + { + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (y[1] < yc) // 顺时针 + { + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else + { + printf("21. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + default: + break; + } + break; + } + case 6: // 起点在x负半轴上 + { + minx = xc - r; + + switch (end) + { + case 1: // 终点在第一象限内 + case 7: // 终点在y正半轴上 + if (k > 0) // 大半弧 + { + maxx = xc + r; + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else if (k < 0) // 小半弧 + { + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else // 半弧 + { + printf("22. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 2: // 终点在第二象限内 + case 3: // 终点在第三象限内 + if (k > 0) // 大半弧 + { + maxx = xc + r; + miny = yc - r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("23. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 4: // 终点在第四象限内 + case 8: // 终点在y负半轴上 + if (k > 0) // 大半弧 + { + maxx = xc + r; + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + maxx = MAX(x[0], x[2]); + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("24. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 5: // 终点在x正半轴上 + maxx = xc + r; + if (y[1] > yc) // 顺时针 + { + miny = MIN(y[0], y[2]); + maxy = yc + r; + } + else if (y[1] < yc) // 逆时针 + { + miny = yc - r; + maxy = MAX(y[0], y[2]); + } + else + { + printf("25. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 6: // 终点在x负半轴上 + printf("26. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + break; + + default: + break; + } + break; + } + + case 7: // 起点在y正半轴上 + { + maxy = yc + r; + + switch (end) + { + + case 1: // 终点在第一象限内 + case 2: // 终点在第二象限内 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + miny = yc - r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + } + else // 半弧 + { + printf("27. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 3: // 终点在第三象限内 + case 6: // 终点在x负半轴上 + if (k > 0) // 大半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = yc - r; + } + else if (k < 0) // 小半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = MIN(y[0], y[2]); + } + else // 半弧 + { + printf("28. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 4: // 终点在第四象限内 + case 5: // 终点在x正半轴上 + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + miny = yc - r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + miny = MIN(y[0], y[2]); + } + else // 半弧 + { + printf("29. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + + case 7: // 终点在y正半轴上 + printf("30. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + break; + + case 8: // 终点在y负半轴上 + miny = yc - r; + if (x[1] > xc) // 顺时针 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + } + else if (x[1] < xc) // 逆时针 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + } + else + { + printf("31. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + default: + break; + } + break; + } + case 8: // 起点在y负半轴上 + { + miny = yc - r; + switch (end) + { + case 1: // 终点在第一象限内 + case 5: // 终点在x正半轴上 + { + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("32. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + } + case 2: // 终点在第二象限内 + case 6: // 终点在x负半轴上 + { + if (k > 0) // 大半弧 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("33. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + } + case 3: // 终点在第三象限内 + case 4: // 终点在第四象限内 + { + if (k > 0) // 大半弧 + { + minx = xc - r; + maxx = xc + r; + maxy = yc + r; + } + else if (k < 0) // 小半弧 + { + minx = MIN(x[0], x[2]); + maxx = MAX(x[0], x[2]); + maxy = MAX(y[0], y[2]); + } + else // 半弧 + { + printf("34. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + } + case 7: // 终点在y正半轴上 + { + maxy = yc + r; + + if (x[1] > xc) // 逆时针 + { + minx = MIN(x[0], x[2]); + maxx = xc + r; + } + else if (x[1] < xc) // 顺时针 + { + minx = xc - r; + maxx = MAX(x[0], x[2]); + } + else + { + printf("35. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + } + break; + } + case 8: // 终点在y负半轴上 + { + printf("36. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end); // 不可能出现的情况 + break; + } + default: + break; + } + break; + } + + default: + break; + } + + if (minx < *pminx) + { + *pminx = minx; + } + + if (miny < *pminy) + { + *pminy = miny; + } + + if (maxx > *pmaxx) + { + *pmaxx = maxx; + } + + if (maxy > *pmaxy) + { + *pmaxy = maxy; + } + + // printf("minx=%.2f, maxx=%.2f, miny=%.2f, maxy=%.2f\n", minx, maxx, miny, maxy); + return 0; +} + +void rotatec(double xin, double yin, double * px, double * py, double angle) +{ + *px=xin*cos(angle)-yin*sin(angle); + *py=xin*sin(angle)+yin*cos(angle); +} + +int arcDir(const double x[], const double y[]) +{ + double k; + if(x[1] > x[0]) + { + k = (y[1] - y[0]) / (x[1]-x[0]); + if (y[2] < (k*(x[2]-x[1]) + y[1])) + { + return -1; + } + else + { + return 1; + } + } + else if (x[1] < x[0]) + { + k = (y[1] - y[0]) / (x[1] - x[0]); + if (y[2] < (k * (x[2]-x[1]) + y[1])) + { + return 1; + } + else + { + return -1; + } + } + else if ( (x[2]>x[1] && y[1] x[1] && y[1]>y[0]) || (x[2] y[1]) ) + { + return -1; + } + else + { + printf("1. what's this case?\n"); + return 0; + } +} + +Point2D pointOnCubicBezier(Point2D* cp, double t) +{ +#if(1) + double ax, bx, cx; double ay, by, cy; + double tSquared, tCubed; Point2D result; + + /* 计算多项式系数 */ + cx = 3.0 * (cp[1].x - cp[0].x); + bx = 3.0 * (cp[2].x - cp[1].x) - cx; + ax = cp[3].x - cp[0].x - cx - bx; + cy = 3.0 * (cp[1].y - cp[0].y); + by = 3.0 * (cp[2].y - cp[1].y) - cy; + ay = cp[3].y - cp[0].y - cy - by; + + /* 计算t位置的点值 */ + tSquared = t * t; + tCubed = tSquared * t; + result.x =((ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x); + result.y =((ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y); + return result; +#endif +} + +void computeBezier(Point2D* cp, long numberOfPoints, Point2D* curve) +{ + double dt; long i; + dt = 1.0 / ( numberOfPoints - 1 ); + for( i = 0; i < numberOfPoints; i++) + { + curve[i] = pointOnCubicBezier( cp, i*dt ); + } +} + +int getBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy) +{ + long k = 0; + double sx,sy; + long i = 0; + double minx, miny, maxx, maxy; + Point2D cp[4]; + + //传递参数 + for (i = 0; i <4;i++) + { + cp[i].x = x[i]; + cp[i].y = y[i]; + } + + //求控制点总长 + for (i = 0; i <3;i++) + { + sx = cp[i+1].x - cp[i].x; + sy = cp[i+1].y - cp[i].y ; + k += sqrt(sx*sx+sy*sy); //分割点数= 总长(精度为0.1mm) + } + if(k == 0) + { + return -1; + } + + if (k > 100) //对多100个点 + { + k = 100; + } + + Point2D curve[k]; + + computeBezier(cp, k, curve); //分割针步 + + minx = S32_MAX; + maxx = S32_MIN; + miny = S32_MAX; + maxy = S32_MIN; + + //判断始末点 + for (i = 0; i <4;i =i+3) + { + if (minx > cp[i].x) + { + minx = cp[i].x; + } + if (maxx < cp[i].x) + { + maxx = cp[i].x; + } + if (miny > cp[i].y) + { + miny = cp[i].y; + } + if (maxy < cp[i].y) + { + maxy = cp[i].y; + } + } + + for (i=0;i curve[i].x) + { + minx = curve[i].x; + } + if (maxx < curve[i].x) + { + maxx = curve[i].x; + } + if (miny > curve[i].y) + { + miny = curve[i].y; + } + if (maxy < curve[i].y) + { + maxy = curve[i].y; + } + } + + //printf("\n BSR minx = %f, maxx = %f, miny = %f, maxy = %f \n",minx,maxx,miny,maxy); + + if (minx < *pminx) + { + *pminx = minx; + } + + if (miny < *pminy) + { + *pminy = miny; + } + + if (maxx > *pmaxx) + { + *pmaxx = maxx; + } + + if (maxy > *pmaxy) + { + *pmaxy = maxy; + } + + return 0; +} + +int calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, WORD datatype) +{ + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + s32 dx, dy; + double length; + double tmp; + int count; + int i; + double stepx, stepy; + double sx, sy; + int actx, acty; + double k; + + if(x0 == x1 && y0 == y1) + { + return 0; + } + + if(x0 > x1) + { + sx = -1.0; // x反向 + } + else + { + sx = 1.0; + } + + if(y0 > y1) + { + sy = -1.0; // y反向 + } + else + { + sy = 1.0; + } + + if(datatype == QUI_TYPE_STEP || datatype == QUI_TYPE_HSTEP) // 跨步或翻头跨步 + { + absItem.ctrl = DATA_OFFSET; + } + else + { + absItem.ctrl = DATA_SEWING; // 其他 + } + + // 开始分割针步 + length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1)); + + tmp = length/step; /* 实际针步数 */ + count = floor(tmp); /* 最少整针步数 */ + + if (tmp - count > 0.01) + { + count += 1; + } + + if (count == 0 && length > 0) // 短直线 + { + count = 1; + } + + tmp = 0; + actx = x0; + acty = y0; + + if (x1 != x0 && y1 == y0) // 横直线 + { + for (i = 0; i < count; i++) + { + tmp = ((i+1)*(length)/count)*sx+x0; // 实际针步 + + stepx = tmp - actx; + dx = (s32)(stepx+0.5*sx); + dy = 0; + actx += dx; + + absItem.ax = tmp; + absItem.ay = y0; + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + } + } + else if (x1 == x0 && y1 != y0) // 竖直线 + { + for (i = 0; i < count; i++) + { + tmp = ((i+1)*(length)/count)*sy + y0; // 实际针步 + + stepy = tmp - acty; + + dx = 0; + dy = (s32)(stepy+0.5*sy); + acty += dy; + + absItem.ax = x0; + absItem.ay = tmp; + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + } + } + else if(x1 != x0 && y1 != y0) // 任意斜线 + { + k = (y1-y0)/(x1-x0); + for (i = 0; i < count; i++) + { + tmp = ((i+1)*(length)/count); + + stepx = fabs(tmp*cos(atan(k)))*sx + x0; // 实际针步x + stepy = fabs(tmp*sin(atan(k)))*sy + y0; // 实际针步y + + dx = (s32)(stepx-actx+0.5*sx); + dy = (s32)(stepy-acty+0.5*sy); + + actx += dx; + acty += dy; + + absItem.ax = stepx; + absItem.ay = stepy; + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + } + } + else + { + printf("what's this?\n"); + } + + return count; +} + +int calcCurve(double threex[], double threey[], s16 step, QByteArray &absAry) +{ + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + BYTE dx, dy; + int count = 0; + int i; + s32 ar = 0; + + double distance, k; + double alph; + double increment; + double xc=0,yc=0,r=0; + int actx, acty; + int ddx, ddy; + + i = isThreePointOnALine(threex, threey); + if(i == 1) // 3点共线 + { + return calcLine(threex[0], threey[0], threex[2], threey[2], step, absAry, QUI_TYPE_LINE); // 作为直线 + } + else if (i == 2) + { + return calcLine(threex[0], threey[0], threex[1], threey[1], step, absAry, QUI_TYPE_LINE); // 作为直线 + } + + getArcCenter(threex, threey, &xc, &yc, &r); + + // printf("center=%.2f,%.2f,r=%.2f\n", xc, yc, r); + + // 计算弦长和圆心角 + distance = sqrt((threex[0]-threex[2])*(threex[0]-threex[2])+(threey[0]-threey[2])*(threey[0]-threey[2])); // 两点间距离就是弦长 + k = (r*r+r*r-distance*distance)/(r*r+r*r); + if (k < -1) + { + k = -1; + } + else if (k > 1) + { + k = 1; + } + + // printf("distance=%f, k=%f\n", distance, k); + + alph = acos(k); + + // 区分象限和方向 + k = (threex[0]-threex[1])*(threex[2]-threex[1]) + (threey[0]-threey[1])*(threey[2]-threey[1]); // 向量 01 和 向量 21 的夹角的余弦的符号-- > 0 小于90度. < 0 大于90度 = 0, 90 度 + if (k > 0) // 夹角小于90度, 说明弧是大于半圆 + { + alph = 2*PI-alph; + } + else // 夹角大于等于90度, 说明弧是小于等于半圆, 不需要处理 + { + } + + // printf("act alph=%f\n", alph); + + // 计算每个针步对应的弧心角大小 + if (fabs(2*r*r-step*step)/(2*r*r) > 1) + { + increment = alph; + } + else + { + increment = (acos((2*r*r-step*step)/(r*r+r*r))); + } + + // 计算分割针步数 + count = (int)(alph/increment+0.5); + if (count == 0) + { + count++; + } + + // printf("1.count=%d, increment=%f\n", count, increment); + + increment = alph/count; // 重新计算每个针步弧心角 + + increment *= arcDir(threex, threey); // 确定针步增加的角度和方向 + + // printf("2.count=%d, increment=%f\n", count, increment); + + double curx, cury, lastx, lasty; + double xrot, yrot; + + lastx = threex[0]; + lasty = threey[0]; + + i = 0; + + actx = (int)(lastx); + acty = (int)(lasty); + + do + { + if (i == count-1) + { + // 最后一个针步 + // printf("the last step\n"); + curx = threex[2]; + cury = threey[2]; + } + else + { + // 点 (lastx, lasty) 在圆上旋转 + // printf("before Rotatec point(%f, %f)\n", lastx, lasty); + + rotatec(lastx-xc, lasty-yc, &xrot, &yrot, increment); + curx = xrot + xc; + cury = yrot + yc; + } + + ddx = curx-actx; + ddy = cury-acty; + + dx = (s16)(curx-actx+(0.5*(ddx>=0?1:-1))); + dy = (s16)(cury-acty+(0.5*(ddy>=0?1:-1))); + + absItem.ctrl = DATA_SEWING; + absItem.ax = curx; + absItem.ay = cury; + + double tar = atan2(dy,dx); + ar = (tar * 10000+0.5*(tar>0?1:-1)); + absItem.ar = ar; + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + + lastx = curx; + lasty = cury; + + actx += dx; + acty += dy; + i++; + + } while(i < count); + + return count; +} + +#define YUFENGE 20 //预分割步数 +#define YUFENGE_BEGIN (YUFENGE*7/10) //扫描起点 + +int calcBezier(double threex[], double threey[], s16 step, QByteArray &absAry) +{ + DsAbsItem absItem; + memset(&absItem,0,sizeof(DsAbsItem)); + + int dx, dy; + long k = 0; + double sx,sy; + long i , l; + Point2D cp[4]; + int count = 0; + double curx, cury, lastx, lasty; + int actx, acty; + int ddx, ddy; + s32 ar = 0; + + //传递参数 + for (i = 0; i <4;i++) + { + cp[i].x = threex[i]; + cp[i].y = threey[i]; + } + + //求控制点总长 + for (i = 0; i <3;i++) + { + sx = cp[i+1].x - cp[i].x; + sy = cp[i+1].y - cp[i].y ; + k += sqrt(sx*sx+sy*sy); //分割点数= 总长(精度为0.1mm) + } + + k = (long)((k / step)+1) * YUFENGE; //预分割针步数,设置针步数*YUFENGE. + Point2D curve[k]; + + double dt; + dt = 1.0 / ( k - 1 ); //分割分辨率 + + lastx = cp[0].x; + lasty = cp[0].y; + + for (i = YUFENGE_BEGIN ;i < k ; ) + { + curve[i] = pointOnCubicBezier(cp, i*dt); + sx = curve[i].x - lastx; + sy = curve[i].y - lasty; + l = sqrt(sx*sx+sy*sy); //拟合针步长度 + + if(i == k-1) + { + //最后一针 + actx = (int)(lastx); + acty = (int)(lasty); + curx = (int)(cp[3].x); + cury = (int)(cp[3].y); + + ddx = curx-actx; + ddy = cury-acty; + + dx = (int)(abs(ddx)+0.5); + dy = (int)(abs(ddy)+0.5); + + lastx = curx; + lasty = cury; + + absItem.ctrl = DATA_SEWING; + absItem.ax = curx; + absItem.ay = cury; + + double tar = atan2(dy,dx); + ar = (tar * 10000+0.5*(tar>0?1:-1)); + absItem.ar = ar; + + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + + count++; + break; + } + else if(l >= (step-1)) + { + actx = (int)(lastx); + acty = (int)(lasty); + curx = (int)(curve[i].x); + cury = (int)(curve[i].y); + + ddx = curx-actx; + ddy = cury-acty; + + dx = (int)(abs(ddx)+0.5); + dy = (int)(abs(ddy)+0.5); + + lastx = curx; + lasty = cury; + count++; + + if ((i + YUFENGE_BEGIN) >= k-1) + { + i = k-1; + } + else + { + i=i+YUFENGE_BEGIN; + } + + absItem.ctrl = DATA_SEWING; + absItem.ax = curx; + absItem.ay = cury; + + double tar = atan2(dy,dx); + ar = (tar * 10000+0.5*(tar>0?1:-1)); + absItem.ar = ar; + + absAry.append((char*)&absItem,sizeof(DsAbsItem)); + } + else + { + i++; + } + } + + return count; +} + +void getSplineNew(QList &ptList, QList &splineList) +{ + //读取样条线拟合控制点 + QPointF pSuPoint; + int i = 0; + int iCountPoint = ptList.size(); + + //绘制二次累加弦长曲线 + QPointF pPoint[iCountPoint]; + double dfMinX, dfMinY; + + dfMinX = dfMinY= 0; + + while (i < iCountPoint) + { + pSuPoint = ptList.at(i); + + pPoint[i].setX(pSuPoint.x()); + pPoint[i].setY(pSuPoint.y()); + if (i == 0) + { + dfMinX = pPoint[i].x(); + dfMinY = pPoint[i].y(); + } + else + { + if (dfMinX > pPoint[i].x()) + dfMinX = pPoint[i].x(); + + if (dfMinY > pPoint[i].y()) + dfMinY = pPoint[i].y(); + } + i++; + } + + for (i = 0; i < iCountPoint; i++) + { + double x = pPoint[i].x() - dfMinX; + double y = pPoint[i].y() - dfMinY; + pPoint[i].setX(x); + pPoint[i].setY(y); + } + + getShap(iCountPoint, pPoint, splineList, dfMinX, dfMinY); +} + +void getShap(int nCtrlPntNum, QPointF *pPoint, QList &splineList, double dfMinX, double dfMinY) +{ + int i,j,k,stp,leg, m = nCtrlPntNum-1; + double t0,t1,r0,r1, *o, *p, *q; + QPointF *u, *v; + + o = new double [nCtrlPntNum + 1]; + p = new double [nCtrlPntNum + 1]; + q = new double [nCtrlPntNum + 1]; + u = new QPointF [nCtrlPntNum + 1]; + v = new QPointF [nCtrlPntNum + 1]; + + do // 计算弦长 + { + j = 0; + for (i = 1; i<= m; i++) + { + t0 = pPoint[i].x() - pPoint[i-1].x(); + t1 = pPoint[i].y() - pPoint[i-1].y(); + o[i] = sqrt(t0 * t0 + t1 * t1); + if (o[i] < 2) + { + j = i; + break; + } + } + + if (j > 0) + { + for (i = j; i <= m; i++) + { + pPoint[i].setX(pPoint[i+1].x()); + pPoint[i].setY(pPoint[i+1].y()); + } + m--; + } + } while (j!=0); + + t0 = o[1] + o[2]; + t1 = 2*o[1] * o[2]; // 边界条件 m[o] 和 m[N] 的构造 + + u[0].setX((t0 * t0 * pPoint[1].x() - o[2] * o[2] * pPoint[0].x() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].x()); + u[0].setY((t0 * t0 * pPoint[1].y() - o[2] * o[2] * pPoint[0].y() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].y()); + t0 = sqrt(u[0].x() * u[0].x() + u[0].y() * u[0].y()); + + u[0].setX(u[0].x() / t0); + u[0].setY(u[0].y() / t0); + t0 = o[m-1] + o[m]; + t1 = 2*o[m-1] * o[m]; + + r0 = (t0 * t0 * pPoint[m-1].x() - o[m] * o[m] * pPoint[m-2].x() - o[m-1] * o[m-1] * pPoint[m].x()) / t1; + r1 = (t0 * t0 * pPoint[m-1].y() - o[m] * o[m] * pPoint[m-2].y() - o[m-1] * o[m-1] * pPoint[m].y()) / t1; + u[m].setX(pPoint[m].x() - r0); + u[m].setY(pPoint[m].y() - r1); + t0 = sqrt(u[m].x() * u[m].x() + u[m].y() * u[m].y()); + u[m].setX(u[m].x() / t0); + u[m].setY(u[m].y() / t0); + + //计算 m 连续方程系数 C[i] + p[1] = o[2] / (o[1] + o[2]); + q[1] = 3; + t0 = p[1] * (pPoint[1].x() - pPoint[0].x()) / o[1]; + t1 = p[1] * (pPoint[1].y() - pPoint[0].y()) / o[1]; + v[1].setX(4 * (t0 + (1-p[1]) * (pPoint[2].x() - pPoint[1].x()) / o[1+1])); + v[1].setY(4 * (t1 + (1-p[1]) * (pPoint[2].y() - pPoint[1].y()) / o[1+1])); + + for (i=2; i<= (m-1); i++) + { + p[i] = o[i+1] / (o[i]+o[i+1]); + q[i] = 3 - p[i] * (1 - p[i-1]) / q[i-1]; + + t0 = p[i] * (pPoint[i].x() - pPoint[i-1].x()) / o[i]; + t1 = p[i] * (pPoint[i].y() - pPoint[i-1].y()) / o[i]; + + v[i].setX(4 * (t0 + (1 - p[i]) * (pPoint[i+1].x() - pPoint[i].x()) / o[i+1])); + v[i].setY(4 * (t1 + (1 - p[i]) * (pPoint[i+1].y() - pPoint[i].y()) / o[i+1])); + } + + v[1].setX(v[1].x() - p[1] * u[0].x()); + v[1].setY(v[1].y() - p[1] * u[0].y()); + v[m-1].setX(v[m-1].x() - (1 - p[m-1]) * u[m].x()); + v[m-1].setY(v[m-1].y() - (1 - p[m-1]) * u[m].y()); + + // 求解 m 连续方程, 获得 m[i] + u[1].setX(v[1].x() / q[1]); + u[1].setY(v[1].y() / q[1]); + + for (i = 2; i <= m-1; i++) + { + u[i].setX((v[i].x() - p[i] * u[i-1].x()) / q[i]); + u[i].setY((v[i].y() - p[i] * u[i-1].y()) / q[i]); + } + + for (i = m-2; i >= 1; i--) + { + u[i].setX(u[i].x() - u[i+1].x() * (1 - p[i]) / q[i]); + u[i].setY(u[i].y() - u[i+1].y() * (1 - p[i]) / q[i]); + } + + // 求得 M[j] j=0,1,...,N + v[0].setX(4 * (pPoint[1].x() - pPoint[0].x()) / (o[1] * o[1]) - (3 * u[0].x() + u[1].x()) / o[1]); + v[0].setY(4 * (pPoint[1].y() - pPoint[0].y()) / (o[1] * o[1]) - (3 * u[0].y() + u[1].y()) / o[1]); + q[0]=0; + + for (i=1; i<= m; i++) + { + q[i] = 0; + t0 = o[i] * o[i]; + v[i].setX(-4 * (pPoint[i].x() - pPoint[i-1].x()) / t0 + (3 * u[i].x() + u[i-1].x()) / o[i]); + v[i].setY(-4 * (pPoint[i].y() - pPoint[i-1].y()) / t0 + (3 * u[i].y() + u[i-1].y()) / o[i]); + for (j=1; j<= i; j++) + q[i] = q[i] + o[j]; + } + + // o[j] j=0,1,...,N 表示半节点 + o[0] = q[0]; + o[m+1] = q[m]; + + for (i = 1; i<= m; i++) + o[i] = (q[i-1] + q[i]) / 2; + + // 显示或绘之曲线 + QPointF suPoint; + suPoint.setX(pPoint[0].x() + dfMinX); + suPoint.setY(pPoint[0].y() + dfMinY); + splineList.append(suPoint); + // pDC->MoveTo(lx1,ly1); + + for (i = 0; i< m; i++) + { + leg = (int)(o[i+1] - o[i]); + stp = leg / 10; + + if (leg> 600) + stp = leg / 60; + + if (leg> 900) + stp = leg / 80; + + if (leg>1200) + stp = leg / 100; + + if (leg > 2400) + stp = leg / 120; + + if (leg>4800) + stp = leg / 140; + + if (stp) + k = leg/stp; + else + k = 0; + + for (j = 0; j<= k; j++) + { + r0 = o[i] + stp * j - q[i]; + suPoint.setX(pPoint[i].x() + r0 * (u[i].x() + v[i].x() / 2 * r0) + dfMinX); + suPoint.setY(pPoint[i].y() + r0 * (u[i].y() + v[i].y() / 2 * r0) + dfMinY); + splineList.append(suPoint); + //pDC->LineTo(lx1,ly1); + } + } + + suPoint.setX(pPoint[m].x() + dfMinX); + suPoint.setY(pPoint[m].y() + dfMinY); + splineList.append(suPoint); + //pDC->LineTo(lx1,ly1); + + delete o; + delete p; + delete q; + delete u; + delete v; +} + +void getCurvePointFillLine(QList &inList, double indRunLen, QList &outList, int iSumParm, BYTE biLenLimit) +{ + QPointF dPoint1, dPoint2, dPoint3; + double dTatol, dLen1, dLen2, dSpace; + long lSum, lCount; + + //计算总的线段长 + int iCountPoint = inList.size(); + if(iCountPoint <= 0) + { + return; + } + + getTotalDistanceFillLine(&inList, dTatol); + if(dTatol == 0) + return; + + if (biLenLimit == ADJUSTLINE_ADD_DUAN_LIMIT) + { + lSum = iSumParm; + if (lSum < 1) + lSum = 1; + dSpace = dTatol / lSum; + } + else if (iSumParm > 2) + { + lSum = iSumParm; + dSpace = dTatol / (double)lSum; + } + else + { + if (biLenLimit == OBJECT_STITCHLEN_NEW_BIG) + { + lSum = int(dTatol / indRunLen); + dSpace = dTatol / lSum; + + if(lSum == 0) + lSum = 1; + } + else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAMALL) + { + lSum = doubleToLong(dTatol / indRunLen + 0.1667); + dSpace = dTatol / (double)lSum; + if(lSum == 0) + lSum = 1; + } + else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAME) + { + lSum = int(dTatol / indRunLen); + dSpace = indRunLen; + if(lSum == 0) + lSum = 1; + } + else if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT || + biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END) + { + lSum = int(dTatol / indRunLen); + dSpace = indRunLen; + } + else if (biLenLimit == LINEDUAN_NUM_LIMIT) + { + lSum = int(dTatol / indRunLen); + dSpace = dTatol / (double)lSum; + } + else + { + if (biLenLimit) + { + lSum = int(dTatol / indRunLen); + if (lSum < 1) + lSum = doubleToLong(dTatol / indRunLen + 0.1667); + } + else + lSum = doubleToLong(dTatol / indRunLen + 0.1667); + + if(lSum == 0) + lSum = 1; + + dSpace = dTatol / (double)lSum; + } + } + + dPoint1 = inList[0]; + outList.append(dPoint1);//添加第一个点 + + pointToPoint(dPoint1, dPoint2); + dLen1 = dSpace; + dLen2 = 0; + int i = 0; + for(lCount = 0; lCount < lSum; lCount++) + { + while(i < inList.size()-1 && dLen2 < dLen1) + { + dLen1 -= dLen2; + pointToPoint(dPoint2, dPoint1); + i++; + dPoint2 = inList[i]; + distPointToPoint(dPoint1, dPoint2, dLen2); + } + if(dLen1 < dLen2) + { + getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3); + } + else + { + dPoint3.setX(dPoint2.x()); + dPoint3.setY(dPoint2.y()); + } + outList.append(dPoint3); + dLen2 -= dLen1; + dLen1 = dSpace; + pointToPoint(dPoint3, dPoint1); + } + + if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END || + biLenLimit == OBJECT_STITCHLEN_NEW_SAME) + { + if (fabs((lSum * indRunLen) - dTatol) > ZERO) + { + outList.append(inList.last()); + } + } +} + +int getTotalDistanceFillLine(QList *pPointList, double &dTotal) +{ + QPointF dPoint, dNext; + double d; + dTotal = 0; + int i = 0; + long lSum = (long)pPointList->count(); + if(lSum > 1) + { + while(i < pPointList->size()) + { + dPoint = pPointList->at(i); + i++; + if(i < pPointList->size()) + { + dNext = pPointList->at(i); + distPointToPoint(dPoint, dNext, d); + dTotal += d; + } + else + { + break; + } + } + } + return ERROR_NOTHING; +} + +void pointToPoint(const QPointF &inPoint, QPointF &outPoint) +{ + outPoint.setX(inPoint.x()); + outPoint.setY(inPoint.y()); +} + +long doubleToLong(double indValue) +{ + return (long)round(indValue); +} + +double round(double indValue) +{ + return floor(indValue + 0.5); +} + +void distPointToPoint(const QPointF &p1, const QPointF &p2, double &outd) +{ + outd = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y()); +} + +bool getPointInSectFillLine(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp) +{ + bool bRes; + QPointF dpoint[3]; + + dpoint[0].setX(p1.x()); + dpoint[0].setY(p1.y()); + dpoint[1].setX(p2.x()); + dpoint[1].setY(p2.y()); + dpoint[2].setX(outp.x()); + dpoint[2].setY(outp.y()); + + bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]); + outp.setX(dpoint[2].x()); + outp.setY(dpoint[2].y()); + + return bRes; +} + +bool getPointAtSect(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp) +{ + double s = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y()); + if(fabs(s) < ZERO) + { + if(d < ZERO) + { + outp.setX(p1.x()); + outp.setY(p1.y()); + } + return false; + } + outp.setX((p2.x() - p1.x()) * d / s + p1.x()); + outp.setY((p2.y() - p1.y()) * d / s + p1.y()); + + return true; +} + +double disPointToPoint(double x1, double y1, double x2, double y2) +{ + return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); +} + +void getBezierPointList(double threex[], double threey[], s16 step, QList &outList) +{ + long k = 0; + double sx,sy; + Point2D cp[4]; + + //传递参数 + for (s16 i = 0; i < 4; i++) + { + cp[i].x = threex[i]; + cp[i].y = threey[i]; + } + + //求控制点总长 + for (s16 i = 0; i < 3; i++) + { + sx = cp[i+1].x - cp[i].x; + sy = cp[i+1].y - cp[i].y ; + k += sqrt(sx*sx+sy*sy); //分割点数= 总长(精度为0.1mm) + } + + k = (long)((k / step)+1) * YUFENGE; //分割针步数 + Point2D curve; + + double dt; + dt = 1.0 / ( k - 1 ); //分割分辨率 + + QPointF p; + for (int i = 0; i < k; i++) + { + curve = pointOnCubicBezier(cp, i*dt); + p.setX(curve.x); + p.setY(curve.y); + outList.append(p); + } +} + +int getSplineMinMax(QList &ptList, double *pminx, double *pmaxx, double *pminy, double *pmaxy) +{ + QList splineListXY;//拟合后的点 + splineListXY.clear(); + + double minx, miny, maxx, maxy; + minx = S32_MAX; + maxx = S32_MIN; + miny = S32_MAX; + maxy = S32_MIN; + + //读取样条线拟合控制点 + QPointF pSuPoint; + int i = 0; + int iCountPoint = ptList.size(); + + //绘制二次累加弦长曲线 + QPointF pPoint[iCountPoint]; + double dfMinX, dfMinY; + + dfMinX = dfMinY= 0; + + while (i < iCountPoint) + { + pSuPoint = ptList.at(i); + + pPoint[i].setX(pSuPoint.x()); + pPoint[i].setY(pSuPoint.y()); + if (i == 0) + { + dfMinX = pPoint[i].x(); + dfMinY = pPoint[i].y(); + } + else + { + if (dfMinX > pPoint[i].x()) + dfMinX = pPoint[i].x(); + + if (dfMinY > pPoint[i].y()) + dfMinY = pPoint[i].y(); + } + i++; + } + + for (i = 0; i < iCountPoint; i++) + { + double x = pPoint[i].x() - dfMinX; + double y = pPoint[i].y() - dfMinY; + pPoint[i].setX(x); + pPoint[i].setY(y); + } + + getShap(iCountPoint, pPoint, splineListXY, dfMinX, dfMinY); + + for (i=0;i splineListXY[i].x()) + { + minx = splineListXY[i].x(); + } + if (maxx < splineListXY[i].x()) + { + maxx = splineListXY[i].x(); + } + if (miny > splineListXY[i].y()) + { + miny = splineListXY[i].y(); + } + if (maxy < splineListXY[i].y()) + { + maxy = splineListXY[i].y(); + } + } + + if (minx < *pminx) + { + *pminx = minx; + } + + if (miny < *pminy) + { + *pminy = miny; + } + + if (maxx > *pmaxx) + { + *pmaxx = maxx; + } + + if (maxy > *pmaxy) + { + *pmaxy = maxy; + } + + return 0; +} diff --git a/datafile/dataoperat.h b/datafile/dataoperat.h new file mode 100644 index 0000000..5a75e03 --- /dev/null +++ b/datafile/dataoperat.h @@ -0,0 +1,83 @@ +#ifndef DATAOPERAT_H +#define DATAOPERAT_H + +#include "machine/comm/datadef.h" +#include +#include +#include +#include +#include +#include + +#define QUI_TYPE_LINE 1 //直线 +#define QUI_TYPE_STEP 4 //跨步 +#define QUI_TYPE_HSTEP 5 //翻头跨步 +#define QUI_TYPE_ARC 2 //三点圆弧 +#define QUI_TYPE_BES 6 //贝塞尔曲线 +#define QUI_TYPE_SPLINE 7 //样条曲线 + +#define ERROR_NOTHING 0 //成功 +#define ZERO 1e-6 + +#define LINEDUAN_NUM_LIMIT 5 // 计算分段数固定:不进行特殊计算 +#define LINEDUAN_STITCHLEN_LIMIT 6 // 针迹步长固定 +#define LINEDUAN_STITCHLEN_LIMIT_END 7 // 针迹步长固定(最后线段) + +#define OBJECT_STITCHLEN_NEW_BIG 8 // 固定针迹长度(大等分) +#define OBJECT_STITCHLEN_NEW_SAME 9 // 固定针迹长度(等距分) +#define OBJECT_STITCHLEN_NEW_SAMALL 10 // 固定针迹长度(小等分) +#define ADJUSTLINE_ADD_DUAN_LIMIT 11 // 自动单针指定分段添加 + +typedef struct +{ + double x; + double y; +} Point2D; + +typedef struct +{ + double x; + double y; + int ctrl; +} QuiPoint; + +int isThreePointOnALine(const double threex[],const double threey[]); +int getArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr); +int getArcMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy); +void rotatec(double xin, double yin, double * px, double * py, double angle); +int arcDir(const double x[], const double y[]); + +Point2D pointOnCubicBezier(Point2D* cp, double t); +void computeBezier(Point2D* cp, long numberOfPoints, Point2D* curve); +int getBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy); +int getSplineMinMax(QList &ptList, double * pminx, double * pmaxx, double * pminy, double * pmaxy); + +int calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, WORD datatype); +int calcCurve(double threex[], double threey[], s16 step, QByteArray &absAry); +int calcBezier(double threex[], double threey[], s16 step, QByteArray &absAry); +void getBezierPointList(double threex[], double threey[], s16 step, QList &outList); + +//样条拟合 +void getSplineNew(QList &ptList, QList &splineList); +void getShap(int nCtrlPntNum, QPointF *pPoint, QList &splineList, double dfMinX, double dfMinY); +//线段拟合 +void getCurvePointFillLine(QList &inList, double indRunLen, + QList &outList, int iSumParm, BYTE biLenLimit); +int getTotalDistanceFillLine(QList *pPointList, double &dTotal); +void pointToPoint(const QPointF &inPoint, QPointF &outPoint); +long doubleToLong(double indValue);//浮点数转整形 +double round(double indValue);//四舍五入 +void distPointToPoint(const QPointF &p1, const QPointF &p2, double &outd); +bool getPointInSectFillLine(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp); + +//距p1点距离为d的点 +// d > s : out_p在p2延长线上 +// s >= d >= 0 : out_p在p1、p2线段上 +// d < 0 : out_p在p1延长线上 +bool getPointAtSect(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp); + +// 两点间距离 +double disPointToPoint(double x1, double y1, double x2, double y2); + + +#endif // DATAOPERAT_H diff --git a/datafile/dsrcryption.cpp b/datafile/dsrcryption.cpp new file mode 100644 index 0000000..229c7d8 --- /dev/null +++ b/datafile/dsrcryption.cpp @@ -0,0 +1,319 @@ +#include "dsrcryption.h" +#include +#include + +DsrCryption::DsrCryption() +{ + m_initflag = 0; + m_cryword = 0; + memset(m_factors, 0, BYTES_OF_CRY_FACTORS); +} + +// 初始化加密控制, 生成加密字和加密因子 +int DsrCryption::InitDsrCryptionCtrl(int version, unsigned int cryword, const unsigned char * factors) +{ + int rslt = 0; + + m_initflag = 0; + m_cryword = 0; + memset(m_factors, 0, BYTES_OF_CRY_FACTORS); + + if (version >= 0) + { + rslt = CreateCryWord(version); + } + else + { + m_cryword = cryword; + } + + if (rslt == 0) + { + rslt = CreateCryFactors(factors); + } + + if (rslt == 0) + { + m_initflag++; + } + + return rslt; +} + +// 获取加密字 +unsigned int DsrCryption::GetDsrCryptionWord() +{ + return m_cryword; +} + +// 加密数据 +int DsrCryption::EnCryption(unsigned char * pData, int size) +{ + if (pData == NULL || size <= 0) + { + return -1; + } + + unsigned char thisfactors[BYTES_OF_CRY_FACTORS]; + unsigned char tempbuff[BYTES_OF_CRY_FACTORS]; + + memcpy(thisfactors, m_factors, BYTES_OF_CRY_FACTORS); // 拷贝临时的加密因子,做计算用 + + int i, j; + for (i = 0; i < size; i += BYTES_OF_CRY_FACTORS) + { + // 拷贝数据到临时buff + int mv = 0; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + if (i+j < size) + { + tempbuff[j] = pData[i+j]; // 拷贝数据 + } + else + { + tempbuff[j] = 0; + } + + mv += thisfactors[j]; // 累加因子,作为移动因子 + } + + // 移动数据 + if (i + BYTES_OF_CRY_FACTORS < size) + { + // 生成移动索引 + unsigned char mvidx[BYTES_OF_CRY_FACTORS]; + int idx, setdidx = BYTES_OF_CRY_FACTORS-1; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + idx = (mv >> j) & 0x1f; + for (int k = 0; k < j; k++) + { + if (mvidx[k] == idx) + { + idx = setdidx; + do + { + int kk; + for (kk = 0; kk < j; kk++) + { + if (mvidx[kk] == idx) + { + break; + } + } + if (kk < j) + { + idx--; + } + else + { + setdidx = idx-1; + break; + } + } while(1); + break; + } + } + mvidx[j] = idx; + } + + // 移动数据 + unsigned char tempdat[BYTES_OF_CRY_FACTORS]; + memcpy(tempdat, tempbuff, BYTES_OF_CRY_FACTORS); + + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + tempbuff[j] = tempdat[mvidx[j]]; + } + } + + // 数据加密 + for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++) + { + tempbuff[j] ^= thisfactors[j]; // 异或加密 + pData[i+j] = tempbuff[j]; // 保存 + } + + // 下次的变幻因子 + int temp = 0; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + temp += thisfactors[j]; + temp *= 3; + temp += 1; + temp /= 2; + thisfactors[j] = temp; + } + } + + return 0; +} + +// 解密数据 +int DsrCryption::DeCryption(unsigned char * pData, int size) +{ + if (pData == NULL || size <= 0) + { + return -1; + } + + if (pData == NULL || size <= 0) + { + return -1; + } + + unsigned char thisfactors[BYTES_OF_CRY_FACTORS]; + unsigned char tempbuff[BYTES_OF_CRY_FACTORS]; + + memcpy(thisfactors, m_factors, BYTES_OF_CRY_FACTORS); + + int i, j; + for (i = 0; i < size; i += BYTES_OF_CRY_FACTORS) + { + // 拷贝数据到临时buff + int mv = 0; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + if (i+j < size) + { + tempbuff[j] = pData[i+j]; // 拷贝数据 + } + else + { + tempbuff[j] = 0; + } + + mv += thisfactors[j]; // 累加因子,作为移动因子 + } + + // 数据解密 + for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++) + { + tempbuff[j] ^= thisfactors[j]; + } + + // 数据移动回去 + if (i + BYTES_OF_CRY_FACTORS < size) + { + // 生成移动索引 + unsigned char mvidx[BYTES_OF_CRY_FACTORS]; + int idx, setdidx = BYTES_OF_CRY_FACTORS-1; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + idx = (mv >> j) & 0x1f; + for (int k = 0; k < j; k++) + { + if (mvidx[k] == idx) + { + idx = setdidx; + do + { + int kk; + for (kk = 0; kk < j; kk++) + { + if (mvidx[kk] == idx) + { + break; + } + } + if (kk < j) + { + idx--; + } + else + { + setdidx = idx-1; + break; + } + } while(1); + break; + } + } + mvidx[j] = idx; + } + + // 移动数据 + unsigned char tempdat[BYTES_OF_CRY_FACTORS]; + memcpy(tempdat, tempbuff, BYTES_OF_CRY_FACTORS); + + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + tempbuff[mvidx[j]] = tempdat[j]; + } + } + + // 保存解密数据 + for (j = 0; i+j < size && j < BYTES_OF_CRY_FACTORS; j++) + { + pData[i+j] = tempbuff[j]; // 保存 + } + + // 下次的变幻因子 + int temp = 0; + for (j = 0; j < BYTES_OF_CRY_FACTORS; j++) + { + temp += thisfactors[j]; + temp *= 3; + temp += 1; + temp /= 2; + thisfactors[j] = temp; + } + } + + return 0; +} + +// 生成加密字 +int DsrCryption::CreateCryWord(int version) +{ + if (version < 0 || version > 250) + { + return -1; + } + + int rdw; + if (version == 0) + { + rdw = 0; + } + else + { + QTime time= QTime::currentTime(); + qsrand(time.msec()+time.second()*1000); + rdw = qrand(); // 产生随机数 + } + + m_cryword = rdw & 0xffffff; + m_cryword *= 251; + m_cryword += version; + + return 0; +} + +// 生成加密因子 +int DsrCryption::CreateCryFactors(const unsigned char * factors) +{ + if (factors == NULL) + { + return -1; + } + memcpy(m_factors, factors, BYTES_OF_CRY_FACTORS); + + int * pDat = (int*)m_factors; + + // 变幻加密因子,兼容非加密情况 + for (int i = 0; i < BYTES_OF_CRY_FACTORS; i+=sizeof(int)) + { + *pDat *= m_cryword; + pDat++; + } + return 0; +} + + + + + + + diff --git a/datafile/dsrcryption.h b/datafile/dsrcryption.h new file mode 100644 index 0000000..cc970f7 --- /dev/null +++ b/datafile/dsrcryption.h @@ -0,0 +1,33 @@ +#ifndef DSRCRYPTION_H +#define DSRCRYPTION_H + +#define CRY_VERSION1 0x01 +#define CRY_VERSION2 0x02 + +#define CUR_CRY_VERSION 0x01 // 当前的加密版本(取值范围为 0 -- 250),方便通过版本使用不同的加密方法。 +#define BYTES_OF_CRY_FACTORS 32 // 加密因子字节数 + + +class DsrCryption +{ +public: + DsrCryption(); + +public: + int InitDsrCryptionCtrl(int version, unsigned int cryword, const unsigned char * factors); // 初始化加密控制, 自动生成生成加密字和加密因子 + unsigned int GetDsrCryptionWord(); // 获取加密字 + + int EnCryption(unsigned char * pData, int size); // 加密数据,使用当前的加密字和加密因子 + int DeCryption(unsigned char * pData, int size); // 解密数据,使用当前的加密字和加密因子 + +private: + int CreateCryWord(int version); // 生成加密字 + int CreateCryFactors(const unsigned char * factors); // 生成加密因子 + +private: + int m_initflag; + unsigned int m_cryword; + unsigned char m_factors[BYTES_OF_CRY_FACTORS]; +}; + +#endif // DSRCRYPTION_H diff --git a/datafile/dxf/dxfhelper.cpp b/datafile/dxf/dxfhelper.cpp new file mode 100644 index 0000000..b2000fc --- /dev/null +++ b/datafile/dxf/dxfhelper.cpp @@ -0,0 +1,520 @@ +#include "dxfhelper.h" +#include "dxfreader.h" + +#include +#include + +DxfHelper::DxfHelper() +{ + +} + +double norm(double x, double y) +{ + return sqrt(x * x + y * y); +} + +QList DxfHelper::expandPolygon(QList polygon, float expand) +{ + QList new_polygon; + int len = polygon.length(); + if(len<3||qFuzzyIsNull(expand)) return polygon; + + bool repeatFlag = false; + if(polygon.first()==polygon.back()) { + repeatFlag = true; + polygon.removeLast(); + len = polygon.length(); + } + + int convertNum = 0; + for (int i = 0; i < len; i++) + { + QVector3D p = polygon[i]; + QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1]; + QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1]; + float v1x = p1.x() - p.x(); + float v1y = p1.y() - p.y(); + float n1 = norm(v1x, v1y); + float vv1x = v1x / n1; + float vv1y = v1y / n1; + float v2x = p2.x() - p.x(); + float v2y = p2.y() - p.y(); + float n2 = norm(v2x, v2y); + float vv2x = v2x / n2; + float vv2y = v2y / n2; + float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f); + float judge = v1x * v2y - v2x * v1y; + if (judge < 0) vectorLen *= -1; + if (judge < 0) convertNum++; + float vx = vv1x + vv2x; + float vy = vv1y + vv2y; + vectorLen = vectorLen / norm(vx, vy); + vx *= vectorLen; + vy *= vectorLen; + new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0)); + } + if(convertNum==len) { + new_polygon.clear(); + for (int i = 0; i < len; i++) + { + QVector3D p = polygon[i]; + QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1]; + QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1]; + float v1x = p1.x() - p.x(); + float v1y = p1.y() - p.y(); + float n1 = norm(v1x, v1y); + float vv1x = v1x / n1; + float vv1y = v1y / n1; + float v2x = p2.x() - p.x(); + float v2y = p2.y() - p.y(); + float n2 = norm(v2x, v2y); + float vv2x = v2x / n2; + float vv2y = v2y / n2; + float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f); + float vx = vv1x + vv2x; + float vy = vv1y + vv2y; + vectorLen = vectorLen / norm(vx, vy); + vx *= vectorLen; + vy *= vectorLen; + new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0)); + } + } + + if(repeatFlag) new_polygon.append(new_polygon.first()); + + return new_polygon; +} + +bool DxfHelper::generateDxf(const QString &fileName) +{ +// currentPos = QPointF(QRandomGenerator::global()->bounded(9999.99), QRandomGenerator::global()->bounded(9999.99)); + currentPos = QPointF(9999.99, 9999.99); + vertexIndex = 0; + controlIndex = 0; + dxfPaths.clear(); + + DxfReader dxfReader(fileName); + for(auto d: dxfReader.dxfText) { + //qDebug() << "text data:" << d.text.c_str() << d.angle << d.style.c_str() << d.height; + } + + for(auto d: dxfReader.dxfLinetypes) { + //qDebug() << "linetypes data:" << d.name.c_str() << d.flags << d.pattern << d.description.c_str() << d.patternLength << d.numberOfDashes; + } + + QVector linepath; + for(auto d: dxfReader.dxfLines) { + //qDebug() << "line data:" << d.x1 << d.y1 << d.z1 << "," << d.x2 << d.y2 << d.z2; + if(currentPos!=QPointF(d.x1, d.y1)) { + if(!linepath.isEmpty()) { + QList linelist; + foreach(auto point, linepath) linelist.append(QVector3D(point)); + linepath.clear(); + linelist = expandPolygon(linelist, expandOffset); + foreach(QVector3D point, linelist) { + double x = point.x(); + double y = point.y(); + linepath.append(QPointF(x, y)); + currentPos = QPointF(x, y); + } + dxfPaths.append(linepath); + linepath.clear(); + } + linepath.append(QPointF(d.x1, d.y1)); + linepath.append(QPointF(d.x2, d.y2)); + currentPos = QPointF(d.x2, d.y2); + } else { + linepath.append(QPointF(d.x2, d.y2)); + currentPos = QPointF(d.x2, d.y2); + } + } + if(!linepath.isEmpty()) { + QList linelist; + foreach(auto point, linepath) linelist.append(QVector3D(point)); + linepath.clear(); + linelist = expandPolygon(linelist, expandOffset); + foreach(QVector3D point, linelist) { + double x = point.x(); + double y = point.y(); + linepath.append(QPointF(x, y)); + currentPos = QPointF(x, y); + } + dxfPaths.append(linepath); + linepath.clear(); + } + + + for(auto d: dxfReader.dxfArcs) { + //qDebug() << "arcs data:" << d.cx << d.cy << d.cz << d.angle1 << d.angle2 << d.radius; + + + double cx = d.cx; + double cy = d.cy; +// double cz = d.cz; + double angle1 = d.angle1; + double angle2 = d.angle2; + double radius = d.radius; + + radius = radius + expandOffset; + + + QPainterPath path; + double startXPos = cx + cos(abs(angle1)*M_PI/180)*radius; + double startYPos = cy + sin(abs(angle1)*M_PI/180)*radius; + + path.moveTo(startXPos, startYPos); + + double angleStart ,anglePassed; + angleStart = angle1; + if(angleStart>=180) angleStart = angleStart-360; + anglePassed = angleStart-angle2; + if(angleStart<180) angleStart = -angleStart; + if(anglePassed<-360) anglePassed = anglePassed+360; + + QRectF rect(cx-radius, cy-radius, 2*radius, 2*radius); + path.arcTo(rect, angleStart, anglePassed); + + QVector arcpath; + for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整 + QPointF point = path.pointAtPercent(i); + double x = point.x(); + double y = point.y(); + arcpath.append(point); + currentPos=QPointF(x, y); + } + dxfPaths.append(arcpath); +// dxfPathList.append(path); + } + + for(auto d: dxfReader.dxfCircles) { + //qDebug() << "circle data:" << d.cx << d.cy << d.cz << d.radius; + + + double cx = d.cx; + double cy = d.cy; +// double cz = d.cz; + double radius = d.radius; + + radius = radius + expandOffset; + + + QPainterPath path; + path.moveTo(cx+radius, cy); + path.arcTo(cx-radius, cy-radius, 2*radius, 2*radius, 0, 360); + + QVector circlepath; + for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整 + QPointF point = path.pointAtPercent(i); + double x = point.x(); + double y = point.y(); + circlepath.append(point); + currentPos=QPointF(x, y); + } + dxfPaths.append(circlepath); +// dxfPathList.append(path); + } + + for(auto d: dxfReader.dxfEllipses) { // 起点角度要×ratio + //qDebug() << "ellipses data:" << d.cx << d.cy << d.cz << d.mx << d.my << d.mz << d.ratio << d.angle1 << d.angle2; + + double cx = d.cx; + double cy = d.cy; +// double cz = d.cz; + double mx = d.mx; + double my = d.my; +// double mz = d.mz; + double ratio = d.ratio; + double angle1 = d.angle1; + double angle2 = d.angle2; + + + double rab = sqrt((cx- mx)*(cx - mx) +(cy - my)*(cy - my)); + double resy = (expandOffset*(my-cy))/rab + my; + double resx = (expandOffset*(mx-cx))/rab + mx; + + mx = resx; + my = resy; + + + QPainterPath path; + double angle_1 = angle1; + double angle_2 = angle2; + while(angle_1>=3.14&&angle_2>=6.28) { + angle_1 -= M_PI; + angle_2 -= M_PI; + } + angle_1 = angle_1*180/M_PI; + angle_2 = angle_2*180/M_PI; + + double angleStart ,anglePassed; + angleStart = angle_1; + if(angleStart>=180) angleStart = angleStart-360; + anglePassed = angleStart-angle_2; + if(angleStart<180) angleStart = -angleStart; + if(anglePassed<-360) anglePassed = anglePassed+360; + + if(abs(anglePassed)<1) anglePassed = 360; + + double c_x = cx; + double c_y = cy; + double dl = sqrt(mx*mx+my*my); + double ds = dl*ratio; + + double rx; + double ry; + if(qFuzzyIsNull(mx)) { + rx = ds; ry = dl; + angleStart += 90; + } else { + rx = dl; ry = ds; + } + + double angle=angleStart; + if(angle<0) angle=-angle; + else if(angle>=0) angle = 360-angle; + //if(!qFuzzyCompare(abs(anglePassed),360)) angle *= ratio; + if(!qFuzzyCompare(float(anglePassed),(float)360)) angle *= ratio; + double a=qDegreesToRadians(angle); + double R=rx*ry/sqrt(pow(rx*sin(a),2)+pow(ry*cos(a),2)); //计算对应角度的半径 + double startXPos=c_x+R*cos(a); + double startYPos=c_y+R*sin(a); + path.moveTo(startXPos, startYPos); + + //qDebug() << c_x << c_y << rx << ry << angleStart << anglePassed << angle; + path.arcTo(c_x-rx, c_y-ry, 2*rx, 2*ry, angleStart, anglePassed); + + QVector ellipsepath; + for(double i = 0; i <= 1; i += 0.003) { // TODO: 步长随图片大小调整 + QPointF point = path.pointAtPercent(i); + double x = point.x(); + double y = point.y(); + ellipsepath.append(point); + currentPos=QPointF(x, y); + } + dxfPaths.append(ellipsepath); +// dxfPathList.append(path); + } + + for(auto d: dxfReader.dxfPolylines) { + //qDebug() << "polylines data:" << d.m << d.n << d.flags << d.number << d.elevation; + + QList