FreeCAD/src/Mod/Fem/App/AppFemPy.cpp
2013-09-12 21:58:11 +02:00

581 lines
24 KiB
C++
Executable File

/***************************************************************************
* Copyright (c) 2008 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 <Python.h>
# include <memory>
#endif
#include <Base/Console.h>
#include <Base/Tools.h>
#include <Base/VectorPy.h>
#include <Base/PlacementPy.h>
#include <App/Application.h>
#include <App/Document.h>
#include <App/DocumentObject.h>
#include <App/DocumentObjectPy.h>
//#include <Mod/Mesh/App/Core/MeshKernel.h>
//#include <Mod/Mesh/App/Core/Evaluation.h>
//#include <Mod/Mesh/App/Core/Iterator.h>
#include <SMESH_Gen.hxx>
#include <SMESH_Group.hxx>
#include <SMESHDS_Mesh.hxx>
#include <SMDS_MeshNode.hxx>
#include <StdMeshers_MaxLength.hxx>
#include <StdMeshers_LocalLength.hxx>
#include <StdMeshers_NumberOfSegments.hxx>
#include <StdMeshers_AutomaticLength.hxx>
#include <StdMeshers_TrianglePreference.hxx>
#include <StdMeshers_MEFISTO_2D.hxx>
#include <StdMeshers_Deflection1D.hxx>
#include <StdMeshers_MaxElementArea.hxx>
#include <StdMeshers_Regular_1D.hxx>
#include <StdMeshers_QuadranglePreference.hxx>
#include <StdMeshers_Quadrangle_2D.hxx>
#include <StdMeshers_LengthFromEdges.hxx>
#include <StdMeshers_NotConformAllowed.hxx>
#include <StdMeshers_Arithmetic1D.hxx>
#include "FemMesh.h"
#include "FemMeshObject.h"
#include "FemMeshPy.h"
#include <cstdlib>
#include <Standard_Real.hxx>
#include "Base/Vector3D.h"
using namespace Fem;
/* module functions */
static PyObject * read(PyObject *self, PyObject *args)
{
const char* Name;
if (!PyArg_ParseTuple(args, "s",&Name))
return NULL;
PY_TRY {
std::auto_ptr<FemMesh> mesh(new FemMesh);
try {
mesh->read(Name);
return new FemMeshPy(mesh.release());
}
catch(...) {
PyErr_SetString(PyExc_Exception, "Loading of mesh was aborted");
return NULL;
}
} PY_CATCH;
Py_Return;
}
static PyObject * open(PyObject *self, PyObject *args)
{
const char* Name;
if (!PyArg_ParseTuple(args, "s",&Name))
return NULL;
PY_TRY {
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(Name);
Base::FileInfo file(Name);
// create new document and add Import feature
App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
FemMeshObject *pcFeature = static_cast<FemMeshObject *>
(pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->FemMesh.setValuePtr(mesh.get());
(void)mesh.release();
pcFeature->purgeTouched();
} PY_CATCH;
Py_Return;
}
static PyObject *
show(PyObject *self, PyObject *args)
{
PyObject *pcObj;
if (!PyArg_ParseTuple(args, "O!", &(FemMeshPy::Type), &pcObj)) // convert args: Python->C
return NULL; // NULL triggers exception
PY_TRY {
App::Document *pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc)
pcDoc = App::GetApplication().newDocument();
FemMeshPy* pShape = static_cast<FemMeshPy*>(pcObj);
Fem::FemMeshObject *pcFeature = (Fem::FemMeshObject *)pcDoc->addObject("Fem::FemMeshObject", "Mesh");
// copy the data
//TopoShape* shape = new MeshObject(*pShape->getTopoShapeObjectPtr());
pcFeature->FemMesh.setValue(*(pShape->getFemMeshPtr()));
pcDoc->recompute();
} PY_CATCH;
Py_Return;
}
static PyObject * importer(PyObject *self, PyObject *args)
{
const char* Name;
const char* DocName=0;
if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
return NULL;
PY_TRY {
App::Document *pcDoc = 0;
if (DocName)
pcDoc = App::GetApplication().getDocument(DocName);
else
pcDoc = App::GetApplication().getActiveDocument();
if (!pcDoc) {
pcDoc = App::GetApplication().newDocument(DocName);
}
std::auto_ptr<FemMesh> mesh(new FemMesh);
mesh->read(Name);
Base::FileInfo file(Name);
FemMeshObject *pcFeature = static_cast<FemMeshObject *>
(pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
pcFeature->Label.setValue(file.fileNamePure().c_str());
pcFeature->FemMesh.setValuePtr(mesh.get());
(void)mesh.release();
pcFeature->purgeTouched();
} PY_CATCH;
Py_Return;
}
//static PyObject * import_NASTRAN(PyObject *self, PyObject *args)
//{
// const char* filename_input, *filename_output;
// if (!PyArg_ParseTuple(args, "ss",&filename_input,&filename_output))
// return NULL;
//
// PY_TRY {
//
// std::ifstream inputfile;
//
// //Für Debugoutput
// ofstream anOutput;
// anOutput.open("c:/time_measurement.txt");
// time_t seconds1,seconds2;
//
// inputfile.open(filename_input);
// if (!inputfile.is_open()) //Exists...?
// {
// std::cerr << "File not found. Exiting..." << std::endl;
// return NULL;
// }
//
// //Return the line pointer to the beginning of the file
// inputfile.seekg(std::ifstream::beg);
// std::string line1,line2,temp;
// std::stringstream astream;
// std::vector<unsigned int> tetra_element;
// std::vector<unsigned int> element_id;
// element_id.clear();
// std::vector<std::vector<unsigned int> > all_elements;
// std::vector<std::vector<unsigned int> >::iterator all_element_iterator;
// std::vector<unsigned int>::iterator one_element_iterator;
// all_elements.clear();
// MeshCore::MeshKernel aMesh;
// MeshCore::MeshPointArray vertices;
// vertices.clear();
// MeshCore::MeshFacetArray faces;
// faces.clear();
// MeshCore::MeshPoint current_node;
//
// seconds1 = time(NULL);
// do
// {
// std::getline(inputfile,line1);
// if (line1.size() == 0) continue;
// if (line1.find("GRID*")!= std::string::npos) //We found a Grid line
// {
// //Now lets extract the GRID Points = Nodes
// //As each GRID Line consists of two subsequent lines we have to
// //take care of that as well
// std::getline(inputfile,line2);
// //Extract X Value
// current_node.x = float(atof(line1.substr(40,56).c_str()));
// //Extract Y Value
// current_node.y = float(atof(line1.substr(56,72).c_str()));
// //Extract Z Value
// current_node.z = float(atof(line2.substr(8,24).c_str()));
//
// vertices.push_back(current_node);
// }
// else if (line1.find("CTETRA")!= std::string::npos)
// {
// tetra_element.clear();
// //Lets extract the elements
// //As each Element Line consists of two subsequent lines as well
// //we have to take care of that
// //At a first step we only extract Quadratic Tetrahedral Elements
// std::getline(inputfile,line2);
// element_id.push_back(atoi(line1.substr(8,16).c_str()));
// tetra_element.push_back(atoi(line1.substr(24,32).c_str()));
// tetra_element.push_back(atoi(line1.substr(32,40).c_str()));
// tetra_element.push_back(atoi(line1.substr(40,48).c_str()));
// tetra_element.push_back(atoi(line1.substr(48,56).c_str()));
// tetra_element.push_back(atoi(line1.substr(56,64).c_str()));
// tetra_element.push_back(atoi(line1.substr(64,72).c_str()));
// tetra_element.push_back(atoi(line2.substr(8,16).c_str()));
// tetra_element.push_back(atoi(line2.substr(16,24).c_str()));
// tetra_element.push_back(atoi(line2.substr(24,32).c_str()));
// tetra_element.push_back(atoi(line2.substr(32,40).c_str()));
//
// all_elements.push_back(tetra_element);
// }
//
// }
// while (inputfile.good());
// inputfile.close();
//
// seconds2 = time(NULL);
//
// anOutput << seconds2-seconds1 <<" for Parsing the input file"<<std::endl;
// //Now lets perform some minimization routines to min the bbox volume
// //To evaluate the COG and principal axes we have to generate a "Mesh" out of the points
// //therefore at least one face is required
// MeshCore::MeshFacet aFacet;
// aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2;
// faces.push_back(aFacet);
// //Fill the Kernel with the structure
// aMesh.Assign(vertices,faces);
//
// seconds1 = time(NULL);
// //First lets get the COG and the principal axes and transfer the mesh there
// MeshCore::MeshEigensystem pca(aMesh);
// pca.Evaluate();
// Base::Matrix4D Trafo = pca.Transform();
// aMesh.Transform(Trafo);
// ///////////////////////////////////////////////////////////////////////////
// //To get the center of gravity we have to build the inverse of the pca Matrix
// pca.Evaluate();
// Trafo = pca.Transform();
// Trafo.inverse();
// Base::Vector3f cog;
// cog.x = float(Trafo[0][3]);cog.y = float(Trafo[1][3]);cog.z = float(Trafo[2][3]);
// ///////////////////////////////////////////////////////////////////////////
// //Now do Monte Carlo to minimize the BBox of the part
// //Use Quaternions for the rotation stuff
// Base::Rotation rotatex,rotatey,rotatez;
// const Base::Vector3d rotate_axis_x(1.0,0.0,0.0),rotate_axis_y(0.0,1.0,0.0),rotate_axis_z(0.0,0.0,1.0);
//
// //Rotate around each axes and choose the settings for the min bbox
// Base::Matrix4D final_trafo;
// Base::BoundBox3f aBBox,min_bbox;
//
//
// double volumeBBOX,min_volumeBBOX;
//
// //Get the current min_volumeBBOX and look if we find a lower one
// aBBox = aMesh.GetBoundBox();
// min_volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
//
//
// MeshCore::MeshKernel atempkernel;
//
// float it_steps=10.0;
// double step_size;
// double alpha_x=0.0,alpha_y=0.0,alpha_z=0.0;
// double perfect_ax=0.0,perfect_ay=0.0,perfect_az=0.0;
//
// //Do a Monte Carlo approach and start from the Principal Axis System
// //and rotate +/- 60° around each axis in a first iteration
// double angle_range_min_x=-M_PI/3.0,angle_range_max_x=M_PI/3.0,
// angle_range_min_y=-M_PI/3.0,angle_range_max_y=M_PI/3.0,
// angle_range_min_z=-M_PI/3.0,angle_range_max_z=M_PI/3.0;
//
// for (step_size = (2.0*M_PI/it_steps);step_size>(2.0*M_PI/360.0);step_size=(2.0*M_PI/it_steps))
// {
// for(alpha_x=angle_range_min_x;alpha_x<angle_range_max_x;alpha_x=alpha_x+step_size)
// {
// rotatex.setValue(rotate_axis_x,alpha_x);
// for(alpha_y=angle_range_min_y;alpha_y<angle_range_max_y;alpha_y=alpha_y+step_size)
// {
// rotatey.setValue(rotate_axis_y,alpha_y);
// for(alpha_z=angle_range_min_z;alpha_z<angle_range_max_z;alpha_z=alpha_z+step_size)
// {
// rotatez.setValue(rotate_axis_z,alpha_z);
// (rotatex*rotatey*rotatez).getValue(final_trafo);
// atempkernel = aMesh;
// atempkernel.Transform(final_trafo);
// aBBox = atempkernel.GetBoundBox();
// volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
// if (volumeBBOX < min_volumeBBOX)
// {
// min_volumeBBOX=volumeBBOX;
// perfect_ax=alpha_x;
// perfect_ay=alpha_y;
// perfect_az=alpha_z;
// }
// }
// }
// }
// //We found a better position than the PAS, now lets fine tune this position
// //and search only in the corridor +/- step_size for an even better one
// angle_range_min_x = perfect_ax - step_size;
// angle_range_max_x = perfect_ax + step_size;
// angle_range_min_y = perfect_ay - step_size;
// angle_range_max_y = perfect_ay + step_size;
// angle_range_min_z = perfect_az - step_size;
// angle_range_max_z = perfect_az + step_size;
// it_steps = it_steps*float(5.0);
// }
//
// //////////////////////////////////////////////////////////////////////////////////////
//
// //Free Memory
// atempkernel.Clear();
//
// //Transform the mesh to the evaluated perfect position right now
// rotatex.setValue(rotate_axis_x,perfect_ax);
// rotatey.setValue(rotate_axis_y,perfect_ay);
// rotatez.setValue(rotate_axis_z,perfect_az);
// (rotatex*rotatey*rotatez).getValue(final_trafo);
// aMesh.Transform(final_trafo);
//
// anOutput << "perfect angles " << perfect_ax << "," << perfect_ay << "," << perfect_az << std::endl;
//
//
// //Move Mesh to stay fully in the positive octant
// aBBox = aMesh.GetBoundBox();
// //Get Distance vector from current lower left corner of BBox to origin
// Base::Vector3f dist_vector;
// dist_vector.x = -aBBox.MinX;dist_vector.y=-aBBox.MinY;dist_vector.z=-aBBox.MinZ;
// Base::Matrix4D trans_matrix(
// float(1.0),float(0.0),float(0.0),dist_vector.x,
// float(0.0),float(1.0),float(0.0),dist_vector.y,
// float(0.0),float(0.0),float(1.0),dist_vector.z,
// float(0.0),float(0.0),float(0.0),float(1.0));
// aMesh.Transform(trans_matrix);
// /////////////////////////////////////////////////////////////////////////////////
// seconds2=time(NULL);
// anOutput << seconds2-seconds1 << " seconds for the min bounding box stuff" << std::endl;
//
// seconds1 = time(NULL);
// //Try to build up an own mesh kernel within SMESH to export the
// //perfect positioned mesh right now
// SMESH_Gen* meshgen = new SMESH_Gen();
// SMESH_Mesh* mesh = meshgen->CreateMesh(1, true);
// SMESHDS_Mesh* meshds = mesh->GetMeshDS();
//
// MeshCore::MeshPointIterator anodeiterator(aMesh);
// int j=1;
// for(anodeiterator.Begin(); anodeiterator.More(); anodeiterator.Next())
// {
// meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,j);
// j++;
// }
//
// for(unsigned int i=0;i<all_elements.size();i++)
// {
// //Die Reihenfolge wie hier die Elemente hinzugefügt werden ist sehr wichtig.
// //Ansonsten ist eine konsistente Datenstruktur nicht möglich
// meshds->AddVolumeWithID(
// meshds->FindNode(all_elements[i][0]),
// meshds->FindNode(all_elements[i][2]),
// meshds->FindNode(all_elements[i][1]),
// meshds->FindNode(all_elements[i][3]),
// meshds->FindNode(all_elements[i][6]),
// meshds->FindNode(all_elements[i][5]),
// meshds->FindNode(all_elements[i][4]),
// meshds->FindNode(all_elements[i][9]),
// meshds->FindNode(all_elements[i][7]),
// meshds->FindNode(all_elements[i][8]),
// element_id[i]
// );
// }
//
// mesh->ExportUNV(filename_output);
// //////////////////////////////////////////////////////////////////////////////////////////
// seconds2 = time(NULL);
// anOutput << seconds2-seconds1 << " seconds for the Mesh Export" << std::endl;
//
// //Output also to ABAQUS Input Format
// ofstream anABAQUS_Output;
// anABAQUS_Output.open("d:/abaqus_output.inp");
// anABAQUS_Output << "*Node , NSET=Nall" << std::endl;
// j=1;
// for(anodeiterator.Begin(); anodeiterator.More(); anodeiterator.Next())
// {
// anABAQUS_Output << j <<","
// <<(*anodeiterator).x << ","
// <<(*anodeiterator).y << ","
// <<(*anodeiterator).z << std::endl;
// j++;
// }
// anABAQUS_Output << "*Element, TYPE=C3D10, ELSET=Eall" << std::endl;
// j=1;
// for(unsigned int i=0;i<all_elements.size();i++)
// {
// //In ABAQUS input format a maximum of 15 Nodes per line is allowed
// anABAQUS_Output
// <<j <<","
// <<all_elements[i][0]<<","
// <<all_elements[i][1]<<","
// <<all_elements[i][2]<<","
// <<all_elements[i][3]<<","
// <<all_elements[i][4]<<","
// <<all_elements[i][5]<<","
// <<all_elements[i][6]<<","
// <<all_elements[i][7]<<","
// <<all_elements[i][8]<<","
// <<all_elements[i][9]<<std::endl;
// j++;
// }
// anABAQUS_Output.close();
// /////////////////////////////////////////////////////////////////////////////
//
//
// //Calculate Mesh Volume
// //For an accurate Volume Calculation of a quadratic Tetrahedron
// //we have to calculate the Volume of 8 Sub-Tetrahedrons
// Base::Vector3f a,b,c,a_b_product;
// double volume = 0.0;
// seconds1 = time(NULL);
// //Calc Volume with 1/6 * |(a x b) * c|
// for(all_element_iterator = all_elements.begin();all_element_iterator != all_elements.end();all_element_iterator++)
// {
// //1,5,8,7
// a = vertices[all_element_iterator->at(4)-1]-vertices[all_element_iterator->at(0)-1];
// b = vertices[all_element_iterator->at(7)-1]-vertices[all_element_iterator->at(0)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(0)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //5,9,8,7
// a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(4)-1];
// b = vertices[all_element_iterator->at(7)-1]-vertices[all_element_iterator->at(4)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(4)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //5,2,9,7
// a = vertices[all_element_iterator->at(1)-1]-vertices[all_element_iterator->at(4)-1];
// b = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(4)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(4)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //2,6,9,7
// a = vertices[all_element_iterator->at(5)-1]-vertices[all_element_iterator->at(1)-1];
// b = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(1)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(1)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //9,6,10,7
// a = vertices[all_element_iterator->at(5)-1]-vertices[all_element_iterator->at(8)-1];
// b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(8)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(8)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //6,3,10,7
// a = vertices[all_element_iterator->at(2)-1]-vertices[all_element_iterator->at(5)-1];
// b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(5)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(5)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //8,9,10,7
// a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(7)-1];
// b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(7)-1];
// c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(7)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
// //8,9,10,4
// a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(7)-1];
// b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(7)-1];
// c = vertices[all_element_iterator->at(3)-1]-vertices[all_element_iterator->at(7)-1];
// a_b_product.x = a.y*b.z-b.y*a.z;a_b_product.y = a.z*b.x-b.z*a.x;a_b_product.z = a.x*b.y-b.x*a.y;
// volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
//
// }
// seconds2=time(NULL);
// anOutput << seconds2-seconds1 << " seconds for Volume Calculation " << "Volumen " << volume/1000.0/1000.0/1000.0 << " in m^3" << std::endl;
// anOutput << "Volumen der BBox" << min_volumeBBOX/1000.0/1000.0/1000.0 << std::endl;
// anOutput << "Fly to Buy Ratio: " << min_volumeBBOX / volume << std::endl;
// anOutput.close();
//
// } PY_CATCH;
//
// Py_Return;
//}
static PyObject * exporter(PyObject *self, PyObject *args)
{
PyObject* object;
const char* filename;
if (!PyArg_ParseTuple(args, "Os",&object,&filename))
return NULL;
PY_TRY {
Py::List list(object);
Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject");
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
if (obj->getTypeId().isDerivedFrom(meshId)) {
static_cast<FemMeshObject*>(obj)->FemMesh.getValue().write(filename);
break;
}
}
}
} PY_CATCH;
Py_Return;
}
// ----------------------------------------------------------------------------
PyDoc_STRVAR(open_doc,
"open(string) -- Create a new document and a Mesh::Import feature to load the file into the document.");
PyDoc_STRVAR(inst_doc,
"insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document.");
PyDoc_STRVAR(export_doc,
"export(list,string) -- Export a list of objects into a single file.");
/* registration table */
struct PyMethodDef Fem_methods[] = {
{"open" ,open , METH_VARARGS, open_doc},
{"insert" ,importer, METH_VARARGS, inst_doc},
{"export" ,exporter, METH_VARARGS, export_doc},
{"read" ,read, Py_NEWARGS, "Read a mesh from a file and returns a Mesh object."},
{"show" ,show ,METH_VARARGS,
"show(shape) -- Add the shape to the active document or create one if no document exists."},
{NULL, NULL} /* sentinel */
};