Implementing Visual for FEM mesh higher degrees

- Tet10
- Add interface to insert higher degree nodes
This commit is contained in:
jriegel 2013-02-17 15:38:14 +01:00
parent 1c9fe432f7
commit 82905f7be2
4 changed files with 526 additions and 55 deletions

View File

@ -116,6 +116,29 @@ static PyObject * open(PyObject *self, PyObject *args)
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 * SMESH_PCA(PyObject *self, PyObject *args)
{
@ -1079,10 +1102,15 @@ struct PyMethodDef Fem_methods[] = {
{"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."},
{"calcMeshVolume", calcMeshVolume, Py_NEWARGS, "Calculate Mesh Volume for C3D10"},
{"getBoundary_Conditions" , getBoundary_Conditions, Py_NEWARGS, "Get Boundary Conditions for Residual Stress Calculation"},
{"SMESH_PCA" , SMESH_PCA, Py_NEWARGS, "Get a Matrix4D related to the PCA of a Mesh Object"},
{"import_NASTRAN",import_NASTRAN, Py_NEWARGS, "Test"},
{"show" ,show ,METH_VARARGS,
"show(shape) -- Add the shape to the active document or create one if no document exists."},
{"calcMeshVolume", calcMeshVolume, Py_NEWARGS,
"Calculate Mesh Volume for C3D10"},
{"getBoundary_Conditions" , getBoundary_Conditions, Py_NEWARGS,
"Get Boundary Conditions for Residual Stress Calculation"},
{"SMESH_PCA" , SMESH_PCA, Py_NEWARGS,
"Get a Matrix4D related to the PCA of a Mesh Object"},
{"import_NASTRAN",import_NASTRAN, Py_NEWARGS, "Import Nastran files, for tests only. Use read() or insert()"},
{"minBoundingBox",minBoundingBox,Py_NEWARGS,"Minimize the Bounding Box and reorient the mesh to the 1st Quadrant"},
{"checkBB",checkBB,Py_NEWARGS,"Check if the nodal z-values are still in the prescribed range"},
{NULL, NULL} /* sentinel */

View File

@ -44,7 +44,6 @@
#include "FemMeshPy.cpp"
#include "HypothesisPy.h"
using namespace Fem;
// returns a string which represents the object e.g. when printed in python
@ -193,27 +192,67 @@ PyObject* FemMeshPy::addEdge(PyObject *args)
PyObject* FemMeshPy::addFace(PyObject *args)
{
int n1,n2,n3;
if (!PyArg_ParseTuple(args, "iii",&n1,&n2,&n3))
return 0;
SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh();
SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
int n1,n2,n3;
if (PyArg_ParseTuple(args, "iii",&n1,&n2,&n3))
{
// old form, debrekadet
try {
const SMDS_MeshNode* node1 = meshDS->FindNode(n1);
const SMDS_MeshNode* node2 = meshDS->FindNode(n2);
const SMDS_MeshNode* node3 = meshDS->FindNode(n3);
if (!node1 || !node2 || !node3)
throw std::runtime_error("Failed to get node of the given indices");
SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3);
if (!face)
throw std::runtime_error("Failed to add face");
return Py::new_reference_to(Py::Int(face->GetID()));
}
catch (const std::exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}
}
PyErr_Clear();
PyObject *obj;
int ElementId=-1;
float min_eps = 1.0e-2f;
if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId))
{
Py::List list(obj);
std::vector<const SMDS_MeshNode*> Nodes;
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
Py::Int NoNr(*it);
const SMDS_MeshNode* node = meshDS->FindNode(NoNr);
if (!node)
throw std::runtime_error("Failed to get node of the given indices");
Nodes.push_back(node);
}
SMDS_MeshFace* face=0;
switch(Nodes.size()){
case 3:
face = meshDS->AddFace(Nodes[0],Nodes[1],Nodes[2]);
if (!face)
throw std::runtime_error("Failed to add triangular face");
break;
default: throw std::runtime_error("Unknown node count, [3|4|6|8] are allowed"); //unknown face type
}
try {
SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh();
SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
const SMDS_MeshNode* node1 = meshDS->FindNode(n1);
const SMDS_MeshNode* node2 = meshDS->FindNode(n2);
const SMDS_MeshNode* node3 = meshDS->FindNode(n3);
if (!node1 || !node2 || !node3)
throw std::runtime_error("Failed to get node of the given indices");
SMDS_MeshFace* face = meshDS->AddFace(node1, node2, node3);
if (!face)
throw std::runtime_error("Failed to add face");
return Py::new_reference_to(Py::Int(face->GetID()));
}
catch (const std::exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}
PyErr_SetString(PyExc_TypeError, "Line constructor accepts:\n"
"-- empty parameter list\n"
"-- Line\n"
"-- Point, Point");
return 0;
}
PyObject* FemMeshPy::addQuad(PyObject *args)
@ -244,28 +283,72 @@ PyObject* FemMeshPy::addQuad(PyObject *args)
PyObject* FemMeshPy::addVolume(PyObject *args)
{
int n1,n2,n3,n4;
if (!PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4))
return 0;
SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh();
SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
int n1,n2,n3,n4;
if (PyArg_ParseTuple(args, "iiii",&n1,&n2,&n3,&n4))
{
try {
const SMDS_MeshNode* node1 = meshDS->FindNode(n1);
const SMDS_MeshNode* node2 = meshDS->FindNode(n2);
const SMDS_MeshNode* node3 = meshDS->FindNode(n3);
const SMDS_MeshNode* node4 = meshDS->FindNode(n4);
if (!node1 || !node2 || !node3 || !node4)
throw std::runtime_error("Failed to get node of the given indices");
SMDS_MeshVolume* vol = meshDS->AddVolume(node1, node2, node3, node4);
if (!vol)
throw std::runtime_error("Failed to add volume");
return Py::new_reference_to(Py::Int(vol->GetID()));
}
catch (const std::exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}
}
PyErr_Clear();
PyObject *obj;
int ElementId=-1;
float min_eps = 1.0e-2f;
if (PyArg_ParseTuple(args, "O!|i", &PyList_Type, &obj, &ElementId))
{
Py::List list(obj);
std::vector<const SMDS_MeshNode*> Nodes;
for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
Py::Int NoNr(*it);
const SMDS_MeshNode* node = meshDS->FindNode(NoNr);
if (!node)
throw std::runtime_error("Failed to get node of the given indices");
Nodes.push_back(node);
}
SMDS_MeshVolume* vol=0;
switch(Nodes.size()){
case 4:
vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3]);
if (!vol)
throw std::runtime_error("Failed to add Tet4 volume");
break;
case 10:
vol = meshDS->AddVolume(Nodes[0],Nodes[1],Nodes[2],Nodes[3],Nodes[4],Nodes[5],Nodes[6],Nodes[7],Nodes[8],Nodes[9]);
if (!vol)
throw std::runtime_error("Failed to add Tet10 volume");
break;
default: throw std::runtime_error("Unknown node count, [4|5|6|8|10|13|18] are allowed"); //unknown face type
}
try {
SMESH_Mesh* mesh = getFemMeshPtr()->getSMesh();
SMESHDS_Mesh* meshDS = mesh->GetMeshDS();
const SMDS_MeshNode* node1 = meshDS->FindNode(n1);
const SMDS_MeshNode* node2 = meshDS->FindNode(n2);
const SMDS_MeshNode* node3 = meshDS->FindNode(n3);
const SMDS_MeshNode* node4 = meshDS->FindNode(n4);
if (!node1 || !node2 || !node3 || !node4)
throw std::runtime_error("Failed to get node of the given indices");
SMDS_MeshVolume* vol = meshDS->AddVolume(node1, node2, node3, node4);
if (!vol)
throw std::runtime_error("Failed to add volume");
return Py::new_reference_to(Py::Int(vol->GetID()));
}
catch (const std::exception& e) {
PyErr_SetString(PyExc_Exception, e.what());
return 0;
}
PyErr_SetString(PyExc_TypeError, "Line constructor accepts:\n"
"-- empty parameter list\n"
"-- Line\n"
"-- Point, Point");
return 0;
}
PyObject* FemMeshPy::copy(PyObject *args)

View File

@ -57,9 +57,110 @@
#include <SMESH_Mesh.hxx>
#include <SMESHDS_Mesh.hxx>
#include <SMDSAbs_ElementType.hxx>
using namespace FemGui;
struct FemFace
{
const SMDS_MeshNode *Nodes[8];
unsigned long ElementNumber;
const SMDS_MeshElement* Element;
unsigned short Size;
unsigned short FaceNo;
bool hide;
void set(short size,const SMDS_MeshElement* element,unsigned short id, short faceNo, const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4=0,const SMDS_MeshNode* n5=0,const SMDS_MeshNode* n6=0,const SMDS_MeshNode* n7=0,const SMDS_MeshNode* n8=0);
bool isSameFace (FemFace &face);
};
void FemFace::set(short size,const SMDS_MeshElement* element,unsigned short id,short faceNo, const SMDS_MeshNode* n1,const SMDS_MeshNode* n2,const SMDS_MeshNode* n3,const SMDS_MeshNode* n4,const SMDS_MeshNode* n5,const SMDS_MeshNode* n6,const SMDS_MeshNode* n7,const SMDS_MeshNode* n8)
{
Nodes[0] = n1;
Nodes[1] = n2;
Nodes[2] = n3;
Nodes[3] = n4;
Nodes[4] = n5;
Nodes[5] = n6;
Nodes[6] = n7;
Nodes[7] = n8;
Element = element;
ElementNumber = id;
Size = size;
FaceNo = faceNo;
hide = false;
// sorting the nodes for later easier comparison (bubble sort)
int i, j, flag = 1; // set flag to 1 to start first pass
const SMDS_MeshNode* temp; // holding variable
for(i = 1; (i <= size) && flag; i++)
{
flag = 0;
for (j=0; j < (size -1); j++)
{
if (Nodes[j+1] > Nodes[j]) // ascending order simply changes to <
{
temp = Nodes[j]; // swap elements
Nodes[j] = Nodes[j+1];
Nodes[j+1] = temp;
flag = 1; // indicates that a swap occurred.
}
}
}
};
bool FemFace::isSameFace (FemFace &face)
{
// the same element can not have the same face
if(face.ElementNumber == ElementNumber)
return false;
if(face.Size == Size){
// if the same face size just compare if the sorted nodes are the same
if( Nodes[0] == face.Nodes[0] &&
Nodes[1] == face.Nodes[1] &&
Nodes[2] == face.Nodes[2] &&
Nodes[3] == face.Nodes[3] &&
Nodes[4] == face.Nodes[4] &&
Nodes[5] == face.Nodes[5] &&
Nodes[6] == face.Nodes[6] &&
Nodes[7] == face.Nodes[7] ){
hide = true;
face.hide = true;
return true;
}
}else{
// TODO: normaly no valid net
// // if the size is not the same test if the nodes are a subset
// bool breakIt = false;
//
// if(Size < face.Size){
// for(int i=0; i<Size;i++){
// int j;
//for(j=0; j< face.Size ;j++)
// if(Nodes[i] == face.Nodes[j])
// break;
// if(j==face.Size) return false;
// }
// hide = true;
// return true;
// }else{
// return false;
// }
// assert(0);
}
};
PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject)
App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0f,64.0f,1.0f};
@ -77,18 +178,20 @@ ViewProviderFemMesh::ViewProviderFemMesh()
ADD_PROPERTY(PointColor,(mat.diffuseColor));
ADD_PROPERTY(PointSize,(2.0f));
PointSize.setConstraints(&floatRange);
ADD_PROPERTY(LineWidth,(1.0f));
ADD_PROPERTY(LineWidth,(4.0f));
LineWidth.setConstraints(&floatRange);
ADD_PROPERTY(BackfaceCulling,(true));
ADD_PROPERTY(ShowInner, (false));
pcDrawStyle = new SoDrawStyle();
pcDrawStyle->ref();
pcDrawStyle->style = SoDrawStyle::LINES;
pcDrawStyle->lineWidth = LineWidth.getValue();
pShapeHints = new SoShapeHints;
pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
pShapeHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING;
pShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
pShapeHints->shapeType = SoShapeHints::SOLID;
pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE;
pShapeHints->ref();
pcMatBinding = new SoMaterialBinding;
@ -200,7 +303,7 @@ void ViewProviderFemMesh::updateData(const App::Property* prop)
{
if (prop->isDerivedFrom(Fem::PropertyFemMesh::getClassTypeId())) {
ViewProviderFEMMeshBuilder builder;
builder.createMesh(prop, pcCoords, pcFaces);
builder.createMesh(prop, pcCoords, pcFaces,ShowInner.getValue());
}
Gui::ViewProviderGeometryObject::updateData(prop);
}
@ -216,6 +319,20 @@ void ViewProviderFemMesh::onChanged(const App::Property* prop)
if (c != PointMaterial.getValue().diffuseColor)
PointMaterial.setDiffuseColor(c);
}
else if (prop == &BackfaceCulling) {
if(BackfaceCulling.getValue()){
pShapeHints->shapeType = SoShapeHints::SOLID;
//pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE;
}else{
pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
//pShapeHints->vertexOrdering = SoShapeHints::CLOCKWISE;
}
}
else if (prop == &ShowInner) {
// recalc mesh with new settings
ViewProviderFEMMeshBuilder builder;
builder.createMesh(&(dynamic_cast<Fem::FemMeshObject*>(this->pcObject)->FemMesh), pcCoords, pcFaces,ShowInner.getValue());
}
else if (prop == &PointMaterial) {
const App::Material& Mat = PointMaterial.getValue();
if (PointColor.getValue() != Mat.diffuseColor)
@ -258,23 +375,262 @@ void ViewProviderFEMMeshBuilder::buildNodes(const App::Property* prop, std::vect
if (pcPointsCoord && pcFaces)
createMesh(prop, pcPointsCoord, pcFaces);
}
#if 1 // new visual
void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordinate3* coords, SoIndexedFaceSet* faces,bool ShowInner) const
{
const Fem::PropertyFemMesh* mesh = static_cast<const Fem::PropertyFemMesh*>(prop);
SMESHDS_Mesh* data = const_cast<SMESH_Mesh*>(mesh->getValue().getSMesh())->GetMeshDS();
int numFaces = data->NbFaces();
int numNodes = data->NbNodes();
int numEdges = data->NbEdges();
const SMDS_MeshInfo& info = data->GetMeshInfo();
int numNode = info.NbNodes();
int numTria = info.NbTriangles();
int numQuad = info.NbQuadrangles();
int numPoly = info.NbPolygons();
int numVolu = info.NbVolumes();
int numTetr = info.NbTetras();
int numHexa = info.NbHexas();
int numPyrd = info.NbPyramids();
int numPris = info.NbPrisms();
int numHedr = info.NbPolyhedrons();
std::vector<FemFace> facesHelper(numTria+numQuad+numPoly+numTetr*4+numHexa*6+numPyrd*5+numPris*6);
SMDS_VolumeIteratorPtr aVolIter = data->volumesIterator();
for (int i=0;aVolIter->more();) {
const SMDS_MeshVolume* aVol = aVolIter->next();
int num = aVol->NbNodes();
switch(num){
// tet 4 element
case 4:
// face 1
facesHelper[i++].set(3,aVol,aVol->GetID(),1,aVol->GetNode(0),aVol->GetNode(1),aVol->GetNode(2));
// face 2
facesHelper[i++].set(3,aVol,aVol->GetID(),2,aVol->GetNode(0),aVol->GetNode(3),aVol->GetNode(1));
// face 3
facesHelper[i++].set(3,aVol,aVol->GetID(),3,aVol->GetNode(1),aVol->GetNode(3),aVol->GetNode(2));
// face 4
facesHelper[i++].set(3,aVol,aVol->GetID(),4,aVol->GetNode(2),aVol->GetNode(3),aVol->GetNode(0));
break;
//unknown case
case 10:
// face 1
facesHelper[i++].set(6,aVol,aVol->GetID(),1,aVol->GetNode(0),aVol->GetNode(1),aVol->GetNode(2),aVol->GetNode(4),aVol->GetNode(5),aVol->GetNode(6));
// face 2
facesHelper[i++].set(6,aVol,aVol->GetID(),2,aVol->GetNode(0),aVol->GetNode(3),aVol->GetNode(7),aVol->GetNode(1),aVol->GetNode(8),aVol->GetNode(4));
// face 3
facesHelper[i++].set(6,aVol,aVol->GetID(),3,aVol->GetNode(1),aVol->GetNode(3),aVol->GetNode(8),aVol->GetNode(2),aVol->GetNode(9),aVol->GetNode(5));
// face 4
facesHelper[i++].set(6,aVol,aVol->GetID(),4,aVol->GetNode(2),aVol->GetNode(3),aVol->GetNode(9),aVol->GetNode(0),aVol->GetNode(7),aVol->GetNode(6));
break;
//unknown case
default: assert(0);
}
}
int FaceSize = facesHelper.size();
// search for double (inside) faces and hide them
if(!ShowInner){
for(int l=0; l< FaceSize;l++){
if(! facesHelper[l].hide){
for(int i=l+1; i<FaceSize; i++){
if(facesHelper[l].isSameFace(facesHelper[i]) ){
break;
}
}
}
}
}
// sort out double nodes and build up index map
std::map<const SMDS_MeshNode*, int> mapNodeIndex;
for(int l=0; l< FaceSize;l++){
if(!facesHelper[l].hide)
for(int i=0; i<8;i++)
if(facesHelper[l].Nodes[i])
mapNodeIndex[facesHelper[l].Nodes[i]]=0;
else
break;
}
// set the point coordinates
coords->point.setNum(mapNodeIndex.size());
std::map<const SMDS_MeshNode*, int>::iterator it= mapNodeIndex.begin();
SbVec3f* verts = coords->point.startEditing();
for (int i=0;it != mapNodeIndex.end() ;++it,i++) {
verts[i].setValue((float)it->first->X(),(float)it->first->Y(),(float)it->first->Z());
it->second = i;
}
coords->point.finishEditing();
// count triangle size
int triangleCount=0;
for(int l=0; l< FaceSize;l++)
if(! facesHelper[l].hide)
switch(facesHelper[l].Size){
case 3:triangleCount++ ;break;
case 6:triangleCount+=4 ;break;
default: assert(0);
}
// set the triangle face indices
faces->coordIndex.setNum(4*triangleCount);
int index=0;
int32_t* indices = faces->coordIndex.startEditing();
// iterate all element faces, allways assure CLOCKWISE triangle ordering to allow backface culling
for(int l=0; l< FaceSize;l++){
if(! facesHelper[l].hide){
switch( facesHelper[l].Element->NbNodes()){
case 4: // Tet 4
switch(facesHelper[l].FaceNo){
case 1: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 2: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 3: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 4: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = SO_END_FACE_INDEX;
break; }
default: assert(0);
}
break;
case 10: // Tet 10
switch(facesHelper[l].FaceNo){
case 1: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 2: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(4)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 3: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(1)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(5)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(8)];
indices[index++] = SO_END_FACE_INDEX;
break; }
case 4: {
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(0)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(2)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(3)];
indices[index++] = SO_END_FACE_INDEX;
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(6)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(7)];
indices[index++] = mapNodeIndex[facesHelper[l].Element->GetNode(9)];
indices[index++] = SO_END_FACE_INDEX;
break; }
default: assert(0);
}
break;
default:assert(0); // not implemented node
}
}
}
faces->coordIndex.finishEditing();
}
#else // old version of createMesh()
void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordinate3* coords, SoIndexedFaceSet* faces) const
{
const Fem::PropertyFemMesh* mesh = static_cast<const Fem::PropertyFemMesh*>(prop);
SMESHDS_Mesh* data = const_cast<SMESH_Mesh*>(mesh->getValue().getSMesh())->GetMeshDS();
const SMDS_MeshInfo& info = data->GetMeshInfo();
int numFaces = data->NbFaces();
int numNodes = data->NbNodes ();
int numEdges = data->NbEdges ();
const SMDS_MeshInfo& info = data->GetMeshInfo();
int numNode = info.NbNodes();
int numTria = info.NbTriangles();
int numQuad = info.NbQuadrangles();
//int numPoly = info.NbPolygons();
//int numVolu = info.NbVolumes();
int numPoly = info.NbPolygons();
int numVolu = info.NbVolumes();
int numTetr = info.NbTetras();
//int numHexa = info.NbHexas();
//int numPyrd = info.NbPyramids();
//int numPris = info.NbPrisms();
//int numHedr = info.NbPolyhedrons();
int numHexa = info.NbHexas();
int numPyrd = info.NbPyramids();
int numPris = info.NbPrisms();
int numHedr = info.NbPolyhedrons();
int index=0;
std::map<const SMDS_MeshNode*, int> mapNodeIndex;
@ -295,6 +651,7 @@ void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordin
index=0;
faces->coordIndex.setNum(4*numTria + 5*numQuad + 16*numTetr);
int32_t* indices = faces->coordIndex.startEditing();
// iterate all faces
SMDS_FaceIteratorPtr aFaceIter = data->facesIterator();
for (;aFaceIter->more();) {
const SMDS_MeshFace* aFace = aFaceIter->next();
@ -336,3 +693,4 @@ void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordin
}
faces->coordIndex.finishEditing();
}
#endif

View File

@ -42,7 +42,7 @@ public:
ViewProviderFEMMeshBuilder(){}
~ViewProviderFEMMeshBuilder(){}
virtual void buildNodes(const App::Property*, std::vector<SoNode*>&) const;
void createMesh(const App::Property*, SoCoordinate3*, SoIndexedFaceSet*) const;
void createMesh(const App::Property*, SoCoordinate3*, SoIndexedFaceSet*,bool ShowInner=false) const;
};
class FemGuiExport ViewProviderFemMesh : public Gui::ViewProviderGeometryObject
@ -61,6 +61,8 @@ public:
App::PropertyFloatConstraint PointSize;
App::PropertyFloatConstraint LineWidth;
App::PropertyMaterial PointMaterial;
App::PropertyBool BackfaceCulling;
App::PropertyBool ShowInner;
void attach(App::DocumentObject *pcObject);
void setDisplayMode(const char* ModeName);