以二进制模式打印到STL(立体光刻)文件

时间:2013-08-20 03:34:52

标签: c++ visual-c++ 3d

我正在尝试打印到stl文件,无法正确打印。 在C ++中有很多用于Hex格式打印的样本,但没有用于二进制格式的示例程序。我的计划如下。我的计划有什么问题?

       string name = "Create by stlwrite.m ";
       name = name + currentDateTime();
       pFile.setf(ios::left);
       pFile.width(sizeof(unsigned char)*80);
       //header
       pFile << name;      
       unsigned int size = faces.rows;
       //size
       pFile.write((char*)&size,sizeof(size));    
       int height = 25;
       unsigned short ** data= new unsigned short *[height];
       for(int i = 0; i < height; i++)
       {
           data[i] = new unsigned short[142000];
       }
       for(int j = 0; j < 142000; j++)
       {
               int i = 0; 

               //for one facets
               for(int k = 0; k < (*facets[j]).cols; k++)
               {
                   for(int l = 0; l < (*facets[j]).rows; l++)
                   {
                       float f = (*facets[j]).at<float>(l,k);
                       data[i][j] = *reinterpret_cast<unsigned int *>(&f);
                       data[i+1][j] = *reinterpret_cast<unsigned int *>(&f)>>16;                     
                       i = i + 2;
                   }

               }

           //then for the last row
           data[height-1][j] = (unsigned short)0;
       }

       for (int i = 0; i < height; i++)
         for (int j = 0; j < faces.rows; j++)
            pFile.write ((char*)&data[i][j], sizeof(unsigned short) );
       pFile.close();

EDIT1:我遵循Matlab stlwrite.mat程序的想法。link

1 个答案:

答案 0 :(得分:0)

这是以二进制模式打印的C代码。 调用函数是:

    stl_write_binary(X, Y, path)

其中X是3xM顶点矩阵,Y是3xN面向矩阵。两者都在OpenCV的Mat结构中 Path是存储STL文件的路径,您可以根据需要对其进行修改 整个代码是:

int stl_write_binary(Mat &vertemp, Mat &faces, PathToFolders &path)
{
    Mat vertices(vertemp.cols,vertemp.rows,vertemp.type());
    vertices = vertemp.t();
    cv::Mat** facets = new cv::Mat*[faces.rows];    
    for(int i = 0; i < faces.rows; i++)
    {
        facets[i] = new cv::Mat(3,4,CV_32F);

        for(int j = 0; j < 3; j++)
        {
            vertices(Range::all(),Range(faces.at<int>(i,j),faces.at<int>(i,j)+1)).convertTo((*(facets[i]))(Range::all(),Range(j+1,j+2)), CV_32F);

        }   
    }
    //Compute their normals
    Mat V1(3,faces.rows,CV_32F);
    Mat V2(3,faces.rows,CV_32F);
    for(int i = 0; i < faces.rows; i++)
    {
        V1(Range::all(),Range(i,i+1)) = ((*(facets[i]))(Range::all(),Range(2,3))) - ((*(facets[i]))(Range::all(),Range(1,2)));
        V2(Range::all(),Range(i,i+1)) = ((*(facets[i]))(Range::all(),Range(3,4))) - ((*(facets[i]))(Range::all(),Range(1,2)));
    }    
    Mat V3(3,faces.rows,CV_32F);
    Mat V4(3,faces.rows,CV_32F);
    Mat V5(3,faces.rows,CV_32F);
    Mat V6(3,faces.rows,CV_32F);
    V1(Range(1,2),Range::all()).copyTo(V3(Range(0,1),Range::all()));
    V1(Range(2,3),Range::all()).copyTo(V3(Range(1,2),Range::all()));
    V1(Range(0,1),Range::all()).copyTo(V3(Range(2,3),Range::all()));

    V2(Range(2,3),Range::all()).copyTo(V4(Range(0,1),Range::all()));
    V2(Range(0,1),Range::all()).copyTo(V4(Range(1,2),Range::all()));
    V2(Range(1,2),Range::all()).copyTo(V4(Range(2,3),Range::all()));

    V2(Range(1,2),Range::all()).copyTo(V5(Range(0,1),Range::all()));
    V2(Range(2,3),Range::all()).copyTo(V5(Range(1,2),Range::all()));
    V2(Range(0,1),Range::all()).copyTo(V5(Range(2,3),Range::all()));

    V1(Range(2,3),Range::all()).copyTo(V6(Range(0,1),Range::all()));
    V1(Range(0,1),Range::all()).copyTo(V6(Range(1,2),Range::all()));
    V1(Range(1,2),Range::all()).copyTo(V6(Range(2,3),Range::all()));

    Mat normals(3,faces.rows,CV_32F);
    normals = V3.mul(V4) - V5.mul(V6);

    V1.release();
    V2.release();
    V3.release();
    V4.release();
    V5.release();
    V6.release();

    Mat normalsqu(3,faces.rows,CV_32F);
    Mat normalsqu_colm_summed(1,faces.rows,CV_32F);
    normalsqu = normals.mul(normals);

    cv::reduce(normalsqu, normalsqu_colm_summed, 0, CV_REDUCE_SUM, CV_32F);
    cv::sqrt(normalsqu_colm_summed,normalsqu_colm_summed);//check mem leak
    normalsqu.release();
    normalsqu_colm_summed = 1/normalsqu_colm_summed;

    for(int i = 0; i < faces.rows; i++)
    {
        normals(Range::all(),Range(i,i+1)) = normals(Range::all(),Range(i,i+1)) * normalsqu_colm_summed.at<float>(i);
    }

    normalsqu_colm_summed.release();
    for(int i = 0; i < faces.rows; i++)
    {
        normals(Range::all(),Range(i,i+1)).copyTo(((*(facets[i]))(Range::all(),Range(0,1))));

    }
    normals.release();
    //write to stl file
    //get file paths
    std::vector<std::string> masktoken;
    split(path.pathtoimages, '/', masktoken);
    path.pathtoSTL = path.pathtoSTL+masktoken[0];
    for(int i = 1; i < masktoken.size()-1; i++)
    {
        path.pathtoSTL = path.pathtoSTL+"/"+masktoken[i];
    }
    path.pathtoSTL = path.pathtoSTL+"/"+"mesh.stl";
    cout<<"Saving file to "<<path.pathtoSTL<<endl;
    const char * c = path.pathtoSTL.c_str();
    ofstream pFile;
    pFile.open (c, ios::out | ios::binary); 
    if (pFile.is_open())
    {
       string name = "Create by stlwrite.m ";
       name = name + currentDateTime();
       pFile.setf(ios::left);
       pFile.width(sizeof(unsigned char)*80);
       //header
       pFile << name;      
       unsigned int size = faces.rows;
       //size
       pFile.write((char*)&size,sizeof(size));    
       int height = (*facets[0]).rows * (*facets[0]).cols * 2 + 1;
       unsigned short ** data= new unsigned short *[height];
       for(int i = 0; i < height; i++)
       {
           data[i] = new unsigned short[faces.rows];
       }
       for(int j = 0; j < faces.rows; j++)
       {
               int i = 0; 

               //for one facets
               for(int k = 0; k < (*facets[j]).cols; k++)
               {
                   for(int l = 0; l < (*facets[j]).rows; l++)
                   {
                       float f = (*facets[j]).at<float>(l,k);
                       data[i][j] = *reinterpret_cast<unsigned int *>(&f);
                       data[i+1][j] = *reinterpret_cast<unsigned int *>(&f)>>16;                     
                       i = i + 2;
                   }

               }

           //then for the last row
           data[height-1][j] = (unsigned short)0;
       }

       for (int i = 0; i < faces.rows; i++)
         for (int j = 0; j < height; j++)
            pFile.write ((char*)&data[j][i], sizeof(unsigned short) );
       pFile.close();
       //fclose (pFile);
       //delete table
       for(int i = 0; i < height; i++)
       {
           delete[] data[i];
       }
       delete[] data;
    }else{
        cout<<"stlwrite:cannotWriteFile"<<" "<<"Unable to write to"<<" "<<path.pathtoSTL<<endl;
    }
    for(int i = 0; i < faces.rows; i++)
    {
        (*facets[i]).release();
    }
    delete[] facets;

    return 1;
}