Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2007-07-06 |
2 | // Created by: Alexander GRIGORIEV | |
973c2be1 | 3 | // Copyright (c) 2007-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 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 | |
973c2be1 | 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. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
7fd59977 | 15 | |
16 | #ifndef NIS_InteractiveObject_HeaderFile | |
17 | #define NIS_InteractiveObject_HeaderFile | |
18 | ||
19 | #include <NIS_Drawer.hxx> | |
20 | #include <Bnd_B3f.hxx> | |
21 | ||
22 | /** | |
23 | * Abstract base type for presentable and selectable object in NIS architecture. | |
24 | * @section InteractiveObject_class | |
25 | * An InteractiveObject has the attributes: | |
26 | * <ul> | |
27 | * <li>Integer ID that is unique within the Interactive Context that hosts | |
ffe2bea7 | 28 | * this Object. This ID is 0 if the Object is not yet attached to an |
7fd59977 | 29 | * InteractiveContext</li> |
30 | * <li>3D Bounding box</li> | |
ffe2bea7 | 31 | * <li>Presentable state of the Object: Normal, Hilighted or Transparent.</li> |
7fd59977 | 32 | * <li>Visibility state (shown/hidden)</li> |
ffe2bea7 A |
33 | * <li>Selectability (selectable/non-selectable)</li> |
34 | * <li>Transparency level (0 to 1 in 1/1000 steps) - for transparent state</li> | |
7fd59977 | 35 | * </ul> |
36 | * Because the class is abstract, it does not define any color, material and | |
37 | * other visual aspect - all relevant aspects should be defined in derived | |
ffe2bea7 A |
38 | * classes and their Drawers. |
39 | * | |
40 | * @section nis_interactiveobject_drawer Drawers for NIS_InteractiveObject | |
7fd59977 | 41 | * Every InteractiveObject type should have an associated NIS_Drawer type; a |
ffe2bea7 | 42 | * new instance of this associated drawer must be returned by the virtual method |
7fd59977 | 43 | * DefaultDrawer(). The drawer is responsible for the correct calculation of |
44 | * the presentation in every possible state (normal, hilighted, etc.); usually | |
ffe2bea7 A |
45 | * the associated drawer instance contains all relevant visual aspects. |
46 | * <p> | |
47 | * Association with a Drawer instance is performed by method SetDrawer(). This | |
7fd59977 | 48 | * method should not be called by any custom code, it is used internally by |
49 | * NIS algorithms (in NIS_InteractiveContext::Display() for instance). If you | |
50 | * develop your own InteractiveObject type, you will need to call SetDrawer | |
51 | * whenever you change the visual aspect, for example: | |
52 | * @code | |
53 | * void MyIOClass::SetColor (const Quantity_Color& theColor); | |
54 | * { | |
ffe2bea7 A |
55 | * const Handle(MyIOClassDrawer) aDrawer = |
56 | * static_cast<MyIOClassDrawer*>(DefaultDrawer(0L)); | |
7fd59977 | 57 | * // copy the current visual aspects and other attributes to the new Drawer |
58 | * aDrawer->Assign (GetDrawer()); | |
59 | * // replace the Drawer | |
60 | * aDrawer->myColor = theColor; | |
61 | * SetDrawer (aDrawer); | |
7fd59977 | 62 | * } |
63 | * @endcode | |
ffe2bea7 A |
64 | * Please keep in mind that with this scheme you should not store the color in |
65 | * MyIOClass type, because it is already stored in its Drawer. | |
66 | * | |
67 | * @section nis_interactiveobject_selection Interactive selection | |
68 | * Interactive selection is made in class NIS_InteractiveContext, methods | |
69 | * selectObjects(). These methods call the virtual API of interactive object, | |
70 | * that consists of 3 methods: | |
71 | * <ul> | |
72 | * <li>Intersect (theAxis, theOver) : find the intersection point with a 3D ray, | |
73 | * the method returns the coordinate of intersection point on the ray. | |
74 | * Parameter theOver provides the tolerance for intersection of thin | |
75 | * geometries (lines, vertices)</li> | |
76 | * <li>Intersect (theBox, theTrsf, isFullIn) : check if the interactive object | |
77 | * intersects with a 3D box. Transformation 'theTrf' is the <b>inverse</b> | |
78 | * box transformation, so it is applied to the interactive object rather | |
79 | * than to the 3D box (3D box stays axis-aligned during intersection | |
80 | * test). Parameter IsFullIn defines the condition for the result: if | |
81 | * True then the whole interactive object must be contained inside the box, | |
82 | * otherwise it is sufficient if only a portion (e.g., a point) is inside. | |
83 | * This method is used for interactive rectangle selection.</li> | |
84 | * <li>Intersect (thePolygon, theTrsf, isFullIn) : similar to the previous | |
85 | * method, but using a polygonal prism instead of box, for selection by | |
86 | * closed curve or polygon.</li> | |
87 | * </ul> | |
88 | * | |
89 | * @section nis_interactiveobject_memory Memory management | |
90 | * All data used in the scope of NIS_InteractiveObject subtype should be either | |
91 | * its explicit fields or pointers to memory managed by a special NIS_Allocator | |
92 | * instance that belongs to NIS_InteractiveContext. This is strictly required | |
93 | * because NIS_InteractiveContext should completely manage all its objects, | |
94 | * meaning that it destroys/reallocates them automatically. To support that, | |
95 | * the virtual method Clone() should be correctly defined for every interactive | |
96 | * object subtype. Supposing that MyIOClass inherits MyBaseIOBase : | |
97 | * @code | |
98 | * void MyIOCalss::Clone (const Handle_NCollection_BaseAllocator& theAlloc, | |
99 | * Handle_NIS_InteractiveObject& theDest) const | |
100 | * { | |
101 | * Handle(MyIOClass) aNewObj; | |
102 | * if (theDest.IsNull()) { | |
103 | * aNewObj = new MyIOClass(); | |
104 | * theDest = aNewObj; | |
105 | * } else { | |
106 | * aNewObj = reinterpret_cast<MyIOClass*> (theDest.operator->()); | |
107 | * aNewObj->myAlloc = theAlloc; | |
108 | * } | |
109 | * MyIOBase::Clone(theAlloc, theDest); | |
110 | * aNewObj->myDataField = myDataField; | |
111 | * memcpy(myNewObj->myDataArray, myDataArray, nBytes); | |
112 | * ... | |
113 | * } | |
114 | * @endcode | |
115 | * | |
116 | * @section nis_interactiveobject_attribute Attribute | |
7fd59977 | 117 | * An instance of this class can have an associated value (Attribute) that is |
118 | * stored as a pointer. It can accommodate an integer/float/boolean value or | |
119 | * a pointer to some structure. This attribute is NOT automatically destroyed | |
120 | * with the InteractiveObject. | |
121 | */ | |
122 | ||
123 | class NIS_InteractiveObject : public Standard_Transient | |
124 | { | |
125 | public: | |
126 | // ---------- PUBLIC METHODS ---------- | |
127 | ||
128 | ||
129 | /** | |
130 | * Empty constructor. Creates an object that is not attached to drawer. | |
131 | */ | |
132 | inline NIS_InteractiveObject () | |
133 | : myID (0), | |
134 | myDrawType (NIS_Drawer::Draw_Normal), | |
ffe2bea7 | 135 | myBaseType (NIS_Drawer::Draw_Normal), |
7fd59977 | 136 | myIsHidden (Standard_True), |
137 | myIsDynHilighted (Standard_False), | |
138 | myIsUpdateBox (Standard_True), | |
ffe2bea7 | 139 | myTransparency (0), |
7fd59977 | 140 | myAttributePtr (0L) |
141 | {} | |
142 | ||
143 | /** | |
144 | * Destructor. | |
145 | */ | |
146 | Standard_EXPORT virtual ~NIS_InteractiveObject (); | |
147 | ||
148 | /** | |
149 | * Query the ID of the Object in its Context. | |
150 | */ | |
151 | inline Standard_Integer ID () const | |
152 | { return Standard_Integer (myID); } | |
153 | ||
154 | /** | |
155 | * Query the type of presentation. | |
156 | */ | |
157 | inline NIS_Drawer::DrawType | |
158 | DrawType () const | |
159 | { return myDrawType; } | |
160 | ||
161 | /** | |
162 | * Replace the drawer. This method must not be called for Object that | |
ebc93ae7 | 163 | * has not yet been added to a Context (thus has empty drawer). |
7fd59977 | 164 | * It is possible to have unassigned myDrawer or a DefaultDrawer as the |
165 | * parameter value (but not both). The Context where we work is taken | |
ebc93ae7 | 166 | * from theDrawer first, then (if NULL) -- from myDrawer. |
7fd59977 | 167 | * This method matches theDrawer with the available Drawers in the Context |
168 | * and adds if no match is found. | |
169 | * @return | |
170 | * Reference to the finally stored or found Drawer instance inside | |
171 | * the Context. | |
172 | */ | |
173 | Standard_EXPORT const Handle_NIS_Drawer& | |
ffe2bea7 A |
174 | SetDrawer (const Handle_NIS_Drawer& theDrawer, |
175 | const Standard_Boolean setUpdated | |
176 | = Standard_True); | |
7fd59977 | 177 | |
178 | /** | |
179 | * Query the current drawer. | |
180 | */ | |
181 | inline const Handle_NIS_Drawer& | |
182 | GetDrawer () const | |
183 | { return myDrawer; } | |
184 | ||
185 | /** | |
ffe2bea7 A |
186 | * Create a default drawer instance. In the upper-level call (in subclass) |
187 | * it is always called with NULL parameter. Then it should call the same | |
188 | * method of the superclass (except for NIS_InteractiveObject superclass type) | |
189 | * with the created Drawer instance as parameter. | |
190 | * @see NIS_Triangulated as example. | |
7fd59977 | 191 | */ |
ffe2bea7 A |
192 | Standard_EXPORT virtual NIS_Drawer * |
193 | DefaultDrawer (NIS_Drawer * theDrv) const = 0; | |
7fd59977 | 194 | |
195 | /** | |
196 | * Query a 3D bounding box of the object. | |
197 | */ | |
198 | Standard_EXPORT const Bnd_B3f& | |
199 | GetBox (); | |
200 | ||
201 | /** | |
202 | * Query the Transparent state. | |
203 | */ | |
204 | inline Standard_Boolean IsTransparent () const | |
ffe2bea7 | 205 | { return myTransparency > 0; } |
7fd59977 | 206 | |
207 | /** | |
208 | * Query the Hidden state | |
209 | */ | |
210 | inline Standard_Boolean IsHidden () const | |
211 | { return myIsHidden; } | |
212 | ||
213 | /** | |
214 | * Query the Displayed state - opposite to IsHidden(). | |
215 | */ | |
216 | inline Standard_Boolean IsDisplayed () const | |
217 | { return !myIsHidden; } | |
218 | ||
219 | /** | |
220 | * Query the Dynamic Hilight state | |
221 | */ | |
222 | inline Standard_Boolean IsDynHilighted() const | |
223 | { return myIsDynHilighted; } | |
224 | ||
225 | /** | |
226 | * Query if the Object is selectable. | |
227 | */ | |
ffe2bea7 | 228 | Standard_EXPORT virtual Standard_Boolean |
7fd59977 | 229 | IsSelectable () const; |
230 | ||
231 | /** | |
232 | * Set or change the selectable state of the Object. | |
233 | * @param isSel | |
234 | * True (default) - the Object will be selectable, False - it will be | |
235 | * ignored by selection/hilighting algorithms. | |
236 | */ | |
ffe2bea7 A |
237 | Standard_EXPORT virtual void |
238 | SetSelectable (const Standard_Boolean isSel | |
7fd59977 | 239 | = Standard_True) const; |
240 | ||
241 | /** | |
242 | * Query the Transparency factor. | |
243 | */ | |
ffe2bea7 A |
244 | inline Standard_ShortReal Transparency () const |
245 | { return static_cast<Standard_ShortReal>(myTransparency) / MaxTransparency; } | |
7fd59977 | 246 | |
247 | /** | |
248 | * Set the Transparency factor. | |
249 | */ | |
250 | Standard_EXPORT void SetTransparency (const Standard_Real theValue = 0.6); | |
251 | ||
252 | /** | |
253 | * Present the Object as opaque (Normal draw type). | |
254 | */ | |
255 | inline void UnsetTransparency () | |
256 | { SetTransparency (0.); } | |
257 | ||
ffe2bea7 A |
258 | /** |
259 | * Create a copy of theObject except its ID. | |
260 | * @param theAll | |
261 | * Allocator where the Dest should store its private data. | |
262 | * @param theDest | |
263 | * <tt>[in-out]</tt> The target object where the data are copied. | |
264 | */ | |
265 | Standard_EXPORT virtual void | |
266 | Clone (const Handle_NCollection_BaseAllocator& theAll, | |
267 | Handle_NIS_InteractiveObject& theDest) const; | |
268 | ||
269 | /** | |
270 | * The same as Clone() but also copies the ID. | |
271 | */ | |
272 | Standard_EXPORT void CloneWithID (const Handle_NCollection_BaseAllocator&, | |
273 | Handle_NIS_InteractiveObject&); | |
274 | ||
7fd59977 | 275 | /** |
276 | * Intersect the InteractiveObject geometry with a line/ray. | |
277 | * @param theAxis | |
278 | * The line or ray in 3D space. | |
279 | * @param theOver | |
280 | * Half-thickness of the selecting line. | |
281 | * @return | |
282 | * If the return value is more than 0.1*RealLast() then no intersection is | |
283 | * detected. Otherwise returns the coordinate of thePnt on the ray. May be | |
284 | * negative. | |
285 | */ | |
286 | Standard_EXPORT virtual Standard_Real | |
287 | Intersect (const gp_Ax1& theAxis, | |
288 | const Standard_Real theOver)const = 0; | |
289 | ||
290 | /** | |
291 | * Intersect the InteractiveObject geometry with an oriented box. | |
292 | * The default implementation (in this abstract class) always returns True, | |
293 | * signalling that every object pre-selected by its bounding box is | |
ebc93ae7 | 294 | * automatically selected. The specializations should define a more correct behaviour. |
7fd59977 | 295 | * The algorithm should transform the InteractiveObject geometry using the |
296 | * parameter theTrf and then reject it with box theBox, like: | |
297 | * @code | |
298 | * gp_Pnt aPnt = ..... // aPnt is part of our geometry. | |
299 | * if (!theBox.IsOut (aPnt.Transformed(theTrf))) | |
300 | * return Standard_True; | |
301 | * @endcode | |
302 | * @param theBox | |
303 | * 3D box of selection | |
304 | * @param theTrf | |
305 | * Position/Orientation of the box. It coincides with theTrfInv that is | |
306 | * passed to NIS_InteractiveObject::selectObjects(). | |
307 | * @param isFull | |
308 | * True if full inclusion is required (full inside the tested box) for | |
309 | * the positive result, False - if only partial inclusion give a result. | |
310 | * @return | |
311 | * True if the InteractiveObject geometry intersects the box or is inside it | |
312 | */ | |
313 | Standard_EXPORT virtual Standard_Boolean | |
314 | Intersect (const Bnd_B3f& theBox, | |
315 | const gp_Trsf& theTrf, | |
316 | const Standard_Boolean isFull) const; | |
317 | ||
ffe2bea7 A |
318 | /** |
319 | * Intersect the InteractiveObject geometry with a selection polygon. | |
320 | * The default implementation (in this abstract class) always returns True, | |
321 | * signalling that every object pre-selected by its bounding box is | |
ebc93ae7 | 322 | * automatically selected. The specializations should define a more correct behaviour. |
ffe2bea7 A |
323 | * The algorithm should transform the InteractiveObject geometry using the |
324 | * parameter theTrf and then reject it with polygon. | |
325 | * @param thePolygon | |
326 | * the list of vertices of a free-form closed polygon without | |
327 | * self-intersections. The last point should not coincide with the first | |
328 | * point of the list. Any two neighbor points should not be confused. | |
329 | * @param theTrf | |
330 | * Position/Orientation of the polygon. It coincides with theTrfInv that is | |
331 | * passed to NIS_InteractiveContext::selectObjects(). | |
332 | * @param isFull | |
333 | * True if full inclusion is required (full inside the tested box) for | |
334 | * the positive result, False - if only partial inclusion give a result. | |
335 | * @return | |
336 | * True if the InteractiveObject geometry intersects the polygon or is inside it | |
337 | */ | |
338 | Standard_EXPORT virtual Standard_Boolean | |
339 | Intersect (const NCollection_List<gp_XY> &thePolygon, | |
340 | const gp_Trsf &theTrf, | |
341 | const Standard_Boolean isFull) const; | |
342 | ||
7fd59977 | 343 | /** |
344 | * Set the pointer to custom (arbitrary) data associated with the Object. | |
345 | */ | |
346 | inline void SetAttribute (void * theAttributePtr) | |
347 | { myAttributePtr = theAttributePtr; } | |
348 | ||
349 | /** | |
350 | * Query the associated custom (arbitrary) attribute pointer. | |
351 | */ | |
352 | inline void * GetAttribute () const | |
353 | { return myAttributePtr; } | |
354 | ||
355 | protected: | |
356 | // ---------- PROTECTED METHODS ---------- | |
357 | ||
358 | inline void setDrawerUpdate () const | |
359 | { myDrawer->SetUpdated (myDrawType); } | |
360 | ||
361 | /** | |
362 | * Create a 3D bounding box of the object. | |
363 | */ | |
364 | Standard_EXPORT virtual void | |
365 | computeBox () = 0; | |
366 | ||
367 | inline Standard_Boolean isUpdateBox () const | |
368 | { return myIsUpdateBox; } | |
369 | ||
370 | inline void setIsUpdateBox (const Standard_Boolean isUpdate) | |
371 | { myIsUpdateBox = isUpdate; } | |
372 | ||
373 | private: | |
374 | // ---------- PRIVATE (PROHIBITED) METHODS ---------- | |
375 | ||
376 | NIS_InteractiveObject (const NIS_InteractiveObject& theOther); | |
377 | NIS_InteractiveObject& operator = (const NIS_InteractiveObject& theOther); | |
378 | ||
379 | private: | |
380 | // ---------- PRIVATE FIELDS ---------- | |
381 | ||
382 | Handle_NIS_Drawer myDrawer; | |
60be1f9b | 383 | Standard_Integer myID; |
ffe2bea7 A |
384 | NIS_Drawer::DrawType myDrawType : 3; |
385 | NIS_Drawer::DrawType myBaseType : 3; | |
7fd59977 | 386 | Standard_Boolean myIsHidden : 1; |
387 | Standard_Boolean myIsDynHilighted: 1; | |
388 | ||
389 | Standard_Boolean myIsUpdateBox : 1; | |
ffe2bea7 A |
390 | unsigned int myTransparency : 10; |
391 | static const unsigned int MaxTransparency = 1000; | |
7fd59977 | 392 | |
393 | protected: | |
394 | Bnd_B3f myBox; | |
395 | void * myAttributePtr; | |
396 | ||
ffe2bea7 | 397 | |
7fd59977 | 398 | friend class NIS_InteractiveContext; |
399 | friend class NIS_Drawer; | |
400 | ||
401 | public: | |
402 | // Declaration of CASCADE RTTI | |
403 | DEFINE_STANDARD_RTTI (NIS_InteractiveObject) | |
404 | }; | |
405 | ||
406 | #include <Handle_NIS_InteractiveObject.hxx> | |
407 | ||
408 | #endif |