Implementing Visual for FEM mesh higher degrees
- Tet10 - Add interface to insert higher degree nodes
This commit is contained in:
parent
1c9fe432f7
commit
82905f7be2
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue
Block a user