0024947: Redesign OCCT legacy type system -- automatic
[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
28
29 //============================================================================
30 // Method:  Constructor
31 // Purpose: Constructs a selectable object initalized by the given shape
32 //============================================================================
33 IVtkOCC_SelectableObject::IVtkOCC_SelectableObject (const IVtkOCC_Shape::Handle& theShape)
34 : SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
35   myShape (theShape)
36 {
37   if (!myShape.IsNull())
38   {
39     myShape->SetSelectableObject (this);
40   }
41
42   // Minor stuff - but it facilitates usage of OCCT selection 
43   // classes dealing with deflection, see ComputeSelection() below
44   myOCCTDrawer = new Prs3d_Drawer();
45 }
46
47 //============================================================================
48 // Method:  Constructor
49 // Purpose: Constructs uninitialized selectable object.
50 //          setShape() should be called later.
51 //============================================================================
52 IVtkOCC_SelectableObject::IVtkOCC_SelectableObject()
53 : SelectMgr_SelectableObject (PrsMgr_TOP_AllView),
54   myShape (0)
55 { }
56
57 //============================================================================
58 // Method:  SetShape
59 // Purpose: Sets the selectable shape
60 //============================================================================
61 void IVtkOCC_SelectableObject::SetShape (const IVtkOCC_Shape::Handle& theShape)
62 {
63   myShape = theShape;
64   if (myShape)
65   {
66     myShape->SetSelectableObject (this);
67   }
68
69   // Shape has changed -> Clear all internal data
70   myBndBox.SetVoid();
71   myselections.Clear();
72 }
73
74 //============================================================================
75 // Method:  ComputeSelection
76 // Purpose: Internal method, computes selection data for viewer selector
77 //============================================================================
78 void IVtkOCC_SelectableObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
79                                                  const Standard_Integer theMode)
80 {
81   if (!myShape)
82   {
83     return;
84   }
85
86   TopoDS_Shape anOcctShape = myShape->GetShape();
87
88   if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
89   {
90     TopoDS_Iterator anExplor (anOcctShape);
91     if (!anExplor.More()) // Shape empty -> go away
92     {
93       return;
94     }
95   }
96
97   TopAbs_ShapeEnum aTypeOfSel = AIS_Shape::SelectionType (theMode);
98
99   Standard_Real aDeflection = myOCCTDrawer->MaximalChordialDeviation();
100   if (myOCCTDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)
101   {
102     Bnd_Box aBndBox;
103     BRepBndLib::Add (anOcctShape, aBndBox);
104     if (!aBndBox.IsVoid())
105     {
106       Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
107       aBndBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
108       aDeflection = Max (aXmax - aXmin, Max (aYmax - aYmin, aZmax - aZmin)) * 
109         myOCCTDrawer->DeviationCoefficient();
110     }
111   }
112
113   // Assume the shape has been displayed already -> triangulation should exist
114   Standard_Boolean isAutoTriangulation = Standard_False;
115
116   try
117   {
118     OCC_CATCH_SIGNALS
119     StdSelect_BRepSelectionTool::Load (theSelection,
120                                        this,
121                                        anOcctShape,
122                                        aTypeOfSel,
123                                        aDeflection,
124                                        myOCCTDrawer->DeviationAngle(),
125                                        isAutoTriangulation);
126   }
127   catch (Standard_Failure)
128   {
129     if (theMode == 0)
130     {
131       Bnd_Box aBndBox = BoundingBox();
132       Handle(StdSelect_BRepOwner) aOwner = new StdSelect_BRepOwner (anOcctShape, this);
133       Handle(Select3D_SensitiveBox) aSensitiveBox = 
134         new Select3D_SensitiveBox (aOwner, aBndBox);
135       theSelection->Add (aSensitiveBox);
136     }
137   }
138 }
139
140 //============================================================================
141 // Method:  BoundingBox
142 // Purpose:
143 //============================================================================
144 const Bnd_Box& IVtkOCC_SelectableObject::BoundingBox()
145 {
146   if (!myShape)
147   {
148     myBndBox.SetVoid();
149     return myBndBox;
150   }
151
152   TopoDS_Shape anOcctShape = myShape->GetShape();
153
154   if (anOcctShape.ShapeType() == TopAbs_COMPOUND)
155   {
156     TopoDS_Iterator anExplor (anOcctShape);
157     if (!anExplor.More())
158     { // Shape empty -> nothing to do
159       myBndBox.SetVoid();
160       return myBndBox;
161     }
162   }
163
164   if (myBndBox.IsVoid())
165   {
166     // Add only edges and vertices, in case of troubles this should work anyway
167     BRepBndLib::AddClose (anOcctShape, myBndBox);
168   }
169
170   return myBndBox;
171 }
172
173 //============================================================================
174 // Method:  BoundingBox
175 // Purpose:
176 //============================================================================
177 void IVtkOCC_SelectableObject::BoundingBox (Bnd_Box& theBndBox)
178 {
179   BoundingBox();
180   theBndBox = myBndBox;
181 }