#include #include #include #include #include #include typedef reviver::dpoint Point; #include "stdio.h" #include #include #include #include #include #include #include using namespace std; void setNearestDistances(int nverts,const RtPoint *P_Rib,double *nearestDistances){ double detail = 1000000; double offset = 1000; Point *P = (Point*)malloc(nverts*sizeof(Point)); for(int n = 0 ; n < nverts ; n++){ unsigned int P_treeX = (P_Rib[n][0]+offset)*detail; unsigned int P_treeY = (P_Rib[n][1]+offset)*detail; unsigned int P_treeZ = (P_Rib[n][2]+offset)*detail; Point treeP(P_treeX,P_treeY,P_treeZ); P[n][0] = treeP[0]; P[n][1] = treeP[1]; P[n][2] = treeP[2]; } vector ans ; nnBase *NN; int size = nverts; ans.resize(1); NN = new sfcnn_ip(P,size); for(int n = 0 ; n < nverts ; n++){ Point queryP(P[n][0],P[n][1],P[n][2]); NN->ksearch(&queryP,3,ans); Point tmp1 = *(ans[1]); Point tmp2 = *(ans[2]); double nX1 = double(tmp1[0]); double nY1 = double(tmp1[1]); double nZ1 = double(tmp1[2]); double nX2 = double(tmp2[0]); double nY2 = double(tmp2[1]); double nZ2 = double(tmp2[2]); double dist1 = sqrt(pow(double(P[n][0])-nX1,2)+pow(double(P[n][1])-nY1,2)+pow(double(P[n][2])-nZ1,2)); double dist2 = sqrt(pow(double(P[n][0])-nX2,2)+pow(double(P[n][1])-nY2,2)+pow(double(P[n][2])-nZ2,2)); nearestDistances[n] = ((dist1 + dist2)/2) / detail; } delete NN; free(P); } class My_RifPlugin : public RifPlugin { public: My_RifPlugin(); virtual ~My_RifPlugin(); virtual RifFilter & GetFilter(); private: RifFilter m_rifFilter; static RtVoid myPointsV(RtInt nverts, RtInt, RtToken[], RtPointer[]); }; RifPlugin * RifPluginManufacture(int args, char **argv) { return new My_RifPlugin(); } My_RifPlugin::My_RifPlugin() { m_rifFilter.PointsV = myPointsV; } My_RifPlugin::~My_RifPlugin() { } RifFilter & My_RifPlugin::GetFilter() { return m_rifFilter; } RtVoid freestrings(RtString *twostrings) { free((void *)twostrings[0]); free((void *)twostrings[1]); free((void *)twostrings); } RtVoid My_RifPlugin::myPointsV(RtInt nverts, RtInt numOfParam, RtToken* paramNames, RtPointer* paramValues){ if(numOfParam > 3){ RtPoint *P = (RtPoint*)paramValues[0]; RtFloat *constantwidth = (RtFloat*)paramValues[1]; RtColor *CS = (RtColor*)paramValues[2]; double *nearestDistances = (double*)malloc(sizeof(double)*nverts); setNearestDistances(nverts,P,nearestDistances); int numOfDots = 30; constantwidth[0] = 0.002; for(int n = 0; n < nverts; n++){ float multiPointRadius = nearestDistances[n]*4; float px = P[n][0]; float py = P[n][1]; float pz = P[n][2]; float r = CS[n][0]; float g = CS[n][1]; float b = CS[n][2]; if(r > 1 || g > 1 || b >1 ){ cout << r << " / "<< g <<" / " <> r; } char buffer[256]; sprintf(buffer,"%f %d %d %f %f %f %f %f %f %f", multiPointRadius,numOfDots,n,constantwidth[0],px,py,pz,r,g,b); RtBound myBound = {px-multiPointRadius,px+multiPointRadius ,py-multiPointRadius,py+multiPointRadius ,pz-multiPointRadius,pz+multiPointRadius}; //http://www.dotcsw.com/doc/procedurals.html RtString *twostrings = (RtString *)malloc(2 * sizeof(RtString)); twostrings[0] = strdup("/home/hchang21/Desktop/SFDM-PROJECT/VSFX/caveman/sam/dots/dots.so"); twostrings[1] = strdup(buffer); RiProcedural (twostrings,myBound,RiProcDynamicLoad,(RtProcFreeFunc)freestrings); } free(nearestDistances); }else{ RiPointsV(nverts,numOfParam,paramNames, paramValues); } }