0030915: Visualization - AIS_ColorScale::FindColor() returns Wrong color for maximal...
authorkgv <kgv@opencascade.com>
Mon, 26 Aug 2019 08:08:23 +0000 (11:08 +0300)
committerkgv <kgv@opencascade.com>
Mon, 26 Aug 2019 12:16:14 +0000 (15:16 +0300)
Map the very upper value (theValue==theMax) to the largest color interval.

src/AIS/AIS_ColorScale.cxx
tests/bugs/vis/bug27573

index ab69613..c698833 100644 (file)
@@ -79,6 +79,31 @@ namespace
     Standard_Real aSaturation = NCollection_Lerp<Standard_Real>::Interpolate (theHlsMin[2], theHlsMax[2], aValue);
     return Quantity_Color (AIS_ColorScale::hueToValidRange (aHue), aLightness, aSaturation, Quantity_TOC_HLS);
   }
+
+  //! Return the index of discrete interval for specified value.
+  //! Note that when value lies exactly on the border between two intervals,
+  //! determining which interval to return is undefined operation;
+  //! Current implementation returns the following interval in this case.
+  //! @param theValue [in] value to map
+  //! @param theMin   [in] values range, lower value
+  //! @param theMax   [in] values range, upper value
+  //! @param theNbIntervals [in] number of discrete intervals
+  //! @return index of interval within [1, theNbIntervals] range
+  static Standard_Integer colorDiscreteInterval (Standard_Real theValue,
+                                                 Standard_Real theMin,
+                                                 Standard_Real theMax,
+                                                 Standard_Integer theNbIntervals)
+  {
+    if (Abs (theMax - theMin) <= Precision::Approximation())
+    {
+      return 1;
+    }
+
+    Standard_Integer anInterval = 1 + (Standard_Integer )Floor (Standard_Real (theNbIntervals) * (theValue - theMin) / (theMax - theMin));
+    // map the very upper value (theValue==theMax) to the largest color interval
+    anInterval = Min (anInterval, theNbIntervals);
+    return anInterval;
+  }
 }
 
 //=======================================================================
@@ -348,21 +373,14 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
 
   if (myColorType == Aspect_TOCSD_USER)
   {
-    Standard_Integer anIndex = 0;
-    if (Abs (myMax - myMin) > Precision::Approximation())
-    {
-      anIndex = (theValue - myMin < Precision::Confusion()) 
-        ? 1
-        : Standard_Integer (Ceiling (( theValue - myMin ) / ( (myMax - myMin) / myNbIntervals)));
-    }
-
-    if (anIndex <= 0 || anIndex > myColors.Length())
+    const Standard_Integer anInterval = colorDiscreteInterval (theValue, myMin, myMax, myNbIntervals);
+    if (anInterval < myColors.Lower() || anInterval > myColors.Upper())
     {
       theColor = Quantity_Color();
       return Standard_False;
     }
 
-    theColor = myColors.Value (anIndex);
+    theColor = myColors.Value (anInterval);
     return Standard_True;
   }
 
@@ -386,13 +404,8 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
     return Standard_False;
   }
 
-  Standard_Real anInterval = 0.0;
-  if (Abs (theMax - theMin) > Precision::Approximation())
-  {
-    anInterval = Floor (Standard_Real (theColorsCount) * (theValue - theMin) / (theMax - theMin));
-  }
-
-  theColor = colorFromValueEx (anInterval, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
+  const Standard_Integer anInterval = colorDiscreteInterval (theValue, theMin, theMax, theColorsCount);
+  theColor = colorFromValueEx (anInterval - 1, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
   return Standard_True;
 }
 
index 4825781..6e16f70 100644 (file)
@@ -1,11 +1,10 @@
 puts "============"
-puts "0027573"
-puts "AIS_ColorScale::FindColor does not take into account custom colors."
+puts "0027573: AIS_ColorScale::FindColor does not take into account custom colors."
 puts "============"
 puts ""
 
 vclose all
-vinit
+vinit View1
 vclear
 vaxo
 
@@ -14,46 +13,18 @@ vcolorscale cs -range 0 20 5
 
 # Set user-defined colors and labels for color scale
 vcolorscale cs -colors white red green blue1 gray
+vdump ${imagedir}/${casename}_pos.png
 
-# Check the first interval border color
-if {[vcolorscale cs -findcolor 0] != "WHITE"} {
-  puts "ERROR: Find color result for the first segment is wrong!"
-}
-
-# Check first-second intervals border
-if {[vcolorscale cs -findcolor 4] != "WHITE"} {
-  puts "ERROR: Find color result for the first segment border is wrong!"
-}
-
-# Check the second interval color
-if {[vcolorscale cs -findcolor 5] != "RED"} {
-  puts "ERROR: Find color result for the second segment is wrong!"
-}
-
-# Check the second interval color
-if {[vcolorscale cs -findcolor 9] != "GREEN"} {
-  puts "ERROR: Find color result for the third segment is wrong!"
-}
-
-# Check the last interval border color
-if {[vcolorscale cs -findcolor 20] != "GRAY"} {
-  puts "ERROR: Find color result for the last segment is wrong!"
-}
+if {[vcolorscale cs -findcolor  0] != "WHITE"} { puts "ERROR: wrong 1st segment сolor" }
+if {[vcolorscale cs -findcolor  4] != "RED"}   { puts "ERROR: wrong color on border between 1st and 2nd segments" }
+if {[vcolorscale cs -findcolor  5] != "RED"}   { puts "ERROR: wrong 2nd segment color" }
+if {[vcolorscale cs -findcolor  9] != "GREEN"} { puts "ERROR: wrong 3rd segment color" }
+if {[vcolorscale cs -findcolor 20] != "GRAY"}  { puts "ERROR: wrong last segment color at border" }
 
 # Check negative value limits
 vcolorscale cs -range -5 5 5
+vdump ${imagedir}/${casename}_neg.png
 
-if {[vcolorscale cs -findcolor -5] != "WHITE"} {
-  puts "ERROR: Find color result for the first segment is wrong!"
-}
-
-if {[vcolorscale cs -findcolor 0] != "GREEN"} {
-  puts "ERROR: Find color result for the middle segment is wrong!"
-}
-
-if {[vcolorscale cs -findcolor 5] != "GRAY"} {
-  puts "ERROR: Find color result for the last segment is wrong!"
-}
-
-# Dump result
-set only_screen 1
\ No newline at end of file
+if {[vcolorscale cs -findcolor -5] != "WHITE"} { puts "ERROR: wrong first  segment color" }
+if {[vcolorscale cs -findcolor  0] != "GREEN"} { puts "ERROR: wrong middle segment color" }
+if {[vcolorscale cs -findcolor  5] != "GRAY"}  { puts "ERROR: wrong last   segment color" }