00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "PreCompiled.h"
00025
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
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
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
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
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
00272
00273 int numTetr = info.NbTetras();
00274
00275
00276
00277
00278
00279 int index=0;
00280 std::map<const SMDS_MeshNode*, int> mapNodeIndex;
00281
00282
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
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 }