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 #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
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
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
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
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))
00231 return NULL;
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))
00256 return NULL;
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))
00275 return NULL;
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))
00296 return NULL;
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))
00318 return NULL;
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))
00337 return NULL;
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))
00357 return NULL;
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
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}
00399 };