static void selectionCallback(void * ud, SoEventCallback * cb) { Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(cb->getUserData()); view->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), selectionCallback, ud); SoNode* root = view->getSceneGraph(); static_cast<Gui::SoFCUnifiedSelection*>(root)->selectionRole.setValue(true); std::vector<SbVec2f> picked = view->getGLPolygon(); SoCamera* cam = view->getSoRenderManager()->getCamera(); SbViewVolume vv = cam->getViewVolume(); Gui::ViewVolumeProjection proj(vv); Base::Polygon2d polygon; if (picked.size() == 2) { SbVec2f pt1 = picked[0]; SbVec2f pt2 = picked[1]; polygon.Add(Base::Vector2d(pt1[0], pt1[1])); polygon.Add(Base::Vector2d(pt1[0], pt2[1])); polygon.Add(Base::Vector2d(pt2[0], pt2[1])); polygon.Add(Base::Vector2d(pt2[0], pt1[1])); } else { for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it) polygon.Add(Base::Vector2d((*it)[0],(*it)[1])); } FaceColors* self = reinterpret_cast<FaceColors*>(ud); self->d->view = 0; if (self->d->obj && self->d->obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { cb->setHandled(); const TopoDS_Shape& shape = static_cast<Part::Feature*>(self->d->obj)->Shape.getValue(); self->d->addFacesToSelection(view, proj, polygon, shape); view->redraw(); } }
void ViewProviderStructured::cut(const std::vector<SbVec2f>& picked, Gui::View3DInventorViewer &Viewer) { // create the polygon from the picked points Base::Polygon2d cPoly; for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it) { cPoly.Add(Base::Vector2d((*it)[0],(*it)[1])); } // get a reference to the point feature Points::Feature* fea = static_cast<Points::Feature*>(pcObject); const Points::PointKernel& points = fea->Points.getValue(); SoCamera* pCam = Viewer.getSoRenderManager()->getCamera(); SbViewVolume vol = pCam->getViewVolume(); // search for all points inside/outside the polygon Points::PointKernel newKernel; newKernel.reserve(points.size()); bool invalidatePoints = false; double nan = std::numeric_limits<double>::quiet_NaN(); for (Points::PointKernel::const_iterator jt = points.begin(); jt != points.end(); ++jt) { // valid point? Base::Vector3d vec(*jt); if (!(boost::math::isnan(jt->x) || boost::math::isnan(jt->y) || boost::math::isnan(jt->z))) { SbVec3f pt(jt->x,jt->y,jt->z); // project from 3d to 2d vol.projectToScreen(pt, pt); if (cPoly.Contains(Base::Vector2d(pt[0],pt[1]))) { invalidatePoints = true; vec.Set(nan, nan, nan); } } newKernel.push_back(vec); } if (invalidatePoints) { //Remove the points from the cloud and open a transaction object for the undo/redo stuff Gui::Application::Instance->activeDocument()->openCommand("Cut points"); // sets the points outside the polygon to update the Inventor node fea->Points.setValue(newKernel); // unset the modified flag because we don't need the features' execute() to be called Gui::Application::Instance->activeDocument()->commitCommand(); fea->purgeTouched(); } }
void ViewProviderScattered::cut(const std::vector<SbVec2f>& picked, Gui::View3DInventorViewer &Viewer) { // create the polygon from the picked points Base::Polygon2d cPoly; for (std::vector<SbVec2f>::const_iterator it = picked.begin(); it != picked.end(); ++it) { cPoly.Add(Base::Vector2d((*it)[0],(*it)[1])); } // get a reference to the point feature Points::Feature* fea = static_cast<Points::Feature*>(pcObject); const Points::PointKernel& points = fea->Points.getValue(); SoCamera* pCam = Viewer.getSoRenderManager()->getCamera(); SbViewVolume vol = pCam->getViewVolume(); // search for all points inside/outside the polygon std::vector<unsigned long> removeIndices; removeIndices.reserve(points.size()); unsigned long index = 0; for (Points::PointKernel::const_iterator jt = points.begin(); jt != points.end(); ++jt, ++index) { SbVec3f pt(jt->x,jt->y,jt->z); // project from 3d to 2d vol.projectToScreen(pt, pt); if (cPoly.Contains(Base::Vector2d(pt[0],pt[1]))) removeIndices.push_back(index); } if (removeIndices.empty()) return; // nothing needs to be done //Remove the points from the cloud and open a transaction object for the undo/redo stuff Gui::Application::Instance->activeDocument()->openCommand("Cut points"); // sets the points outside the polygon to update the Inventor node fea->Points.removeIndices(removeIndices); std::map<std::string,App::Property*> Map; pcObject->getPropertyMap(Map); for (std::map<std::string,App::Property*>::iterator it = Map.begin(); it != Map.end(); ++it) { Base::Type type = it->second->getTypeId(); if (type == Points::PropertyNormalList::getClassTypeId()) { static_cast<Points::PropertyNormalList*>(it->second)->removeIndices(removeIndices); } else if (type == Points::PropertyGreyValueList::getClassTypeId()) { static_cast<Points::PropertyGreyValueList*>(it->second)->removeIndices(removeIndices); } else if (type == App::PropertyColorList::getClassTypeId()) { //static_cast<App::PropertyColorList*>(it->second)->removeIndices(removeIndices); const std::vector<App::Color>& colors = static_cast<App::PropertyColorList*>(it->second)->getValues(); if (removeIndices.size() > colors.size()) break; std::vector<App::Color> remainValue; remainValue.reserve(colors.size() - removeIndices.size()); std::vector<unsigned long>::iterator pos = removeIndices.begin(); for (std::vector<App::Color>::const_iterator jt = colors.begin(); jt != colors.end(); ++jt) { unsigned long index = jt - colors.begin(); if (pos == removeIndices.end()) remainValue.push_back( *jt ); else if (index != *pos) remainValue.push_back( *jt ); else ++pos; } static_cast<App::PropertyColorList*>(it->second)->setValues(remainValue); } } // unset the modified flag because we don't need the features' execute() to be called Gui::Application::Instance->activeDocument()->commitCommand(); fea->purgeTouched(); }