Пример #1
0
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;
}
Пример #2
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);
}