diff --git a/src/AIS/AIS_ColorScale.cxx b/src/AIS/AIS_ColorScale.cxx index 9db164a9a0..ebcad40889 100644 --- a/src/AIS/AIS_ColorScale.cxx +++ b/src/AIS/AIS_ColorScale.cxx @@ -13,6 +13,7 @@ // commercial license or contractual agreement. #include + #include #include #include @@ -38,42 +39,78 @@ #include #include +IMPLEMENT_STANDARD_RTTIEXT(AIS_ColorScale, AIS_InteractiveObject) -IMPLEMENT_STANDARD_RTTIEXT(AIS_ColorScale,AIS_InteractiveObject) +namespace +{ + //! Method to add colored quad into array of triangles. + static void addColoredQuad (const Handle(Graphic3d_ArrayOfTriangles)& theTris, + const Standard_Integer theXLeft, const Standard_Integer theYBottom, + const Standard_Integer theSizeX, const Standard_Integer theSizeY, + const Quantity_Color& theColorBottom, + const Quantity_Color& theColorTop) + { + const Standard_Integer aVertIndex = theTris->VertexNumber() + 1; + theTris->AddVertex (gp_Pnt (theXLeft, theYBottom, 0.0), theColorBottom); + theTris->AddVertex (gp_Pnt (theXLeft + theSizeX, theYBottom, 0.0), theColorBottom); + theTris->AddVertex (gp_Pnt (theXLeft, theYBottom + theSizeY, 0.0), theColorTop); + theTris->AddVertex (gp_Pnt (theXLeft + theSizeX, theYBottom + theSizeY, 0.0), theColorTop); + theTris->AddEdge (aVertIndex); + theTris->AddEdge (aVertIndex + 1); + theTris->AddEdge (aVertIndex + 2); + theTris->AddEdge (aVertIndex + 1); + theTris->AddEdge (aVertIndex + 2); + theTris->AddEdge (aVertIndex + 3); + } + + //! Compute hue angle from specified value. + static Quantity_Color colorFromValueEx (const Standard_Real theValue, + const Standard_Real theMin, + const Standard_Real theMax, + const Graphic3d_Vec3d& theHlsMin, + const Graphic3d_Vec3d& theHlsMax) + { + const Standard_Real aValueDelta = theMax - theMin; + Standard_Real aValue = 0.0; + if (aValueDelta != 0.0) + { + aValue = (theValue - theMin) / aValueDelta; + } + + Standard_Real aHue = NCollection_Lerp::Interpolate (theHlsMin[0], theHlsMax[0], aValue); + Standard_Real aLightness = NCollection_Lerp::Interpolate (theHlsMin[1], theHlsMax[1], aValue); + Standard_Real aSaturation = NCollection_Lerp::Interpolate (theHlsMin[2], theHlsMax[2], aValue); + return Quantity_Color (AIS_ColorScale::hueToValidRange (aHue), aLightness, aSaturation, Quantity_TOC_HLS); + } +} //======================================================================= //function : AIS_ColorScale //purpose : //======================================================================= -AIS_ColorScale::AIS_ColorScale() : -myMin (0.0), -myMax (1.0), -myTitle (""), -myFormat ("%.4g"), -myInterval (10), -myColorType (Aspect_TOCSD_AUTO), -myLabelType (Aspect_TOCSD_AUTO), -myAtBorder (Standard_True), -myReversed (Standard_False), -myIsLogarithmic (Standard_False), -myLabelPos (Aspect_TOCSP_RIGHT), -myTitlePos (Aspect_TOCSP_CENTER), -myXPos (0), -myYPos (0), -myBreadth (0), -myHeight (0), -myTextHeight(20) +AIS_ColorScale::AIS_ColorScale() +: myMin (0.0), + myMax (1.0), + myColorHlsMin (230.0, 1.0, 1.0), + myColorHlsMax (0.0, 1.0, 1.0), + myFormat ("%.4g"), + myNbIntervals (10), + myColorType (Aspect_TOCSD_AUTO), + myLabelType (Aspect_TOCSD_AUTO), + myIsLabelAtBorder (Standard_True), + myIsReversed (Standard_False), + myIsLogarithmic (Standard_False), + myIsSmooth (Standard_False), + myLabelPos (Aspect_TOCSP_RIGHT), + myTitlePos (Aspect_TOCSP_LEFT), + myXPos (0), + myYPos (0), + myBreadth (0), + myHeight (0), + mySpacing (5), + myTextHeight (20) { -} - -//======================================================================= -//function : GetRange -//purpose : -//======================================================================= -void AIS_ColorScale::GetRange (Standard_Real& theMin, Standard_Real& theMax) const -{ - theMin = myMin; - theMax = myMax; + SetDisplayMode (0); } //======================================================================= @@ -82,22 +119,23 @@ void AIS_ColorScale::GetRange (Standard_Real& theMin, Standard_Real& theMax) con //======================================================================= TCollection_ExtendedString AIS_ColorScale::GetLabel (const Standard_Integer theIndex) const { - if (GetLabelType() == Aspect_TOCSD_USER) + if (myLabelType == Aspect_TOCSD_USER) { - if (theIndex <= 0 || theIndex > myLabels.Length()) + if (theIndex >= myLabels.Lower() + || theIndex <= myLabels.Upper()) { - return ""; + return myLabels.Value(theIndex); } - return myLabels.Value (theIndex); + return TCollection_ExtendedString(); } // value to be shown depends on label position - Standard_Real aVal = IsLabelAtBorder() ? GetIntervalValue (theIndex - 1) : - 0.5 * (GetIntervalValue (theIndex - 1) + GetIntervalValue (theIndex)); + const Standard_Real aVal = myIsLabelAtBorder + ? GetIntervalValue (theIndex - 1) + : (0.5 * (GetIntervalValue (theIndex - 1) + GetIntervalValue (theIndex))); - const TCollection_AsciiString aFormat = Format(); - Standard_Character aBuf[1024]; - sprintf (aBuf, aFormat.ToCString(), aVal); + char aBuf[1024]; + sprintf (aBuf, myFormat.ToCString(), aVal); return TCollection_ExtendedString (aBuf); } @@ -107,7 +145,7 @@ TCollection_ExtendedString AIS_ColorScale::GetLabel (const Standard_Integer theI //======================================================================= Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex) const { - if (GetColorType() == Aspect_TOCSD_USER) + if (myColorType== Aspect_TOCSD_USER) { if (theIndex <= 0 || theIndex > myColors.Length()) { @@ -116,7 +154,7 @@ Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex return myColors.Value (theIndex); } - return Quantity_Color (HueFromValue (theIndex - 1, 0, GetNumberOfIntervals() - 1), 1.0, 1.0, Quantity_TOC_HLS); + return colorFromValue (theIndex - 1, 0, myNbIntervals - 1); } //======================================================================= @@ -126,8 +164,10 @@ Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex void AIS_ColorScale::GetLabels (TColStd_SequenceOfExtendedString& theLabels) const { theLabels.Clear(); - for (Standard_Integer i = 1; i <= myLabels.Length(); i++) - theLabels.Append (myLabels.Value (i)); + for (TColStd_SequenceOfExtendedString::Iterator aLabIter (myLabels); aLabIter.More(); aLabIter.Next()) + { + theLabels.Append (aLabIter.Value()); + } } //======================================================================= @@ -137,26 +177,10 @@ void AIS_ColorScale::GetLabels (TColStd_SequenceOfExtendedString& theLabels) con void AIS_ColorScale::GetColors (Aspect_SequenceOfColor& theColors) const { theColors.Clear(); - for (Standard_Integer i = 1; i <= myColors.Length(); i++) - theColors.Append (myColors.Value (i)); -} - -//======================================================================= -//function : SetMin -//purpose : -//======================================================================= -void AIS_ColorScale::SetMin (const Standard_Real theMin) -{ - SetRange (theMin, GetMax()); -} - -//======================================================================= -//function : SetMax -//purpose : -//======================================================================= -void AIS_ColorScale::SetMax (const Standard_Real theMax) -{ - SetRange (GetMin(), theMax); + for (Aspect_SequenceOfColor::Iterator aColorIter (myColors); aColorIter.More(); aColorIter.Next()) + { + theColors.Append (aColorIter.Value()); + } } //======================================================================= @@ -165,95 +189,52 @@ void AIS_ColorScale::SetMax (const Standard_Real theMax) //======================================================================= void AIS_ColorScale::SetRange (const Standard_Real theMin, const Standard_Real theMax) { - if (myMin == theMin && myMax == theMax) - return; - myMin = Min (theMin, theMax); myMax = Max (theMin, theMax); } -//======================================================================= -//function : SetLabelType -//purpose : -//======================================================================= -void AIS_ColorScale::SetLabelType (const Aspect_TypeOfColorScaleData theType) -{ - if (myLabelType == theType) - return; - - myLabelType = theType; -} - -//======================================================================= -//function : SetColorType -//purpose : -//======================================================================= -void AIS_ColorScale::SetColorType (const Aspect_TypeOfColorScaleData theType) -{ - if (myColorType == theType) - return; - - myColorType = theType; -} - //======================================================================= //function : SetNumberOfIntervals //purpose : //======================================================================= void AIS_ColorScale::SetNumberOfIntervals (const Standard_Integer theNum) { - if (myInterval == theNum || theNum < 1) + if (theNum < 1) + { return; + } - myInterval = theNum; -} - -//======================================================================= -//function : SetTitle -//purpose : -//======================================================================= -void AIS_ColorScale::SetTitle (const TCollection_ExtendedString& theTitle) -{ - if (myTitle == theTitle) - return; - - myTitle = theTitle; -} - -//======================================================================= -//function : SetFormat -//purpose : -//======================================================================= -void AIS_ColorScale::SetFormat (const TCollection_AsciiString& theFormat) -{ - if (myFormat == theFormat) - return; - - myFormat = theFormat; + myNbIntervals = theNum; } //======================================================================= //function : SetLabel //purpose : //======================================================================= -void AIS_ColorScale::SetLabel (const TCollection_ExtendedString& theLabel, const Standard_Integer theIndex) +void AIS_ColorScale::SetLabel (const TCollection_ExtendedString& theLabel, + const Standard_Integer theIndex) { - Standard_Integer i = (theIndex <= 0 ? myLabels.Length() + 1 : theIndex); - while (i > myLabels.Length()) + const Standard_Integer aLabIndex = (theIndex <= 0 ? myLabels.Length() + 1 : theIndex); + while (myLabels.Length() < aLabIndex) + { myLabels.Append (TCollection_ExtendedString()); - myLabels.SetValue (i, theLabel); + } + myLabels.SetValue (aLabIndex, theLabel); } //======================================================================= //function : SetIntervalColor //purpose : //======================================================================= -void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor, const Standard_Integer theIndex) +void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor, + const Standard_Integer theIndex) { - Standard_Integer i = (theIndex <= 0 ? myColors.Length() + 1 : theIndex); - while (i > myColors.Length()) + const Standard_Integer aColorIndex = (theIndex <= 0 ? myColors.Length() + 1 : theIndex); + while (myColors.Length() < aColorIndex) + { myColors.Append (Quantity_Color()); - myColors.SetValue (i, theColor); + } + myColors.SetValue (aColorIndex, theColor); } //======================================================================= @@ -263,8 +244,10 @@ void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor, const Sta void AIS_ColorScale::SetLabels (const TColStd_SequenceOfExtendedString& theSeq) { myLabels.Clear(); - for (Standard_Integer i = 1; i <= theSeq.Length(); i++) - myLabels.Append (theSeq.Value (i)); + for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theSeq); aLabIter.More(); aLabIter.Next()) + { + myLabels.Append (aLabIter.Value()); + } } //======================================================================= @@ -274,138 +257,10 @@ void AIS_ColorScale::SetLabels (const TColStd_SequenceOfExtendedString& theSeq) void AIS_ColorScale::SetColors (const Aspect_SequenceOfColor& theSeq) { myColors.Clear(); - for (Standard_Integer i = 1; i <= theSeq.Length(); i++) - myColors.Append (theSeq.Value (i)); -} - -//======================================================================= -//function : SetLabelPosition -//purpose : -//======================================================================= -void AIS_ColorScale::SetLabelPosition (const Aspect_TypeOfColorScalePosition thePos) -{ - if (myLabelPos == thePos) - return; - - myLabelPos = thePos; -} - -//======================================================================= -//function : SetTitlePosition -//purpose : -//======================================================================= -void AIS_ColorScale::SetTitlePosition (const Aspect_TypeOfColorScalePosition thePos) -{ - if (myTitlePos == thePos) - return; - - myTitlePos = thePos; -} - -//======================================================================= -//function : SetReversed -//purpose : -//======================================================================= -void AIS_ColorScale::SetReversed (const Standard_Boolean theReverse) -{ - if (myReversed == theReverse) - return; - - myReversed = theReverse; -} - -//======================================================================= -//function : SetLabelAtBorder -//purpose : -//======================================================================= -void AIS_ColorScale::SetLabelAtBorder (const Standard_Boolean theOn) -{ - if (myAtBorder == theOn) - return; - - myAtBorder = theOn; -} - -//======================================================================= -//function : GetPosition -//purpose : -//======================================================================= -void AIS_ColorScale::GetPosition (Standard_Real& theX, Standard_Real& theY) const -{ - theX = myXPos; - theY = myYPos; -} - -//======================================================================= -//function : SetPosition -//purpose : -//======================================================================= -void AIS_ColorScale::SetPosition (const Standard_Integer theX, const Standard_Integer theY) -{ - if (myXPos == theX && myYPos == theY) - return; - - myXPos = theX; - myYPos = theY; -} - -//======================================================================= -//function : SetXPosition -//purpose : -//======================================================================= -void AIS_ColorScale::SetXPosition (const Standard_Integer theX) -{ - SetPosition (theX, GetYPosition()); -} - -//======================================================================= -//function : SetYPosition -//purpose : -//======================================================================= -void AIS_ColorScale::SetYPosition (const Standard_Integer theY) -{ - SetPosition (GetXPosition(), theY); -} - -//======================================================================= -//function : GetSize -//purpose : -//======================================================================= -void AIS_ColorScale::GetSize (Standard_Integer& theBreadth, Standard_Integer& theHeight) const -{ - theBreadth = myBreadth; - theHeight = myHeight; -} - -//======================================================================= -//function : SetSize -//purpose : -//======================================================================= -void AIS_ColorScale::SetSize (const Standard_Integer theBreadth, const Standard_Integer theHeight) -{ - if (myBreadth == theBreadth && myHeight == theHeight) - return; - - myBreadth = theBreadth; - myHeight = theHeight; -} - -//======================================================================= -//function : SetBreadth -//purpose : -//======================================================================= -void AIS_ColorScale::SetBreadth (const Standard_Integer theWidth) -{ - SetSize (theWidth, GetHeight()); -} - -//======================================================================= -//function : SetHeight -//purpose : -//======================================================================= -void AIS_ColorScale::SetHeight (const Standard_Integer theHeight) -{ - SetSize (GetBreadth(), theHeight); + for (Aspect_SequenceOfColor::Iterator aColorIter (theSeq); aColorIter.More(); aColorIter.Next()) + { + myColors.Append (aColorIter.Value()); + } } //======================================================================= @@ -414,84 +269,67 @@ void AIS_ColorScale::SetHeight (const Standard_Integer theHeight) //======================================================================= void AIS_ColorScale::SizeHint (Standard_Integer& theWidth, Standard_Integer& theHeight) const { - Standard_Integer aNum = GetNumberOfIntervals(); - - Standard_Integer aSpacer = 5; + const Standard_Integer aTextHeight = TextHeight (""); + const Standard_Integer aColorWidth = 20; Standard_Integer aTextWidth = 0; - Standard_Integer aTextHeight = TextHeight (""); - Standard_Integer aColorWidth = 20; - - if (GetLabelPosition() != Aspect_TOCSP_NONE) + if (myLabelPos != Aspect_TOCSP_NONE) { - for (Standard_Integer idx = (IsLabelAtBorder() ? 0 : 1); idx <= aNum; idx++) - aTextWidth = Max (aTextWidth, TextWidth (GetLabel (idx))); + for (Standard_Integer aLabIter = (myIsLabelAtBorder ? 0 : 1); aLabIter <= myNbIntervals; ++aLabIter) + { + aTextWidth = Max (aTextWidth, TextWidth (GetLabel (aLabIter))); + } } - Standard_Integer aScaleWidth = 0; - Standard_Integer aScaleHeight = 0; + const Standard_Integer aScaleWidth = aColorWidth + aTextWidth + (aTextWidth ? 3 : 2) * mySpacing; + const Standard_Integer aScaleHeight = (Standard_Integer)(1.5 * (myNbIntervals + (myIsLabelAtBorder ? 2 : 1)) * aTextHeight); - aScaleWidth = aColorWidth + aTextWidth + ( aTextWidth ? 3 : 2 ) * aSpacer; - aScaleHeight = (Standard_Integer)( 1.5 * ( aNum + (IsLabelAtBorder() ? 2 : 1) ) * aTextHeight ); - - Standard_Integer aTitleWidth = 0; + Standard_Integer aTitleWidth = 0; Standard_Integer aTitleHeight = 0; - if (GetTitle().Length()) + if (!myTitle.IsEmpty()) { - aTitleHeight = TextHeight (GetTitle()) + aSpacer; - aTitleWidth = TextWidth (GetTitle()) + 10; + aTitleHeight = TextHeight (myTitle) + mySpacing; + aTitleWidth = TextWidth (myTitle) + mySpacing * 2; } - theWidth = Max (aTitleWidth, aScaleWidth); + theWidth = Max (aTitleWidth, aScaleWidth); theHeight = aScaleHeight + aTitleHeight; } -//======================================================================= -//function : Format -//purpose : -//======================================================================= -TCollection_AsciiString AIS_ColorScale::Format() const -{ - return GetFormat(); -} - //======================================================================= //function : GetIntervalValue //purpose : //======================================================================= Standard_Real AIS_ColorScale::GetIntervalValue (const Standard_Integer theIndex) const { - if (GetNumberOfIntervals() <= 0) - return 0.; + if (myNbIntervals <= 0) + { + return 0.0; + } if (IsLogarithmic()) { - Standard_Real aMin = myMin > 0 ? myMin : 1.0; - Standard_Real aDivisor = std::pow (myMax/aMin, 1.0/myInterval); - return aMin*std::pow (aDivisor,theIndex); + Standard_Real aMin = myMin > 0 ? myMin : 1.0; + Standard_Real aDivisor = std::pow (myMax / aMin, 1.0 / myNbIntervals); + return aMin * std::pow (aDivisor,theIndex); } Standard_Real aNum = 0; - if (GetNumberOfIntervals() > 0) - aNum = GetMin() + theIndex * ( Abs (GetMax() - GetMin()) / GetNumberOfIntervals() ); + if (myNbIntervals > 0) + { + aNum = GetMin() + theIndex * (Abs (GetMax() - GetMin()) / myNbIntervals); + } return aNum; } //======================================================================= -//function : HueFromValue +//function : colorFromValue //purpose : //======================================================================= -Standard_Integer AIS_ColorScale::HueFromValue (const Standard_Integer theValue, - const Standard_Integer theMin, const Standard_Integer theMax) +Quantity_Color AIS_ColorScale::colorFromValue (const Standard_Real theValue, + const Standard_Real theMin, + const Standard_Real theMax) const { - Standard_Integer aMinLimit (0), aMaxLimit (230); - - Standard_Integer aHue = aMaxLimit; - if (theMin != theMax) - aHue = (Standard_Integer)( aMaxLimit - ( aMaxLimit - aMinLimit ) * ( theValue - theMin ) / ( theMax - theMin ) ); - - aHue = Min (Max (aMinLimit, aHue), aMaxLimit); - - return aHue; + return colorFromValueEx (theValue, theMin, theMax, myColorHlsMin, myColorHlsMax); } //======================================================================= @@ -507,14 +345,14 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue, return Standard_False; } - if (GetColorType() == Aspect_TOCSD_USER) + 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) / myInterval))); + : Standard_Integer (Ceiling (( theValue - myMin ) / ( (myMax - myMin) / myNbIntervals))); } if (anIndex <= 0 || anIndex > myColors.Length()) @@ -527,7 +365,7 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue, return Standard_True; } - return FindColor (theValue, myMin, myMax, myInterval, theColor); + return FindColor (theValue, myMin, myMax, myNbIntervals, theColor); } //======================================================================= @@ -538,182 +376,383 @@ Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue, const Standard_Real theMin, const Standard_Real theMax, const Standard_Integer theColorsCount, + const Graphic3d_Vec3d& theColorHlsMin, + const Graphic3d_Vec3d& theColorHlsMax, Quantity_Color& theColor) { if (theValue < theMin || theValue > theMax || theMax < theMin) - return Standard_False; - - else { - Standard_Real anIntervNumber = 0; - if(Abs (theMax-theMin) > Precision::Approximation()) - anIntervNumber = Floor (Standard_Real (theColorsCount) * ( theValue - theMin ) / ( theMax - theMin )); - - Standard_Integer anInterv = Standard_Integer (anIntervNumber); - - theColor = Quantity_Color (HueFromValue (anInterv, 0, theColorsCount - 1), 1.0, 1.0, Quantity_TOC_HLS); - - return Standard_True; + 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); + return Standard_True; +} + +//======================================================================= +//function : computeMaxLabelWidth +//purpose : +//======================================================================= +Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const +{ + { + Handle(V3d_Viewer) aViewer = GetContext()->CurrentViewer(); + aViewer->InitActiveViews(); // for AIS_ColorScale::TextSize() + } + + Standard_Integer aWidthMax = 0; + for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next()) + { + if (!aLabIter.Value().IsEmpty()) + { + aWidthMax = Max (aWidthMax, TextWidth (aLabIter.Value())); + } + } + return aWidthMax; +} + +//======================================================================= +//function : updateTextAspect +//purpose : +//======================================================================= +void AIS_ColorScale::updateTextAspect() +{ + // update text aspect + const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE); + if (!myDrawer->HasOwnTextAspect()) + { + myDrawer->SetTextAspect (new Prs3d_TextAspect()); + *myDrawer->TextAspect()->Aspect() = *myDrawer->Link()->TextAspect()->Aspect(); + } + + const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect(); + anAspect->SetColor (aFgColor); + anAspect->SetHeight (myTextHeight); + anAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT); + anAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM); + anAspect->Aspect()->SetTextZoomable (Standard_True); } //======================================================================= //function : Compute //purpose : //======================================================================= -void AIS_ColorScale::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer /*theMode*/) +void AIS_ColorScale::Compute (const Handle(PrsMgr_PresentationManager3d)& , + const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theMode) { - Handle(V3d_Viewer) aViewer= GetContext()->CurrentViewer(); - aViewer->InitActiveViews(); - Standard_Integer aNum = GetNumberOfIntervals(); - Aspect_TypeOfColorScalePosition aLabPos = GetLabelPosition(); - - Standard_Integer aSpacer = 5; - Standard_Integer aTextWidth = 0; - Standard_Integer aTextHeight = myTextHeight; - Standard_Boolean toDrawLabel = GetLabelPosition() != Aspect_TOCSP_NONE; - TCollection_ExtendedString aTitle = GetTitle(); - Standard_Integer aTitleHeight = aSpacer; - Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE); - - // Draw title - if (aTitle.Length()) + if (theMode != 0) { - aTitleHeight += myTextHeight + aSpacer; - drawText (thePresentation, aTitle, (Standard_Integer)myXPos + aSpacer, myHeight - ((Standard_Integer)myYPos - 2 * aSpacer + aTitleHeight), aFgColor); + return; } - Standard_Boolean toReverse = IsReversed(); + // update text aspect + updateTextAspect(); - Aspect_SequenceOfColor aColors; - for (Standard_Integer i = 1; i <= aNum; i++) + const Standard_Integer aTitleOffset = !myTitle.IsEmpty() ? (myTextHeight + mySpacing) : 0; + + const Standard_Integer aBarYOffset = myTextHeight / 2 + 2 * mySpacing; // a half-label offset + const Standard_Integer aBarBottom = myYPos + aBarYOffset; + const Standard_Integer aBarTop = myYPos + myHeight - aTitleOffset - aBarYOffset; + const Standard_Integer aBarHeight = aBarTop - aBarBottom; + + // draw title + if (!myTitle.IsEmpty()) { - if (toReverse) - { - aColors.Prepend (GetIntervalColor (i)); - } - else - { - aColors.Append (GetIntervalColor (i)); - } + drawText (Prs3d_Root::CurrentGroup (thePrs), myTitle, + myXPos + mySpacing, + aBarTop + aBarYOffset, + Graphic3d_VTA_BOTTOM); } TColStd_SequenceOfExtendedString aLabels; - Standard_Integer aLabCount = IsLabelAtBorder() ? aNum + 1 : aNum; - for (Standard_Integer i = 1; i <= aLabCount; i++) + if (myLabelType == Aspect_TOCSD_USER) { - if (toReverse) + aLabels = myLabels; + } + else + { + const Standard_Integer aNbLabels = myIsLabelAtBorder ? myNbIntervals + 1 : myNbIntervals; + for (Standard_Integer aLabIter = 1; aLabIter <= aNbLabels; ++aLabIter) { - aLabels.Prepend (GetLabel (i)); + if (myIsReversed) + { + aLabels.Prepend (GetLabel (aLabIter)); + } + else + { + aLabels.Append (GetLabel (aLabIter)); + } + } + } + + const Standard_Integer aTextWidth = myLabelPos != Aspect_TOCSP_NONE ? computeMaxLabelWidth (aLabels) : 0; + Standard_Integer aColorBreadth = Max (5, Min (20, myBreadth - aTextWidth - 3 * mySpacing)); + if (myLabelPos == Aspect_TOCSP_CENTER + || myLabelPos == Aspect_TOCSP_NONE) + { + aColorBreadth += aTextWidth; + } + + // draw colors + drawColorBar (thePrs, aBarBottom, aBarHeight, aTextWidth, aColorBreadth); + + // draw Labels + drawLabels (thePrs, aLabels, aBarBottom, aBarHeight, aTextWidth, aColorBreadth); +} + +//======================================================================= +//function : drawColorBar +//purpose : +//======================================================================= +void AIS_ColorScale::drawColorBar (const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theBarBottom, + const Standard_Integer theBarHeight, + const Standard_Integer theMaxLabelWidth, + const Standard_Integer theColorBreadth) +{ + const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(myNbIntervals); + if (aStepY <= 0.0) + { + return; + } + + // Draw colors + const Standard_Integer anXLeft = myLabelPos == Aspect_TOCSP_LEFT + ? myXPos + mySpacing + theMaxLabelWidth + (theMaxLabelWidth != 0 ? 1 : 0) * mySpacing + : myXPos + mySpacing; + + Aspect_SequenceOfColor aColors; + for (Standard_Integer anIntervalIter = 1; anIntervalIter <= myNbIntervals; ++anIntervalIter) + { + if (myIsReversed) + { + aColors.Prepend (GetIntervalColor (anIntervalIter)); } else { - aLabels.Append (GetLabel (i)); + aColors.Append (GetIntervalColor (anIntervalIter)); } } - if (toDrawLabel) - for (Standard_Integer i = 1; i <= aLabels.Length(); i++) - aTextWidth = Max (aTextWidth, TextWidth (aLabels.Value (i))); - - Standard_Integer aSpc = ( myHeight - ( ( Min (aLabCount, 2) + Abs (aLabCount - aNum - 1) ) * aTextHeight ) - aTitleHeight ); - Standard_Real aVal = aSpc != 0 ? 1.0 * ( aLabCount - Min (aLabCount, 0) ) * aTextHeight / aSpc : 0; - Standard_Real anIPart; - Standard_Real anFPart = modf (aVal, &anIPart); - Standard_Integer aFilter = (Standard_Integer)anIPart + ( anFPart != 0 ? 1 : 0 ); - - Standard_Real aStep = 1.0 * ( myHeight - (aLabCount - aNum + Abs (aLabCount - aNum - 1)) * aTextHeight - aTitleHeight ) / aNum; - - Standard_Integer anAscent = 0; - Standard_Integer aColorBreadth = Max (5, Min (20, myBreadth - aTextWidth - 3 * aSpacer)); - if (aLabPos == Aspect_TOCSP_CENTER || !toDrawLabel) - aColorBreadth += aTextWidth; - - // Draw colors - Standard_Integer aX = (Standard_Integer)myXPos + aSpacer; - if (aLabPos == Aspect_TOCSP_LEFT) - aX += aTextWidth + ( aTextWidth ? 1 : 0 ) * aSpacer; - - Standard_Real anOffset = 1.0 * aTextHeight / 2 * ( aLabCount - aNum + Abs (aLabCount - aNum - 1) ); - anOffset += 2*aSpacer; - Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation); - Handle (Graphic3d_ArrayOfTriangles) aPrim; - Standard_Integer anEdgesPerColor = 6; - Standard_Integer aVerticiesPerColor = 4; - aPrim = new Graphic3d_ArrayOfTriangles (aColors.Length()*aVerticiesPerColor, aColors.Length()*anEdgesPerColor, 0, 1); - Standard_Integer aVertIndex = 1; - for (Standard_Integer i = 1; i <= aColors.Length() && aStep > 0; i++) + Handle(Graphic3d_ArrayOfTriangles) aTriangles; + if (myIsSmooth + && myColorType == Aspect_TOCSD_USER) { - Standard_Integer aY = (Standard_Integer)( myYPos + ( i - 1 )* aStep + anOffset ); - Standard_Integer aColorHeight = (Standard_Integer)( myYPos + ( i ) * aStep + anOffset ) - aY; - aPrim->AddVertex (gp_Pnt (aX, aY, 0.0), aColors.Value( i )); - aPrim->AddVertex (gp_Pnt (aX+aColorBreadth, aY, 0.0), aColors.Value( i )); - aPrim->AddVertex (gp_Pnt (aX, aY+aColorHeight, 0.0), aColors.Value( i )); - aPrim->AddVertex (gp_Pnt (aX+aColorBreadth, aY+aColorHeight, 0.0), aColors.Value( i )); - aPrim->AddEdge(aVertIndex); - aPrim->AddEdge(aVertIndex+1); - aPrim->AddEdge(aVertIndex+2); - aPrim->AddEdge(aVertIndex+1); - aPrim->AddEdge(aVertIndex+2); - aPrim->AddEdge(aVertIndex+3); - aVertIndex += 4; + // Smooth custom intervals, so that the color in the center of interval is equal to specified one + // (thus the halves of first and last intervals have solid color) + aTriangles = new Graphic3d_ArrayOfTriangles ((aColors.Length() + 1) * 4, // quads + (aColors.Length() + 1) * 2 * 3, // quads as triangles + false, true); // per-vertex colors + Quantity_Color aColor1 (aColors.Value (1)), aColor2; + Standard_Integer aSizeY = Standard_Integer(aStepY / 2); + const Standard_Integer anYBottom = theBarBottom + aSizeY; + Standard_Integer anYBottomIter = anYBottom; + addColoredQuad (aTriangles, + anXLeft, theBarBottom, + theColorBreadth, aSizeY, + aColor1, aColor1); + for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals - 1; ++aColorIter) + { + aColor1 = aColors.Value (aColorIter + 1); + aColor2 = aColors.Value (aColorIter + 2); + aSizeY = anYBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, aSizeY, + aColor1, aColor2); + anYBottomIter += aSizeY; + } + aColor2 = aColors.Value (myNbIntervals); + aSizeY = theBarBottom + theBarHeight - anYBottomIter; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, aSizeY, + aColor2, aColor2); } - aGroup->AddPrimitiveArray (aPrim); - - if (aStep > 0) - drawFrame (thePresentation, aX - 1, (Standard_Integer)(myYPos + anOffset - 1), aColorBreadth + 2, (Standard_Integer)(aColors.Length() * aStep + 2), aFgColor); - - // Draw Labels - anOffset = 1.0 * Abs (aLabCount - aNum - 1) * ( aStep - aTextHeight ) / 2 + 1.0 * Abs (aLabCount - aNum - 1) * aTextHeight / 2; - anOffset += 2*aSpacer; - if (toDrawLabel && aLabels.Length() && aFilter > 0) + else if (myIsSmooth) { - Standard_Integer i1 = 0; - Standard_Integer i2 = aLabCount - 1; - Standard_Integer aLast1( i1 ), aLast2( i2 ); - aX = (Standard_Integer)myXPos + aSpacer; - switch (aLabPos) + // smooth transition between standard colors - without solid color regions at the beginning and end of full color range + const Quantity_Color aColorsFixed[5] = { - case Aspect_TOCSP_NONE: - case Aspect_TOCSP_LEFT: - break; - case Aspect_TOCSP_CENTER: - aX += ( aColorBreadth - aTextWidth ) / 2; - break; - case Aspect_TOCSP_RIGHT: - aX += aColorBreadth + aSpacer; - break; + colorFromValue (0, 0, 4), + colorFromValue (1, 0, 4), + colorFromValue (2, 0, 4), + colorFromValue (3, 0, 4), + colorFromValue (4, 0, 4) + }; + aTriangles = new Graphic3d_ArrayOfTriangles (4 * 4, // quads + 4 * 2 * 3, // quads as triangles + false, true); // per-vertex colors + Standard_Integer anYBottomIter = theBarBottom; + addColoredQuad (aTriangles, + anXLeft, theBarBottom, + theColorBreadth, theBarHeight / 4, + aColorsFixed[0], aColorsFixed[1]); + anYBottomIter += theBarHeight / 4; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, theBarHeight / 4, + aColorsFixed[1], aColorsFixed[2]); + anYBottomIter += theBarHeight / 4; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, theBarHeight / 4, + aColorsFixed[2], aColorsFixed[3]); + anYBottomIter += theBarHeight / 4; + const Standard_Integer aLastSizeY = theBarBottom + theBarHeight - anYBottomIter; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, aLastSizeY, + aColorsFixed[3], aColorsFixed[4]); + } + else + { + // no color smoothing + aTriangles = new Graphic3d_ArrayOfTriangles (aColors.Length() * 4, // quads + aColors.Length() * 2 * 3, // quads as triangles + false, true); // per-vertex colors + Standard_Integer anYBottomIter = theBarBottom; + for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals; ++aColorIter) + { + const Quantity_Color& aColor = aColors.Value (aColorIter + 1); + const Standard_Integer aSizeY = theBarBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter; + addColoredQuad (aTriangles, + anXLeft, anYBottomIter, + theColorBreadth, aSizeY, + aColor, aColor); + anYBottomIter += aSizeY; } - while (i2 - i1 >= aFilter || ( i2 == 0 && i1 == 0 )) + } + + Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs); + aGroup->AddPrimitiveArray (aTriangles); + + const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE); + drawFrame (thePrs, + anXLeft - 1, theBarBottom - 1, + theColorBreadth + 2, + theBarHeight + 2, + aFgColor); +} + +//======================================================================= +//function : drawLabels +//purpose : +//======================================================================= +void AIS_ColorScale::drawLabels (const Handle(Prs3d_Presentation)& thePrs, + const TColStd_SequenceOfExtendedString& theLabels, + const Standard_Integer theBarBottom, + const Standard_Integer theBarHeight, + const Standard_Integer theMaxLabelWidth, + const Standard_Integer theColorBreadth) +{ + if (myLabelPos == Aspect_TOCSP_NONE + || theLabels.IsEmpty()) + { + return; + } + + const Standard_Integer aNbLabels = theLabels.Size(); + const Standard_Integer aNbIntervals = myIsLabelAtBorder ? aNbLabels - 1 : aNbLabels; + const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(aNbIntervals); + if (aStepY <= 0.0) + { + return; + } + + Standard_Integer aFilter = 0; + { + const Standard_Integer aTitleHeight = !myTitle.IsEmpty() ? (myTextHeight + 2 * mySpacing) : mySpacing; + const Standard_Integer aSpc = myHeight - aTitleHeight - ((Min (aNbLabels, 2) + Abs (aNbLabels - aNbIntervals - 1)) * myTextHeight); + if (aSpc <= 0) { - Standard_Integer aPos1 = i1; - Standard_Integer aPos2 = aLabCount - 1 - i2; - if (aFilter && !( aPos1 % aFilter )) - { - drawText (thePresentation, aLabels.Value (i1 + 1), aX, (Standard_Integer)( myYPos + i1 * aStep + anAscent + anOffset ), aFgColor); - aLast1 = i1; - } - if (aFilter && !( aPos2 % aFilter )) - { - drawText (thePresentation, aLabels.Value (i2 + 1), aX, (Standard_Integer)( myYPos + i2 * aStep + anAscent + anOffset ), aFgColor); - aLast2 = i2; - } - i1++; - i2--; - } - Standard_Integer aPos = i1; - Standard_Integer i0 = -1; - while (aPos <= i2 && i0 == -1) - { - if (aFilter && !( aPos % aFilter ) && Abs (aPos - aLast1) >= aFilter && Abs (aPos - aLast2) >= aFilter) - i0 = aPos; - aPos++; + return; } - if (i0 != -1) - drawText (thePresentation, aLabels.Value (i0 + 1), aX, (Standard_Integer)( myYPos + i0 * aStep + anAscent + anOffset ), aFgColor); + const Standard_Real aVal = Standard_Real(aNbLabels) * myTextHeight / aSpc; + Standard_Real anIPart = 0.0; + Standard_Real anFPart = std::modf (aVal, &anIPart); + aFilter = (Standard_Integer )anIPart + (anFPart != 0 ? 1 : 0); + } + if (aFilter <= 0) + { + return; + } + + Standard_Integer anXLeft = myXPos + mySpacing; + const Standard_Integer anAscent = 0; + switch (myLabelPos) + { + case Aspect_TOCSP_NONE: + case Aspect_TOCSP_LEFT: + { + break; + } + case Aspect_TOCSP_CENTER: + { + anXLeft += (theColorBreadth - theMaxLabelWidth) / 2; + break; + } + case Aspect_TOCSP_RIGHT: + { + anXLeft += theColorBreadth + mySpacing; + break; + } + } + + Standard_Integer i1 = 0; + Standard_Integer i2 = aNbLabels - 1; + Standard_Integer aLast1 = i1; + Standard_Integer aLast2 = i2; + const Standard_Integer anYBottom = myIsLabelAtBorder + ? theBarBottom + : theBarBottom + Standard_Integer(aStepY / 2); + while (i2 - i1 >= aFilter || ( i2 == 0 && i1 == 0 )) + { + Standard_Integer aPos1 = i1; + Standard_Integer aPos2 = aNbLabels - 1 - i2; + if (aFilter && !(aPos1 % aFilter)) + { + drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i1 + 1), + anXLeft, anYBottom + Standard_Integer(i1 * aStepY + anAscent), + Graphic3d_VTA_CENTER); + aLast1 = i1; + } + if (aFilter && !(aPos2 % aFilter)) + { + drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i2 + 1), + anXLeft, anYBottom + Standard_Integer(i2 * aStepY + anAscent), + Graphic3d_VTA_CENTER); + aLast2 = i2; + } + i1++; + i2--; + } + Standard_Integer aPos = i1; + Standard_Integer i0 = -1; + while (aPos <= i2 && i0 == -1) + { + if (aFilter && !(aPos % aFilter) + && Abs (aPos - aLast1) >= aFilter + && Abs (aPos - aLast2) >= aFilter) + { + i0 = aPos; + } + aPos++; + } + + if (i0 != -1) + { + drawText (Prs3d_Root::CurrentGroup (thePrs), theLabels.Value (i0 + 1), + anXLeft, anYBottom + Standard_Integer(i0 * aStepY + anAscent), + Graphic3d_VTA_CENTER); } } @@ -721,22 +760,21 @@ void AIS_ColorScale::Compute(const Handle(PrsMgr_PresentationManager3d)& /*thePr //function : drawFrame //purpose : //======================================================================= -void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theX, const Standard_Integer theY, - const Standard_Integer theWidth, const Standard_Integer theHeight, - const Quantity_Color& theColor) +void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theX, const Standard_Integer theY, + const Standard_Integer theWidth, const Standard_Integer theHeight, + const Quantity_Color& theColor) { - Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation); Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5); - aPrim->AddVertex (theX,theY,0.0); - aPrim->AddVertex (theX+theWidth,theY,0.0); - aPrim->AddVertex (theX+theWidth,theY+theHeight,0.0); - aPrim->AddVertex (theX,theY+theHeight,0.0); - aPrim->AddVertex (theX,theY,0.0); - Handle(Prs3d_LineAspect) anAspect = - new Prs3d_LineAspect (theColor, Aspect_TOL_SOLID, 1.0); - anAspect->SetColor (theColor); - aGroup->SetPrimitivesAspect (anAspect->Aspect()); + aPrim->AddVertex (theX, theY, 0.0); + aPrim->AddVertex (theX + theWidth, theY, 0.0); + aPrim->AddVertex (theX + theWidth, theY + theHeight, 0.0); + aPrim->AddVertex (theX, theY + theHeight, 0.0); + aPrim->AddVertex (theX, theY, 0.0); + + Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d (theColor, Aspect_TOL_SOLID, 1.0); + Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs); + aGroup->SetPrimitivesAspect (anAspect); aGroup->AddPrimitiveArray (aPrim); } @@ -744,25 +782,23 @@ void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePresentatio //function : drawText //purpose : //======================================================================= -void AIS_ColorScale::drawText (const Handle(Prs3d_Presentation)& thePresentation, - const TCollection_ExtendedString& theText, - const Standard_Integer theX, const Standard_Integer theY, - const Quantity_Color& theColor) +void AIS_ColorScale::drawText (const Handle(Graphic3d_Group)& theGroup, + const TCollection_ExtendedString& theText, + const Standard_Integer theX, const Standard_Integer theY, + const Graphic3d_VerticalTextAlignment theVertAlignment) { - if (!myDrawer->HasOwnTextAspect()) - { - myDrawer->SetTextAspect (new Prs3d_TextAspect()); - *myDrawer->TextAspect()->Aspect() = *myDrawer->Link()->TextAspect()->Aspect(); - } - Handle(Prs3d_TextAspect) anAspect = myDrawer->TextAspect(); - anAspect->SetColor (theColor); - anAspect->SetHeight (myTextHeight); - anAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT); - anAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM); - anAspect->Aspect()->SetTextZoomable (Standard_True); - anAspect->Aspect()->SetTextAngle (0.0); - anAspect->Aspect()->SetTextFontAspect (Font_FA_Regular); - Prs3d_Text::Draw (Prs3d_Root::CurrentGroup (thePresentation), anAspect, theText, gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()), Standard_False); + const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect(); + theGroup->SetPrimitivesAspect (anAspect->Aspect()); + theGroup->Text (theText, + gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()), + anAspect->Height(), + anAspect->Angle(), + anAspect->Orientation(), + Graphic3d_HTA_LEFT, + theVertAlignment, + Standard_True, + Standard_False); // has own anchor + } //======================================================================= @@ -772,7 +808,7 @@ void AIS_ColorScale::drawText (const Handle(Prs3d_Presentation)& thePresentation Standard_Integer AIS_ColorScale::TextWidth (const TCollection_ExtendedString& theText) const { Standard_Integer aWidth, anAscent, aDescent; - TextSize (theText, GetTextHeight(), aWidth, anAscent, aDescent); + TextSize (theText, myTextHeight, aWidth, anAscent, aDescent); return aWidth; } @@ -783,21 +819,34 @@ Standard_Integer AIS_ColorScale::TextWidth (const TCollection_ExtendedString& th Standard_Integer AIS_ColorScale::TextHeight (const TCollection_ExtendedString& theText) const { Standard_Integer aWidth, anAscent, aDescent; - TextSize (theText, GetTextHeight(), aWidth, anAscent, aDescent); - return anAscent+aDescent; + TextSize (theText, myTextHeight, aWidth, anAscent, aDescent); + return anAscent + aDescent; } //======================================================================= //function : TextSize //purpose : //======================================================================= -void AIS_ColorScale::TextSize (const TCollection_ExtendedString& theText, const Standard_Integer theHeight, Standard_Integer& theWidth, Standard_Integer& theAscent, Standard_Integer& theDescent) const +void AIS_ColorScale::TextSize (const TCollection_ExtendedString& theText, + const Standard_Integer theHeight, + Standard_Integer& theWidth, + Standard_Integer& theAscent, + Standard_Integer& theDescent) const { - const Handle(Graphic3d_CView)& aView = GetContext()->CurrentViewer()->ActiveViewIterator().Value()->View(); - Standard_ShortReal aWidth(10.0), anAscent(1.0), aDescent(1.0); - TCollection_AsciiString aText (theText.ToExtString(), '?'); - GetContext()->CurrentViewer()->Driver()->TextSize (aView, aText.ToCString(), (Standard_ShortReal)theHeight, aWidth, anAscent, aDescent); - theWidth = (Standard_Integer)aWidth; - theAscent = (Standard_Integer)anAscent; + if (!HasInteractiveContext()) + { + return; + } + + Standard_ShortReal aWidth = 10.0f; + Standard_ShortReal anAscent = 1.0f; + Standard_ShortReal aDescent = 1.0f; + const TCollection_AsciiString aText (theText); + + const Handle(V3d_Viewer)& aViewer = GetContext()->CurrentViewer(); + const Handle(Graphic3d_CView)& aView = aViewer->ActiveViewIterator().Value()->View(); + aViewer->Driver()->TextSize (aView, aText.ToCString(), (Standard_ShortReal)theHeight, aWidth, anAscent, aDescent); + theWidth = (Standard_Integer)aWidth; + theAscent = (Standard_Integer)anAscent; theDescent = (Standard_Integer)aDescent; } diff --git a/src/AIS/AIS_ColorScale.hxx b/src/AIS/AIS_ColorScale.hxx index ea2a146159..3dc3e4041b 100644 --- a/src/AIS/AIS_ColorScale.hxx +++ b/src/AIS/AIS_ColorScale.hxx @@ -33,8 +33,43 @@ //! Colors and labels can be either defined automatically or set by the user. //! Automatic labels are calculated from numerical limits of the scale, //! its type (logarithmic or plain), and formatted by specified format string. +class AIS_ColorScale : public AIS_InteractiveObject +{ + DEFINE_STANDARD_RTTIEXT(AIS_ColorScale, AIS_InteractiveObject) +public: -class AIS_ColorScale : public AIS_InteractiveObject { + //! Calculate color according passed value; returns true if value is in range or false, if isn't + Standard_EXPORT static Standard_Boolean FindColor (const Standard_Real theValue, + const Standard_Real theMin, + const Standard_Real theMax, + const Standard_Integer theColorsCount, + const Graphic3d_Vec3d& theColorHlsMin, + const Graphic3d_Vec3d& theColorHlsMax, + Quantity_Color& theColor); + + //! Calculate color according passed value; returns true if value is in range or false, if isn't + static Standard_Boolean FindColor (const Standard_Real theValue, + const Standard_Real theMin, + const Standard_Real theMax, + const Standard_Integer theColorsCount, + Quantity_Color& theColor) + { + return FindColor (theValue, theMin, theMax, theColorsCount, + Graphic3d_Vec3d (230.0, 1.0, 1.0), + Graphic3d_Vec3d (0.0, 1.0, 1.0), + theColor); + } + + //! Shift hue into valid range. + //! Lightness and Saturation should be specified in valid range [0.0, 1.0], + //! however Hue might be given out of Quantity_Color range to specify desired range for interpolation. + static Standard_Real hueToValidRange (const Standard_Real theHue) + { + Standard_Real aHue = theHue; + while (aHue < 0.0) { aHue += 360.0; } + while (aHue > 360.0) { aHue -= 360.0; } + return aHue; + } public: @@ -44,38 +79,111 @@ public: //! Calculate color according passed value; returns true if value is in range or false, if isn't Standard_EXPORT Standard_Boolean FindColor (const Standard_Real theValue, Quantity_Color& theColor) const; - //! Calculate color according passed value; returns true if value is in range or false, if isn't - Standard_EXPORT static Standard_Boolean FindColor (const Standard_Real theValue, const Standard_Real theMin, const Standard_Real theMax, const Standard_Integer theColorsCount, Quantity_Color& theColor); + //! Returns minimal value of color scale, 0.0 by default. + Standard_Real GetMin() const { return myMin; } - //! Returns minimal value of color scale; - Standard_EXPORT Standard_Real GetMin() const { return myMin; } + //! Sets the minimal value of color scale. + void SetMin (const Standard_Real theMin) { SetRange (theMin, GetMax()); } - //! Returns maximal value of color scale; - Standard_EXPORT Standard_Real GetMax() const { return myMax; } + //! Returns maximal value of color scale, 1.0 by default. + Standard_Real GetMax() const { return myMax; } - //! Returns minimal and maximal values of color scale; - Standard_EXPORT void GetRange (Standard_Real& theMin, Standard_Real& theMax) const; + //! Sets the maximal value of color scale. + void SetMax (const Standard_Real theMax) { SetRange (GetMin(), theMax); } - //! Returns the type of labels; + //! Returns minimal and maximal values of color scale, 0.0 to 1.0 by default. + void GetRange (Standard_Real& theMin, Standard_Real& theMax) const + { + theMin = myMin; + theMax = myMax; + } + + //! Sets the minimal and maximal value of color scale. + //! Note that values order will be ignored - the minimum and maximum values will be swapped if needed. + //! ::SetReversed() should be called to swap displaying order. + Standard_EXPORT void SetRange (const Standard_Real theMin, const Standard_Real theMax); + + //! Returns the hue angle corresponding to minimum value, 230 by default (blue). + Standard_Real HueMin() const { return myColorHlsMin[0]; } + + //! Returns the hue angle corresponding to maximum value, 0 by default (red). + Standard_Real HueMax() const { return myColorHlsMax[0]; } + + //! Returns the hue angle range corresponding to minimum and maximum values, 230 to 0 by default (blue to red). + void HueRange (Standard_Real& theMinAngle, + Standard_Real& theMaxAngle) const + { + theMinAngle = myColorHlsMin[0]; + theMaxAngle = myColorHlsMax[0]; + } + + //! Sets hue angle range corresponding to minimum and maximum values. + //! The valid angle range is [0, 360], see Quantity_Color and Quantity_TOC_HLS for more details. + void SetHueRange (const Standard_Real theMinAngle, + const Standard_Real theMaxAngle) + { + myColorHlsMin[0] = theMinAngle; + myColorHlsMax[0] = theMaxAngle; + } + + //! Returns color range corresponding to minimum and maximum values, blue to red by default. + void ColorRange (Quantity_Color& theMinColor, + Quantity_Color& theMaxColor) const + { + theMinColor.SetValues (hueToValidRange (myColorHlsMin[0]), myColorHlsMin[1], myColorHlsMin[2], Quantity_TOC_HLS); + theMaxColor.SetValues (hueToValidRange (myColorHlsMin[0]), myColorHlsMin[1], myColorHlsMin[2], Quantity_TOC_HLS); + } + + //! Sets color range corresponding to minimum and maximum values. + void SetColorRange (const Quantity_Color& theMinColor, + const Quantity_Color& theMaxColor) + { + theMinColor.Values (myColorHlsMin[0], myColorHlsMin[1], myColorHlsMin[2], Quantity_TOC_HLS); + theMaxColor.Values (myColorHlsMax[0], myColorHlsMax[1], myColorHlsMax[2], Quantity_TOC_HLS); + } + + //! Returns the type of labels, Aspect_TOCSD_AUTO by default. //! Aspect_TOCSD_AUTO - labels as boundary values for intervals //! Aspect_TOCSD_USER - user specified label is used - Standard_EXPORT Aspect_TypeOfColorScaleData GetLabelType() const { return myLabelType; } + Aspect_TypeOfColorScaleData GetLabelType() const { return myLabelType; } - //! Returns the type of colors; + //! Sets the type of labels. + //! Aspect_TOCSD_AUTO - labels as boundary values for intervals + //! Aspect_TOCSD_USER - user specified label is used + void SetLabelType (const Aspect_TypeOfColorScaleData theType) { myLabelType = theType; } + + //! Returns the type of colors, Aspect_TOCSD_AUTO by default. //! Aspect_TOCSD_AUTO - value between Red and Blue //! Aspect_TOCSD_USER - user specified color from color map - Standard_EXPORT Aspect_TypeOfColorScaleData GetColorType() const { return myColorType; } + Aspect_TypeOfColorScaleData GetColorType() const { return myColorType; } - //! Returns the number of color scale intervals; - Standard_EXPORT Standard_Integer GetNumberOfIntervals() const { return myInterval; } + //! Sets the type of colors. + //! Aspect_TOCSD_AUTO - value between Red and Blue + //! Aspect_TOCSD_USER - user specified color from color map + void SetColorType (const Aspect_TypeOfColorScaleData theType) { myColorType = theType; } - //! Returns the color scale title string; - Standard_EXPORT TCollection_ExtendedString GetTitle() const { return myTitle; } + //! Returns the number of color scale intervals, 10 by default. + Standard_Integer GetNumberOfIntervals() const { return myNbIntervals; } - //! Returns the format for numbers. + //! Sets the number of color scale intervals. + Standard_EXPORT void SetNumberOfIntervals (const Standard_Integer theNum); + + //! Returns the color scale title string, empty string by default. + const TCollection_ExtendedString& GetTitle() const { return myTitle; } + + //! Sets the color scale title string. + void SetTitle (const TCollection_ExtendedString& theTitle) { myTitle = theTitle; } + + //! Returns the format for numbers, "%.4g" by default. //! The same like format for function printf(). //! Used if GetLabelType() is TOCSD_AUTO; - Standard_EXPORT TCollection_AsciiString GetFormat() const { return myFormat; } + const TCollection_AsciiString& GetFormat() const { return myFormat; } + + //! Returns the format of text. + const TCollection_AsciiString& Format() const { return myFormat; } + + //! Sets the color scale auto label format specification. + void SetFormat (const TCollection_AsciiString& theFormat) { myFormat = theFormat; } //! Returns the user specified label with index theIndex. //! Index is in range from 1 to GetNumberOfIntervals() or to @@ -83,134 +191,154 @@ public: //! Returns empty string if label not defined. Standard_EXPORT TCollection_ExtendedString GetLabel (const Standard_Integer theIndex) const; - //! Returns the user specified color from color map with index (starts at 1). + //! Returns the user specified color from color map with index (starts at 1). //! Returns default color if index is out of range in color map. Standard_EXPORT Quantity_Color GetIntervalColor (const Standard_Integer theIndex) const; + //! Sets the color of the specified interval. + //! Note that list is automatically resized to include specified index. + //! @param theColor color value to set + //! @param theIndex index in range [1, GetNumberOfIntervals()]; + //! appended to the end of list if -1 is specified + Standard_EXPORT void SetIntervalColor (const Quantity_Color& theColor, const Standard_Integer theIndex); + //! Returns the user specified labels. Standard_EXPORT void GetLabels (TColStd_SequenceOfExtendedString& theLabels) const; + //! Returns the user specified labels. + const TColStd_SequenceOfExtendedString& Labels() const { return myLabels; } + + //! Sets the color scale labels. + //! The length of the sequence should be equal to GetNumberOfIntervals() or to GetNumberOfIntervals() + 1 if IsLabelAtBorder() is true. + //! If length of the sequence does not much the number of intervals, + //! then these labels will be considered as "free" and will be located + //! at the virtual intervals corresponding to the number of labels + //! (with flag IsLabelAtBorder() having the same effect as in normal case). + Standard_EXPORT void SetLabels (const TColStd_SequenceOfExtendedString& theSeq); + //! Returns the user specified colors. Standard_EXPORT void GetColors (Aspect_SequenceOfColor& theColors) const; - //! Returns the position of labels concerning color filled rectangles. - Standard_EXPORT Aspect_TypeOfColorScalePosition GetLabelPosition() const { return myLabelPos; } - - //! Returns the position of color scale title. - Standard_EXPORT Aspect_TypeOfColorScalePosition GetTitlePosition() const { return myTitlePos; } - - //! Returns true if the labels and colors used in reversed order. - Standard_EXPORT Standard_Boolean IsReversed() const { return myReversed; } - - //! Returns true if the labels are placed at border of color intervals. - Standard_EXPORT Standard_Boolean IsLabelAtBorder() const { return myAtBorder; } - - //! Returns true if the color scale has logarithmic intervals - Standard_Boolean IsLogarithmic() const { return myIsLogarithmic; } - - //! Sets the minimal value of color scale. - Standard_EXPORT void SetMin (const Standard_Real theMin); - - //! Sets the maximal value of color scale. - Standard_EXPORT void SetMax (const Standard_Real theMax); - - //! Sets the minimal and maximal value of color scale. - Standard_EXPORT void SetRange (const Standard_Real theMin, const Standard_Real theMax); - - //! Sets the type of labels. - //! Aspect_TOCSD_AUTO - labels as boundary values for intervals - //! Aspect_TOCSD_USER - user specified label is used - Standard_EXPORT void SetLabelType (const Aspect_TypeOfColorScaleData theType); - - //! Sets the type of colors. - //! Aspect_TOCSD_AUTO - value between Red and Blue - //! Aspect_TOCSD_USER - user specified color from color map - Standard_EXPORT void SetColorType (const Aspect_TypeOfColorScaleData theType); - - //! Sets the number of color scale intervals. - Standard_EXPORT void SetNumberOfIntervals (const Standard_Integer theNum); - - //! Sets the color scale title string. - Standard_EXPORT void SetTitle (const TCollection_ExtendedString& theTitle); - - //! Sets the color scale auto label format specification. - Standard_EXPORT void SetFormat (const TCollection_AsciiString& theFormat); - - //! Sets the color scale label at index. - //! Index is in range from 1 to GetNumberOfIntervals() or to - //! GetNumberOfIntervals() + 1 if IsLabelAtBorder() is true. - Standard_EXPORT void SetLabel (const TCollection_ExtendedString& theLabel, const Standard_Integer anIndex); - - //! Sets the color of the specified interval. - //! Index is in range from 1 to GetNumberOfIntervals(). - Standard_EXPORT void SetIntervalColor (const Quantity_Color& theColor, const Standard_Integer theIndex); - - //! Sets the color scale labels. - //! The length of the sequence should be equal to GetNumberOfIntervals() or to - //! GetNumberOfIntervals() + 1 if IsLabelAtBorder() is true. - Standard_EXPORT void SetLabels (const TColStd_SequenceOfExtendedString& theSeq); + //! Returns the user specified colors. + const Aspect_SequenceOfColor& GetColors() const { return myColors; } //! Sets the color scale colors. //! The length of the sequence should be equal to GetNumberOfIntervals(). Standard_EXPORT void SetColors (const Aspect_SequenceOfColor& theSeq); + //! Returns the position of labels concerning color filled rectangles, Aspect_TOCSP_RIGHT by default. + Aspect_TypeOfColorScalePosition GetLabelPosition() const { return myLabelPos; } + //! Sets the color scale labels position relative to color bar. - Standard_EXPORT void SetLabelPosition (const Aspect_TypeOfColorScalePosition thePos); + void SetLabelPosition (const Aspect_TypeOfColorScalePosition thePos) { myLabelPos = thePos; } + + //! Returns the position of color scale title, Aspect_TOCSP_LEFT by default. + Aspect_TypeOfColorScalePosition GetTitlePosition() const { return myTitlePos; } //! Sets the color scale title position. - Standard_EXPORT void SetTitlePosition (const Aspect_TypeOfColorScalePosition thePos); + Standard_DEPRECATED("AIS_ColorScale::SetTitlePosition() has no effect!") + void SetTitlePosition (const Aspect_TypeOfColorScalePosition thePos) { myTitlePos = thePos; } + + //! Returns TRUE if the labels and colors used in reversed order, FALSE by default. + //! - Normal, bottom-up order with Minimal value on the Bottom and Maximum value on Top. + //! - Reversed, top-down order with Maximum value on the Bottom and Minimum value on Top. + Standard_Boolean IsReversed() const { return myIsReversed; } //! Sets true if the labels and colors used in reversed order. - Standard_EXPORT void SetReversed (const Standard_Boolean theReverse); + void SetReversed (const Standard_Boolean theReverse) { myIsReversed = theReverse; } - //! Sets true if the labels are placed at border of color intervals (true by default). + //! Return TRUE if color transition between neighbor intervals + //! should be linearly interpolated, FALSE by default. + Standard_Boolean IsSmoothTransition() const { return myIsSmooth; } + + //! Setup smooth color transition. + void SetSmoothTransition (const Standard_Boolean theIsSmooth) { myIsSmooth = theIsSmooth; } + + //! Returns TRUE if the labels are placed at border of color intervals, TRUE by default. + //! The automatically generated label will show value exactly on the current position: + //! - value connecting two neighbor intervals (TRUE) + //! - value in the middle of interval (FALSE) + Standard_Boolean IsLabelAtBorder() const { return myIsLabelAtBorder; } + + //! Sets true if the labels are placed at border of color intervals (TRUE by default). //! If set to False, labels will be drawn at color intervals rather than at borders. - Standard_EXPORT void SetLabelAtBorder (const Standard_Boolean theOn); + void SetLabelAtBorder (const Standard_Boolean theOn) { myIsLabelAtBorder = theOn; } + + //! Returns TRUE if the color scale has logarithmic intervals, FALSE by default. + Standard_Boolean IsLogarithmic() const { return myIsLogarithmic; } //! Sets true if the color scale has logarithmic intervals. - void SetLogarithmic (const Standard_Boolean isLogarithmic) { myIsLogarithmic = isLogarithmic; }; + void SetLogarithmic (const Standard_Boolean isLogarithmic) { myIsLogarithmic = isLogarithmic; } - //! Returns the size of color bar. - Standard_EXPORT void GetSize (Standard_Integer& theBreadth, Standard_Integer& theHeight) const; + //! Sets the color scale label at index. + //! Note that list is automatically resized to include specified index. + //! @param theLabel new label text + //! @param theIndex index in range [1, GetNumberOfIntervals()] or [1, GetNumberOfIntervals() + 1] if IsLabelAtBorder() is true; + //! label is appended to the end of list if negative index is specified + Standard_EXPORT void SetLabel (const TCollection_ExtendedString& theLabel, const Standard_Integer theIndex); - //! Returns the breadth of color bar. - Standard_EXPORT Standard_Integer GetBreadth() const { return myBreadth; } - - //! Returns the height of color bar. - Standard_EXPORT Standard_Integer GetHeight() const { return myHeight; } + //! Returns the size of color bar, 0 and 0 by default + //! (e.g. should be set by user explicitly before displaying). + void GetSize (Standard_Integer& theBreadth, Standard_Integer& theHeight) const + { + theBreadth = myBreadth; + theHeight = myHeight; + } //! Sets the size of color bar. - Standard_EXPORT void SetSize (const Standard_Integer theWidth, const Standard_Integer theHeight); + void SetSize (const Standard_Integer theBreadth, const Standard_Integer theHeight) + { + myBreadth = theBreadth; + myHeight = theHeight; + } + + //! Returns the breadth of color bar, 0 by default + //! (e.g. should be set by user explicitly before displaying). + Standard_Integer GetBreadth() const { return myBreadth; } //! Sets the width of color bar. - Standard_EXPORT void SetBreadth (const Standard_Integer theBreadth); + void SetBreadth (const Standard_Integer theBreadth) { myBreadth = theBreadth; } + + //! Returns the height of color bar, 0 by default + //! (e.g. should be set by user explicitly before displaying). + Standard_Integer GetHeight() const { return myHeight; } //! Sets the height of color bar. - Standard_EXPORT void SetHeight (const Standard_Integer theHeight); + void SetHeight (const Standard_Integer theHeight) { myHeight = theHeight; } - //! Returns the position of color scale. - Standard_EXPORT void GetPosition (Standard_Real& theX, Standard_Real& theY) const; - - //! Returns the X position of color scale. - Standard_EXPORT Standard_Integer GetXPosition() const { return myXPos; } - - //! Returns the height of color scale. - Standard_EXPORT Standard_Integer GetYPosition() const { return myYPos; } + //! Returns the bottom-left position of color scale, 0x0 by default. + void GetPosition (Standard_Real& theX, Standard_Real& theY) const + { + theX = myXPos; + theY = myYPos; + } //! Sets the position of color scale. - Standard_EXPORT void SetPosition (const Standard_Integer theX, const Standard_Integer theY); + void SetPosition (const Standard_Integer theX, const Standard_Integer theY) + { + myXPos = theX; + myYPos = theY; + } - //! Sets the X position of color scale. - Standard_EXPORT void SetXPosition (const Standard_Integer theX); + //! Returns the left position of color scale, 0 by default. + Standard_Integer GetXPosition() const { return myXPos; } - //! Sets the Y position of color scale. - Standard_EXPORT void SetYPosition (const Standard_Integer theY); + //! Sets the left position of color scale. + void SetXPosition (const Standard_Integer theX) { myXPos = theX; } - //! Returns the height of text of color scale. - Standard_EXPORT Standard_Integer GetTextHeight() const { return myTextHeight; } + //! Returns the bottom position of color scale, 0 by default. + Standard_Integer GetYPosition() const { return myYPos; } + + //! Sets the bottom position of color scale. + void SetYPosition (const Standard_Integer theY) { myYPos = theY; } + + //! Returns the font height of text labels, 20 by default. + Standard_Integer GetTextHeight() const { return myTextHeight; } //! Sets the height of text of color scale. - Standard_EXPORT void SetTextHeight (const Standard_Integer theHeight) { myTextHeight = theHeight; } + void SetTextHeight (const Standard_Integer theHeight) { myTextHeight = theHeight; } + +public: //! Returns the width of text. //! @param theText [in] the text of which to calculate width. @@ -220,33 +348,25 @@ public: //! @param theText [in] the text of which to calculate height. Standard_EXPORT Standard_Integer TextHeight (const TCollection_ExtendedString& theText) const; - Standard_EXPORT void TextSize (const TCollection_ExtendedString& theText, const Standard_Integer theHeight, Standard_Integer& theWidth, Standard_Integer& theAscent, Standard_Integer& theDescent) const; + Standard_EXPORT void TextSize (const TCollection_ExtendedString& theText, + const Standard_Integer theHeight, + Standard_Integer& theWidth, + Standard_Integer& theAscent, + Standard_Integer& theDescent) const; +public: - DEFINE_STANDARD_RTTIEXT(AIS_ColorScale,AIS_InteractiveObject) + //! Return true if specified display mode is supported. + virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; } -protected: + //! Compute presentation. + Standard_EXPORT virtual void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, + const Handle(Prs3d_Presentation)& thePresentation, + const Standard_Integer theMode) Standard_OVERRIDE; - //! Draws a frame. - //! @param theX [in] the X coordinate of frame position. - //! @param theY [in] the Y coordinate of frame position. - //! @param theWidth [in] the width of frame. - //! @param theHeight [in] the height of frame. - //! @param theColor [in] the color of frame. - Standard_EXPORT void drawFrame (const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theX, const Standard_Integer theY, - const Standard_Integer theWidth, const Standard_Integer theHeight, - const Quantity_Color& theColor); - - //! Draws a text. - //! @param theText [in] the text to draw. - //! @param theX [in] the X coordinate of text position. - //! @param theY [in] the Y coordinate of text position. - //! @param theColor [in] the color of text. - Standard_EXPORT void drawText (const Handle(Prs3d_Presentation)& thePresentation, - const TCollection_ExtendedString& theText, - const Standard_Integer theX, const Standard_Integer theY, - const Quantity_Color& theColor); + //! Compute selection - not implemented for color scale. + virtual void ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/, + const Standard_Integer /*aMode*/) Standard_OVERRIDE {} private: @@ -255,47 +375,86 @@ private: //! @param theHeight [out] the height of color scale. void SizeHint (Standard_Integer& theWidth, Standard_Integer& theHeight) const; - void Compute (const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, - const Handle(Prs3d_Presentation)& thePresentation, - const Standard_Integer theMode) Standard_OVERRIDE; - - void ComputeSelection (const Handle(SelectMgr_Selection)& /*aSelection*/, - const Standard_Integer /*aMode*/) Standard_OVERRIDE - {} - - //! Returns the format of text. - TCollection_AsciiString Format() const; - //! Returns the upper value of given interval, or minimum for theIndex = 0. Standard_Real GetIntervalValue (const Standard_Integer theIndex) const; - //! Returns the color's hue for the given value in the given interval. - //! @param theValue [in] the current value of interval. - //! @param theMin [in] the min value of interval. - //! @param theMax [in] the max value of interval. - static Standard_Integer HueFromValue (const Standard_Integer theValue, const Standard_Integer theMin, const Standard_Integer theMax); + //! Returns the color for the given value in the given interval. + //! @param theValue [in] the current value of interval + //! @param theMin [in] the min value of interval + //! @param theMax [in] the max value of interval + Quantity_Color colorFromValue (const Standard_Real theValue, + const Standard_Real theMin, + const Standard_Real theMax) const; + + //! Initialize text aspect for drawing the labels. + void updateTextAspect(); + + //! Simple alias for Prs3d_Text::Draw(). + //! @param theGroup [in] presentation group + //! @param theText [in] text to draw + //! @param theX [in] X coordinate of text position + //! @param theY [in] Y coordinate of text position + //! @param theVertAlignment [in] text vertical alignment + void drawText (const Handle(Graphic3d_Group)& theGroup, + const TCollection_ExtendedString& theText, + const Standard_Integer theX, const Standard_Integer theY, + const Graphic3d_VerticalTextAlignment theVertAlignment); + + //! Determine the maximum text label width in pixels. + Standard_Integer computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const; + + //! Draw labels. + void drawLabels (const Handle(Prs3d_Presentation)& thePrs, + const TColStd_SequenceOfExtendedString& theLabels, + const Standard_Integer theBarBottom, + const Standard_Integer theBarHeight, + const Standard_Integer theMaxLabelWidth, + const Standard_Integer theColorBreadth); + + //! Draw a color bar. + void drawColorBar (const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theBarBottom, + const Standard_Integer theBarHeight, + const Standard_Integer theMaxLabelWidth, + const Standard_Integer theColorBreadth); + + //! Draw a frame. + //! @param theX [in] the X coordinate of frame position. + //! @param theY [in] the Y coordinate of frame position. + //! @param theWidth [in] the width of frame. + //! @param theHeight [in] the height of frame. + //! @param theColor [in] the color of frame. + void drawFrame (const Handle(Prs3d_Presentation)& thePrs, + const Standard_Integer theX, const Standard_Integer theY, + const Standard_Integer theWidth, const Standard_Integer theHeight, + const Quantity_Color& theColor); private: - Standard_Real myMin; - Standard_Real myMax; - TCollection_ExtendedString myTitle; - TCollection_AsciiString myFormat; - Standard_Integer myInterval; //! Number of intervals - Aspect_TypeOfColorScaleData myColorType; - Aspect_TypeOfColorScaleData myLabelType; - Standard_Boolean myAtBorder; - Standard_Boolean myReversed; - Standard_Boolean myIsLogarithmic; - Aspect_SequenceOfColor myColors; //! Sequence of custom colors - TColStd_SequenceOfExtendedString myLabels; - Aspect_TypeOfColorScalePosition myLabelPos; - Aspect_TypeOfColorScalePosition myTitlePos; - Standard_Integer myXPos; - Standard_Integer myYPos; - Standard_Integer myBreadth; - Standard_Integer myHeight; - Standard_Integer myTextHeight; - Quantity_Color myBgColor; + Standard_Real myMin; //!< values range - minimal value + Standard_Real myMax; //!< values range - maximal value + Graphic3d_Vec3d myColorHlsMin; //!< HLS color corresponding to minimum value + Graphic3d_Vec3d myColorHlsMax; //!< HLS color corresponding to maximum value + TCollection_ExtendedString myTitle; //!< optional title string + TCollection_AsciiString myFormat; //!< sprintf() format for generating label from value + Standard_Integer myNbIntervals; //!< number of intervals + Aspect_TypeOfColorScaleData myColorType; //!< color type + Aspect_TypeOfColorScaleData myLabelType; //!< label type + Standard_Boolean myIsLabelAtBorder; //!< at border + Standard_Boolean myIsReversed; //!< flag indicating reversed order + Standard_Boolean myIsLogarithmic; //!< flag indicating logarithmic scale + Standard_Boolean myIsSmooth; //!< flag indicating smooth transition between the colors + Aspect_SequenceOfColor myColors; //!< sequence of custom colors + TColStd_SequenceOfExtendedString myLabels; //!< sequence of custom text labels + Aspect_TypeOfColorScalePosition myLabelPos; //!< label position relative to the color scale + Aspect_TypeOfColorScalePosition myTitlePos; //!< title position + Standard_Integer myXPos; //!< left position + Standard_Integer myYPos; //!< bottom position + Standard_Integer myBreadth; //!< color scale breadth + Standard_Integer myHeight; //!< height of the color scale + Standard_Integer mySpacing; //!< extra spacing between element + Standard_Integer myTextHeight; //!< label font height + }; + #endif diff --git a/src/ViewerTest/ViewerTest_ViewerCommands.cxx b/src/ViewerTest/ViewerTest_ViewerCommands.cxx index 4f2bd01db8..d4a1ec3f4a 100644 --- a/src/ViewerTest/ViewerTest_ViewerCommands.cxx +++ b/src/ViewerTest/ViewerTest_ViewerCommands.cxx @@ -3428,38 +3428,6 @@ static int VExport(Draw_Interpretor& di, Standard_Integer argc, const char** arg return 0; } -//============================================================================== -//function : VColorScale -//purpose : representation color scale -//============================================================================== - -static Standard_Boolean checkColor (const TCollection_AsciiString& theRed, - const TCollection_AsciiString& theGreen, - const TCollection_AsciiString& theBlue, - Standard_Real& theRedValue, - Standard_Real& theGreenValue, - Standard_Real& theBlueValue) -{ - if (!theRed.IsRealValue() - || !theGreen.IsRealValue() - || !theBlue.IsRealValue()) - { - std::cout << "Error: RGB color values should be real!\n"; - return Standard_True; - } - theRedValue = theRed .RealValue(); - theGreenValue = theGreen.RealValue(); - theBlueValue = theBlue .RealValue(); - if (theRedValue < 0.0 || theRedValue > 1.0 - || theGreenValue < 0.0 || theGreenValue > 1.0 - || theBlueValue < 0.0 || theBlueValue > 1.0) - { - std::cout << "Error: RGB color values should be within range 0..1!\n"; - return Standard_True; - } - return Standard_False; -} - static int VColorScale (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) @@ -3477,57 +3445,35 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - Handle(AIS_ColorScale) aCS; - // find object - Handle(AIS_InteractiveObject) anIObj; + Handle(AIS_ColorScale) aColorScale; if (GetMapOfAIS().IsBound2 (theArgVec[1])) { - aCS = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1])); - if (aCS.IsNull()) + // find existing object + aColorScale = Handle(AIS_ColorScale)::DownCast (GetMapOfAIS().Find2 (theArgVec[1])); + if (aColorScale.IsNull()) { std::cout << "Error: object '" << theArgVec[1] << "'is already defined and is not a color scale!\n"; return 1; } } - else - { - aCS = new AIS_ColorScale(); - GetMapOfAIS().Bind (aCS,theArgVec[1]); - } - - if (aCS->ZLayer() != Graphic3d_ZLayerId_TopOSD) - { - aCS->SetZLayer (Graphic3d_ZLayerId_TopOSD); - } - if (aCS->TransformPersistence().IsNull() - || aCS->TransformPersistence()->Mode() != Graphic3d_TMF_2d) - { - aContext->SetTransformPersistence (aCS, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER)); - } - - Standard_Real aMinRange = aCS->GetMin(); - Standard_Real aMaxRange = aCS->GetMax(); - Standard_Integer aBreadth = aCS->GetBreadth(); - Standard_Integer aHeight = aCS->GetHeight(); - Standard_Integer aNbIntervals = aCS->GetNumberOfIntervals(); - Standard_Integer aTextHeight = aCS->GetTextHeight(); - Aspect_TypeOfColorScalePosition aLabPosition = aCS->GetLabelPosition(); - Standard_Integer aPosX = aCS->GetXPosition(); - Standard_Integer aPosY = aCS->GetYPosition(); - - ViewerTest_AutoUpdater anUpdateTool (aContext, aView); if (theArgNb <= 2) { + if (aColorScale.IsNull()) + { + std::cout << "Syntax error: colorscale with a given name does not exist.\n"; + return 1; + } + theDI << "Color scale parameters for '"<< theArgVec[1] << "':\n" - << "Min range: " << aMinRange << "\n" - << "Max range: " << aMaxRange << "\n" - << "Number of intervals: " << aNbIntervals << "\n" - << "Text height: " << aTextHeight << "\n" - << "Color scale position: " << aPosX <<" "<< aPosY<< "\n" - << "Color scale title: " << aCS->GetTitle() << "\n" + << "Min range: " << aColorScale->GetMin() << "\n" + << "Max range: " << aColorScale->GetMax() << "\n" + << "Number of intervals: " << aColorScale->GetNumberOfIntervals() << "\n" + << "Text height: " << aColorScale->GetTextHeight() << "\n" + << "Color scale position: " << aColorScale->GetXPosition() << " " << aColorScale->GetYPosition() << "\n" + << "Color scale title: " << aColorScale->GetTitle() << "\n" << "Label position: "; - switch (aLabPosition) + switch (aColorScale->GetLabelPosition()) { case Aspect_TOCSP_NONE: theDI << "None\n"; @@ -3545,6 +3491,14 @@ static int VColorScale (Draw_Interpretor& theDI, return 0; } + if (aColorScale.IsNull()) + { + aColorScale = new AIS_ColorScale(); + aColorScale->SetZLayer (Graphic3d_ZLayerId_TopOSD); + aContext->SetTransformPersistence (aColorScale, new Graphic3d_TransformPers (Graphic3d_TMF_2d, Aspect_TOTP_LEFT_LOWER)); + } + + ViewerTest_AutoUpdater anUpdateTool (aContext, aView); for (Standard_Integer anArgIter = 2; anArgIter < theArgNb; ++anArgIter) { Standard_CString anArg = theArgVec[anArgIter]; @@ -3562,28 +3516,23 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - TCollection_AsciiString anArg1 (theArgVec[++anArgIter]); - TCollection_AsciiString anArg2 (theArgVec[++anArgIter]); - TCollection_AsciiString anArg3 (theArgVec[++anArgIter]); - if (!anArg1.IsRealValue()) + const TCollection_AsciiString aRangeMin (theArgVec[++anArgIter]); + const TCollection_AsciiString aRangeMax (theArgVec[++anArgIter]); + const TCollection_AsciiString aNbIntervals (theArgVec[++anArgIter]); + if (!aRangeMin.IsRealValue() + || !aRangeMax.IsRealValue()) { - std::cout << "Error: the minRange value should be real!\n"; + std::cout << "Error: the range values should be real!\n"; return 1; } - else if (!anArg2.IsRealValue()) - { - std::cout << "Error: the maxRange value should be real!\n"; - return 1; - } - else if (!anArg3.IsIntegerValue()) + else if (!aNbIntervals.IsIntegerValue()) { std::cout << "Error: the number of intervals should be integer!\n"; return 1; } - aMinRange = anArg1.RealValue(); - aMaxRange = anArg2.RealValue(); - aNbIntervals = anArg3.IntegerValue(); + aColorScale->SetRange (aRangeMin.RealValue(), aRangeMax.RealValue()); + aColorScale->SetNumberOfIntervals (aNbIntervals.IntegerValue()); } else if (aFlag == "-font") { @@ -3599,7 +3548,7 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - aTextHeight = aFontArg.IntegerValue(); + aColorScale->SetTextHeight (aFontArg.IntegerValue()); anArgIter += 1; } else if (aFlag == "-textpos") @@ -3609,8 +3558,10 @@ static int VColorScale (Draw_Interpretor& theDI, std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; return 1; } + TCollection_AsciiString aTextPosArg(theArgVec[++anArgIter]); aTextPosArg.LowerCase(); + Aspect_TypeOfColorScalePosition aLabPosition = Aspect_TOCSP_NONE; if (aTextPosArg == "none") { aLabPosition = Aspect_TOCSP_NONE; @@ -3632,6 +3583,7 @@ static int VColorScale (Draw_Interpretor& theDI, std::cout << "Error: unknown position '" << aTextPosArg << "'!\n"; return 1; } + aColorScale->SetLabelPosition (aLabPosition); } else if (aFlag == "-logarithmic" || aFlag == "-log") @@ -3641,13 +3593,71 @@ static int VColorScale (Draw_Interpretor& theDI, std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; return 1; } + Standard_Boolean IsLog; if (!ViewerTest::ParseOnOff(theArgVec[++anArgIter], IsLog)) { std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; return 1; } - aCS->SetLogarithmic (IsLog); + aColorScale->SetLogarithmic (IsLog); + } + else if (aFlag == "-huerange" + || aFlag == "-hue") + { + if (anArgIter + 2 >= theArgNb) + { + std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; + return 1; + } + + const Standard_Real aHueMin = Draw::Atof (theArgVec[++anArgIter]); + const Standard_Real aHueMax = Draw::Atof (theArgVec[++anArgIter]); + aColorScale->SetHueRange (aHueMin, aHueMax); + } + else if (aFlag == "-colorrange") + { + Quantity_Color aColorMin, aColorMax; + Standard_Integer aNbParsed1 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1), + theArgVec + (anArgIter + 1), + aColorMin); + anArgIter += aNbParsed1; + Standard_Integer aNbParsed2 = ViewerTest::ParseColor (theArgNb - (anArgIter + 1), + theArgVec + (anArgIter + 1), + aColorMax); + anArgIter += aNbParsed2; + if (aNbParsed1 == 0 + || aNbParsed2 == 0) + { + std::cerr << "Error: wrong syntax at '" << anArg << "'\n"; + return 1; + } + + aColorScale->SetColorRange (aColorMin, aColorMax); + } + else if (aFlag == "-reversed" + || aFlag == "-inverted" + || aFlag == "-topdown" + || aFlag == "-bottomup") + { + Standard_Boolean toEnable = Standard_True; + if (anArgIter + 1 < theArgNb + && ViewerTest::ParseOnOff(theArgVec[anArgIter + 1], toEnable)) + { + ++anArgIter; + } + aColorScale->SetReversed ((aFlag == "-topdown") ? !toEnable : toEnable); + } + else if (aFlag == "-smooth" + || aFlag == "-smoothtransition") + { + Standard_Boolean toEnable = Standard_True; + if (anArgIter + 1 < theArgNb + && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable)) + { + ++anArgIter; + } + aColorScale->SetSmoothTransition (toEnable); } else if (aFlag == "-xy") { @@ -3657,20 +3667,20 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - TCollection_AsciiString aX (theArgVec[++anArgIter]); - TCollection_AsciiString aY (theArgVec[++anArgIter]); - if (!aX.IsIntegerValue() - || !aY.IsIntegerValue()) + const TCollection_AsciiString anX (theArgVec[++anArgIter]); + const TCollection_AsciiString anY (theArgVec[++anArgIter]); + if (!anX.IsIntegerValue() + || !anY.IsIntegerValue()) { std::cout << "Error: coordinates should be integer values!\n"; return 1; } - aPosX = aX.IntegerValue(); - aPosY = aY.IntegerValue(); + aColorScale->SetPosition (anX.IntegerValue(), anY.IntegerValue()); } else if (aFlag == "-width" - || aFlag == "-w") + || aFlag == "-w" + || aFlag == "-breadth") { if (anArgIter + 1 >= theArgNb) { @@ -3678,14 +3688,13 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - TCollection_AsciiString aW (theArgVec[++anArgIter]); - if (!aW.IsIntegerValue()) + const TCollection_AsciiString aBreadth (theArgVec[++anArgIter]); + if (!aBreadth.IsIntegerValue()) { std::cout << "Error: a width should be an integer value!\n"; return 1; } - - aBreadth = aW.IntegerValue(); + aColorScale->SetBreadth (aBreadth.IntegerValue()); } else if (aFlag == "-height" || aFlag == "-h") @@ -3696,75 +3705,56 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } - TCollection_AsciiString aH (theArgVec[++anArgIter]); - if (!aH.IsIntegerValue()) + const TCollection_AsciiString aHeight (theArgVec[++anArgIter]); + if (!aHeight.IsIntegerValue()) { std::cout << "Error: a width should be an integer value!\n"; return 1; } - - aHeight = aH.IntegerValue(); + aColorScale->SetHeight (aHeight.IntegerValue()); } else if (aFlag == "-color") { - if (aCS->GetColorType() != Aspect_TOCSD_USER) + if (aColorScale->GetColorType() != Aspect_TOCSD_USER) { std::cout << "Error: wrong color type! Call -colors before to set user-specified colors!\n"; return 1; } - - Quantity_NameOfColor aColorName; - if (anArgIter + 4 >= theArgNb) + else if (anArgIter + 2 >= theArgNb) { - if (anArgIter + 2 >= theArgNb) - { - std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; - return 1; - } - else if (!Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName)) - { - std::cout << "Error: wrong color name: '" << theArgVec[anArgIter + 2] << "' !\n"; - return 1; - } + std::cout << "Error: wrong syntax at argument '" << anArg << "'!\n"; + return 1; } - TCollection_AsciiString anInd (theArgVec[anArgIter + 1]); + const TCollection_AsciiString anInd (theArgVec[++anArgIter]); if (!anInd.IsIntegerValue()) { std::cout << "Error: Index value should be integer!\n"; return 1; } - - Standard_Integer anIndex = anInd.IntegerValue(); - if (anIndex <= 0 || anIndex > aNbIntervals) + const Standard_Integer anIndex = anInd.IntegerValue(); + if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals()) { - std::cout << "Error: Index value should be within range 1.." << aNbIntervals <<"!\n"; + std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() <<"!\n"; return 1; } - if (Quantity_Color::ColorFromName (theArgVec[anArgIter + 2], aColorName)) - { - aCS->SetIntervalColor (Quantity_Color (aColorName), anIndex); - aCS->SetColorType (Aspect_TOCSD_USER); - anArgIter += 2; - continue; - } - - TCollection_AsciiString aRed (theArgVec[anArgIter + 2]); - TCollection_AsciiString aGreen (theArgVec[anArgIter + 3]); - TCollection_AsciiString aBlue (theArgVec[anArgIter + 4]); - Standard_Real aRedValue,aGreenValue, aBlueValue; - if(checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue)) + Quantity_Color aColor; + Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1), + theArgVec + (anArgIter + 1), + aColor); + if (aNbParsed == 0) { + std::cerr << "Error: wrong syntax at '" << anArg << "'\n"; return 1; } - aCS->SetIntervalColor (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB), anIndex); - aCS->SetColorType (Aspect_TOCSD_USER); - anArgIter += 4; + aColorScale->SetIntervalColor (aColor, anIndex); + aColorScale->SetColorType (Aspect_TOCSD_USER); + anArgIter += aNbParsed; } else if (aFlag == "-label") { - if (aCS->GetColorType() != Aspect_TOCSD_USER) + if (aColorScale->GetColorType() != Aspect_TOCSD_USER) { std::cout << "Error: wrong label type! Call -labels before to set user-specified labels!\n"; return 1; @@ -3776,90 +3766,115 @@ static int VColorScale (Draw_Interpretor& theDI, } Standard_Integer anIndex = Draw::Atoi (theArgVec[anArgIter + 1]); - if (anIndex <= 0 || anIndex > aNbIntervals+1) + if (anIndex <= 0 || anIndex > aColorScale->GetNumberOfIntervals() + 1) { - std::cout << "Error: Index value should be within range 1.." << aNbIntervals+1 <<"!\n"; + std::cout << "Error: Index value should be within range 1.." << aColorScale->GetNumberOfIntervals() + 1 <<"!\n"; return 1; } TCollection_ExtendedString aText (theArgVec[anArgIter + 2]); - aCS->SetLabel (aText, anIndex); - aCS->SetLabelType (Aspect_TOCSD_USER); + aColorScale->SetLabel (aText, anIndex); + aColorScale->SetLabelType (Aspect_TOCSD_USER); anArgIter += 2; } + else if (aFlag == "-labelat" + || aFlag == "-labat" + || aFlag == "-labelatborder" + || aFlag == "-labatborder" + || aFlag == "-labelatcenter" + || aFlag == "-labatcenter") + { + Standard_Boolean toEnable = Standard_True; + if (aFlag == "-labelat" + || aFlag == "-labat") + { + Standard_Integer aLabAtBorder = -1; + if (++anArgIter >= theArgNb) + { + TCollection_AsciiString anAtBorder (theArgVec[anArgIter]); + anAtBorder.LowerCase(); + if (anAtBorder == "border") + { + aLabAtBorder = 1; + } + else if (anAtBorder == "center") + { + aLabAtBorder = 0; + } + } + if (aLabAtBorder == -1) + { + std::cout << "Syntax error at argument '" << anArg << "'!\n"; + return 1; + } + toEnable = (aLabAtBorder == 1); + } + else if (anArgIter + 1 < theArgNb + && ViewerTest::ParseOnOff (theArgVec[anArgIter + 1], toEnable)) + { + ++anArgIter; + } + aColorScale->SetLabelAtBorder (aFlag == "-labelatcenter" + || aFlag == "-labatcenter" + ? !toEnable + : toEnable); + } else if (aFlag == "-colors") { Aspect_SequenceOfColor aSeq; - if (anArgIter + aNbIntervals + 1 > theArgNb) + for (;;) { - std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the " - << aNbIntervals << " intervals\n"; - return 1; - } - - Standard_Integer aColorIter = anArgIter + 1; - while (aColorIter < theArgNb) - { - if (theArgVec[aColorIter][0] == '-') + Quantity_Color aColor; + Standard_Integer aNbParsed = ViewerTest::ParseColor (theArgNb - (anArgIter + 1), + theArgVec + (anArgIter + 1), + aColor); + if (aNbParsed == 0) { break; } - - else if (theArgVec[aColorIter][0] >= 97 - && theArgVec[aColorIter][0] <= 122) - { - Quantity_NameOfColor aColorName; - if (!Quantity_Color::ColorFromName (theArgVec[aColorIter], aColorName)) - { - std::cout << "Error: wrong color name: " << theArgVec[aColorIter] << " !\n"; - return 1; - } - aSeq.Append (Quantity_Color (aColorName)); - aColorIter++; - anArgIter++; - } - else - { - TCollection_AsciiString aRed (theArgVec[aColorIter]); - TCollection_AsciiString aGreen (theArgVec[aColorIter + 1]); - TCollection_AsciiString aBlue (theArgVec[aColorIter + 2]); - Standard_Real aRedValue,aGreenValue, aBlueValue; - if (checkColor (aRed, aGreen, aBlue, aRedValue, aGreenValue, aBlueValue)) - { - return 1; - } - aSeq.Append (Quantity_Color (aRedValue, aGreenValue, aBlueValue, Quantity_TOC_RGB)); - aColorIter += 3; - anArgIter += 3; - } + anArgIter += aNbParsed; + aSeq.Append (aColor); } - if (aSeq.Length() < aNbIntervals) + if (aSeq.Length() != aColorScale->GetNumberOfIntervals()) { std::cout << "Error: not enough arguments! You should provide color names or RGB color values for every interval of the " - << aNbIntervals << " intervals\n"; + << aColorScale->GetNumberOfIntervals() << " intervals\n"; return 1; } - aCS->SetColors (aSeq); - aCS->SetColorType (Aspect_TOCSD_USER); + aColorScale->SetColors (aSeq); + aColorScale->SetColorType (Aspect_TOCSD_USER); } - else if (aFlag == "-labels") + else if (aFlag == "-labels" + || aFlag == "-freelabels") { - if (anArgIter + aNbIntervals + 1 >= theArgNb) + if (anArgIter + 1 >= theArgNb) { - std::cout << "Error: not enough arguments! You should provide " << (aNbIntervals + 1) - << " text labels for " << aNbIntervals << " intervals.\n"; + std::cout << "Syntax error at argument '" << anArg << "'!\n"; + return 1; + } + + Standard_Integer aNbLabels = aColorScale->IsLabelAtBorder() + ? aColorScale->GetNumberOfIntervals() + 1 + : aColorScale->GetNumberOfIntervals(); + if (aFlag == "-freelabels") + { + ++anArgIter; + aNbLabels = Draw::Atoi (theArgVec[anArgIter]); + } + if (anArgIter + aNbLabels >= theArgNb) + { + std::cout << "Error: not enough arguments! " << aNbLabels << " text labels are expected.\n"; return 1; } TColStd_SequenceOfExtendedString aSeq; - for (int aLabelIter = anArgIter + 1; aLabelIter <= anArgIter + aNbIntervals + 1; aLabelIter += 1) + for (Standard_Integer aLabelIter = 0; aLabelIter < aNbLabels; ++aLabelIter) { - aSeq.Append (TCollection_ExtendedString (theArgVec[aLabelIter])); + aSeq.Append (TCollection_ExtendedString (theArgVec[++anArgIter])); } - aCS->SetLabels (aSeq); - aCS->SetLabelType (Aspect_TOCSD_USER); - anArgIter += aSeq.Length(); + aColorScale->SetLabels (aSeq); + aColorScale->SetLabelType (Aspect_TOCSD_USER); } else if (aFlag == "-title") { @@ -3874,29 +3889,31 @@ static int VColorScale (Draw_Interpretor& theDI, { TCollection_AsciiString aSecondArg (theArgVec[anArgIter + 2]); aSecondArg.LowerCase(); + Standard_DISABLE_DEPRECATION_WARNINGS if (aSecondArg == "none") { - aCS->SetTitlePosition (Aspect_TOCSP_NONE); + aColorScale->SetTitlePosition (Aspect_TOCSP_NONE); isTwoArgs = Standard_True; } else if (aSecondArg == "left") { - aCS->SetTitlePosition (Aspect_TOCSP_LEFT); + aColorScale->SetTitlePosition (Aspect_TOCSP_LEFT); isTwoArgs = Standard_True; } else if (aSecondArg == "right") { - aCS->SetTitlePosition (Aspect_TOCSP_RIGHT); + aColorScale->SetTitlePosition (Aspect_TOCSP_RIGHT); isTwoArgs = Standard_True; } else if (aSecondArg == "center") { - aCS->SetTitlePosition (Aspect_TOCSP_CENTER); + aColorScale->SetTitlePosition (Aspect_TOCSP_CENTER); isTwoArgs = Standard_True; } + Standard_ENABLE_DEPRECATION_WARNINGS } - aCS->SetTitle (theArgVec[anArgIter + 1]); + aColorScale->SetTitle (theArgVec[anArgIter + 1]); if (isTwoArgs) { anArgIter += 1; @@ -3906,17 +3923,15 @@ static int VColorScale (Draw_Interpretor& theDI, else if (aFlag == "-demoversion" || aFlag == "-demo") { - aPosX = 0; - aPosY = 0; - aTextHeight = 16; - aMinRange = 0.0; - aMaxRange = 100; - aNbIntervals = 10; - aBreadth = 0; - aHeight = 0; - aLabPosition = Aspect_TOCSP_RIGHT; - aCS->SetColorType (Aspect_TOCSD_AUTO); - aCS->SetLabelType (Aspect_TOCSD_AUTO); + aColorScale->SetPosition (0, 0); + aColorScale->SetTextHeight (16); + aColorScale->SetRange (0.0, 100.0); + aColorScale->SetNumberOfIntervals (10); + aColorScale->SetBreadth (0); + aColorScale->SetHeight (0); + aColorScale->SetLabelPosition (Aspect_TOCSP_RIGHT); + aColorScale->SetColorType (Aspect_TOCSD_AUTO); + aColorScale->SetLabelType (Aspect_TOCSD_AUTO); } else if (aFlag == "-findcolor") { @@ -3935,7 +3950,7 @@ static int VColorScale (Draw_Interpretor& theDI, } Quantity_Color aColor; - aCS->FindColor (anArg1.RealValue(), aColor); + aColorScale->FindColor (anArg1.RealValue(), aColor); theDI << Quantity_Color::StringName (aColor.Name()); return 0; } @@ -3945,29 +3960,19 @@ static int VColorScale (Draw_Interpretor& theDI, return 1; } } - if (!aBreadth || !aHeight) - { - Standard_Integer aWinWidth, aWinHeight; - aView->Window()->Size (aWinWidth, aWinHeight); - if (!aBreadth) - { - aBreadth = aWinWidth; - } - if (!aHeight) - { - aHeight = aWinHeight; - } - } - aCS->SetSize (aBreadth, aHeight); - aCS->SetPosition (aPosX, aPosY); - aCS->SetTextHeight (aTextHeight); - aCS->SetRange (aMinRange, aMaxRange); - aCS->SetNumberOfIntervals (aNbIntervals); - aCS->SetLabelPosition (aLabPosition); -// aCS->SetColor (aView->BackgroundColor().Invert()); - aCS->SetToUpdate(); - aContext->Display (aCS); + Standard_Integer aWinWidth = 0, aWinHeight = 0; + aView->Window()->Size (aWinWidth, aWinHeight); + if (aColorScale->GetBreadth() == 0) + { + aColorScale->SetBreadth (aWinWidth); + } + if (aColorScale->GetHeight() == 0) + { + aColorScale->SetHeight (aWinHeight); + } + aColorScale->SetToUpdate(); + ViewerTest::Display (theArgVec[1], aColorScale, Standard_False, Standard_True); return 0; } @@ -10341,22 +10346,35 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands) " : notice that EMF format requires patched gl2ps", __FILE__,VExport,group); theCommands.Add("vcolorscale", - "vcolorscale : vcolorscale name [-range RangeMin = 0 RangeMax = 100 Intervals = 10 -font HeightFont = 16 -textpos " - "Position = left -xy X = 0 Y = 0] [-noupdate|-update]: draw color scale\n" - "-demo/-demoversion draw a demoversion of color scale.\n" - "-show/display display color scale.\n" - "-hide/erase erase color scale.\n" - "Please note that -show/-hide option must be the first argument!\n" - "-color Index R G B: set color for indexed interval\n" - "-color Index ColorName: set color for indexed interval\n" - "-colors R G B R G B ...: set colors for all intervals\n" - "-colors ColorName1 ColorName2 ...: set colors for all intervals\n" - "-colors supports both color names and rgb values in one call\n" - "-label Index Text: set label for indexed interval\n" - "-labels Text Text Text ...: set labels for all intervals\n" - "-title Title [Position]: set the title for color scale with certain position. Default position = center;\n" - "Available text positions: left, right, center, none;\n", - __FILE__,VColorScale,group); + "vcolorscale name [-noupdate|-update] [-demo]" + "\n\t\t: [-range RangeMin=0 RangeMax=1 NbIntervals=10]" + "\n\t\t: [-font HeightFont=20]" + "\n\t\t: [-logarithmic {on|off}=off] [-reversed {on|off}=off]" + "\n\t\t: [-smoothTransition {on|off}=off]" + "\n\t\t: [-hueRange MinAngle=230 MaxAngle=0]" + "\n\t\t: [-colorRange MinColor=BLUE1 MaxColor=RED]" + "\n\t\t: [-textpos {left|right|center|none}=right]" + "\n\t\t: [-labelAtBorder {on|off}=on]" + "\n\t\t: [-colors Color1 Color2 ...] [-color Index Color]" + "\n\t\t: [-labels Label1 Label2 ...] [-label Index Label]" + "\n\t\t: [-freeLabels NbOfLabels Label1 Label2 ...]" + "\n\t\t: [-xy Left=0 Bottom=0]" + "\n\t\t: -demo - displays a color scale with demonstratio values" + "\n\t\t: -colors - set colors for all intervals" + "\n\t\t: -color - set color for specific interval" + "\n\t\t: -textpos - horizontal label position relative to color scale bar" + "\n\t\t: -labelAtBorder - vertical label position relative to color interval;" + "\n\t\t: at border means the value inbetween neighbor intervals," + "\n\t\t: at center means the center value within current interval" + "\n\t\t: -labels - set labels for all intervals" + "\n\t\t: -freeLabels - same as -labels but does not require" + "\n\t\t: matching the number of intervals" + "\n\t\t: -label - set label for specific interval" + "\n\t\t: -title - set title" + "\n\t\t: -reversed - setup smooth color transition between intervals" + "\n\t\t: -smoothTransition - swap colorscale direction" + "\n\t\t: -hueRange - set hue angles corresponding to minimum and maximum values" + __FILE__, VColorScale, group); theCommands.Add("vgraduatedtrihedron", "vgraduatedtrihedron : -on/-off [-xname Name] [-yname Name] [-zname Name] [-arrowlength Value]\n" "\t[-namefont Name] [-valuesfont Name]\n" diff --git a/tests/bugs/vis/bug25136 b/tests/bugs/vis/bug25136 index c9a0930239..f63a497a13 100644 --- a/tests/bugs/vis/bug25136 +++ b/tests/bugs/vis/bug25136 @@ -4,29 +4,27 @@ puts "Display customized colorscale." puts "============" puts "" -vinit View1 vclear +vinit View1 vaxo # create default color scale -vcolorscale cs -demo -vdump ${imagedir}/${casename}_1.png +vcolorscale cs1 -demo -xy 0 0 +foreach {y aColor} {20 RED 60 DARKORANGE1 100 GOLD 140 GREENYELLOW 180 CHARTREUSE2 220 GREEN 250 MEDIUMSPRINGGREEN 290 CYAN1 330 DODGERBLUE1 370 BLUE1} { if { [vreadpixel 15 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } # reduce color scale range and number of intervals -vcolorscale cs -range 0 20 5 -vdump ${imagedir}/${casename}_2.png +vcolorscale cs2 -range 0 20 5 -xy 60 0 +foreach {y aColor} {40 RED 120 YELLOW 200 GREEN 280 CYAN2 350 BLUE1} { if { [vreadpixel 75 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } # set user-defined colors and labels for color scale -vcolorscale cs -colors white 0 0 1 green 1 0 0 1 1 1 -labels start 1 2 3 4 end -vdump ${imagedir}/${casename}_3.png +vcolorscale cs3 -range 0 20 5 -colors white 0 0 1 green 1 0 0 1 1 1 -labels start 1 2 3 4 end -xy 120 0 +foreach {y aColor} {40 WHITE 120 RED 200 GREEN 280 BLUE1 350 WHITE} { if { [vreadpixel 135 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } # change colors of first and last intervals -vcolorscale cs -color 1 0.42 0.35 0.8 -vcolorscale cs -color 5 pink - -# change last label -vcolorscale cs -label 6 "last" - -# set a title for color scale -vcolorscale cs -title "My color scale" -vdump ${imagedir}/${casename}_4.png +vcolorscale cs4 -range 0 20 5 -colors white 0 0 1 green 1 0 0 1 1 1 -labels start 1 2 3 4 end -xy 200 0 +vcolorscale cs4 -color 1 0.42 0.35 0.8 +vcolorscale cs4 -color 5 pink +vcolorscale cs4 -label 6 "last" +vcolorscale cs4 -title "My color scale" +foreach {y aColor} {60 PINK 120 RED 200 GREEN 280 BLUE1 350 SLATEBLUE} { if { [vreadpixel 215 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } +vdump ${imagedir}/${casename}.png diff --git a/tests/bugs/vis/bug28004 b/tests/bugs/vis/bug28004 new file mode 100644 index 0000000000..7ab866dd12 --- /dev/null +++ b/tests/bugs/vis/bug28004 @@ -0,0 +1,31 @@ +puts "============" +puts "OCC28004" +puts "Visualization, AIS_ColorScale - allow defining labels list not equal to intervals list" +puts "============" +puts "" + +vclear +vinit View1 +vaxo + +# create default color scale +vcolorscale cs1 -demo -smooth 0 -xy 0 0 +vcolorscale cs2 -demo -smooth 1 -xy 60 0 +foreach {y aColor} {20 RED 60 DARKORANGE1 100 GOLD 140 GREENYELLOW 180 CHARTREUSE2 220 GREEN 250 MEDIUMSPRINGGREEN 290 CYAN1 330 DODGERBLUE1 370 BLUE1} { if { [vreadpixel 15 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } +foreach {y aColor} {20 RED 60 DARKORANGE1 100 GOLD 140 GREENYELLOW 180 CHARTREUSE2 220 GREEN 250 MEDIUMSPRINGGREEN 290 CYAN1 330 DODGERBLUE1 370 BLUE1} { if { [vreadpixel 15 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } + +# reduce color scale range and number of intervals +vcolorscale cs3 -range 0 20 5 -font 16 -colors white 0 0 1 green 1 0 0 1 1 1 -labels start 1 2 3 4 end -smooth 0 -xy 120 0 +vcolorscale cs4 -range 0 20 5 -font 16 -colors white 0 0 1 green 1 0 0 1 1 1 -labels start 1 2 3 4 end -smooth 1 -xy 180 0 +foreach {y aColor} {40 WHITE 120 RED 200 GREEN 280 BLUE1 350 WHITE} { if { [vreadpixel 135 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } + +# color scale with overridden hue range +vcolorscale cs5 -demo -smooth 0 -hueRange 300 130 -xy 240 0 +vcolorscale cs6 -demo -smooth 1 -hueRange 300 130 -xy 300 0 +foreach {y aColor} {20 GREEN 60 SPRINGGREEN 100 CYAN2 140 TURQUOISE2 180 DODGERBLUE1 220 BLUE1 250 BLUE1 290 BLUEVIOLET 330 PURPLE 370 MAGENTA1} { if { [vreadpixel 245 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } +foreach {y aColor} {20 GREEN 60 SPRINGGREEN 100 CYAN2 140 TURQUOISE2 180 DODGERBLUE1 220 DODGERBLUE2 250 BLUE1 290 BLUE1 330 PURPLE 370 MAGENTA2} { if { [vreadpixel 315 $y rgb name] != "$aColor" } { puts "Error: wrong color at $y" } } + +# free labels +vcolorscale cs7 -demo -smooth 0 -colorRange BLACK WHITE -xy 360 0 -freeLabels 3 l1 l2 l3 + +vdump ${imagedir}/${casename}.png