AppMeshPy.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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 #ifndef _PreComp_
00025 #endif
00026 
00027 #include <Base/Console.h>
00028 #include <Base/Interpreter.h>
00029 #include <Base/FileInfo.h>
00030 #include <App/Application.h>
00031 #include <App/Document.h>
00032 #include <App/DocumentObjectPy.h>
00033 #include <App/Property.h>
00034 
00035 #include "Core/MeshKernel.h"
00036 #include "Core/MeshIO.h"
00037 #include "MeshPy.h"
00038 #include "Mesh.h"
00039 #include "FeatureMeshImport.h"
00040 
00041 using namespace Mesh;
00042 using namespace MeshCore;
00043 
00044 
00045 /* module functions */
00046 static PyObject * read(PyObject *self, PyObject *args)
00047 {
00048     const char* Name;
00049     if (!PyArg_ParseTuple(args, "s",&Name))
00050         return NULL;
00051 
00052     PY_TRY {
00053         std::auto_ptr<MeshObject> mesh(new MeshObject);
00054         if (mesh->load(Name)) {
00055             return new MeshPy(mesh.release());
00056         }
00057         else {
00058             PyErr_SetString(PyExc_Exception, "Loading of mesh was aborted");
00059             return NULL;
00060         }
00061     } PY_CATCH;
00062 
00063     Py_Return;
00064 }
00065 
00066 static PyObject * open(PyObject *self, PyObject *args)
00067 {
00068     const char* Name;
00069     if (!PyArg_ParseTuple(args, "s",&Name))
00070         return NULL;
00071 
00072     PY_TRY {
00073         MeshObject mesh;
00074         if (mesh.load(Name)) {
00075             Base::FileInfo file(Name);
00076             // create new document and add Import feature
00077             App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
00078             unsigned long segmct = mesh.countSegments();
00079             if (segmct > 1) {
00080                 for (unsigned long i=0; i<segmct; i++) {
00081                     std::auto_ptr<MeshObject> segm(mesh.meshFromSegment(mesh.getSegment(i).getIndices()));
00082                     Mesh::Feature *pcFeature = static_cast<Mesh::Feature *>
00083                         (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str()));
00084                     pcFeature->Label.setValue(file.fileNamePure().c_str());
00085                     pcFeature->Mesh.swapMesh(*segm);
00086                     pcFeature->purgeTouched();
00087                 }
00088             }
00089             else {
00090                 Mesh::Feature *pcFeature = static_cast<Mesh::Feature *>
00091                     (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str()));
00092                 pcFeature->Label.setValue(file.fileNamePure().c_str());
00093                 pcFeature->Mesh.swapMesh(mesh);
00094                 pcFeature->purgeTouched();
00095             }
00096         }
00097     } PY_CATCH;
00098 
00099     Py_Return;
00100 }
00101 
00102 static PyObject * importer(PyObject *self, PyObject *args)
00103 {
00104     const char* Name;
00105     const char* DocName=0;
00106 
00107     if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
00108         return NULL;
00109 
00110     PY_TRY {
00111         App::Document *pcDoc = 0;
00112         if (DocName)
00113             pcDoc = App::GetApplication().getDocument(DocName);
00114         else
00115             pcDoc = App::GetApplication().getActiveDocument();
00116 
00117         if (!pcDoc) {
00118             pcDoc = App::GetApplication().newDocument(DocName);
00119         }
00120 
00121         MeshObject mesh;
00122         if (mesh.load(Name)) {
00123             Base::FileInfo file(Name);
00124             unsigned long segmct = mesh.countSegments();
00125             if (segmct > 1) {
00126                 for (unsigned long i=0; i<segmct; i++) {
00127                     std::auto_ptr<MeshObject> segm(mesh.meshFromSegment(mesh.getSegment(i).getIndices()));
00128                     Mesh::Feature *pcFeature = static_cast<Mesh::Feature *>
00129                         (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str()));
00130                     pcFeature->Label.setValue(file.fileNamePure().c_str());
00131                     pcFeature->Mesh.swapMesh(*segm);
00132                     pcFeature->purgeTouched();
00133                 }
00134             }
00135             else {
00136                 Mesh::Feature *pcFeature = static_cast<Mesh::Feature *>
00137                     (pcDoc->addObject("Mesh::Feature", file.fileNamePure().c_str()));
00138                 pcFeature->Label.setValue(file.fileNamePure().c_str());
00139                 pcFeature->Mesh.swapMesh(mesh);
00140                 pcFeature->purgeTouched();
00141             }
00142         }
00143     } PY_CATCH;
00144 
00145     Py_Return;
00146 }
00147 
00148 static PyObject * exporter(PyObject *self, PyObject *args)
00149 {
00150     PyObject* object;
00151     const char* filename;
00152     if (!PyArg_ParseTuple(args, "Os",&object,&filename))
00153         return NULL;
00154 
00155     float fTolerance = 0.1f;
00156     MeshObject global_mesh;
00157 
00158     PY_TRY {
00159         Py::List list(object);
00160         Base::Type meshId = Base::Type::fromName("Mesh::Feature");
00161         Base::Type partId = Base::Type::fromName("Part::Feature");
00162         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00163             PyObject* item = (*it).ptr();
00164             if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
00165                 App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
00166                 if (obj->getTypeId().isDerivedFrom(meshId)) {
00167                     const MeshObject& mesh = static_cast<Mesh::Feature*>(obj)->Mesh.getValue();
00168                     if (global_mesh.countFacets() == 0)
00169                         global_mesh = mesh;
00170                     else
00171                         global_mesh.addMesh(mesh);
00172                 }
00173                 else if (obj->getTypeId().isDerivedFrom(partId)) {
00174                     App::Property* shape = obj->getPropertyByName("Shape");
00175                     Base::Reference<MeshObject> mesh(new MeshObject());
00176                     if (shape && shape->getTypeId().isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
00177                         std::vector<Base::Vector3d> aPoints;
00178                         std::vector<Data::ComplexGeoData::Facet> aTopo;
00179                         static_cast<App::PropertyComplexGeoData*>(shape)->getFaces(aPoints, aTopo,fTolerance);
00180                         mesh->addFacets(aTopo, aPoints);
00181                         if (global_mesh.countFacets() == 0)
00182                             global_mesh = *mesh;
00183                         else
00184                             global_mesh.addMesh(*mesh);
00185                     }
00186                 }
00187                 else {
00188                     Base::Console().Message("'%s' is not a mesh or shape, export will be ignored.\n", obj->Label.getValue());
00189                 }
00190             }
00191         }
00192 
00193         // export mesh compound
00194         global_mesh.save(filename);
00195     } PY_CATCH;
00196 
00197     Py_Return;
00198 }
00199 
00200 static PyObject * 
00201 show(PyObject *self, PyObject *args)
00202 {
00203     PyObject *pcObj;
00204     if (!PyArg_ParseTuple(args, "O!", &(MeshPy::Type), &pcObj))
00205         return NULL;
00206 
00207     PY_TRY {
00208         App::Document *pcDoc = App::GetApplication().getActiveDocument();
00209         if (!pcDoc)
00210             pcDoc = App::GetApplication().newDocument();
00211         MeshPy* pMesh = static_cast<MeshPy*>(pcObj);
00212         Mesh::Feature *pcFeature = (Mesh::Feature *)pcDoc->addObject("Mesh::Feature", "Mesh");
00213         Mesh::MeshObject* mo = pMesh->getMeshObjectPtr();
00214         if (!mo) {
00215             PyErr_SetString(PyExc_ReferenceError,
00216                 "object doesn't reference a valid mesh");
00217             return 0;
00218         }
00219         // copy the data
00220         pcFeature->Mesh.setValue(*mo);
00221     } PY_CATCH;
00222 
00223     Py_Return;
00224 }
00225 
00226 static PyObject *
00227 createPlane(PyObject *self, PyObject *args)
00228 {
00229     float x=1,y=0,z=0;
00230     if (!PyArg_ParseTuple(args, "|fff",&x,&y,&z))     // convert args: Python->C 
00231         return NULL;                                   // NULL triggers exception 
00232 
00233     if(y==0) 
00234         y=x;
00235 
00236     float hx = x/2.0f;
00237     float hy = y/2.0f;
00238 
00239     PY_TRY {
00240         std::vector<MeshCore::MeshGeomFacet> TriaList;
00241         TriaList.push_back(MeshCore::MeshGeomFacet(Base::Vector3f(-hx, -hy, 0.0),Base::Vector3f(hx, hy, 0.0),Base::Vector3f(-hx, hy, 0.0)));
00242         TriaList.push_back(MeshCore::MeshGeomFacet(Base::Vector3f(-hx, -hy, 0.0),Base::Vector3f(hx, -hy, 0.0),Base::Vector3f(hx, hy, 0.0)));
00243 
00244         std::auto_ptr<MeshObject> mesh(new MeshObject);
00245         mesh->addFacets(TriaList);
00246         return new MeshPy(mesh.release());
00247     } PY_CATCH;
00248 }
00249 
00250 static PyObject *
00251 createSphere(PyObject *self, PyObject *args)
00252 {
00253     float radius = 5.0f;
00254     int sampling = 50;
00255     if (!PyArg_ParseTuple(args, "|fi",&radius,&sampling))     // convert args: Python->C 
00256         return NULL;                                   // NULL triggers exception 
00257 
00258     PY_TRY {
00259         MeshObject* mesh = MeshObject::createSphere(radius, sampling);
00260         if (!mesh) {
00261             PyErr_SetString(PyExc_Exception, "Creation of sphere failed");
00262             return NULL;
00263         }
00264         return new MeshPy(mesh);
00265     } PY_CATCH;
00266 }
00267 
00268 static PyObject *
00269 createEllipsoid(PyObject *self, PyObject *args)
00270 {
00271     float radius1 = 2.0f;
00272     float radius2 = 4.0f;
00273     int sampling = 50;
00274     if (!PyArg_ParseTuple(args, "|ffi",&radius1,&radius2,&sampling))     // convert args: Python->C 
00275         return NULL;                                   // NULL triggers exception 
00276 
00277     PY_TRY {
00278         MeshObject* mesh = MeshObject::createEllipsoid(radius1, radius2, sampling);
00279         if (!mesh) {
00280             PyErr_SetString(PyExc_Exception, "Creation of ellipsoid failed");
00281             return NULL;
00282         }
00283         return new MeshPy(mesh);
00284     } PY_CATCH;
00285 }
00286 
00287 static PyObject *
00288 createCylinder(PyObject *self, PyObject *args)
00289 {
00290     float radius = 2.0f;
00291     float length = 10.0f;
00292     int closed = 1;
00293     float edgelen = 1.0f;
00294     int sampling = 50;
00295     if (!PyArg_ParseTuple(args, "|ffifi",&radius,&length,&closed,&edgelen,&sampling))     // convert args: Python->C 
00296         return NULL;                                   // NULL triggers exception 
00297 
00298     PY_TRY {
00299         MeshObject* mesh = MeshObject::createCylinder(radius, length, closed, edgelen, sampling);
00300         if (!mesh) {
00301             PyErr_SetString(PyExc_Exception, "Creation of cylinder failed");
00302             return NULL;
00303         }
00304         return new MeshPy(mesh);
00305     } PY_CATCH;
00306 }
00307 
00308 static PyObject *
00309 createCone(PyObject *self, PyObject *args)
00310 {
00311     float radius1 = 2.0f;
00312     float radius2 = 4.0f;
00313     float len = 10.0f;
00314     int closed = 1;
00315     float edgelen = 1.0f;
00316     int sampling = 50;
00317     if (!PyArg_ParseTuple(args, "|fffifi",&radius1,&radius2,&len,&closed,&edgelen,&sampling))     // convert args: Python->C 
00318         return NULL;                                   // NULL triggers exception 
00319 
00320     PY_TRY {
00321         MeshObject* mesh = MeshObject::createCone(radius1, radius2, len, closed, edgelen, sampling);
00322         if (!mesh) {
00323             PyErr_SetString(PyExc_Exception, "Creation of cone failed");
00324             return NULL;
00325         }
00326         return new MeshPy(mesh);
00327     } PY_CATCH;
00328 }
00329 
00330 static PyObject *
00331 createTorus(PyObject *self, PyObject *args)
00332 {
00333     float radius1 = 10.0f;
00334     float radius2 = 2.0f;
00335     int sampling = 50;
00336     if (!PyArg_ParseTuple(args, "|ffi",&radius1,&radius2,&sampling))     // convert args: Python->C 
00337         return NULL;                                   // NULL triggers exception 
00338 
00339     PY_TRY {
00340         MeshObject* mesh = MeshObject::createTorus(radius1, radius2, sampling);
00341         if (!mesh) {
00342             PyErr_SetString(PyExc_Exception, "Creation of torus failed");
00343             return NULL;
00344         }
00345         return new MeshPy(mesh);
00346     } PY_CATCH;
00347 }
00348 
00349 static PyObject * 
00350 createBox(PyObject *self, PyObject *args)
00351 {
00352     float length = 10.0f;
00353     float width = 10.0f;
00354     float height = 10.0f;
00355     float edgelen = -1.0f;
00356     if (!PyArg_ParseTuple(args, "|ffff",&length,&width,&height,&edgelen))     // convert args: Python->C 
00357         return NULL;                                   // NULL triggers exception 
00358 
00359     PY_TRY {
00360         MeshObject* mesh;
00361         if (edgelen < 0.0f)
00362             mesh = MeshObject::createCube(length, width, height);
00363         else
00364             mesh = MeshObject::createCube(length, width, height, edgelen);
00365 
00366         if (!mesh) {
00367             PyErr_SetString(PyExc_Exception, "Creation of box failed");
00368             return NULL;
00369         }
00370         return new MeshPy(mesh);
00371     } PY_CATCH;
00372 }
00373 
00374 PyDoc_STRVAR(open_doc,
00375 "open(string) -- Create a new document and a Mesh::Import feature to load the file into the document.");
00376 
00377 PyDoc_STRVAR(inst_doc,
00378 "insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document.");
00379 
00380 PyDoc_STRVAR(export_doc,
00381 "export(list,string) -- Export a list of objects into a single file.");
00382 
00383 /* List of functions defined in the module */
00384 
00385 struct PyMethodDef Mesh_Import_methods[] = { 
00386     {"open"       ,open ,       METH_VARARGS, open_doc},
00387     {"insert"     ,importer,    METH_VARARGS, inst_doc},
00388     {"export"     ,exporter,    METH_VARARGS, export_doc},
00389     {"read"       ,read,        Py_NEWARGS,   "Read a mesh from a file and returns a Mesh object."},
00390     {"show"       ,show,        Py_NEWARGS,   "Put a mesh object in the active document or creates one if needed"},
00391     {"createBox"  ,createBox,   Py_NEWARGS,   "Create a solid mesh box"},
00392     {"createPlane",createPlane, Py_NEWARGS,   "Create a mesh XY plane normal +Z"},
00393     {"createSphere",createSphere, Py_NEWARGS,   "Create a tessellated sphere"},
00394     {"createEllipsoid",createEllipsoid, Py_NEWARGS,   "Create a tessellated ellipsoid"},
00395     {"createCylinder",createCylinder, Py_NEWARGS,   "Create a tessellated cylinder"},
00396     {"createCone",createCone, Py_NEWARGS,   "Create a tessellated cone"},
00397     {"createTorus",createTorus, Py_NEWARGS,   "Create a tessellated torus"},
00398     {NULL, NULL}  /* sentinel */
00399 };

Generated on Wed Nov 23 18:59:56 2011 for FreeCAD by  doxygen 1.6.1