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 | |
18 | namespace |
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 | // ======================================================================= |
328 | Handle(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 | } |