PovTools.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) Jürgen Riegel          (juergen.riegel@web.de) 2005     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include "PreCompiled.h"
00024 
00025 #ifndef _PreComp_
00026 # include <BRep_Tool.hxx>
00027 # include <BRepMesh_IncrementalMesh.hxx>
00028 # include <GeomAPI_ProjectPointOnSurf.hxx>
00029 # include <GeomLProp_SLProps.hxx>
00030 # include <Poly_Triangulation.hxx>
00031 # include <TopExp_Explorer.hxx>
00032 # include <TopoDS.hxx>
00033 # include <TopoDS_Face.hxx>
00034 # include <sstream>
00035 #endif
00036 
00037 #include <Base/Console.h>
00038 #include <Base/Exception.h>
00039 #include <Base/Sequencer.h>
00040 #include <App/ComplexGeoData.h>
00041 
00042 
00043 #include "PovTools.h"
00044 
00045 using Base::Console;
00046 
00047 using namespace Raytracing;
00048 using namespace std;
00049 
00050 #include "PovTools.h"
00051 
00052 //#include "TempCamera.inc"
00053 //camera {
00054 //  location  CamPos
00055 //  look_at   LookAt
00056 //  sky       Up
00057 //  angle     50
00058 //}
00059 
00060 std::string PovTools::getCamera(const CamDef& Cam)
00061 {
00062     std::stringstream out;
00063     out << "// declares positon and view direction\n" << endl
00064         << "// Generated by FreeCAD (http://free-cad.sf.net/)" << endl
00065 
00066         // writing Camera positions
00067         << "#declare cam_location =  <" << Cam.CamPos.X() <<"," << Cam.CamPos.Z() <<"," << Cam.CamPos.Y()<<">;" << endl
00068 
00069         // writing lookat
00070         << "#declare cam_look_at  = <" << Cam.LookAt.X()  <<"," << Cam.LookAt.Z()    <<"," << Cam.LookAt.Y()    <<">;"<< endl
00071 
00072         // writing the Up Vector
00073         << "#declare cam_sky      = <" << Cam.Up.X()  <<"," << Cam.Up.Z()    <<"," << Cam.Up.Y()    <<">;"<< endl
00074 
00075         // array of zoom factors
00076         << "#declare cam_angle    = 50; " << endl
00077         // instance of the camera
00078         << "camera {" << endl
00079         << "  location  cam_location" << endl
00080         << "  look_at   cam_look_at" << endl
00081         << "  sky       cam_sky" << endl
00082         << "  angle     cam_angle " << endl
00083         << "}"<< endl
00084         // default light
00085         << "//default light" << endl
00086         << "light_source {" << endl
00087         << "  cam_location + cam_angle * 100            // light's position" << endl
00088         << "  color rgb <10, 10, 10>  // light's color" << endl
00089         << "}" << endl ;
00090     return out.str();
00091 }
00092 
00093 void PovTools::writeCamera(const char* FileName, const CamDef& Cam)
00094 {
00095     std::vector<CamDef> vCam;
00096     vCam.push_back(Cam);
00097     writeCameraVec(FileName,vCam);
00098 }
00099 
00100 
00101 void PovTools::writeCameraVec(const char* FileName, const std::vector<CamDef>& CamVec)
00102 {
00103     std::stringstream out;
00104     std::vector<CamDef>::const_iterator It;
00105     out << "// declares positon and view directions\n"
00106         << "// Generated by FreeCAD (http://free-cad.sf.net/)\n\n"
00107         << "// Total number of camera positions\n"
00108         << "#declare nCamPos = " << CamVec.size() << ";\n\n";
00109 
00110     // writing Camera positions
00111     out << "// Array of positions\n"
00112         << "#declare  CamPos = array[" << CamVec.size() << "] {\n";
00113     for (It = CamVec.begin(); It != CamVec.end(); It++)
00114         out << "   <" << It->CamPos.X()  <<"," << It->CamPos.Z()    <<"," << It->CamPos.Y()    <<">,\n";
00115     out << "};\n"
00116         // writing Camera Direction vector
00117         << "// Array of Directions (only for special calculations)\n"
00118         << "#declare  CamDir = array[" << CamVec.size() << "] {\n";
00119 
00120     for (It = CamVec.begin(); It != CamVec.end(); It++)
00121         out << "   <" << It->CamDir.X()  <<"," << It->CamDir.Z()    <<"," << It->CamDir.Y()    <<">,\n";
00122     out << "};\n"
00123         // writing lookat
00124         << "// Array of Look At positions\n"
00125         << "#declare  LookAt = array[" << CamVec.size() << "] {\n";
00126 
00127     for (It = CamVec.begin(); It != CamVec.end(); It++)
00128         out << "   <" << It->LookAt.X()  <<"," << It->LookAt.Z()    <<"," << It->LookAt.Y()    <<">,\n";
00129     out << "};\n"
00130         // writing the Up Vector
00131         << "// // Array of up vectors\n"
00132         << "#declare  Up = array[" << CamVec.size() << "] {\n";
00133 
00134     for (It = CamVec.begin(); It != CamVec.end(); It++)
00135         out << "   <" << It->Up.X()  <<"," << It->Up.Z()    <<"," << It->Up.Y()    <<">,\n";
00136     out << "};\n"
00137         // array of zoom factors
00138         << "// // Array of up vectors\n"
00139         << "#declare  CamZoom = array[" << CamVec.size() << "] {\n";
00140 
00141     for (It = CamVec.begin(); It != CamVec.end(); It++)
00142         out << "   50,\n";
00143     out << "};\n";
00144 
00145 
00146     // open the file and write
00147     Base::ofstream fout(FileName);
00148     fout <<  out.str() << endl;
00149     fout.close();
00150 }
00151 
00152 void PovTools::writeData(const char *FileName, const char *PartName,
00153                          const Data::ComplexGeoData* data, float fMeshDeviation)
00154 {
00155     // open the file and write
00156     Base::ofstream fout(FileName);
00157     // write the file
00158     fout <<  "// Written by FreeCAD http://free-cad.sf.net/" << endl;
00159 
00160     unsigned long count = data->countSubElements("Face");
00161     for (unsigned long i=0; i<count; i++) {
00162         std::vector<Base::Vector3d> points;
00163         std::vector<Base::Vector3d> normals;
00164         std::vector<Data::ComplexGeoData::Facet> facets;
00165         Data::Segment* segm = data->getSubElement("Face", i);
00166         data->getFacesFromSubelement(segm, points, normals, facets);
00167         delete segm;
00168 
00169         // writing per face header
00170         fout << "// element number" << i << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00171              << "#declare " << PartName << i << " = mesh2{" << endl
00172              << "  vertex_vectors {" << endl
00173              << "    " << points.size() << "," << endl;
00174 
00175         // writing vertices
00176         for (std::vector<Base::Vector3d>::iterator it = points.begin(); it != points.end(); ++it) {
00177             fout << "    <"
00178                  << it->x << ","
00179                  << it->y << ","
00180                  << it->z << ">,"
00181                  << endl;
00182         }
00183 
00184         // writing per vertex normals
00185         fout << "  }" << endl
00186              << "  normal_vectors {" << endl
00187              << "    " << normals.size() << "," << endl;
00188 
00189         for (std::vector<Base::Vector3d>::iterator it = normals.begin(); it != normals.end(); ++it) {
00190             fout << "    <" 
00191                  << it->x << ","
00192                  << it->y << ","
00193                  << it->z << ">,"
00194                  << endl;
00195         }
00196 
00197         // writing triangle indices
00198         fout << "  }" << endl
00199              << "  face_indices {" << endl
00200              << "    " << facets.size() << "," << endl;
00201         for (std::vector<Data::ComplexGeoData::Facet>::iterator it = facets.begin(); it != facets.end(); ++it) {
00202             fout << "    <" << it->I1 << ","<< it->I3 << ","<< it->I2 << ">," << endl;
00203         }
00204 
00205         // end of face
00206         fout << "  }" << endl
00207              << "} // end of element" << i << endl << endl;
00208     }
00209 
00210     fout << endl << endl << "// Declare all together +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00211          << "#declare " << PartName << " = union {" << endl;
00212     for (unsigned long i=1; i < count; i++) {
00213         fout << "mesh2{ " << PartName << i << "}" << endl;
00214     }
00215     fout << "}" << endl;
00216     fout.close();
00217 }
00218 
00219 void PovTools::writeShape(const char *FileName, const char *PartName,
00220                           const TopoDS_Shape& Shape, float fMeshDeviation)
00221 {
00222     // open the file and write
00223     Base::ofstream fout(FileName);
00224     writeShape(fout,PartName,Shape,fMeshDeviation);
00225     fout.close();
00226 }
00227 
00228 void PovTools::writeShape(std::ostream &out, const char *PartName,
00229                           const TopoDS_Shape& Shape, float fMeshDeviation)
00230 {
00231     Base::Console().Log("Meshing with Deviation: %f\n",fMeshDeviation);
00232 
00233     TopExp_Explorer ex;
00234     BRepMesh_IncrementalMesh MESH(Shape,fMeshDeviation);
00235 
00236 
00237     // counting faces and start sequencer
00238     int l = 1;
00239     for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {}
00240     Base::SequencerLauncher seq("Writing file", l);
00241 
00242     // write the file
00243     out <<  "// Written by FreeCAD http://free-cad.sf.net/" << endl;
00244     l = 1;
00245     for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {
00246 
00247         // get the shape and mesh it
00248         const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
00249 
00250         // this block mesh the face and transfers it in a C array of vertices and face indexes
00251         Standard_Integer nbNodesInFace,nbTriInFace;
00252         gp_Vec* vertices=0;
00253         gp_Vec* vertexnormals=0;
00254         long* cons=0;
00255 
00256         transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace);
00257 
00258         if (!vertices) break;
00259         // writing per face header
00260         out << "// face number" << l << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00261         << "#declare " << PartName << l << " = mesh2{" << endl
00262         << "  vertex_vectors {" << endl
00263         << "    " << nbNodesInFace << "," << endl;
00264         // writing vertices
00265         for (int i=0; i < nbNodesInFace; i++) {
00266             out << "    <" << vertices[i].X() << ","
00267             << vertices[i].Z() << ","
00268             << vertices[i].Y() << ">,"
00269             << endl;
00270         }
00271         out << "  }" << endl
00272         // writing per vertex normals
00273         << "  normal_vectors {" << endl
00274         << "    " << nbNodesInFace << "," << endl;
00275         for (int j=0; j < nbNodesInFace; j++) {
00276             out << "    <" << vertexnormals[j].X() << ","
00277             << vertexnormals[j].Z() << ","
00278             << vertexnormals[j].Y() << ">,"
00279             << endl;
00280         }
00281 
00282         out << "  }" << endl
00283         // writing triangle indices
00284         << "  face_indices {" << endl
00285         << "    " << nbTriInFace << "," << endl;
00286         for (int k=0; k < nbTriInFace; k++) {
00287             out << "    <" << cons[3*k] << ","<< cons[3*k+2] << ","<< cons[3*k+1] << ">," << endl;
00288         }
00289         // end of face
00290         out << "  }" << endl
00291         << "} // end of Face"<< l << endl << endl;
00292 
00293         delete [] vertexnormals;
00294         delete [] vertices;
00295         delete [] cons;
00296 
00297         seq.next();
00298 
00299     } // end of face loop
00300 
00301 
00302     out << endl << endl << "// Declare all together +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00303     << "#declare " << PartName << " = union {" << endl;
00304     for (int i=1; i < l; i++) {
00305         out << "mesh2{ " << PartName << i << "}" << endl;
00306     }
00307     out << "}" << endl;
00308 }
00309 
00310 void PovTools::writeShapeCSV(const char *FileName,
00311                              const TopoDS_Shape& Shape,
00312                              float fMeshDeviation,
00313                              float fLength)
00314 {
00315     const char cSeperator = ',';
00316 
00317     Base::Console().Log("Meshing with Deviation: %f\n",fMeshDeviation);
00318 
00319     TopExp_Explorer ex;
00320     BRepMesh_IncrementalMesh MESH(Shape,fMeshDeviation);
00321 
00322     // open the file and write
00323     std::ofstream fout(FileName);
00324 
00325     // counting faces and start sequencer
00326     int l = 1;
00327     for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {}
00328     Base::SequencerLauncher seq("Writing file", l);
00329 
00330     // write the file
00331     l = 1;
00332     for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {
00333 
00334         // get the shape and mesh it
00335         const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
00336 
00337         // this block mesh the face and transfers it in a C array of vertices and face indexes
00338         Standard_Integer nbNodesInFace,nbTriInFace;
00339         gp_Vec* vertices=0;
00340         gp_Vec* vertexnormals=0;
00341         long* cons=0;
00342 
00343         transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace);
00344 
00345         if (!vertices) break;
00346         // writing per face header
00347         // writing vertices
00348         for (int i=0; i < nbNodesInFace; i++) {
00349             fout << vertices[i].X() << cSeperator
00350             << vertices[i].Z() << cSeperator
00351             << vertices[i].Y() << cSeperator
00352             << vertexnormals[i].X() * fLength <<cSeperator
00353             << vertexnormals[i].Z() * fLength <<cSeperator
00354             << vertexnormals[i].Y() * fLength <<cSeperator
00355             << endl;
00356         }
00357 
00358         delete [] vertexnormals;
00359         delete [] vertices;
00360         delete [] cons;
00361 
00362         seq.next();
00363 
00364     } // end of face loop
00365 
00366     fout.close();
00367 }
00368 
00369 void PovTools::transferToArray(const TopoDS_Face& aFace,gp_Vec** vertices,gp_Vec** vertexnormals, long** cons,int &nbNodesInFace,int &nbTriInFace )
00370 {
00371     TopLoc_Location aLoc;
00372 
00373     // doing the meshing and checking the result
00374     //BRepMesh_IncrementalMesh MESH(aFace,fDeflection);
00375     Handle(Poly_Triangulation) aPoly = BRep_Tool::Triangulation(aFace,aLoc);
00376     if (aPoly.IsNull()) {
00377         Base::Console().Log("Empty face trianglutaion\n");
00378         nbNodesInFace =0;
00379         nbTriInFace = 0;
00380         vertices = 0l;
00381         cons = 0l;
00382         return;
00383     }
00384 
00385     // geting the transformation of the shape/face
00386     gp_Trsf myTransf;
00387     Standard_Boolean identity = true;
00388     if (!aLoc.IsIdentity())  {
00389         identity = false;
00390         myTransf = aLoc.Transformation();
00391     }
00392 
00393     Standard_Integer i;
00394     // geting size and create the array
00395     nbNodesInFace = aPoly->NbNodes();
00396     nbTriInFace = aPoly->NbTriangles();
00397     *vertices = new gp_Vec[nbNodesInFace];
00398     *vertexnormals = new gp_Vec[nbNodesInFace];
00399     for (i=0; i < nbNodesInFace; i++) {
00400         (*vertexnormals)[i]= gp_Vec(0.0,0.0,0.0);
00401     }
00402 
00403     *cons = new long[3*(nbTriInFace)+1];
00404 
00405     // check orientation
00406     TopAbs_Orientation orient = aFace.Orientation();
00407 
00408     // cycling through the poly mesh
00409     const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
00410     const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
00411     for (i=1; i<=nbTriInFace; i++) {
00412         // Get the triangle
00413         Standard_Integer N1,N2,N3;
00414         Triangles(i).Get(N1,N2,N3);
00415 
00416         // change orientation of the triangles
00417         if ( orient != TopAbs_FORWARD )
00418         {
00419             Standard_Integer tmp = N1;
00420             N1 = N2;
00421             N2 = tmp;
00422         }
00423 
00424         gp_Pnt V1 = Nodes(N1);
00425         gp_Pnt V2 = Nodes(N2);
00426         gp_Pnt V3 = Nodes(N3);
00427 
00428         // transform the vertices to the place of the face
00429         if (!identity) {
00430             V1.Transform(myTransf);
00431             V2.Transform(myTransf);
00432             V3.Transform(myTransf);
00433         }
00434 
00435         // Calculate triangle normal
00436         gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z());
00437         gp_Vec Normal = (v2-v1)^(v3-v1);
00438 
00439         //Standard_Real Area = 0.5 * Normal.Magnitude();
00440 
00441         // add the triangle normal to the vertex normal for all points of this triangle
00442         (*vertexnormals)[N1-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
00443         (*vertexnormals)[N2-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
00444         (*vertexnormals)[N3-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z());
00445 
00446         (*vertices)[N1-1].SetX((float)(V1.X()));
00447         (*vertices)[N1-1].SetY((float)(V1.Y()));
00448         (*vertices)[N1-1].SetZ((float)(V1.Z()));
00449         (*vertices)[N2-1].SetX((float)(V2.X()));
00450         (*vertices)[N2-1].SetY((float)(V2.Y()));
00451         (*vertices)[N2-1].SetZ((float)(V2.Z()));
00452         (*vertices)[N3-1].SetX((float)(V3.X()));
00453         (*vertices)[N3-1].SetY((float)(V3.Y()));
00454         (*vertices)[N3-1].SetZ((float)(V3.Z()));
00455 
00456         int j = i - 1;
00457         N1--;
00458         N2--;
00459         N3--;
00460         (*cons)[3*j] = N1;
00461         (*cons)[3*j+1] = N2;
00462         (*cons)[3*j+2] = N3;
00463     }
00464 
00465     // normalize all vertex normals
00466     for (i=0; i < nbNodesInFace; i++) {
00467 
00468         gp_Dir clNormal;
00469 
00470         try {
00471             Handle_Geom_Surface Surface = BRep_Tool::Surface(aFace);
00472 
00473             gp_Pnt vertex((*vertices)[i].XYZ());
00474 //     gp_Pnt vertex((*vertices)[i][0], (*vertices)[i][1], (*vertices)[i][2]);
00475             GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface);
00476             Standard_Real fU, fV;
00477             ProPntSrf.Parameters(1, fU, fV);
00478 
00479             GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution());
00480 
00481             clNormal = clPropOfFace.Normal();
00482             gp_Vec temp = clNormal;
00483             //Base::Console().Log("unterschied:%.2f",temp.dot((*vertexnormals)[i]));
00484             if ( temp * (*vertexnormals)[i] < 0 )
00485                 temp = -temp;
00486             (*vertexnormals)[i] = temp;
00487 
00488         }
00489         catch (...) {
00490         }
00491 
00492         (*vertexnormals)[i].Normalize();
00493     }
00494 }

Generated on Wed Nov 23 19:00:28 2011 for FreeCAD by  doxygen 1.6.1