void MeshGeometry::createCubeFaces(FaceGeometry& topFace, FaceGeometry& frontFace, FaceGeometry& leftFace,
                                   FaceGeometry& backFace, FaceGeometry& rightFace, FaceGeometry& bottomFace,
                                   tgt::vec3 coordLlf, tgt::vec3 coordUrb, tgt::vec3 texLlf,
                                   tgt::vec3 texUrb, tgt::vec3 colorLlf, tgt::vec3 colorUrb, float alpha)
{
    // expecting coordLlf < coordUrb
    if (coordLlf.x > coordUrb.x) {
        std::swap(coordLlf.x, coordUrb.x);
        std::swap(texLlf.x, texUrb.x);
        std::swap(colorLlf.x, colorUrb.x);
    }
    if (coordLlf.y > coordUrb.y) {
        std::swap(coordLlf.y, coordUrb.y);
        std::swap(texLlf.y, texUrb.y);
        std::swap(colorLlf.y, colorUrb.y);
    }
    if (coordLlf.z > coordUrb.z) {
        std::swap(coordLlf.z, coordUrb.z);
        std::swap(texLlf.z, texUrb.z);
        std::swap(colorLlf.z, colorUrb.z);
    }

    VertexGeometry llf(vec3(coordLlf.x, coordLlf.y, coordLlf.z), vec3(texLlf.x, texLlf.y, texLlf.z), vec4(colorLlf.x, colorLlf.y, colorLlf.z, alpha));
    VertexGeometry lrf(vec3(coordUrb.x, coordLlf.y, coordLlf.z), vec3(texUrb.x, texLlf.y, texLlf.z), vec4(colorUrb.x, colorLlf.y, colorLlf.z, alpha));
    VertexGeometry lrb(vec3(coordUrb.x, coordLlf.y, coordUrb.z), vec3(texUrb.x, texLlf.y, texUrb.z), vec4(colorUrb.x, colorLlf.y, colorUrb.z, alpha));
    VertexGeometry llb(vec3(coordLlf.x, coordLlf.y, coordUrb.z), vec3(texLlf.x, texLlf.y, texUrb.z), vec4(colorLlf.x, colorLlf.y, colorUrb.z, alpha));

    VertexGeometry ulb(vec3(coordLlf.x, coordUrb.y, coordUrb.z), vec3(texLlf.x, texUrb.y, texUrb.z), vec4(colorLlf.x, colorUrb.y, colorUrb.z, alpha));
    VertexGeometry ulf(vec3(coordLlf.x, coordUrb.y, coordLlf.z), vec3(texLlf.x, texUrb.y, texLlf.z), vec4(colorLlf.x, colorUrb.y, colorLlf.z, alpha));
    VertexGeometry urf(vec3(coordUrb.x, coordUrb.y, coordLlf.z), vec3(texUrb.x, texUrb.y, texLlf.z), vec4(colorUrb.x, colorUrb.y, colorLlf.z, alpha));
    VertexGeometry urb(vec3(coordUrb.x, coordUrb.y, coordUrb.z), vec3(texUrb.x, texUrb.y, texUrb.z), vec4(colorUrb.x, colorUrb.y, colorUrb.z, alpha));

    topFace.addVertex(urb);
    topFace.addVertex(urf);
    topFace.addVertex(ulf);
    topFace.addVertex(ulb);

    frontFace.addVertex(llf);
    frontFace.addVertex(ulf);
    frontFace.addVertex(urf);
    frontFace.addVertex(lrf);

    leftFace.addVertex(llf);
    leftFace.addVertex(llb);
    leftFace.addVertex(ulb);
    leftFace.addVertex(ulf);

    backFace.addVertex(urb);
    backFace.addVertex(ulb);
    backFace.addVertex(llb);
    backFace.addVertex(lrb);

    rightFace.addVertex(urb);
    rightFace.addVertex(lrb);
    rightFace.addVertex(lrf);
    rightFace.addVertex(urf);

    bottomFace.addVertex(llf);
    bottomFace.addVertex(lrf);
    bottomFace.addVertex(lrb);
    bottomFace.addVertex(llb);
}
LinePrimitive::LinePrimitive(const LidarOctree* octree,const Vector& translation,Cluster::MulticastPipe* pipe)
	{
	/* Create a LiDAR line extractor: */
	LidarLineExtractor lle;
	
	/* Process all selected points: */
	octree->processSelectedPoints(lle);
	
	if(lle.getNumPoints()>=2)
		{
		/* Extract the line's coordinate frame: */
		LidarLineExtractor::Point centroid;
		LidarLineExtractor::Vector laxis;
		lle.calcLine(centroid,laxis);
		
		/* Calculate the bounding interval of the selected points in line coordinates: */
		LidarLineFitter llf(centroid,laxis);
		octree->processSelectedPoints(llf);
		double min=llf.getMin();
		double max=llf.getMax();
		double size=max-min;
		min-=0.1*size;
		max+=0.1*size;
		
		/* Store the number of points and the RMS residual: */
		numPoints=lle.getNumPoints();
		rms=llf.getRMS();
		
		/* Store the line: */
		laxis.normalize();
		center=Point(centroid+laxis*Math::mid(min,max));
		axis=Vector(laxis);
		length=Scalar(max-min);
		
		/* Print the line's equation: */
		std::cout<<"Line fitting "<<numPoints<<" points"<<std::endl;
		Point tCenter=center;
		tCenter+=translation;
		std::cout<<"Center point: ("<<tCenter[0]<<", "<<tCenter[1]<<", "<<tCenter[2]<<")"<<std::endl;
		std::cout<<"Axis direction: ("<<axis[0]<<", "<<axis[1]<<", "<<axis[2]<<")"<<std::endl;
		std::cout<<"Length: "<<length<<std::endl;
		std::cout<<"RMS approximation residual: "<<rms<<std::endl;
		
		if(pipe!=0)
			{
			/* Send the extracted primitive over the pipe: */
			pipe->write<int>(1);
			pipe->write<unsigned int>((unsigned int)(numPoints));
			pipe->write<Scalar>(rms);
			pipe->write<Scalar>(center.getComponents(),3);
			pipe->write<Scalar>(axis.getComponents(),3);
			pipe->write<Scalar>(length);
			pipe->flush();
			}
		}
	else
		{
		if(pipe!=0)
			{
			pipe->write<int>(0);
			pipe->flush();
			}
		Misc::throwStdErr("LinePrimitive::LinePrimitive: Not enough selected points");
		}
	}