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);
84 //=======================================================================
85 //function : AIS_ColorScale
87 //=======================================================================
88 AIS_ColorScale::AIS_ColorScale()
91 myColorHlsMin (230.0, 1.0, 1.0),
92 myColorHlsMax (0.0, 1.0, 1.0),
95 myColorType (Aspect_TOCSD_AUTO),
96 myLabelType (Aspect_TOCSD_AUTO),
97 myIsLabelAtBorder (Standard_True),
98 myIsReversed (Standard_False),
99 myIsLogarithmic (Standard_False),
100 myIsSmooth (Standard_False),
101 myLabelPos (Aspect_TOCSP_RIGHT),
102 myTitlePos (Aspect_TOCSP_LEFT),
111 myDrawer->SetupOwnShadingAspect();
112 myDrawer->ShadingAspect()->Aspect()->SetShadingModel (Graphic3d_TOSM_UNLIT);
113 myDrawer->ShadingAspect()->Aspect()->SetAlphaMode (Graphic3d_AlphaMode_Opaque);
114 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (Quantity_NOC_WHITE);
117 //=======================================================================
118 //function : GetLabel
120 //=======================================================================
121 TCollection_ExtendedString AIS_ColorScale::GetLabel (const Standard_Integer theIndex) const
123 if (myLabelType == Aspect_TOCSD_USER)
125 if (theIndex >= myLabels.Lower()
126 || theIndex <= myLabels.Upper())
128 return myLabels.Value(theIndex);
130 return TCollection_ExtendedString();
133 // value to be shown depends on label position
134 const Standard_Real aVal = myIsLabelAtBorder
135 ? GetIntervalValue (theIndex - 1)
136 : (0.5 * (GetIntervalValue (theIndex - 1) + GetIntervalValue (theIndex)));
139 sprintf (aBuf, myFormat.ToCString(), aVal);
140 return TCollection_ExtendedString (aBuf);
143 //=======================================================================
144 //function : GetIntervalColor
146 //=======================================================================
147 Quantity_Color AIS_ColorScale::GetIntervalColor (const Standard_Integer theIndex) const
149 if (myColorType== Aspect_TOCSD_USER)
151 if (theIndex <= 0 || theIndex > myColors.Length())
153 return Quantity_Color();
155 return myColors.Value (theIndex);
158 return colorFromValue (theIndex - 1, 0, myNbIntervals - 1);
161 //=======================================================================
162 //function : GetLabels
164 //=======================================================================
165 void AIS_ColorScale::GetLabels (TColStd_SequenceOfExtendedString& theLabels) const
168 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (myLabels); aLabIter.More(); aLabIter.Next())
170 theLabels.Append (aLabIter.Value());
174 //=======================================================================
175 //function : GetColors
177 //=======================================================================
178 void AIS_ColorScale::GetColors (Aspect_SequenceOfColor& theColors) const
181 for (Aspect_SequenceOfColor::Iterator aColorIter (myColors); aColorIter.More(); aColorIter.Next())
183 theColors.Append (aColorIter.Value());
187 //=======================================================================
188 //function : SetRange
190 //=======================================================================
191 void AIS_ColorScale::SetRange (const Standard_Real theMin, const Standard_Real theMax)
193 myMin = Min (theMin, theMax);
194 myMax = Max (theMin, theMax);
197 //=======================================================================
198 //function : SetNumberOfIntervals
200 //=======================================================================
201 void AIS_ColorScale::SetNumberOfIntervals (const Standard_Integer theNum)
208 myNbIntervals = theNum;
211 //=======================================================================
212 //function : SetLabel
214 //=======================================================================
215 void AIS_ColorScale::SetLabel (const TCollection_ExtendedString& theLabel,
216 const Standard_Integer theIndex)
218 const Standard_Integer aLabIndex = (theIndex <= 0 ? myLabels.Length() + 1 : theIndex);
219 while (myLabels.Length() < aLabIndex)
221 myLabels.Append (TCollection_ExtendedString());
223 myLabels.SetValue (aLabIndex, theLabel);
226 //=======================================================================
227 //function : SetIntervalColor
229 //=======================================================================
230 void AIS_ColorScale::SetIntervalColor (const Quantity_Color& theColor,
231 const Standard_Integer theIndex)
233 const Standard_Integer aColorIndex = (theIndex <= 0 ? myColors.Length() + 1 : theIndex);
234 while (myColors.Length() < aColorIndex)
236 myColors.Append (Quantity_Color());
238 myColors.SetValue (aColorIndex, theColor);
241 //=======================================================================
242 //function : SetLabels
244 //=======================================================================
245 void AIS_ColorScale::SetLabels (const TColStd_SequenceOfExtendedString& theSeq)
248 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theSeq); aLabIter.More(); aLabIter.Next())
250 myLabels.Append (aLabIter.Value());
254 //=======================================================================
255 //function : SetColors
257 //=======================================================================
258 void AIS_ColorScale::SetColors (const Aspect_SequenceOfColor& theSeq)
261 for (Aspect_SequenceOfColor::Iterator aColorIter (theSeq); aColorIter.More(); aColorIter.Next())
263 myColors.Append (aColorIter.Value());
267 //=======================================================================
268 //function : SizeHint
270 //=======================================================================
271 void AIS_ColorScale::SizeHint (Standard_Integer& theWidth, Standard_Integer& theHeight) const
273 const Standard_Integer aTextHeight = TextHeight ("");
274 const Standard_Integer aColorWidth = 20;
275 Standard_Integer aTextWidth = 0;
276 if (myLabelPos != Aspect_TOCSP_NONE)
278 for (Standard_Integer aLabIter = (myIsLabelAtBorder ? 0 : 1); aLabIter <= myNbIntervals; ++aLabIter)
280 aTextWidth = Max (aTextWidth, TextWidth (GetLabel (aLabIter)));
284 const Standard_Integer aScaleWidth = aColorWidth + aTextWidth + (aTextWidth ? 3 : 2) * mySpacing;
285 const Standard_Integer aScaleHeight = (Standard_Integer)(1.5 * (myNbIntervals + (myIsLabelAtBorder ? 2 : 1)) * aTextHeight);
287 Standard_Integer aTitleWidth = 0;
288 Standard_Integer aTitleHeight = 0;
289 if (!myTitle.IsEmpty())
291 aTitleHeight = TextHeight (myTitle) + mySpacing;
292 aTitleWidth = TextWidth (myTitle) + mySpacing * 2;
295 theWidth = Max (aTitleWidth, aScaleWidth);
296 theHeight = aScaleHeight + aTitleHeight;
299 //=======================================================================
300 //function : GetIntervalValue
302 //=======================================================================
303 Standard_Real AIS_ColorScale::GetIntervalValue (const Standard_Integer theIndex) const
305 if (myNbIntervals <= 0)
312 Standard_Real aMin = myMin > 0 ? myMin : 1.0;
313 Standard_Real aDivisor = std::pow (myMax / aMin, 1.0 / myNbIntervals);
314 return aMin * std::pow (aDivisor,theIndex);
317 Standard_Real aNum = 0;
318 if (myNbIntervals > 0)
320 aNum = GetMin() + theIndex * (Abs (GetMax() - GetMin()) / myNbIntervals);
325 //=======================================================================
326 //function : colorFromValue
328 //=======================================================================
329 Quantity_Color AIS_ColorScale::colorFromValue (const Standard_Real theValue,
330 const Standard_Real theMin,
331 const Standard_Real theMax) const
333 return colorFromValueEx (theValue, theMin, theMax, myColorHlsMin, myColorHlsMax);
336 //=======================================================================
337 //function : FindColor
339 //=======================================================================
340 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
341 Quantity_Color& theColor) const
343 if (theValue < myMin || theValue > myMax || myMax < myMin)
345 theColor = Quantity_Color();
346 return Standard_False;
349 if (myColorType == Aspect_TOCSD_USER)
351 Standard_Integer anIndex = 0;
352 if (Abs (myMax - myMin) > Precision::Approximation())
354 anIndex = (theValue - myMin < Precision::Confusion())
356 : Standard_Integer (Ceiling (( theValue - myMin ) / ( (myMax - myMin) / myNbIntervals)));
359 if (anIndex <= 0 || anIndex > myColors.Length())
361 theColor = Quantity_Color();
362 return Standard_False;
365 theColor = myColors.Value (anIndex);
366 return Standard_True;
369 return FindColor (theValue, myMin, myMax, myNbIntervals, theColor);
372 //=======================================================================
373 //function : FindColor
375 //=======================================================================
376 Standard_Boolean AIS_ColorScale::FindColor (const Standard_Real theValue,
377 const Standard_Real theMin,
378 const Standard_Real theMax,
379 const Standard_Integer theColorsCount,
380 const Graphic3d_Vec3d& theColorHlsMin,
381 const Graphic3d_Vec3d& theColorHlsMax,
382 Quantity_Color& theColor)
384 if (theValue < theMin || theValue > theMax || theMax < theMin)
386 return Standard_False;
389 Standard_Real anInterval = 0.0;
390 if (Abs (theMax - theMin) > Precision::Approximation())
392 anInterval = Floor (Standard_Real (theColorsCount) * (theValue - theMin) / (theMax - theMin));
395 theColor = colorFromValueEx (anInterval, 0, theColorsCount - 1, theColorHlsMin, theColorHlsMax);
396 return Standard_True;
399 //=======================================================================
400 //function : computeMaxLabelWidth
402 //=======================================================================
403 Standard_Integer AIS_ColorScale::computeMaxLabelWidth (const TColStd_SequenceOfExtendedString& theLabels) const
406 Handle(V3d_Viewer) aViewer = GetContext()->CurrentViewer();
407 aViewer->InitActiveViews(); // for AIS_ColorScale::TextSize()
410 Standard_Integer aWidthMax = 0;
411 for (TColStd_SequenceOfExtendedString::Iterator aLabIter (theLabels); aLabIter.More(); aLabIter.Next())
413 if (!aLabIter.Value().IsEmpty())
415 aWidthMax = Max (aWidthMax, TextWidth (aLabIter.Value()));
421 //=======================================================================
422 //function : updateTextAspect
424 //=======================================================================
425 void AIS_ColorScale::updateTextAspect()
427 // update text aspect
428 const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE);
429 if (!myDrawer->HasOwnTextAspect())
431 myDrawer->SetTextAspect (new Prs3d_TextAspect());
432 *myDrawer->TextAspect()->Aspect() = *myDrawer->Link()->TextAspect()->Aspect();
435 const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect();
436 anAspect->SetColor (aFgColor);
437 anAspect->SetHeight (myTextHeight);
438 anAspect->SetHorizontalJustification (Graphic3d_HTA_LEFT);
439 anAspect->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
440 anAspect->Aspect()->SetTextZoomable (Standard_True);
443 //=======================================================================
446 //=======================================================================
447 void AIS_ColorScale::Compute (const Handle(PrsMgr_PresentationManager3d)& ,
448 const Handle(Prs3d_Presentation)& thePrs,
449 const Standard_Integer theMode)
456 // update text aspect
459 const Standard_Integer aTitleOffset = !myTitle.IsEmpty() ? (myTextHeight + mySpacing) : 0;
461 const Standard_Integer aBarYOffset = myTextHeight / 2 + 2 * mySpacing; // a half-label offset
462 const Standard_Integer aBarBottom = myYPos + aBarYOffset;
463 const Standard_Integer aBarTop = myYPos + myHeight - aTitleOffset - aBarYOffset;
464 const Standard_Integer aBarHeight = aBarTop - aBarBottom;
466 TColStd_SequenceOfExtendedString aLabels;
467 if (myLabelType == Aspect_TOCSD_USER)
473 const Standard_Integer aNbLabels = myIsLabelAtBorder ? myNbIntervals + 1 : myNbIntervals;
474 for (Standard_Integer aLabIter = 1; aLabIter <= aNbLabels; ++aLabIter)
478 aLabels.Prepend (GetLabel (aLabIter));
482 aLabels.Append (GetLabel (aLabIter));
487 const Standard_Integer aTextWidth = myLabelPos != Aspect_TOCSP_NONE ? computeMaxLabelWidth (aLabels) : 0;
488 Standard_Integer aColorBreadth = Max (5, Min (20, myBreadth - aTextWidth - 3 * mySpacing));
489 if (myLabelPos == Aspect_TOCSP_CENTER
490 || myLabelPos == Aspect_TOCSP_NONE)
492 aColorBreadth += aTextWidth;
496 Handle(Graphic3d_Group) aLabelsGroup;
497 if (!myTitle.IsEmpty()
498 || !aLabels.IsEmpty())
500 aLabelsGroup = thePrs->NewGroup();
501 aLabelsGroup->SetGroupPrimitivesAspect (myDrawer->TextAspect()->Aspect());
503 if (!myTitle.IsEmpty())
505 drawText (aLabelsGroup, myTitle,
507 aBarTop + aBarYOffset,
508 Graphic3d_VTA_BOTTOM);
512 drawColorBar (thePrs, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
515 drawLabels (aLabelsGroup, aLabels, aBarBottom, aBarHeight, aTextWidth, aColorBreadth);
518 //=======================================================================
519 //function : drawColorBar
521 //=======================================================================
522 void AIS_ColorScale::drawColorBar (const Handle(Prs3d_Presentation)& thePrs,
523 const Standard_Integer theBarBottom,
524 const Standard_Integer theBarHeight,
525 const Standard_Integer theMaxLabelWidth,
526 const Standard_Integer theColorBreadth)
528 const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(myNbIntervals);
535 const Standard_Integer anXLeft = myLabelPos == Aspect_TOCSP_LEFT
536 ? myXPos + mySpacing + theMaxLabelWidth + (theMaxLabelWidth != 0 ? 1 : 0) * mySpacing
537 : myXPos + mySpacing;
539 Aspect_SequenceOfColor aColors;
540 for (Standard_Integer anIntervalIter = 1; anIntervalIter <= myNbIntervals; ++anIntervalIter)
544 aColors.Prepend (GetIntervalColor (anIntervalIter));
548 aColors.Append (GetIntervalColor (anIntervalIter));
552 Handle(Graphic3d_ArrayOfTriangles) aTriangles;
554 && myColorType == Aspect_TOCSD_USER)
556 // Smooth custom intervals, so that the color in the center of interval is equal to specified one
557 // (thus the halves of first and last intervals have solid color)
558 aTriangles = new Graphic3d_ArrayOfTriangles ((aColors.Length() + 1) * 4, // quads
559 (aColors.Length() + 1) * 2 * 3, // quads as triangles
560 false, true); // per-vertex colors
561 Quantity_Color aColor1 (aColors.Value (1)), aColor2;
562 Standard_Integer aSizeY = Standard_Integer(aStepY / 2);
563 const Standard_Integer anYBottom = theBarBottom + aSizeY;
564 Standard_Integer anYBottomIter = anYBottom;
565 addColoredQuad (aTriangles,
566 anXLeft, theBarBottom,
567 theColorBreadth, aSizeY,
569 for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals - 1; ++aColorIter)
571 aColor1 = aColors.Value (aColorIter + 1);
572 aColor2 = aColors.Value (aColorIter + 2);
573 aSizeY = anYBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter;
574 addColoredQuad (aTriangles,
575 anXLeft, anYBottomIter,
576 theColorBreadth, aSizeY,
578 anYBottomIter += aSizeY;
580 aColor2 = aColors.Value (myNbIntervals);
581 aSizeY = theBarBottom + theBarHeight - anYBottomIter;
582 addColoredQuad (aTriangles,
583 anXLeft, anYBottomIter,
584 theColorBreadth, aSizeY,
589 // smooth transition between standard colors - without solid color regions at the beginning and end of full color range
590 const Quantity_Color aColorsFixed[5] =
592 colorFromValue (0, 0, 4),
593 colorFromValue (1, 0, 4),
594 colorFromValue (2, 0, 4),
595 colorFromValue (3, 0, 4),
596 colorFromValue (4, 0, 4)
598 aTriangles = new Graphic3d_ArrayOfTriangles (4 * 4, // quads
599 4 * 2 * 3, // quads as triangles
600 false, true); // per-vertex colors
601 Standard_Integer anYBottomIter = theBarBottom;
602 addColoredQuad (aTriangles,
603 anXLeft, theBarBottom,
604 theColorBreadth, theBarHeight / 4,
605 aColorsFixed[0], aColorsFixed[1]);
606 anYBottomIter += theBarHeight / 4;
607 addColoredQuad (aTriangles,
608 anXLeft, anYBottomIter,
609 theColorBreadth, theBarHeight / 4,
610 aColorsFixed[1], aColorsFixed[2]);
611 anYBottomIter += theBarHeight / 4;
612 addColoredQuad (aTriangles,
613 anXLeft, anYBottomIter,
614 theColorBreadth, theBarHeight / 4,
615 aColorsFixed[2], aColorsFixed[3]);
616 anYBottomIter += theBarHeight / 4;
617 const Standard_Integer aLastSizeY = theBarBottom + theBarHeight - anYBottomIter;
618 addColoredQuad (aTriangles,
619 anXLeft, anYBottomIter,
620 theColorBreadth, aLastSizeY,
621 aColorsFixed[3], aColorsFixed[4]);
625 // no color smoothing
626 aTriangles = new Graphic3d_ArrayOfTriangles (aColors.Length() * 4, // quads
627 aColors.Length() * 2 * 3, // quads as triangles
628 false, true); // per-vertex colors
629 Standard_Integer anYBottomIter = theBarBottom;
630 for (Standard_Integer aColorIter = 0; aColorIter < myNbIntervals; ++aColorIter)
632 const Quantity_Color& aColor = aColors.Value (aColorIter + 1);
633 const Standard_Integer aSizeY = theBarBottom + Standard_Integer((aColorIter + 1) * aStepY) - anYBottomIter;
634 addColoredQuad (aTriangles,
635 anXLeft, anYBottomIter,
636 theColorBreadth, aSizeY,
638 anYBottomIter += aSizeY;
642 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
643 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
644 aGroup->AddPrimitiveArray (aTriangles);
646 const Quantity_Color aFgColor (hasOwnColor ? myDrawer->Color() : Quantity_NOC_WHITE);
648 anXLeft - 1, theBarBottom - 1,
654 //=======================================================================
655 //function : drawLabels
657 //=======================================================================
658 void AIS_ColorScale::drawLabels (const Handle(Graphic3d_Group)& theGroup,
659 const TColStd_SequenceOfExtendedString& theLabels,
660 const Standard_Integer theBarBottom,
661 const Standard_Integer theBarHeight,
662 const Standard_Integer theMaxLabelWidth,
663 const Standard_Integer theColorBreadth)
665 if (myLabelPos == Aspect_TOCSP_NONE
666 || theLabels.IsEmpty())
671 const Standard_Integer aNbLabels = theLabels.Size();
672 const Standard_Integer aNbIntervals = myIsLabelAtBorder ? aNbLabels - 1 : aNbLabels;
673 const Standard_Real aStepY = Standard_Real(theBarHeight) / Standard_Real(aNbIntervals);
679 Standard_Integer aFilter = 0;
681 const Standard_Integer aTitleHeight = !myTitle.IsEmpty() ? (myTextHeight + 2 * mySpacing) : mySpacing;
682 const Standard_Integer aSpc = myHeight - aTitleHeight - ((Min (aNbLabels, 2) + Abs (aNbLabels - aNbIntervals - 1)) * myTextHeight);
688 const Standard_Real aVal = Standard_Real(aNbLabels) * myTextHeight / aSpc;
689 Standard_Real anIPart = 0.0;
690 Standard_Real anFPart = std::modf (aVal, &anIPart);
691 aFilter = (Standard_Integer )anIPart + (anFPart != 0 ? 1 : 0);
698 Standard_Integer anXLeft = myXPos + mySpacing;
699 const Standard_Integer anAscent = 0;
702 case Aspect_TOCSP_NONE:
703 case Aspect_TOCSP_LEFT:
707 case Aspect_TOCSP_CENTER:
709 anXLeft += (theColorBreadth - theMaxLabelWidth) / 2;
712 case Aspect_TOCSP_RIGHT:
714 anXLeft += theColorBreadth + mySpacing;
719 Standard_Integer i1 = 0;
720 Standard_Integer i2 = aNbLabels - 1;
721 Standard_Integer aLast1 = i1;
722 Standard_Integer aLast2 = i2;
723 const Standard_Integer anYBottom = myIsLabelAtBorder
725 : theBarBottom + Standard_Integer(aStepY / 2);
726 while (i2 - i1 >= aFilter || ( i2 == 0 && i1 == 0 ))
728 Standard_Integer aPos1 = i1;
729 Standard_Integer aPos2 = aNbLabels - 1 - i2;
730 if (aFilter && !(aPos1 % aFilter))
732 drawText (theGroup, theLabels.Value (i1 + 1),
733 anXLeft, anYBottom + Standard_Integer(i1 * aStepY + anAscent),
734 Graphic3d_VTA_CENTER);
737 if (aFilter && !(aPos2 % aFilter))
739 drawText (theGroup, theLabels.Value (i2 + 1),
740 anXLeft, anYBottom + Standard_Integer(i2 * aStepY + anAscent),
741 Graphic3d_VTA_CENTER);
747 Standard_Integer aPos = i1;
748 Standard_Integer i0 = -1;
749 while (aPos <= i2 && i0 == -1)
751 if (aFilter && !(aPos % aFilter)
752 && Abs (aPos - aLast1) >= aFilter
753 && Abs (aPos - aLast2) >= aFilter)
762 drawText (theGroup, theLabels.Value (i0 + 1),
763 anXLeft, anYBottom + Standard_Integer(i0 * aStepY + anAscent),
764 Graphic3d_VTA_CENTER);
768 //=======================================================================
769 //function : drawFrame
771 //=======================================================================
772 void AIS_ColorScale::drawFrame (const Handle(Prs3d_Presentation)& thePrs,
773 const Standard_Integer theX, const Standard_Integer theY,
774 const Standard_Integer theWidth, const Standard_Integer theHeight,
775 const Quantity_Color& theColor)
777 Handle(Graphic3d_ArrayOfPolylines) aPrim = new Graphic3d_ArrayOfPolylines(5);
778 aPrim->AddVertex (theX, theY, 0.0);
779 aPrim->AddVertex (theX + theWidth, theY, 0.0);
780 aPrim->AddVertex (theX + theWidth, theY + theHeight, 0.0);
781 aPrim->AddVertex (theX, theY + theHeight, 0.0);
782 aPrim->AddVertex (theX, theY, 0.0);
784 Handle(Graphic3d_AspectLine3d) anAspect = new Graphic3d_AspectLine3d (theColor, Aspect_TOL_SOLID, 1.0);
785 Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
786 aGroup->SetGroupPrimitivesAspect (anAspect);
787 aGroup->AddPrimitiveArray (aPrim);
790 //=======================================================================
791 //function : drawText
793 //=======================================================================
794 void AIS_ColorScale::drawText (const Handle(Graphic3d_Group)& theGroup,
795 const TCollection_ExtendedString& theText,
796 const Standard_Integer theX, const Standard_Integer theY,
797 const Graphic3d_VerticalTextAlignment theVertAlignment)
799 const Handle(Prs3d_TextAspect)& anAspect = myDrawer->TextAspect();
801 Handle(Graphic3d_Text) aText = new Graphic3d_Text ((Standard_ShortReal)anAspect->Height());
802 aText->SetText (theText.ToExtString());
803 aText->SetOrientation (gp_Ax2 (gp_Pnt (theX, theY, 0.0), gp::DZ()));
804 aText->SetOwnAnchorPoint (Standard_False);
805 aText->SetVerticalAlignment (theVertAlignment);
807 theGroup->AddText (aText);
810 //=======================================================================
811 //function : TextWidth
813 //=======================================================================
814 Standard_Integer AIS_ColorScale::TextWidth (const TCollection_ExtendedString& theText) const
816 Standard_Integer aWidth, anAscent, aDescent;
817 TextSize (theText, myTextHeight, aWidth, anAscent, aDescent);
821 //=======================================================================
822 //function : TextHeight
824 //=======================================================================
825 Standard_Integer AIS_ColorScale::TextHeight (const TCollection_ExtendedString& theText) const
827 Standard_Integer aWidth, anAscent, aDescent;
828 TextSize (theText, myTextHeight, aWidth, anAscent, aDescent);
829 return anAscent + aDescent;
832 //=======================================================================
833 //function : TextSize
835 //=======================================================================
836 void AIS_ColorScale::TextSize (const TCollection_ExtendedString& theText,
837 const Standard_Integer theHeight,
838 Standard_Integer& theWidth,
839 Standard_Integer& theAscent,
840 Standard_Integer& theDescent) const
842 if (!HasInteractiveContext())
847 Standard_ShortReal aWidth = 10.0f;
848 Standard_ShortReal anAscent = 1.0f;
849 Standard_ShortReal aDescent = 1.0f;
850 const TCollection_AsciiString aText (theText);
852 const Handle(V3d_Viewer)& aViewer = GetContext()->CurrentViewer();
853 const Handle(Graphic3d_CView)& aView = aViewer->ActiveViewIterator().Value()->View();
854 aViewer->Driver()->TextSize (aView, aText.ToCString(), (Standard_ShortReal)theHeight, aWidth, anAscent, aDescent);
855 theWidth = (Standard_Integer)aWidth;
856 theAscent = (Standard_Integer)anAscent;
857 theDescent = (Standard_Integer)aDescent;