ViewProviderFemMesh.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2008 Jürgen Riegel (juergen.riegel@web.de)              *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <Standard_math.hxx>
00028 # include <Inventor/SoDB.h>
00029 # include <Inventor/SoInput.h>
00030 # include <Inventor/SbVec3f.h>
00031 # include <Inventor/actions/SoSearchAction.h>
00032 # include <Inventor/nodes/SoBaseColor.h>
00033 # include <Inventor/nodes/SoLightModel.h>
00034 # include <Inventor/nodes/SoMaterial.h>
00035 # include <Inventor/nodes/SoSeparator.h>
00036 # include <Inventor/nodes/SoTransform.h>
00037 # include <Inventor/nodes/SoRotation.h>
00038 # include <Inventor/nodes/SoCoordinate3.h>
00039 # include <Inventor/nodes/SoDrawStyle.h>
00040 # include <Inventor/nodes/SoIndexedFaceSet.h>
00041 # include <Inventor/nodes/SoShapeHints.h>
00042 # include <Inventor/nodes/SoPointSet.h>
00043 # include <Inventor/nodes/SoPolygonOffset.h>
00044 # include <QFile>
00045 #endif
00046 
00047 #include "ViewProviderFemMesh.h"
00048 
00049 #include <Mod/Fem/App/FemMeshObject.h>
00050 #include <Mod/Fem/App/FemMesh.h>
00051 #include <Gui/SoFCSelection.h>
00052 #include <App/Document.h>
00053 #include <Base/FileInfo.h>
00054 #include <Base/Stream.h>
00055 #include <Base/Console.h>
00056 #include <sstream>
00057 
00058 #include <SMESH_Mesh.hxx>
00059 #include <SMESHDS_Mesh.hxx>
00060 
00061 using namespace FemGui;
00062 
00063 PROPERTY_SOURCE(FemGui::ViewProviderFemMesh, Gui::ViewProviderGeometryObject)
00064 
00065 App::PropertyFloatConstraint::Constraints ViewProviderFemMesh::floatRange = {1.0f,64.0f,1.0f};
00066 
00067 ViewProviderFemMesh::ViewProviderFemMesh()
00068 {
00069     App::Material mat;
00070     mat.ambientColor.set(0.2f,0.2f,0.2f);
00071     mat.diffuseColor.set(0.1f,0.1f,0.1f);
00072     mat.specularColor.set(0.0f,0.0f,0.0f);
00073     mat.emissiveColor.set(0.0f,0.0f,0.0f);
00074     mat.shininess = 0.0f;
00075     mat.transparency = 0.0f;
00076     ADD_PROPERTY(PointMaterial,(mat));
00077     ADD_PROPERTY(PointColor,(mat.diffuseColor));
00078     ADD_PROPERTY(PointSize,(2.0f));
00079     PointSize.setConstraints(&floatRange);
00080     ADD_PROPERTY(LineWidth,(1.0f));
00081     LineWidth.setConstraints(&floatRange);
00082 
00083     pcDrawStyle = new SoDrawStyle();
00084     pcDrawStyle->ref();
00085     pcDrawStyle->style = SoDrawStyle::LINES;
00086     pcDrawStyle->lineWidth = LineWidth.getValue();
00087 
00088     pShapeHints = new SoShapeHints;
00089     pShapeHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00090     pShapeHints->vertexOrdering = SoShapeHints::UNKNOWN_ORDERING;
00091     pShapeHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00092     pShapeHints->ref();
00093 
00094     pcMatBinding = new SoMaterialBinding;
00095     pcMatBinding->value = SoMaterialBinding::OVERALL;
00096     pcMatBinding->ref();
00097 
00098     pcCoords = new SoCoordinate3();
00099     pcCoords->ref();
00100 
00101     pcFaces = new SoIndexedFaceSet;
00102     pcFaces->ref();
00103 
00104     pcPointStyle = new SoDrawStyle();
00105     pcPointStyle->ref();
00106     pcPointStyle->style = SoDrawStyle::POINTS;
00107     pcPointStyle->pointSize = PointSize.getValue();
00108 
00109     pcPointMaterial = new SoMaterial;
00110     pcPointMaterial->ref();
00111     PointMaterial.touch();
00112 
00113 }
00114 
00115 ViewProviderFemMesh::~ViewProviderFemMesh()
00116 {
00117     pcCoords->unref();
00118     pcDrawStyle->unref();
00119     pcFaces->unref();
00120     pShapeHints->unref();
00121     pcMatBinding->unref();
00122     pcPointMaterial->unref();
00123     pcPointStyle->unref();
00124 
00125 }
00126 
00127 void ViewProviderFemMesh::attach(App::DocumentObject *pcObj)
00128 {
00129     ViewProviderGeometryObject::attach(pcObj);
00130 
00131     // flat
00132     SoGroup* pcFlatRoot = new SoGroup();
00133     pcFlatRoot->addChild(pShapeHints);
00134     pcFlatRoot->addChild(pcShapeMaterial);
00135     pcFlatRoot->addChild(pcMatBinding);
00136     pcFlatRoot->addChild(pcHighlight);
00137     addDisplayMaskMode(pcFlatRoot, "Flat");
00138 
00139     // line
00140     SoLightModel* pcLightModel = new SoLightModel();
00141     pcLightModel->model = SoLightModel::BASE_COLOR;
00142     SoGroup* pcWireRoot = new SoGroup();
00143     pcWireRoot->addChild(pcDrawStyle);
00144     pcWireRoot->addChild(pcLightModel);
00145     SoBaseColor* color = new SoBaseColor();
00146     color->rgb.setValue(0.0f,0.0f,0.0f);
00147     pcWireRoot->addChild(color);
00148     pcWireRoot->addChild(pcHighlight);
00149     addDisplayMaskMode(pcWireRoot, "Wireframe");
00150 
00151     // flat+line
00152     SoPolygonOffset* offset = new SoPolygonOffset();
00153     offset->styles = SoPolygonOffset::LINES;
00154     offset->factor = -2.0f;
00155     offset->units = 1.0f;
00156     SoGroup* pcFlatWireRoot = new SoSeparator();
00157     pcFlatWireRoot->addChild(pcFlatRoot);
00158     pcFlatWireRoot->addChild(offset);
00159     pcFlatWireRoot->addChild(pcWireRoot);
00160     addDisplayMaskMode(pcFlatWireRoot, "Flat Lines");
00161 
00162     // Points
00163     SoGroup* pcPointsRoot = new SoSeparator();
00164     pcPointsRoot->addChild(pcPointMaterial);  
00165     pcPointsRoot->addChild(pcPointStyle);
00166     pcPointsRoot->addChild(pcCoords);
00167     SoPointSet * pointset = new SoPointSet;
00168     pcPointsRoot->addChild(pointset);
00169     addDisplayMaskMode(pcPointsRoot, "Points");
00170 
00171     pcHighlight->addChild(pcCoords);
00172     pcHighlight->addChild(pcFaces);
00173 }
00174 
00175 void ViewProviderFemMesh::setDisplayMode(const char* ModeName)
00176 {
00177     if (strcmp("Flat Lines",ModeName)==0)
00178         setDisplayMaskMode("Flat Lines");
00179     else if (strcmp("Shaded",ModeName)==0)
00180         setDisplayMaskMode("Flat");
00181     else if (strcmp("Wireframe",ModeName)==0)
00182         setDisplayMaskMode("Wireframe");
00183     else if (strcmp("Points",ModeName)==0)
00184         setDisplayMaskMode("Points");
00185 
00186     ViewProviderGeometryObject::setDisplayMode( ModeName );
00187 }
00188 
00189 std::vector<std::string> ViewProviderFemMesh::getDisplayModes(void) const
00190 {
00191     std::vector<std::string> StrList;
00192     StrList.push_back("Flat Lines");
00193     StrList.push_back("Shaded");
00194     StrList.push_back("Wireframe");
00195     StrList.push_back("Points");
00196     return StrList;
00197 }
00198 
00199 void ViewProviderFemMesh::updateData(const App::Property* prop)
00200 {
00201     if (prop->isDerivedFrom(Fem::PropertyFemMesh::getClassTypeId())) {
00202         ViewProviderFEMMeshBuilder builder;
00203         builder.createMesh(prop, pcCoords, pcFaces);
00204     }
00205     Gui::ViewProviderGeometryObject::updateData(prop);
00206 }
00207 
00208 void ViewProviderFemMesh::onChanged(const App::Property* prop)
00209 {
00210     if (prop == &PointSize) {
00211         pcPointStyle->pointSize = PointSize.getValue();
00212     }
00213     else if (prop == &PointColor) {
00214         const App::Color& c = PointColor.getValue();
00215         pcPointMaterial->diffuseColor.setValue(c.r,c.g,c.b);
00216         if (c != PointMaterial.getValue().diffuseColor)
00217         PointMaterial.setDiffuseColor(c);
00218     }
00219     else if (prop == &PointMaterial) {
00220         const App::Material& Mat = PointMaterial.getValue();
00221         if (PointColor.getValue() != Mat.diffuseColor)
00222         PointColor.setValue(Mat.diffuseColor);
00223         pcPointMaterial->ambientColor.setValue(Mat.ambientColor.r,Mat.ambientColor.g,Mat.ambientColor.b);
00224         pcPointMaterial->diffuseColor.setValue(Mat.diffuseColor.r,Mat.diffuseColor.g,Mat.diffuseColor.b);
00225         pcPointMaterial->specularColor.setValue(Mat.specularColor.r,Mat.specularColor.g,Mat.specularColor.b);
00226         pcPointMaterial->emissiveColor.setValue(Mat.emissiveColor.r,Mat.emissiveColor.g,Mat.emissiveColor.b);
00227         pcPointMaterial->shininess.setValue(Mat.shininess);
00228         pcPointMaterial->transparency.setValue(Mat.transparency);
00229     }
00230     else if (prop == &LineWidth) {
00231         pcDrawStyle->lineWidth = LineWidth.getValue();
00232     }
00233     else {
00234         ViewProviderGeometryObject::onChanged(prop);
00235     }
00236 }
00237 
00238 // ----------------------------------------------------------------------------
00239 
00240 void ViewProviderFEMMeshBuilder::buildNodes(const App::Property* prop, std::vector<SoNode*>& nodes) const
00241 {
00242     SoCoordinate3 *pcPointsCoord=0;
00243     SoIndexedFaceSet *pcFaces=0;
00244 
00245     if (nodes.empty()) {
00246         pcPointsCoord = new SoCoordinate3();
00247         nodes.push_back(pcPointsCoord);
00248         pcFaces = new SoIndexedFaceSet();
00249         nodes.push_back(pcFaces);
00250     }
00251     else if (nodes.size() == 2) {
00252         if (nodes[0]->getTypeId() == SoCoordinate3::getClassTypeId())
00253             pcPointsCoord = static_cast<SoCoordinate3*>(nodes[0]);
00254         if (nodes[1]->getTypeId() == SoIndexedFaceSet::getClassTypeId())
00255             pcFaces = static_cast<SoIndexedFaceSet*>(nodes[1]);
00256     }
00257 
00258     if (pcPointsCoord && pcFaces)
00259         createMesh(prop, pcPointsCoord, pcFaces);
00260 }
00261 
00262 void ViewProviderFEMMeshBuilder::createMesh(const App::Property* prop, SoCoordinate3* coords, SoIndexedFaceSet* faces) const
00263 {
00264     const Fem::PropertyFemMesh* mesh = static_cast<const Fem::PropertyFemMesh*>(prop);
00265 
00266     SMESHDS_Mesh* data = const_cast<SMESH_Mesh*>(mesh->getValue().getSMesh())->GetMeshDS();
00267     const SMDS_MeshInfo& info = data->GetMeshInfo();
00268     int numNode = info.NbNodes();
00269     int numTria = info.NbTriangles();
00270     int numQuad = info.NbQuadrangles();
00271     //int numPoly = info.NbPolygons();
00272     //int numVolu = info.NbVolumes();
00273     int numTetr = info.NbTetras();
00274     //int numHexa = info.NbHexas();
00275     //int numPyrd = info.NbPyramids();
00276     //int numPris = info.NbPrisms();
00277     //int numHedr = info.NbPolyhedrons();
00278 
00279     int index=0;
00280     std::map<const SMDS_MeshNode*, int> mapNodeIndex;
00281 
00282     // set the point coordinates
00283     coords->point.setNum(numNode);
00284     SMDS_NodeIteratorPtr aNodeIter = data->nodesIterator();
00285     unsigned int i=0;
00286     SbVec3f* verts = coords->point.startEditing();
00287     for (;aNodeIter->more();) {
00288         const SMDS_MeshNode* aNode = aNodeIter->next();
00289         verts[i++].setValue((float)aNode->X(),(float)aNode->Y(),(float)aNode->Z());
00290         mapNodeIndex[aNode] = index++;
00291     }
00292     coords->point.finishEditing();
00293 
00294     // set the face indices
00295     index=0;
00296     faces->coordIndex.setNum(4*numTria + 5*numQuad + 16*numTetr);
00297     int32_t* indices = faces->coordIndex.startEditing();
00298     SMDS_FaceIteratorPtr aFaceIter = data->facesIterator();
00299     for (;aFaceIter->more();) {
00300         const SMDS_MeshFace* aFace = aFaceIter->next();
00301         int num = aFace->NbNodes();
00302         if (num != 3 && num != 4)
00303             continue;
00304         for (int j=0; j<num;j++) {
00305             const SMDS_MeshNode* node = aFace->GetNode(j);
00306             indices[index++] = mapNodeIndex[node];
00307         }
00308         indices[index++] = SO_END_FACE_INDEX;
00309     }
00310     SMDS_VolumeIteratorPtr aVolIter = data->volumesIterator();
00311     for (;aVolIter->more();) {
00312         const SMDS_MeshVolume* aVol = aVolIter->next();
00313         int num = aVol->NbNodes();
00314         if (num != 4)
00315             continue;
00316         int i1 = mapNodeIndex[aVol->GetNode(0)];
00317         int i2 = mapNodeIndex[aVol->GetNode(1)];
00318         int i3 = mapNodeIndex[aVol->GetNode(2)];
00319         int i4 = mapNodeIndex[aVol->GetNode(3)];
00320         indices[index++] = i1;
00321         indices[index++] = i3;
00322         indices[index++] = i2;
00323         indices[index++] = SO_END_FACE_INDEX;
00324         indices[index++] = i1;
00325         indices[index++] = i2;
00326         indices[index++] = i4;
00327         indices[index++] = SO_END_FACE_INDEX;
00328         indices[index++] = i1;
00329         indices[index++] = i4;
00330         indices[index++] = i3;
00331         indices[index++] = SO_END_FACE_INDEX;
00332         indices[index++] = i2;
00333         indices[index++] = i3;
00334         indices[index++] = i4;
00335         indices[index++] = SO_END_FACE_INDEX;
00336     }
00337     faces->coordIndex.finishEditing();
00338 }

Generated on Wed Nov 23 19:00:59 2011 for FreeCAD by  doxygen 1.6.1