int main(int argc, char **argv) { int done; char units[16], fname[80]; int optc; while ( (optc = bu_getopt( argc, argv, "tsmnc" )) != -1) { switch ( optc ) /* Set joint type and cable option */ { case 't': torus = 1; break; case 's': sphere = 1; break; case 'm': mitre = 1; break; case 'n': nothing = 1; break; case 'c': cable = 1; break; case '?': fprintf( stderr, "Illegal option %c\n", optc ); Usage(); return 1; break; } } if ( (torus + sphere + mitre + nothing) > 1 ) /* Too many joint options */ { Usage(); fprintf( stderr, "Options t, s, m, n are mutually exclusive\n" ); return 1; } else if ( (torus + sphere + mitre + nothing) == 0 ) { torus = 1; /* default */ } if ( (argc - bu_optind) != 2 ) { Usage(); return 1; } bu_strlcpy( name, argv[bu_optind++], sizeof(name) ); /* Base name for objects */ fdout = wdb_fopen( argv[bu_optind] ); if ( fdout == NULL ) { fprintf( stderr, "Cannot open %s\n", argv[bu_optind] ); perror( "Pipe" ); Usage(); return 1; } MAT_IDN(identity); /* Identity matrix for all objects */ pi = atan2( 0.0, -1.0 ); /* PI */ printf( "FLUID & PIPING V%d.%d 10 Mar 89\n\n", VERSION, RELEASE ); printf( "append %s to your target description using 'concat' in mged\n", argv[bu_optind] ); k = 0.0; while ( k == 0.0 ) { printf( "UNITS? (ft, in, m, cm, default is millimeters) "); bu_fgets(units, sizeof(units), stdin); switch (units[0]) { case '\0': k = 1.0; break; case 'f': k = 12*25.4; break; case 'i': k=25.4; break; case 'm': if ( units[1] == '\0') k=1000.0; else k=1.0; break; case 'c': k=10.0; break; default: k=0.0; printf( "\n\t%s is not a legal choice for units\n", units ); printf( "\tTry again\n" ); break; } } done = 0; while ( !done ) { if ( !cable ) { printf( "radius and wall thickness: "); if (scanf("%lf %lf", &radius, &wall) == EOF ) return 1; if (radius > wall) done = 1; else { printf( " *** bad input!\n\n"); printf( "\tradius must be larger than wall thickness\n" ); printf( "\tTry again\n" ); } } else { printf( "radius: "); if ( scanf("%lf", &radius ) == EOF ) return 1; done=1; } } radius=k*radius; wall=k*wall; Readpoints(); /* Read data points */ Names(); /* Construct names for all solids */ Normals(); /* Calculate normals and other vectors */ Adjust(); /* Adjust points to allow for elbows */ /* Generate Title */ bu_strlcpy(fname, name, sizeof(fname)); if ( !cable ) bu_strlcat(fname, " pipe and fluid", sizeof(fname)); else bu_strlcat(fname, " cable", sizeof(fname)); /* Create ident record */ mk_id(fdout, fname); Pipes(); /* Construct the piping */ Elbows(); /* Construct the elbow sections */ Groups(); /* Make some groups */ return 0; }
void mc::Terrain::LoadHeightMap( const ds::String& Filename ) { int GridQuality = 4; struct HeightPoint { float X, Y, Z; ds::Color Normal; }; struct Vertex3 { float X, Y, Z; }; ds::Size GridSize = Size * GridQuality + GridQuality - 1; int* Map = new int[ GridSize.X * GridSize.Y * 3 ]; for( int i = 0; i < GridSize.X * GridSize.Y * 3; i++ ) Map[ i ] = ds::Math::RandomInt( 0, 1000 ); HeightPoint* Point = new HeightPoint[ GridSize.X * GridSize.Y ]; int It = 0, Index = 0; for( int y = 0; y < GridSize.Y; y++ ) for( int x = 0; x < GridSize.X; x++ ) { Index = ( GridSize.Y * y) + x; Point[ Index ].X = ( float )x;// * HEX_A / GridQuality - HEX_A / 2; Point[ Index ].Y = ( float )y;// * HEX_B / GridQuality - HEX_B / 2; Point[ Index ].Z = ( float )Map[ It ]; It += 3; } int Iter[ 4 ], Count; Vertex3 Vert[ 3 ], Vector[ 2 ], Sum; float Len; Index = 0; std::vector< Vertex3 > Normals( ( GridSize.X - 1 ) * ( GridSize.Y - 1 ) ); for(int y = 0; y < ( GridSize.Y - 1 ); y++ ) { for( int x = 0; x < ( GridSize.X - 1 ); x++ ) { Iter[ 1 ] = (y * GridSize.Y) + x; Iter[ 2 ] = (y * GridSize.Y) + (x+1); Iter[ 3 ] = ((y+1) * GridSize.Y) + x; // Get three vertices from the face. Vert[ 0 ].X = Point[Iter[ 1 ]].X; Vert[ 0 ].Y = Point[Iter[ 1 ]].Y; Vert[ 0 ].Z = Point[Iter[ 1 ]].Z; Vert[ 1 ].X = Point[Iter[ 2 ]].X; Vert[ 1 ].Y = Point[Iter[ 2 ]].Y; Vert[ 1 ].Z = Point[Iter[ 2 ]].Z; Vert[ 2 ].X = Point[Iter[ 3 ]].X; Vert[ 2 ].Y = Point[Iter[ 3 ]].Y; Vert[ 2 ].Z = Point[Iter[ 3 ]].Z; // Calculate the two vectors for this face. Vector[ 0 ].X = Vert[ 0 ].X - Vert[ 2 ].X; Vector[ 0 ].Y = Vert[ 0 ].Y - Vert[ 2 ].Y; Vector[ 0 ].Z = Vert[ 0 ].Z - Vert[ 2 ].Z; Vector[ 1 ].X = Vert[ 2 ].X - Vert[ 1 ].X; Vector[ 1 ].Y = Vert[ 2 ].Y - Vert[ 1 ].Y; Vector[ 1 ].Z = Vert[ 2 ].Z - Vert[ 1 ].Z; Index = (y * (GridSize.Y-1)) + x; // Calculate the cross product of those two vectors to get the un-normalized value for this face normal. Normals[Index].X = (Vector[ 0 ].Y * Vector[ 1 ].Z) - (Vector[ 0 ].Z * Vector[ 1 ].Y); Normals[Index].Y = (Vector[ 0 ].Z * Vector[ 1 ].X) - (Vector[ 0 ].X * Vector[ 1 ].Z); Normals[Index].Z = (Vector[ 0 ].X * Vector[ 1 ].Y) - (Vector[ 0 ].Y * Vector[ 1 ].X); } } // Now go through all the vertices and take an average of each face normal // that the vertex touches to get the averaged normal for that vertex. for(int y=0; y<GridSize.Y; y++) { for(int x=0; x<GridSize.X; x++) { // Initialize the sum. Sum.X = 0.0f; Sum.Y = 0.0f; Sum.Z = 0.0f; // Initialize the count. Count = 0; // Bottom left face. if(((x-1) >= 0) && ((y-1) >= 0)) { Index = ((y-1) * (GridSize.Y-1)) + (x-1); Sum.X += Normals[Index].X; Sum.Y += Normals[Index].Y; Sum.Z += Normals[Index].Z; Count++; } // Bottom right face. if((x < (GridSize.X-1)) && ((y-1) >= 0)) { Index = ((y-1) * (GridSize.Y-1)) + x; Sum.X += Normals[Index].X; Sum.Y += Normals[Index].Y; Sum.Z += Normals[Index].Z; Count++; } // Upper left face. if(((x-1) >= 0) && (y < (GridSize.Y-1))) { Index = (y * (GridSize.Y-1)) + (x-1); Sum.X += Normals[Index].X; Sum.Y += Normals[Index].Y; Sum.Z += Normals[Index].Z; Count++; } // Upper right face. if((x < (GridSize.X-1)) && (y < (GridSize.Y-1))) { Index = (y * (GridSize.Y-1)) + x; Sum.X += Normals[Index].X; Sum.Y += Normals[Index].Y; Sum.Z += Normals[Index].Z; Count++; } // Take the average of the faces touching this vertex. Sum.X = (Sum.X / (float)Count); Sum.Y = (Sum.Y / (float)Count); Sum.Z = (Sum.Z / (float)Count); // Calculate the length of this normal. Len = sqrt((Sum.X * Sum.X) + (Sum.Y * Sum.Y) + (Sum.Z * Sum.Z)); // Get an Index to the vertex location in the height map array. Index = (y * GridSize.Y) + x; // Normalize the final shared normal for this vertex and store it in the height map array. Point[Index].Normal.R = (Sum.X / Len); Point[Index].Normal.G = (Sum.Y / Len); Point[Index].Normal.B = (Sum.Z / Len); } } VertexArray = mc::Terrain::Array( ( GridSize.X - 1 ) * ( GridSize.Y - 1 ) * 6 ); IndexArray = ds::IndexArray( VertexArray.size( ) ); Index = 0; ds::Color Color = ds::Color( 100, 0, 0 ); mc::Terrain::Vertex* Vertex = &VertexArray[ 0 ]; for( int y = 0; y < GridSize.Y - 1; y++ ) { for( int x = 0; x < GridSize.X - 1; x++ ) { Iter[ 0 ] = ( GridSize.Y * y ) + x; // Bottom left. Iter[ 1 ] = ( GridSize.Y * y ) + ( x + 1 ); // Bottom right. Iter[ 2 ] = ( GridSize.Y * ( y + 1 ) ) + x; // Upper left. Iter[ 3 ] = ( GridSize.Y * ( y + 1 ) ) + ( x + 1 ); // Upper right. // Upper left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 2 ] ].X; Vertex->Y = Point[ Iter[ 2 ] ].Y; Vertex->Z = Point[ Iter[ 2 ] ].Z; Vertex->Color = Point[ Iter [ 2 ] ].Normal; IndexArray[Index] = Index; Index++; // Upper right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 3 ] ].X; Vertex->Y = Point[ Iter[ 3 ] ].Y; Vertex->Z = Point[ Iter[ 3 ] ].Z; Vertex->Color = Point[ Iter [ 3 ] ].Normal; IndexArray[Index] = Index; Index++; /*// Upper right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 3 ] ].X; Vertex->Y = Point[ Iter[ 3 ] ].Y; Vertex->Z = Point[ Iter[ 3 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++;*/ // Bottom left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 0 ] ].X; Vertex->Y = Point[ Iter[ 0 ] ].Y; Vertex->Z = Point[ Iter[ 0 ] ].Z; Vertex->Color = Point[ Iter [ 0 ] ].Normal; IndexArray[Index] = Index; Index++; // Bottom left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 0 ] ].X; Vertex->Y = Point[ Iter[ 0 ] ].Y; Vertex->Z = Point[ Iter[ 0 ] ].Z; Vertex->Color = Point[ Iter [ 0 ] ].Normal; IndexArray[Index] = Index; Index++; /*// Upper left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 2 ] ].X; Vertex->Y = Point[ Iter[ 2 ] ].Y; Vertex->Z = Point[ Iter[ 2 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++; // Bottom left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 0 ] ].X; Vertex->Y = Point[ Iter[ 0 ] ].Y; Vertex->Z = Point[ Iter[ 0 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++; // Upper right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 3 ] ].X; Vertex->Y = Point[ Iter[ 3 ] ].Y; Vertex->Z = Point[ Iter[ 3 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++; */ // Upper right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 3 ] ].X; Vertex->Y = Point[ Iter[ 3 ] ].Y; Vertex->Z = Point[ Iter[ 3 ] ].Z; Vertex->Color = Point[ Iter [ 3 ] ].Normal; IndexArray[Index] = Index; Index++; // Bottom right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 1 ] ].X; Vertex->Y = Point[ Iter[ 1 ] ].Y; Vertex->Z = Point[ Iter[ 1 ] ].Z; Vertex->Color = Point[ Iter [ 1 ] ].Normal; IndexArray[Index] = Index; Index++; /*// Bottom right. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 1 ] ].X; Vertex->Y = Point[ Iter[ 1 ] ].Y; Vertex->Z = Point[ Iter[ 1 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++; // Bottom left. Vertex = &VertexArray[ Index ]; Vertex->X = Point[ Iter[ 0 ] ].X; Vertex->Y = Point[ Iter[ 0 ] ].Y; Vertex->Z = Point[ Iter[ 0 ] ].Z; Vertex->Color = Color; IndexArray[Index] = Index; Index++;*/ } } VertexBuffer.Create< mc::Terrain::Vertex >( VertexArray ); IndexBuffer.Create( IndexArray ); }
void PhotometricStereo::execute() { /* measuring ps performance */ long start = getMilliSecs(); /* creating OpenCL buffers */ size_t imgSize3 = sizeof(float) * (height*width*3); size_t gradSize = sizeof(float) * (height*width); size_t sSize = sizeof(float) * (lightSrcsInv.rows*lightSrcsInv.cols*lightSrcsInv.channels()); cl::ImageFormat imgFormat = cl::ImageFormat(CL_INTENSITY, CL_UNORM_INT8); cl_img1 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img2 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img3 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img4 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img5 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img6 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img7 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_img8 = cl::Image2D(context, CL_MEM_READ_ONLY, imgFormat, width, height, 0, NULL, &error); cl_Sinv = cl::Buffer(context, CL_MEM_READ_ONLY, sSize, NULL, &error); cl_Pgrads = cl::Buffer(context, CL_MEM_WRITE_ONLY, gradSize, NULL, &error); cl_Qgrads = cl::Buffer(context, CL_MEM_WRITE_ONLY, gradSize, NULL, &error); cl_N = cl::Buffer(context, CL_MEM_WRITE_ONLY, imgSize3, NULL, &error); /* pushing data to CPU */ cv::Mat Normals(height, width, CV_32FC3, cv::Scalar::all(0)); cv::Mat Pgrads(height, width, CV_32F, cv::Scalar::all(0)); cv::Mat Qgrads(height, width, CV_32F, cv::Scalar::all(0)); cl::size_t<3> origin; origin[0] = 0; origin[1] = 0; origin[2] = 0; cl::size_t<3> region; region[0] = width; region[1] = height; region[2] = 1; mutex.lock(); queue.enqueueWriteImage(cl_img1, CL_TRUE, origin, region, 0, 0, psImages.at(0).data); queue.enqueueWriteImage(cl_img2, CL_TRUE, origin, region, 0, 0, psImages.at(1).data); queue.enqueueWriteImage(cl_img3, CL_TRUE, origin, region, 0, 0, psImages.at(2).data); queue.enqueueWriteImage(cl_img4, CL_TRUE, origin, region, 0, 0, psImages.at(3).data); queue.enqueueWriteImage(cl_img5, CL_TRUE, origin, region, 0, 0, psImages.at(4).data); queue.enqueueWriteImage(cl_img6, CL_TRUE, origin, region, 0, 0, psImages.at(5).data); queue.enqueueWriteImage(cl_img7, CL_TRUE, origin, region, 0, 0, psImages.at(6).data); queue.enqueueWriteImage(cl_img8, CL_TRUE, origin, region, 0, 0, psImages.at(7).data); mutex.unlock(); queue.enqueueWriteBuffer(cl_Sinv, CL_TRUE, 0, sSize, lightSrcsInv.data, NULL, &event); queue.enqueueWriteBuffer(cl_Pgrads, CL_TRUE, 0, gradSize, Pgrads.data, NULL, &event); queue.enqueueWriteBuffer(cl_Qgrads, CL_TRUE, 0, gradSize, Qgrads.data, NULL, &event); queue.enqueueWriteBuffer(cl_N, CL_TRUE, 0, imgSize3, Normals.data, NULL, &event); /* set kernel arguments */ calcNormKernel.setArg(0, cl_img1); // 1-8 images calcNormKernel.setArg(1, cl_img2); calcNormKernel.setArg(2, cl_img3); calcNormKernel.setArg(3, cl_img4); calcNormKernel.setArg(4, cl_img5); calcNormKernel.setArg(5, cl_img6); calcNormKernel.setArg(6, cl_img7); calcNormKernel.setArg(7, cl_img8); calcNormKernel.setArg(8, width); // required for.. calcNormKernel.setArg(9, height); // ..determining array dimensions calcNormKernel.setArg(10, cl_Sinv); // inverse of light matrix calcNormKernel.setArg(11, cl_Pgrads); // P gradients calcNormKernel.setArg(12, cl_Qgrads); // Q gradients calcNormKernel.setArg(13, cl_N); // normals for each point calcNormKernel.setArg(14, maxpq); // max depth gradients as in [Wei2001] calcNormKernel.setArg(15, minIntensity); // exaggerate slope as in [Malzbender2006] /* wait for command queue to finish before continuing */ queue.finish(); /* executing kernel */ queue.enqueueNDRangeKernel(calcNormKernel, cl::NullRange, cl::NDRange(height, width), cl::NullRange, NULL, &event); queue.finish(); /* reading back from CPU device */ queue.enqueueReadBuffer(cl_Pgrads, CL_TRUE, 0, gradSize, Pgrads.data); queue.enqueueReadBuffer(cl_Qgrads, CL_TRUE, 0, gradSize, Qgrads.data); queue.enqueueReadBuffer(cl_N, CL_TRUE, 0, sizeof(float) * (height*width*3), Normals.data); /* integrate and get heights globally */ cv::Mat Zcoords = getGlobalHeights(Pgrads, Qgrads); /* pushing normals to CPU again */ cl_N = cl::Buffer(context, CL_MEM_READ_WRITE, imgSize3, NULL, &error); queue.enqueueWriteBuffer(cl_N, CL_TRUE, 0, imgSize3, Normals.data); /* unsharp masking as in [Malzbender2006] */ updateNormKernel.setArg(0, cl_N); updateNormKernel.setArg(1, width); updateNormKernel.setArg(2, height); updateNormKernel.setArg(3, cl_Pgrads); updateNormKernel.setArg(4, cl_Qgrads); updateNormKernel.setArg(5, unsharpScaleFactor); /* executing kernel updating normals */ queue.enqueueNDRangeKernel(updateNormKernel, cl::NullRange, cl::NDRange(height, width), cl::NullRange, NULL, &event); queue.finish(); /* reading back from CPU device */ queue.enqueueReadBuffer(cl_Pgrads, CL_TRUE, 0, gradSize, Pgrads.data); queue.enqueueReadBuffer(cl_Qgrads, CL_TRUE, 0, gradSize, Qgrads.data); queue.enqueueReadBuffer(cl_N, CL_TRUE, 0, imgSize3, Normals.data); /* integrate updated gradients second time */ Zcoords = getGlobalHeights(Pgrads, Qgrads); /* store 3d data and normals tensor-like */ std::vector<cv::Mat> matVec; matVec.push_back(XCoords); matVec.push_back(YCoords); matVec.push_back(Zcoords); matVec.push_back(Normals); emit executionTime("Elapsed time: " + QString::number(getMilliSecs() - start) + " ms."); emit modelFinished(matVec); }