/*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2005 * * * * 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 # include # include # include # include # include # include # include # include #endif #include #include #include #include #include "PovTools.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 positon 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 vCam; vCam.push_back(Cam); writeCameraVec(FileName,vCam); } void PovTools::writeCameraVec(const char* FileName, const std::vector& CamVec) { std::stringstream out; std::vector::const_iterator It; out << "// declares positon 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 points; std::vector normals; std::vector 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::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::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::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()); // this block mesh the face and transfers it in a C array of vertices and face indexes Standard_Integer nbNodesInFace,nbTriInFace; gp_Vec* vertices=0; gp_Vec* vertexnormals=0; long* cons=0; transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace); if (!vertices) break; // writing per face header out << "// face number" << l << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl << "#declare " << PartName << l << " = mesh2{" << endl << " vertex_vectors {" << endl << " " << nbNodesInFace << "," << endl; // writing vertices for (int i=0; i < nbNodesInFace; i++) { out << " <" << vertices[i].X() << "," << vertices[i].Z() << "," << vertices[i].Y() << ">," << endl; } out << " }" << endl // writing per vertex normals << " normal_vectors {" << endl << " " << nbNodesInFace << "," << endl; for (int j=0; j < nbNodesInFace; j++) { out << " <" << vertexnormals[j].X() << "," << vertexnormals[j].Z() << "," << vertexnormals[j].Y() << ">," << endl; } out << " }" << endl // writing triangle indices << " face_indices {" << endl << " " << nbTriInFace << "," << endl; for (int k=0; k < nbTriInFace; k++) { out << " <" << cons[3*k] << ","<< cons[3*k+2] << ","<< cons[3*k+1] << ">," << endl; } // end of face out << " }" << endl << "} // end of Face"<< l << endl << endl; delete [] vertexnormals; delete [] vertices; delete [] cons; 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 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()); // this block mesh the face and transfers it in a C array of vertices and face indexes Standard_Integer nbNodesInFace,nbTriInFace; gp_Vec* vertices=0; gp_Vec* vertexnormals=0; long* cons=0; transferToArray(aFace,&vertices,&vertexnormals,&cons,nbNodesInFace,nbTriInFace); if (!vertices) break; // writing per face header // writing vertices for (int i=0; i < nbNodesInFace; i++) { fout << vertices[i].X() << cSeperator << vertices[i].Z() << cSeperator << vertices[i].Y() << cSeperator << vertexnormals[i].X() * fLength <NbNodes(); nbTriInFace = aPoly->NbTriangles(); *vertices = new gp_Vec[nbNodesInFace]; *vertexnormals = new gp_Vec[nbNodesInFace]; for (i=0; i < nbNodesInFace; i++) { (*vertexnormals)[i]= gp_Vec(0.0,0.0,0.0); } *cons = new long[3*(nbTriInFace)+1]; // check orientation TopAbs_Orientation orient = aFace.Orientation(); // cycling through the poly mesh const Poly_Array1OfTriangle& Triangles = aPoly->Triangles(); const TColgp_Array1OfPnt& Nodes = aPoly->Nodes(); for (i=1; i<=nbTriInFace; i++) { // Get the triangle Standard_Integer N1,N2,N3; Triangles(i).Get(N1,N2,N3); // change orientation of the triangles if ( orient != TopAbs_FORWARD ) { Standard_Integer tmp = N1; N1 = N2; N2 = tmp; } gp_Pnt V1 = Nodes(N1); gp_Pnt V2 = Nodes(N2); gp_Pnt V3 = Nodes(N3); // transform the vertices to the place of the face if (!identity) { V1.Transform(myTransf); V2.Transform(myTransf); V3.Transform(myTransf); } // Calculate triangle normal gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); gp_Vec Normal = (v2-v1)^(v3-v1); //Standard_Real Area = 0.5 * Normal.Magnitude(); // add the triangle normal to the vertex normal for all points of this triangle (*vertexnormals)[N1-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertexnormals)[N2-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertexnormals)[N3-1] += gp_Vec(Normal.X(),Normal.Y(),Normal.Z()); (*vertices)[N1-1].SetX((float)(V1.X())); (*vertices)[N1-1].SetY((float)(V1.Y())); (*vertices)[N1-1].SetZ((float)(V1.Z())); (*vertices)[N2-1].SetX((float)(V2.X())); (*vertices)[N2-1].SetY((float)(V2.Y())); (*vertices)[N2-1].SetZ((float)(V2.Z())); (*vertices)[N3-1].SetX((float)(V3.X())); (*vertices)[N3-1].SetY((float)(V3.Y())); (*vertices)[N3-1].SetZ((float)(V3.Z())); int j = i - 1; N1--; N2--; N3--; (*cons)[3*j] = N1; (*cons)[3*j+1] = N2; (*cons)[3*j+2] = N3; } // normalize all vertex normals for (i=0; i < nbNodesInFace; i++) { gp_Dir clNormal; try { Handle_Geom_Surface Surface = BRep_Tool::Surface(aFace); gp_Pnt vertex((*vertices)[i].XYZ()); // gp_Pnt vertex((*vertices)[i][0], (*vertices)[i][1], (*vertices)[i][2]); GeomAPI_ProjectPointOnSurf ProPntSrf(vertex, Surface); Standard_Real fU, fV; ProPntSrf.Parameters(1, fU, fV); GeomLProp_SLProps clPropOfFace(Surface, fU, fV, 2, gp::Resolution()); clNormal = clPropOfFace.Normal(); gp_Vec temp = clNormal; //Base::Console().Log("unterschied:%.2f",temp.dot((*vertexnormals)[i])); if ( temp * (*vertexnormals)[i] < 0 ) temp = -temp; (*vertexnormals)[i] = temp; } catch (...) { } (*vertexnormals)[i].Normalize(); } }