1 // Copyright (c) 2020 OPEN CASCADE SAS
3 // This file is part of Open CASCADE Technology software library.
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.
11 // Alternatively, this file may be used under the terms of Open CASCADE
12 // commercial license or contractual agreement.
14 #include <SelectMgr_SelectionImageFiller.hxx>
16 #include <SelectMgr_ViewerSelector.hxx>
20 //! Help class for filling pixel with random color.
21 class GeneratedEntityColorFiller : public SelectMgr_SelectionImageFiller
24 GeneratedEntityColorFiller (Image_PixMap& thePixMap,
25 SelectMgr_ViewerSelector* theSelector)
26 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
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())
31 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
32 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
34 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
35 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
37 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
38 if (!myMapEntityColors.IsBound (aSens->BaseSensitive()))
40 Quantity_Color aColor;
41 randomPastelColor (aColor);
42 myMapEntityColors.Bind (aSens->BaseSensitive(), aColor);
49 virtual void Fill (const Standard_Integer theCol,
50 const Standard_Integer theRow,
51 const Standard_Integer thePicked) Standard_OVERRIDE
54 || thePicked > myMainSel->NbPicked())
56 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
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);
67 NCollection_DataMap<Handle(Select3D_SensitiveEntity), Quantity_Color> myMapEntityColors;
70 //! Help class for filling pixel with normalized depth of ray.
71 class NormalizedDepthFiller : public SelectMgr_SelectionImageFiller
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)
82 myUnnormImage.InitZero (Image_Format_GrayF, thePixMap.SizeX(), thePixMap.SizeY());
85 //! Accumulate the data.
86 virtual void Fill (const Standard_Integer theCol,
87 const Standard_Integer theRow,
88 const Standard_Integer thePicked) Standard_OVERRIDE
90 if (myUnnormImage.IsEmpty())
96 || thePicked > myMainSel->NbPicked())
98 myUnnormImage.ChangeValue<float> (theRow, theCol) = ShortRealLast();
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);
108 //! Normalize the depth values.
109 virtual void Flush() Standard_OVERRIDE
113 if (myDepthMin <= myDepthMax)
115 aFrom = float(myDepthMin);
116 aDelta = float(myDepthMax) - float(myDepthMin);
117 if (aDelta <= ShortRealEpsilon())
122 for (Standard_Size aRowIter = 0; aRowIter < myUnnormImage.SizeY(); ++aRowIter)
124 for (Standard_Size aColIter = 0; aColIter < myUnnormImage.SizeX(); ++aColIter)
126 float aDepth = myUnnormImage.Value<float> (aRowIter, aColIter);
127 if (aDepth <= -ShortRealLast()
128 || aDepth >= ShortRealLast())
130 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
131 Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
135 float aNormDepth = (aDepth - aFrom) / aDelta;
138 aNormDepth = 1.0f - aNormDepth;
140 myImage->SetPixelColor (Standard_Integer(aColIter), Standard_Integer(aRowIter),
141 Quantity_ColorRGBA (aNormDepth, aNormDepth, aNormDepth, 1.0f));
147 Image_PixMap myUnnormImage;
148 Standard_Real myDepthMin;
149 Standard_Real myDepthMax;
150 Standard_Boolean myToInverse;
153 //! Help class for filling pixel with unnormalized depth of ray.
154 class UnnormalizedDepthFiller : public SelectMgr_SelectionImageFiller
157 UnnormalizedDepthFiller (Image_PixMap& thePixMap,
158 SelectMgr_ViewerSelector* theSelector)
159 : SelectMgr_SelectionImageFiller (thePixMap, theSelector) {}
161 virtual void Fill (const Standard_Integer theCol,
162 const Standard_Integer theRow,
163 const Standard_Integer thePicked) Standard_OVERRIDE
166 || thePicked > myMainSel->NbPicked())
168 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (0.0f, 0.0f, 0.0f, 1.0f));
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)));
178 //! Help class for filling pixel with color of detected object.
179 class GeneratedOwnerColorFiller : public SelectMgr_SelectionImageFiller
182 GeneratedOwnerColorFiller (Image_PixMap& thePixMap,
183 SelectMgr_ViewerSelector* theSelector)
184 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
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())
189 const Handle(SelectMgr_SelectableObject)& anObj = anObjIter.Value();
190 for (SelectMgr_SequenceOfSelection::Iterator aSelIter (anObj->Selections()); aSelIter.More(); aSelIter.Next())
192 const Handle(SelectMgr_Selection)& aSel = aSelIter.Value();
193 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSel->Entities()); aSelEntIter.More(); aSelEntIter.Next())
195 const Handle(SelectMgr_SensitiveEntity)& aSens = aSelEntIter.Value();
196 const Handle(SelectMgr_EntityOwner)& anOwner = aSens->BaseSensitive()->OwnerId();
197 if (!myMapOwnerColors.IsBound (anOwner))
199 Quantity_Color aColor;
200 randomPastelColor (aColor);
201 myMapOwnerColors.Bind (anOwner, aColor);
208 virtual void Fill (const Standard_Integer theCol,
209 const Standard_Integer theRow,
210 const Standard_Integer thePicked) Standard_OVERRIDE
213 || thePicked > myMainSel->NbPicked())
215 myImage->SetPixelColor (theCol, theRow, Quantity_Color(Quantity_NOC_BLACK));
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);
226 NCollection_DataMap<Handle(SelectMgr_EntityOwner), Quantity_Color> myMapOwnerColors;
229 //! Help class for filling pixel with random color for each selection mode.
230 class GeneratedSelModeColorFiller : public SelectMgr_SelectionImageFiller
233 GeneratedSelModeColorFiller (Image_PixMap& thePixMap,
234 SelectMgr_ViewerSelector* theSelector)
235 : SelectMgr_SelectionImageFiller (thePixMap, theSelector)
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
253 virtual void Fill (const Standard_Integer theCol,
254 const Standard_Integer theRow,
255 const Standard_Integer thePicked) Standard_OVERRIDE
258 || thePicked > myMainSel->NbPicked())
260 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
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())
269 const Handle(SelectMgr_Selection)& aSelection = aSelIter.Value();
270 for (NCollection_Vector<Handle(SelectMgr_SensitiveEntity)>::Iterator aSelEntIter (aSelection->Entities()); aSelEntIter.More(); aSelEntIter.Next())
272 if (aSelEntIter.Value()->BaseSensitive() == anEntity)
274 aSelectionMode = aSelection->Mode();
279 if (aSelectionMode == -1)
281 myImage->SetPixelColor (theCol, theRow, Quantity_Color (Quantity_NOC_BLACK));
285 if (!myMapSelectionModeColors.IsBound (aSelectionMode))
287 Quantity_Color aColor;
288 randomPastelColor (aColor);
289 myMapSelectionModeColors.Bind (aSelectionMode, aColor);
292 const Quantity_Color& aColor = myMapSelectionModeColors.Find (aSelectionMode);
293 myImage->SetPixelColor (theCol, theRow, aColor);
297 NCollection_DataMap<Standard_Integer, Quantity_Color> myMapSelectionModeColors;
300 //! Help class for filling pixel with color of detected shape.
301 class DetectedObjectColorFiller : public SelectMgr_SelectionImageFiller
304 DetectedObjectColorFiller (Image_PixMap& thePixMap,
305 SelectMgr_ViewerSelector* theSelector)
306 : SelectMgr_SelectionImageFiller (thePixMap, theSelector) {}
308 virtual void Fill (const Standard_Integer theCol,
309 const Standard_Integer theRow,
310 const Standard_Integer thePicked) Standard_OVERRIDE
312 Quantity_Color aColor (Quantity_NOC_BLACK);
314 && thePicked <= myMainSel->NbPicked())
316 const Handle(SelectMgr_SelectableObject)& aSelectable = myMainSel->Picked (thePicked)->Selectable();
317 aColor = aSelectable->Attributes()->Color();
319 myImage->SetPixelColor (theCol, theRow, aColor);
323 //! Help class for filling pixel with normal direction value.
324 class SurfaceNormalFiller : public SelectMgr_SelectionImageFiller
327 SurfaceNormalFiller (Image_PixMap& thePixMap,
328 SelectMgr_ViewerSelector* theSelector)
329 : SelectMgr_SelectionImageFiller (thePixMap, theSelector) {}
331 virtual void Fill (const Standard_Integer theCol,
332 const Standard_Integer theRow,
333 const Standard_Integer thePicked) Standard_OVERRIDE
336 || thePicked > myMainSel->NbPicked())
338 myImage->SetPixelColor (theCol, theRow, Quantity_NOC_BLACK);
342 const SelectMgr_SortCriterion& aPickedData = myMainSel->PickedData (thePicked);
343 Graphic3d_Vec3 aNormal = aPickedData.Normal;
345 if (aNormal.Modulus() > 0.0f)
347 myImage->SetPixelColor (theCol, theRow, Quantity_ColorRGBA (aNormal.x() * 0.5f + 0.5f,
348 aNormal.y() * 0.5f + 0.5f,
349 aNormal.z() * 0.5f + 0.5f, 1.0f));
353 myImage->SetPixelColor (theCol, theRow, Quantity_NOC_BLACK);
360 // =======================================================================
361 // function : CreateFiller
363 // =======================================================================
364 Handle(SelectMgr_SelectionImageFiller) SelectMgr_SelectionImageFiller::CreateFiller (Image_PixMap& thePixMap,
365 SelectMgr_ViewerSelector* theSelector,
366 StdSelect_TypeOfSelectionImage theType)
370 case StdSelect_TypeOfSelectionImage_NormalizedDepth:
371 case StdSelect_TypeOfSelectionImage_NormalizedDepthInverted:
373 return new NormalizedDepthFiller (thePixMap, theSelector, theType == StdSelect_TypeOfSelectionImage_NormalizedDepthInverted);
375 case StdSelect_TypeOfSelectionImage_UnnormalizedDepth:
377 return new UnnormalizedDepthFiller (thePixMap, theSelector);
379 case StdSelect_TypeOfSelectionImage_ColoredDetectedObject:
381 return new DetectedObjectColorFiller (thePixMap, theSelector);
383 case StdSelect_TypeOfSelectionImage_ColoredEntity:
385 return new GeneratedEntityColorFiller (thePixMap, theSelector);
387 case StdSelect_TypeOfSelectionImage_ColoredOwner:
389 return new GeneratedOwnerColorFiller (thePixMap, theSelector);
391 case StdSelect_TypeOfSelectionImage_ColoredSelectionMode:
393 return new GeneratedSelModeColorFiller (thePixMap, theSelector);
395 case StdSelect_TypeOfSelectionImage_SurfaceNormal:
397 return new SurfaceNormalFiller (thePixMap, theSelector);
400 return Handle(SelectMgr_SelectionImageFiller)();