1 // Created on: 2015-02-03
2 // Copyright (c) 2015 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <AIS_ColorScale.hxx>
17 #include <AIS_InteractiveContext.hxx>
18 #include <Aspect_TypeOfColorScaleData.hxx>
19 #include <Aspect_TypeOfColorScalePosition.hxx>
20 #include <Aspect_Window.hxx>
21 #include <Geom_Line.hxx>
22 #include <GeomAdaptor_Curve.hxx>
23 #include <Graphic3d_ArrayOfPolygons.hxx>
24 #include <Graphic3d_ArrayOfPolylines.hxx>
25 #include <Graphic3d_AspectFillArea3d.hxx>
26 #include <Graphic3d_AspectText3d.hxx>
27 #include <Graphic3d_GraphicDriver.hxx>
28 #include <Graphic3d_ArrayOfTriangles.hxx>
29 #include <Graphic3d_Text.hxx>
30 #include <Prs3d_LineAspect.hxx>
31 #include <Prs3d_Root.hxx>
32 #include <Prs3d_ShadingAspect.hxx>
33 #include <Prs3d_Text.hxx>
34 #include <Prs3d_TextAspect.hxx>
35 #include <SelectMgr_EntityOwner.hxx>
36 #include <SelectMgr_Selection.hxx>
37 #include <Select3D_SensitiveBox.hxx>
38 #include <Select3D_SensitiveSegment.hxx>
39 #include <StdPrs_Curve.hxx>
40 #include <V3d_Viewer.hxx>
41 #include <V3d_View.hxx>
43 IMPLEMENT_STANDARD_RTTIEXT(AIS_ColorScale, AIS_InteractiveObject)
47 //! Method to add colored quad into array of triangles.
48 static void addColoredQuad (const Handle(Graphic3d_ArrayOfTriangles)& theTris,
49 const Standard_Integer theXLeft, const Standard_Integer theYBottom,
50 const Standard_Integer theSizeX, const Standard_Integer theSizeY,
51 const Quantity_Color& theColorBottom,
52 const Quantity_Color& theColorTop)
54 const Standard_Integer aVertIndex = theTris->VertexNumber() + 1;
55 theTris->AddVertex (gp_Pnt (theXLeft, theYBottom, 0.0), theColorBottom);
56 theTris->AddVertex (gp_Pnt (theXLeft + theSizeX, theYBottom, 0.0), theColorBottom);
57 theTris->AddVertex (gp_Pnt (theXLeft, theYBottom + theSizeY, 0.0), theColorTop);
58 theTris->AddVertex (gp_Pnt (theXLeft + theSizeX, theYBottom + theSizeY, 0.0), theColorTop);
59 theTris->AddEdges (aVertIndex, aVertIndex + 1, aVertIndex + 2);
60 theTris->AddEdges (aVertIndex + 1, aVertIndex + 2, aVertIndex + 3);
63 //! Compute hue angle from specified value.
64 static Quantity_Color colorFromValueEx (const Standard_Real theValue,
65 const Standard_Real theMin,
66 const Standard_Real theMax,
67 const Graphic3d_Vec3d& theHlsMin,
68 const Graphic3d_Vec3d& theHlsMax)
70 const Standard_Real aValueDelta = theMax - theMin;
71 Standard_Real aValue = 0.0;
72 if (aValueDelta != 0.0)
74 aValue = (theValue - theMin) / aValueDelta;
77 Standard_Real aHue = NCollection_Lerp<Standard_Real>::Interpolate (theHlsMin[0], theHlsMax[0], aValue);
78 Standard_Real aLightness = NCollection_Lerp<Standard_Real>::Interpolate (theHlsMin[1], theHlsMax[1], aValue);
79 Standard_Real aSaturation = NCollection_Lerp<Standard_Real>::Interpolate (theHlsMin[2], theHlsMax[2], aValue);
80 return Quantity_Color (AIS_ColorScale::hueToValidRange (aHue), aLightness, aSaturation, Quantity_TOC_HLS);
83 //! Return the index of discrete interval for specified value.
84 //! Note that when value lies exactly on the border between two intervals,
85 //! determining which interval to return is undefined operation;
86 //! Current implementation returns the following interval in this case.
87 //! @param theValue [in] value to map
88 //! @param theMin [in] values range, lower value
89 //! @param theMax [in] values range, upper value
90 //! @param theNbIntervals [in] number of discrete intervals
91 //! @return index of interval within [1, theNbIntervals] range
92 static Standard_Integer colorDiscreteInterval (Standard_Real theValue,
95 Standard_Integer theNbIntervals)
97 if (Abs (theMax - theMin) <= Precision::Approximation())
102 Standard_Integer anInterval = 1 + (Standard_Integer )Floor (Standard_Real (theNbIntervals) * (theValue - theMin) / (theMax - theMin));
103 // map the very upper value (theValue==theMax) to the largest color interval
104 anInterval = Min (anInterval, theNbIntervals);
109 //=======================================================================
110 //function : AIS_ColorScale
112 //=======================================================================
113 AIS_ColorScale::AIS_ColorScale()
116 myColorHlsMin (230.0, 1.0, 1.0),
117 myColorHlsMax (0.0, 1.0, 1.0),
120 myColorType (Aspect_TOCSD_AUTO),
121 myLabelType (Aspect_TOCSD_AUTO),
122 myIsLabelAtBorder (Standard_True),
123 myIsReversed (Standard_False),
124 myIsLogarithmic (Standard_False),
125 myIsSmooth (Standard_False),
126 myLabelPos (Aspect_TOCSP_RIGHT),
127 myTitlePos (Aspect_TOCSP_LEFT),
136 myDrawer->SetupOwnShadingAspect();
137 myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
138 myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
139 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (Quantity_NOC_WHITE);
142 //=======================================================================
143 //function : GetLabel
145 //=======================================================================
146 TCollection_ExtendedString AIS_ColorScale::GetLabel (const Standard_Integer theIndex) const
148 if (myLabelType == Aspect_TOCSD_USER)
150 if (theIndex >= myLabels.Lower()
151 || theIndex <= myLabels.Upper())
153 return myLabels.Value(theIndex);
155 return TCollection_ExtendedString();
158 // value to be shown depends on label position
159 const Standard_Real aVal = myIsLabelAtBorder
160 ? GetIntervalValue (theIndex - 1)
161 : (0.5 * (GetIntervalValue (theIndex - 1) + GetIntervalValue (theIndex)));
164 sprintf (aBuf, myFormat.ToCString(), aVal);
165 return TCollection_ExtendedString (aBuf);
168 //=======================================================================
169 //function : GetIntervalColor
171 //=======================================================================
172 Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex) const
174 if (myColorType== Aspect_TOCSD_USER)
176 if (theIndex <= 0 || theIndex > myColors.Length())
178 return Quantity_Color();
180 return myColors.Value (theIndex);
183 return colorFromValue (theIndex - 1, 0, myNbIntervals - 1);
186 //=======================================================================
187 //function : GetLabels
189 //=======================================================================
190 void AIS_ColorScale::GetLabels (TColStd_SequenceOfExtendedString& theLabels) const
193 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (myLabels); aLabIter.More(); aLabIter.Next())
195 theLabels.Append (aLabIter.Value());
199 //=======================================================================
200 //function : GetColors
202 //=======================================================================
203 void AIS_ColorScale::GetColors (Aspect_SequenceOfColor& theColors) const
206 for (Aspect_SequenceOfColor::Iterator aColorIter (myColors); aColorIter.More(); aColorIter.Next())
208 theColors.Append (aColorIter.Value());
212 //=======================================================================
213 //function : SetRange
215 //=======================================================================
216 void AIS_ColorScale::SetRange (const Standard_Real theMin, const Standard_Real theMax)
218 myMin = Min (theMin, theMax);
219 myMax = Max (theMin, theMax);
222 //=======================================================================
223 //function : SetNumberOfIntervals
225 //=======================================================================
226 void AIS_ColorScale::SetNumberOfIntervals (const Standard_Integer theNum)
233 myNbIntervals = theNum;
236 //=======================================================================
237 //function : SetLabel
239 //=======================================================================
240 void AIS_ColorScale::SetLabel (const TCollection_ExtendedString& theLabel,
241 const Standard_Integer theIndex)
243 const Standard_Integer aLabIndex = (theIndex <= 0 ? myLabels.Length() + 1 : theIndex);
244 while (myLabels.Length() < aLabIndex)
246 myLabels.Append (TCollection_ExtendedString());
248 myLabels.SetValue (aLabIndex, theLabel);
251 //=======================================================================
252 //function : SetIntervalColor
254 //=======================================================================
255 void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor,
256 const Standard_Integer theIndex)
258 const Standard_Integer aColorIndex = (theIndex <= 0 ? myColors.Length() + 1 : theIndex);
259 while (myColors.Length() < aColorIndex)
261 myColors.Append (Quantity_Color());
263 myColors.SetValue (aColorIndex, theColor);
266 //=======================================================================
267 //function : SetLabels
269 //=======================================================================
270 void AIS_ColorScale::SetLabels (const TColStd_SequenceOfExtendedString& theSeq)
273 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theSeq); aLabIter.More(); aLabIter.Next())
275 myLabels.Append (aLabIter.Value());
279 //=======================================================================
280 //function : SetColors
282 //=======================================================================
283 void AIS_ColorScale::SetColors (const Aspect_SequenceOfColor& theSeq)
286 for (Aspect_SequenceOfColor::Iterator aColorIter (theSeq); aColorIter.More(); aColorIter.Next())
288 myColors.Append (aColorIter.Value());
292 //=======================================================================
293 //function : SizeHint
295 //=======================================================================
296 void AIS_ColorScale::SizeHint (Standard_Integer& theWidth, Standard_Integer& theHeight) const
298 const Standard_Integer aTextHeight = TextHeight ("");
299 const Standard_Integer aColorWidth = 20;
300 Standard_Integer aTextWidth = 0;
301 if (myLabelPos != Aspect_TOCSP_NONE)
303 for (Standard_Integer aLabIter = (myIsLabelAtBorder ? 0 : 1); aLabIter <= myNbIntervals; ++aLabIter)
305 aTextWidth = Max (aTextWidth, TextWidth (GetLabel (aLabIter)));
309 const Standard_Integer aScaleWidth = aColorWidth + aTextWidth + (aTextWidth ? 3 : 2) * mySpacing;
310 const Standard_Integer aScaleHeight = (Standard_Integer)(1.5 * (myNbIntervals + (myIsLabelAtBorder ? 2 : 1)) * aTextHeight);
312 Standard_Integer aTitleWidth = 0;
313 Standard_Integer aTitleHeight = 0;
314 if (!myTitle.IsEmpty())
316 aTitleHeight = TextHeight (myTitle) + mySpacing;
317 aTitleWidth = TextWidth (myTitle) + mySpacing * 2;
320 theWidth = Max (aTitleWidth, aScaleWidth);
321 theHeight = aScaleHeight + aTitleHeight;
324 //=======================================================================
325 //function : GetIntervalValue
327 //=======================================================================
328 Standard_Real AIS_ColorScale::GetIntervalValue (const Standard_Integer theIndex) const
330 if (myNbIntervals <= 0)
337 Standard_Real aMin = myMin > 0 ? myMin : 1.0;
338 Standard_Real aDivisor = std::pow (myMax / aMin, 1.0 / myNbIntervals);
339 return aMin * std::pow (aDivisor,theIndex);
342 Standard_Real aNum = 0;
343 if (myNbIntervals > 0)
345 aNum = GetMin() + theIndex * (Abs (GetMax() - GetMin()) / myNbIntervals);
350 //=======================================================================
351 //function : colorFromValue
353 //=======================================================================
354 Quantity_Color AIS_ColorScale::colorFromValue (const Standard_Real theValue,
355 const Standard_Real theMin,
356 const Standard_Real theMax) const
358 return colorFromValueEx (theValue, theMin, theMax, myColorHlsMin, myColorHlsMax);
361 //=======================================================================
362 //function : FindColor
364 //=======================================================================
365 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
366 Quantity_Color& theColor) const
368 if (theValue < myMin || theValue > myMax || myMax < myMin)
370 theColor = Quantity_Color();
371 return Standard_False;
374 if (myColorType == Aspect_TOCSD_USER)
376 const Standard_Integer anInterval = colorDiscreteInterval (theValue, myMin, myMax, myNbIntervals);
377 if (anInterval < myColors.Lower() || anInterval > myColors.Upper())
379 theColor = Quantity_Color();
380 return Standard_False;
383 theColor = myColors.Value (anInterval);
384 return Standard_True;
387 return FindColor (theValue, myMin, myMax, myNbIntervals, theColor);
390 //=======================================================================
391 //function : FindColor
393 //=======================================================================
394 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
395 const Standard_Real theMin,
396 const Standard_Real theMax,
397 const Standard_Integer theColorsCount,
398 const Graphic3d_Vec3d& theColorHlsMin,
399 const Graphic3d_Vec3d& theColorHlsMax,
400 Quantity_Color& theColor)
402 if (theValue < theMin || theValue > theMax || theMax < theMin)
404 return Standard_False;
407 const Standard_Integer anInterval = colorDiscreteInterval (theValue, theMin, theMax, theColorsCount);
408 theColor = colorFromValueEx (anInterval - 1, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
409 return Standard_True;
412 //=======================================================================
413 //function : computeMaxLabelWidth
415 //=======================================================================
416 Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const
418 Standard_Integer aWidthMax = 0;
419 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next())
421 if (!aLabIter.Value().IsEmpty())
423 aWidthMax = Max (aWidthMax, TextWidth (aLabIter.Value()));
429 //=======================================================================
430 //function : updateTextAspect
432 //=======================================================================
433 void AIS_ColorScale::updateTextAspect()
435 // update text aspect
436 const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE);
437 if (!myDrawer->HasOwnTextAspect())
439 myDrawer->SetTextAspect (new Prs3d_TextAspect());
440 *myDrawer->TextAspect()->Aspect() = *myDrawer->Link()->TextAspect()->Aspect();
443 const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect();
444 anAspect->SetColor (aFgColor);
445 anAspect->SetHeight (myTextHeight);
446 anAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT);
447 anAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
448 anAspect->Aspect()->SetTextZoomable (Standard_True);
451 //=======================================================================
454 //=======================================================================
455 void AIS_ColorScale::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
456 const Handle(Prs3d_Presentation)& thePrs,
457 const Standard_Integer theMode)
464 // update text aspect
467 const Standard_Integer aTitleOffset = !myTitle.IsEmpty() ? (myTextHeight + mySpacing) : 0;
469 const Standard_Integer aBarYOffset = myTextHeight / 2 + 2 * mySpacing; // a half-label offset
470 const Standard_Integer aBarBottom = myYPos + aBarYOffset;
471 const Standard_Integer aBarTop = myYPos + myHeight - aTitleOffset - aBarYOffset;
472 const Standard_Integer aBarHeight = aBarTop - aBarBottom;
474 TColStd_SequenceOfExtendedString aLabels;
475 if (myLabelType == Aspect_TOCSD_USER)
481 const Standard_Integer aNbLabels = myIsLabelAtBorder ? myNbIntervals + 1 : myNbIntervals;
482 for (Standard_Integer aLabIter = 1; aLabIter <= aNbLabels; ++aLabIter)
486 aLabels.Prepend (GetLabel (aLabIter));
490 aLabels.Append (GetLabel (aLabIter));
495 const Standard_Integer aTextWidth = myLabelPos != Aspect_TOCSP_NONE ? computeMaxLabelWidth (aLabels) : 0;
496 Standard_Integer aColorBreadth = Max (5, Min (20, myBreadth - aTextWidth - 3 * mySpacing));
497 if (myLabelPos == Aspect_TOCSP_CENTER
498 || myLabelPos == Aspect_TOCSP_NONE)
500 aColorBreadth += aTextWidth;
504 Handle(Graphic3d_Group) aLabelsGroup;
505 if (!myTitle.IsEmpty()
506 || !aLabels.IsEmpty())
508 aLabelsGroup = thePrs->NewGroup();
509 aLabelsGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
511 if (!myTitle.IsEmpty())
513 drawText (aLabelsGroup, myTitle,
515 aBarTop + aBarYOffset,
516 Graphic3d_VTA_BOTTOM);
520 drawColorBar (thePrs, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
523 drawLabels (aLabelsGroup, aLabels, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
526 //=======================================================================
527 //function : drawColorBar
529 //=======================================================================
530 void AIS_ColorScale::drawColorBar (const Handle(Prs3d_Presentation)& thePrs,
531 const Standard_Integer theBarBottom,
532 const Standard_Integer theBarHeight,
533 const Standard_Integer theMaxLabelWidth,
534 const Standard_Integer theColorBreadth)
536 const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(myNbIntervals);
543 const Standard_Integer anXLeft = myLabelPos == Aspect_TOCSP_LEFT
544 ? myXPos + mySpacing + theMaxLabelWidth + (theMaxLabelWidth != 0 ? 1 : 0) * mySpacing
545 : myXPos + mySpacing;
547 Aspect_SequenceOfColor aColors;
548 for (Standard_Integer anIntervalIter = 1; anIntervalIter <= myNbIntervals; ++anIntervalIter)
552 aColors.Prepend (GetIntervalColor (anIntervalIter));
556 aColors.Append (GetIntervalColor (anIntervalIter));
560 Handle(Graphic3d_ArrayOfTriangles) aTriangles;
562 && myColorType == Aspect_TOCSD_USER)
564 // Smooth custom intervals, so that the color in the center of interval is equal to specified one
565 // (thus the halves of first and last intervals have solid color)
566 aTriangles = new Graphic3d_ArrayOfTriangles ((aColors.Length() + 1) * 4, // quads
567 (aColors.Length() + 1) * 2 * 3, // quads as triangles
568 false, true); // per-vertex colors
569 Quantity_Color aColor1 (aColors.Value (1)), aColor2;
570 Standard_Integer aSizeY = Standard_Integer(aStepY / 2);
571 const Standard_Integer anYBottom = theBarBottom + aSizeY;
572 Standard_Integer anYBottomIter = anYBottom;
573 addColoredQuad (aTriangles,
574 anXLeft, theBarBottom,
575 theColorBreadth, aSizeY,
577 for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals - 1; ++aColorIter)
579 aColor1 = aColors.Value (aColorIter + 1);
580 aColor2 = aColors.Value (aColorIter + 2);
581 aSizeY = anYBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter;
582 addColoredQuad (aTriangles,
583 anXLeft, anYBottomIter,
584 theColorBreadth, aSizeY,
586 anYBottomIter += aSizeY;
588 aColor2 = aColors.Value (myNbIntervals);
589 aSizeY = theBarBottom + theBarHeight - anYBottomIter;
590 addColoredQuad (aTriangles,
591 anXLeft, anYBottomIter,
592 theColorBreadth, aSizeY,
597 // smooth transition between standard colors - without solid color regions at the beginning and end of full color range
598 const Quantity_Color aColorsFixed[5] =
600 colorFromValue (0, 0, 4),
601 colorFromValue (1, 0, 4),
602 colorFromValue (2, 0, 4),
603 colorFromValue (3, 0, 4),
604 colorFromValue (4, 0, 4)
606 aTriangles = new Graphic3d_ArrayOfTriangles (4 * 4, // quads
607 4 * 2 * 3, // quads as triangles
608 false, true); // per-vertex colors
609 Standard_Integer anYBottomIter = theBarBottom;
610 addColoredQuad (aTriangles,
611 anXLeft, theBarBottom,
612 theColorBreadth, theBarHeight / 4,
613 aColorsFixed[0], aColorsFixed[1]);
614 anYBottomIter += theBarHeight / 4;
615 addColoredQuad (aTriangles,
616 anXLeft, anYBottomIter,
617 theColorBreadth, theBarHeight / 4,
618 aColorsFixed[1], aColorsFixed[2]);
619 anYBottomIter += theBarHeight / 4;
620 addColoredQuad (aTriangles,
621 anXLeft, anYBottomIter,
622 theColorBreadth, theBarHeight / 4,
623 aColorsFixed[2], aColorsFixed[3]);
624 anYBottomIter += theBarHeight / 4;
625 const Standard_Integer aLastSizeY = theBarBottom + theBarHeight - anYBottomIter;
626 addColoredQuad (aTriangles,
627 anXLeft, anYBottomIter,
628 theColorBreadth, aLastSizeY,
629 aColorsFixed[3], aColorsFixed[4]);
633 // no color smoothing
634 aTriangles = new Graphic3d_ArrayOfTriangles (aColors.Length() * 4, // quads
635 aColors.Length() * 2 * 3, // quads as triangles
636 false, true); // per-vertex colors
637 Standard_Integer anYBottomIter = theBarBottom;
638 for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals; ++aColorIter)
640 const Quantity_Color& aColor = aColors.Value (aColorIter + 1);
641 const Standard_Integer aSizeY = theBarBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter;
642 addColoredQuad (aTriangles,
643 anXLeft, anYBottomIter,
644 theColorBreadth, aSizeY,
646 anYBottomIter += aSizeY;
650 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
651 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
652 aGroup->AddPrimitiveArray (aTriangles);
654 const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE);
656 anXLeft - 1, theBarBottom - 1,
662 //=======================================================================
663 //function : drawLabels
665 //=======================================================================
666 void AIS_ColorScale::drawLabels (const Handle(Graphic3d_Group)& theGroup,
667 const TColStd_SequenceOfExtendedString& theLabels,
668 const Standard_Integer theBarBottom,
669 const Standard_Integer theBarHeight,
670 const Standard_Integer theMaxLabelWidth,
671 const Standard_Integer theColorBreadth)
673 if (myLabelPos == Aspect_TOCSP_NONE
674 || theLabels.IsEmpty())
679 const Standard_Integer aNbLabels = theLabels.Size();
680 const Standard_Integer aNbIntervals = myIsLabelAtBorder ? aNbLabels - 1 : aNbLabels;
681 const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(aNbIntervals);
687 Standard_Integer aFilter = 0;
689 const Standard_Integer aTitleHeight = !myTitle.IsEmpty() ? (myTextHeight + 2 * mySpacing) : mySpacing;
690 const Standard_Integer aSpc = myHeight - aTitleHeight - ((Min (aNbLabels, 2) + Abs (aNbLabels - aNbIntervals - 1)) * myTextHeight);
696 const Standard_Real aVal = Standard_Real(aNbLabels) * myTextHeight / aSpc;
697 Standard_Real anIPart = 0.0;
698 Standard_Real anFPart = std::modf (aVal, &anIPart);
699 aFilter = (Standard_Integer )anIPart + (anFPart != 0 ? 1 : 0);
706 Standard_Integer anXLeft = myXPos + mySpacing;
707 const Standard_Integer anAscent = 0;
710 case Aspect_TOCSP_NONE:
711 case Aspect_TOCSP_LEFT:
715 case Aspect_TOCSP_CENTER:
717 anXLeft += (theColorBreadth - theMaxLabelWidth) / 2;
720 case Aspect_TOCSP_RIGHT:
722 anXLeft += theColorBreadth + mySpacing;
727 Standard_Integer i1 = 0;
728 Standard_Integer i2 = aNbLabels - 1;
729 Standard_Integer aLast1 = i1;
730 Standard_Integer aLast2 = i2;
731 const Standard_Integer anYBottom = myIsLabelAtBorder
733 : theBarBottom + Standard_Integer(aStepY / 2);
734 while (i2 - i1 >= aFilter || ( i2 == 0 && i1 == 0 ))
736 Standard_Integer aPos1 = i1;
737 Standard_Integer aPos2 = aNbLabels - 1 - i2;
738 if (aFilter && !(aPos1 % aFilter))
740 drawText (theGroup, theLabels.Value (i1 + 1),
741 anXLeft, anYBottom + Standard_Integer(i1 * aStepY + anAscent),
742 Graphic3d_VTA_CENTER);
745 if (aFilter && !(aPos2 % aFilter))
747 drawText (theGroup, theLabels.Value (i2 + 1),
748 anXLeft, anYBottom + Standard_Integer(i2 * aStepY + anAscent),
749 Graphic3d_VTA_CENTER);
755 Standard_Integer aPos = i1;
756 Standard_Integer i0 = -1;
757 while (aPos <= i2 && i0 == -1)
759 if (aFilter && !(aPos % aFilter)
760 && Abs (aPos - aLast1) >= aFilter
761 && Abs (aPos - aLast2) >= aFilter)
770 drawText (theGroup, theLabels.Value (i0 + 1),
771 anXLeft, anYBottom + Standard_Integer(i0 * aStepY + anAscent),
772 Graphic3d_VTA_CENTER);
776 //=======================================================================
777 //function : drawFrame
779 //=======================================================================
780 void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePrs,
781 const Standard_Integer theX, const Standard_Integer theY,
782 const Standard_Integer theWidth, const Standard_Integer theHeight,
783 const Quantity_Color& theColor)
785 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
786 aPrim->AddVertex (theX, theY, 0.0);
787 aPrim->AddVertex (theX + theWidth, theY, 0.0);
788 aPrim->AddVertex (theX + theWidth, theY + theHeight, 0.0);
789 aPrim->AddVertex (theX, theY + theHeight, 0.0);
790 aPrim->AddVertex (theX, theY, 0.0);
792 Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d (theColor, Aspect_TOL_SOLID, 1.0);
793 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
794 aGroup->SetGroupPrimitivesAspect (anAspect);
795 aGroup->AddPrimitiveArray (aPrim);
798 //=======================================================================
799 //function : drawText
801 //=======================================================================
802 void AIS_ColorScale::drawText (const Handle(Graphic3d_Group)& theGroup,
803 const TCollection_ExtendedString& theText,
804 const Standard_Integer theX, const Standard_Integer theY,
805 const Graphic3d_VerticalTextAlignment theVertAlignment)
807 const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect();
809 Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)anAspect->Height());
810 aText->SetText (theText.ToExtString());
811 aText->SetOrientation (gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()));
812 aText->SetOwnAnchorPoint (Standard_False);
813 aText->SetVerticalAlignment (theVertAlignment);
815 theGroup->AddText (aText);
818 //=======================================================================
819 //function : TextWidth
821 //=======================================================================
822 Standard_Integer AIS_ColorScale::TextWidth (const TCollection_ExtendedString& theText) const
824 Standard_Integer aWidth, anAscent, aDescent;
825 TextSize (theText, myTextHeight, aWidth, anAscent, aDescent);
829 //=======================================================================
830 //function : TextHeight
832 //=======================================================================
833 Standard_Integer AIS_ColorScale::TextHeight (const TCollection_ExtendedString& theText) const
835 Standard_Integer aWidth, anAscent, aDescent;
836 TextSize (theText, myTextHeight, aWidth, anAscent, aDescent);
837 return anAscent + aDescent;
840 //=======================================================================
841 //function : TextSize
843 //=======================================================================
844 void AIS_ColorScale::TextSize (const TCollection_ExtendedString& theText,
845 const Standard_Integer theHeight,
846 Standard_Integer& theWidth,
847 Standard_Integer& theAscent,
848 Standard_Integer& theDescent) const
850 if (!HasInteractiveContext())
855 Standard_ShortReal aWidth = 10.0f;
856 Standard_ShortReal anAscent = 1.0f;
857 Standard_ShortReal aDescent = 1.0f;
858 const TCollection_AsciiString aText (theText);
860 const Handle(V3d_Viewer)& aViewer = GetContext()->CurrentViewer();
861 const Handle(Graphic3d_CView)& aView = aViewer->ActiveViewIterator().Value()->View();
862 aViewer->Driver()->TextSize (aView, aText.ToCString(), (Standard_ShortReal)theHeight, aWidth, anAscent, aDescent);
863 theWidth = (Standard_Integer)aWidth;
864 theAscent = (Standard_Integer)anAscent;
865 theDescent = (Standard_Integer)aDescent;