0030268: Inspectors - improvements in VInspector plugin
[occt.git] / tools / VInspector / VInspector_Tools.cxx
1 // Created on: 2017-06-16
2 // Created by: Natalia ERMOLAEVA
3 // Copyright (c) 2017 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 <inspector/VInspector_Tools.hxx>
17
18 #include <inspector/ViewControl_TableModelValues.hxx>
19 #include <inspector/ViewControl_Tools.hxx>
20
21 #include <inspector/Convert_Tools.hxx>
22
23 #include <AIS_ListIteratorOfListOfInteractive.hxx>
24 #include <AIS_ListOfInteractive.hxx>
25 #include <AIS_Selection.hxx>
26 #include <AIS_Shape.hxx>
27 #include <BRepPrimAPI_MakeBox.hxx>
28 #include <BRepBuilderAPI_MakeEdge.hxx>
29 #include <BRepBuilderAPI_MakeVertex.hxx>
30 #include <Graphic3d_IndexBuffer.hxx>
31 #include <Graphic3d_Buffer.hxx>
32 #include <Graphic3d_BoundBuffer.hxx>
33
34 #include <SelectMgr_StateOfSelection.hxx>
35 #include <SelectMgr_TypeOfUpdate.hxx>
36 #include <SelectMgr_TypeOfBVHUpdate.hxx>
37 #include <StdSelect_BRepOwner.hxx>
38
39 #include <Standard_WarningsDisable.hxx>
40 #include <QStringList>
41 #include <Standard_WarningsRestore.hxx>
42
43 #include <TopoDS_Compound.hxx>
44
45 #include <sstream>
46
47 // =======================================================================
48 // function : GetShapeTypeInfo
49 // purpose :
50 // =======================================================================
51 TCollection_AsciiString VInspector_Tools::GetShapeTypeInfo (const TopAbs_ShapeEnum& theType)
52 {
53   Standard_SStream aSStream;
54   TopAbs::Print (theType, aSStream);
55   return aSStream.str().c_str();
56 }
57
58 // =======================================================================
59 // function : SelectedOwners
60 // purpose :
61 // =======================================================================
62 int VInspector_Tools::SelectedOwners (const Handle(AIS_InteractiveContext)& theContext,
63                                       const Handle(AIS_InteractiveObject)& theObject,
64                                       const bool theShapeInfoOnly)
65 {
66   QStringList anObjects;
67   if (theContext.IsNull())
68     return 0;
69
70   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
71   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
72   {
73     Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
74     if (anOwner.IsNull()) // TODO: check why it is possible
75       continue;
76
77     if (!theObject.IsNull())
78     {
79       Handle(AIS_InteractiveObject) anOwnerPresentation =
80                                     Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
81       if (anOwnerPresentation != theObject)
82         continue;
83     }
84     Handle(StdSelect_BRepOwner) BROwnr = Handle(StdSelect_BRepOwner)::DownCast (anOwner);
85     if (theShapeInfoOnly && BROwnr.IsNull())
86       continue;
87
88     Standard_Transient* anOwnerPtr = anOwner.get();
89     if (aSelectedIds.contains ((size_t)anOwnerPtr))
90       continue;
91     aSelectedIds.append ((size_t)anOwnerPtr);
92
93     anObjects.append (Standard_Dump::GetPointerInfo (anOwnerPtr, true).ToCString());
94   }
95   return anObjects.size();
96 }
97
98 // =======================================================================
99 // function : IsOwnerSelected
100 // purpose :
101 // =======================================================================
102 bool VInspector_Tools::IsOwnerSelected (const Handle(AIS_InteractiveContext)& theContext,
103                                         const Handle(SelectBasics_EntityOwner)& theOwner)
104 {
105   bool anIsSelected = false;
106   for (theContext->InitSelected(); theContext->MoreSelected() && !anIsSelected; theContext->NextSelected())
107     anIsSelected = theContext->SelectedOwner() == theOwner;
108   return anIsSelected;
109 }
110
111 // =======================================================================
112 // function : ContextOwners
113 // purpose :
114 // =======================================================================
115 NCollection_List<Handle(SelectBasics_EntityOwner)> VInspector_Tools::ContextOwners (
116                                                const Handle(AIS_InteractiveContext)& theContext)
117 {
118   NCollection_List<Handle(SelectBasics_EntityOwner)> aResultOwners;
119   if (theContext.IsNull())
120     return aResultOwners;
121
122   AIS_ListOfInteractive aListOfIO;
123   theContext->DisplayedObjects (aListOfIO);
124   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
125   for (AIS_ListIteratorOfListOfInteractive aIt(aListOfIO); aIt.More(); aIt.Next())
126   {
127     Handle(AIS_InteractiveObject) anIO = aIt.Value();
128     if (anIO.IsNull())
129       continue;
130     for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anIO->Selections()); aSelIter.More(); aSelIter.Next())
131     {
132       Handle(SelectMgr_Selection) aSelection = aSelIter.Value();
133       if (aSelection.IsNull())
134         continue;
135       for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
136       {
137         Handle(SelectMgr_SensitiveEntity) anEntity = aSelEntIter.Value();
138         if (anEntity.IsNull())
139           continue;
140         const Handle(SelectBasics_SensitiveEntity)& aBase = anEntity->BaseSensitive();
141         Handle(SelectBasics_EntityOwner) anOwner = aBase->OwnerId();
142         Standard_Transient* anOwnerPtr = anOwner.get();
143         if (aSelectedIds.contains ((size_t)anOwnerPtr))
144           continue;
145         aSelectedIds.append ((size_t)anOwnerPtr);
146         aResultOwners.Append (anOwner);
147       }
148     }
149   }
150   return aResultOwners;
151 }
152
153 // =======================================================================
154 // function : ActiveOwners
155 // purpose :
156 // =======================================================================
157 NCollection_List<Handle(SelectBasics_EntityOwner)> VInspector_Tools::ActiveOwners (
158                                 const Handle(AIS_InteractiveContext)& theContext,
159                                 NCollection_List<Handle(SelectBasics_EntityOwner)>& theEmptySelectableOwners)
160 {
161   NCollection_List<Handle(SelectBasics_EntityOwner)> aResultOwners;
162
163   // only local context is processed: TODO for global context
164   Handle(AIS_InteractiveContext) aContext = theContext;
165   if (aContext.IsNull())
166     return aResultOwners;
167   NCollection_List<Handle(SelectBasics_EntityOwner)> anActiveOwners;
168   // OCCT BUG:1 - equal pointer owners are appears in the list
169   aContext->MainSelector()->ActiveOwners (anActiveOwners);
170   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
171   Handle(SelectMgr_EntityOwner) anOwner;
172   for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt (anActiveOwners);
173        anOwnersIt.More(); anOwnersIt.Next())
174   {
175     anOwner = anOwnersIt.Value();
176     if (anOwner.IsNull())
177       continue;
178
179     Standard_Transient* anOwnerPtr = anOwner.get();
180     if (aSelectedIds.contains ((size_t)anOwnerPtr))
181       continue;
182     aSelectedIds.append ((size_t)anOwnerPtr);
183
184     aResultOwners.Append (anOwner);
185     Handle(SelectMgr_SelectableObject) aSelectable = anOwner->Selectable();
186     if (aSelectable.IsNull() ||
187         !theContext->IsDisplayed(Handle(AIS_InteractiveObject)::DownCast (aSelectable)))
188       theEmptySelectableOwners.Append (anOwner);
189   }
190   return aResultOwners;
191 }
192
193 // =======================================================================
194 // function : AddOrRemoveSelectedShapes
195 // purpose :
196 // =======================================================================
197 void VInspector_Tools::AddOrRemoveSelectedShapes (const Handle(AIS_InteractiveContext)& theContext,
198                                                   const NCollection_List<Handle(SelectBasics_EntityOwner)>& theOwners)
199 {
200   // TODO: the next two rows are to be removed later
201   theContext->UnhilightSelected(false);
202   theContext->ClearSelected(false);
203
204   theContext->UnhilightSelected(Standard_False);
205
206   for (NCollection_List<Handle(SelectBasics_EntityOwner)>::Iterator anOwnersIt(theOwners);
207        anOwnersIt.More(); anOwnersIt.Next())
208   {
209     Handle(SelectMgr_EntityOwner) anOwner = anOwnersIt.Value();
210     theContext->AddOrRemoveSelected (anOwner, Standard_False);
211   }
212   theContext->UpdateCurrentViewer();
213 }
214
215 // =======================================================================
216 // function : AddOrRemovePresentations
217 // purpose :
218 // =======================================================================
219 void VInspector_Tools::AddOrRemovePresentations (const Handle(AIS_InteractiveContext)& theContext,
220                                                  const NCollection_List<Handle(AIS_InteractiveObject)>& thePresentations)
221 {
222   // TODO: the next two rows are to be removed later
223   theContext->UnhilightSelected(false);
224   theContext->ClearSelected(false);
225
226   for (NCollection_List<Handle(AIS_InteractiveObject)>::Iterator anIOIt (thePresentations); anIOIt.More(); anIOIt.Next())
227     theContext->AddOrRemoveSelected (anIOIt.Value(), false);
228
229   theContext->UpdateCurrentViewer();
230 }
231
232 // =======================================================================
233 // function : GetInfo
234 // purpose :
235 // =======================================================================
236 QList<QVariant> VInspector_Tools::GetInfo (Handle(AIS_InteractiveObject)& theObject)
237 {
238   QList<QVariant> anInfo;
239   anInfo.append (theObject->DynamicType()->Name());
240   anInfo.append (Standard_Dump::GetPointerInfo (theObject, true).ToCString());
241
242   Handle(AIS_Shape) aShapeIO = Handle(AIS_Shape)::DownCast (theObject);
243   if (aShapeIO.IsNull())
244     return anInfo;
245
246   const TopoDS_Shape& aShape = aShapeIO->Shape();
247   if (!aShape.IsNull())
248     anInfo.append (VInspector_Tools::GetShapeTypeInfo (aShape.ShapeType()).ToCString());
249
250   return anInfo;
251 }
252
253 // =======================================================================
254 // function : GetHighlightInfo
255 // purpose :
256 // =======================================================================
257 QList<QVariant> VInspector_Tools::GetHighlightInfo (const Handle(AIS_InteractiveContext)& theContext)
258 {
259   QList<QVariant> aValues;
260   if (theContext.IsNull())
261     return aValues;
262
263   QStringList aSelectedNames;
264   QStringList aSelectedPointers;
265   QStringList aSelectedTypes;
266   QStringList aSelectedOwners;
267   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
268   for (theContext->InitDetected(); theContext->MoreDetected(); theContext->NextDetected())
269   {
270     Handle(SelectMgr_EntityOwner) anOwner = theContext->DetectedOwner();
271     if (anOwner.IsNull())
272       continue;
273     Standard_Transient* anOwnerPtr = anOwner.get();
274     if (aSelectedIds.contains ((size_t)anOwnerPtr))
275       continue;
276     aSelectedIds.append ((size_t)anOwnerPtr);
277     Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
278     if (anIO.IsNull())
279       continue;
280     QList<QVariant> anIOInfo = VInspector_Tools::GetInfo (anIO);
281     if (anIOInfo.size() == 3)
282     {
283       aSelectedNames.append (anIOInfo[0].toString());
284       aSelectedPointers.append (anIOInfo[1].toString());
285       aSelectedTypes.append (anIOInfo[2].toString());
286     }
287     aSelectedOwners.append (Standard_Dump::GetPointerInfo (anOwnerPtr, true).ToCString());
288   }
289   aValues.append (aSelectedNames.join (", "));
290   aValues.append (aSelectedPointers.join (", "));
291   aValues.append (aSelectedTypes.join (", "));
292   aValues.append (aSelectedOwners.join (", "));
293
294   return aValues;
295 }
296
297 // =======================================================================
298 // function : GetSelectedInfo
299 // purpose :
300 // =======================================================================
301 QList<QVariant> VInspector_Tools::GetSelectedInfo (const Handle(AIS_InteractiveContext)& theContext)
302 {
303   QList<QVariant> aValues;
304   if (theContext.IsNull())
305     return aValues;
306
307   QStringList aSelectedNames;
308   QStringList aSelectedPointers;
309   QStringList aSelectedTypes;
310   QStringList aSelectedOwners;
311   QList<size_t> aSelectedIds; // Remember of selected address in order to avoid duplicates
312   for (theContext->InitSelected(); theContext->MoreSelected(); theContext->NextSelected())
313   {
314     Handle(SelectMgr_EntityOwner) anOwner = theContext->SelectedOwner();
315     if (anOwner.IsNull())
316       continue;
317     Standard_Transient* anOwnerPtr = anOwner.get();
318     if (aSelectedIds.contains ((size_t)anOwnerPtr))
319       continue;
320     aSelectedIds.append ((size_t)anOwnerPtr);
321     Handle(AIS_InteractiveObject) anIO = Handle(AIS_InteractiveObject)::DownCast (anOwner->Selectable());
322     if (anIO.IsNull())
323       continue;
324
325     QList<QVariant> anIOInfo = VInspector_Tools::GetInfo (anIO);
326     if (anIOInfo.size() == 3)
327     {
328       aSelectedNames.append (anIOInfo[0].toString());
329       aSelectedPointers.append (anIOInfo[1].toString());
330       aSelectedTypes.append (anIOInfo[2].toString());
331     }
332     aSelectedOwners.append (Standard_Dump::GetPointerInfo (anOwnerPtr, true).ToCString());
333   }
334   aValues.append (aSelectedNames.join (", "));
335   aValues.append (aSelectedPointers.join (", "));
336   aValues.append (aSelectedTypes.join (", "));
337   aValues.append (aSelectedOwners.join (", "));
338   return aValues;
339 }
340
341 // =======================================================================
342 // function : GetSelectedInfoPointers
343 // purpose :
344 // =======================================================================
345 QString VInspector_Tools::GetSelectedInfoPointers (const Handle(AIS_InteractiveContext)& theContext)
346 {
347   QList<QVariant> aSelectedInfo = VInspector_Tools::GetSelectedInfo (theContext);
348   return aSelectedInfo.size() > 2 ? aSelectedInfo[1].toString() : QString();
349 }
350
351 namespace
352 {
353   static Standard_CString VInspector_Table_PrintDisplayActionType[5] =
354   {
355     "None", "Display", "Redisplay", "Erase", "Remove"
356   };
357 }
358
359 //=======================================================================
360 //function : DisplayActionTypeToString
361 //purpose  :
362 //=======================================================================
363 Standard_CString VInspector_Tools::DisplayActionTypeToString (View_DisplayActionType theType)
364 {
365   return VInspector_Table_PrintDisplayActionType[theType];
366 }
367
368 //=======================================================================
369 //function : DisplayActionTypeFromString
370 //purpose  :
371 //=======================================================================
372 Standard_Boolean VInspector_Tools::DisplayActionTypeFromString (Standard_CString theTypeString,
373                                                                 View_DisplayActionType& theType)
374 {
375   const TCollection_AsciiString aName (theTypeString);
376   for (Standard_Integer aTypeIter = 0; aTypeIter <= View_DisplayActionType_RemoveId; ++aTypeIter)
377   {
378     Standard_CString aTypeName = VInspector_Table_PrintDisplayActionType[aTypeIter];
379     if (aName == aTypeName)
380     {
381       theType = View_DisplayActionType (aTypeIter);
382       return Standard_True;
383     }
384   }
385   return Standard_False;
386 }