ViewProviderCurvature.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Werner Mayer <wmayer[at]users.sourceforge.net>     *
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 <Inventor/SoPickedPoint.h>
00028 # include <Inventor/details/SoFaceDetail.h>
00029 # include <Inventor/details/SoPointDetail.h>
00030 # include <Inventor/events/SoMouseButtonEvent.h>
00031 # include <Inventor/events/SoKeyboardEvent.h>
00032 # include <Inventor/events/SoLocation2Event.h>
00033 # include <Inventor/nodes/SoDrawStyle.h>
00034 # include <Inventor/nodes/SoIndexedFaceSet.h>
00035 # include <Inventor/nodes/SoMaterial.h>
00036 # include <Inventor/nodes/SoMaterialBinding.h>
00037 # include <Inventor/nodes/SoShapeHints.h>
00038 # include <Inventor/sensors/SoIdleSensor.h>
00039 # include <algorithm>
00040 # include <sstream>
00041 # include <QEvent>
00042 # include <QMenu>
00043 # include <QMessageBox>
00044 # include <QCursor>
00045 # include <QToolTip>
00046 # include <QWhatsThis>
00047 #endif
00048 
00049 # include <iomanip>
00050 # include <ios>
00051 
00052 // Here the FreeCAD includes sorted by Base,App,Gui......
00053 #include <Base/Console.h>
00054 #include <Base/Parameter.h>
00055 #include <Base/Exception.h>
00056 #include <Base/Sequencer.h>
00057 #include <App/Annotation.h>
00058 #include <App/Application.h>
00059 #include <App/Document.h>
00060 #include <App/DocumentObjectGroup.h>
00061 #include <Gui/Application.h>
00062 #include <Gui/Document.h>
00063 #include <Gui/MainWindow.h>
00064 #include <Gui/Selection.h>
00065 #include <Gui/SoFCSelection.h>
00066 #include <Gui/SoFCColorBar.h>
00067 #include <Gui/View3DInventorViewer.h>
00068 #include <Gui/ViewProviderGeometryObject.h>
00069 #include <Gui/Widgets.h>
00070 
00071 #include <Mod/Mesh/App/MeshProperties.h>
00072 #include <Mod/Mesh/App/MeshFeature.h>
00073 #include <Mod/Mesh/App/FeatureMeshCurvature.h>
00074 #include <Mod/Mesh/App/MeshProperties.h>
00075 
00076 #include "ViewProvider.h"
00077 #include "ViewProviderCurvature.h"
00078 
00079 using namespace Mesh;
00080 using namespace MeshGui;
00081 using namespace std;
00082 
00083 bool ViewProviderMeshCurvature::addflag = false;
00084 
00085 PROPERTY_SOURCE(MeshGui::ViewProviderMeshCurvature, Gui::ViewProviderDocumentObject)
00086 
00087 ViewProviderMeshCurvature::ViewProviderMeshCurvature()
00088 {
00089     pcColorRoot = new SoSeparator();
00090     pcColorRoot->ref();
00091     pcColorMat = new SoMaterial;
00092     pcColorMat->ref();
00093     pcColorStyle = new SoDrawStyle(); 
00094     pcColorRoot->addChild(pcColorStyle);
00095     // simple color bar
00096     pcColorBar = new Gui::SoFCColorBar;
00097     pcColorBar->Attach(this);
00098     pcColorBar->ref();
00099     pcColorBar->setRange(-0.5f, 0.5f, 3);
00100     pcLinkRoot = new SoGroup;
00101     pcLinkRoot->ref();
00102 
00103     App::Material mat;
00104     const SbColor* cols;
00105     if (pcColorMat->ambientColor.getNum() == 1) {
00106         cols = pcColorMat->ambientColor.getValues(0);
00107         mat.ambientColor.setPackedValue(cols[0].getPackedValue());
00108     }
00109     if (pcColorMat->diffuseColor.getNum() == 1) {
00110         cols = pcColorMat->diffuseColor.getValues(0);
00111         mat.diffuseColor.setPackedValue(cols[0].getPackedValue());
00112     }
00113     if (pcColorMat->emissiveColor.getNum() == 1) {
00114         cols = pcColorMat->emissiveColor.getValues(0);
00115         mat.emissiveColor.setPackedValue(cols[0].getPackedValue());
00116     }
00117     if (pcColorMat->specularColor.getNum() == 1) {
00118         cols = pcColorMat->specularColor.getValues(0);
00119         mat.specularColor.setPackedValue(cols[0].getPackedValue());
00120     }
00121     if (pcColorMat->shininess.getNum() == 1) {
00122         const float* shiny = pcColorMat->shininess.getValues(0);
00123         mat.shininess = shiny[0];
00124     }
00125     if (pcColorMat->transparency.getNum() == 1) {
00126         const float* trans = pcColorMat->transparency.getValues(0);
00127         mat.transparency = trans[0];
00128     }
00129 
00130     ADD_PROPERTY(TextureMaterial,(mat));
00131 }
00132 
00133 ViewProviderMeshCurvature::~ViewProviderMeshCurvature()
00134 {
00135     pcColorRoot->unref();
00136     pcColorMat->unref();
00137     pcColorBar->Detach(this);
00138     pcColorBar->unref();
00139     pcLinkRoot->unref();
00140 }
00141 
00142 void ViewProviderMeshCurvature::onChanged(const App::Property* prop)
00143 {
00144     if (prop == &TextureMaterial) {
00145         const App::Material& Mat = TextureMaterial.getValue();
00146         pcColorMat->ambientColor.setValue(Mat.ambientColor.r,Mat.ambientColor.g,Mat.ambientColor.b);
00147         pcColorMat->specularColor.setValue(Mat.specularColor.r,Mat.specularColor.g,Mat.specularColor.b);
00148         pcColorMat->emissiveColor.setValue(Mat.emissiveColor.r,Mat.emissiveColor.g,Mat.emissiveColor.b);
00149         pcColorMat->shininess.setValue(Mat.shininess);
00150         pcColorMat->transparency.setValue(Mat.transparency);
00151     }
00152 
00153     ViewProviderDocumentObject::onChanged(prop);
00154 }
00155 
00156 void ViewProviderMeshCurvature::hide(void)
00157 {
00158     inherited::hide();
00159     pcColorStyle->style = SoDrawStyle::INVISIBLE;
00160 }
00161 
00162 void ViewProviderMeshCurvature::show(void)
00163 {
00164     inherited::show();
00165     pcColorStyle->style = SoDrawStyle::FILLED;
00166 }
00167 
00168 void ViewProviderMeshCurvature::init(const Mesh::PropertyCurvatureList* pCurvInfo)
00169 {
00170     std::vector<float> aMinValues, aMaxValues;
00171     const std::vector<Mesh::CurvatureInfo>& fCurvInfo = pCurvInfo->getValues();
00172     aMinValues.reserve(fCurvInfo.size());
00173     aMaxValues.reserve(fCurvInfo.size());
00174 
00175     for ( std::vector<Mesh::CurvatureInfo>::const_iterator jt=fCurvInfo.begin();jt!=fCurvInfo.end(); ++jt ) {
00176         aMinValues.push_back( jt->fMinCurvature );
00177         aMaxValues.push_back( jt->fMaxCurvature );
00178     }
00179 
00180     if ( aMinValues.empty() || aMaxValues.empty() ) 
00181         return; // no values inside
00182 
00183     float fMin = *std::min_element( aMinValues.begin(), aMinValues.end() );
00184     float fMax = *std::max_element( aMinValues.begin(), aMinValues.end() );
00185 
00186     // histogram over all values
00187     std::map<int, int> aHistogram;
00188     for ( std::vector<float>::const_iterator kt = aMinValues.begin(); kt != aMinValues.end(); ++kt ) {
00189         int grp = (int)(10.0f*( *kt - fMin )/( fMax - fMin ));
00190         aHistogram[grp]++;
00191     }
00192 
00193     float fRMin=-1.0f;
00194     for ( std::map<int, int>::iterator mIt = aHistogram.begin(); mIt != aHistogram.end(); ++mIt ) {
00195         if ( (float)mIt->second / (float)aMinValues.size() > 0.15f ) {
00196             fRMin = mIt->first * ( fMax - fMin )/10.0f + fMin;
00197             break;
00198         }
00199     }
00200 
00201     fMin = *std::min_element( aMaxValues.begin(), aMaxValues.end() );
00202     fMax = *std::max_element( aMaxValues.begin(), aMaxValues.end() );
00203 
00204     // histogram over all values
00205     aHistogram.clear();
00206     for ( std::vector<float>::const_iterator it2 = aMaxValues.begin(); it2 != aMaxValues.end(); ++it2 ) {
00207         int grp = (int)(10.0f*( *it2 - fMin )/( fMax - fMin ));
00208         aHistogram[grp]++;
00209     }
00210 
00211     float fRMax=1.0f;
00212     for ( std::map<int, int>::reverse_iterator rIt2 = aHistogram.rbegin(); rIt2 != aHistogram.rend(); ++rIt2 ) {
00213         if ( (float)rIt2->second / (float)aMaxValues.size() > 0.15f ) {
00214             fRMax = rIt2->first * ( fMax - fMin )/10.0f + fMin;
00215             break;
00216         }
00217     }
00218 
00219     float fAbs = std::max<float>(fabs(fRMin), fabs(fRMax));
00220     fRMin = -fAbs;
00221     fRMax =  fAbs;
00222     fMin = fRMin; fMax = fRMax;
00223     pcColorBar->setRange( fMin, fMax, 3 );
00224 }
00225 
00226 void ViewProviderMeshCurvature::slotCreatedObject(const App::DocumentObject& Obj)
00227 {
00228 }
00229 
00230 void ViewProviderMeshCurvature::slotDeletedObject(const App::DocumentObject& Obj)
00231 {
00232 }
00233 
00234 void ViewProviderMeshCurvature::slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop)
00235 {
00236     // we get this for any object for that a property has changed. Thus, we must regard that object
00237     // which is linked by our link property
00238     App::DocumentObject* object = static_cast<Mesh::Curvature*>(pcObject)->Source.getValue();
00239     if (object == &Obj) {
00240         const Mesh::PropertyMeshKernel& mesh = static_cast<Mesh::Feature*>(object)->Mesh;
00241         if ((&mesh) == (&Prop)) {
00242             const Mesh::MeshObject& kernel = mesh.getValue();
00243             pcColorMat->diffuseColor.setNum((int)kernel.countPoints());
00244             pcColorMat->transparency.setNum((int)kernel.countPoints());
00245             static_cast<Mesh::Curvature*>(pcObject)->Source.touch(); // make sure to recompute the feature
00246         }
00247     }
00248 }
00249 
00250 void ViewProviderMeshCurvature::slotCreatedDocument(const App::Document& Doc)
00251 {
00252 }
00253 
00254 void ViewProviderMeshCurvature::slotDeletedDocument(const App::Document& Doc)
00255 {
00256 }
00257 
00258 void ViewProviderMeshCurvature::attach(App::DocumentObject *pcFeat)
00259 {
00260     // creats the standard viewing modes
00261     inherited::attach(pcFeat);
00262     attachDocument(pcFeat->getDocument());
00263 
00264     SoShapeHints * flathints = new SoShapeHints;
00265     flathints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE ;
00266     flathints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE;
00267 
00268     SoGroup* pcColorShadedRoot = new SoGroup();
00269     pcColorShadedRoot->addChild(flathints);
00270 
00271     // color shaded
00272     SoDrawStyle *pcFlatStyle = new SoDrawStyle();
00273     pcFlatStyle->style = SoDrawStyle::FILLED;
00274     pcColorShadedRoot->addChild(pcFlatStyle);
00275 
00276     SoMaterialBinding* pcMatBinding = new SoMaterialBinding;
00277     pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
00278     pcColorShadedRoot->addChild(pcColorMat);
00279     pcColorShadedRoot->addChild(pcMatBinding);
00280     pcColorShadedRoot->addChild(pcLinkRoot);
00281 
00282     addDisplayMaskMode(pcColorShadedRoot, "ColorShaded");
00283 
00284     // Check for an already existing color bar
00285     Gui::SoFCColorBar* pcBar = ((Gui::SoFCColorBar*)findFrontRootOfType( Gui::SoFCColorBar::getClassTypeId() ));
00286     if ( pcBar ) {
00287         float fMin = pcColorBar->getMinValue();
00288         float fMax = pcColorBar->getMaxValue();
00289 
00290         // Attach to the foreign color bar and delete our own bar
00291         pcBar->Attach(this);
00292         pcBar->ref();
00293         pcBar->setRange(fMin, fMax, 3);
00294         pcBar->Notify(0);
00295         pcColorBar->Detach(this);
00296         pcColorBar->unref();
00297         pcColorBar = pcBar;
00298     }
00299 
00300     pcColorRoot->addChild(pcColorBar);
00301 }
00302 
00303 void ViewProviderMeshCurvature::updateData(const App::Property* prop)
00304 {
00305     // set to the expected size
00306     if (prop->getTypeId() == App::PropertyLink::getClassTypeId()) {
00307         Mesh::Feature* object = static_cast<const App::PropertyLink*>(prop)->getValue<Mesh::Feature*>();
00308         this->pcLinkRoot->removeAllChildren();
00309         if (object) {
00310             const Mesh::MeshObject& kernel = object->Mesh.getValue();
00311             pcColorMat->diffuseColor.setNum((int)kernel.countPoints());
00312             pcColorMat->transparency.setNum((int)kernel.countPoints());
00313 
00314             // get the view provider of the associated mesh feature
00315             App::Document* rDoc = pcObject->getDocument();
00316             Gui::Document* pDoc = Gui::Application::Instance->getDocument(rDoc);
00317             Gui::ViewProviderGeometryObject* view = static_cast<Gui::ViewProviderGeometryObject*>(pDoc->getViewProvider(object));
00318             this->pcLinkRoot->addChild(view->getHighlightNode());
00319         }
00320     }
00321     else if (prop->getTypeId() == Mesh::PropertyCurvatureList::getClassTypeId()) {
00322         const Mesh::PropertyCurvatureList* curv = static_cast<const Mesh::PropertyCurvatureList*>(prop);
00323         if (curv->getSize() < 3) return; // invalid array
00324 #if 0 // FIXME: Do not always change the range
00325         init(curv); // init color bar
00326 #endif
00327         setActiveMode();
00328     }
00329 }
00330 
00331 SoSeparator* ViewProviderMeshCurvature::getFrontRoot(void) const
00332 {
00333     return pcColorRoot;
00334 }
00335 
00336 void ViewProviderMeshCurvature::setVertexCurvatureMode(int mode)
00337 {
00338     Mesh::PropertyCurvatureList* pCurvInfo=0;
00339     std::map<std::string,App::Property*> Map;
00340     pcObject->getPropertyMap(Map);
00341     for( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it ) {
00342         Base::Type t = it->second->getTypeId();
00343         if ( t==Mesh::PropertyCurvatureList::getClassTypeId() ) {
00344             pCurvInfo = (Mesh::PropertyCurvatureList*)it->second;
00345             break;
00346         }
00347     }
00348 
00349     if ( !pCurvInfo )
00350         return; // cannot display this feature type due to missing curvature property
00351 
00352     // curvature values
00353     std::vector<float> fValues = pCurvInfo->getCurvature( mode ); 
00354     unsigned long j=0;
00355     for ( std::vector<float>::const_iterator jt = fValues.begin(); jt != fValues.end(); ++jt, j++ ) {
00356         App::Color col = pcColorBar->getColor( *jt );
00357         pcColorMat->diffuseColor.set1Value(j, SbColor(col.r, col.g, col.b));
00358         if ( pcColorBar->isVisible( *jt ) ) {
00359             pcColorMat->transparency.set1Value(j, 0.0f);
00360         } else {
00361             pcColorMat->transparency.set1Value(j, 0.8f);
00362         }
00363     }
00364 }
00365 
00366 QIcon ViewProviderMeshCurvature::getIcon() const
00367 {
00368     static const char * Mesh_Feature_xpm[] = {
00369         "16 16 7 1",
00370         ".      c None",
00371         "#      c #000000",
00372         "s      c #BEC2FC",
00373         "g      c #00FF00",
00374         "y      c #FFFF00",
00375         "b      c #0000FF",
00376         "r      c #FF0000",
00377         ".......##.......",
00378         "....#######.....",
00379         "..##ggg#yyy#....",
00380         "##ggggg#yyyy##..",
00381         "#b#ggg#yyyyyy##.",
00382         "#bb#gg#yyyy###s.",
00383         "#bb#gg#yy##yy#s.",
00384         "#bbb#####rrr#ss.",
00385         "#bbbb##rrrr#ss..",
00386         ".#b##b#rrrr#s...",
00387         ".##bbb#rrr#ss...",
00388         ".##bbb#r#ss.....",
00389         "..s#####r#s.....",
00390         "....sss##ss.....",
00391         "........ss......",
00392         "................"};
00393     QPixmap px(Mesh_Feature_xpm);
00394     return px;
00395 }
00396 
00397 void ViewProviderMeshCurvature::setDisplayMode(const char* ModeName)
00398 {
00399     if ( strcmp("Mean curvature",ModeName)==0 ) {
00400         setVertexCurvatureMode(Mesh::PropertyCurvatureList::MeanCurvature);
00401         setDisplayMaskMode("ColorShaded");
00402     }
00403     else if ( strcmp("Gaussian curvature",ModeName)==0  ) {
00404         setVertexCurvatureMode(Mesh::PropertyCurvatureList::GaussCurvature);
00405         setDisplayMaskMode("ColorShaded");
00406     }
00407     else if ( strcmp("Maximum curvature",ModeName)==0  ) {
00408         setVertexCurvatureMode(Mesh::PropertyCurvatureList::MaxCurvature);
00409         setDisplayMaskMode("ColorShaded");
00410     }
00411     else if ( strcmp("Minimum curvature",ModeName)==0  ) {
00412         setVertexCurvatureMode(Mesh::PropertyCurvatureList::MinCurvature);
00413         setDisplayMaskMode("ColorShaded");
00414     }
00415     else if ( strcmp("Absolute curvature",ModeName)==0  ) {
00416         setVertexCurvatureMode(Mesh::PropertyCurvatureList::AbsCurvature);
00417         setDisplayMaskMode("ColorShaded");
00418     }
00419 
00420     inherited::setDisplayMode(ModeName);
00421 }
00422 
00423 const char* ViewProviderMeshCurvature::getDefaultDisplayMode() const
00424 {
00425     return "Absolute curvature";
00426 }
00427 
00428 std::vector<std::string> ViewProviderMeshCurvature::getDisplayModes(void) const
00429 {
00430     std::vector<std::string> StrList = inherited::getDisplayModes();
00431 
00432     // add modes
00433     StrList.push_back("Absolute curvature");
00434     StrList.push_back("Mean curvature");
00435     StrList.push_back("Gaussian curvature");
00436     StrList.push_back("Maximum curvature");
00437     StrList.push_back("Minimum curvature");
00438 
00439     return StrList;
00440 }
00441 
00442 void ViewProviderMeshCurvature::OnChange(Base::Subject<int> &rCaller,int rcReason)
00443 {
00444     setActiveMode();
00445 }
00446 
00447 namespace MeshGui {
00448 
00449 class Annotation
00450 {
00451 public:
00452     Annotation(Gui::ViewProviderDocumentObject* vp,
00453         const QString& s,const SbVec3f& p, const SbVec3f& n)
00454         : vp(vp), s(s), p(p), n(n)
00455     {
00456     }
00457     ~Annotation()
00458     {
00459     }
00460 
00461     static void run(void * data, SoSensor * sensor)
00462     {
00463         Annotation* self = reinterpret_cast<Annotation*>(data);
00464         self->show();
00465         delete self;
00466         delete sensor;
00467     }
00468 
00469     void show()
00470     {
00471         App::Document* doc = vp->getObject()->getDocument();
00472 
00473         std::vector<App::DocumentObject*> groups = doc->getObjectsOfType
00474             (App::DocumentObjectGroup::getClassTypeId());
00475         App::DocumentObjectGroup* group = 0;
00476         std::string internalname = "CurvatureGroup";
00477         for (std::vector<App::DocumentObject*>::iterator it = groups.begin(); it != groups.end(); ++it) {
00478             if (internalname == (*it)->getNameInDocument()) {
00479                 group = static_cast<App::DocumentObjectGroup*>(*it);
00480                 break;
00481             }
00482         }
00483         if (!group) {
00484             group = static_cast<App::DocumentObjectGroup*>(doc->addObject
00485                 ("App::DocumentObjectGroup",internalname.c_str()));
00486         }
00487 
00488         App::AnnotationLabel* anno = static_cast<App::AnnotationLabel*>
00489             (group->addObject("App::AnnotationLabel", internalname.c_str()));
00490         QStringList lines = s.split(QLatin1String("\n"));
00491         std::vector<std::string> text;
00492         for (QStringList::Iterator it = lines.begin(); it != lines.end(); ++it)
00493             text.push_back((const char*)it->toAscii());
00494         anno->LabelText.setValues(text);
00495         std::stringstream str;
00496         str << "Curvature info (" << group->Group.getSize() << ")";
00497         anno->Label.setValue(str.str());
00498         anno->BasePosition.setValue(p[0],p[1],p[2]);
00499         anno->TextPosition.setValue(n[0],n[1],n[2]);
00500     }
00501 
00502 private:
00503     Gui::ViewProviderDocumentObject* vp;
00504     QString s;
00505     SbVec3f p;
00506     SbVec3f n;
00507 };
00508 
00509 }
00510 
00511 void ViewProviderMeshCurvature::curvatureInfoCallback(void * ud, SoEventCallback * n)
00512 {
00513     Gui::View3DInventorViewer* view  = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00514     const SoEvent* ev = n->getEvent();
00515     if (ev->getTypeId() == SoMouseButtonEvent::getClassTypeId()) {
00516         const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent *>(ev);
00517 
00518         // Mark all incoming mouse button events as handled, especially, to deactivate the selection node
00519         n->getAction()->setHandled();
00520         if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
00521             n->setHandled();
00522             // context-menu
00523             QMenu menu;
00524             QAction* fl = menu.addAction(QObject::tr("Annotation"));
00525             fl->setCheckable(true);
00526             fl->setChecked(addflag);
00527             QAction* cl = menu.addAction(QObject::tr("Leave info mode"));
00528             QAction* id = menu.exec(QCursor::pos());
00529             if (fl == id) {
00530                 addflag = fl->isChecked();
00531             }
00532             else if (cl == id) {
00533                 view->setEditing(false);
00534                 view->getWidget()->setCursor(QCursor(Qt::ArrowCursor));
00535                 view->setRedirectToSceneGraph(false);
00536                 view->removeEventCallback(SoEvent::getClassTypeId(), curvatureInfoCallback);
00537             }
00538         }
00539         else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::UP) {
00540             const SoPickedPoint * point = n->getPickedPoint();
00541             if (point == NULL) {
00542                 Base::Console().Message("No facet picked.\n");
00543                 return;
00544             }
00545 
00546             n->setHandled();
00547 
00548             // By specifying the indexed mesh node 'pcFaceSet' we make sure that the picked point is
00549             // really from the mesh we render and not from any other geometry
00550             Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
00551             if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMeshCurvature::getClassTypeId()))
00552                 return;
00553             ViewProviderMeshCurvature* self = static_cast<ViewProviderMeshCurvature*>(vp);
00554             const SoDetail* detail = point->getDetail(point->getPath()->getTail());
00555             if (detail && detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
00556                 // safe downward cast, know the type
00557                 SoFaceDetail * facedetail = (SoFaceDetail *)detail;
00558                 // get the curvature info of the three points of the picked facet
00559                 int index1 = facedetail->getPoint(0)->getCoordinateIndex();
00560                 int index2 = facedetail->getPoint(1)->getCoordinateIndex();
00561                 int index3 = facedetail->getPoint(2)->getCoordinateIndex();
00562                 std::string info = self->curvatureInfo(true, index1, index2, index3);
00563                 QString text = QString::fromAscii(info.c_str());
00564                 if (addflag) {
00565                     SbVec3f pt = point->getPoint();
00566                     SbVec3f nl = point->getNormal();
00567                     Annotation* anno = new Annotation(self, text, pt, nl);
00568                     SoIdleSensor* sensor = new SoIdleSensor(Annotation::run, anno);
00569                     sensor->schedule();
00570                 }
00571                 else {
00572                     Gui::ToolTip::showText(QCursor::pos(), text);
00573                 }
00574             }
00575         }
00576     }
00577     else if (ev->getTypeId().isDerivedFrom(SoLocation2Event::getClassTypeId())) {
00578         const SoPickedPoint * point = n->getPickedPoint();
00579         if (point == NULL)
00580             return;
00581         n->setHandled();
00582 
00583         // By specifying the indexed mesh node 'pcFaceSet' we make sure that the picked point is
00584         // really from the mesh we render and not from any other geometry
00585         Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
00586         if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMeshCurvature::getClassTypeId()))
00587             return;
00588         ViewProviderMeshCurvature* that = static_cast<ViewProviderMeshCurvature*>(vp);
00589         const SoDetail* detail = point->getDetail(point->getPath()->getTail());
00590         if (detail && detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
00591             // safe downward cast, know the type
00592             SoFaceDetail * facedetail = (SoFaceDetail *)detail;
00593             // get the curvature info of the three points of the picked facet
00594             int index1 = facedetail->getPoint(0)->getCoordinateIndex();
00595             int index2 = facedetail->getPoint(1)->getCoordinateIndex();
00596             int index3 = facedetail->getPoint(2)->getCoordinateIndex();
00597             std::string info = that->curvatureInfo(false, index1, index2, index3);
00598             Gui::getMainWindow()->setPaneText(1,QString::fromAscii(info.c_str()));
00599         }
00600     }
00601 }
00602 
00603 std::string ViewProviderMeshCurvature::curvatureInfo(bool detail, int index1, int index2, int index3) const
00604 {
00605     // get the curvature info of the three points of the picked facet
00606     App::Property* prop = pcObject->getPropertyByName("CurvInfo");
00607     std::stringstream str;
00608     if (prop && prop->getTypeId() == Mesh::PropertyCurvatureList::getClassTypeId()) {
00609         Mesh::PropertyCurvatureList* curv = (Mesh::PropertyCurvatureList*)prop;
00610         const Mesh::CurvatureInfo& cVal1 = (*curv)[index1];
00611         const Mesh::CurvatureInfo& cVal2 = (*curv)[index2];
00612         const Mesh::CurvatureInfo& cVal3 = (*curv)[index3];
00613         float fVal1 = 0.0f; float fVal2 = 0.0f; float fVal3 = 0.0f;
00614 
00615         bool print=true;
00616         std::string mode = getActiveDisplayMode();
00617         if (mode == "Minimum curvature") {
00618             fVal1 = cVal1.fMinCurvature;
00619             fVal2 = cVal1.fMinCurvature;
00620             fVal3 = cVal1.fMinCurvature;
00621         }
00622         else if (mode == "Maximum curvature") {
00623             fVal1 = cVal1.fMaxCurvature;
00624             fVal2 = cVal1.fMaxCurvature;
00625             fVal3 = cVal1.fMaxCurvature;
00626         }
00627         else if (mode == "Gaussian curvature") {
00628             fVal1 = cVal1.fMaxCurvature*cVal1.fMinCurvature;
00629             fVal2 = cVal1.fMaxCurvature*cVal2.fMinCurvature;
00630             fVal3 = cVal1.fMaxCurvature*cVal3.fMinCurvature;
00631         }
00632         else if (mode == "Mean curvature") {
00633             fVal1 = 0.5f*(cVal1.fMaxCurvature+cVal1.fMinCurvature);
00634             fVal2 = 0.5f*(cVal1.fMaxCurvature+cVal2.fMinCurvature);
00635             fVal3 = 0.5f*(cVal1.fMaxCurvature+cVal3.fMinCurvature);
00636         }
00637         else if (mode == "Absolute curvature") {
00638             fVal1 = fabs(cVal1.fMaxCurvature) > fabs(cVal1.fMinCurvature) ? cVal1.fMaxCurvature : cVal1.fMinCurvature;
00639             fVal2 = fabs(cVal2.fMaxCurvature) > fabs(cVal2.fMinCurvature) ? cVal2.fMaxCurvature : cVal2.fMinCurvature;
00640             fVal3 = fabs(cVal3.fMaxCurvature) > fabs(cVal3.fMinCurvature) ? cVal3.fMaxCurvature : cVal3.fMinCurvature;
00641         }
00642         else {
00643             print = false;
00644         }
00645 
00646         if (print) {
00647             if (!detail) {
00648                 str << mode << ": <" << fVal1 << ", " << fVal2 << ", " << fVal3 << ">";
00649             }
00650             else {
00651                 str.setf(std::ios::fixed | std::ios::showpoint);
00652                 str.precision(5);
00653                 str << mode << std::endl
00654                     << "v1: " << std::setw(5) << fVal1 << std::endl
00655                     << "v2: " << std::setw(5) << fVal2 << std::endl
00656                     << "v3: " << std::setw(5) << fVal3;
00657             }
00658         }
00659         else if (!detail) {
00660             str << "No curvature mode set";
00661         }
00662     }
00663 
00664     return str.str();
00665 }

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