00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025 #ifndef _PreComp_
00026 # include <Python.h>
00027 # include <memory>
00028 #endif
00029
00030 #include <Base/Console.h>
00031 #include <Base/VectorPy.h>
00032 #include <Base/PlacementPy.h>
00033 #include <App/Application.h>
00034 #include <App/Document.h>
00035 #include <App/DocumentObject.h>
00036 #include <App/DocumentObjectPy.h>
00037 #include <Mod/Mesh/App/Core/MeshKernel.h>
00038 #include <Mod/Mesh/App/Core/Evaluation.h>
00039 #include <Mod/Mesh/App/Core/Iterator.h>
00040
00041 #include <SMESH_Gen.hxx>
00042 #include <SMESH_Group.hxx>
00043 #include <SMESHDS_Mesh.hxx>
00044 #include <SMDS_MeshNode.hxx>
00045 #include <StdMeshers_MaxLength.hxx>
00046 #include <StdMeshers_LocalLength.hxx>
00047 #include <StdMeshers_NumberOfSegments.hxx>
00048 #include <StdMeshers_AutomaticLength.hxx>
00049 #include <StdMeshers_TrianglePreference.hxx>
00050 #include <StdMeshers_MEFISTO_2D.hxx>
00051 #include <StdMeshers_Deflection1D.hxx>
00052 #include <StdMeshers_MaxElementArea.hxx>
00053 #include <StdMeshers_Regular_1D.hxx>
00054 #include <StdMeshers_QuadranglePreference.hxx>
00055 #include <StdMeshers_Quadrangle_2D.hxx>
00056
00057 #include <StdMeshers_LengthFromEdges.hxx>
00058 #include <StdMeshers_NotConformAllowed.hxx>
00059 #include <StdMeshers_Arithmetic1D.hxx>
00060
00061 #include "FemMesh.h"
00062 #include "FemMeshObject.h"
00063 #include "FemMeshPy.h"
00064
00065 #include <cstdlib>
00066
00067 #include <Standard_Real.hxx>
00068 #include "Base/Vector3D.h"
00069
00070 using namespace Fem;
00071
00072
00073
00074 static PyObject * read(PyObject *self, PyObject *args)
00075 {
00076 const char* Name;
00077 if (!PyArg_ParseTuple(args, "s",&Name))
00078 return NULL;
00079
00080 PY_TRY {
00081 std::auto_ptr<FemMesh> mesh(new FemMesh);
00082 try {
00083 mesh->read(Name);
00084 return new FemMeshPy(mesh.release());
00085 }
00086 catch(...) {
00087 PyErr_SetString(PyExc_Exception, "Loading of mesh was aborted");
00088 return NULL;
00089 }
00090 } PY_CATCH;
00091
00092 Py_Return;
00093 }
00094
00095 static PyObject * open(PyObject *self, PyObject *args)
00096 {
00097 const char* Name;
00098 if (!PyArg_ParseTuple(args, "s",&Name))
00099 return NULL;
00100
00101 PY_TRY {
00102 std::auto_ptr<FemMesh> mesh(new FemMesh);
00103 mesh->read(Name);
00104 Base::FileInfo file(Name);
00105
00106 App::Document *pcDoc = App::GetApplication().newDocument("Unnamed");
00107 FemMeshObject *pcFeature = static_cast<FemMeshObject *>
00108 (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
00109 pcFeature->Label.setValue(file.fileNamePure().c_str());
00110 pcFeature->FemMesh.setValuePtr(mesh.get());
00111 (void)mesh.release();
00112 pcFeature->purgeTouched();
00113 } PY_CATCH;
00114
00115 Py_Return;
00116 }
00117
00118
00119 static PyObject * SMESH_PCA(PyObject *self, PyObject *args)
00120 {
00121 PyObject *input;
00122
00123 if (!PyArg_ParseTuple(args, "O",&input))
00124 return NULL;
00125
00126 PY_TRY {
00127
00128 FemMeshPy *inputMesh = static_cast<FemMeshPy*>(input);
00129 MeshCore::MeshKernel aMesh;
00130 MeshCore::MeshPointArray vertices;
00131 vertices.clear();
00132 MeshCore::MeshFacetArray faces;
00133 faces.clear();
00134 MeshCore::MeshPoint current_node;
00135 SMDS_NodeIteratorPtr aNodeIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator();
00136 for (;aNodeIter->more();) {
00137 const SMDS_MeshNode* aNode = aNodeIter->next();
00138 current_node.Set(float(aNode->X()),float(aNode->Y()),float(aNode->Z()));
00139 vertices.push_back(current_node);
00140 }
00141
00142 MeshCore::MeshFacet aFacet;
00143 aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2;
00144 faces.push_back(aFacet);
00145
00146 aMesh.Adopt(vertices,faces);
00147 MeshCore::MeshEigensystem pca(aMesh);
00148 pca.Evaluate();
00149 Base::Matrix4D Trafo = pca.Transform();
00150
00151 inputMesh->getFemMeshPtr()->transformGeometry(Trafo);
00152
00153 } PY_CATCH;
00154
00155 Py_Return;
00156 }
00157
00158 static PyObject * calcMeshVolume(PyObject *self, PyObject *args)
00159 {
00160 PyObject *input;
00161
00162 if (!PyArg_ParseTuple(args, "O",&input))
00163 return NULL;
00164
00165 PY_TRY {
00166
00167 FemMeshPy *inputMesh = static_cast<FemMeshPy*>(input);
00168
00169 SMDS_VolumeIteratorPtr aVolIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator();
00170 Base::Vector3d a,b,c,a_b_product,temp,temp1;
00171 double volume =0.0;
00172 for (;aVolIter->more();)
00173 {
00174 const SMDS_MeshVolume* aVol = aVolIter->next();
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191 temp.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00192 temp1.Set(aVol->GetNode(0)->X(),aVol->GetNode(0)->Y(),aVol->GetNode(0)->Z());
00193 a = temp - temp1;
00194 temp.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00195 temp1.Set(aVol->GetNode(0)->X(),aVol->GetNode(0)->Y(),aVol->GetNode(0)->Z());
00196 b = temp - temp1;
00197 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00198 temp1.Set(aVol->GetNode(0)->X(),aVol->GetNode(0)->Y(),aVol->GetNode(0)->Z());
00199 c = temp - temp1;
00200 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;
00201 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00202
00203 temp.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00204 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00205 a = temp - temp1;
00206 temp.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00207 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00208 b = temp - temp1;
00209 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00210 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00211 c = temp - temp1;
00212 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;
00213 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00214
00215 temp.Set(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z());
00216 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00217 a = temp - temp1;
00218 temp.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00219 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00220 b = temp - temp1;
00221 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00222 temp1.Set(aVol->GetNode(6)->X(),aVol->GetNode(6)->Y(),aVol->GetNode(6)->Z());
00223 c = temp - temp1;
00224 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;
00225 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00226
00227 temp.Set(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z());
00228 temp1.Set(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z());
00229 a = temp - temp1;
00230 temp.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00231 temp1.Set(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z());
00232 b = temp - temp1;
00233 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00234 temp1.Set(aVol->GetNode(2)->X(),aVol->GetNode(2)->Y(),aVol->GetNode(2)->Z());
00235 c = temp - temp1;
00236 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;
00237 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00238
00239 temp.Set(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z());
00240 temp1.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00241 a = temp - temp1;
00242 temp.Set(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z());
00243 temp1.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00244 b = temp - temp1;
00245 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00246 temp1.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00247 c = temp - temp1;
00248 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;
00249 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00250
00251 temp.Set(aVol->GetNode(1)->X(),aVol->GetNode(1)->Y(),aVol->GetNode(1)->Z());
00252 temp1.Set(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z());
00253 a = temp - temp1;
00254 temp.Set(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z());
00255 temp1.Set(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z());
00256 b = temp - temp1;
00257 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00258 temp1.Set(aVol->GetNode(5)->X(),aVol->GetNode(5)->Y(),aVol->GetNode(5)->Z());
00259 c = temp - temp1;
00260 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;
00261 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00262
00263 temp.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00264 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00265 a = temp - temp1;
00266 temp.Set(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z());
00267 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00268 b = temp - temp1;
00269 temp.Set(aVol->GetNode(4)->X(),aVol->GetNode(4)->Y(),aVol->GetNode(4)->Z());
00270 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00271 c = temp - temp1;
00272 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;
00273 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00274
00275 temp.Set(aVol->GetNode(9)->X(),aVol->GetNode(9)->Y(),aVol->GetNode(9)->Z());
00276 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00277 a = temp - temp1;
00278 temp.Set(aVol->GetNode(7)->X(),aVol->GetNode(7)->Y(),aVol->GetNode(7)->Z());
00279 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00280 b = temp - temp1;
00281 temp.Set(aVol->GetNode(3)->X(),aVol->GetNode(3)->Y(),aVol->GetNode(3)->Z());
00282 temp1.Set(aVol->GetNode(8)->X(),aVol->GetNode(8)->Y(),aVol->GetNode(8)->Z());
00283 c = temp - temp1;
00284 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;
00285 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00286 }
00287 Py::Float py_volume(volume);
00288 return Py::new_reference_to(py_volume);
00289
00290 } PY_CATCH;
00291
00292 Py_Return;
00293 }
00294
00295 static PyObject * checkBB(PyObject *self, PyObject *args)
00296 {
00297 PyObject *input;
00298 PyObject* plm=0;
00299 float billet_thickness;
00300 bool oversize = false;
00301
00302 if (!PyArg_ParseTuple(args, "O|O!f", &input,&(Base::PlacementPy::Type),&plm,&billet_thickness))
00303 return NULL;
00304
00305 try {
00306 Base::Placement* placement = 0;
00307 if (plm) {
00308 placement = static_cast<Base::PlacementPy*>(plm)->getPlacementPtr();
00309
00310 }
00311 Base::Vector3d current_node;
00312 Base::Matrix4D matrix = placement->toMatrix();
00313 FemMeshPy *inputMesh = static_cast<FemMeshPy*>(input);
00314 SMDS_NodeIteratorPtr aNodeIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator();
00315 for (;aNodeIter->more();) {
00316 const SMDS_MeshNode* aNode = aNodeIter->next();
00317 current_node.Set(float(aNode->X()),float(aNode->Y()),float(aNode->Z()));
00318 current_node = matrix * current_node;
00319 if(current_node.z > billet_thickness || current_node.z < 0.0)
00320 {
00321
00322
00323 oversize = true;
00324 Py::Boolean py_oversize(oversize);
00325 return Py::new_reference_to(py_oversize);
00326 }
00327 }
00328 Py::Boolean py_oversize(oversize);
00329 return Py::new_reference_to(py_oversize);
00330 }
00331 catch (const std::exception& e) {
00332 PyErr_SetString(PyExc_Exception, e.what());
00333 return 0;
00334 }
00335 Py_Return;
00336 }
00337
00338
00339
00340
00341 static PyObject * getBoundary_Conditions(PyObject *self, PyObject *args)
00342 {
00343 PyObject *input;
00344 Py::List boundary_nodes;
00345
00346 if (!PyArg_ParseTuple(args, "O",&input))
00347 return NULL;
00348
00349 PY_TRY {
00350
00351 FemMeshPy *inputMesh = static_cast<FemMeshPy*>(input);
00352 MeshCore::MeshKernel aMesh;
00353 MeshCore::MeshPointArray vertices;
00354 vertices.clear();
00355 MeshCore::MeshFacetArray faces;
00356 faces.clear();
00357 MeshCore::MeshPoint current_node;
00358 SMDS_NodeIteratorPtr aNodeIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator();
00359 SMDS_VolumeIteratorPtr aVolIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator();
00360 for (;aNodeIter->more();) {
00361 const SMDS_MeshNode* aNode = aNodeIter->next();
00362 current_node.Set(float(aNode->X()),float(aNode->Y()),float(aNode->Z()));
00363 vertices.push_back(current_node);
00364 }
00365 MeshCore::MeshFacet aFacet;
00366 aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2;
00367 faces.push_back(aFacet);
00368
00369 aMesh.Adopt(vertices,faces);
00370 Base::BoundBox3f aBBox;
00371 aBBox = aMesh.GetBoundBox();
00372
00373 float dist_length;
00374 Base::Vector3f dist;
00375 int minNodeID,maxNodeID,midNodeID;
00376 dist_length = FLOAT_MAX;
00377
00378 aVolIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator();
00379
00380 for (;aVolIter->more();)
00381 {
00382 const SMDS_MeshVolume* aVol = aVolIter->next();
00383 for (unsigned j=0;j<4;j++)
00384 {
00385 const SMDS_MeshNode* aNode = aVol->GetNode(j);
00386
00387 dist.x = float(aNode->X())-aBBox.MinX;dist.y = float(aNode->Y())-aBBox.MinY;dist.z = float(aNode->Z())-aBBox.MinZ;
00388 if(dist.Length()<dist_length)
00389 {
00390 minNodeID = aNode->GetID();
00391 dist_length = dist.Length();
00392 }
00393 }
00394 }
00395
00396 boundary_nodes.append(Py::Int(minNodeID));
00397
00398 dist_length = FLOAT_MAX;
00399 aVolIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator();
00400 for (;aVolIter->more();)
00401 {
00402 const SMDS_MeshVolume* aVol = aVolIter->next();
00403 for (unsigned j=0;j<4;j++)
00404 {
00405 const SMDS_MeshNode* aNode = aVol->GetNode(j);
00406
00407 dist.x = float(aNode->X())-aBBox.MaxX;dist.y = float(aNode->Y())-aBBox.MinY;dist.z = float(aNode->Z())-aBBox.MinZ;
00408 if(dist.Length()<dist_length)
00409 {
00410 midNodeID = aNode->GetID();
00411 dist_length = dist.Length();
00412 }
00413 }
00414 }
00415 boundary_nodes.append(Py::Int(midNodeID));
00416
00417 dist_length = FLOAT_MAX;
00418 aVolIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->volumesIterator();
00419 for (;aVolIter->more();)
00420 {
00421 const SMDS_MeshVolume* aVol = aVolIter->next();
00422 for (unsigned j=0;j<4;j++)
00423 {
00424 const SMDS_MeshNode* aNode = aVol->GetNode(j);
00425
00426 dist.x = float(aNode->X())-aBBox.MinX;dist.y = float(aNode->Y())-aBBox.MaxY;dist.z = float(aNode->Z())-aBBox.MinZ;
00427 if(dist.Length()<dist_length)
00428 {
00429 maxNodeID = aNode->GetID();
00430 dist_length = dist.Length();
00431 }
00432 }
00433 }
00434 boundary_nodes.append(Py::Int(maxNodeID));
00435
00436
00437
00438
00439 return Py::new_reference_to(boundary_nodes);
00440
00441
00442 } PY_CATCH;
00443
00444 Py_Return;
00445 }
00446
00447
00448
00449
00450 static PyObject * minBoundingBox(PyObject *self, PyObject *args)
00451 {
00452
00453 PyObject *input;
00454
00455 if (!PyArg_ParseTuple(args, "O",&input))
00456 return NULL;
00457
00458 PY_TRY {
00459 FemMeshPy *inputMesh = static_cast<FemMeshPy*>(input);
00460 MeshCore::MeshKernel aMesh;
00461 MeshCore::MeshPointArray vertices;
00462 vertices.clear();
00463 MeshCore::MeshFacetArray faces;
00464 faces.clear();
00465 MeshCore::MeshPoint current_node;
00466 SMDS_NodeIteratorPtr aNodeIter = inputMesh->getFemMeshPtr()->getSMesh()->GetMeshDS()->nodesIterator();
00467 for (;aNodeIter->more();) {
00468 const SMDS_MeshNode* aNode = aNodeIter->next();
00469 current_node.Set(float(aNode->X()),float(aNode->Y()),float(aNode->Z()));
00470 vertices.push_back(current_node);
00471 }
00472 MeshCore::MeshFacet aFacet;
00473 aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2;
00474 faces.push_back(aFacet);
00475
00476 aMesh.Adopt(vertices,faces);
00477
00479
00480
00481 Base::Rotation rotatex,rotatey,rotatez;
00482 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);
00483
00484
00485 Base::Matrix4D final_trafo;
00486 Base::BoundBox3f aBBox,min_bbox;
00487 double volumeBBOX,min_volumeBBOX;
00488
00489 aBBox = aMesh.GetBoundBox();
00490 min_volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
00491
00492 MeshCore::MeshKernel atempkernel;
00493
00494 float it_steps=10.0;
00495 double step_size;
00496 double alpha_x=0.0,alpha_y=0.0,alpha_z=0.0;
00497 double perfect_ax=0.0,perfect_ay=0.0,perfect_az=0.0;
00498
00499
00500
00501 double angle_range_min_x=-PI/3.0,angle_range_max_x=PI/3.0,
00502 angle_range_min_y=-PI/3.0,angle_range_max_y=PI/3.0,
00503 angle_range_min_z=-PI/3.0,angle_range_max_z=PI/3.0;
00504
00505
00506 for (step_size = (2.0*PI/it_steps);step_size>(2.0*PI/3600.0);step_size=(2.0*PI/it_steps))
00507 {
00508 for(alpha_x=angle_range_min_x;alpha_x<angle_range_max_x;alpha_x=alpha_x+step_size)
00509 {
00510 rotatex.setValue(rotate_axis_x,alpha_x);
00511 for(alpha_y=angle_range_min_y;alpha_y<angle_range_max_y;alpha_y=alpha_y+step_size)
00512 {
00513 rotatey.setValue(rotate_axis_y,alpha_y);
00514 for(alpha_z=angle_range_min_z;alpha_z<angle_range_max_z;alpha_z=alpha_z+step_size)
00515 {
00516 rotatez.setValue(rotate_axis_z,alpha_z);
00517 (rotatex*rotatey*rotatez).getValue(final_trafo);
00518 atempkernel = aMesh;
00519 atempkernel.Transform(final_trafo);
00520 aBBox = atempkernel.GetBoundBox();
00521 volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
00522 if (volumeBBOX < min_volumeBBOX)
00523 {
00524 min_volumeBBOX=volumeBBOX;
00525 perfect_ax=alpha_x;
00526 perfect_ay=alpha_y;
00527 perfect_az=alpha_z;
00528 }
00529 }
00530 }
00531 }
00532
00533
00534 angle_range_min_x = perfect_ax - step_size;
00535 angle_range_max_x = perfect_ax + step_size;
00536 angle_range_min_y = perfect_ay - step_size;
00537 angle_range_max_y = perfect_ay + step_size;
00538 angle_range_min_z = perfect_az - step_size;
00539 angle_range_max_z = perfect_az + step_size;
00540 it_steps = it_steps*float(5.0);
00541 }
00542
00544
00545 atempkernel.Clear();
00546
00547 rotatex.setValue(rotate_axis_x,perfect_ax);
00548 rotatey.setValue(rotate_axis_y,perfect_ay);
00549 rotatez.setValue(rotate_axis_z,perfect_az);
00550 (rotatex*rotatey*rotatez).getValue(final_trafo);
00551 aMesh.Transform(final_trafo);
00552 inputMesh->getFemMeshPtr()->transformGeometry(final_trafo);
00554
00555 aBBox = aMesh.GetBoundBox();
00556
00557 Base::Vector3f dist_vector;
00558 dist_vector.x = -aBBox.MinX;dist_vector.y=-aBBox.MinY;dist_vector.z=-aBBox.MinZ;
00559 Base::Matrix4D trans_matrix(
00560 float(1.0),float(0.0),float(0.0),dist_vector.x,
00561 float(0.0),float(1.0),float(0.0),dist_vector.y,
00562 float(0.0),float(0.0),float(1.0),dist_vector.z,
00563 float(0.0),float(0.0),float(0.0),float(1.0));
00564 inputMesh->getFemMeshPtr()->transformGeometry(trans_matrix);
00565
00566
00567
00568 } PY_CATCH;
00569
00570 Py_Return;
00571 }
00572
00573
00574 static PyObject * importer(PyObject *self, PyObject *args)
00575 {
00576 const char* Name;
00577 const char* DocName=0;
00578
00579 if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName))
00580 return NULL;
00581
00582 PY_TRY {
00583 App::Document *pcDoc = 0;
00584 if (DocName)
00585 pcDoc = App::GetApplication().getDocument(DocName);
00586 else
00587 pcDoc = App::GetApplication().getActiveDocument();
00588
00589 if (!pcDoc) {
00590 pcDoc = App::GetApplication().newDocument(DocName);
00591 }
00592
00593 std::auto_ptr<FemMesh> mesh(new FemMesh);
00594 mesh->read(Name);
00595 Base::FileInfo file(Name);
00596 FemMeshObject *pcFeature = static_cast<FemMeshObject *>
00597 (pcDoc->addObject("Fem::FemMeshObject", file.fileNamePure().c_str()));
00598 pcFeature->Label.setValue(file.fileNamePure().c_str());
00599 pcFeature->FemMesh.setValuePtr(mesh.get());
00600 (void)mesh.release();
00601 pcFeature->purgeTouched();
00602 } PY_CATCH;
00603
00604 Py_Return;
00605 }
00606
00607
00608 static PyObject * import_NASTRAN(PyObject *self, PyObject *args)
00609 {
00610 const char* filename_input, *filename_output;
00611 if (!PyArg_ParseTuple(args, "ss",&filename_input,&filename_output))
00612 return NULL;
00613
00614 PY_TRY {
00615
00616 std::ifstream inputfile;
00617
00618
00619 ofstream anOutput;
00620 anOutput.open("c:/time_measurement.txt");
00621 time_t seconds1,seconds2;
00622
00623 inputfile.open(filename_input);
00624 if (!inputfile.is_open())
00625 {
00626 std::cerr << "File not found. Exiting..." << std::endl;
00627 return NULL;
00628 }
00629
00630
00631 inputfile.seekg(std::ifstream::beg);
00632 std::string line1,line2,temp;
00633 std::stringstream astream;
00634 std::vector<unsigned int> tetra_element;
00635 std::vector<unsigned int> element_id;
00636 element_id.clear();
00637 std::vector<std::vector<unsigned int> > all_elements;
00638 std::vector<std::vector<unsigned int> >::iterator all_element_iterator;
00639 std::vector<unsigned int>::iterator one_element_iterator;
00640 all_elements.clear();
00641 MeshCore::MeshKernel aMesh;
00642 MeshCore::MeshPointArray vertices;
00643 vertices.clear();
00644 MeshCore::MeshFacetArray faces;
00645 faces.clear();
00646 MeshCore::MeshPoint current_node;
00647
00648 seconds1 = time(NULL);
00649 do
00650 {
00651 std::getline(inputfile,line1);
00652 if (line1.size() == 0) continue;
00653 if (line1.find("GRID*")!= std::string::npos)
00654 {
00655
00656
00657
00658 std::getline(inputfile,line2);
00659
00660 current_node.x = float(atof(line1.substr(40,56).c_str()));
00661
00662 current_node.y = float(atof(line1.substr(56,72).c_str()));
00663
00664 current_node.z = float(atof(line2.substr(8,24).c_str()));
00665
00666 vertices.push_back(current_node);
00667 }
00668 else if (line1.find("CTETRA")!= std::string::npos)
00669 {
00670 tetra_element.clear();
00671
00672
00673
00674
00675 std::getline(inputfile,line2);
00676 element_id.push_back(atoi(line1.substr(8,16).c_str()));
00677 tetra_element.push_back(atoi(line1.substr(24,32).c_str()));
00678 tetra_element.push_back(atoi(line1.substr(32,40).c_str()));
00679 tetra_element.push_back(atoi(line1.substr(40,48).c_str()));
00680 tetra_element.push_back(atoi(line1.substr(48,56).c_str()));
00681 tetra_element.push_back(atoi(line1.substr(56,64).c_str()));
00682 tetra_element.push_back(atoi(line1.substr(64,72).c_str()));
00683 tetra_element.push_back(atoi(line2.substr(8,16).c_str()));
00684 tetra_element.push_back(atoi(line2.substr(16,24).c_str()));
00685 tetra_element.push_back(atoi(line2.substr(24,32).c_str()));
00686 tetra_element.push_back(atoi(line2.substr(32,40).c_str()));
00687
00688 all_elements.push_back(tetra_element);
00689 }
00690
00691 }
00692 while (inputfile.good());
00693 inputfile.close();
00694
00695 seconds2 = time(NULL);
00696
00697 anOutput << seconds2-seconds1 <<" for Parsing the input file"<<std::endl;
00698
00699
00700
00701 MeshCore::MeshFacet aFacet;
00702 aFacet._aulPoints[0] = 0;aFacet._aulPoints[1] = 1;aFacet._aulPoints[2] = 2;
00703 faces.push_back(aFacet);
00704
00705 aMesh.Assign(vertices,faces);
00706
00707 seconds1 = time(NULL);
00708
00709 MeshCore::MeshEigensystem pca(aMesh);
00710 pca.Evaluate();
00711 Base::Matrix4D Trafo = pca.Transform();
00712 aMesh.Transform(Trafo);
00714
00715 pca.Evaluate();
00716 Trafo = pca.Transform();
00717 Trafo.inverse();
00718 Base::Vector3f cog;
00719 cog.x = float(Trafo[0][3]);cog.y = float(Trafo[1][3]);cog.z = float(Trafo[2][3]);
00721
00722
00723 Base::Rotation rotatex,rotatey,rotatez;
00724 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);
00725
00726
00727 Base::Matrix4D final_trafo;
00728 Base::BoundBox3f aBBox,min_bbox;
00729
00730
00731 double volumeBBOX,min_volumeBBOX;
00732
00733
00734 aBBox = aMesh.GetBoundBox();
00735 min_volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
00736
00737
00738 MeshCore::MeshKernel atempkernel;
00739
00740 float it_steps=10.0;
00741 double step_size;
00742 double alpha_x=0.0,alpha_y=0.0,alpha_z=0.0;
00743 double perfect_ax=0.0,perfect_ay=0.0,perfect_az=0.0;
00744
00745
00746
00747 double angle_range_min_x=-PI/3.0,angle_range_max_x=PI/3.0,
00748 angle_range_min_y=-PI/3.0,angle_range_max_y=PI/3.0,
00749 angle_range_min_z=-PI/3.0,angle_range_max_z=PI/3.0;
00750
00751 for (step_size = (2.0*PI/it_steps);step_size>(2.0*PI/360.0);step_size=(2.0*PI/it_steps))
00752 {
00753 for(alpha_x=angle_range_min_x;alpha_x<angle_range_max_x;alpha_x=alpha_x+step_size)
00754 {
00755 rotatex.setValue(rotate_axis_x,alpha_x);
00756 for(alpha_y=angle_range_min_y;alpha_y<angle_range_max_y;alpha_y=alpha_y+step_size)
00757 {
00758 rotatey.setValue(rotate_axis_y,alpha_y);
00759 for(alpha_z=angle_range_min_z;alpha_z<angle_range_max_z;alpha_z=alpha_z+step_size)
00760 {
00761 rotatez.setValue(rotate_axis_z,alpha_z);
00762 (rotatex*rotatey*rotatez).getValue(final_trafo);
00763 atempkernel = aMesh;
00764 atempkernel.Transform(final_trafo);
00765 aBBox = atempkernel.GetBoundBox();
00766 volumeBBOX = aBBox.LengthX()*aBBox.LengthY()*aBBox.LengthZ();
00767 if (volumeBBOX < min_volumeBBOX)
00768 {
00769 min_volumeBBOX=volumeBBOX;
00770 perfect_ax=alpha_x;
00771 perfect_ay=alpha_y;
00772 perfect_az=alpha_z;
00773 }
00774 }
00775 }
00776 }
00777
00778
00779 angle_range_min_x = perfect_ax - step_size;
00780 angle_range_max_x = perfect_ax + step_size;
00781 angle_range_min_y = perfect_ay - step_size;
00782 angle_range_max_y = perfect_ay + step_size;
00783 angle_range_min_z = perfect_az - step_size;
00784 angle_range_max_z = perfect_az + step_size;
00785 it_steps = it_steps*float(5.0);
00786 }
00787
00789
00790
00791 atempkernel.Clear();
00792
00793
00794 rotatex.setValue(rotate_axis_x,perfect_ax);
00795 rotatey.setValue(rotate_axis_y,perfect_ay);
00796 rotatez.setValue(rotate_axis_z,perfect_az);
00797 (rotatex*rotatey*rotatez).getValue(final_trafo);
00798 aMesh.Transform(final_trafo);
00799
00800 anOutput << "perfect angles " << perfect_ax << "," << perfect_ay << "," << perfect_az << std::endl;
00801
00802
00803
00804 aBBox = aMesh.GetBoundBox();
00805
00806 Base::Vector3f dist_vector;
00807 dist_vector.x = -aBBox.MinX;dist_vector.y=-aBBox.MinY;dist_vector.z=-aBBox.MinZ;
00808 Base::Matrix4D trans_matrix(
00809 float(1.0),float(0.0),float(0.0),dist_vector.x,
00810 float(0.0),float(1.0),float(0.0),dist_vector.y,
00811 float(0.0),float(0.0),float(1.0),dist_vector.z,
00812 float(0.0),float(0.0),float(0.0),float(1.0));
00813 aMesh.Transform(trans_matrix);
00815 seconds2=time(NULL);
00816 anOutput << seconds2-seconds1 << " seconds for the min bounding box stuff" << std::endl;
00817
00818 seconds1 = time(NULL);
00819
00820
00821 SMESH_Gen* meshgen = new SMESH_Gen();
00822 SMESH_Mesh* mesh = meshgen->CreateMesh(1, true);
00823 SMESHDS_Mesh* meshds = mesh->GetMeshDS();
00824
00825 MeshCore::MeshPointIterator anodeiterator(aMesh);
00826 int j=1;
00827 for(anodeiterator.Begin(); anodeiterator.More(); anodeiterator.Next())
00828 {
00829 meshds->AddNodeWithID((*anodeiterator).x,(*anodeiterator).y,(*anodeiterator).z,j);
00830 j++;
00831 }
00832
00833 for(unsigned int i=0;i<all_elements.size();i++)
00834 {
00835
00836
00837 meshds->AddVolumeWithID(
00838 meshds->FindNode(all_elements[i][0]),
00839 meshds->FindNode(all_elements[i][2]),
00840 meshds->FindNode(all_elements[i][1]),
00841 meshds->FindNode(all_elements[i][3]),
00842 meshds->FindNode(all_elements[i][6]),
00843 meshds->FindNode(all_elements[i][5]),
00844 meshds->FindNode(all_elements[i][4]),
00845 meshds->FindNode(all_elements[i][9]),
00846 meshds->FindNode(all_elements[i][7]),
00847 meshds->FindNode(all_elements[i][8]),
00848 element_id[i]
00849 );
00850 }
00851
00852 mesh->ExportUNV(filename_output);
00854 seconds2 = time(NULL);
00855 anOutput << seconds2-seconds1 << " seconds for the Mesh Export" << std::endl;
00856
00857
00858 ofstream anABAQUS_Output;
00859 anABAQUS_Output.open("d:/abaqus_output.inp");
00860 anABAQUS_Output << "*Node , NSET=Nall" << std::endl;
00861 j=1;
00862 for(anodeiterator.Begin(); anodeiterator.More(); anodeiterator.Next())
00863 {
00864 anABAQUS_Output << j <<","
00865 <<(*anodeiterator).x << ","
00866 <<(*anodeiterator).y << ","
00867 <<(*anodeiterator).z << std::endl;
00868 j++;
00869 }
00870 anABAQUS_Output << "*Element, TYPE=C3D10, ELSET=Eall" << std::endl;
00871 j=1;
00872 for(unsigned int i=0;i<all_elements.size();i++)
00873 {
00874
00875 anABAQUS_Output
00876 <<j <<","
00877 <<all_elements[i][0]<<","
00878 <<all_elements[i][1]<<","
00879 <<all_elements[i][2]<<","
00880 <<all_elements[i][3]<<","
00881 <<all_elements[i][4]<<","
00882 <<all_elements[i][5]<<","
00883 <<all_elements[i][6]<<","
00884 <<all_elements[i][7]<<","
00885 <<all_elements[i][8]<<","
00886 <<all_elements[i][9]<<std::endl;
00887 j++;
00888 }
00889 anABAQUS_Output.close();
00891
00892
00893
00894
00895
00896 Base::Vector3f a,b,c,a_b_product;
00897 double volume = 0.0;
00898 seconds1 = time(NULL);
00899
00900 for(all_element_iterator = all_elements.begin();all_element_iterator != all_elements.end();all_element_iterator++)
00901 {
00902
00903 a = vertices[all_element_iterator->at(4)-1]-vertices[all_element_iterator->at(0)-1];
00904 b = vertices[all_element_iterator->at(7)-1]-vertices[all_element_iterator->at(0)-1];
00905 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(0)-1];
00906 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;
00907 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00908
00909 a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(4)-1];
00910 b = vertices[all_element_iterator->at(7)-1]-vertices[all_element_iterator->at(4)-1];
00911 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(4)-1];
00912 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;
00913 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00914
00915 a = vertices[all_element_iterator->at(1)-1]-vertices[all_element_iterator->at(4)-1];
00916 b = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(4)-1];
00917 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(4)-1];
00918 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;
00919 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00920
00921 a = vertices[all_element_iterator->at(5)-1]-vertices[all_element_iterator->at(1)-1];
00922 b = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(1)-1];
00923 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(1)-1];
00924 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;
00925 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00926
00927 a = vertices[all_element_iterator->at(5)-1]-vertices[all_element_iterator->at(8)-1];
00928 b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(8)-1];
00929 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(8)-1];
00930 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;
00931 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00932
00933 a = vertices[all_element_iterator->at(2)-1]-vertices[all_element_iterator->at(5)-1];
00934 b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(5)-1];
00935 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(5)-1];
00936 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;
00937 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00938
00939 a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(7)-1];
00940 b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(7)-1];
00941 c = vertices[all_element_iterator->at(6)-1]-vertices[all_element_iterator->at(7)-1];
00942 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;
00943 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00944
00945 a = vertices[all_element_iterator->at(8)-1]-vertices[all_element_iterator->at(7)-1];
00946 b = vertices[all_element_iterator->at(9)-1]-vertices[all_element_iterator->at(7)-1];
00947 c = vertices[all_element_iterator->at(3)-1]-vertices[all_element_iterator->at(7)-1];
00948 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;
00949 volume += 1.0/6.0 * fabs((a_b_product.x * c.x)+ (a_b_product.y * c.y)+(a_b_product.z * c.z));
00950
00951 }
00952 seconds2=time(NULL);
00953 anOutput << seconds2-seconds1 << " seconds for Volume Calculation " << "Volumen " << volume/1000.0/1000.0/1000.0 << " in m^3" << std::endl;
00954 anOutput << "Volumen der BBox" << min_volumeBBOX/1000.0/1000.0/1000.0 << std::endl;
00955 anOutput << "Fly to Buy Ratio: " << min_volumeBBOX / volume << std::endl;
00956 anOutput.close();
00957
00958 } PY_CATCH;
00959
00960 Py_Return;
00961 }
00962
00963
00964 static PyObject * exporter(PyObject *self, PyObject *args)
00965 {
00966 PyObject* object;
00967 const char* filename;
00968 if (!PyArg_ParseTuple(args, "Os",&object,&filename))
00969 return NULL;
00970
00971 PY_TRY {
00972 Py::List list(object);
00973 Base::Type meshId = Base::Type::fromName("Fem::FemMeshObject");
00974 for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00975 PyObject* item = (*it).ptr();
00976 if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
00977 App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
00978 if (obj->getTypeId().isDerivedFrom(meshId)) {
00979 static_cast<FemMeshObject*>(obj)->FemMesh.getValue().write(filename);
00980 break;
00981 }
00982 }
00983 }
00984 } PY_CATCH;
00985
00986 Py_Return;
00987 }
00988
00989
00990
00991 PyDoc_STRVAR(open_doc,
00992 "open(string) -- Create a new document and a Mesh::Import feature to load the file into the document.");
00993
00994 PyDoc_STRVAR(inst_doc,
00995 "insert(string|mesh,[string]) -- Load or insert a mesh into the given or active document.");
00996
00997 PyDoc_STRVAR(export_doc,
00998 "export(list,string) -- Export a list of objects into a single file.");
00999
01000
01001 struct PyMethodDef Fem_methods[] = {
01002 {"open" ,open , METH_VARARGS, open_doc},
01003 {"insert" ,importer, METH_VARARGS, inst_doc},
01004 {"export" ,exporter, METH_VARARGS, export_doc},
01005 {"read" ,read, Py_NEWARGS, "Read a mesh from a file and returns a Mesh object."},
01006 {"calcMeshVolume", calcMeshVolume, Py_NEWARGS, "Calculate Mesh Volume for C3D10"},
01007 {"getBoundary_Conditions" , getBoundary_Conditions, Py_NEWARGS, "Get Boundary Conditions for Residual Stress Calculation"},
01008 {"SMESH_PCA" , SMESH_PCA, Py_NEWARGS, "Get a Matrix4D related to the PCA of a Mesh Object"},
01009 {"import_NASTRAN",import_NASTRAN, Py_NEWARGS, "Test"},
01010 {"minBoundingBox",minBoundingBox,Py_NEWARGS,"Minimize the Bounding Box and reorient the mesh to the 1st Quadrant"},
01011 {"checkBB",checkBB,Py_NEWARGS,"Check if the nodal z-values are still in the prescribed range"},
01012 {NULL, NULL}
01013 };