From 82905f7be2ced4dceeda49a6f25bbe8912a9ffef Mon Sep 17 00:00:00 2001 From: jriegel Date: Sun, 17 Feb 2013 15:38:14 +0100 Subject: [PATCH] Implementing Visual for FEM mesh higher degrees - Tet10 - Add interface to insert higher degree nodes --- src/Mod/Fem/App/AppFemPy.cpp | 36 ++- src/Mod/Fem/App/FemMeshPyImp.cpp | 159 +++++++--- src/Mod/Fem/Gui/ViewProviderFemMesh.cpp | 382 +++++++++++++++++++++++- src/Mod/Fem/Gui/ViewProviderFemMesh.h | 4 +- 4 files changed, 526 insertions(+), 55 deletions(-) diff --git a/src/Mod/Fem/App/AppFemPy.cpp b/src/Mod/Fem/App/AppFemPy.cpp index 9bb9cead4..d0f006e8f 100755 --- a/src/Mod/Fem/App/AppFemPy.cpp +++ b/src/Mod/Fem/App/AppFemPy.cpp @@ -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(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 */ diff --git a/src/Mod/Fem/App/FemMeshPyImp.cpp b/src/Mod/Fem/App/FemMeshPyImp.cpp index 3ca370f03..e31ca7e08 100755 --- a/src/Mod/Fem/App/FemMeshPyImp.cpp +++ b/src/Mod/Fem/App/FemMeshPyImp.cpp @@ -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 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 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) diff --git a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp index c90862b77..61ea77f60 100755 --- a/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp +++ b/src/Mod/Fem/Gui/ViewProviderFemMesh.cpp @@ -57,9 +57,110 @@ #include #include +#include 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; iref(); 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(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(prop); + + SMESHDS_Mesh* data = const_cast(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 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 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::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(prop); SMESHDS_Mesh* data = const_cast(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 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 \ No newline at end of file diff --git a/src/Mod/Fem/Gui/ViewProviderFemMesh.h b/src/Mod/Fem/Gui/ViewProviderFemMesh.h index eef906dc3..6ca347c87 100755 --- a/src/Mod/Fem/Gui/ViewProviderFemMesh.h +++ b/src/Mod/Fem/Gui/ViewProviderFemMesh.h @@ -42,7 +42,7 @@ public: ViewProviderFEMMeshBuilder(){} ~ViewProviderFEMMeshBuilder(){} virtual void buildNodes(const App::Property*, std::vector&) 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);