0031682: Visualization - Prs3d_ShadingAspect::SetTransparency() has no effect with...
[occt.git] / src / SelectMgr / SelectMgr_SelectionImageFiller.cxx
CommitLineData
7f24b768 1// Copyright (c) 2020 OPEN CASCADE SAS
2//
3// This file is part of Open CASCADE Technology software library.
4//
5// This library is free software; you can redistribute it and/or modify it under
6// the terms of the GNU Lesser General Public License version 2.1 as published
7// by the Free Software Foundation, with special exception defined in the file
8// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
9// distribution for complete text of the license and disclaimer of any warranty.
10//
11// Alternatively, this file may be used under the terms of Open CASCADE
12// commercial license or contractual agreement.
13
14#include <SelectMgr_SelectionImageFiller.hxx>
15
16#include <SelectMgr_ViewerSelector.hxx>
17
18namespace
19{
20 //! Help class for filling pixel with random color.
21 class GeneratedEntityColorFiller : public SelectMgr_SelectionImageFiller
22 {
23 public:
24 GeneratedEntityColorFiller (Image_PixMap& thePixMap,
25 SelectMgr_ViewerSelector* theSelector)
26 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
27 {
28 // generate per-entity colors in the order as they have been activated
29 for (SelectMgr_SelectableObjectSet::Iterator anObjIter (theSelector->SelectableObjects()); anObjIter.More(); anObjIter.Next())
30 {
31 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
32 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
33 {
34 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
35 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
36 {
37 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
38 if (!myMapEntityColors.IsBound (aSens->BaseSensitive()))
39 {
40 Quantity_Color aColor;
41 randomPastelColor (aColor);
42 myMapEntityColors.Bind (aSens->BaseSensitive(), aColor);
43 }
44 }
45 }
46 }
47 }
48
49 virtual void Fill (const Standard_Integer theCol,
50 const Standard_Integer theRow,
51 const Standard_Integer thePicked) Standard_OVERRIDE
52 {
53 if (thePicked < 1
54 || thePicked > myMainSel->NbPicked())
55 {
56 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
57 return;
58 }
59
60 const Handle(Select3D_SensitiveEntity)& aPickedEntity = myMainSel->PickedEntity (thePicked);
61 Quantity_Color aColor (Quantity_NOC_BLACK);
62 myMapEntityColors.Find (aPickedEntity, aColor);
63 myImage->SetPixelColor (theCol, theRow, aColor);
64 }
65
66 protected:
67 NCollection_DataMap<Handle(Select3D_SensitiveEntity), Quantity_Color> myMapEntityColors;
68 };
69
70 //! Help class for filling pixel with normalized depth of ray.
71 class NormalizedDepthFiller : public SelectMgr_SelectionImageFiller
72 {
73 public:
74 NormalizedDepthFiller (Image_PixMap& thePixMap,
75 SelectMgr_ViewerSelector* theSelector,
76 const Standard_Boolean theToInverse)
77 : SelectMgr_SelectionImageFiller (thePixMap, theSelector),
78 myDepthMin ( RealLast()),
79 myDepthMax (-RealLast()),
80 myToInverse(theToInverse)
81 {
82 myUnnormImage.InitZero (Image_Format_GrayF, thePixMap.SizeX(), thePixMap.SizeY());
83 }
84
85 //! Accumulate the data.
86 virtual void Fill (const Standard_Integer theCol,
87 const Standard_Integer theRow,
88 const Standard_Integer thePicked) Standard_OVERRIDE
89 {
90 if (myUnnormImage.IsEmpty())
91 {
92 return;
93 }
94
95 if (thePicked < 1
96 || thePicked > myMainSel->NbPicked())
97 {
98 myUnnormImage.ChangeValue<float> (theRow, theCol) = ShortRealLast();
99 return;
100 }
101
102 const SelectMgr_SortCriterion& aSortCriterion = myMainSel->PickedData (thePicked);
103 myUnnormImage.ChangeValue<float> (theRow, theCol) = float(aSortCriterion.Depth);
104 myDepthMin = Min (myDepthMin, aSortCriterion.Depth);
105 myDepthMax = Max (myDepthMax, aSortCriterion.Depth);
106 }
107
108 //! Normalize the depth values.
109 virtual void Flush() Standard_OVERRIDE
110 {
111 float aFrom = 0.0f;
112 float aDelta = 1.0f;
113 if (myDepthMin <= myDepthMax)
114 {
115 aFrom = float(myDepthMin);
116 aDelta = float(myDepthMax) - float(myDepthMin);
117 if (aDelta <= ShortRealEpsilon())
118 {
119 aDelta = 1.0f;
120 }
121 }
122 for (Standard_Size aRowIter = 0; aRowIter < myUnnormImage.SizeY(); ++aRowIter)
123 {
124 for (Standard_Size aColIter = 0; aColIter < myUnnormImage.SizeX(); ++aColIter)
125 {
126 float aDepth = myUnnormImage.Value<float> (aRowIter, aColIter);
127 if (aDepth <= -ShortRealLast()
128 || aDepth >= ShortRealLast())
129 {
130 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
131 Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
132 continue;
133 }
134
135 float aNormDepth = (aDepth - aFrom) / aDelta;
136 if (myToInverse)
137 {
138 aNormDepth = 1.0f - aNormDepth;
139 }
140 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
141 Quantity_ColorRGBA (aNormDepth, aNormDepth, aNormDepth, 1.0f));
142 }
143 }
144 }
145
146 private:
147 Image_PixMap myUnnormImage;
148 Standard_Real myDepthMin;
149 Standard_Real myDepthMax;
150 Standard_Boolean myToInverse;
151 };
152
153 //! Help class for filling pixel with unnormalized depth of ray.
154 class UnnormalizedDepthFiller : public SelectMgr_SelectionImageFiller
155 {
156 public:
157 UnnormalizedDepthFiller (Image_PixMap& thePixMap,
158 SelectMgr_ViewerSelector* theSelector)
159 : SelectMgr_SelectionImageFiller (thePixMap, theSelector) {}
160
161 virtual void Fill (const Standard_Integer theCol,
162 const Standard_Integer theRow,
163 const Standard_Integer thePicked) Standard_OVERRIDE
164 {
165 if (thePicked < 1
166 || thePicked > myMainSel->NbPicked())
167 {
168 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
169 return;
170 }
171
172 const SelectMgr_SortCriterion& aSortCriterion = myMainSel->PickedData (thePicked);
173 const float aDepth = float(aSortCriterion.Depth);
174 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (Graphic3d_Vec4 (aDepth, aDepth, aDepth, 1.0f)));
175 }
176 };
177
178 //! Help class for filling pixel with color of detected object.
179 class GeneratedOwnerColorFiller : public SelectMgr_SelectionImageFiller
180 {
181 public:
182 GeneratedOwnerColorFiller (Image_PixMap& thePixMap,
183 SelectMgr_ViewerSelector* theSelector)
184 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
185 {
186 // generate per-owner colors in the order as they have been activated
187 for (SelectMgr_SelectableObjectSet::Iterator anObjIter (theSelector->SelectableObjects()); anObjIter.More(); anObjIter.Next())
188 {
189 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
190 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
191 {
192 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
193 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
194 {
195 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
196 const Handle(SelectBasics_EntityOwner)& anOwner = aSens->BaseSensitive()->OwnerId();
197 if (!myMapOwnerColors.IsBound (anOwner))
198 {
199 Quantity_Color aColor;
200 randomPastelColor (aColor);
201 myMapOwnerColors.Bind (anOwner, aColor);
202 }
203 }
204 }
205 }
206 }
207
208 virtual void Fill (const Standard_Integer theCol,
209 const Standard_Integer theRow,
210 const Standard_Integer thePicked) Standard_OVERRIDE
211 {
212 if (thePicked < 1
213 || thePicked > myMainSel->NbPicked())
214 {
215 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
216 return;
217 }
218
219 const Handle(SelectMgr_EntityOwner)& aPickedOwner = myMainSel->Picked (thePicked);
220 Quantity_Color aColor (Quantity_NOC_BLACK);
221 myMapOwnerColors.Find (aPickedOwner, aColor);
222 myImage->SetPixelColor (theCol, theRow, aColor);
223 }
224
225 protected:
226 NCollection_DataMap<Handle(SelectBasics_EntityOwner), Quantity_Color> myMapOwnerColors;
227 };
228
229 //! Help class for filling pixel with random color for each selection mode.
230 class GeneratedSelModeColorFiller : public SelectMgr_SelectionImageFiller
231 {
232 public:
233 GeneratedSelModeColorFiller (Image_PixMap& thePixMap,
234 SelectMgr_ViewerSelector* theSelector)
235 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
236 {
237 // generate standard modes in proper order, consider custom objects would use similar scheme
238 myMapSelectionModeColors.Bind ( 0, Quantity_NOC_WHITE); // default (entire object selection)
239 myMapSelectionModeColors.Bind ( 1, Quantity_NOC_YELLOW); // TopAbs_VERTEX
240 myMapSelectionModeColors.Bind ( 2, Quantity_NOC_GREEN); // TopAbs_EDGE
241 myMapSelectionModeColors.Bind ( 3, Quantity_NOC_RED); // TopAbs_WIRE
242 myMapSelectionModeColors.Bind ( 4, Quantity_NOC_BLUE1); // TopAbs_FACE
243 myMapSelectionModeColors.Bind ( 5, Quantity_NOC_CYAN1); // TopAbs_SHELL
244 myMapSelectionModeColors.Bind ( 6, Quantity_NOC_PURPLE); // TopAbs_SOLID
245 myMapSelectionModeColors.Bind ( 7, Quantity_NOC_MAGENTA1); // TopAbs_COMPSOLID
246 myMapSelectionModeColors.Bind ( 8, Quantity_NOC_BROWN); // TopAbs_COMPOUND
247 myMapSelectionModeColors.Bind (0x0010, Quantity_NOC_PINK); // MeshVS_SMF_Volume
248 myMapSelectionModeColors.Bind (0x001E, Quantity_NOC_LIMEGREEN); // MeshVS_SMF_Element
249 myMapSelectionModeColors.Bind (0x001F, Quantity_NOC_DARKOLIVEGREEN); // MeshVS_SMF_All
250 myMapSelectionModeColors.Bind (0x0100, Quantity_NOC_GOLD); // MeshVS_SMF_Group
251 }
252
253 virtual void Fill (const Standard_Integer theCol,
254 const Standard_Integer theRow,
255 const Standard_Integer thePicked) Standard_OVERRIDE
256 {
257 if (thePicked < 1
258 || thePicked > myMainSel->NbPicked())
259 {
260 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
261 return;
262 }
263
264 Standard_Integer aSelectionMode = -1;
265 const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked (thePicked)->Selectable();
266 const Handle(Select3D_SensitiveEntity)& anEntity = myMainSel->PickedEntity (thePicked);
267 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (aSelectable->Selections()); aSelIter.More(); aSelIter.Next())
268 {
269 const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
270 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
271 {
272 if (aSelEntIter.Value()->BaseSensitive() == anEntity)
273 {
274 aSelectionMode = aSelection->Mode();
275 break;
276 }
277 }
278 }
279 if (aSelectionMode == -1)
280 {
281 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
282 return;
283 }
284
285 if (!myMapSelectionModeColors.IsBound (aSelectionMode))
286 {
287 Quantity_Color aColor;
288 randomPastelColor (aColor);
289 myMapSelectionModeColors.Bind (aSelectionMode, aColor);
290 }
291
292 const Quantity_Color& aColor = myMapSelectionModeColors.Find (aSelectionMode);
293 myImage->SetPixelColor (theCol, theRow, aColor);
294 }
295
296 protected:
297 NCollection_DataMap<Standard_Integer, Quantity_Color> myMapSelectionModeColors;
298 };
299
300 //! Help class for filling pixel with color of detected shape.
301 class DetectedObjectColorFiller : public SelectMgr_SelectionImageFiller
302 {
303 public:
304 DetectedObjectColorFiller (Image_PixMap& thePixMap,
305 SelectMgr_ViewerSelector* theSelector)
306 : SelectMgr_SelectionImageFiller (thePixMap, theSelector) {}
307
308 virtual void Fill (const Standard_Integer theCol,
309 const Standard_Integer theRow,
310 const Standard_Integer thePicked) Standard_OVERRIDE
311 {
312 Quantity_Color aColor (Quantity_NOC_BLACK);
313 if (thePicked > 0
314 && thePicked <= myMainSel->NbPicked())
315 {
316 const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked (thePicked)->Selectable();
317 aColor = aSelectable->Attributes()->Color();
318 }
319 myImage->SetPixelColor (theCol, theRow, aColor);
320 }
321 };
322}
323
324// =======================================================================
325// function : CreateFiller
326// purpose :
327// =======================================================================
328Handle(SelectMgr_SelectionImageFiller) SelectMgr_SelectionImageFiller::CreateFiller (Image_PixMap& thePixMap,
329 SelectMgr_ViewerSelector* theSelector,
330 StdSelect_TypeOfSelectionImage theType)
331{
332 switch (theType)
333 {
334 case StdSelect_TypeOfSelectionImage_NormalizedDepth:
335 case StdSelect_TypeOfSelectionImage_NormalizedDepthInverted:
336 {
337 return new NormalizedDepthFiller (thePixMap, theSelector, theType == StdSelect_TypeOfSelectionImage_NormalizedDepthInverted);
338 }
339 case StdSelect_TypeOfSelectionImage_UnnormalizedDepth:
340 {
341 return new UnnormalizedDepthFiller (thePixMap, theSelector);
342 }
343 case StdSelect_TypeOfSelectionImage_ColoredDetectedObject:
344 {
345 return new DetectedObjectColorFiller (thePixMap, theSelector);
346 }
347 case StdSelect_TypeOfSelectionImage_ColoredEntity:
348 {
349 return new GeneratedEntityColorFiller (thePixMap, theSelector);
350 }
351 case StdSelect_TypeOfSelectionImage_ColoredOwner:
352 {
353 return new GeneratedOwnerColorFiller (thePixMap, theSelector);
354 }
355 case StdSelect_TypeOfSelectionImage_ColoredSelectionMode:
356 {
357 return new GeneratedSelModeColorFiller (thePixMap, theSelector);
358 }
359 }
360 return Handle(SelectMgr_SelectionImageFiller)();
361}