]> SALOME platform Git repositories - modules/geom.git/blob - src/EntityGUI/EntityGUI_FeatureDetectorDlg.cxx
Salome HOME
Merge from BR_OPENCV
[modules/geom.git] / src / EntityGUI / EntityGUI_FeatureDetectorDlg.cxx
1 // Copyright (C) 2007-2011  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 // GEOM GEOMGUI : GUI for Geometry component
24 // File   : EntityGUI_SketcherDlg.cxx
25 // Author : Renaud NEDELEC, Open CASCADE S.A.S.
26
27 #include "EntityGUI_FeatureDetectorDlg.h"
28
29 #include <OCCViewer_ViewPort3d.h>
30 #include <OCCViewer_ViewWindow.h>
31 #include <OCCViewer_ViewManager.h>
32
33 #include <SOCC_ViewModel.h>
34
35 #include <DlgRef.h>
36 #include <GeometryGUI.h>
37 #include <EntityGUI.h>
38 #include <GEOMBase.h>
39 #include <GEOM_Object.hxx>
40 #include <ShapeRec_FeatureDetector.hxx>
41
42 #include <SUIT_Desktop.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_ViewWindow.h>
46 #include <SalomeApp_Application.h>
47 #include <LightApp_Application.h>
48 #include <LightApp_SelectionMgr.h>
49
50 #include <SALOME_ListIteratorOfListIO.hxx>
51
52 #include <SalomeApp_Study.h>
53
54 #include <utilities.h>
55
56 #include <gp_Pnt.hxx>
57 #include <TopoDS_Shape.hxx>
58 #include <TopoDS_Wire.hxx>
59
60 #include <BRepBuilderAPI_MakeVertex.hxx>
61 #include <BRepBuilderAPI_MakeFace.hxx>
62 #include <BRepBuilderAPI_MakePolygon.hxx>
63 #include <BRepBuilderAPI_Transform.hxx>
64
65 #include <AIS_TexturedShape.hxx>
66 #include <TCollection_AsciiString.hxx>
67 #include <StdSelect_DisplayMode.hxx>
68
69 #include <Graphic3d_MaterialAspect.hxx>
70
71 #include <Precision.hxx>
72
73 #include <set>
74 #include <utility>
75
76 #include <boost/utility.hpp>
77
78 // Constructors
79 enum{
80   CONTOURS,
81   CORNERS,
82   LINES
83 };
84
85 enum {
86   RADIO_BUTTONS,
87   MSG,
88   PUSH_BUTTON,
89 };
90
91 // // // View
92 // // enum {
93 // //   XY,
94 // //   YZ,
95 // //   XZ
96 // // };
97   
98
99 //=================================================================================
100 // class    : EntityGUI_FeatureDetectorDlg()
101 // purpose  : Constructs a EntityGUI_FeatureDetectorDlg which is a child of 'parent', with the
102 //            name 'name' and widget flags set to 'f'.
103 //            The dialog will by default be modeless, unless you set 'modal' to
104 //            TRUE to construct a modal dialog.
105 //=================================================================================
106 EntityGUI_FeatureDetectorDlg::EntityGUI_FeatureDetectorDlg( GeometryGUI* theGeometryGUI, QWidget* parent,
107                                               bool modal, Qt::WindowFlags fl)
108   : GEOMBase_Skeleton(theGeometryGUI, parent, modal, fl) 
109 {
110   QPixmap image0(SUIT_Session::session()->resourceMgr()->loadPixmap("OCCViewer", tr("ICON_OCCVIEWER_VIEW_DUMP")));
111   QPixmap image1(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
112   
113   setWindowTitle(tr("GEOM_DETECT_TITLE"));
114   
115   /***************************************************************/
116   
117   mainFrame()->GroupConstructors->setTitle(tr("GEOM_FEATURES"));
118   mainFrame()->RadioButton1->setText(tr("GEOM_CONTOURS"));
119   mainFrame()->RadioButton2->setText(tr("GEOM_CORNERS"));
120 //   mainFrame()->RadioButton2->setAttribute(Qt::WA_DeleteOnClose);
121 //   mainFrame()->RadioButton2->close();
122 //   mainFrame()->RadioButton3->setAttribute(Qt::WA_DeleteOnClose);
123 //   mainFrame()->RadioButton3->close();
124   
125 //   myViewGroup = new DlgRef_3Radio(centralWidget());
126 //   myViewGroup->GroupBox1->setTitle(tr("GEOM_VIEW"));
127 //   myViewGroup->RadioButton1->setText(tr( "GEOM_TOP"  ));
128 //   myViewGroup->RadioButton2->setText(tr( "GEOM_FRONT"));
129 //   myViewGroup->RadioButton3->setText(tr( "GEOM_LEFT" ));
130 //   myViewButtonGroup = new QButtonGroup( this );
131 //   myViewButtonGroup->addButton( myViewGroup->RadioButton1, XY ); // Top view
132 //   myViewButtonGroup->addButton( myViewGroup->RadioButton2, YZ ); // Front View
133 //   myViewButtonGroup->addButton( myViewGroup->RadioButton3, XZ ); // Left View
134 //   
135 //   myViewGroup->hide();
136   
137   mySelectionGroup = new QGroupBox(tr("GEOM_DETECT"), centralWidget());
138   QGridLayout* mySelectGrpLayout = new QGridLayout(mySelectionGroup);
139   myPushButton = new QPushButton(mySelectionGroup);
140   myPushButton->setIcon(image0);
141   myPushButton->setCheckable(true);
142   
143   mySelButton = new QPushButton(mySelectionGroup);
144   mySelButton->setIcon(image1);
145   myLineEdit = new QLineEdit(mySelectionGroup);
146   myCheckBox = new QCheckBox(mySelectionGroup);
147   
148   mySnapshotLabel = new QLabel(mySelectionGroup);
149   mySelectGrpLayout->addWidget(myLineEdit,      0, 1);
150   mySelectGrpLayout->addWidget(mySelButton,     0, 0);
151   mySelectGrpLayout->addWidget(mySnapshotLabel, 1, 1);
152   mySelectGrpLayout->addWidget(myPushButton,    1, 0);
153   mySelectGrpLayout->addWidget(myCheckBox,      2, 0);
154   
155   myOutputGroup = new DlgRef_3Radio(centralWidget());
156   myOutputGroup->GroupBox1->setTitle(tr("GEOM_DETECT_OUTPUT"));
157   myOutputGroup->RadioButton2->setText(tr( "GEOM_POLYLINE"  ));
158   myOutputGroup->RadioButton1->setText(tr( "GEOM_SPLINE"));
159   myOutputGroup->RadioButton3->hide();
160   
161 //   myOutputGroup->hide(); //caché pour la demo
162     
163   QVBoxLayout* layout = new QVBoxLayout(centralWidget());
164   layout->setMargin(0); layout->setSpacing(6);
165 //   layout->addWidget( myViewGroup);
166   layout->addWidget( mySelectionGroup);
167   layout->addWidget( myOutputGroup);
168   
169 //   mainFrame()->GroupBoxName->hide();
170   
171   Init();
172   
173 }
174
175 //=================================================================================
176 // function : ~EntityGUI_FeatureDetectorDlg()
177 // purpose  : Destroys the object and frees any allocated resources
178 //=================================================================================
179 EntityGUI_FeatureDetectorDlg::~EntityGUI_FeatureDetectorDlg()
180 {
181   
182 }
183
184 //=================================================================================
185 // function : Init()
186 // purpose  :
187 //=================================================================================
188 void EntityGUI_FeatureDetectorDlg::Init()
189 {
190   connect( myGeomGUI,         SIGNAL( SignalCloseAllDialogs() ), this, SLOT( ClickOnCancel() ) );
191   connect( buttonOk(),        SIGNAL( clicked() ),               this, SLOT( ClickOnOk() ) );
192   connect( buttonApply(),     SIGNAL( clicked() ),               this, SLOT( ClickOnApply() ) );
193  
194   connect( this,              SIGNAL(constructorsClicked(int)),  this, SLOT(ConstructorsClicked(int)));
195   
196   connect( myPushButton,      SIGNAL( toggled( bool ) ),         this, SLOT( onButtonToggled( bool ) ) );
197   connect( mySelButton,       SIGNAL( clicked() ),               this, SLOT( SetEditCurrentArgument() ) );
198   
199 //   connect( myViewButtonGroup, SIGNAL( buttonClicked( int ) ),    this, SLOT( onViewClicked( int ) ) );
200   
201   connect( myGeomGUI->getApp()->selectionMgr(), SIGNAL( currentSelectionChanged() ),this, SLOT( SelectionIntoArgument() ) );
202   
203   myConstructorId = 0;
204   
205   mySelButton->click();
206   mySelButton->setDown(true);
207   
208 //   SetEditCurrentArgument();
209   SelectionIntoArgument();
210   
211   initName(tr("GEOM_CONTOURS")); 
212   resize(100,100);
213   
214 //   myViewGroup->RadioButton1->setChecked(true);
215   myOutputGroup->RadioButton1->setChecked(true);
216   
217   gp_Pnt aOrigin = gp_Pnt(0, 0, 0);
218   gp_Dir aDirZ = gp_Dir(0, 0, 1);
219   gp_Dir aDirX = gp_Dir(1, 0, 0);
220   
221   aGlobalCS = gp_Ax3(aOrigin, aDirZ, aDirX);
222   
223   myStartPnt = QPoint(0,0);
224   myEndPnt = myStartPnt;
225   
226   myGeomGUI->SetWorkingPlane( aGlobalCS );
227   myGeomGUI->ActiveWorkingPlane();
228   
229   ConstructorsClicked(myConstructorId);
230 }
231
232 //=================================================================================
233 // function : SetEditCurrentArgument()
234 // purpose  :
235 //=================================================================================
236 void EntityGUI_FeatureDetectorDlg::SetEditCurrentArgument()
237 {
238   QPushButton* send = (QPushButton*)sender();
239   if ( send == mySelButton ) { 
240     myEditCurrentArgument = myLineEdit;
241     myLineEdit->setEnabled(true);
242   }
243   else 
244     myLineEdit->setEnabled(false);
245   send->setDown(true);
246 }
247
248 //=================================================================================
249 // function : SelectionIntoArgument()
250 // purpose  : Called when selection as changed or other case
251 //=================================================================================
252 void EntityGUI_FeatureDetectorDlg::SelectionIntoArgument()
253 {
254   if (!myEditCurrentArgument->isEnabled())
255     return;
256   
257   myEditCurrentArgument->setText( "" );
258
259   LightApp_SelectionMgr* aSelMgr = myGeomGUI->getApp()->selectionMgr();
260   SALOME_ListIO aSelList;
261   aSelMgr->selectedObjects(aSelList);
262   SALOME_ListIteratorOfListIO anIt( aSelList );
263   for( ; anIt.More(); anIt.Next() )
264     if( !anIt.Value().IsNull() )
265     {
266       myFaceEntry = anIt.Value()->getEntry();
267     }
268
269   if (aSelList.Extent() != 1) {
270     if (myEditCurrentArgument == myLineEdit) 
271       myFace.nullify();
272     return;
273   }
274
275   TopAbs_ShapeEnum aNeedType = TopAbs_FACE ;
276   GEOM::GeomObjPtr aSelectedObject = getSelected( aNeedType );
277   TopoDS_Shape aShape;
278   if ( aSelectedObject && GEOMBase::GetShape( aSelectedObject.get(), aShape ) && !aShape.IsNull() ) {
279     QString aName = GEOMBase::GetName( aSelectedObject.get() );
280     myEditCurrentArgument->setText( aName );
281     if ( myEditCurrentArgument == myLineEdit ) {
282       myFace = aSelectedObject;
283     } 
284   }
285   
286 }
287
288
289 // //=================================================================================
290 // // function : OnPointSelected
291 // // purpose  :
292 // //=================================================================================
293 // void EntityGUI_FeatureDetectorDlg::OnPointSelected(const gp_Pnt& thePnt)
294 // {
295 //   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
296 //   int aPrecision = resMgr->integerValue("Geometry", "length_precision", 6);
297 //   if (myPushButton1->isDown())
298 //   {
299 // //     myX->setValue(thePnt.X());
300 // //     myY->setValue(thePnt.Y());
301 // //     myZ->setValue(thePnt.Z());
302 //     myX->setText(DlgRef::PrintDoubleValue(thePnt.X(), aPrecision));
303 //     myY->setText(DlgRef::PrintDoubleValue(thePnt.Y(), aPrecision));
304 //     myZ->setText(DlgRef::PrintDoubleValue(thePnt.Z(), aPrecision));
305 //     x1 = thePnt.X(); 
306 //     y1 = thePnt.Y();
307 //     z1 = thePnt.Z();
308 //   
309 //     myPushButton2->click();
310 //   }
311 //   else
312 //   {
313 // //     myX2->setValue(thePnt.X());
314 // //     myY2->setValue(thePnt.Y());
315 // //     myZ2->setValue(thePnt.Z());
316 //     myX2->setText(DlgRef::PrintDoubleValue(thePnt.X(), aPrecision));
317 //     myY2->setText(DlgRef::PrintDoubleValue(thePnt.Y(), aPrecision));
318 //     myZ2->setText(DlgRef::PrintDoubleValue(thePnt.Z(), aPrecision));
319 //     x2 = thePnt.X(); 
320 //     y2 = thePnt.Y();
321 //     z2 = thePnt.Z();
322 //    
323 //   }
324 // }
325
326 //=================================================================================
327 // function : acceptMouseEvent()
328 // purpose  :
329 //=================================================================================
330 bool EntityGUI_FeatureDetectorDlg::acceptMouseEvent() const
331
332   return myPushButton->isChecked();  
333 }
334
335 //=======================================================================
336 // function : ClickOnOk()
337 // purpose  :
338 //=======================================================================
339 void EntityGUI_FeatureDetectorDlg::ClickOnOk()
340 {
341   setIsApplyAndClose( true );
342   if (onAccept())
343     ClickOnCancel();
344 }
345
346 //=================================================================================
347 // function : ClickOnApply()
348 // purpose  :
349 //=================================================================================
350 bool EntityGUI_FeatureDetectorDlg::ClickOnApply()
351 {
352   if (!onAccept())
353     return false;
354
355 //   initName();
356   ConstructorsClicked(getConstructorId());
357   return true;
358 }
359
360 //=================================================================================
361 // function : onConstructorClicked(int)
362 // purpose  :
363 //=================================================================================
364 void EntityGUI_FeatureDetectorDlg::ConstructorsClicked(int id)
365 {
366   MESSAGE("Constructor id ="<<id)
367   myConstructorId = id;
368   switch (id)
369   {
370     case CORNERS:
371 //       myViewGroup->show();
372 //       mySelectionGroup->show();
373       mySnapshotLabel->setText(tr("GEOM_DETECT_ZONE"));
374       initName(tr("GEOM_CORNERS"));
375       break;
376     case CONTOURS:
377 //       myViewGroup->hide();
378 //       mySelectionGroup->hide();
379 //       mySelectionGroup->show();
380       mySnapshotLabel->setText(tr("GEOM_COLOR_FILTER"));
381       initName(tr("GEOM_CONTOURS"));
382       break;
383     case LINES:
384 //       myViewGroup->hide();
385 //       mySelectionGroup->hide();
386 //       mySelectionGroup->show();
387       mySnapshotLabel->setText(tr(""));
388       initName(tr("GEOM_LINES"));
389       break;
390   }
391 }
392
393 // //=================================================================================
394 // // function : onViewClicked()
395 // // purpose  :
396 // //=================================================================================
397 // void EntityGUI_FeatureDetectorDlg::onViewClicked(int id)
398 // {
399 //   gp_Pnt aOrigin = gp_Pnt(0, 0, 0);
400 //   gp_Dir aDirZ;
401 //   gp_Dir aDirX;
402 //   
403 //   switch(id)
404 //   {
405 //     case XY:
406 //         aDirZ = gp_Dir(0, 0, 1);
407 //         aDirX = gp_Dir(1, 0, 0);
408 //       break;
409 //     case YZ:
410 //         aDirZ = gp_Dir(1, 0, 0);
411 //         aDirX = gp_Dir(0, 1, 0);
412 //       break;
413 //     case XZ:
414 //         aDirZ = gp_Dir(0, -1, 0);
415 //         aDirX = gp_Dir(1, 0 , 0);
416 //       break;
417 //   }
418 //   
419 //   myWPlane = gp_Ax3(aOrigin, aDirZ, aDirX);
420 //   myGeomGUI->SetWorkingPlane( myWPlane );
421 //   myGeomGUI->ActiveWorkingPlane();
422 //   
423 // }
424
425 //=================================================================================
426 // function : onButtonToggled()
427 // purpose  :
428 //=================================================================================
429 void EntityGUI_FeatureDetectorDlg::onButtonToggled( bool checked)
430 {
431   if (!checked)
432   {
433     myStartPnt = QPoint(0,0);
434     myEndPnt = myStartPnt;
435     myLineEdit->setEnabled(true);
436   }
437   else
438   {
439     myLineEdit->setEnabled(false);
440   }
441 }
442
443 //=================================================================================
444 // function : setStartPnt( const QPoint& )
445 // purpose  :
446 //=================================================================================
447 void EntityGUI_FeatureDetectorDlg::setStartPnt(const QPoint& theStartPnt)
448 {
449   myStartPnt = theStartPnt;
450 }
451
452 //=================================================================================
453 // function : setEndPnt( const QPoint& )
454 // purpose  :
455 //=================================================================================
456 void EntityGUI_FeatureDetectorDlg::setEndPnt(const QPoint& theEndPnt)
457 {
458   myEndPnt = theEndPnt;
459 }
460
461 //=================================================================================
462 // function : createOperation
463 // purpose  :
464 //=================================================================================
465 GEOM::GEOM_IOperations_ptr EntityGUI_FeatureDetectorDlg::createOperation()
466 {
467   return myGeomGUI->GetGeomGen()->GetIShapesOperations( getStudyId() );
468 }
469
470 //=================================================================================
471 // function : execute()
472 // purpose  :
473 //=================================================================================
474 bool EntityGUI_FeatureDetectorDlg::execute( ObjectList& objects )
475 {
476   MESSAGE("EntityGUI_FeatureDetectorDlg::execute( ObjectList& objects )")
477   
478   bool res = false;
479   SUIT_ViewWindow*       theViewWindow  = getDesktop()->activeWindow();
480   OCCViewer_ViewPort3d*  vp             = ((OCCViewer_ViewWindow*)theViewWindow)->getViewPort();
481   
482   MESSAGE("myFaceEntry = "<< myFaceEntry.toStdString());
483   std::map< std::string , std::vector<Handle(AIS_InteractiveObject)> >::iterator AISit;
484   SOCC_Viewer* soccViewer = (SOCC_Viewer*)(theViewWindow->getViewManager()->getViewModel());
485   
486   MESSAGE("repere1")
487   AISit = soccViewer->entry2aisobjects.find(myFaceEntry.toStdString());
488   if (AISit == soccViewer->entry2aisobjects.end())
489     return res;
490   
491   Handle(AIS_InteractiveObject) myAIS = (*AISit).second[0];
492   Handle(GEOM_AISShape) myAISShape;
493   if( myAIS->IsInstance( STANDARD_TYPE(GEOM_AISShape) ) ) {
494     myAISShape = Handle(GEOM_AISShape)::DownCast( myAIS );
495   }
496   else
497     return res;
498   
499   QString theImgFileName = QString::fromStdString( myAISShape->TextureFile() );
500    
501   
502   if ( theImgFileName.isEmpty() )
503     return res;
504   
505   // Build an instance of detection used to perform image processing operations
506   ShapeRec_FeatureDetector* aDetector = new ShapeRec_FeatureDetector( theImgFileName );
507     
508   int height            =  aDetector->GetImgHeight();
509   int width             =  aDetector->GetImgWidth();
510   
511 //   NOTE: OLD
512   int winHeight         =  vp->height();
513   int winWidth          =  vp->width();
514   double x_offset, y_offset;
515   int i;
516
517 //   NOTE: OLD
518   // Recompute of the values computed in OCC OpenGl_view.c 
519   // while waiting for a function to retrieve parameters of the displayed backgroun image 
520   double hratio = winHeight * 1.0 / height;
521   double wratio = winWidth  * 1.0 / width ;
522   double imgZoomRatio = 1.0;
523   
524   if (hratio < wratio){ 
525     x_offset = 0.5 * width * hratio;
526     y_offset = 0.5 * winHeight;
527     imgZoomRatio = hratio;
528   }
529   else {
530     y_offset = 0.5 * height * wratio;
531     x_offset = 0.5 * winWidth;
532     imgZoomRatio = wratio;
533   }
534   
535   // Selection rectangle coordinates in the view
536   double rectLeft  = myStartPnt.x(); 
537   double rectTop   = myStartPnt.y(); 
538   
539   // Operations to display the corners properly in the 3D scene
540   double viewLeft  = 0.5 * winWidth  - x_offset;  // X coordinate of the top left  corner of the background image in the view
541   double viewTop   = 0.5 * winHeight - y_offset;  // Y coordinate of both top corners
542   
543   // Set detection rectangle in the background image coordinates system and detect the corners
544   myStartPnt.setX( (myStartPnt.x() -  (0.5 * winWidth  - x_offset)) * 1.0 / imgZoomRatio );
545   myStartPnt.setY( (myStartPnt.y() -  (0.5 * winHeight - y_offset)) * 1.0 / imgZoomRatio );
546   myEndPnt.setX(   (myEndPnt.x()   -  (0.5 * winWidth  - x_offset)) * 1.0 / imgZoomRatio );
547   myEndPnt.setY(   (myEndPnt.y()   -  (0.5 * winHeight - y_offset)) * 1.0 / imgZoomRatio );
548   
549   QRect aRect = QRect(myStartPnt, myEndPnt);
550   
551   
552   GEOM::GEOM_IBasicOperations_var  aBasicOperations  = myGeomGUI->GetGeomGen()->GetIBasicOperations( getStudyId() );
553   GEOM::GEOM_IShapesOperations_var aShapesOperations = GEOM::GEOM_IShapesOperations::_narrow( getOperation() );
554   if (myConstructorId == CORNERS)
555   {
556     if( !aRect.isEmpty() )
557     {
558       aDetector->SetROI( aRect );
559       viewLeft  =  rectLeft;                
560       viewTop   =  rectTop;
561     }
562     aDetector->ComputeCorners();
563     CvPoint2D32f* corners     = aDetector->GetCorners();
564     int cornerCount           = aDetector->GetCornerCount();
565     
566     // Build the geom objects associated to the detected corners and returned by execute   
567     if( !aBasicOperations->_is_nil() && !aShapesOperations->_is_nil() ) 
568     {
569       GEOM::GEOM_Object_var  aGeomCorner;
570       GEOM::ListOfGO_var     geomCorners = new GEOM::ListOfGO();
571       geomCorners->length( cornerCount );
572       for (i = 0; i < cornerCount; i++)
573       {
574 //         gp_Pnt aCornerPnt = EntityGUI::ConvertClickToPoint( viewLeft + corners[i].x*imgZoomRatio,
575 //                                                             viewTop  + corners[i].y*imgZoomRatio, vp->getView() );
576 //         
577 //         double x = aCornerPnt.X();
578 //         double y = aCornerPnt.Y();
579 //         double z = aCornerPnt.Z();
580
581         // When using the new way with textures on shapes we just have to do the following
582         double x = -0.5*width  + corners[i].x;
583         double y =  0.5*height - corners[i].y;
584         double z =  0;
585         
586         aGeomCorner = aBasicOperations->MakePointXYZ( x,y,z );
587         
588         geomCorners[i] = aGeomCorner;  
589       } 
590       GEOM::GEOM_Object_var aCompound = aShapesOperations->MakeCompound(geomCorners);    
591       if ( !aCompound->_is_nil() )
592       {
593         // Dark blue color
594         SALOMEDS::Color aColor;
595         aColor.R = 0;
596         aColor.G = 0;
597         aColor.B = 0.8;
598         
599         aCompound->SetColor(aColor);
600         aCompound->SetMarkerStd(GEOM::MT_POINT,GEOM::MS_30);
601         objects.push_back( aCompound._retn() );
602         res = true;
603       }
604     }
605   }
606   else if (myConstructorId == CONTOURS)
607   {
608     int method = 0 ; //CANNY
609     if( !aRect.isEmpty() && aRect.width() > 1 )
610     {
611       aDetector->SetROI( aRect );
612       method = 1 ; //COLORFILTER    
613     }
614     
615     GEOM::GEOM_ICurvesOperations_var aCurveOperations = myGeomGUI->GetGeomGen()->GetICurvesOperations( getStudyId() );
616 //     GEOM::GEOM_ICurvesOperations::_narrow( getOperation() );
617     
618     aDetector->ComputeContours( method );
619     std::vector< std::vector<cv::Point> >   contours  = aDetector->GetContours();
620     std::vector<cv::Vec4i>                  hierarchy = aDetector->GetContoursHierarchy();
621     
622     std::vector< cv::Point >                contour;
623     int idx = 0;
624     
625     GEOM::ListOfGO_var                      geomContours = new GEOM::ListOfGO();
626     int contourCount = 0;
627     
628     bool insert;
629     
630     // TEST for debug only
631 //     GEOM::GEOM_Object_var  aRemovedPnt;
632 //     GEOM::ListOfGO_var     removedPnts     = new GEOM::ListOfGO();
633 //     int r = 0;
634     
635     MESSAGE("hierarchy.size() =" << hierarchy.size()) 
636     for( ; idx >= 0; idx = hierarchy[idx][0])
637     {
638 //       for(int count=0, child=idx; child>=0, count<1; child=hierarchy[idx][2], count++)
639 //       {     
640 //         contour = contours[child];
641         contour = contours[idx];
642         std::vector< cv::Point >::iterator it;
643         std::vector< cv::Point >::iterator it_previous;
644         std::vector< cv::Point >::iterator it_next;
645         GEOM::GEOM_Object_var  aGeomContourPnt;
646         GEOM::ListOfGO_var     geomContourPnts = new GEOM::ListOfGO();
647        
648         geomContourPnts->length( contour.size() );
649
650         int j = 0;
651         std::set< std::vector<int> > existing_points;
652         std::pair< std::set< std::vector<int> >::iterator,bool > pnt_it;
653         for ( it=contour.begin() ; it < contour.end(); it++ )
654         {
655   //         gp_Pnt  aContourPnt = EntityGUI::ConvertClickToPoint(viewLeft + it->x*imgZoomRatio, viewTop + it->y*imgZoomRatio, vp->getView());
656   //         double x = aContourPnt.X();
657   //         double y = aContourPnt.Y();
658   //         double z = aContourPnt.Z();
659           
660           // When using the new way with textures on shapes we just have to do the following
661           int pnt_array[] = {it->x,it->y};     
662           std::vector<int> pnt (pnt_array, pnt_array + sizeof(pnt_array) / sizeof(int) );
663
664           pnt_it=existing_points.insert(pnt);
665           if (pnt_it.second == true || !myCheckBox->isChecked() )         // To avoid double points in the contours
666           {
667             insert = true;
668             if (it!=contour.begin())         // From the second point on perform some checking to avoid loops in the contours we build
669             {
670               it_previous = boost::prior(it);
671               it_next = boost::next(it);
672               
673               double u_v_scalar_product = (it->x - it_previous->x) * (it_next->x - it->x) + 
674                                           (it->y - it_previous->y) * (it_next->y - it->y);                                       
675               if (u_v_scalar_product < 0)
676               {
677                 double u_v_det = (it->x - it_previous->x) * (it_next->y - it->y) - 
678                                  (it->y - it_previous->y) * (it_next->x - it->x);
679                                           
680                 double norme_u = sqrt ( (it->x - it_previous->x)*(it->x - it_previous->x) +
681                                         (it->y - it_previous->y)*(it->y - it_previous->y) );
682                 
683                 double norme_v = sqrt ( (it->x - it_next->x)*(it->x - it_next->x) +
684                                         (it->y - it_next->y)*(it->y - it_next->y) );
685                                                                                                 
686                 double u_v_sinus = u_v_det / (norme_u * norme_v);
687                 
688                 if (fabs(u_v_sinus) < Precision::Confusion())
689                 { 
690                   // TEST for debug only
691 //                   if (myCheckBox->isChecked())
692 //                   {
693 //                     MESSAGE("correction appliquee : fabs(u_v_sinus) ="<<fabs(u_v_sinus))
694 //                     MESSAGE("it->x = "<<it->x)
695 //                     MESSAGE("it->y = "<<it->y)
696 //                     MESSAGE("it_previous->x = "<<it_previous->x)
697 //                     MESSAGE("it_previous->y = "<<it_previous->y)
698 //                     MESSAGE("it_next->x = "<<it_next->x)
699 //                     MESSAGE("it_next->y = "<<it_next->y)
700 //                     MESSAGE("norme_u = "<<norme_u)
701 //                     MESSAGE("norme_v = "<<norme_v)
702 //                     MESSAGE("u_v_det = "<<u_v_det)
703 //                   }
704                   insert = !myCheckBox->isChecked();  // TEST correction appliquee que si la checkbox est cochee
705                 }                         
706               }
707             }
708             double x = -0.5 *width  + it->x;
709             double y =  0.5 *height - it->y;
710             double z =  0;
711             if (insert)
712             {
713               aGeomContourPnt    = aBasicOperations->MakePointXYZ( x,y,z );
714               geomContourPnts->length( j+1 );
715               geomContourPnts[j] = aGeomContourPnt;
716               j++;
717             }
718 //             TEST for debug only
719 //             else
720 //             { 
721 //               aRemovedPnt   = aBasicOperations->MakePointXYZ( x,y,z );
722 //               removedPnts->length( r+1 );
723 //               removedPnts[r] = aRemovedPnt;
724 //               r++;
725 //             }
726           }
727         }
728         
729         GEOM::GEOM_Object_var aWire;
730         if(myOutputGroup->RadioButton2->isChecked())
731         {
732           aWire = aCurveOperations->MakePolyline(geomContourPnts.in(), false);
733         }
734         else if(myOutputGroup->RadioButton1->isChecked())
735         {
736           aWire = aCurveOperations->MakeSplineInterpolation(geomContourPnts.in(), /*closed =*/ false, /*reordering =*/ false);
737         }
738         else
739           return res;
740         
741         if ( !aWire->_is_nil() )
742         {
743           geomContours->length(contourCount + 1);
744           geomContours[contourCount] = aWire;
745           contourCount++;
746         }
747 //       }
748     }
749     GEOM::GEOM_Object_var aContoursCompound = aShapesOperations->MakeCompound(geomContours);
750 //   TEST for debu only  GEOM::GEOM_Object_var aRemovedPntsCompound = aShapesOperations->MakeCompound(removedPnts);
751     if ( !aContoursCompound->_is_nil() )
752     {
753       objects.push_back( aContoursCompound._retn() );
754     }
755 //   TEST for debug only
756 //     if ( !aRemovedPntsCompound->_is_nil() )
757 //     {
758 //       objects.push_back( aRemovedPntsCompound._retn() );
759 //     }
760
761     res=true;
762   }
763   
764   else if(myConstructorId ==LINES)
765   {
766     aDetector->ComputeLines();
767     std::vector<cv::Vec4i>  lines = aDetector->GetLines();
768     GEOM::GEOM_Object_var  Pnt1;
769     GEOM::GEOM_Object_var  Pnt2;
770     GEOM::GEOM_Object_var  aLine;
771     
772     GEOM::ListOfGO_var     geomLines = new GEOM::ListOfGO();
773     int linesCount=0;
774     for( int i = 0; i < lines.size(); i++ )
775     {
776       Pnt1 = aBasicOperations->MakePointXYZ( -0.5 *width + lines[i][0], 0.5 *height - lines[i][1], 0 );
777       Pnt2 = aBasicOperations->MakePointXYZ( -0.5 *width + lines[i][2], 0.5 *height - lines[i][3], 0 );
778       aLine = aBasicOperations->MakeLineTwoPnt( Pnt1, Pnt2 );
779       if ( !aLine->_is_nil() )
780       {
781         geomLines->length(linesCount + 1);
782         geomLines[linesCount] = aLine;
783         linesCount++;
784       }
785     }
786     GEOM::GEOM_Object_var aLinesCompound = aShapesOperations->MakeCompound(geomLines);
787     if ( !aLinesCompound->_is_nil() )
788     {
789       objects.push_back( aLinesCompound._retn() );
790     }
791
792     res=true;
793   }
794   
795   return res;
796 }