HMDT MGL_EXPORT mgl_triangulation_3d(HCDT x, HCDT y, HCDT z) { mglData *nums=0; long n = x->GetNx(), m; if(y->GetNx()!=n || z->GetNx()!=n) return nums; mglPoint *pp = new mglPoint[n]; long *nn=0; for(long i=0;i<n;i++) pp[i] = mglPoint(x->v(i), y->v(i), z->v(i)); m = mgl_crust(n,pp,&nn,0); if(m>0) { nums=new mglData(3,m); for(long i=0;i<3*m;i++) nums->a[i]=nn[i]; } delete []pp; free(nn); return nums; }
//----------------------------------------------------------------------------- void MGL_NO_EXPORT mgl_ifs_3d_point(HCDT A, mreal& x, mreal& y, mreal& z, mreal amax) { int i, n=A->GetNy(); mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for (i=0; i<n; i++) { sum_prob += A->v(12,i); if(r < sum_prob) break; } x1= A->v(0,i)*x + A->v(1,i)*y + A->v(2,i)*z + A->v(9,i); y1= A->v(3,i)*x + A->v(4,i)*y + A->v(5,i)*z + A->v(10,i); z = A->v(6,i)*x + A->v(7,i)*y + A->v(8,i)*z + A->v(11,i); x = x1; y = y1; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_contf_z_val(HMGL gr, HCDT v, HCDT a, const char *sch, double sv, const char *opt) { long n=a->GetNx(),m=a->GetNy(); if(n<2 || m<2) { gr->SetWarn(mglWarnLow,"ContFZ"); return; } gr->SaveState(opt); if(mgl_isnan(sv)) sv = gr->GetOrgZ('z'); if(sv<gr->Min.z || sv>gr->Max.z) { gr->SetWarn(mglWarnSlc,"ContFZ"); gr->LoadState(); return; } static int cgid=1; gr->StartGroup("ContFZ",cgid++); mglDataV xx,yy,zz; mglData aa; long ss=gr->AddTexture(sch); a = fill_slice_z(gr,sv,a,xx,yy,zz,aa); #pragma omp parallel for for(long i=0;i<v->GetNx()-1;i++) { mreal v0 = v->v(i); mgl_contf_gen(gr,v0,v->v(i+1),a,&xx,&yy,&zz,gr->GetC(ss,v0),0); } gr->EndGroup(); }
//----------------------------------------------------------------------------- HCDT static fill_slice_z(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); if(l>1) { aa.Create(n,m); mreal d = (l-1)*(sv - gr->Min.z)/(gr->Max.z - gr->Min.z); long k = long(d); d = d - k; if(k>l-2) { k=l-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<m;j++) for(long i=0;i<n;i++) aa.a[i+n*j] = a->v(i,j,k)*(1-d) + d*a->v(i,j,k+1); a = &aa; } zz.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'y'); xx.Fill(gr->Min.x, gr->Max.x,'x'); return a; }
//----------------------------------------------------------------------------- HCDT static fill_slice_x(HMGL gr, double sv, HCDT a, mglDataV &xx, mglDataV &yy, mglDataV &zz, mglData &aa) { long n=a->GetNx(),m=a->GetNy(),l=a->GetNz(); if(l>1) { aa.Create(m,l); xx.Create(m,l); yy.Create(m,l); zz.Create(m,l); mreal d = (n-1)*(sv - gr->Min.x)/(gr->Max.x - gr->Min.x); long k = long(d); d = d - k; if(k>n-2) { k=n-2; d=1; } if(k<0) { k=0; d=0; } #pragma omp parallel for collapse(2) for(long j=0;j<l;j++) for(long i=0;i<m;i++) aa.a[i+m*j] = a->v(k,i,j)*(1-d) + d*a->v(k+1,i,j); a = &aa; } else { xx.Create(n,m); yy.Create(n,m); zz.Create(n,m); } xx.Fill(sv, sv); yy.Fill(gr->Min.y, gr->Max.y,'x'); zz.Fill(gr->Min.z, gr->Max.z,'y'); return a; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_datac_set(HADT d, HCDT a) { if(!a) return; const mglDataC *dd = dynamic_cast<const mglDataC *>(a); // faster for mglData mgl_datac_create(d, a->GetNx(), a->GetNy(), a->GetNz()); if(dd) // this one should be much faster memcpy(d->a, dd->a, d->nx*d->ny*d->nz*sizeof(dual)); else // very inefficient!!! { register long i,j,k; for(k=0;k<d->nz;k++) for(j=0;j<d->ny;j++) for(i=0;i<d->nx;i++) d->a[i+d->nx*(j+d->ny*k)] = a->v(i,j,k); } }
HMDT MGL_EXPORT mgl_data_ifs_3d(HCDT A, long n, long skip) { if(!A || A->GetNx()<13 || n<1) return 0; // incompatible dimensions mreal amax = 0; for(int i=0; i<A->GetNy(); i++) amax += A->v(12,i); if(amax <= 0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0, z = 0; for(long i=0; i<skip; i++) mgl_ifs_3d_point(A, x, y, z, amax); for(long i=0; i<n; i++) { mgl_ifs_3d_point(A, x, y, z, amax); f->a[3*i] = x; f->a[3*i+1] = y; f->a[3*i+2] = z; } return f; }
HMDT MGL_EXPORT mgl_data_flame_2d(HCDT A, HCDT F, long n, long skip) { if(!A || A->GetNx()<7 || n<1) return 0; // incompatible dimensions if(!F || F->GetNx()<2 || F->GetNz()!=A->GetNy()) return 0; // incompatible dimensions mreal amax=0; for(long i=0; i<A->GetNy(); i++) amax += A->v(6,i); if(amax<=0) return 0; mglData *f = new mglData(3,n); mreal x = 0, y = 0; for(long i=0; i<skip; i++) mgl_flame_2d_point(A, F, x, y,amax); for(long i=0; i<n; i++) { f->a[3*i+2] = mgl_flame_2d_point(A, F, x, y, amax); // TODO color information ?!! f->a[3*i] = x; f->a[3*i+1] = y; } return f; }
//----------------------------------------------------------------------------- void MGL_EXPORT mgl_tricont_xyzcv(HMGL gr, HCDT v, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { mglDataV zz(x->GetNx(),x->GetNy()); if(!z) z = &zz; if(mgl_check_trig(gr,nums,x,y,z,a,"TriCont")) return; gr->SaveState(opt); static int cgid=1; gr->StartGroup("TriCont",cgid++); int text=0; if(mglchr(sch,'t')) text=1; if(mglchr(sch,'T')) text=2; bool fixed=(mglchr(sch,'_')) || (gr->Min.z==gr->Max.z); long s=gr->AddTexture(sch); gr->SetPenPal(sch); for(long k=0;k<v->GetNx();k++) { mreal v0 = v->v(k); zz.Fill(fixed ? gr->Min.z : v0); mgl_draw_curvs(gr,v0,gr->GetC(s,v0),text,mgl_get_curvs(gr,mgl_tri_lines(v0,nums,a,x,y,fixed?&zz:z))); } }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata(HCDT d, long xx,long yy,long zz) { long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(), n=1,m=1,l=1; int dx=0,dy=0,dz=0; if(xx<0) { xx=0; dx=1; n=nx; } if(yy<0) { yy=0; dy=1; m=ny; } if(zz<0) { zz=0; dz=1; l=nz; } const mglDataC *dd = dynamic_cast<const mglDataC *>(d); mglDataC *r=new mglDataC(n,m,l); if(xx>=nx || yy>=ny || zz>=nz) #pragma omp parallel for for(long i=0;i<n*m*l;i++) r->a[i] = NAN; else if(dd) #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = dd->a[xx+dx*i + nx*(yy+dy*j + ny*(zz+dz*k))]; else #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) r->a[i+n*(j+m*k)] = d->v(xx+dx*i, yy+dy*j, zz+dz*k); if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; }
//----------------------------------------------------------------------------- long MGL_NO_EXPORT mgl_flame_2d_point(HCDT A, HCDT F, mreal& x, mreal& y, mreal amax) { long i, n=A->GetNy(), m=F->GetNy(), last_func=0, l=F->GetNx(); l = l>6?6:l; mreal r = amax*mgl_rnd(), sum_prob = 0, x1, y1; for(i=0;i<n;i++) { sum_prob += A->v(6,i); if(r<sum_prob) break; } x1 = A->v(0,i)*x + A->v(1,i)*y + A->v(4,i); y1 = A->v(2,i)*x + A->v(3,i)*y + A->v(5,i); x = y = 0; for(long j=0;j<m;j++) { int v=int(F->v(0,j,i)+0.5); mreal par[5] = {F->v(1,j,i),0,0,0,0}; for(int k=2;k<l;k++) par[k-1]=F->v(k,j,i); if(v<0 || v>=mglFlameLAST) { v=0; par[0]=1; } ffunc[v](x,y,x1,y1,par); last_func=v; } return last_func; }
//----------------------------------------------------------------------------- // // TriPlot series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_triplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n = x->GetNx(), m = nums->GetNy(); if(mgl_check_trig(gr,nums,x,y,z,a,"TriPlot")) return; long ss=gr->AddTexture(sch); gr->SaveState(opt); gr->SetPenPal("-"); static int cgid=1; gr->StartGroup("TriPlot",cgid++); bool wire = mglchr(sch,'#'); long nc = a->GetNx(); if(nc!=n && nc>=m) // colors per triangle { mglPoint p1,p2,p3,q; gr->Reserve(m*3); for(long i=0;i<m;i++) { register long k1 = long(nums->v(0,i)+0.5); p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1)); register long k2 = long(nums->v(1,i)+0.5); p2 = mglPoint(x->v(k2), y->v(k2), z->v(k2)); register long k3 = long(nums->v(2,i)+0.5); p3 = mglPoint(x->v(k3), y->v(k3), z->v(k3)); q = wire ? mglPoint(NAN,NAN) : (p2-p1) ^ (p3-p1); k1 = gr->AddPnt(p1,gr->GetC(ss,a->v(k1)),q); k2 = gr->AddPnt(p2,gr->GetC(ss,a->v(k2)),q); k3 = gr->AddPnt(p3,gr->GetC(ss,a->v(k3)),q); gr->trig_plot(k1,k2,k3); } } else if(nc>=n) // colors per point { gr->Reserve(n); long *kk = new long[n]; mglPoint *pp = new mglPoint[n]; for(long i=0;i<m;i++) // add averaged normales { register long k1 = long(nums->v(0,i)+0.5); register long k2 = long(nums->v(1,i)+0.5); register long k3 = long(nums->v(2,i)+0.5); if(!wire) { mglPoint q = mglPoint(x->v(k2)-x->v(k1), y->v(k2)-y->v(k1), z->v(k2)-z->v(k1)) ^ mglPoint(x->v(k3)-x->v(k1), y->v(k3)-y->v(k1), z->v(k3)-z->v(k1)); q.Normalize(); // try be sure that in the same direction ... if(q.z<0) q *= -1; pp[k1] += q; pp[k2] += q; pp[k3] += q; } else pp[k1]=pp[k2]=pp[k3]=mglPoint(NAN,NAN); } for(long i=0;i<n;i++) // add points kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)), gr->GetC(ss,a->v(i)), pp[i]); for(long i=0;i<m;i++) // draw triangles { register long k1 = long(nums->v(0,i)+0.5); register long k2 = long(nums->v(1,i)+0.5); register long k3 = long(nums->v(2,i)+0.5); if(wire) { gr->line_plot(kk[k1],kk[k2]); gr->line_plot(kk[k1],kk[k3]); gr->line_plot(kk[k3],kk[k2]); } else gr->trig_plot(kk[k1],kk[k2],kk[k3]); } delete []kk; delete []pp; } gr->EndGroup(); }
//----------------------------------------------------------------------------- std::vector<mglSegment> MGL_NO_EXPORT mgl_tri_lines(mreal val, HCDT nums, HCDT a, HCDT x, HCDT y, HCDT z) { long n = x->GetNx(), m = nums->GetNy(); std::vector<mglSegment> lines; for(long i=0;i<m;i++) { register long k1 = long(nums->v(0,i)+0.1); if(k1<0 || k1>=n) continue; register long k2 = long(nums->v(1,i)+0.1); if(k2<0 || k2>=n) continue; register long k3 = long(nums->v(2,i)+0.1); if(k3<0 || k3>=n) continue; register mreal v1 = a->v(k1), v2 = a->v(k2), v3 = a->v(k3); register mreal d1 = mgl_d(val,v1,v2), d2 = mgl_d(val,v1,v3), d3 = mgl_d(val,v2,v3); mglSegment line; if(d1>=0 && d1<=1 && d2>=0 && d2<=1) { line.p1 = mglPoint(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1); line.p2 = mglPoint(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2); } else if(d1>=0 && d1<=1 && d3>=0 && d3<=1) { line.p1 = mglPoint(x->v(k1)*(1-d1)+x->v(k2)*d1, y->v(k1)*(1-d1)+y->v(k2)*d1, z->v(k1)*(1-d1)+z->v(k2)*d1); line.p2 = mglPoint(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3); } else if(d3>=0 && d3<=1 && d2>=0 && d2<=1) { line.p1 = mglPoint(x->v(k1)*(1-d2)+x->v(k3)*d2, y->v(k1)*(1-d2)+y->v(k3)*d2, z->v(k1)*(1-d2)+z->v(k3)*d2); line.p2 = mglPoint(x->v(k2)*(1-d3)+x->v(k3)*d3, y->v(k2)*(1-d3)+y->v(k3)*d3, z->v(k2)*(1-d3)+z->v(k3)*d3); } if(line.p1!=line.p2) lines.push_back(line); } return lines; }
//----------------------------------------------------------------------------- // // QuadPlot series // //----------------------------------------------------------------------------- void MGL_EXPORT mgl_quadplot_xyzc(HMGL gr, HCDT nums, HCDT x, HCDT y, HCDT z, HCDT a, const char *sch, const char *opt) { long n = x->GetNx(), m = nums->GetNy(); if(mgl_check_trig(gr,nums,x,y,z,a,"QuadPlot",4)) return; long ss=gr->AddTexture(sch); gr->SaveState(opt); gr->SetPenPal("-"); static int cgid=1; gr->StartGroup("QuadPlot",cgid++); mglPoint p1,p2,p3,p4; long nc = a->GetNx(); bool wire = mglchr(sch,'#'); if(nc!=n && nc>=m) // colors per triangle { gr->Reserve(m*4); for(long i=0;i<m;i++) { register long k1 = long(nums->v(0,i)+0.5); p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1)); register long k2 = long(nums->v(1,i)+0.5); p2 = mglPoint(x->v(k2), y->v(k2), z->v(k2)); register long k3 = long(nums->v(2,i)+0.5); p3 = mglPoint(x->v(k3), y->v(k3), z->v(k3)); register long k4 = floor(nums->v(3,i)+0.5); p4 = mglPoint(x->v(k4), y->v(k4), z->v(k4)); mglPoint q = wire ? mglPoint(NAN,NAN):(p2-p1) ^ (p3-p1); k1 = gr->AddPnt(p1,gr->GetC(ss,a->v(k1)),q); k2 = gr->AddPnt(p2,gr->GetC(ss,a->v(k2)),q); k3 = gr->AddPnt(p3,gr->GetC(ss,a->v(k3)),q); k4 = gr->AddPnt(p4,gr->GetC(ss,a->v(k4)),q); gr->quad_plot(k1,k2,k3,k4); } } else if(nc>=n) // colors per point { gr->Reserve(n); long *kk = new long[n]; mglPoint *pp = new mglPoint[n]; for(long i=0;i<m;i++) // add averaged normales { register long k1 = long(nums->v(0,i)+0.5); p1 = mglPoint(x->v(k1), y->v(k1), z->v(k1)); register long k2 = long(nums->v(1,i)+0.5); p2 = mglPoint(x->v(k2), y->v(k2), z->v(k2)); register long k3 = long(nums->v(2,i)+0.5); p3 = mglPoint(x->v(k3), y->v(k3), z->v(k3)); register long k4 = floor(nums->v(3,i)+0.5); p4 = mglPoint(x->v(k4), y->v(k4), z->v(k4)); if(wire) pp[k1]=pp[k2]=pp[k3]=pp[k4]=mglPoint(NAN,NAN); else { mglPoint q1 = (p2-p1) ^ (p3-p1); if(q1.z<0) q1*=-1; mglPoint q2 = (p2-p4) ^ (p3-p4); if(q2.z<0) q2*=-1; mglPoint q3 = (p1-p2) ^ (p4-p2); if(q3.z<0) q3*=-1; mglPoint q4 = (p1-p4) ^ (p4-p3); if(q4.z<0) q4*=-1; pp[k1] += q1; pp[k2] += q2; pp[k3] += q3; pp[k4] += q4; } } for(long i=0;i<n;i++) // add points kk[i] = gr->AddPnt(mglPoint(x->v(i), y->v(i), z->v(i)),gr->GetC(ss,a->v(i)), pp[i]); for(long i=0;i<m;i++) // draw quads { register long k1 = floor(nums->v(0,i)+0.5); register long k2 = floor(nums->v(1,i)+0.5); register long k3 = floor(nums->v(2,i)+0.5); register long k4 = floor(nums->v(3,i)+0.5); if(wire) { gr->line_plot(kk[k1],kk[k2]); gr->line_plot(kk[k1],kk[k3]); gr->line_plot(kk[k4],kk[k2]); gr->line_plot(kk[k4],kk[k3]); } else gr->quad_plot(kk[k1],kk[k2],kk[k3],kk[k4]); } delete []kk; delete []pp; } gr->EndGroup(); }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_subdata_ext(HCDT d, HCDT xx, HCDT yy, HCDT zz) { if(!xx || !yy || !zz) { mglData tmp; tmp.a[0]=-1; return mgl_datac_subdata_ext(d,xx?xx:&tmp,yy?yy:&tmp,zz?zz:&tmp); } long n=0,m=0,l=0,j,k; bool ix=false, iy=false, iz=false; if(xx->GetNz()>1) // 3d data { n = xx->GetNx(); m = xx->GetNy(); l = xx->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNz()>1) { n = yy->GetNx(); m = yy->GetNy(); l = yy->GetNz(); j = xx->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = zz->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNz()>1) { n = zz->GetNx(); m = zz->GetNy(); l = zz->GetNz(); j = yy->GetNN(); if(j>1 && j!=n*m*l) return 0; // wrong sizes k = xx->GetNN(); if(k>1 && k!=n*m*l) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } else if(xx->GetNy()>1) // 2d data { n = xx->GetNx(); m = xx->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes ix = true; iy = j>1; iz = k>1; } else if(yy->GetNy()>1) { n = yy->GetNx(); m = yy->GetNy(); l = 1; j = xx->GetNx()*xx->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = zz->GetNx()*zz->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iy = true; ix = j>1; iz = k>1; } else if(zz->GetNy()>1) { n = zz->GetNx(); m = zz->GetNy(); l = 1; j = yy->GetNx()*yy->GetNy(); if(j>1 && j!=n*m) return 0; // wrong sizes k = xx->GetNx()*xx->GetNy(); if(k>1 && k!=n*m) return 0; // wrong sizes iz = true; iy = j>1; ix = k>1; } long nx=d->GetNx(),ny=d->GetNy(),nz=d->GetNz(); long vx=long(xx->v(0)), vy=long(yy->v(0)), vz=long(zz->v(0)); const mglDataC *dd = dynamic_cast<const mglDataC *>(d); if(n*m*l>1) // this is 2d or 3d data { mglDataV tx(n,m,l),ty(n,m,l),tz(n,m,l); if(!ix) { xx = &tx; if(vx>=0) tx.Fill(vx); else tx.All(); } if(!iy) { yy = &ty; if(vy>=0) ty.Fill(vy); else ty.All(); } if(!iz) { zz = &tz; if(vz>=0) tz.Fill(vz); else tz.All(); } mglDataC *r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for for(long i0=0;i0<n*m*l;i0++) { register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for for(long i0=0;i0<n*m*l;i0++) { register long x=long(0.5+xx->vthr(i0)), y=long(0.5+yy->vthr(i0)), z=long(0.5+zz->vthr(i0)); r->a[i0] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN; } return r; } // this is 1d data -> try as normal SubData() mglDataV tx(nx),ty(ny),tz(nz); tx.Fill(0,nx-1); ty.Fill(0,ny-1); tz.Fill(0,nz-1); if(xx->GetNx()>1 || vx>=0) n=xx->GetNx(); else { n=nx; xx = &tx; } if(yy->GetNx()>1 || vy>=0) m=yy->GetNx(); else { m=ny; yy = &ty; } if(zz->GetNx()>1 || vz>=0) l=zz->GetNx(); else { l=nz; zz = &tz; } mglDataC *r=new mglDataC(n,m,l); if(dd) #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) { register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?dd->a[x+nx*(y+ny*z)]:NAN; } else #pragma omp parallel for collapse(3) for(long k=0;k<l;k++) for(long j=0;j<m;j++) for(long i=0;i<n;i++) { register long x=long(0.5+xx->v(i)), y=long(0.5+yy->v(j)), z=long(0.5+zz->v(k)); r->a[i+n*(j+m*k)] = (x>=0 && x<nx && y>=0 && y<ny && z>=0 && z<nz)?d->v(x,y,z):NAN; } if(m==1) { r->ny=r->nz; r->nz=1; }// "squeeze" dimensions if(n==1) { r->nx=r->ny; r->ny=r->nz; r->nz=1; r->NewId();} return r; }
//----------------------------------------------------------------------------- HADT MGL_EXPORT mgl_datac_momentum(HCDT dat, char dir, const char *how) { if(!how || !(*how) || !strchr("xyz",dir)) return 0; long nx=dat->GetNx(),ny=dat->GetNy(),nz=dat->GetNz(); mglDataV x(nx,ny,nz, 0,1,'x'); x.s=L"x"; mglDataV y(nx,ny,nz, 0,1,'y'); y.s=L"y"; mglDataV z(nx,ny,nz, 0,1,'z'); z.s=L"z"; mglDataC u(dat); u.s=L"u"; // NOTE slow !!! std::vector<mglDataA*> list; list.push_back(&x); list.push_back(&y); list.push_back(&z); list.push_back(&u); mglDataC res=mglFormulaCalcC(how,list); mglDataC *b=0; if(dir=='x') { b=new mglDataC(nx); #pragma omp parallel for for(long i=0;i<nx;i++) { register dual i1=0,i0=0; for(long j=0;j<ny*nz;j++) { register dual u=dat->vthr(i+nx*j); i0 += u; i1 += u*res.a[i+nx*j]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='y') { b=new mglDataC(ny); #pragma omp parallel for for(long i=0;i<ny;i++) { register dual i1=0,i0=0; for(long k=0;k<nz;k++) for(long j=0;j<nx;j++) { register dual u=dat->v(j,i,k); i0 += u; i1 += u*res.a[j+nx*(i+ny*k)]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } if(dir=='z') { long nn=nx*ny; b=new mglDataC(nz); #pragma omp parallel for for(long i=0;i<nz;i++) { register dual i1=0,i0=0; for(long j=0;j<nn;j++) { register dual u=dat->vthr(j+nn*i); i0 += u; i1 += u*res.a[j+nn*i]; } b->a[i] = i0!=mreal(0) ? i1/i0 : 0; } } return b; }