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 # ifdef FC_OS_WIN32
00028 # include <windows.h>
00029 # endif
00030 # include <Inventor/nodes/SoCamera.h>
00031 # include <Inventor/nodes/SoCoordinate3.h>
00032 # include <Inventor/nodes/SoDrawStyle.h>
00033 # include <Inventor/nodes/SoPointSet.h>
00034 # include <Inventor/nodes/SoMaterial.h>
00035 # include <Inventor/nodes/SoMaterialBinding.h>
00036 # include <Inventor/nodes/SoNormal.h>
00037 # include <Inventor/errors/SoDebugError.h>
00038 # include <Inventor/events/SoMouseButtonEvent.h>
00039 #endif
00040
00042 #include <Base/Console.h>
00043 #include <Base/Parameter.h>
00044 #include <Base/Exception.h>
00045 #include <Base/Sequencer.h>
00046 #include <Base/Tools2D.h>
00047 #include <Base/Vector3D.h>
00048 #include <App/Application.h>
00049 #include <App/Document.h>
00050 #include <Gui/Application.h>
00051 #include <Gui/Document.h>
00052 #include <Gui/SoFCSelection.h>
00053
00054 #include <Gui/View3DInventorViewer.h>
00055 #include <Mod/Points/App/PointsFeature.h>
00056
00057 #include "ViewProvider.h"
00058 #include "../App/Properties.h"
00059
00060
00061 using namespace PointsGui;
00062 using namespace Points;
00063
00064
00065 PROPERTY_SOURCE(PointsGui::ViewProviderPoints, Gui::ViewProviderGeometryObject)
00066
00067
00068 App::PropertyFloatConstraint::Constraints ViewProviderPoints::floatRange = {1.0f,64.0f,1.0f};
00069
00070 ViewProviderPoints::ViewProviderPoints()
00071 {
00072 ADD_PROPERTY(PointSize,(2.0f));
00073 PointSize.setConstraints(&floatRange);
00074
00075 pcPointsCoord = new SoCoordinate3();
00076 pcPointsCoord->ref();
00077 pcPoints = new SoPointSet();
00078 pcPoints->ref();
00079 pcPointsNormal = new SoNormal();
00080 pcPointsNormal->ref();
00081 pcColorMat = new SoMaterial;
00082 pcColorMat->ref();
00083
00084 pcPointStyle = new SoDrawStyle();
00085 pcPointStyle->ref();
00086 pcPointStyle->style = SoDrawStyle::POINTS;
00087 pcPointStyle->pointSize = PointSize.getValue();
00088 }
00089
00090 ViewProviderPoints::~ViewProviderPoints()
00091 {
00092 pcPointsCoord->unref();
00093 pcPoints->unref();
00094 pcPointsNormal->unref();
00095 pcColorMat->unref();
00096 pcPointStyle->unref();
00097 }
00098
00099 void ViewProviderPoints::onChanged(const App::Property* prop)
00100 {
00101 if ( prop == &PointSize ) {
00102 pcPointStyle->pointSize = PointSize.getValue();
00103 }
00104 else {
00105 ViewProviderGeometryObject::onChanged(prop);
00106 }
00107 }
00108
00109 void ViewProviderPoints::setVertexColorMode(App::PropertyColorList* pcProperty)
00110 {
00111 const std::vector<App::Color>& val = pcProperty->getValues();
00112 unsigned long i=0;
00113
00114 pcColorMat->enableNotify(false);
00115 pcColorMat->diffuseColor.deleteValues(0);
00116 pcColorMat->diffuseColor.setNum(val.size());
00117
00118 for ( std::vector<App::Color>::const_iterator it = val.begin(); it != val.end(); ++it ) {
00119 pcColorMat->diffuseColor.set1Value(i++, SbColor(it->r, it->g, it->b));
00120 }
00121
00122 pcColorMat->enableNotify(true);
00123 pcColorMat->touch();
00124 }
00125
00126 void ViewProviderPoints::setVertexGreyvalueMode(Points::PropertyGreyValueList* pcProperty)
00127 {
00128 const std::vector<float>& val = pcProperty->getValues();
00129 unsigned long i=0;
00130
00131 pcColorMat->enableNotify(false);
00132 pcColorMat->diffuseColor.deleteValues(0);
00133 pcColorMat->diffuseColor.setNum(val.size());
00134
00135 for ( std::vector<float>::const_iterator it = val.begin(); it != val.end(); ++it ) {
00136 pcColorMat->diffuseColor.set1Value(i++, SbColor(*it, *it, *it));
00137 }
00138
00139 pcColorMat->enableNotify(true);
00140 pcColorMat->touch();
00141 }
00142
00143 void ViewProviderPoints::setVertexNormalMode(Points::PropertyNormalList* pcProperty)
00144 {
00145 const std::vector<Base::Vector3f>& val = pcProperty->getValues();
00146 unsigned long i=0;
00147
00148 pcPointsNormal->enableNotify(false);
00149 pcPointsNormal->vector.deleteValues(0);
00150 pcPointsNormal->vector.setNum(val.size());
00151
00152 for ( std::vector<Base::Vector3f>::const_iterator it = val.begin(); it != val.end(); ++it ) {
00153 pcPointsNormal->vector.set1Value(i++, it->x, it->y, it->z);
00154 }
00155
00156 pcPointsNormal->enableNotify(true);
00157 pcPointsNormal->touch();
00158 }
00159
00160 void ViewProviderPoints::attach(App::DocumentObject* pcObj)
00161 {
00162
00163 ViewProviderGeometryObject::attach(pcObj);
00164
00165 SoGroup* pcPointRoot = new SoGroup();
00166 SoGroup* pcPointShadedRoot = new SoGroup();
00167 SoGroup* pcColorShadedRoot = new SoGroup();
00168
00169
00170 pcHighlight->addChild(pcPointsCoord);
00171 pcHighlight->addChild(pcPoints);
00172
00173
00174 pcPointRoot->addChild(pcPointStyle);
00175 pcPointRoot->addChild(pcShapeMaterial);
00176 pcPointRoot->addChild(pcHighlight);
00177
00178
00179 pcPointShadedRoot->addChild(pcPointStyle);
00180 pcPointShadedRoot->addChild(pcShapeMaterial);
00181 pcPointShadedRoot->addChild(pcPointsNormal);
00182 pcPointShadedRoot->addChild(pcHighlight);
00183
00184
00185 pcColorShadedRoot->addChild(pcPointStyle);
00186 SoMaterialBinding* pcMatBinding = new SoMaterialBinding;
00187 pcMatBinding->value = SoMaterialBinding::PER_VERTEX_INDEXED;
00188 pcColorShadedRoot->addChild(pcColorMat);
00189 pcColorShadedRoot->addChild(pcMatBinding);
00190 pcColorShadedRoot->addChild(pcHighlight);
00191
00192
00193 addDisplayMaskMode(pcPointRoot, "Point");
00194 addDisplayMaskMode(pcColorShadedRoot, "Color");
00195 addDisplayMaskMode(pcPointShadedRoot, "Shaded");
00196 }
00197
00198 void ViewProviderPoints::setDisplayMode(const char* ModeName)
00199 {
00200 int numPoints = pcPointsCoord->point.getNum();
00201
00202 if ( strcmp("Color",ModeName)==0 )
00203 {
00204 std::map<std::string,App::Property*> Map;
00205 pcObject->getPropertyMap(Map);
00206 for( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it )
00207 {
00208 Base::Type t = it->second->getTypeId();
00209 if ( t==App::PropertyColorList::getClassTypeId() )
00210 {
00211 App::PropertyColorList* colors = (App::PropertyColorList*)it->second;
00212 if ( numPoints != colors->getSize() ) {
00213 #ifdef FC_DEBUG
00214 SoDebugError::postWarning("ViewProviderPoints::setDisplayMode",
00215 "The number of points (%d) doesn't match with the number of colors (%d).", numPoints, colors->getSize());
00216 #endif
00217
00218 setDisplayMaskMode("Point");
00219 } else {
00220 setVertexColorMode(colors);
00221 setDisplayMaskMode("Color");
00222 }
00223 break;
00224 }
00225 }
00226 }
00227 else if ( strcmp("Intensity",ModeName)==0 )
00228 {
00229 std::map<std::string,App::Property*> Map;
00230 pcObject->getPropertyMap(Map);
00231 for( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it )
00232 {
00233 Base::Type t = it->second->getTypeId();
00234 if ( t==Points::PropertyGreyValueList::getClassTypeId() )
00235 {
00236 Points::PropertyGreyValueList* greyValues = (Points::PropertyGreyValueList*)it->second;
00237 if ( numPoints != greyValues->getSize() ) {
00238 #ifdef FC_DEBUG
00239 SoDebugError::postWarning("ViewProviderPoints::setDisplayMode",
00240 "The number of points (%d) doesn't match with the number of grey values (%d).", numPoints, greyValues->getSize());
00241 #endif
00242
00243 setDisplayMaskMode("Point");
00244 } else {
00245 setVertexGreyvalueMode((Points::PropertyGreyValueList*)it->second);
00246 setDisplayMaskMode("Color");
00247 }
00248 break;
00249 }
00250 }
00251 }
00252 else if ( strcmp("Shaded",ModeName)==0 )
00253 {
00254 std::map<std::string,App::Property*> Map;
00255 pcObject->getPropertyMap(Map);
00256 for( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it )
00257 {
00258 Base::Type t = it->second->getTypeId();
00259 if ( t==Points::PropertyNormalList::getClassTypeId() )
00260 {
00261 Points::PropertyNormalList* normals = (Points::PropertyNormalList*)it->second;
00262 if ( numPoints != normals->getSize() ) {
00263 #ifdef FC_DEBUG
00264 SoDebugError::postWarning("ViewProviderPoints::setDisplayMode",
00265 "The number of points (%d) doesn't match with the number of normals (%d).", numPoints, normals->getSize());
00266 #endif
00267
00268 setDisplayMaskMode("Point");
00269 } else {
00270 setVertexNormalMode(normals);
00271 setDisplayMaskMode("Shaded");
00272 }
00273 break;
00274 }
00275 }
00276 }
00277 else if ( strcmp("Points",ModeName)==0 )
00278 {
00279 setDisplayMaskMode("Point");
00280 }
00281
00282 ViewProviderGeometryObject::setDisplayMode(ModeName);
00283 }
00284
00285 std::vector<std::string> ViewProviderPoints::getDisplayModes(void) const
00286 {
00287 std::vector<std::string> StrList;
00288 StrList.push_back("Points");
00289
00290 if ( pcObject )
00291 {
00292 std::map<std::string,App::Property*> Map;
00293 pcObject->getPropertyMap(Map);
00294
00295 for( std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it )
00296 {
00297 Base::Type t = it->second->getTypeId();
00298 if ( t==Points::PropertyNormalList::getClassTypeId() )
00299 StrList.push_back("Shaded");
00300 else if ( t==Points::PropertyGreyValueList::getClassTypeId() )
00301 StrList.push_back("Intensity");
00302 else if ( t==App::PropertyColorList::getClassTypeId() )
00303 StrList.push_back("Color");
00304 }
00305 }
00306
00307 return StrList;
00308 }
00309
00310 void ViewProviderPoints::updateData(const App::Property* prop)
00311 {
00312 Gui::ViewProviderGeometryObject::updateData(prop);
00313 if (prop->getTypeId() == Points::PropertyPointKernel::getClassTypeId()) {
00314 ViewProviderPointsBuilder builder;
00315 builder.createPoints(prop, pcPointsCoord, pcPoints);
00316
00317
00318 setActiveMode();
00319 }
00320 }
00321
00322 QIcon ViewProviderPoints::getIcon() const
00323 {
00324 static const char * const Points_Feature_xpm[] = {
00325 "16 16 4 1",
00326 ". c none",
00327 "s c #000000",
00328 "b c #FFFF00",
00329 "r c #FF0000",
00330 "ss.....ss.....bb",
00331 "ss..ss.ss.....bb",
00332 "....ss..........",
00333 "...........bb...",
00334 ".ss..ss....bb...",
00335 ".ss..ss.........",
00336 "........bb....bb",
00337 "ss......bb....bb",
00338 "ss..rr......bb..",
00339 "....rr......bb..",
00340 "........bb......",
00341 "..rr....bb..bb..",
00342 "..rr........bb..",
00343 ".....rr.........",
00344 "rr...rr..rr..rr.",
00345 "rr.......rr..rr."};
00346 QPixmap px(Points_Feature_xpm);
00347 return px;
00348 }
00349
00350 bool ViewProviderPoints::setEdit(int)
00351 {
00352 return true;
00353 }
00354
00355 void ViewProviderPoints::unsetEdit(int)
00356 {
00357 }
00358
00359 void ViewProviderPoints::clipPointsCallback(void * ud, SoEventCallback * n)
00360 {
00361
00362 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00363 view->setEditing(false);
00364 view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), clipPointsCallback);
00365 n->setHandled();
00366
00367 std::vector<SbVec2f> clPoly = view->getGLPolygon();
00368 if (clPoly.size() < 3)
00369 return;
00370 if (clPoly.front() != clPoly.back())
00371 clPoly.push_back(clPoly.front());
00372
00373 std::vector<Gui::ViewProvider*> views = view->getViewProvidersOfType(ViewProviderPoints::getClassTypeId());
00374 for (std::vector<Gui::ViewProvider*>::iterator it = views.begin(); it != views.end(); ++it) {
00375 ViewProviderPoints* that = static_cast<ViewProviderPoints*>(*it);
00376 if (that->getEditingMode() > -1) {
00377 that->finishEditing();
00378 that->cut(clPoly, *view);
00379 }
00380 }
00381
00382 view->render();
00383 }
00384
00385 void ViewProviderPoints::cut(const std::vector<SbVec2f>& picked, Gui::View3DInventorViewer &Viewer)
00386 {
00387
00388 Base::Polygon2D cPoly;
00389 for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it) {
00390 cPoly.Add(Base::Vector2D((*it)[0],(*it)[1]));
00391 }
00392
00393
00394 Points::Feature* fea = (Points::Feature*)pcObject;
00395 const Points::PointKernel& points = fea->Points.getValue();
00396
00397 SoCamera* pCam = Viewer.getCamera();
00398 SbViewVolume vol = pCam->getViewVolume();
00399
00400
00401 Points::PointKernel newKernel;
00402 for ( Points::PointKernel::const_iterator jt = points.begin(); jt != points.end(); ++jt ) {
00403 SbVec3f pt(jt->x,jt->y,jt->z);
00404
00405
00406 vol.projectToScreen(pt, pt);
00407 if (!cPoly.Contains(Base::Vector2D(pt[0],pt[1])))
00408 newKernel.push_back(*jt);
00409 }
00410
00411 if (newKernel.size() == points.size())
00412 return;
00413
00414
00415 Gui::Application::Instance->activeDocument()->openCommand("Cut points");
00416
00417
00418 fea->Points.setValue(newKernel);
00419
00420
00421 Gui::Application::Instance->activeDocument()->commitCommand();
00422 fea->purgeTouched();
00423 }
00424
00425
00426
00427 namespace Gui {
00429 PROPERTY_SOURCE_TEMPLATE(PointsGui::ViewProviderPython, PointsGui::ViewProviderPoints)
00431
00432
00433 template class PointsGuiExport ViewProviderPythonFeatureT<PointsGui::ViewProviderPoints>;
00434 }
00435
00436
00437
00438 void ViewProviderPointsBuilder::buildNodes(const App::Property* prop, std::vector<SoNode*>& nodes) const
00439 {
00440 SoCoordinate3 *pcPointsCoord=0;
00441 SoPointSet *pcPoints=0;
00442
00443 if (nodes.empty()) {
00444 pcPointsCoord = new SoCoordinate3();
00445 nodes.push_back(pcPointsCoord);
00446 pcPoints = new SoPointSet();
00447 nodes.push_back(pcPoints);
00448 }
00449 else if (nodes.size() == 2) {
00450 if (nodes[0]->getTypeId() == SoCoordinate3::getClassTypeId())
00451 pcPointsCoord = static_cast<SoCoordinate3*>(nodes[0]);
00452 if (nodes[1]->getTypeId() == SoPointSet::getClassTypeId())
00453 pcPoints = static_cast<SoPointSet*>(nodes[1]);
00454 }
00455
00456 if (pcPointsCoord && pcPoints)
00457 createPoints(prop, pcPointsCoord, pcPoints);
00458 }
00459
00460 void ViewProviderPointsBuilder::createPoints(const App::Property* prop, SoCoordinate3* coords, SoPointSet* points) const
00461 {
00462 const Points::PropertyPointKernel* prop_points = static_cast<const Points::PropertyPointKernel*>(prop);
00463 const Points::PointKernel& cPts = prop_points->getValue();
00464
00465
00466 coords->enableNotify(false);
00467 coords->point.deleteValues(0);
00468 coords->point.setNum(cPts.size());
00469
00470
00471 int idx=0;
00472 const std::vector<Base::Vector3f>& kernel = cPts.getBasicPoints();
00473 for (std::vector<Base::Vector3f>::const_iterator it = kernel.begin(); it != kernel.end(); ++it, idx++) {
00474 coords->point.set1Value(idx, it->x, it->y, it->z);
00475 }
00476
00477 points->numPoints = cPts.size();
00478 coords->enableNotify(true);
00479 coords->touch();
00480 }