//HEADER: CurveExpand //customFunctions float clampAngle(float inputAngle){ float x = inputAngle/3.14159265; x=x%2; if(x>1){ x=-1+(x%1); } if(x<-1){ x=1+(x%1); } x = x*3.14159265; return x; } void mergeArray(int array1[];int array2[]){ foreach(int a2; array2){ if(find(array1,a2)<0){ push(array1, a2); } } } float angleBetweenVectors2(vector a; vector b){ a = normalize(a*{1,0,1}); b = normalize(b*{1,0,1}); vector c = normalize(a+b); float result = atan2(c[2],c[0]); return(result); } float sideCheckXZ(vector s; vector e; vector p){ //+=left float result = (e[0]-s[0])*(p[2]-s[2]) - (e[2]-s[2])*(p[0]-s[0]); return result; } void Specialdecode1(int i; string S_input; int output[]){ output = {}; string L[] = split(S_input,"L"); if(i>len(L)-1){output = {-1};} string splits[] = split(L[i],","); //encode to integer array foreach(string s; splits){ push(output, atoi(s)); } } string ftoa(float in){ return sprintf("%.10f", in); } void addIntegerToStringSet(int i; string Set){ int intarray[]; string splits[] = split(Set, ","); foreach(string s; splits){ int convert = atoi(s); push(intarray,convert); } if(find(intarray,i)<0){ if(Set[-1]!=","){Set+=",";} Set+=itoa(i); } } void drawAngle(vector position;float scale; float radians; vector color){ //draw a circle with 10 points. int circle = addprim(0,"polyline"); float total = 36; float pi = 3.141592; for(int points=0;points-1){//IF ADDRESS EXISTS. string LocalSets[] = split(source,"N"); foreach(string local; LocalSets){ if(find(local, S_addresss)>-1){//IF ADDRESS IS IN CURRENT SET. int results[]; string S_nums[] = split(local, ","); foreach(string S_point; S_nums){ int stoi = atoi(S_point); if(stoi!=address){ push(results,stoi); } } outArray = results; return; } } } outArray = {}; return; } //Pntoverlap(originalOverlaps, 908, PNTOVRLAP_RESULT); //printf("npr: %f\\n",PNTOVRLAP_RESULT); //printf("len(npr): %f\\n",len(PNTOVRLAP_RESULT)); //10102019: edited lines 184>185,186; 246>147,248 //neightbourcount modified on 199 and 226 int OVERLAP_PRIM_RESULTS[]; void PRMoverlap(string source; int address; int subresult[]; int outArray[]){ Pntoverlap(source, address, subresult); outArray = pointprims(0,address); foreach(int entry; subresult){ int pntprims[] = pointprims(0,entry); foreach(int pp; pntprims){ push(outArray,pp); } } } //example: PRMoverlap(originalOverlaps, 1508, PNTOVRLAP_RESULT, OVERLAP_PRIM_RESULTS); printf("OVERLAP_PRIM_RESULTS: %f\\n", OVERLAP_PRIM_RESULTS); int loops[]; for(int loopcandidate=0;loopcandidate-1){//if branch is found in pointless if(find(specialIntersections,thisJunction)<0){ push(specialIntersections,thisJunction); } rem[j] += itoa(thisConnectedPrim)+","; //possible error, correct array index? } else{//branch is not pointless reg[j] += itoa(thisConnectedPrim)+","; } } } } // sharesSimple is an array of all pointless prim sets. //2 questions. // 1.does this pointless prim exist in a share? // yes: break. (optimization) // no : next question... // 2. BURN PROCESS. Find all adjacent pointless siblings. and create+assign to new share. string sharesSimple[]; //Pointless primitive sets. EG: "{1,2,8,54","101,102,103"} < pointlessprims that share starts or ends with or more of each other. for(int i=0;i-1){ //if found findResultAllIndices=1; break; } } if(findResultAllIndices==0){//if not found, new entry needed //We will be creating a new share, because all adjacents will be gathered in one go! int newPrims[]; push(newPrims,edge); // < initially only has this edge, records edges/prims that are connected to current. int processedPrims[]; //flag. do not process primitives int processedPoints[]; //flag. do not process points //THIS IS A BURN. We continue until no adjacent (POINTLESS)edges are found int NewEdgesFound =1; while(NewEdgesFound>0){ for(int cp = 0; cp-1&&find(processedPrims, iEdge)<0&&find(newPrims, iEdge)<0){ //if not processed, if not in newprim, and pointless. push(newPrims,iEdge); NewEdgesFound+=1; } } foreach(int eEdge; endEdges){ if(find(pointlessPrims, eEdge)>-1&&find(processedPrims, eEdge)<0&&find(newPrims, eEdge)<0){ //if not processed, if not in newprim, and pointless. push(newPrims,eEdge); NewEdgesFound+=1; } } } } } //convert newPrim integer array to string for storage. string S_newShare = ","; foreach(int p; newPrims){ S_newShare+=itoa(p)+","; } push(sharesSimple,S_newShare); } } //TODO: get sharepoints string sharePrims[]; //for each group of edges, there will be a group of *non removed* edges connected (PRIMS!). string shareDirection[]; //1=out, 0=in // maps to the above. string firstValidPoint[]; //walk edge until first usable point. (POINTS!) foreach(string oneSimpleShare; sharesSimple){ //for each collection of edges/primitives int I_output[]; string output = ","; string directionoutput = ","; string firstValid = ","; int sharePointProcessedPrims[]; //keep track of prims that have been processed. string thisShareSplit[] = split(oneSimpleShare,","); //",4,5," pointless prims. int I_removablePrimitiveInShare[]; foreach(string s; thisShareSplit){ push(I_removablePrimitiveInShare, atoi(s)); } //Get end and start of each split for(int rpis=0;rpis-1){//check if first point exists in junction. foreach(int walkForwardPoint;thisoutputPoints){//walk to first valid point.. if(find(pointsTooClose,walkForwardPoint)<0){//point is not too close. firstValid = firstValid + itoa(walkForwardPoint)+","; directionoutput = directionoutput + "1,"; //now we check to see if the end also belongs to this intersection. if(find(pointlessEnds,tpoint)>-1){//check to see if last point ALSO exists in junction. (loop detection) int reversedPoints[] = reverse(thisoutputPoints); foreach(int walkBackwardsPoint;reversedPoints){//walk reverse to first terminal that is valid if(find(pointsTooClose,walkBackwardsPoint)<0){//if not too close push(extraOutput, thisoutput); push(extraPoints, walkBackwardsPoint); push(extraDirections, 0); break; } } } break; } } } else if(find(pointlessEnds,tpoint)>-1){//else check if last point exists in junction. foreach(int walkBackwardsPoint;reverse(thisoutputPoints)){//walk backwards to first point that is valid. if(find(pointsTooClose,walkBackwardsPoint)<0){//point is not too close. firstValid = firstValid + itoa(walkBackwardsPoint)+","; directionoutput = directionoutput + "0,"; //no need to also check first, we already did. break; } } } //APPEND EXTRAS! } //append extras. foreach(int eO; extraOutput){ output = output + itoa(eO)+","; } foreach(int eP; extraPoints){ firstValid = firstValid + itoa(eP)+ ","; } foreach(int eD; extraDirections){ directionoutput = directionoutput + itoa(eD)+ ","; } push(sharePrims,output); push(firstValidPoint, firstValid); push(shareDirection, directionoutput); } } } //calc new location. vector V_shareLoc[]; foreach(string oneSimpleShare; sharesSimple){ // HAVING A POINT RECORDED MANY TIMES IS ***GOOD***. EMERGENT WEIGHTS. string S_edges[] = split(oneSimpleShare, ","); int I_edges[]; int JunctionPoints[]; foreach(string item; S_edges){ push(I_edges, atoi(item)); } foreach(int edgeindex; I_edges){ int rawpoints[] = primpoints(0,edgeindex); int e0 = rawpoints[0]; int e1 = rawpoints[-1]; push(JunctionPoints,e0); push(JunctionPoints,e1); } vector newLoc = {0,0,0}; //sum position for all points foreach(int point; JunctionPoints){ vector loc = point(0,"P",point); newLoc+=loc; } newLoc = newLoc/len(JunctionPoints); //AVERAGE push(V_shareLoc,newLoc); } //Calculate UV Offset. Will need flow direction for +/- multiplier. //get valid point //get direction //get prim //get beginning or end based on direction //calculate location difference as float offset. //store floats in a string array. //offset source uv happens when we sweep the curve. //offset junction happens when we expand the junction. string offsets[]; // uv offset for first valid point. for(int k=0; k0;a--){ if(find(pointsTooClose,edgepoints[a])<0){//if not too close record. S_FVP+= itoa(edgepoints[a])+","; push(adj,edgepoints[a]); break; } } } } //average adjacencies (adj) points to obtain center. store that center location, and calculate offsets. vector v_adjloc[]; vector v_averageLocation={0,0,0}; foreach(int adjpnt; adj){ vector ploc = point(0,"P",adjpnt); push(v_adjloc, ploc); v_averageLocation+=ploc; } v_averageLocation=v_averageLocation/len(adj); push(V_shareLoc, v_averageLocation); //calculate distances foreach(vector pointlocation; v_adjloc){ S_OFF+= ftoa(distance(v_averageLocation, pointlocation))+","; } push(sharePrims,S_PRM); push(shareDirection,S_DIR); push(firstValidPoint,S_FVP); push(offsets, S_OFF); } } ////////////////////// //SWEEP --LETS DO THIS. int pointleafleaf[]; //each prim contains 6 entries. start,leaf,leaf,end,leaf,leaf. vector V_pUV[]; //each prim contains 2 entries: uvstart,uvend int startingPrimCount = nprimitives(0); for(int sweep=0; sweep-1){ //add beginning index to end of aray? looping = 1; //push(notremoved,notremoved[0]); //push(vert_notremoved,vert_notremoved[0]); } float notRemovedAngles[]; //now we calculate the angles to accompany points that were not removed. for(int angleCalc=0; angleCalc-1){ removepoint(0,index); } } //Create the Junctions. foreach(int index; string junction; firstValidPoint){ vector centroid = V_shareLoc[index]; string S_connectionPoints[] = split(junction,","); int I_connectionPoints[]; foreach(string j; S_connectionPoints){push(I_connectionPoints,atoi(j));} vector V_connectionLocation[]; foreach (int cp;I_connectionPoints){vector loc = point(0,"P",cp); push(V_connectionLocation,loc);} //create integer arrays of direction and offset. string S_dir = shareDirection[index]; int I_dir[]; foreach(string singleDir;split(S_dir,",")){push(I_dir,atoi(singleDir));} string S_off = offsets[index]; float F_offsets[]; foreach(string singleOffset; split(S_off,",") ){push(F_offsets, atof(singleOffset));} //draw an angle to each connection. //drawAngle(centroid+{0,-.01,0},radius, 0.0, {1.0,2.0,0}); float allAngles[]; foreach(vector v; V_connectionLocation){ float dx = v[0]-centroid[0]; float dz = v[2]-centroid[2]; float thisAngle = atan2(dz,dx); //drawAngle(v+{0,-.01,0},0.15,thisAngle,{0,0.2,0.5}); push(allAngles,thisAngle); } //sort the angles. int angsort[] = argsort(allAngles); float sortall[] = reorder(allAngles,angsort); float sortang[] = reorder(allAngles,angsort); int sortcon[] = reorder(I_connectionPoints,angsort); int sortdir[] = reorder(I_dir,angsort); float sortoff[] = reorder(F_offsets,angsort); //printf("angsort: %f\\n",angsort); //printf("sortang: %f\\n",sortang); //printf("sortcon: %f\\n",sortcon); //printf("sortcon+1: %f",sortcon[-1]);//first item in sortcon? float ccbisectors[]; for(int b=0;b