Files
create/src/Mod/Raytracing/App/PovTools.cpp

360 lines
13 KiB
C++

/***************************************************************************
* Copyright (c) 2005 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRep_Tool.hxx>
# include <BRepMesh_IncrementalMesh.hxx>
# include <GeomAPI_ProjectPointOnSurf.hxx>
# include <GeomLProp_SLProps.hxx>
# include <Poly_Triangulation.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Face.hxx>
# include <sstream>
#endif
#include <Base/Console.h>
#include <Base/Exception.h>
#include <Base/Sequencer.h>
#include <App/ComplexGeoData.h>
#include "PovTools.h"
#include <Mod/Part/App/Tools.h>
using Base::Console;
using namespace Raytracing;
using namespace std;
#include "PovTools.h"
//#include "TempCamera.inc"
//camera {
// location CamPos
// look_at LookAt
// sky Up
// angle 45
//}
std::string PovTools::getCamera(const CamDef& Cam, int width, int height)
{
std::stringstream out;
out << "// declares position and view direction\n" << endl
<< "// Generated by FreeCAD (http://www.freecadweb.org/)" << endl
// writing Camera positions
<< "#declare cam_location = <" << Cam.CamPos.X() <<"," << Cam.CamPos.Z() <<"," << Cam.CamPos.Y()<<">;" << endl
// writing lookat
<< "#declare cam_look_at = <" << Cam.LookAt.X() <<"," << Cam.LookAt.Z() <<"," << Cam.LookAt.Y() <<">;"<< endl
// writing the Up Vector
<< "#declare cam_sky = <" << Cam.Up.X() <<"," << Cam.Up.Z() <<"," << Cam.Up.Y() <<">;"<< endl
// array of zoom factors
<< "#declare cam_angle = 45; " << endl
// instance of the camera
<< "camera {" << endl
<< " location cam_location" << endl
<< " look_at cam_look_at" << endl
<< " sky cam_sky" << endl
<< " angle cam_angle " << endl
<< " right x*" << width << "/" << height << endl
<< "}"<< endl;
return out.str();
}
void PovTools::writeCamera(const char* FileName, const CamDef& Cam)
{
std::vector<CamDef> vCam;
vCam.push_back(Cam);
writeCameraVec(FileName,vCam);
}
void PovTools::writeCameraVec(const char* FileName, const std::vector<CamDef>& CamVec)
{
std::stringstream out;
std::vector<CamDef>::const_iterator It;
out << "// declares position and view directions\n"
<< "// Generated by FreeCAD (http://www.freecadweb.org/)\n\n"
<< "// Total number of camera positions\n"
<< "#declare nCamPos = " << CamVec.size() << ";\n\n";
// writing Camera positions
out << "// Array of positions\n"
<< "#declare CamPos = array[" << CamVec.size() << "] {\n";
for (It = CamVec.begin(); It != CamVec.end(); ++It)
out << " <" << It->CamPos.X() <<"," << It->CamPos.Z() <<"," << It->CamPos.Y() <<">,\n";
out << "};\n"
// writing Camera Direction vector
<< "// Array of Directions (only for special calculations)\n"
<< "#declare CamDir = array[" << CamVec.size() << "] {\n";
for (It = CamVec.begin(); It != CamVec.end(); ++It)
out << " <" << It->CamDir.X() <<"," << It->CamDir.Z() <<"," << It->CamDir.Y() <<">,\n";
out << "};\n"
// writing lookat
<< "// Array of Look At positions\n"
<< "#declare LookAt = array[" << CamVec.size() << "] {\n";
for (It = CamVec.begin(); It != CamVec.end(); ++It)
out << " <" << It->LookAt.X() <<"," << It->LookAt.Z() <<"," << It->LookAt.Y() <<">,\n";
out << "};\n"
// writing the Up Vector
<< "// // Array of up vectors\n"
<< "#declare Up = array[" << CamVec.size() << "] {\n";
for (It = CamVec.begin(); It != CamVec.end(); ++It)
out << " <" << It->Up.X() <<"," << It->Up.Z() <<"," << It->Up.Y() <<">,\n";
out << "};\n"
// array of zoom factors
<< "// // Array of up vectors\n"
<< "#declare CamZoom = array[" << CamVec.size() << "] {\n";
for (It = CamVec.begin(); It != CamVec.end(); ++It)
out << " 45,\n";
out << "};\n";
// open the file and write
Base::ofstream fout(FileName);
fout << out.str() << endl;
fout.close();
}
void PovTools::writeData(const char *FileName, const char *PartName,
const Data::ComplexGeoData* data, float /*fMeshDeviation*/)
{
// open the file and write
Base::ofstream fout(FileName);
// write the file
fout << "// Written by FreeCAD http://www.freecadweb.org/" << endl;
unsigned long count = data->countSubElements("Face");
for (unsigned long i=0; i<count; i++) {
std::vector<Base::Vector3d> points;
std::vector<Base::Vector3d> normals;
std::vector<Data::ComplexGeoData::Facet> facets;
Data::Segment* segm = data->getSubElement("Face", i);
data->getFacesFromSubElement(segm, points, normals, facets);
delete segm;
// writing per face header
fout << "// element number" << i << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
<< "#declare " << PartName << i << " = mesh2{" << endl
<< " vertex_vectors {" << endl
<< " " << points.size() << "," << endl;
// writing vertices
for (std::vector<Base::Vector3d>::iterator it = points.begin(); it != points.end(); ++it) {
fout << " <"
<< it->x << ","
<< it->y << ","
<< it->z << ">,"
<< endl;
}
// writing per vertex normals
fout << " }" << endl
<< " normal_vectors {" << endl
<< " " << normals.size() << "," << endl;
for (std::vector<Base::Vector3d>::iterator it = normals.begin(); it != normals.end(); ++it) {
fout << " <"
<< it->x << ","
<< it->y << ","
<< it->z << ">,"
<< endl;
}
// writing triangle indices
fout << " }" << endl
<< " face_indices {" << endl
<< " " << facets.size() << "," << endl;
for (std::vector<Data::ComplexGeoData::Facet>::iterator it = facets.begin(); it != facets.end(); ++it) {
fout << " <" << it->I1 << ","<< it->I3 << ","<< it->I2 << ">," << endl;
}
// end of face
fout << " }" << endl
<< "} // end of element" << i << endl << endl;
}
fout << endl << endl << "// Declare all together +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
<< "#declare " << PartName << " = union {" << endl;
for (unsigned long i=1; i < count; i++) {
fout << "mesh2{ " << PartName << i << "}" << endl;
}
fout << "}" << endl;
fout.close();
}
void PovTools::writeShape(const char *FileName, const char *PartName,
const TopoDS_Shape& Shape, float fMeshDeviation)
{
// open the file and write
Base::ofstream fout(FileName);
writeShape(fout,PartName,Shape,fMeshDeviation);
fout.close();
}
void PovTools::writeShape(std::ostream &out, const char *PartName,
const TopoDS_Shape& Shape, float fMeshDeviation)
{
Base::Console().Log("Meshing with Deviation: %f\n",fMeshDeviation);
TopExp_Explorer ex;
BRepMesh_IncrementalMesh MESH(Shape,fMeshDeviation);
// counting faces and start sequencer
int l = 1;
for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {}
Base::SequencerLauncher seq("Writing file", l);
// write the file
out << "// Written by FreeCAD http://www.freecadweb.org/" << endl;
l = 1;
for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
std::vector<gp_Pnt> points;
std::vector<gp_Vec> vertexnormals;
std::vector<Poly_Triangle> facets;
if (!Part::Tools::getTriangulation(aFace, points, facets)) {
break;
}
Part::Tools::getPointNormals(points, facets, vertexnormals);
Part::Tools::getPointNormals(points, aFace, vertexnormals);
// writing per face header
out << "// face number" << l << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
<< "#declare " << PartName << l << " = mesh2{" << endl
<< " vertex_vectors {" << endl
<< " " << points.size() << "," << endl;
// writing vertices
for (std::size_t i=0; i < points.size(); i++) {
out << " <"
<< points[i].X() << ","
<< points[i].Z() << ","
<< points[i].Y() << ">,"
<< endl;
}
out << " }" << endl
// writing per vertex normals
<< " normal_vectors {" << endl
<< " " << vertexnormals.size() << "," << endl;
for (std::size_t j=0; j < vertexnormals.size(); j++) {
out << " <"
<< vertexnormals[j].X() << ","
<< vertexnormals[j].Z() << ","
<< vertexnormals[j].Y() << ">,"
<< endl;
}
out << " }" << endl
// writing triangle indices
<< " face_indices {" << endl
<< " " << facets.size() << "," << endl;
for (std::size_t k=0; k < facets.size(); k++) {
Standard_Integer n1, n2, n3;
facets[k].Get(n1, n2, n3);
out << " <" << n1 << ","<< n3 << "," << n2 << ">," << endl;
}
// end of face
out << " }" << endl
<< "} // end of Face"<< l << endl << endl;
seq.next();
} // end of face loop
out << endl << endl << "// Declare all together +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
<< "#declare " << PartName << " = union {" << endl;
for (int i=1; i < l; i++) {
out << "mesh2{ " << PartName << i << "}" << endl;
}
out << "}" << endl;
}
void PovTools::writeShapeCSV(const char *FileName,
const TopoDS_Shape& Shape,
float fMeshDeviation,
float fLength)
{
const char cSeperator = ',';
Base::Console().Log("Meshing with Deviation: %f\n",fMeshDeviation);
TopExp_Explorer ex;
BRepMesh_IncrementalMesh MESH(Shape,fMeshDeviation);
// open the file and write
std::ofstream fout(FileName);
// counting faces and start sequencer
int l = 1;
for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {}
Base::SequencerLauncher seq("Writing file", l);
// write the file
for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next()) {
// get the shape and mesh it
const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
std::vector<gp_Pnt> points;
std::vector<gp_Vec> vertexnormals;
std::vector<Poly_Triangle> facets;
if (!Part::Tools::getTriangulation(aFace, points, facets)) {
break;
}
Part::Tools::getPointNormals(points, facets, vertexnormals);
Part::Tools::getPointNormals(points, aFace, vertexnormals);
// writing per face header
// writing vertices
for (std::size_t i=0; i < points.size(); i++) {
fout << points[i].X() << cSeperator
<< points[i].Z() << cSeperator
<< points[i].Y() << cSeperator
<< vertexnormals[i].X() * fLength << cSeperator
<< vertexnormals[i].Z() * fLength << cSeperator
<< vertexnormals[i].Y() * fLength << cSeperator
<< endl;
}
seq.next();
} // end of face loop
fout.close();
}