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 <algorithm>
00028 # include <climits>
00029 # include <boost/bind.hpp>
00030 # include <QPushButton>
00031 # include <Inventor/SbBox2s.h>
00032 # include <Inventor/SoPickedPoint.h>
00033 # include <Inventor/details/SoFaceDetail.h>
00034 # include <Inventor/events/SoMouseButtonEvent.h>
00035 # include <Inventor/nodes/SoSeparator.h>
00036 #endif
00037
00038 #include "RemoveComponents.h"
00039 #include "ui_RemoveComponents.h"
00040 #include "ViewProvider.h"
00041 #include <Base/Console.h>
00042 #include <Base/Tools.h>
00043 #include <App/Application.h>
00044 #include <Gui/Application.h>
00045 #include <Gui/Document.h>
00046 #include <Gui/Selection.h>
00047 #include <Gui/SoFCSelectionAction.h>
00048 #include <Gui/View3DInventor.h>
00049 #include <Gui/View3DInventorViewer.h>
00050 #include <Mod/Mesh/App/MeshFeature.h>
00051 #include <Mod/Mesh/App/Core/Algorithm.h>
00052 #include <Mod/Mesh/App/Core/MeshKernel.h>
00053 #include <Mod/Mesh/App/Core/Iterator.h>
00054 #include <Mod/Mesh/App/Core/TopoAlgorithm.h>
00055 #include <Mod/Mesh/App/Core/Tools.h>
00056
00057 using namespace MeshGui;
00058
00059 #define CROSS_WIDTH 16
00060 #define CROSS_HEIGHT 16
00061 #define CROSS_HOT_X 7
00062 #define CROSS_HOT_Y 7
00063
00064 static unsigned char cross_bitmap[] = {
00065 0xc0, 0x03, 0x40, 0x02, 0x40, 0x02, 0x40, 0x02,
00066 0x40, 0x02, 0x40, 0x02, 0x7f, 0xfe, 0x01, 0x80,
00067 0x01, 0x80, 0x7f, 0xfe, 0x40, 0x02, 0x40, 0x02,
00068 0x40, 0x02, 0x40, 0x02, 0x40, 0x02, 0xc0, 0x03
00069 };
00070
00071 static unsigned char cross_mask_bitmap[] = {
00072 0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xff,0xff,0xff,
00073 0xff,0xff,0xff,0xff,0xff,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,0xc0,0x03,
00074 0xc0,0x03
00075 };
00076
00077 RemoveComponents::RemoveComponents(QWidget* parent, Qt::WFlags fl)
00078 : QWidget(parent, fl), _interactiveMode(0)
00079 {
00080 ui = new Ui_RemoveComponents;
00081 ui->setupUi(this);
00082 ui->spSelectComp->setRange(1, INT_MAX);
00083 ui->spSelectComp->setValue(10);
00084 ui->spDeselectComp->setRange(1, INT_MAX);
00085 ui->spDeselectComp->setValue(10);
00086 }
00087
00088 RemoveComponents::~RemoveComponents()
00089 {
00090
00091 delete ui;
00092 }
00093
00094 void RemoveComponents::changeEvent(QEvent *e)
00095 {
00096 if (e->type() == QEvent::LanguageChange) {
00097 ui->retranslateUi(this);
00098 }
00099 QWidget::changeEvent(e);
00100 }
00101
00102 void RemoveComponents::on_selectRegion_clicked()
00103 {
00104
00105 this->selectRegion = true;
00106 Gui::View3DInventorViewer* viewer = this->getViewer();
00107 if (viewer) {
00108 stopInteractiveCallback(viewer);
00109 startInteractiveCallback(viewer, selectGLCallback);
00110
00111 viewer->startSelection(Gui::View3DInventorViewer::Lasso);
00112 SoQtCursor::CustomCursor custom;
00113 custom.dim.setValue(CROSS_WIDTH, CROSS_HEIGHT);
00114 custom.hotspot.setValue(CROSS_HOT_X, CROSS_HOT_Y);
00115 custom.bitmap = cross_bitmap;
00116 custom.mask = cross_mask_bitmap;
00117 viewer->setComponentCursor(SoQtCursor(&custom));
00118 }
00119 }
00120
00121 void RemoveComponents::on_deselectRegion_clicked()
00122 {
00123
00124 this->selectRegion = false;
00125 Gui::View3DInventorViewer* viewer = this->getViewer();
00126 if (viewer) {
00127 stopInteractiveCallback(viewer);
00128 startInteractiveCallback(viewer, selectGLCallback);
00129
00130 viewer->startSelection(Gui::View3DInventorViewer::Lasso);
00131 SoQtCursor::CustomCursor custom;
00132 custom.dim.setValue(CROSS_WIDTH, CROSS_HEIGHT);
00133 custom.hotspot.setValue(CROSS_HOT_X, CROSS_HOT_Y);
00134 custom.bitmap = cross_bitmap;
00135 custom.mask = cross_mask_bitmap;
00136 viewer->setComponentCursor(SoQtCursor(&custom));
00137 }
00138 }
00139
00140 void RemoveComponents::on_selectAll_clicked()
00141 {
00142
00143 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00144 if (!doc) return;
00145 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00146 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00147 Mesh::Feature* mf = static_cast<Mesh::Feature*>((*it)->getObject());
00148 const Mesh::MeshObject* mo = mf->Mesh.getValuePtr();
00149 std::vector<unsigned long> faces(mo->countFacets());
00150 std::generate(faces.begin(), faces.end(), Base::iotaGen<unsigned long>(0));
00151 (*it)->addSelection(faces);
00152 }
00153 }
00154
00155 void RemoveComponents::on_deselectAll_clicked()
00156 {
00157
00158 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00159 if (!doc) return;
00160 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00161 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00162 (*it)->clearSelection();
00163 }
00164 }
00165
00166 void RemoveComponents::on_selectComponents_clicked()
00167 {
00168
00169 int size = ui->spSelectComp->value();
00170 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00171 if (!doc) return;
00172 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00173 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00174 Mesh::Feature* mf = static_cast<Mesh::Feature*>((*it)->getObject());
00175 const Mesh::MeshObject* mo = mf->Mesh.getValuePtr();
00176
00177 std::vector<std::vector<unsigned long> > segm;
00178 MeshCore::MeshComponents comp(mo->getKernel());
00179 comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segm);
00180
00181 std::vector<unsigned long> faces;
00182 for (std::vector<std::vector<unsigned long> >::iterator jt = segm.begin(); jt != segm.end(); ++jt) {
00183 if (jt->size() < (unsigned long)size)
00184 faces.insert(faces.end(), jt->begin(), jt->end());
00185 }
00186
00187 (*it)->addSelection(faces);
00188 }
00189 }
00190
00191 void RemoveComponents::on_deselectComponents_clicked()
00192 {
00193
00194 int size = ui->spDeselectComp->value();
00195 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00196 if (!doc) return;
00197 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00198 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00199 Mesh::Feature* mf = static_cast<Mesh::Feature*>((*it)->getObject());
00200 const Mesh::MeshObject* mo = mf->Mesh.getValuePtr();
00201
00202 std::vector<std::vector<unsigned long> > segm;
00203 MeshCore::MeshComponents comp(mo->getKernel());
00204 comp.SearchForComponents(MeshCore::MeshComponents::OverEdge,segm);
00205
00206 std::vector<unsigned long> faces;
00207 for (std::vector<std::vector<unsigned long> >::iterator jt = segm.begin(); jt != segm.end(); ++jt) {
00208 if (jt->size() > (unsigned long)size)
00209 faces.insert(faces.end(), jt->begin(), jt->end());
00210 }
00211
00212 (*it)->removeSelection(faces);
00213 }
00214 }
00215
00216 void RemoveComponents::deleteSelection()
00217 {
00218
00219 bool selected = false;
00220 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00221 if (!doc) return;
00222 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00223 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00224 Mesh::Feature* mf = static_cast<Mesh::Feature*>((*it)->getObject());
00225 unsigned long ct = MeshCore::MeshAlgorithm(mf->Mesh.getValue().getKernel()).
00226 CountFacetFlag(MeshCore::MeshFacet::SELECTED);
00227 if (ct > 0) {
00228 selected = true;
00229 break;
00230 }
00231 }
00232 if (!selected) return;
00233
00234 doc->openCommand("Delete selection");
00235 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00236 (*it)->deleteSelection();
00237 }
00238 doc->commitCommand();
00239 }
00240
00241 void RemoveComponents::invertSelection()
00242 {
00243 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00244 if (!doc) return;
00245 std::list<ViewProviderMesh*> views = getViewProviders(doc);
00246 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00247 Mesh::Feature* mf = static_cast<Mesh::Feature*>((*it)->getObject());
00248 const Mesh::MeshObject* mo = mf->Mesh.getValuePtr();
00249 const MeshCore::MeshFacetArray& faces = mo->getKernel().GetFacets();
00250 unsigned long num_notsel = std::count_if(faces.begin(), faces.end(),
00251 std::bind2nd(MeshCore::MeshIsNotFlag<MeshCore::MeshFacet>(),
00252 MeshCore::MeshFacet::SELECTED));
00253 std::vector<unsigned long> notselect;
00254 notselect.reserve(num_notsel);
00255 MeshCore::MeshFacetArray::_TConstIterator beg = faces.begin();
00256 MeshCore::MeshFacetArray::_TConstIterator end = faces.end();
00257 for (MeshCore::MeshFacetArray::_TConstIterator jt = beg; jt != end; ++jt) {
00258 if (!jt->IsFlag(MeshCore::MeshFacet::SELECTED))
00259 notselect.push_back(jt-beg);
00260 }
00261 (*it)->setSelection(notselect);
00262 }
00263 }
00264
00265 void RemoveComponents::on_selectTriangle_clicked()
00266 {
00267
00268 this->selectRegion = true;
00269 Gui::View3DInventorViewer* viewer = this->getViewer();
00270 if (viewer) {
00271 stopInteractiveCallback(viewer);
00272 startInteractiveCallback(viewer, pickFaceCallback);
00273 }
00274 }
00275
00276 void RemoveComponents::on_deselectTriangle_clicked()
00277 {
00278
00279 this->selectRegion = false;
00280 Gui::View3DInventorViewer* viewer = this->getViewer();
00281 if (viewer) {
00282 stopInteractiveCallback(viewer);
00283 startInteractiveCallback(viewer, pickFaceCallback);
00284 }
00285 }
00286
00287 void RemoveComponents::reject()
00288 {
00289 if (_interactiveMode) {
00290 Gui::View3DInventorViewer* viewer = this->getViewer();
00291 if (viewer)
00292 stopInteractiveCallback(viewer);
00293 }
00294 on_deselectAll_clicked();
00295 }
00296
00297 std::list<ViewProviderMesh*> RemoveComponents::getViewProviders(const Gui::Document* doc) const
00298 {
00299 std::list<ViewProviderMesh*> vps;
00300 std::vector<Mesh::Feature*> mesh = doc->getDocument()->getObjectsOfType<Mesh::Feature>();
00301 for (std::vector<Mesh::Feature*>::iterator it = mesh.begin(); it != mesh.end(); ++it) {
00302 Gui::ViewProvider* vp = doc->getViewProvider(*it);
00303 if (vp->isVisible())
00304 vps.push_back(static_cast<ViewProviderMesh*>(vp));
00305 }
00306
00307 return vps;
00308 }
00309
00310 Gui::View3DInventorViewer* RemoveComponents::getViewer() const
00311 {
00312 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00313 if (!doc) return 0;
00314 Gui::MDIView* view = doc->getActiveView();
00315 if (view && view->getTypeId().isDerivedFrom(Gui::View3DInventor::getClassTypeId())) {
00316 Gui::View3DInventorViewer* viewer = static_cast<Gui::View3DInventor*>(view)->getViewer();
00317 return viewer;
00318 }
00319
00320 return 0;
00321 }
00322
00323 void RemoveComponents::startInteractiveCallback(Gui::View3DInventorViewer* viewer,SoEventCallbackCB *cb)
00324 {
00325 if (this->_interactiveMode)
00326 return;
00327 viewer->setEditing(true);
00328 viewer->addEventCallback(SoMouseButtonEvent::getClassTypeId(), cb, this);
00329 this->_interactiveMode = cb;
00330 }
00331
00332 void RemoveComponents::stopInteractiveCallback(Gui::View3DInventorViewer* viewer)
00333 {
00334 if (!this->_interactiveMode)
00335 return;
00336 if (viewer->isEditing()) {
00337 viewer->setEditing(false);
00338 viewer->removeEventCallback(SoMouseButtonEvent::getClassTypeId(), this->_interactiveMode, this);
00339 this->_interactiveMode = 0;
00340 }
00341 }
00342
00343 void RemoveComponents::selectGLCallback(void * ud, SoEventCallback * n)
00344 {
00345
00346 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00347 RemoveComponents* that = reinterpret_cast<RemoveComponents*>(ud);
00348 that->stopInteractiveCallback(view);
00349 n->setHandled();
00350 std::vector<SbVec2f> polygon = view->getGLPolygon();
00351 if (polygon.size() < 3)
00352 return;
00353 if (polygon.front() != polygon.back())
00354 polygon.push_back(polygon.front());
00355
00356 SbVec3f pnt, dir;
00357 view->getNearPlane(pnt, dir);
00358 Base::Vector3f point (pnt[0],pnt[1],pnt[2]);
00359 Base::Vector3f normal(dir[0],dir[1],dir[2]);
00360
00361 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00362 if (!doc) return;
00363 std::list<ViewProviderMesh*> views = that->getViewProviders(doc);
00364 for (std::list<ViewProviderMesh*>::iterator it = views.begin(); it != views.end(); ++it) {
00365 ViewProviderMesh* vp = static_cast<ViewProviderMesh*>(*it);
00366
00367 std::vector<unsigned long> faces;
00368 const Mesh::MeshObject& mesh = static_cast<Mesh::Feature*>((*it)->getObject())->Mesh.getValue();
00369 const MeshCore::MeshKernel& kernel = mesh.getKernel();
00370
00371
00372 vp->getFacetsFromPolygon(polygon, *view, true, faces);
00373 if (that->ui->frontTriangles->isChecked()) {
00374 const SbVec2s& sz = view->getViewportRegion().getWindowSize();
00375 short width,height; sz.getValue(width,height);
00376 std::vector<SbVec2s> pixelPoly = view->getPolygon();
00377 SbBox2s rect;
00378 for (std::vector<SbVec2s>::iterator it = pixelPoly.begin(); it != pixelPoly.end(); ++it) {
00379 const SbVec2s& p = *it;
00380 rect.extendBy(SbVec2s(p[0],height-p[1]));
00381 }
00382 std::vector<unsigned long> rf; rf.swap(faces);
00383 std::vector<unsigned long> vf = vp->getVisibleFacetsAfterZoom
00384 (rect, view->getViewportRegion(), view->getCamera());
00385
00386
00387 std::sort(vf.begin(), vf.end());
00388 std::sort(rf.begin(), rf.end());
00389 std::back_insert_iterator<std::vector<unsigned long> > biit(faces);
00390 std::set_intersection(vf.begin(), vf.end(), rf.begin(), rf.end(), biit);
00391 }
00392
00393
00394 if (that->ui->screenTriangles->isChecked()) {
00395 std::vector<unsigned long> screen;
00396 screen.reserve(faces.size());
00397 MeshCore::MeshFacetIterator it_f(kernel);
00398 for (std::vector<unsigned long>::iterator it = faces.begin(); it != faces.end(); ++it) {
00399 it_f.Set(*it);
00400 if (it_f->GetNormal() * normal > 0.0f) {
00401 screen.push_back(*it);
00402 }
00403 }
00404
00405 faces.swap(screen);
00406 }
00407
00408 if (that->selectRegion)
00409 vp->addSelection(faces);
00410 else
00411 vp->removeSelection(faces);
00412 }
00413
00414 view->render();
00415 }
00416
00417 void RemoveComponents::pickFaceCallback(void * ud, SoEventCallback * n)
00418 {
00419
00420 if (n->getEvent()->isOfType(SoMouseButtonEvent::getClassTypeId())) {
00421 const SoMouseButtonEvent * mbe = static_cast<const SoMouseButtonEvent*>(n->getEvent());
00422 Gui::View3DInventorViewer* view = reinterpret_cast<Gui::View3DInventorViewer*>(n->getUserData());
00423
00424
00425 n->getAction()->setHandled();
00426 if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) {
00427 const SoPickedPoint * point = n->getPickedPoint();
00428 if (point == NULL) {
00429 Base::Console().Message("No facet picked.\n");
00430 return;
00431 }
00432
00433 n->setHandled();
00434
00435
00436
00437 Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
00438 if (!vp || !vp->getTypeId().isDerivedFrom(ViewProviderMesh::getClassTypeId()))
00439 return;
00440 ViewProviderMesh* that = static_cast<ViewProviderMesh*>(vp);
00441 RemoveComponents* dlg = reinterpret_cast<RemoveComponents*>(ud);
00442 Gui::Document* doc = Gui::Application::Instance->activeDocument();
00443 if (!doc) return;
00444 std::list<ViewProviderMesh*> views = dlg->getViewProviders(doc);
00445 if (std::find(views.begin(), views.end(), that) == views.end())
00446 return;
00447 const SoDetail* detail = point->getDetail();
00448 if (detail && detail->getTypeId() == SoFaceDetail::getClassTypeId()) {
00449
00450 unsigned long uFacet = static_cast<const SoFaceDetail*>(detail)->getFaceIndex();
00451 std::vector<unsigned long> faces; faces.push_back(uFacet);
00452 if (dlg->selectRegion) {
00453 if (dlg->ui->cbSelectComp->isChecked())
00454 that->selectComponent(uFacet);
00455 else
00456 that->selectFacet(uFacet);
00457 }
00458 else {
00459 if (dlg->ui->cbDeselectComp->isChecked())
00460 that->deselectComponent(uFacet);
00461 else
00462 that->removeSelection(faces);
00463 }
00464 }
00465 }
00466 }
00467 }
00468
00469
00470
00471 RemoveComponentsDialog::RemoveComponentsDialog(QWidget* parent, Qt::WFlags fl)
00472 : QDialog(parent, fl)
00473 {
00474 widget = new RemoveComponents(this);
00475 this->setWindowTitle(widget->windowTitle());
00476
00477 QVBoxLayout* hboxLayout = new QVBoxLayout(this);
00478 QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
00479 buttonBox->setStandardButtons(QDialogButtonBox::Close|QDialogButtonBox::Ok);
00480 QPushButton* okButton = buttonBox->button(QDialogButtonBox::Ok);
00481 okButton->setText(MeshGui::TaskRemoveComponents::tr("Delete"));
00482 buttonBox->addButton(MeshGui::TaskRemoveComponents::tr("Invert"),
00483 QDialogButtonBox::ActionRole);
00484
00485 connect(buttonBox, SIGNAL(clicked(QAbstractButton*)),
00486 this, SLOT(clicked(QAbstractButton*)));
00487
00488 hboxLayout->addWidget(widget);
00489 hboxLayout->addWidget(buttonBox);
00490 }
00491
00492 RemoveComponentsDialog::~RemoveComponentsDialog()
00493 {
00494 }
00495
00496 void RemoveComponentsDialog::reject()
00497 {
00498 widget->reject();
00499 QDialog::reject();
00500 }
00501
00502 void RemoveComponentsDialog::clicked(QAbstractButton* btn)
00503 {
00504 QDialogButtonBox* buttonBox = qobject_cast<QDialogButtonBox*>(sender());
00505 QDialogButtonBox::StandardButton id = buttonBox->standardButton(btn);
00506 if (id == QDialogButtonBox::Ok) {
00507 widget->deleteSelection();
00508 }
00509 else if (id == QDialogButtonBox::Close) {
00510 this->reject();
00511 }
00512 else if (id == QDialogButtonBox::NoButton) {
00513 widget->invertSelection();
00514 }
00515 }
00516
00517
00518
00519
00520
00521 TaskRemoveComponents::TaskRemoveComponents()
00522 {
00523 widget = new RemoveComponents();
00524 taskbox = new Gui::TaskView::TaskBox(
00525 QPixmap(), widget->windowTitle(), false, 0);
00526 taskbox->groupLayout()->addWidget(widget);
00527 Content.push_back(taskbox);
00528 }
00529
00530 TaskRemoveComponents::~TaskRemoveComponents()
00531 {
00532
00533 }
00534
00535 void TaskRemoveComponents::modifyStandardButtons(QDialogButtonBox* box)
00536 {
00537 QPushButton* btn = box->button(QDialogButtonBox::Ok);
00538 btn->setText(tr("Delete"));
00539 box->addButton(tr("Invert"), QDialogButtonBox::ActionRole);
00540 }
00541
00542 bool TaskRemoveComponents::accept()
00543 {
00544 return false;
00545 }
00546
00547 void TaskRemoveComponents::clicked(int id)
00548 {
00549 if (id == QDialogButtonBox::Ok) {
00550 widget->deleteSelection();
00551 }
00552 else if (id == QDialogButtonBox::Close) {
00553 widget->reject();
00554 }
00555 else if (id == QDialogButtonBox::NoButton) {
00556 widget->invertSelection();
00557 }
00558 }
00559
00560 #include "moc_RemoveComponents.cpp"