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 <sstream>
00028 # include <QApplication>
00029 # include <Inventor/SoPickedPoint.h>
00030 # include <Inventor/events/SoMouseButtonEvent.h>
00031 # include <Inventor/nodes/SoSeparator.h>
00032 # include <Inventor/nodes/SoBaseColor.h>
00033 # include <Inventor/nodes/SoFontStyle.h>
00034 # include <Inventor/nodes/SoPickStyle.h>
00035 # include <Inventor/nodes/SoText2.h>
00036 # include <Inventor/nodes/SoTranslation.h>
00037 # include <Inventor/nodes/SoCoordinate3.h>
00038 # include <Inventor/nodes/SoIndexedLineSet.h>
00039 # include <Inventor/nodes/SoMarkerSet.h>
00040 # include <Inventor/nodes/SoDrawStyle.h>
00041 #endif
00042
00043 #include "ViewProviderMeasureDistance.h"
00044 #include "SoFCSelection.h"
00045 #include "Application.h"
00046 #include "Document.h"
00047 #include "View3DInventorViewer.h"
00048
00049 #include <App/PropertyGeo.h>
00050 #include <App/PropertyStandard.h>
00051 #include <App/MeasureDistance.h>
00052 #include <Base/Console.h>
00053
00054 using namespace Gui;
00055
00056 PROPERTY_SOURCE(Gui::ViewProviderMeasureDistance, Gui::ViewProviderDocumentObject)
00057
00058
00059 ViewProviderMeasureDistance::ViewProviderMeasureDistance()
00060 {
00061 ADD_PROPERTY(TextColor,(0.0f,0.0f,0.0f));
00062 ADD_PROPERTY(LineColor,(1.0f,1.0f,1.0f));
00063 ADD_PROPERTY(FontSize,(18));
00064 ADD_PROPERTY(DistFactor,(1.0));
00065 ADD_PROPERTY(Mirror,(false));
00066
00067 pFont = new SoFontStyle();
00068 pFont->ref();
00069 pLabel = new SoText2();
00070 pLabel->ref();
00071 pColor = new SoBaseColor();
00072 pColor->ref();
00073 pTextColor = new SoBaseColor();
00074 pTextColor->ref();
00075 pTranslation = new SoTranslation();
00076 pTranslation->ref();
00077
00078 TextColor.touch();
00079 FontSize.touch();
00080 LineColor.touch();
00081
00082 static const SbVec3f verts[4] =
00083 {
00084 SbVec3f(0,0,0), SbVec3f(0,0,0),
00085 SbVec3f(0,0,0), SbVec3f(0,0,0)
00086 };
00087
00088
00089 static const int32_t lines[9] =
00090 {
00091 0,2,-1,
00092 1,3,-1,
00093 2,3,-1
00094 };
00095
00096 pCoords = new SoCoordinate3();
00097 pCoords->ref();
00098 pCoords->point.setNum(4);
00099 pCoords->point.setValues(0, 4, verts);
00100
00101 pLines = new SoIndexedLineSet();
00102 pLines->ref();
00103 pLines->coordIndex.setNum(9);
00104 pLines->coordIndex.setValues(0, 9, lines);
00105 sPixmap = "view-measurement";
00106 }
00107
00108 ViewProviderMeasureDistance::~ViewProviderMeasureDistance()
00109 {
00110 pFont->unref();
00111 pLabel->unref();
00112 pColor->unref();
00113 pTextColor->unref();
00114 pTranslation->unref();
00115 pCoords->unref();
00116 pLines->unref();
00117 }
00118
00119 void ViewProviderMeasureDistance::onChanged(const App::Property* prop)
00120 {
00121 if (prop == &Mirror || prop == &DistFactor) {
00122 updateData(prop);
00123 }
00124 else if (prop == &TextColor) {
00125 const App::Color& c = TextColor.getValue();
00126 pTextColor->rgb.setValue(c.r,c.g,c.b);
00127 }
00128 else if (prop == &LineColor) {
00129 const App::Color& c = LineColor.getValue();
00130 pColor->rgb.setValue(c.r,c.g,c.b);
00131 }
00132 else if (prop == &FontSize) {
00133 pFont->size = FontSize.getValue();
00134 }
00135 else {
00136 ViewProviderDocumentObject::onChanged(prop);
00137 }
00138 }
00139
00140 std::vector<std::string> ViewProviderMeasureDistance::getDisplayModes(void) const
00141 {
00142
00143 std::vector<std::string> StrList;
00144 StrList.push_back("Base");
00145 return StrList;
00146 }
00147
00148 void ViewProviderMeasureDistance::setDisplayMode(const char* ModeName)
00149 {
00150 if (strcmp(ModeName, "Base") == 0)
00151 setDisplayMaskMode("Base");
00152 ViewProviderDocumentObject::setDisplayMode(ModeName);
00153 }
00154
00155 void ViewProviderMeasureDistance::attach(App::DocumentObject* pcObject)
00156 {
00157 ViewProviderDocumentObject::attach(pcObject);
00158
00159 SoPickStyle* ps = new SoPickStyle();
00160 ps->style = SoPickStyle::UNPICKABLE;
00161
00162 SoSeparator *lineSep = new SoSeparator();
00163 SoDrawStyle* style = new SoDrawStyle();
00164 style->lineWidth = 2.0f;
00165 lineSep->addChild(ps);
00166 lineSep->addChild(style);
00167 lineSep->addChild(pColor);
00168 lineSep->addChild(pCoords);
00169 lineSep->addChild(pLines);
00170 SoMarkerSet* points = new SoMarkerSet();
00171 points->markerIndex = SoMarkerSet::CROSS_9_9;
00172 points->numPoints=2;
00173 lineSep->addChild(points);
00174
00175
00176
00177
00178 SoFCSelection* textsep = new SoFCSelection();
00179 textsep->objectName = pcObject->getNameInDocument();
00180 textsep->documentName = pcObject->getDocument()->getName();
00181 textsep->subElementName = "Main";
00182
00183 textsep->addChild(pTranslation);
00184 textsep->addChild(pTextColor);
00185 textsep->addChild(pFont);
00186 textsep->addChild(pLabel);
00187
00188 SoSeparator* sep = new SoSeparator();
00189 sep->addChild(lineSep);
00190 sep->addChild(textsep);
00191 addDisplayMaskMode(sep, "Base");
00192 }
00193
00194 void ViewProviderMeasureDistance::updateData(const App::Property* prop)
00195 {
00196 if (prop->getTypeId() == App::PropertyVector::getClassTypeId() ||
00197 prop == &Mirror || prop == &DistFactor) {
00198 if (strcmp(prop->getName(),"P1") == 0) {
00199 Base::Vector3f v = static_cast<const App::PropertyVector*>(prop)->getValue();
00200 pCoords->point.set1Value(0, SbVec3f(v.x,v.y,v.z));
00201 }
00202 else if (strcmp(prop->getName(),"P2") == 0) {
00203 Base::Vector3f v = static_cast<const App::PropertyVector*>(prop)->getValue();
00204 pCoords->point.set1Value(1, SbVec3f(v.x,v.y,v.z));
00205 }
00206
00207 SbVec3f pt1 = pCoords->point[0];
00208 SbVec3f pt2 = pCoords->point[1];
00209 SbVec3f dif = pt1-pt2;
00210
00211 float length = fabs(dif.length())*DistFactor.getValue();
00212 if (Mirror.getValue())
00213 length = -length;
00214
00215
00216 if (dif.sqrLength() < 10.0e-6f) {
00217 pCoords->point.set1Value(2, pt1+SbVec3f(0.0f,0.0f,length));
00218 pCoords->point.set1Value(3, pt2+SbVec3f(0.0f,0.0f,length));
00219 }
00220 else {
00221 SbVec3f dir = dif.cross(SbVec3f(1.0f,0.0f,0.0f));
00222 if (dir.sqrLength() < 10.0e-6f)
00223 dir = dif.cross(SbVec3f(0.0f,1.0f,0.0f));
00224 if (dir.sqrLength() < 10.0e-6f)
00225 dir = dif.cross(SbVec3f(0.0f,0.0f,1.0f));
00226 dir.normalize();
00227 if (dir.dot(SbVec3f(0.0f,0.0f,1.0f)) < 0.0f)
00228 length = -length;
00229 pCoords->point.set1Value(2, pt1 + length*dir);
00230 pCoords->point.set1Value(3, pt2 + length*dir);
00231 }
00232
00233 SbVec3f pos = (pCoords->point[2]+pCoords->point[3])/2.0f;
00234 pTranslation->translation.setValue(pos);
00235
00236 std::stringstream s;
00237 s.precision(3);
00238 s.setf(std::ios::fixed | std::ios::showpoint);
00239 s << dif.length();
00240 pLabel->string.setValue(s.str().c_str());
00241 }
00242
00243 ViewProviderDocumentObject::updateData(prop);
00244 }
00245
00246
00247
00248 PointMarker::PointMarker(View3DInventorViewer* iv) : view(iv),
00249 vp(new ViewProviderPointMarker)
00250 {
00251 view->addViewProvider(vp);
00252 }
00253
00254 PointMarker::~PointMarker()
00255 {
00256 view->removeViewProvider(vp);
00257 delete vp;
00258 }
00259
00260 void PointMarker::addPoint(const SbVec3f& pt)
00261 {
00262 int ct = countPoints();
00263 vp->pCoords->point.set1Value(ct, pt);
00264 vp->pMarker->numPoints=ct+1;
00265 }
00266
00267 int PointMarker::countPoints() const
00268 {
00269 return vp->pCoords->point.getNum();
00270 }
00271
00272 void PointMarker::customEvent(QEvent* e)
00273 {
00274 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00275 App::DocumentObject* obj = doc->getDocument()->addObject
00276 (App::MeasureDistance::getClassTypeId().getName(),"Distance");
00277
00278 App::MeasureDistance* md = static_cast<App::MeasureDistance*>(obj);
00279 const SbVec3f& pt1 = vp->pCoords->point[0];
00280 const SbVec3f& pt2 = vp->pCoords->point[1];
00281 md->P1.setValue(Base::Vector3f(pt1[0],pt1[1],pt1[2]));
00282 md->P2.setValue(Base::Vector3f(pt2[0],pt2[1],pt2[2]));
00283 std::stringstream s;
00284 s.precision(3);
00285 s.setf(std::ios::fixed | std::ios::showpoint);
00286 s << "Distance: " << md->Distance.getValue();
00287 md->Label.setValue(s.str());
00288 }
00289
00290 PROPERTY_SOURCE(Gui::ViewProviderPointMarker, Gui::ViewProviderDocumentObject)
00291
00292 ViewProviderPointMarker::ViewProviderPointMarker()
00293 {
00294 pCoords = new SoCoordinate3();
00295 pCoords->ref();
00296 pCoords->point.setNum(0);
00297 pMarker = new SoMarkerSet();
00298 pMarker->markerIndex = SoMarkerSet::CROSS_9_9;
00299 pMarker->numPoints=0;
00300 pMarker->ref();
00301
00302 SoGroup* grp = new SoGroup();
00303 grp->addChild(pCoords);
00304 grp->addChild(pMarker);
00305 addDisplayMaskMode(grp, "Base");
00306 setDisplayMaskMode("Base");
00307 }
00308
00309 ViewProviderPointMarker::~ViewProviderPointMarker()
00310 {
00311 pCoords->unref();
00312 pMarker->unref();
00313 }
00314
00315 void ViewProviderMeasureDistance::measureDistanceCallback(void * ud, SoEventCallback * n)
00316 {
00317 const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent());
00318 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00319 PointMarker *pm = reinterpret_cast<PointMarker*>(ud);
00320
00321
00322 n->getAction()->setHandled();
00323 if (mbe->getButton() == SoMouseButtonEvent::BUTTON2 && mbe->getState() == SoButtonEvent::UP) {
00324 n->setHandled();
00325 view->setEditing(false);
00326 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), measureDistanceCallback, ud);
00327 pm->deleteLater();
00328 }
00329 else if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
00330 const SoPickedPoint * point = n->getPickedPoint();
00331 if (point == NULL) {
00332 Base::Console().Message("No point picked.\n");
00333 return;
00334 }
00335
00336 n->setHandled();
00337 pm->addPoint(point->getPoint());
00338 if (pm->countPoints() == 2) {
00339 QEvent *e = new QEvent(QEvent::User);
00340 QApplication::postEvent(pm, e);
00341
00342 view->setEditing(false);
00343 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), measureDistanceCallback, ud);
00344 pm->deleteLater();
00345 }
00346 }
00347 }