This is PlotShape.m in view mode; [Download] [Up]
#import "Plot3DView.h" #import "PlotShape.h" #import <ri/ri.h> #import <math.h> #define SC .05 #define SCP1 SC/1.732 #define SCP2 SC/.866 #define SCP3 SC/2.45 #define SCP4 SC/1.633-SCP3 #define SWAPP(a,b) { float f; int i; for (i=0; i<3; i++) { f=a[i]; a[i]=b[i]; b[i]=f; } } /* used to position z axis label */ struct ZAXTAB { float x,y; int d; }; @implementation PlotShape:N3DShape - renderSelf:(RtToken)context { int i,j,cm; float x,y,z,xpm,ypm,a,b; struct ZAXTAB zaxtab[8] = { {1.0,1.0,0},{-1.0,-1.0,1},{-1.0,1.0,1},{1.0,-1.0,0} ,{-1.0,-1.0,0},{1.0,1.0,1},{1.0,-1.0,1},{-1.0,1.0,0} }; static RtPoint square[4]= {{-1.0,-1.0,-1.01},{1.0,-1.0,-1.01},{1.0,1.0,-1.01},{-1.0,1.0,-1.01}}; static RtFloat squareST[8]= { 0.0,0.0,1.0,0.0,1.0,1.0,0.0,1.0 }; static RtPoint zsquare[4]= {{-1.0,-1.0,0},{1.0,-1.0,0},{1.0,1.0,0},{-1.0,1.0,0}}; static RtPoint sq1[4]= {{-1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,1.0,1.0},{-1.0,-1.0,1.0}}; static RtPoint sq2[4]= {{-1.0,1.0,-1.0},{-1.0,1.0,1.0},{1.0,1.0,1.0},{1.0,1.0,-1.0}}; static RtPoint sq3[4]= {{1.0,1.0,1.0},{1.0,1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,1.0}}; static RtPoint sq4[4]= {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,1.0},{-1.0,-1.0,1.0}}; RtPoint scaX[4] = {{-1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{1.0,-1.0,-1.0},{-1.0,-1.0,-1.0} }; RtPoint scaY[4] = {{-1.0,-1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,1.0,-1.0},{-1.0,-1.0,-1.0} }; static RtPoint scaZ[4]; RtFloat scaST[8] = { 0,1.0,1.0,1.0,1.0,0.75,0,0.75 }; static RtFloat scaSTZ[8] = { 1.0,0.5,1.0,0,0,0,0,0.5 }; static RtPoint Box[8] = {{-SC,-SC,-SC},{-SC,-SC,SC},{-SC,SC,SC},{-SC,SC,-SC}, {SC,-SC,-SC},{SC,-SC,SC},{SC,SC,SC},{SC,SC,-SC}}; static RtInt BoxP[24] = {0,1,2,3,0,1,5,4,4,5,6,7,2,3,7,6,1,5,6,2,0,3,7,4}; static RtInt BoxV[6]={4,4,4,4,4,4}; static RtPoint Pyr[4] = {{0,-SCP2,-SCP4},{-SC,SCP1,-SCP4},{SC,SCP1,-SCP4}, {0,0,SCP4}}; static RtInt PyrP[12] = {0,1,2,0,1,3,0,2,3,1,2,3}; static RtInt PyrV[4] = {3,3,3,3}; static RtColor bgCol = {1.0,1.0,1.0}; static RtColor dCol = { 1.0,1.0,1.0 }; static RtColor opac = { .2,.2,.2 }; static RtColor cylCol = { .9,.9,.9 }; static RtPoint bsquare[4]= {{-100.0,-100.0,-40.0},{100.0,-100.0,-40.0},{100.0,100.0,-40.0},{-100.0,100.0,-40.0}}; RtColor Alpha; RtFloat *SZ; char tmaps[100],*tmap; char home[60]; sprintf(home,"/tmp/%s",getenv("USER")); if (getenv("USER")==NULL) strcpy(home,"/tmp"); sprintf(tmaps,"%s/plot3d.tx",home); tmap=tmaps; RiDeclare("texname","uniform string"); RiDeclare("Cst","uniform float"); RiDeclare("Csp","uniform float"); RiSurface("constant",RI_NULL); if (mode>=4) { RiTransformBegin(); RiRotate(chi,0,0,1.0); RiRotate(-theta+90.0,1.0,0,0); RiColor(bgCol); RiPolygon(4,RI_P,(RtPointer)bsquare,RI_NULL); RiTransformEnd(); } RiSurface("matte",RI_NULL); RiColor(flagcol[1]); /* FLOOR */ if (flags&2) { if (mode>=4 && Omode&OVER_base) { /* RiTextureCoordinates(0,0,.5,0,0,.5,.5,.5);*/ RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL); } RiPolygon(4,RI_P,(RtPointer)square,RI_ST,(RtPointer)squareST,RI_NULL); } RiSurface("matte",RI_NULL); RiColor(dCol); if (chi>90.0&&chi<270.0) ypm=-1.0; else ypm=1.0; if (chi<180.0) xpm=-1.0; else xpm=1.0; /* Backs */ if (flags&4) { RiColor(flagcol[2]); if (chi>90.0&&chi<270.0) RiPolygon(4,RI_P,(RtPointer)sq4,RI_NULL); else RiPolygon(4,RI_P,(RtPointer)sq2,RI_NULL); if (chi<180.0) RiPolygon(4,RI_P,(RtPointer)sq1,RI_NULL); else RiPolygon(4,RI_P,(RtPointer)sq3,RI_NULL); if (flags&8) { RiColor(flagcol[3]); RiTransformBegin(); RiTranslate(xpm,0.0,0.0); RiRotate(90.0,1.0,0.0,0.0); RiTranslate(0,tickmin[2],0.0); for (z=tickmin[2]; z<1.0; z+=tickstp[2]) { RiCylinder(.007,-1.0,1.0,360.0,RI_NULL); RiTranslate(0,tickstp[2],0); } RiTransformEnd(); RiTransformBegin(); RiTranslate(0.0,ypm,0.0); RiRotate(90.0,0.0,1.0,0.0); RiTranslate(-tickmin[2],0,0); for (z=tickmin[2]; z<1.0; z+=tickstp[2]) { RiCylinder(.007,-1.0,1.0,360.0,RI_NULL); RiTranslate(-tickstp[2],0,0); } RiTransformEnd(); } } /* Axes */ if (flags&1 && data[0].sym!=6) { RiColor(flagcol[0]); RiTransformBegin(); RiTranslate(-1.0,-1.0,-1.0); RiCylinder(.015,0.0,2.0,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiRotate(-90.0,0,1.0,0.0); RiTranslate(-1.0,-1.0,-1.0); RiCylinder(.015,0.0,2.0,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiRotate(90.0,1.0,0.0,0.0); RiTranslate(-1.0,-1.0,-1.0); RiCylinder(.015,0.0,2.0,360.0,RI_NULL); RiTransformEnd(); } else if (flags&1) { RiColor(flagcol[0]); RiTransformBegin(); RiCylinder(.015,-1.0,1.0,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiRotate(-90.0,0,1.0,0.0); RiCylinder(.015,-1.0,1.0,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiRotate(90.0,1.0,0.0,0.0); RiCylinder(.015,-1.0,1.0,360.0,RI_NULL); RiTransformEnd(); } /*else if (flags&1) { RiColor(flagcol[0]); RiLine(2,RI_P,axes1,RI_NULL); RiLine(2,RI_P,axes2,RI_NULL); RiLine(2,RI_P,axes3,RI_NULL); }*/ /* Ticks */ if (flags&8) { RiColor(flagcol[0]); RiTransformBegin(); RiRotate(-90.0,0,1.0,0.0); RiTranslate(-1.0,-ypm,-1.0); RiCylinder(.015,0.0,2.0,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiRotate(90.0,1.0,0.0,0.0); RiTranslate(-xpm,-1.0,-1.0); RiCylinder(.015,0.0,2.0,360.0,RI_NULL); RiTransformEnd(); RiColor(flagcol[3]); RiTransformBegin(); RiTranslate(0,-ypm,-1.0); RiRotate(90,0,1.0,0); for (x=tickmin[0]; x<1.0; x+=tickstp[0]) RiDisk(x,.03,360.0,RI_NULL); RiTransformEnd(); RiTransformBegin(); RiTranslate(-xpm,0.0,-1.0); RiRotate(90,1.0,0,0); for (x=tickmin[1]; x<1.0; x+=tickstp[1]) RiDisk(x,.03,360.0,RI_NULL); RiTransformEnd(); if (!(flags&4)) { RiTranslate(-1.0,-1.0,0.0); for (x=tickmin[2]; x<1.0; x+=tickstp[2]) RiDisk(x,.03,360.0,RI_NULL); RiTranslate(1.0,1.0,0.0); } } /* Labels */ if (flags&32 && mode>=4) { if (ypm<0) { SWAPP(scaX[0],scaX[1]); SWAPP(scaX[2],scaX[3]); } if (xpm>0) { SWAPP(scaY[0],scaY[1]); SWAPP(scaY[2],scaY[3]); } scaX[0][1]=scaX[1][1]=scaX[2][1]=scaX[3][1]=-ypm; scaY[0][0]=scaY[1][0]=scaY[2][0]=scaY[3][0]=-xpm; scaX[0][2]-=.5/aspect; scaX[1][2]-=.5/aspect; scaY[0][2]-=.5/aspect; scaY[1][2]-=.5/aspect; i=floor(chi/45.0); scaZ[0][2]=scaZ[1][2]=-1.0; scaZ[2][2]=scaZ[3][2]=1.0; scaZ[0][0]=scaZ[3][0]=zaxtab[i].x; scaZ[1][0]=scaZ[2][0]=zaxtab[i].x; scaZ[0][1]=scaZ[3][1]=zaxtab[i].y; scaZ[1][1]=scaZ[2][1]=zaxtab[i].y; if (i%2==0) { scaZ[1][zaxtab[i].d]*=(1.0+aspect); scaZ[2][zaxtab[i].d]*=(1.0+aspect); } else { scaZ[0][zaxtab[i].d]*=(1.0+aspect); scaZ[3][zaxtab[i].d]*=(1.0+aspect); } sprintf(tmaps,"%s/plot3dxyz.tx",home); x=1.05/ambient; y=0.0; RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_KA,(RtPointer)&x,RI_KD,(RtPointer)&y,RI_NULL); RiPolygon(4,RI_P,(RtPointer)scaX,RI_ST,(RtPointer)scaST,RI_NULL); scaST[1]=scaST[3]=.75; scaST[5]=scaST[7]=.5; RiPolygon(4,RI_P,(RtPointer)scaY,RI_ST,(RtPointer)scaST,RI_NULL); RiPolygon(4,RI_P,(RtPointer)scaZ,RI_ST,(RtPointer)scaSTZ,RI_NULL); sprintf(tmaps,"%s/plot3d.tx",home); RiSurface("matte",RI_NULL); } /* Planes */ if (flags&16) { RiColor(flagcol[4]); RiOpacity(opac); RiTransformBegin(); RiTranslate(0,0,tickmin[2]); for (z=tickmin[2]; z<1.0; z+=tickstp[2]) { RiPolygon(4,RI_P,(RtPointer)zsquare,RI_NULL); RiTranslate(0,0,tickstp[2]); } RiTransformEnd(); RiOpacity(dCol); } if (data==NULL) return self; for (i=0; i<MAXSETS; i++) { if (data[i].sym<0) continue; if ((mode&3)>=2) RiColor(data[i].mapcol[0]); else RiColor(data[i].mapcol[0]); Alpha[0]=Alpha[1]=Alpha[2]=data[i].alpha; RiOpacity(Alpha); cm=data[i].mapmode; switch(data[i].sym) { case 0: for (j=0; j<data[i].ndata; j++) { x=data[i].data[j].x; y=data[i].data[j].y; z=data[i].data[j].z; if (cm) RiColor(data[i].color[j]); RiTransformBegin(); RiTranslate(x,y,z); RiPointsPolygons(6,BoxV,BoxP,RI_P,(RtPointer)Box,RI_NULL); RiTransformEnd(); } break; case 1: for (j=0; j<data[i].ndata; j++) { x=data[i].data[j].x; y=data[i].data[j].y; z=data[i].data[j].z; if (cm) RiColor(data[i].color[j]); RiTransformBegin(); RiTranslate(x,y,z); RiPointsPolygons(4,PyrV,PyrP,RI_P,(RtPointer)Pyr,RI_NULL); RiTransformEnd(); } break; case 2: for (j=0; j<data[i].ndata; j++) { x=data[i].data[j].x; y=data[i].data[j].y; z=data[i].data[j].z; if (cm) RiColor(data[i].color[j]); RiTransformBegin(); RiTranslate(x,y,z); RiSphere(SC,-SC,SC,360.0,RI_NULL); RiTransformEnd(); } break; case 3: for (j=0; j<data[i].ndata; j++) { x=data[i].data[j].x; y=data[i].data[j].y; z=data[i].data[j].z; if (cm) RiColor(data[i].color[j]); RiTransformBegin(); RiTranslate(x,y,z); RiTorus(SC,SC/3.0,0,360.0,360.0,RI_NULL); RiTransformEnd(); } break; case 4: a=1.0/(float)data[i].nx; b=1.0/(float)data[i].ny; for (j=0; j<data[i].ndata; j++) { x=data[i].data[j].x; y=data[i].data[j].y; z=data[i].data[j].z; if (x-a<-1.0||x+a>1.0||y-b<-1.0||y+b>1.0) continue; /* clip */ RiTransformBegin(); RiTranslate(x,y,0); RiScale(a,b,1.0); RiColor(cylCol); RiCylinder(1.0,-1.0,z,360.0,RI_NULL); if (cm) RiColor(data[i].color[j]); RiDisk(z,1.0,360.0,RI_NULL); RiTransformEnd(); } break; case 5: if ((data[i].flag&7)==F_SDATA) break; /* no mesh in sfile mode */ if (data[i].nx*data[i].ny!=data[i].ndata) break; if (mode>=4 && Omode&OVER_csurf) { SZ=malloc(data[i].ndata*sizeof(RtFloat)); for (j=0; j<data[i].ndata; j++) SZ[j]=(data[i].data[j].z+1.0)/2.0; RiSurface("contour",(RtToken)"Cst",(RtPointer)&Cst, (RtToken)"Csp",(RtPointer)&Csp,RI_NULL); if (cm) RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].data, RI_S,(RtPointer)SZ,RI_CS,(RtPointer)data[i].color,RI_NULL); else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].data, RI_S,(RtPointer)SZ,RI_NULL); free(SZ); } else if (mode>=4 && Omode&OVER_surf) { RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL); RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_NULL); } else if (cm) RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC, data[i].ny,RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_CS, (RtPointer)data[i].color,RI_NULL); else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].data,RI_NULL); break; case 6: if ((data[i].flag&7)==F_SDATA) break; /* no mesh in sfile mode */ if (data[i].nx*data[i].ny!=data[i].ndata) break; if (mode>=4 && Omode&OVER_csurf) { SZ=malloc(data[i].ndata*sizeof(RtFloat)); for (j=0; j<data[i].ndata; j++) SZ[j]=(data[i].data[j].z+1.0)/2.0; RiSurface("contour",(RtToken)"Cst",(RtPointer)&Cst, (RtToken)"Csp",(RtPointer)&Csp,RI_NULL); if (cm) RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata, RI_S,(RtPointer)SZ,RI_CS,(RtPointer)data[i].color,RI_NULL); else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata, RI_S,(RtPointer)SZ,RI_NULL); free(SZ); } else if (mode>=4 && Omode&OVER_surf) { RiSurface("texmap",(RtToken)"texname",(RtPointer)&tmap,RI_NULL); RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_NULL); } else if (cm) RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC, data[i].ny,RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_CS, (RtPointer)data[i].color,RI_NULL); else RiPatchMesh(RI_BILINEAR,data[i].nx,RI_NONPERIODIC,data[i].ny, RI_NONPERIODIC,RI_P,(RtPointer)data[i].Sdata,RI_NULL); break; } } return self; } -setTicks:(RtPoint)Min :(RtPoint)Step { tickmin[0]=Min[0]; tickmin[1]=Min[1]; tickmin[2]=Min[2]; tickstp[0]=Step[0]; tickstp[1]=Step[1]; tickstp[2]=Step[2]; return self; } -setData:(SetPref *)Data :(int)Mode :(int)Flags { data=Data; mode=Mode; flags=Flags; /* mmx[0]=mmy[0]=mmz[0]=MAXFLOAT; mmx[1]=mmy[1]=mmz[1]=-MAXFLOAT; for (i=0; i<MAXSETS; i++) { for (j=0; j<data[i].ndata; j++) { if (data[i].data[j].x<mmx[0]) mmx[0]=data[i].data[j].x; if (data[i].data[j].x>mmx[1]) mmx[1]=data[i].data[j].x; if (data[i].data[j].y<mmy[0]) mmy[0]=data[i].data[j].y; if (data[i].data[j].y>mmy[1]) mmy[1]=data[i].data[j].y; if (data[i].data[j].z<mmz[0]) mmz[0]=data[i].data[j].z; if (data[i].data[j].z>mmz[1]) mmz[1]=data[i].data[j].z; } } mmx[1]=(mmx[1]-mmx[0])/2.0; mmy[1]=(mmy[1]-mmy[0])/2.0; mmz[1]=(mmz[1]-mmz[0])/2.0; */ return self; } -setFlagColors:(RtColor *)col { bcopy(col,flagcol,sizeof(RtColor)*5); return self; } - setSurfaceType:(N3DSurfaceType)st andDescendants:(BOOL)flag { [super setSurfaceType:st andDescendants:flag]; return self; } -setAng:(float)alt :(float)az :(float)Phi :(float)Aspect :(float)Ambient { RtPoint ax; RtMatrix mx = { { -1.0,0,0,0 }, {0,1.0,0,0}, {0,0,1.0,0}, {0,0,0,1.0} }; theta=alt*180.0/M_PI; chi=az*180.0/M_PI; phi=Phi*180/M_PI; aspect=Aspect; ambient=Ambient; [self setTransformMatrix:mx]; [self scale:1.0 :1.0 :Aspect]; ax[0]=ax[2]=0; ax[1]=1.0; [self rotateAngle:phi axis:ax]; ax[0]=ax[1]=0; ax[2]=1.0; [self rotateAngle:chi axis:ax]; ax[0]=1.0; ax[1]=ax[2]=0; [self rotateAngle:theta-90.0 axis:ax]; return self; } - setOver:(int)OMODE { Omode=OMODE; return self; } -setContour:(float)start :(float)space { Cst=start; Csp=space; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.