0024904: Visualization - Integration of VIS component:
[occt.git] / src / IVtkOCC / IVtkOCC_SelectableObject.cxx
1 // Created on: 2011-10-20 
2 // Created by: Roman KOZLOV
3 // Copyright (c) 2011-2014 OPEN CASCADE SAS 
4 // 
5 // This file is part of Open CASCADE Technology software library.
6 //
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16 #include <AIS_Shape.hxx>
17 #include <BRepBndLib.hxx>
18 #include <IVtkOCC_SelectableObject.hxx>
19 #include <Select3D_SensitiveBox.hxx>
20 #include <SelectMgr_Selection.hxx>
21 #include <Standard_ErrorHandler.hxx>
22 #include <StdSelect_BRepOwner.hxx>
23 #include <StdSelect_BRepSelectionTool.hxx>
24 #include <TopoDS_Iterator.hxx>
25
26 // Handle implementation
27 IMPLEMENT_STANDARD_HANDLE( IVtkOCC_SelectableObject, SelectMgr_SelectableObject )
28 IMPLEMENT_STANDARD_RTTIEXT( IVtkOCC_SelectableObject, SelectMgr_SelectableObject )
29
30 //============================================================================
31 // Method:  Constructor
32 // Purpose: Constructs a selectable object initalized by the given shape
33 //============================================================================
34 IVtkOCC_SelectableObject::IVtkOCC_SelectableObject (const IVtkOCC_Shape::Handle& theShape)
35 : SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
36   myShape (theShape)
37 {
38   if (!myShape.IsNull())
39   {
40     myShape->SetSelectableObject (this);
41   }
42
43   // Minor stuff - but it facilitates usage of OCCT selection 
44   // classes dealing with deflection, see ComputeSelection() below
45   myOCCTDrawer = new Prs3d_Drawer();
46 }
47
48 //============================================================================
49 // Method:  Constructor
50 // Purpose: Constructs uninitialized selectable object.
51 //          setShape() should be called later.
52 //============================================================================
53 IVtkOCC_SelectableObject::IVtkOCC_SelectableObject()
54 : SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
55   myShape (0)
56 { }
57
58 //============================================================================
59 // Method:  SetShape
60 // Purpose: Sets the selectable shape
61 //============================================================================
62 void IVtkOCC_SelectableObject::SetShape (const IVtkOCC_Shape::Handle& theShape)
63 {
64   myShape = theShape;
65   if (myShape)
66   {
67     myShape->SetSelectableObject (this);
68   }
69
70   // Shape has changed -> Clear all internal data
71   myBndBox.SetVoid();
72   myselections.Clear();
73 }
74
75 //============================================================================
76 // Method:  ComputeSelection
77 // Purpose: Internal method, computes selection data for viewer selector
78 //============================================================================
79 void IVtkOCC_SelectableObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
80                                                  const Standard_Integer theMode)
81 {
82   if (!myShape)
83   {
84     return;
85   }
86
87   TopoDS_Shape anOcctShape = myShape->GetShape();
88
89   if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
90   {
91     TopoDS_Iterator anExplor (anOcctShape);
92     if (!anExplor.More()) // Shape empty -> go away
93     {
94       return;
95     }
96   }
97
98   TopAbs_ShapeEnum aTypeOfSel = AIS_Shape::SelectionType (theMode);
99
100   Standard_Real aDeflection = myOCCTDrawer->MaximalChordialDeviation();
101   if (myOCCTDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)
102   {
103     Bnd_Box aBndBox;
104     BRepBndLib::Add (anOcctShape, aBndBox);
105     if (!aBndBox.IsVoid())
106     {
107       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
108       aBndBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
109       aDeflection = Max (aXmax - aXmin, Max (aYmax - aYmin, aZmax - aZmin)) * 
110         myOCCTDrawer->DeviationCoefficient();
111     }
112   }
113
114   // Assume the shape has been displayed already -> triangulation should exist
115   Standard_Boolean isAutoTriangulation = Standard_False;
116
117   try
118   {
119     OCC_CATCH_SIGNALS
120     StdSelect_BRepSelectionTool::Load (theSelection,
121                                        this,
122                                        anOcctShape,
123                                        aTypeOfSel,
124                                        aDeflection,
125                                        myOCCTDrawer->DeviationAngle(),
126                                        isAutoTriangulation);
127   }
128   catch (Standard_Failure)
129   {
130     if (theMode == 0)
131     {
132       Bnd_Box aBndBox = BoundingBox();
133       Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner (anOcctShape, this);
134       Handle(Select3D_SensitiveBox) aSensitiveBox = 
135         new Select3D_SensitiveBox (aOwner, aBndBox);
136       theSelection->Add (aSensitiveBox);
137     }
138   }
139 }
140
141 //============================================================================
142 // Method:  BoundingBox
143 // Purpose:
144 //============================================================================
145 const Bnd_Box& IVtkOCC_SelectableObject::BoundingBox()
146 {
147   if (!myShape)
148   {
149     myBndBox.SetVoid();
150     return myBndBox;
151   }
152
153   TopoDS_Shape anOcctShape = myShape->GetShape();
154
155   if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
156   {
157     TopoDS_Iterator anExplor (anOcctShape);
158     if (!anExplor.More())
159     { // Shape empty -> nothing to do
160       myBndBox.SetVoid();
161       return myBndBox;
162     }
163   }
164
165   if (myBndBox.IsVoid())
166   {
167     // Add only edges and vertices, in case of troubles this should work anyway
168     BRepBndLib::AddClose (anOcctShape, myBndBox);
169   }
170
171   return myBndBox;
172 }