00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00053
00054
00055
00056
00057
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
00067 << "#declare cam_location = <" << Cam.CamPos.X() <<"," << Cam.CamPos.Z() <<"," << Cam.CamPos.Y()<<">;" << endl
00068
00069
00070 << "#declare cam_look_at = <" << Cam.LookAt.X() <<"," << Cam.LookAt.Z() <<"," << Cam.LookAt.Y() <<">;"<< endl
00071
00072
00073 << "#declare cam_sky = <" << Cam.Up.X() <<"," << Cam.Up.Z() <<"," << Cam.Up.Y() <<">;"<< endl
00074
00075
00076 << "#declare cam_angle = 50; " << endl
00077
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
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
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
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
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
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
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
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
00156 Base::ofstream fout(FileName);
00157
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
00170 fout << "// element number" << i << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00171 << "#declare " << PartName << i << " = mesh2{" << endl
00172 << " vertex_vectors {" << endl
00173 << " " << points.size() << "," << endl;
00174
00175
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
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
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
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
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
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
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
00248 const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
00249
00250
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
00260 out << "// face number" << l << " +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
00261 << "#declare " << PartName << l << " = mesh2{" << endl
00262 << " vertex_vectors {" << endl
00263 << " " << nbNodesInFace << "," << endl;
00264
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
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
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
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 }
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
00323 std::ofstream fout(FileName);
00324
00325
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
00331 l = 1;
00332 for (ex.Init(Shape, TopAbs_FACE); ex.More(); ex.Next(),l++) {
00333
00334
00335 const TopoDS_Face& aFace = TopoDS::Face(ex.Current());
00336
00337
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
00347
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 }
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
00374
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
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
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
00406 TopAbs_Orientation orient = aFace.Orientation();
00407
00408
00409 const Poly_Array1OfTriangle& Triangles = aPoly->Triangles();
00410 const TColgp_Array1OfPnt& Nodes = aPoly->Nodes();
00411 for (i=1; i<=nbTriInFace; i++) {
00412
00413 Standard_Integer N1,N2,N3;
00414 Triangles(i).Get(N1,N2,N3);
00415
00416
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
00429 if (!identity) {
00430 V1.Transform(myTransf);
00431 V2.Transform(myTransf);
00432 V3.Transform(myTransf);
00433 }
00434
00435
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
00440
00441
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
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
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
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 }