1 // Copyright (c) 1999-2013 OPEN CASCADE SAS
3 // The content of this file is subject to the Open CASCADE Technology Public
4 // License Version 6.5 (the "License"). You may not use the content of this file
5 // except in compliance with the License. Please obtain a copy of the License
6 // at http://www.opencascade.org and read it completely before using this file.
8 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
9 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 // The Original Code and all software distributed under the License is
12 // distributed on an "AS IS" basis, without warranty of any kind, and the
13 // Initial Developer hereby disclaims all such warranties, including without
14 // limitation, any warranties of merchantability, fitness for a particular
15 // purpose or non-infringement. Please see the License for the specific terms
16 // and conditions governing the rights and limitations under the License.
18 #include <AIS_Dimension.hxx>
21 #include <AIS_DimensionDisplayMode.hxx>
22 #include <AIS_DimensionOwner.hxx>
23 #include <AIS_Drawer.hxx>
24 #include <Adaptor3d_HCurve.hxx>
25 #include <BRepAdaptor_Curve.hxx>
26 #include <BRepAdaptor_Surface.hxx>
27 #include <BRepBuilderAPI_MakeEdge.hxx>
28 #include <BRepLib_MakeVertex.hxx>
29 #include <BRepBndLib.hxx>
30 #include <GeomAdaptor_Curve.hxx>
32 #include <Font_BRepFont.hxx>
33 #include <GC_MakeCircle.hxx>
34 #include <Geom_Circle.hxx>
35 #include <Geom_Plane.hxx>
36 #include <Geom_TrimmedCurve.hxx>
37 #include <gce_MakeDir.hxx>
38 #include <gce_MakeLin.hxx>
39 #include <Graphic3d_ArrayOfSegments.hxx>
40 #include <Graphic3d_ArrayOfTriangles.hxx>
41 #include <Graphic3d_AspectLine3d.hxx>
42 #include <Graphic3d_AspectFillArea3d.hxx>
43 #include <Graphic3d_AspectText3d.hxx>
44 #include <Graphic3d_Group.hxx>
45 #include <PrsMgr_PresentationManager3d.hxx>
46 #include <Prs3d_Arrow.hxx>
47 #include <Prs3d_ArrowAspect.hxx>
48 #include <Prs3d_Drawer.hxx>
49 #include <Prs3d_LineAspect.hxx>
50 #include <Prs3d_Presentation.hxx>
51 #include <Prs3d_Root.hxx>
52 #include <Prs3d_ShadingAspect.hxx>
53 #include <Prs3d_Text.hxx>
54 #include <SelectMgr_EntityOwner.hxx>
55 #include <SelectMgr_Selection.hxx>
56 #include <SelectMgr_SequenceOfOwner.hxx>
57 #include <Select3D_ListIteratorOfListOfSensitive.hxx>
58 #include <Select3D_ListOfSensitive.hxx>
59 #include <Select3D_SensitiveBox.hxx>
60 #include <Select3D_SensitiveCircle.hxx>
61 #include <Select3D_SensitiveGroup.hxx>
62 #include <Select3D_SensitiveSegment.hxx>
63 #include <Standard_CString.hxx>
64 #include <StdPrs_ShadedShape.hxx>
65 #include <StdPrs_WFShape.hxx>
66 #include <TCollection_AsciiString.hxx>
67 #include <TCollection_ExtendedString.hxx>
68 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Vertex.hxx>
72 #include <Units_UnitsDictionary.hxx>
73 #include <UnitsAPI.hxx>
74 #include <UnitsAPI_SystemUnits.hxx>
76 IMPLEMENT_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
77 IMPLEMENT_STANDARD_RTTIEXT(AIS_Dimension, AIS_InteractiveObject)
81 static const Standard_Utf32Char THE_FILL_CHARACTER ('0');
82 static const TCollection_ExtendedString THE_EMPTY_LABEL;
83 static const Standard_Real THE_3D_TEXT_MARGIN = 0.1;
86 //=======================================================================
87 //function : Constructor
89 //=======================================================================
90 AIS_Dimension::AIS_Dimension()
91 : AIS_InteractiveObject(),
92 myDefaultPlane (gp_Pln (gp::XOY())),
93 myIsWorkingPlaneCustom (Standard_False),
95 myIsValueCustom (Standard_False),
96 myUnitsQuantity (TCollection_AsciiString("LENGTH")),
97 myToDisplayUnits (Standard_False),
98 mySpecialSymbol (' '),
99 myDisplaySpecialSymbol (AIS_DSS_No),
100 myIsTextReversed (Standard_False),
101 myIsInitialized (Standard_False),
103 myKindOfDimension (AIS_KOD_NONE)
106 // Units default settings
107 UnitsAPI::SetLocalSystem (UnitsAPI_SI);
108 myModelUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
109 myDisplayUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
112 //=======================================================================
113 //function : AcceptDisplayMode
114 //purpose : Checks if display mode <theMode> is allowed to display object.
115 //=======================================================================
116 Standard_Boolean AIS_Dimension::AcceptDisplayMode (const Standard_Integer theMode) const
118 return theMode == 0 ? Standard_True : Standard_False;
121 //=======================================================================
122 //function : computeValue
123 //purpose : Computes dimension value in display units.
124 //=======================================================================
125 void AIS_Dimension::computeValue()
127 UnitsAPI::SetCurrentUnit (myUnitsQuantity.ToCString(), myModelUnits.ToCString());
128 myValue = UnitsAPI::CurrentFromLS (myValue, myUnitsQuantity.ToCString());
129 myValue = valueToDisplayUnits();
132 //=======================================================================
133 //function : countDefaultPlane
135 //=======================================================================
136 void AIS_Dimension::countDefaultPlane()
140 //=======================================================================
141 //function : GetWorkingPlane
143 //=======================================================================
144 const gp_Pln& AIS_Dimension::GetWorkingPlane() const
146 return myWorkingPlane;
149 //=======================================================================
150 //function : SetWorkingPlane
152 //=======================================================================
153 void AIS_Dimension::SetWorkingPlane (const gp_Pln& thePlane)
155 myWorkingPlane = thePlane;
156 myIsWorkingPlaneCustom = Standard_True;
159 //=======================================================================
160 //function : ResetWorkingPlane
161 //purpose : Set default value of working plane
162 //=======================================================================
163 void AIS_Dimension::ResetWorkingPlane()
165 myWorkingPlane = myDefaultPlane;
166 myIsWorkingPlaneCustom = Standard_False;
169 //=======================================================================
170 //function : resetWorkingPlane
171 //purpose : Set default value of working plane
172 // Only for internal use.
173 //=======================================================================
174 void AIS_Dimension::resetWorkingPlane (const gp_Pln& theNewDefaultPlane)
176 myDefaultPlane = theNewDefaultPlane;
180 //=======================================================================
181 //function : valueInDisplayUnits
183 //=======================================================================
184 Standard_Real AIS_Dimension::valueToDisplayUnits()
186 return UnitsAPI::AnyToAny (myValue,
187 myModelUnits.ToCString(),
188 myDisplayUnits.ToCString());
191 //=======================================================================
192 //function : KindOfDimension
194 //=======================================================================
195 AIS_KindOfDimension AIS_Dimension::KindOfDimension() const
197 return myKindOfDimension;
200 //=======================================================================
201 //function : SetKindOfDimension
203 //=======================================================================
204 void AIS_Dimension::SetKindOfDimension (const AIS_KindOfDimension theKindOfDimension)
206 myKindOfDimension = theKindOfDimension;
209 //=======================================================================
210 //function : GetValue
212 //=======================================================================
213 Standard_Real AIS_Dimension::GetValue() const
218 //=======================================================================
219 //function : SetCustomValue
221 //=======================================================================
222 void AIS_Dimension::SetCustomValue (const Standard_Real theValue)
225 myIsValueCustom = Standard_True;
228 //=======================================================================
229 //function : SetFirstShape
231 //=======================================================================
232 void AIS_Dimension::SetFirstShape (const TopoDS_Shape& theShape)
234 myFirstShape = theShape;
235 myIsInitialized = Standard_False;
239 //=======================================================================
240 //function : SetSecondShape
242 //=======================================================================
243 void AIS_Dimension::SetSecondShape (const TopoDS_Shape& theShape)
245 mySecondShape = theShape;
246 myIsInitialized = Standard_False;
250 //=======================================================================
251 //function : getTextWidthAndString
253 //=======================================================================
254 void AIS_Dimension::getTextWidthAndString (Quantity_Length& theWidth,
255 TCollection_ExtendedString& theString) const
257 char aValueSimpleStr[25];
258 sprintf (aValueSimpleStr, "%g", GetValue());
259 theString = TCollection_ExtendedString (aValueSimpleStr);
261 if (IsUnitsDisplayed())
264 theString += TCollection_ExtendedString (myDisplayUnits);
267 if (myDisplaySpecialSymbol == AIS_DSS_Before)
269 theString = TCollection_ExtendedString (mySpecialSymbol) + theString;
271 else if (myDisplaySpecialSymbol == AIS_DSS_After)
273 theString += TCollection_ExtendedString (mySpecialSymbol);
276 // Get text style parameters
277 Quantity_Color aColor;
278 Standard_CString aFontName;
279 Standard_Real aFactor;
280 Standard_Real aSpace;
281 myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, aFactor, aSpace);
282 // Init font instance
283 Handle(Font_FTFont) aFont = new Font_FTFont ();
284 aFont->Init (aFontName,
285 myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect(),
286 (Standard_Integer) myDrawer->DimensionAspect()->TextAspect()->Height(), 72);
288 TCollection_ExtendedString aString (theString);
290 Standard_PCharacter aUtf8String = new Standard_Character[aString.Length()];
291 Standard_Integer aStrLength = aString.ToUTF8CString(aUtf8String);
293 for (Standard_Integer anIt = 0; anIt < aStrLength - 1; ++anIt)
295 Standard_Real anAdvance = aFont->AdvanceX (aUtf8String[anIt], aUtf8String[anIt + 1]);
296 theWidth += anAdvance;
300 //=======================================================================
301 //function : drawArrow
303 //=======================================================================
304 void AIS_Dimension::drawArrow (const Handle(Prs3d_Presentation)& thePresentation,
305 const gp_Pnt& theLocation,
306 const gp_Dir& theDirection)
308 Prs3d_Root::NewGroup (thePresentation);
309 Quantity_Length anArrowLength = myDrawer->DimensionAspect()->ArrowAspect()->Length();
311 if (myDrawer->DimensionAspect()->IsArrows3d())
313 Prs3d_Arrow::Draw (thePresentation,
316 myDrawer->DimensionAspect()->ArrowAspect()->Angle(),
321 gp_Vec aBackDir (theDirection.Reversed());
322 Quantity_Length theCathetusLength = anArrowLength / Cos (M_PI / 9.0);
323 Handle(Graphic3d_ArrayOfTriangles) anArrow = new Graphic3d_ArrayOfTriangles(3);
324 gp_Pnt aLeftPoint (theLocation.Translated (aBackDir.Rotated (myWorkingPlane.Axis(), M_PI / 9.0) * theCathetusLength));
325 gp_Pnt aRightPoint (theLocation.Translated (aBackDir.Rotated (myWorkingPlane.Axis(), M_PI * 17.0 / 9.0) * theCathetusLength));
327 anArrow->AddVertex (aLeftPoint);
328 anArrow->AddVertex (theLocation);
329 anArrow->AddVertex (aRightPoint);
331 // Set aspect for arrow triangles
332 Quantity_Color aColor;
333 Aspect_TypeOfLine aTOL;
334 Standard_Real aWidth;
335 myDrawer->DimensionAspect()->ArrowAspect()->Aspect()->Values (aColor, aTOL, aWidth);
336 Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
337 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
338 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
339 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
341 Handle(Prs3d_ShadingAspect) aShadingStyle = new Prs3d_ShadingAspect();
342 aShadingStyle->SetColor (aColor);
343 aShadingStyle->SetMaterial (aShadeMat);
345 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aShadingStyle->Aspect());
346 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (anArrow);
350 //=======================================================================
351 //function : drawText
353 //=======================================================================
354 Standard_Real AIS_Dimension::drawText (const Handle(Prs3d_Presentation)& thePresentation,
355 const gp_Dir& theTextDir,
356 const TCollection_ExtendedString theText,
357 const AIS_DimensionDisplayMode theMode,
358 const Standard_Integer theLabelPosition)
360 Standard_Real aTextWidth (0.0), aTextHeight (0.0);
361 if (theMode == AIS_DDM_Line)
366 if (myDrawer->DimensionAspect()->IsText3d())
368 // Getting font parameters
369 Quantity_Color aColor;
370 Standard_CString aFontName;
371 Standard_Real anExpansionFactor;
372 Standard_Real aSpace;
373 myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, anExpansionFactor, aSpace);
374 Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect();
375 Standard_Real aHeight = myDrawer->DimensionAspect()->TextAspect()->Height();
377 // Creating TopoDS_Shape for text
378 Font_BRepFont aFont (aFontName, aFontAspect, aHeight);
379 NCollection_String aText = (Standard_Utf16Char* )theText.ToExtString();
380 TopoDS_Shape aTextShape = aFont.RenderText (aText);
382 // Formating text position in XOY plane
384 BRepBndLib::AddClose (aTextShape, aTextBndBox);
385 Standard_Real aXMin, anYMin, aZMin, aXMax, anYMax, aZMax;
386 aTextBndBox.Get (aXMin, anYMin, aZMin, aXMax, anYMax, aZMax);
387 aTextWidth = aXMax - aXMin;
388 aTextHeight = anYMax - anYMin;
390 Standard_Integer aHLabelPos = theLabelPosition & LabelPosition_HMask;
391 Standard_Integer aVLabelPos = theLabelPosition & LabelPosition_VMask;
393 gp_Dir aTextDir (aHLabelPos == LabelPosition_Left ? -theTextDir : theTextDir);
395 // compute label offsets
396 Standard_Real aMarginSize = aHeight * THE_3D_TEXT_MARGIN;
397 Standard_Real aCenterHOffset = 0.0;
398 Standard_Real aCenterVOffset = 0.0;
401 case LabelPosition_HCenter : aCenterHOffset = 0.0; break;
402 case LabelPosition_Right : aCenterHOffset = aTextWidth / 2.0 + aMarginSize; break;
403 case LabelPosition_Left : aCenterHOffset = -aTextWidth / 2.0 - aMarginSize; break;
407 case LabelPosition_VCenter : aCenterVOffset = 0.0; break;
408 case LabelPosition_Above : aCenterVOffset = aTextHeight / 2.0 + aMarginSize; break;
409 case LabelPosition_Below : aCenterVOffset = -aTextHeight / 2.0 - aMarginSize; break;
412 // compute shape offset transformation
413 Standard_Real aShapeHOffset = aCenterHOffset - aTextWidth / 2.0;
414 Standard_Real aShapeVOffset = aCenterVOffset - aTextHeight / 2.0;
416 gp_Trsf anOffsetTrsf;
417 anOffsetTrsf.SetTranslation (gp::Origin(), gp_Pnt (aShapeHOffset, aShapeVOffset, 0.0));
418 aTextShape.Move (anOffsetTrsf);
420 // Transform text to myWorkingPlane coordinate system
421 gp_Ax3 aTextCoordSystem (myGeom.myTextPosition, myWorkingPlane.Axis().Direction(), aTextDir);
422 gp_Trsf aTextPlaneTrsf;
423 aTextPlaneTrsf.SetTransformation (aTextCoordSystem, gp_Ax3 (gp::XOY()));
424 aTextShape.Move (aTextPlaneTrsf);
426 // Set display parameters for advanced selection
427 BRepBndLib::AddClose (aTextShape, myGeom.myTextBndBox);
429 // Set text flipping anchors
430 gp_Trsf aCenterOffsetTrsf;
431 gp_Pnt aCenterOffset (aCenterHOffset, aCenterVOffset, 0.0);
432 aCenterOffsetTrsf.SetTranslation (gp::Origin(), aCenterOffset);
434 gp_Pnt aCenterOfFlip (gp::Origin());
435 aCenterOfFlip.Transform (aCenterOffsetTrsf);
436 aCenterOfFlip.Transform (aTextPlaneTrsf);
438 gp_Ax2 aFlippingAxes (aCenterOfFlip, myWorkingPlane.Axis().Direction(), aTextDir);
439 Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_True, aFlippingAxes);
442 if (myDrawer->DimensionAspect()->IsTextShaded())
444 // Setting text shading and color parameters
445 Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
446 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
447 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
448 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
449 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
450 myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
451 myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
454 StdPrs_ShadedShape::Add (thePresentation, aTextShape, myDrawer);
458 // Setting color for text
459 myDrawer->FreeBoundaryAspect()->Aspect()->SetColor (aColor);
461 StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer);
463 Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_False, gp_Ax2());
465 return aTextWidth + aMarginSize * 2.0;
468 myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION);
470 Prs3d_Text::Draw (thePresentation,
471 myDrawer->DimensionAspect()->TextAspect(),
473 myGeom.myTextPosition);
475 // For 2d text we don not create new group for lines and draw them in the same group with text
476 // for the proper handling of stencil test buffer.
480 //=======================================================================
481 //function : drawExtension
483 //=======================================================================
484 void AIS_Dimension::drawExtension (const Handle(Prs3d_Presentation)& thePresentation,
485 const Standard_Real theExtensionSize,
486 const gp_Pnt& theExtensionStart,
487 const gp_Dir& theExtensionDir,
488 const TCollection_ExtendedString& theValueString,
489 const AIS_DimensionDisplayMode theMode,
490 const Standard_Integer theLabelPosition)
492 Standard_Real aTextWidth = 0.0;
494 Standard_Boolean isLabel = theValueString.Length() > 0;
497 // compute text primitives; get its model width
498 myGeom.myTextPosition = theExtensionStart.Translated (
499 gp_Vec (theExtensionDir).Scaled (theExtensionSize));
501 aTextWidth = drawText (thePresentation,
502 myIsTextReversed ? -theExtensionDir : theExtensionDir,
508 if (theMode == AIS_DDM_Text)
513 // compute graphical primitives and sensitives for extension line
514 gp_Pnt anExtStart = theExtensionStart;
515 gp_Pnt anExtEnd = !isLabel || (theLabelPosition & LabelPosition_VCenter) != 0
516 ? theExtensionStart.Translated (gp_Vec (theExtensionDir) * theExtensionSize)
517 : theExtensionStart.Translated (gp_Vec (theExtensionDir) * (theExtensionSize + aTextWidth));
519 Handle(Graphic3d_ArrayOfSegments) anExtPrimitive = new Graphic3d_ArrayOfSegments (2);
520 anExtPrimitive->AddVertex (anExtStart);
521 anExtPrimitive->AddVertex (anExtEnd);
523 Handle(SelectMgr_EntityOwner) aDummyOwner;
525 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (aDummyOwner, anExtStart, anExtEnd));
527 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
529 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
531 Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect();
532 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle);
533 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (anExtPrimitive);
534 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
536 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
540 //=======================================================================
541 //function : SetDimensionAspect
543 //=======================================================================
544 void AIS_Dimension::SetDimensionAspect (const Handle(Prs3d_DimensionAspect)& theDimensionAspect)
546 myDrawer->SetDimensionAspect (theDimensionAspect);
549 //=======================================================================
550 //function : DimensionAspect
552 //=======================================================================
553 Handle(Prs3d_DimensionAspect) AIS_Dimension::DimensionAspect() const
555 return myDrawer->DimensionAspect();
558 //=======================================================================
559 //function : drawLinearDimension
561 //=======================================================================
562 void AIS_Dimension::drawLinearDimension (const Handle(Prs3d_Presentation)& thePresentation,
563 const AIS_DimensionDisplayMode theMode,
564 const Standard_Boolean isOneSideDimension/* = Standard_False*/)
566 // Don't build any dimension for equal points
567 if (myFirstPoint.IsEqual (mySecondPoint, Precision::Confusion()))
569 setComputed (Standard_False);
573 // compute dimension line points
574 gp_Ax1 aWorkingPlaneNormal = GetWorkingPlane().Axis();
575 gp_Dir aTargetPointsVector = gce_MakeDir (myFirstPoint, mySecondPoint);
577 // compute flyout direction vector
578 gp_Dir aFlyoutVector = aWorkingPlaneNormal.Direction() ^ aTargetPointsVector;
580 // create lines for layouts
581 gp_Lin aLine1 (myFirstPoint, aFlyoutVector);
582 gp_Lin aLine2 (mySecondPoint, aFlyoutVector);
584 // Get flyout end points
585 gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, myFirstPoint) + GetFlyout(), aLine1);
586 gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, mySecondPoint) + GetFlyout(), aLine2);
588 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
589 Handle(SelectMgr_EntityOwner) anEmptyOwner;
590 myGeom.mySensitiveSegments.Clear();
592 gp_Lin aDimensionLine = gce_MakeLin (aLineBegPoint, aLineEndPoint);
594 // For extensions we need to know arrow size, text size and extension size: get it from aspect
595 Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
596 Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize();
598 if (!myIsValueCustom)
603 TCollection_ExtendedString aValueString;
604 Standard_Real aTextLength;
605 getTextWidthAndString (aTextLength, aValueString);
607 // Handle user-defined and automatic arrow placement
608 bool isArrowsExternal = false;
609 switch (aDimensionAspect->ArrowOrientation())
611 case Prs3d_DAO_External: isArrowsExternal = true; break;
612 case Prs3d_DAO_Internal: isArrowsExternal = false; break;
615 Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
616 Standard_Real anArrowsWidth = isOneSideDimension ? anArrowLength : 2.0 * anArrowLength;
617 isArrowsExternal = aDimensionWidth < aTextLength + anArrowsWidth;
622 // Arrows positions and directions
623 gp_Dir aFirstArrowDir = aDimensionLine.Direction().Reversed();
624 gp_Dir aSecondArrowDir = aDimensionLine.Direction();
625 gp_Dir aFirstExtensionDir = aDimensionLine.Direction().Reversed();
626 gp_Dir aSecondExtensionDir = aDimensionLine.Direction();
628 gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0);
629 gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0);
630 gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0);
631 gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0);
633 if (isArrowsExternal)
635 aFirstArrowDir.Reverse();
636 aSecondArrowDir.Reverse();
639 aFirstArrowBegin = aLineBegPoint;
640 aSecondArrowBegin = aLineEndPoint;
641 aFirstArrowEnd = aLineBegPoint.Translated (-gp_Vec (aFirstArrowDir).Scaled (anArrowLength));
642 aSecondArrowEnd = aLineEndPoint.Translated (-gp_Vec (aSecondArrowDir).Scaled (anArrowLength));
644 gp_Pnt aCenterLineBegin = isArrowsExternal
645 ? aLineBegPoint : aFirstArrowEnd;
647 gp_Pnt aCenterLineEnd = isArrowsExternal || isOneSideDimension
648 ? aLineEndPoint : aSecondArrowEnd;
650 Standard_Integer aLabelPosition = LabelPosition_None;
652 // Handle user-defined and automatic text placement
653 switch (aDimensionAspect->TextHorizontalPosition())
655 case Prs3d_DTHP_Left : aLabelPosition |= LabelPosition_Left; break;
656 case Prs3d_DTHP_Right : aLabelPosition |= LabelPosition_Right; break;
657 case Prs3d_DTHP_Center: aLabelPosition |= LabelPosition_HCenter; break;
660 Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint);
661 Standard_Real anArrowsWidth = isOneSideDimension ? anArrowLength : 2.0 * anArrowLength;
662 Standard_Real aContentWidth = isArrowsExternal ? aTextLength : aTextLength + anArrowsWidth;
664 aLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter;
669 switch (aDimensionAspect->TextVerticalPosition())
671 case Prs3d_DTVP_Above : aLabelPosition |= LabelPosition_Above; break;
672 case Prs3d_DTVP_Below : aLabelPosition |= LabelPosition_Below; break;
673 case Prs3d_DTVP_Center : aLabelPosition |= LabelPosition_VCenter; break;
676 switch (aLabelPosition & LabelPosition_HMask)
678 // ------------------------------------------------------------------------ //
680 // -------------------------------------------------------------------------//
682 case LabelPosition_HCenter:
684 // add label on dimension or extension line to presentation
685 Prs3d_Root::NewGroup (thePresentation);
687 gp_Vec aTextDir (aLineBegPoint, aLineEndPoint);
689 myGeom.myTextPosition = gp_XYZ (aLineBegPoint.XYZ() + aLineEndPoint.XYZ()) * 0.5;
691 Standard_Real aTextWidth = drawText (thePresentation,
692 myIsTextReversed ? -aTextDir : aTextDir,
697 if (theMode == AIS_DDM_Text)
702 Standard_Real aLabelMargin =
703 aDimensionAspect->IsText3d() ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN : 0.0;
705 Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center
706 && aDimensionAspect->IsText3d();
708 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (isLineBreak ? 4 : 2);
710 // compute dimension continuous or sectioned dimension line
713 Standard_Real aPTextPosition = ElCLib::Parameter (aDimensionLine, myGeom.myTextPosition);
714 gp_Pnt aSection1Beg = aCenterLineBegin;
715 gp_Pnt aSection1End = ElCLib::Value (aPTextPosition - aLabelMargin - (aTextWidth * 0.5), aDimensionLine);
716 gp_Pnt aSection2Beg = ElCLib::Value (aPTextPosition + aLabelMargin + (aTextWidth * 0.5), aDimensionLine);
717 gp_Pnt aSection2End = aCenterLineEnd;
719 aPrimSegments->AddVertex (aSection1Beg);
720 aPrimSegments->AddVertex (aSection1End);
721 aPrimSegments->AddVertex (aSection2Beg);
722 aPrimSegments->AddVertex (aSection2End);
724 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aSection1Beg, aSection1End));
725 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aSection2Beg, aSection2End));
729 aPrimSegments->AddVertex (aCenterLineBegin);
730 aPrimSegments->AddVertex (aCenterLineEnd);
732 myGeom.mySensitiveSegments.Append (
733 new Select3D_SensitiveSegment (anEmptyOwner, aCenterLineBegin, aCenterLineEnd));
736 // set text label justification
737 Graphic3d_VerticalTextAlignment aTextJustificaton = Graphic3d_VTA_BOTTOM;
738 switch (aLabelPosition & LabelPosition_VMask)
740 case LabelPosition_Above :
741 case LabelPosition_VCenter : aTextJustificaton = Graphic3d_VTA_BOTTOM; break;
742 case LabelPosition_Below : aTextJustificaton = Graphic3d_VTA_TOP; break;
744 aDimensionAspect->TextAspect()->SetVerticalJustification (aTextJustificaton);
746 // Main dimension line, short extension
747 if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
749 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
751 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
752 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
753 if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
755 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
758 // add arrows to presentation
759 Prs3d_Root::NewGroup (thePresentation);
761 drawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir);
762 if (!isOneSideDimension)
764 drawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
767 if (!isArrowsExternal)
772 // add arrow extension lines to presentation
773 Prs3d_Root::NewGroup (thePresentation);
775 drawExtension (thePresentation, anExtensionSize,
776 aFirstArrowEnd, aFirstExtensionDir,
777 THE_EMPTY_LABEL, theMode, LabelPosition_None);
778 if (!isOneSideDimension)
780 drawExtension (thePresentation, anExtensionSize,
781 aSecondArrowEnd, aSecondExtensionDir,
782 THE_EMPTY_LABEL, theMode, LabelPosition_None);
785 // ------------------------------------------------------------------------ //
787 // -------------------------------------------------------------------------//
789 case LabelPosition_Left:
791 // add label on dimension or extension line to presentation
792 Prs3d_Root::NewGroup (thePresentation);
794 // Left extension with the text
795 drawExtension (thePresentation, anExtensionSize,
796 isArrowsExternal ? aFirstArrowEnd : aLineBegPoint,
802 if (theMode == AIS_DDM_Text)
807 // add central dimension line
808 Prs3d_Root::NewGroup (thePresentation);
810 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
811 aPrimSegments->AddVertex (aCenterLineBegin);
812 aPrimSegments->AddVertex (aCenterLineEnd);
813 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
814 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
816 myGeom.mySensitiveSegments.Append (
817 new Select3D_SensitiveSegment (anEmptyOwner, aCenterLineBegin, aCenterLineEnd));
819 // add arrows to presentation
820 Prs3d_Root::NewGroup (thePresentation);
822 drawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir);
823 if (!isOneSideDimension)
825 drawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
828 if (!isArrowsExternal || isOneSideDimension)
833 // add extension lines for external arrows
834 Prs3d_Root::NewGroup (thePresentation);
836 drawExtension (thePresentation, anExtensionSize,
837 aSecondArrowEnd, aSecondExtensionDir,
838 THE_EMPTY_LABEL, theMode, LabelPosition_None);
842 // ------------------------------------------------------------------------ //
844 // -------------------------------------------------------------------------//
846 case LabelPosition_Right:
848 // add label on dimension or extension line to presentation
849 Prs3d_Root::NewGroup (thePresentation);
851 // Right extension with text
852 drawExtension (thePresentation, anExtensionSize,
853 isArrowsExternal ? aSecondArrowEnd : aSecondArrowBegin,
859 if (theMode == AIS_DDM_Text)
864 // add central dimension line
865 Prs3d_Root::NewGroup (thePresentation);
867 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2);
868 aPrimSegments->AddVertex (aCenterLineBegin);
869 aPrimSegments->AddVertex (aCenterLineEnd);
870 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
871 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
873 myGeom.mySensitiveSegments.Append (
874 new Select3D_SensitiveSegment (anEmptyOwner, aCenterLineBegin, aCenterLineEnd));
876 // add arrows to presentation
877 Prs3d_Root::NewGroup (thePresentation);
879 drawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir);
880 if (!isOneSideDimension)
882 drawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir);
885 if (!isArrowsExternal || isOneSideDimension)
890 // add extension lines for external arrows
891 Prs3d_Root::NewGroup (thePresentation);
893 drawExtension (thePresentation, anExtensionSize,
894 aFirstArrowEnd, aFirstExtensionDir,
895 THE_EMPTY_LABEL, theMode, LabelPosition_None);
900 // add flyout lines to presentation
901 if (theMode == AIS_DDM_All)
903 Prs3d_Root::NewGroup (thePresentation);
905 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments(4);
906 aPrimSegments->AddVertex (myFirstPoint);
907 aPrimSegments->AddVertex (aLineBegPoint);
909 aPrimSegments->AddVertex (mySecondPoint);
910 aPrimSegments->AddVertex (aLineEndPoint);
912 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
913 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
914 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
917 setComputed (Standard_True);
920 //=======================================================================
921 //function : SetFirstPoint
923 //=======================================================================
924 void AIS_Dimension::SetFirstPoint (const gp_Pnt& thePoint)
926 myFirstPoint = thePoint;
929 //=======================================================================
930 //function : SetSecondPoint
932 //=======================================================================
933 void AIS_Dimension::SetSecondPoint (const gp_Pnt& thePoint)
935 mySecondPoint = thePoint;
938 //=======================================================================
941 //=======================================================================
942 AIS_KindOfInteractive AIS_Dimension::Type() const
944 return AIS_KOI_Relation;
947 //=======================================================================
948 //function : circleFromPlanarFace
949 //purpose : if possible computes circle from planar face
950 //=======================================================================
951 Standard_Boolean AIS_Dimension::circleFromPlanarFace (const TopoDS_Face& theFace,
952 Handle(Geom_Curve)& theCurve,
953 gp_Pnt & theFirstPoint,
954 gp_Pnt & theLastPoint)
956 TopExp_Explorer anIt (theFace, TopAbs_EDGE);
957 for ( ; anIt.More(); anIt.Next())
959 TopoDS_Edge aCurEdge = TopoDS::Edge (anIt.Current());
960 if (AIS::ComputeGeometry (aCurEdge, theCurve, theFirstPoint, theLastPoint))
962 if (theCurve->IsInstance (STANDARD_TYPE(Geom_Circle)))
964 return Standard_True;
968 return Standard_False;
971 //=======================================================================
972 //function : initCircularDimension
973 //purpose : if it's possible computes circle from planar face
974 //=======================================================================
975 Standard_Boolean AIS_Dimension::initCircularDimension (const TopoDS_Shape& theShape,
977 gp_Pnt& theMiddleArcPoint,
978 gp_Pnt& theOppositeDiameterPoint)
981 Handle(Geom_Surface) aBasisSurf;
982 AIS_KindOfSurface aSurfType = AIS_KOS_OtherSurface;
983 gp_Pnt aFirstPoint, aLastPoint;
984 Standard_Real anOffset = 0.0;
985 Standard_Real aFirstParam = 0.0;
986 Standard_Real aLastParam = 0.0;
987 Standard_Boolean isAnArc = Standard_False;
989 if (theShape.ShapeType() == TopAbs_FACE)
991 AIS::GetPlaneFromFace (TopoDS::Face (theShape), aPln, aBasisSurf, aSurfType, anOffset);
993 if (aSurfType == AIS_KOS_Plane)
995 Handle(Geom_Curve) aCurve;
996 if (!circleFromPlanarFace (TopoDS::Face (theShape), aCurve, aFirstPoint, aLastPoint))
998 Standard_ConstructionError::Raise ("AIS_Dimension:: Curve is not a circle or is Null") ;
999 return Standard_False;
1002 theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
1003 isAnArc = !(aFirstPoint.IsEqual (aLastPoint, Precision::Confusion()));
1008 BRepAdaptor_Surface aSurf1 (TopoDS::Face (theShape));
1009 Standard_Real aFirstU = aSurf1.FirstUParameter();
1010 Standard_Real aLastU = aSurf1.LastUParameter();
1011 Standard_Real aFirstV = aSurf1.FirstVParameter();
1012 Standard_Real aLastV = aSurf1.LastVParameter();
1013 Standard_Real aMidU = (aFirstU + aLastU) * 0.5;
1014 Standard_Real aMidV = (aFirstV + aLastV) * 0.5;
1015 aSurf1.D0(aMidU, aMidV, aCurPos);
1016 Handle (Adaptor3d_HCurve) aBasisCurve;
1017 Standard_Boolean isExpectedType = Standard_False;
1018 if (aSurfType == AIS_KOS_Cylinder)
1020 isExpectedType = Standard_True;
1024 if (aSurfType == AIS_KOS_Revolution)
1026 aBasisCurve = aSurf1.BasisCurve();
1027 if (aBasisCurve->GetType() == GeomAbs_Line)
1029 isExpectedType = Standard_True;
1032 else if (aSurfType == AIS_KOS_Extrusion)
1034 aBasisCurve = aSurf1.BasisCurve();
1035 if (aBasisCurve->GetType() == GeomAbs_Circle)
1037 isExpectedType = Standard_True;
1042 if (!isExpectedType)
1044 Standard_ConstructionError::Raise ("AIS_Dimension:: Unexpected type of surface") ;
1045 return Standard_False;
1047 Handle(Geom_Curve) aCurve;
1048 aCurve = aBasisSurf->VIso(aMidV);
1049 if (aCurve->DynamicType() == STANDARD_TYPE (Geom_Circle))
1051 theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
1053 else if (aCurve->DynamicType() == STANDARD_TYPE (Geom_TrimmedCurve))
1055 Handle(Geom_TrimmedCurve) aTrimmedCurve = Handle(Geom_TrimmedCurve)::DownCast (aCurve);
1056 aFirstU = aTrimmedCurve->FirstParameter();
1057 aLastU = aTrimmedCurve->LastParameter();
1058 if (aTrimmedCurve->DynamicType() == STANDARD_TYPE (Geom_Circle))
1060 theCircle = Handle(Geom_Circle)::DownCast(aTrimmedCurve)->Circ();
1065 // Compute a circle from 3 points on "aCurve"
1067 aSurf1.D0 (aFirstU, aMidV, aP1);
1068 aSurf1.D0 (aLastU, aMidV, aP2);
1069 GC_MakeCircle aMkCirc (aP1, aCurPos, aP2);
1070 theCircle = aMkCirc.Value()->Circ();
1073 gp_Vec aVec = gp_Vec (theCircle.Location(), aCurPos).Normalized();
1074 aFirstPoint = ElCLib::Value (aFirstU, theCircle);
1075 aLastPoint = ElCLib::Value (aLastU, theCircle);
1078 else // TopAbs_EDGE | TopAbs_WIRE
1081 if (theShape.ShapeType() == TopAbs_WIRE)
1083 TopExp_Explorer anIt (theShape, TopAbs_EDGE);
1086 anEdge = TopoDS::Edge (anIt.Current());
1089 else if (theShape.ShapeType() == TopAbs_EDGE)
1091 anEdge = TopoDS::Edge (theShape);
1093 else // Unexpected type of shape
1095 Standard_ConstructionError::Raise ("AIS_Dimension:: Unexpected type of shape");
1096 return Standard_False;
1098 BRepAdaptor_Curve anAdaptedCurve (anEdge);
1099 if (!anAdaptedCurve.GetType() == GeomAbs_Circle)
1101 return Standard_False;
1103 theCircle = anAdaptedCurve.Circle();
1104 aFirstPoint = anAdaptedCurve.Value (anAdaptedCurve.FirstParameter());
1105 aLastPoint = anAdaptedCurve.Value (anAdaptedCurve.LastParameter());
1107 // Get <theMiddleArcPoint> and <theOppositeDiameterPoint> values from <theCircle>
1108 isAnArc = !(aFirstPoint.IsEqual (aLastPoint, Precision::Confusion()));
1109 gp_Pnt aCenter = theCircle.Location();
1113 gp_Dir anXDir = theCircle.XAxis().Direction();
1114 theMiddleArcPoint = aCenter.Translated (gp_Vec (anXDir) * theCircle.Radius());
1115 theOppositeDiameterPoint = aCenter.Translated (-gp_Vec (anXDir) * theCircle.Radius());
1120 aFirstParam = ElCLib::Parameter (theCircle, aFirstPoint);
1121 aLastParam = ElCLib::Parameter (theCircle, aLastPoint);
1122 if (aFirstParam > aLastParam)
1124 aFirstParam -= 2.0 * M_PI;
1126 Standard_Real aParCurPos = (aFirstParam + aLastParam) * 0.5;
1127 gp_Vec aVec = gp_Vec (aCenter, ElCLib::Value (aParCurPos, theCircle)).Normalized () * theCircle.Radius ();
1128 theMiddleArcPoint = aCenter.Translated (aVec);
1129 theOppositeDiameterPoint = aCenter.Translated (-aVec);
1132 return Standard_True;
1135 //=======================================================================
1136 //function : SetDisplaySpecialSymbol
1137 //purpose : specifies dimension special symbol display options
1138 //=======================================================================
1139 void AIS_Dimension::SetDisplaySpecialSymbol (const AIS_DisplaySpecialSymbol theDisplaySpecSymbol)
1141 myDisplaySpecialSymbol = theDisplaySpecSymbol;
1144 //=======================================================================
1145 //function : DisplaySpecialSymbol
1146 //purpose : shows dimension special symbol display options
1147 //=======================================================================
1148 AIS_DisplaySpecialSymbol AIS_Dimension::DisplaySpecialSymbol() const
1150 return myDisplaySpecialSymbol;
1153 //=======================================================================
1154 //function : SetSpecialSymbol
1155 //purpose : specifies special symbol
1156 //=======================================================================
1157 void AIS_Dimension::SetSpecialSymbol (const Standard_ExtCharacter theSpecialSymbol)
1159 mySpecialSymbol = theSpecialSymbol;
1162 //=======================================================================
1163 //function : SpecialSymbol
1164 //purpose : returns special symbol
1165 //=======================================================================
1166 Standard_ExtCharacter AIS_Dimension::SpecialSymbol() const
1168 return mySpecialSymbol;
1171 //=======================================================================
1172 //function : IsUnitsDisplayed
1173 //purpose : shows if Units are to be displayed along with dimension value
1174 //=======================================================================
1175 Standard_Boolean AIS_Dimension::IsUnitsDisplayed() const
1177 return myToDisplayUnits;
1180 //=======================================================================
1181 //function : MakeUnitsDisplayed
1182 //purpose : sets to display units along with the dimension value or no
1183 //=======================================================================
1184 void AIS_Dimension::MakeUnitsDisplayed (const Standard_Boolean toDisplayUnits)
1186 myToDisplayUnits = toDisplayUnits;
1189 //=======================================================================
1190 //function : MakeUnitsDisplayed
1191 //purpose : returns the current type of units
1192 //=======================================================================
1193 TCollection_AsciiString AIS_Dimension::UnitsQuantity() const
1195 return myUnitsQuantity;
1198 //=======================================================================
1199 //function : SetUnitsQuantity
1200 //purpose : sets the current type of units
1201 //=======================================================================
1202 void AIS_Dimension::SetUnitsQuantity (const TCollection_AsciiString& theUnitsQuantity)
1204 myUnitsQuantity = theUnitsQuantity;
1207 //=======================================================================
1208 //function : ModelUnits
1209 //purpose : returns the current model units
1210 //=======================================================================
1211 TCollection_AsciiString AIS_Dimension::ModelUnits() const
1213 return myModelUnits;
1216 //=======================================================================
1217 //function : SetModelUnits
1218 //purpose : sets the current model units
1219 //=======================================================================
1220 void AIS_Dimension::SetModelUnits (const TCollection_AsciiString& theUnits)
1222 myModelUnits = theUnits;
1225 //=======================================================================
1226 //function : DisplayUnits
1227 //purpose : returns the current display units
1228 //=======================================================================
1229 TCollection_AsciiString AIS_Dimension::DisplayUnits() const
1231 return myDisplayUnits;
1234 //=======================================================================
1235 //function : SetDisplayUnits
1236 //purpose : sets the current display units
1237 //=======================================================================
1238 void AIS_Dimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
1240 myDisplayUnits = theUnits;
1243 //=======================================================================
1244 //function : isComputed
1246 //=======================================================================
1247 Standard_Boolean AIS_Dimension::isComputed() const
1249 return myGeom.myIsComputed;
1252 //=======================================================================
1253 //function : setComputed
1255 //=======================================================================
1256 void AIS_Dimension::setComputed (Standard_Boolean isComputed)
1258 myGeom.myIsComputed = isComputed;
1261 //=======================================================================
1262 //function : textPosition
1264 //=======================================================================
1265 gp_Pnt AIS_Dimension::textPosition() const
1267 return myGeom.myTextPosition;
1270 //=======================================================================
1271 //function : setTextPosition
1273 //=======================================================================
1274 void AIS_Dimension::setTextPosition (const gp_Pnt thePosition)
1276 myGeom.myTextPosition = thePosition;
1279 //=======================================================================
1280 //function : resetGeom
1282 //=======================================================================
1283 void AIS_Dimension::resetGeom()
1285 setComputed (Standard_False);
1288 //=======================================================================
1289 //function : IsTextReversed
1291 //=======================================================================
1292 Standard_Boolean AIS_Dimension::IsTextReversed() const
1294 return myIsTextReversed;
1297 //=======================================================================
1298 //function : MakeTextReversed
1300 //=======================================================================
1301 void AIS_Dimension::MakeTextReversed (const Standard_Boolean isTextReversed)
1303 myIsTextReversed = isTextReversed;
1306 //=======================================================================
1307 //function : SetSelToleranceForText2d
1309 //=======================================================================
1310 void AIS_Dimension::SetSelToleranceForText2d (const Standard_Real theTol)
1312 myGeom.mySelToleranceForText2d = theTol;
1315 //=======================================================================
1316 //function : SelToleranceForText2d
1318 //=======================================================================
1319 Standard_Real AIS_Dimension::SelToleranceForText2d() const
1321 return myGeom.mySelToleranceForText2d;
1324 //=======================================================================
1325 //function : SetFlyout
1327 //=======================================================================
1328 void AIS_Dimension::SetFlyout (const Standard_Real theFlyout)
1330 if (myFlyout == theFlyout)
1335 myFlyout = theFlyout;
1339 //=======================================================================
1340 //function : computeFlyoutSelection
1341 //purpose : computes selection for flyouts
1342 //=======================================================================
1343 void AIS_Dimension::computeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection,
1344 const Handle(AIS_DimensionOwner)& theOwner)
1346 //Count flyout direction
1347 gp_Ax1 aWorkingPlaneNormal = GetWorkingPlane().Axis();
1348 gp_Dir aTargetPointsVector = gce_MakeDir (myFirstPoint, mySecondPoint);
1350 // Count a flyout direction vector.
1351 gp_Dir aFlyoutVector = aWorkingPlaneNormal.Direction()^aTargetPointsVector;
1353 // Create lines for layouts
1354 gp_Lin aLine1 (myFirstPoint, aFlyoutVector);
1355 gp_Lin aLine2 (mySecondPoint, aFlyoutVector);
1357 // Get flyout end points
1358 gp_Pnt aFlyoutEnd1 = ElCLib::Value (ElCLib::Parameter (aLine1, myFirstPoint) + GetFlyout(), aLine1);
1359 gp_Pnt aFlyoutEnd2 = ElCLib::Value (ElCLib::Parameter (aLine2, mySecondPoint) + GetFlyout(), aLine2);
1361 // Fill sensitive entity for flyouts
1362 Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner);
1363 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, myFirstPoint, aFlyoutEnd1));
1364 aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, mySecondPoint, aFlyoutEnd2));
1365 theSelection->Add (aSensitiveEntity);
1368 //=======================================================================
1369 //function : ComputeSelection
1371 //=======================================================================
1372 void AIS_Dimension::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
1373 const Standard_Integer theMode)
1380 Handle(Select3D_SensitiveGroup) aSensitiveForLine;
1381 Handle(Select3D_SensitiveEntity) aSensitiveForText;
1382 Select3D_ListOfSensitive aSensitiveList;
1383 aSensitiveList.Assign (myGeom.mySensitiveSegments);
1385 // Full dimension selection
1386 Handle(AIS_DimensionOwner) anOwner = new AIS_DimensionOwner (this, AIS_DDM_All, theMode == 0 ? 5 : 6);
1387 for (Select3D_ListIteratorOfListOfSensitive anIt (aSensitiveList); anIt.More(); anIt.Next())
1389 anIt.Value()->Set (anOwner);
1391 aSensitiveForLine = new Select3D_SensitiveGroup (anOwner, aSensitiveList);
1394 if (myDrawer->DimensionAspect()->IsText3d())
1396 aSensitiveForText = new Select3D_SensitiveBox (anOwner,myGeom.myTextBndBox);
1400 Handle(Geom_Circle) aSensitiveGeom = new Geom_Circle (gp_Circ (gp_Ax2 (myGeom.myTextPosition,
1401 myWorkingPlane.Position().XDirection()),
1402 myGeom.mySelToleranceForText2d != 0
1403 ? myGeom.mySelToleranceForText2d : 1.0));
1404 aSensitiveForText = new Select3D_SensitiveCircle (anOwner, aSensitiveGeom, Standard_True);
1408 anOwner->SetDisplayMode (AIS_DDM_Line);
1409 Handle(AIS_DimensionOwner) aTextOwner = new AIS_DimensionOwner (this, AIS_DDM_Text, 7);
1410 aSensitiveForText->Set (aTextOwner);
1414 computeFlyoutSelection (theSelection, anOwner);
1417 theSelection->Add (aSensitiveForLine);
1418 theSelection->Add (aSensitiveForText);