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.
19 #include <AIS_Dimension.hxx>
20 #include <AIS_DimensionDisplayMode.hxx>
21 #include <AIS_DimensionOwner.hxx>
22 #include <AIS_Drawer.hxx>
23 #include <Adaptor3d_HCurve.hxx>
24 #include <BRepAdaptor_Curve.hxx>
25 #include <BRepAdaptor_Surface.hxx>
26 #include <BRepBuilderAPI_MakeEdge.hxx>
27 #include <BRepLib_MakeVertex.hxx>
28 #include <BRepBndLib.hxx>
29 #include <GeomAdaptor_Curve.hxx>
31 #include <Font_BRepFont.hxx>
32 #include <GC_MakeCircle.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Plane.hxx>
35 #include <Geom_TrimmedCurve.hxx>
36 #include <gce_MakeDir.hxx>
37 #include <gce_MakeLin.hxx>
38 #include <Graphic3d_ArrayOfSegments.hxx>
39 #include <Graphic3d_ArrayOfTriangles.hxx>
40 #include <Graphic3d_AspectLine3d.hxx>
41 #include <Graphic3d_AspectFillArea3d.hxx>
42 #include <Graphic3d_AspectText3d.hxx>
43 #include <Graphic3d_Group.hxx>
44 #include <PrsMgr_PresentationManager3d.hxx>
45 #include <Prs3d_Arrow.hxx>
46 #include <Prs3d_ArrowAspect.hxx>
47 #include <Prs3d_Drawer.hxx>
48 #include <Prs3d_LineAspect.hxx>
49 #include <Prs3d_Presentation.hxx>
50 #include <Prs3d_Root.hxx>
51 #include <Prs3d_ShadingAspect.hxx>
52 #include <Prs3d_Text.hxx>
53 #include <SelectMgr_EntityOwner.hxx>
54 #include <SelectMgr_Selection.hxx>
55 #include <SelectMgr_SequenceOfOwner.hxx>
56 #include <Select3D_ListIteratorOfListOfSensitive.hxx>
57 #include <Select3D_ListOfSensitive.hxx>
58 #include <Select3D_SensitiveBox.hxx>
59 #include <Select3D_SensitiveCircle.hxx>
60 #include <Select3D_SensitiveGroup.hxx>
61 #include <Select3D_SensitiveSegment.hxx>
62 #include <Standard_CString.hxx>
63 #include <StdPrs_ShadedShape.hxx>
64 #include <StdPrs_WFShape.hxx>
65 #include <TCollection_AsciiString.hxx>
66 #include <TCollection_ExtendedString.hxx>
67 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Vertex.hxx>
71 #include <Units_UnitsDictionary.hxx>
72 #include <UnitsAPI.hxx>
73 #include <UnitsAPI_SystemUnits.hxx>
75 IMPLEMENT_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject)
76 IMPLEMENT_STANDARD_RTTIEXT(AIS_Dimension, AIS_InteractiveObject)
78 //=======================================================================
79 //function : Constructor
81 //=======================================================================
83 AIS_Dimension::AIS_Dimension (const Standard_Real theExtensionSize /*= 1.0*/)
84 : AIS_InteractiveObject(),
85 myDefaultPlane (gp_Pln (gp::XOY())),
86 myIsWorkingPlaneCustom (Standard_False),
88 myIsValueCustom (Standard_False),
89 myUnitsQuantity (TCollection_AsciiString("LENGTH")),
90 myToDisplayUnits (Standard_False),
91 mySpecialSymbol (' '),
92 myDisplaySpecialSymbol (AIS_DSS_No),
93 myIsTextReversed (Standard_False),
94 myTextOffset (DimensionAspect()->ArrowAspect()->Length()),
95 myIsInitialized (Standard_False),
96 myKindOfDimension (AIS_KOD_NONE),
97 myExtensionSize (theExtensionSize)
100 // Units default settings
101 UnitsAPI::SetLocalSystem (UnitsAPI_SI);
102 myModelUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
103 myDisplayUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
106 //=======================================================================
107 //function : Constructor
109 //=======================================================================
111 AIS_Dimension::AIS_Dimension (const Handle(Prs3d_DimensionAspect)& theAspect,
112 const Standard_Real theExtensionSize /*= 1.0*/)
113 : AIS_InteractiveObject(),
114 myDefaultPlane (gp_Pln (gp::XOY())),
115 myIsWorkingPlaneCustom (Standard_False),
117 myIsValueCustom (Standard_False),
118 myUnitsQuantity (TCollection_AsciiString("LENGTH")),
119 myToDisplayUnits (Standard_False),
120 mySpecialSymbol (' '),
121 myDisplaySpecialSymbol (AIS_DSS_No),
122 myIsTextReversed (Standard_False),
123 myTextOffset (DimensionAspect()->ArrowAspect()->Length()),
124 myIsInitialized (Standard_False),
125 myKindOfDimension (AIS_KOD_NONE),
126 myExtensionSize (theExtensionSize)
129 // Units default settings
130 UnitsAPI::SetLocalSystem (UnitsAPI_SI);
131 myModelUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
132 myDisplayUnits = Units::DictionaryOfUnits()->ActiveUnit (myUnitsQuantity.ToCString());
133 SetDimensionAspect (theAspect);
136 //=======================================================================
137 //function : AcceptDisplayMode
138 //purpose : Checks if display mode <theMode> is allowed to display object.
139 //=======================================================================
141 Standard_Boolean AIS_Dimension::AcceptDisplayMode (const Standard_Integer theMode) const
143 return theMode == 0 ? Standard_True : Standard_False;
146 //=======================================================================
147 //function : computeValue
148 //purpose : Computes dimension value in display units.
149 //=======================================================================
151 void AIS_Dimension::computeValue()
153 UnitsAPI::SetCurrentUnit (myUnitsQuantity.ToCString(), myModelUnits.ToCString());
154 myValue = UnitsAPI::CurrentFromLS (myValue, myUnitsQuantity.ToCString());
155 myValue = valueToDisplayUnits();
158 //=======================================================================
159 //function : countDefaultPlane
161 //=======================================================================
163 void AIS_Dimension::countDefaultPlane()
167 //=======================================================================
168 //function : GetWorkingPlane
170 //=======================================================================
172 const gp_Pln& AIS_Dimension::GetWorkingPlane() const
174 return myWorkingPlane;
177 //=======================================================================
178 //function : SetWorkingPlane
180 //=======================================================================
182 void AIS_Dimension::SetWorkingPlane (const gp_Pln& thePlane)
184 myWorkingPlane = thePlane;
185 myIsWorkingPlaneCustom = Standard_True;
188 //=======================================================================
189 //function : ResetWorkingPlane
190 //purpose : Set default value of working plane
191 //=======================================================================
193 void AIS_Dimension::ResetWorkingPlane()
195 myWorkingPlane = myDefaultPlane;
196 myIsWorkingPlaneCustom = Standard_False;
199 //=======================================================================
200 //function : resetWorkingPlane
201 //purpose : Set default value of working plane
202 // Only for internal use.
203 //=======================================================================
205 void AIS_Dimension::resetWorkingPlane (const gp_Pln& theNewDefaultPlane)
207 myDefaultPlane = theNewDefaultPlane;
211 //=======================================================================
212 //function : valueInDisplayUnits
214 //=======================================================================
216 Standard_Real AIS_Dimension::valueToDisplayUnits()
218 return UnitsAPI::AnyToAny (myValue,
219 myModelUnits.ToCString(),
220 myDisplayUnits.ToCString());
223 //=======================================================================
224 //function : KindOfDimension
226 //=======================================================================
228 AIS_KindOfDimension AIS_Dimension::KindOfDimension() const
230 return myKindOfDimension;
233 //=======================================================================
234 //function : SetKindOfDimension
236 //=======================================================================
238 void AIS_Dimension::SetKindOfDimension (const AIS_KindOfDimension theKindOfDimension)
240 myKindOfDimension = theKindOfDimension;
243 //=======================================================================
244 //function : SetExtensionSize
246 //=======================================================================
248 void AIS_Dimension::SetExtensionSize (const Standard_Real theExtensionSize)
250 myExtensionSize = theExtensionSize;
253 //=======================================================================
254 //function : GetExtensionSize
256 //=======================================================================
258 Standard_Real AIS_Dimension::GetExtensionSize() const
260 return myExtensionSize;
263 //=======================================================================
264 //function : GetValue
266 //=======================================================================
268 Standard_Real AIS_Dimension::GetValue() const
273 //=======================================================================
274 //function : SetCustomValue
276 //=======================================================================
278 void AIS_Dimension::SetCustomValue (const Standard_Real theValue)
281 myIsValueCustom = Standard_True;
284 //=======================================================================
285 //function : SetFirstShape
287 //=======================================================================
289 void AIS_Dimension::SetFirstShape (const TopoDS_Shape& theShape)
291 myFirstShape = theShape;
292 myIsInitialized = Standard_False;
296 //=======================================================================
297 //function : SetSecondShape
299 //=======================================================================
301 void AIS_Dimension::SetSecondShape (const TopoDS_Shape& theShape)
303 mySecondShape = theShape;
304 myIsInitialized = Standard_False;
308 //=======================================================================
309 //function : getTextWidthAndString
311 //=======================================================================
313 void AIS_Dimension::getTextWidthAndString (Quantity_Length& theWidth,
314 TCollection_ExtendedString& theString) const
316 char aValueSimpleStr[25];
317 sprintf (aValueSimpleStr, "%g", GetValue());
318 theString = TCollection_ExtendedString (aValueSimpleStr);
320 if (IsUnitsDisplayed())
323 theString += TCollection_ExtendedString (myDisplayUnits);
326 if (myDisplaySpecialSymbol == AIS_DSS_Before)
328 theString = TCollection_ExtendedString (mySpecialSymbol) + theString;
330 else if (myDisplaySpecialSymbol == AIS_DSS_After)
332 theString += TCollection_ExtendedString (mySpecialSymbol);
336 // Get expansion ratio for getting a width of symbols
337 Quantity_Color aColor;
338 Standard_CString aFont;
339 Standard_Real aFactor;
340 Standard_Real aSpace;
341 myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFont, aFactor, aSpace);
342 theWidth = (myDrawer->DimensionAspect()->TextAspect()->Height() / aFactor) * theString.Length();
345 //=======================================================================
346 //function : drawArrow
348 //=======================================================================
350 void AIS_Dimension::drawArrow (const Handle(Prs3d_Presentation)& thePresentation,
351 const gp_Pnt& theLocation,
352 const gp_Dir& theDirection)
354 Prs3d_Root::NewGroup (thePresentation);
355 Quantity_Length anArrowLength = myDrawer->DimensionAspect()->ArrowAspect()->Length();
357 if (myDrawer->DimensionAspect()->IsArrows3d())
359 Prs3d_Arrow::Draw (thePresentation,
361 theDirection.Reversed(),
362 myDrawer->DimensionAspect()->ArrowAspect()->Angle(),
367 gp_Vec anArrowDir (theDirection);
368 Quantity_Length theCathetusLength = anArrowLength / Cos (M_PI / 9.0);
369 Handle(Graphic3d_ArrayOfTriangles) anArrow = new Graphic3d_ArrayOfTriangles(3);
370 gp_Pnt aLeftPoint (theLocation.Translated (anArrowDir.Rotated (myWorkingPlane.Axis(), M_PI / 9.0) * theCathetusLength));
371 gp_Pnt aRightPoint (theLocation.Translated (anArrowDir.Rotated (myWorkingPlane.Axis(), M_PI * 17.0 / 9.0) * theCathetusLength));
373 anArrow->AddVertex (aLeftPoint);
374 anArrow->AddVertex (theLocation);
375 anArrow->AddVertex (aRightPoint);
377 // Set aspect for arrow triangles
378 Quantity_Color aColor;
379 Aspect_TypeOfLine aTOL;
380 Standard_Real aWidth;
381 myDrawer->DimensionAspect()->ArrowAspect()->Aspect()->Values (aColor, aTOL, aWidth);
382 Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
383 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
384 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
385 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
386 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
387 myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
388 myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
389 Prs3d_Root::CurrentGroup(thePresentation)->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
390 Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray (anArrow);
394 //=======================================================================
395 //function : drawText
397 //=======================================================================
399 Standard_Real AIS_Dimension::drawText (const Handle(Prs3d_Presentation)& thePresentation,
400 const gp_Dir& theTextDir,
401 const TCollection_ExtendedString theText,
402 const AIS_DimensionDisplayMode theMode)
404 Standard_Real aTextWidth (0.0), aTextHeight (0.0);
405 if (theMode == AIS_DDM_Line)
407 // Creating new group for text
408 Prs3d_Root::NewGroup (thePresentation);
410 if (myDrawer->DimensionAspect()->IsText3d())
412 // Getting font parameters
413 Quantity_Color aColor;
414 Standard_CString aFontName;
415 Standard_Real anExpansionFactor;
416 Standard_Real aSpace;
417 myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, anExpansionFactor, aSpace);
418 Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect();
419 Standard_Real aHeight = myDrawer->DimensionAspect()->TextAspect()->Height();
421 // Creating TopoDS_Shape for text
422 Font_BRepFont aFont (aFontName, aFontAspect, aHeight);
423 NCollection_String aText = (Standard_Utf16Char* )theText.ToExtString();
424 TopoDS_Shape aTextShape = aFont.RenderText (aText);
426 // Formating text position in XOY plane
428 BRepBndLib::AddClose (aTextShape, aTextBndBox);
429 Standard_Real aXMin, anYMin, aZMin, aXMax, anYMax, aZMax;
430 aTextBndBox.Get (aXMin, anYMin, aZMin, aXMax, anYMax, aZMax);
431 aTextWidth = aXMax - aXMin;
432 aTextHeight = anYMax - anYMin;
433 gp_Dir aTextDir (theTextDir);
434 Standard_Real aHorizontalOffset (0.0), aVerticalOffset (0.0);
435 switch (myDrawer->DimensionAspect()->HorizontalTextAlignment())
439 aHorizontalOffset = -aTextWidth;
441 case Prs3d_HTA_Center:
442 aHorizontalOffset = -(aTextWidth / 2.0);
444 case Prs3d_HTA_Right:
445 aHorizontalOffset = 0.0;
448 switch (myDrawer->DimensionAspect()->VerticalTextAlignment())
451 aVerticalOffset = 0.0;
453 case Prs3d_VTA_Center:
454 aVerticalOffset = -(aTextHeight / 2.0);
456 case Prs3d_VTA_Bottom:
457 aVerticalOffset = -aTextHeight;
461 aTrsf.SetTranslation (gp_Pnt (), gp_Pnt (aHorizontalOffset, aVerticalOffset, 0.0));
462 aTextShape.Move (aTrsf);
464 // Transform text to myWorkingPlane coordinate system
465 gp_Ax3 aPenAx3 (myGeom.myTextPosition, myWorkingPlane.Axis().Direction(), aTextDir);
466 aTrsf.SetTransformation (aPenAx3, gp_Ax3 (gp::XOY()));
467 aTextShape.Move (aTrsf);
469 // Set display parameters for advanced selection
470 BRepBndLib::AddClose (aTextShape, myGeom.myTextBndBox);
472 if (myDrawer->DimensionAspect()->IsTextShaded())
474 // Setting text shading and color parameters
475 Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT);
476 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT);
477 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE);
478 aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR);
479 myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor);
480 myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor);
481 myDrawer->ShadingAspect()->SetMaterial (aShadeMat);
484 StdPrs_ShadedShape::Add (thePresentation, aTextShape, myDrawer);
488 // Setting color for text
489 myDrawer->FreeBoundaryAspect()->Aspect()->SetColor (aColor);
491 StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer);
493 // Creating new group for lines
494 Prs3d_Root::NewGroup (thePresentation);
498 myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION);
499 Prs3d_Text::Draw (thePresentation,
500 myDrawer->DimensionAspect()->TextAspect(),
502 myGeom.myTextPosition);
504 // For 2d text we don not create new group for lines and draw them in the same group with text
505 // for the proper handling of stencil test buffer.
511 //=======================================================================
512 //function : drawExtensionWithText
514 //=======================================================================
516 void AIS_Dimension::drawExtensionWithText (const Handle(Prs3d_Presentation)& thePresentation,
517 const gp_Pnt& theStartPoint,
518 const gp_Lin& theDimensionLine,
519 const TCollection_ExtendedString& theValueString,
520 const AIS_DimensionDisplayMode theMode)
522 Handle(SelectMgr_EntityOwner) anEmptyOwner;
523 Standard_Boolean isGapInCenter = (myDrawer->DimensionAspect()->VerticalTextAlignment() == Prs3d_VTA_Center
524 && myDrawer->DimensionAspect()->IsText3d());
526 Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (isGapInCenter ? 4 : 2);
528 gp_Dir anAttachPointsVector = myWorkingPlane.Axis().Direction() ^ gce_MakeDir (myFirstPoint, mySecondPoint);
529 Standard_Real aGap = 1.;
530 Standard_Real aStartParam = ElCLib::Parameter (theDimensionLine, theStartPoint);
533 Standard_Real aTextParam = isGapInCenter ? aStartParam + myTextOffset + aGap : aStartParam + myTextOffset;
534 myGeom.myTextPosition = ElCLib::Value (aTextParam, theDimensionLine);
535 Standard_Real aTextWidth = drawText (thePresentation,
536 myIsTextReversed ? theDimensionLine.Direction().Reversed()
537 : theDimensionLine.Direction(),
540 gp_Pnt aFirstPoint, aLastPoint;
541 aFirstPoint = theStartPoint;
542 Standard_Real aParam = isGapInCenter ? aTextParam + aTextWidth + aGap : aTextParam + aTextWidth;
544 // If text separates dimension line into two parts (4 points)
547 aLastPoint = ElCLib::Value (aStartParam + myTextOffset, theDimensionLine);
548 aPrimSegments->AddVertex (aFirstPoint);
549 aPrimSegments->AddVertex (aLastPoint);
550 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
551 aFirstPoint = ElCLib::Value (aParam, theDimensionLine);
554 // Draw additional line segment only after 3D text
555 if (myDrawer->DimensionAspect()->IsText3d())
557 aParam += myTextOffset;
560 aLastPoint = ElCLib::Value (aParam, theDimensionLine);
561 aPrimSegments->AddVertex (aFirstPoint);
562 aPrimSegments->AddVertex (aLastPoint);
563 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
565 // Extension line in the same group
566 if (theMode != AIS_DDM_Text)
568 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
570 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
572 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (myDrawer->DimensionAspect()->LineAspect()->Aspect());
573 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
574 if (!myDrawer->DimensionAspect()->IsText3d() && theMode == AIS_DDM_All)
576 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
581 //=======================================================================
582 //function : SetDimensionAspect
584 //=======================================================================
586 void AIS_Dimension::SetDimensionAspect (const Handle(Prs3d_DimensionAspect)& theDimensionAspect)
588 myDrawer->SetDimensionAspect (theDimensionAspect);
591 //=======================================================================
592 //function : DimensionAspect
594 //=======================================================================
596 Handle(Prs3d_DimensionAspect) AIS_Dimension::DimensionAspect() const
598 return myDrawer->DimensionAspect();
601 //=======================================================================
602 //function : SetTextOffset
604 //=======================================================================
606 void AIS_Dimension::SetTextOffset (const Standard_Real theOffset)
608 myTextOffset = theOffset;
611 //=======================================================================
612 //function : TextOffset
614 //=======================================================================
616 Standard_Real AIS_Dimension::TextOffset() const
621 //=======================================================================
622 //function : drawLinearDimension
624 //=======================================================================
626 void AIS_Dimension::drawLinearDimension (const Handle(Prs3d_Presentation)& thePresentation,
627 const gp_Pnt& theFirstAttach,
628 const gp_Pnt& theSecondAttach,
629 const AIS_DimensionDisplayMode theMode,
630 const Standard_Boolean isOneSideDimension/* = Standard_False*/)
632 // Don't build any dimension for equal points
633 if (myFirstPoint.IsEqual (mySecondPoint, Precision::Confusion()))
635 setComputed (Standard_False);
638 Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect();
639 Handle(SelectMgr_EntityOwner) anEmptyOwner;
640 myGeom.mySensitiveSegments.Clear();
642 gp_Dir aAttachPointsVector = GetWorkingPlane().Axis().Direction()^gce_MakeDir (myFirstPoint, mySecondPoint);
643 // Get line of the dimension
644 gp_Lin aDimensionLine = gce_MakeLin (theFirstAttach, theSecondAttach);
646 // Get parameters on dimension line of two layout points
647 Standard_Real aParam1 = ElCLib::Parameter (aDimensionLine, theFirstAttach);
648 Standard_Real aParam2 = ElCLib::Parameter (aDimensionLine, theSecondAttach);
650 // For extensions we need to know arrow size and text size, get it from aspect
651 Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length();
652 // Set line parameters
653 Standard_Real aGap = 0.; // gap between line and text if AIS_VTA_Center
654 if (!myIsValueCustom)
659 TCollection_ExtendedString aValueString;
660 Standard_Real aTextLength;
661 getTextWidthAndString (aTextLength, aValueString);
663 // Automatical text and arrow placement
664 Standard_Real aValue = myFirstPoint.Distance (mySecondPoint);
665 if (aDimensionAspect->HorizontalTextAlignment() == Prs3d_HTA_Center)
667 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_Internal);
668 if (aValue < aTextLength + (isOneSideDimension ? anArrowLength : 2.0 * anArrowLength))
670 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
671 aDimensionAspect->SetHorizontalTextAlignment (Prs3d_HTA_Left);
676 aDimensionAspect->SetArrowOrientation (Prs3d_DAO_External);
679 // Arrows positions and directions
680 gp_Pnt aFirstArrowPosition = ElCLib::Value (aParam1, aDimensionLine);
681 gp_Pnt aSecondArrowPosition = ElCLib::Value (aParam2, aDimensionLine);
682 gp_Dir aFirstArrowDir = aDimensionLine.Direction();
683 gp_Dir aSecondArrowDir = aDimensionLine.Direction().Reversed();
684 Standard_Real aFirstArrowBegin, aFirstArrowEnd, aSecondArrowBegin, aSecondArrowEnd;
686 if (aDimensionAspect->GetArrowOrientation() == Prs3d_DAO_External)
688 aFirstArrowDir.Reverse();
689 aSecondArrowDir.Reverse();
691 aFirstArrowBegin = aParam1 - anArrowLength;
692 aFirstArrowEnd = aParam1;
693 aSecondArrowBegin = aParam2;
694 aSecondArrowEnd = aParam2 + anArrowLength;
698 aFirstArrowBegin = aParam1;
699 aFirstArrowEnd = aParam1 + anArrowLength;
700 aSecondArrowBegin = aParam2 - anArrowLength;
701 aSecondArrowEnd = aParam2;
704 Handle(Graphic3d_ArrayOfSegments) aPrimSegments;
705 gp_Pnt aFirstPoint, aLastPoint;
706 // Take into account vertical text alignment:
707 // only for 3D text! subtract the text length if it is in the center.
708 Standard_Boolean isGapInCenter = (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Center
709 && aDimensionAspect->IsText3d());
715 switch (aDimensionAspect->HorizontalTextAlignment())
717 // Default case - text is to be in the center of length dimension line
718 case Prs3d_HTA_Center:
721 if (theMode != AIS_DDM_Text)
723 drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
724 if (!isOneSideDimension)
726 drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
730 // Group 2: Text and dimension line
731 aPrimSegments = new Graphic3d_ArrayOfSegments (isGapInCenter ? 4 : 2);
732 myGeom.myTextPosition = ElCLib::Value ((aParam1 + aParam2) / 2.0, aDimensionLine);
734 gp_Vec aTextDir (myFirstPoint, mySecondPoint);
735 Standard_Real aTextWidth = drawText (thePresentation,
736 myIsTextReversed ? aTextDir.Reversed() : aTextDir,
740 aFirstPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
743 aLastPoint = ElCLib::Value (ElCLib::Parameter (aDimensionLine,myGeom.myTextPosition) - aGap - (aTextWidth / 2.0), aDimensionLine);
744 aPrimSegments->AddVertex (aFirstPoint);
745 aPrimSegments->AddVertex (aLastPoint);
746 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner,aFirstPoint,aLastPoint));
747 aFirstPoint = ElCLib::Value (ElCLib::Parameter(aDimensionLine,myGeom.myTextPosition) + (aTextWidth / 2.0) + aGap, aDimensionLine);
749 else if (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Top)
751 aDimensionAspect->TextAspect()->SetVerticalJustification (Graphic3d_VTA_BOTTOM);
753 else if (aDimensionAspect->VerticalTextAlignment() == Prs3d_VTA_Bottom)
755 aDimensionAspect->TextAspect()->SetVerticalJustification(Graphic3d_VTA_TOP);
758 aLastPoint = isOneSideDimension ? theSecondAttach : ElCLib::Value (aSecondArrowBegin, aDimensionLine);
760 aPrimSegments->AddVertex (aFirstPoint);
761 aPrimSegments->AddVertex (aLastPoint);
762 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
764 // Main dimension line, short extension
765 if (theMode != AIS_DDM_Text)
767 if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
769 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True);
771 Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
772 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
773 if (!aDimensionAspect->IsText3d() && theMode == AIS_DDM_All)
775 Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False);
780 // Text is disposed from the left side of length dimension (after the left flyout line)
781 // Needs to create extensions: left for text and right for proper view of dimensions.
784 aPrimSegments = new Graphic3d_ArrayOfSegments (4);
786 gp_Pnt aFirstArrowBeginPnt = ElCLib::Value (aFirstArrowBegin, aDimensionLine);
787 gp_Lin aLongExtLine (aDimensionLine.Location(), aDimensionLine.Direction().Reversed());
788 gp_Pnt aStartPoint = ElCLib::Value (aFirstArrowBegin, aDimensionLine);
789 // Left extension with the text
790 drawExtensionWithText (thePresentation, aStartPoint, aLongExtLine, aValueString, theMode);
792 // Central(main) dimension line
793 aFirstPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
794 aLastPoint = isOneSideDimension ? theSecondAttach : ElCLib::Value (aSecondArrowBegin, aDimensionLine);
795 aPrimSegments->AddVertex (aFirstPoint);
796 aPrimSegments->AddVertex (aLastPoint);
797 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
800 if (!isOneSideDimension)
802 aFirstPoint = ElCLib::Value (aSecondArrowEnd, aDimensionLine);
803 aLastPoint = ElCLib::Value (aSecondArrowEnd + anArrowLength, aDimensionLine);
804 aPrimSegments->AddVertex (aFirstPoint);
805 aPrimSegments->AddVertex (aLastPoint);
806 myGeom.mySensitiveSegments.Append(new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
808 if (theMode != AIS_DDM_Text)
810 // Main dimension line, short extension
811 Prs3d_Root::NewGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
812 Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments);
813 // Group1: Add arrows to a group
814 drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
815 if (!isOneSideDimension)
817 drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
822 case Prs3d_HTA_Right:
824 aPrimSegments = new Graphic3d_ArrayOfSegments (4);
826 if (!isOneSideDimension)
828 aFirstPoint = ElCLib::Value (aFirstArrowBegin - anArrowLength, aDimensionLine);
829 aLastPoint = ElCLib::Value (aFirstArrowEnd, aDimensionLine);
830 aPrimSegments->AddVertex (aFirstPoint);
831 aPrimSegments->AddVertex (aLastPoint);
832 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
835 // Central(main) dimension line
836 aFirstPoint = isOneSideDimension ? theFirstAttach : ElCLib::Value (aFirstArrowEnd, aDimensionLine);
837 aLastPoint = ElCLib::Value (aSecondArrowBegin, aDimensionLine);
838 aPrimSegments->AddVertex (aFirstPoint);
839 aPrimSegments->AddVertex (aLastPoint);
840 myGeom.mySensitiveSegments.Append (new Select3D_SensitiveSegment (anEmptyOwner, aFirstPoint, aLastPoint));
842 // Right extension with text
843 aFirstPoint = ElCLib::Value (aSecondArrowEnd, aDimensionLine);
844 drawExtensionWithText (thePresentation, aFirstPoint, aDimensionLine, aValueString, theMode);
846 if (theMode != AIS_DDM_Text)
848 // Main dimension line, short extension
849 Prs3d_Root::NewGroup(thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect());
850 Prs3d_Root::CurrentGroup(thePresentation)->AddPrimitiveArray (aPrimSegments);
851 // Group1, 2: Add arrows to a group
852 if (!isOneSideDimension)
854 drawArrow (thePresentation, aFirstArrowPosition, aFirstArrowDir);
857 drawArrow (thePresentation, aSecondArrowPosition, aSecondArrowDir);
863 setComputed (Standard_True);
866 //=======================================================================
867 //function : SetFirstPoint
869 //=======================================================================
871 void AIS_Dimension::SetFirstPoint (const gp_Pnt& thePoint)
873 myFirstPoint = thePoint;
876 //=======================================================================
877 //function : SetSecondPoint
879 //=======================================================================
881 void AIS_Dimension::SetSecondPoint (const gp_Pnt& thePoint)
883 mySecondPoint = thePoint;
886 //=======================================================================
889 //=======================================================================
891 AIS_KindOfInteractive AIS_Dimension::Type() const
893 return AIS_KOI_Relation;
896 //=======================================================================
897 //function : circleFromPlanarFace
898 //purpose : if possible computes circle from planar face
899 //=======================================================================
901 Standard_Boolean AIS_Dimension::circleFromPlanarFace (const TopoDS_Face& theFace,
902 Handle(Geom_Curve)& theCurve,
903 gp_Pnt & theFirstPoint,
904 gp_Pnt & theLastPoint)
906 TopExp_Explorer anIt (theFace, TopAbs_EDGE);
907 for ( ; anIt.More(); anIt.Next())
909 TopoDS_Edge aCurEdge = TopoDS::Edge (anIt.Current());
910 if (AIS::ComputeGeometry (aCurEdge, theCurve, theFirstPoint, theLastPoint))
912 if (theCurve->IsInstance (STANDARD_TYPE(Geom_Circle)))
914 return Standard_True;
918 return Standard_False;
921 //=======================================================================
922 //function : initCircularDimension
923 //purpose : if it's possible computes circle from planar face
924 //=======================================================================
926 Standard_Boolean AIS_Dimension::initCircularDimension (const TopoDS_Shape& theShape,
928 gp_Pnt& theMiddleArcPoint,
929 gp_Pnt& theOppositeDiameterPoint)
932 Handle(Geom_Surface) aBasisSurf;
933 AIS_KindOfSurface aSurfType = AIS_KOS_OtherSurface;
934 gp_Pnt aFirstPoint, aLastPoint;
935 Standard_Real anOffset = 0.0;
936 Standard_Real aFirstParam = 0.0;
937 Standard_Real aLastParam = 0.0;
938 Standard_Boolean isAnArc = Standard_False;
940 if (theShape.ShapeType() == TopAbs_FACE)
942 AIS::GetPlaneFromFace (TopoDS::Face (theShape), aPln, aBasisSurf, aSurfType, anOffset);
944 if (aSurfType == AIS_KOS_Plane)
946 Handle(Geom_Curve) aCurve;
947 if (!circleFromPlanarFace (TopoDS::Face (theShape), aCurve, aFirstPoint, aLastPoint))
949 Standard_ConstructionError::Raise ("AIS_Dimension:: Curve is not a circle or is Null") ;
950 return Standard_False;
953 theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
954 isAnArc = !(aFirstPoint.IsEqual (aLastPoint, Precision::Confusion()));
959 BRepAdaptor_Surface aSurf1 (TopoDS::Face (theShape));
960 Standard_Real aFirstU = aSurf1.FirstUParameter();
961 Standard_Real aLastU = aSurf1.LastUParameter();
962 Standard_Real aFirstV = aSurf1.FirstVParameter();
963 Standard_Real aLastV = aSurf1.LastVParameter();
964 Standard_Real aMidU = (aFirstU + aLastU) * 0.5;
965 Standard_Real aMidV = (aFirstV + aLastV) * 0.5;
966 aSurf1.D0(aMidU, aMidV, aCurPos);
967 Handle (Adaptor3d_HCurve) aBasisCurve;
968 Standard_Boolean isExpectedType = Standard_False;
969 if (aSurfType == AIS_KOS_Cylinder)
971 isExpectedType = Standard_True;
975 if (aSurfType == AIS_KOS_Revolution)
977 aBasisCurve = aSurf1.BasisCurve();
978 if (aBasisCurve->GetType() == GeomAbs_Line)
980 isExpectedType = Standard_True;
983 else if (aSurfType == AIS_KOS_Extrusion)
985 aBasisCurve = aSurf1.BasisCurve();
986 if (aBasisCurve->GetType() == GeomAbs_Circle)
988 isExpectedType = Standard_True;
995 Standard_ConstructionError::Raise ("AIS_Dimension:: Unexpected type of surface") ;
996 return Standard_False;
998 Handle(Geom_Curve) aCurve;
999 aCurve = aBasisSurf->VIso(aMidV);
1000 if (aCurve->DynamicType() == STANDARD_TYPE (Geom_Circle))
1002 theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ();
1004 else if (aCurve->DynamicType() == STANDARD_TYPE (Geom_TrimmedCurve))
1006 Handle(Geom_TrimmedCurve) aTrimmedCurve = Handle(Geom_TrimmedCurve)::DownCast (aCurve);
1007 aFirstU = aTrimmedCurve->FirstParameter();
1008 aLastU = aTrimmedCurve->LastParameter();
1009 if (aTrimmedCurve->DynamicType() == STANDARD_TYPE (Geom_Circle))
1011 theCircle = Handle(Geom_Circle)::DownCast(aTrimmedCurve)->Circ();
1016 // Compute a circle from 3 points on "aCurve"
1018 aSurf1.D0 (aFirstU, aMidV, aP1);
1019 aSurf1.D0 (aLastU, aMidV, aP2);
1020 GC_MakeCircle aMkCirc (aP1, aCurPos, aP2);
1021 theCircle = aMkCirc.Value()->Circ();
1024 gp_Vec aVec = gp_Vec (theCircle.Location(), aCurPos).Normalized();
1025 aFirstPoint = ElCLib::Value (aFirstU, theCircle);
1026 aLastPoint = ElCLib::Value (aLastU, theCircle);
1029 else // TopAbs_EDGE | TopAbs_WIRE
1032 if (theShape.ShapeType() == TopAbs_WIRE)
1034 TopExp_Explorer anIt (theShape, TopAbs_EDGE);
1037 anEdge = TopoDS::Edge (anIt.Current());
1040 else if (theShape.ShapeType() == TopAbs_EDGE)
1042 anEdge = TopoDS::Edge (theShape);
1044 else // Unexpected type of shape
1046 Standard_ConstructionError::Raise ("AIS_Dimension:: Unexpected type of shape");
1047 return Standard_False;
1049 BRepAdaptor_Curve anAdaptedCurve (anEdge);
1050 if (!anAdaptedCurve.GetType() == GeomAbs_Circle)
1052 return Standard_False;
1054 theCircle = anAdaptedCurve.Circle();
1055 aFirstPoint = anAdaptedCurve.Value (anAdaptedCurve.FirstParameter());
1056 aLastPoint = anAdaptedCurve.Value (anAdaptedCurve.LastParameter());
1058 // Get <theMiddleArcPoint> and <theOppositeDiameterPoint> values from <theCircle>
1059 isAnArc = !(aFirstPoint.IsEqual (aLastPoint, Precision::Confusion()));
1060 gp_Pnt aCenter = theCircle.Location();
1064 gp_Dir anXDir = theCircle.XAxis().Direction();
1065 theMiddleArcPoint = aCenter.Translated (gp_Vec (anXDir) * theCircle.Radius());
1066 theOppositeDiameterPoint = aCenter.Translated (-gp_Vec (anXDir) * theCircle.Radius());
1071 aFirstParam = ElCLib::Parameter (theCircle, aFirstPoint);
1072 aLastParam = ElCLib::Parameter (theCircle, aLastPoint);
1073 if (aFirstParam > aLastParam)
1075 aFirstParam -= 2.0 * M_PI;
1077 Standard_Real aParCurPos = (aFirstParam + aLastParam) * 0.5;
1078 gp_Vec aVec = gp_Vec (aCenter, ElCLib::Value (aParCurPos, theCircle)).Normalized () * theCircle.Radius ();
1079 theMiddleArcPoint = aCenter.Translated (aVec);
1080 theOppositeDiameterPoint = aCenter.Translated (-aVec);
1083 return Standard_True;
1086 //=======================================================================
1087 //function : SetDisplaySpecialSymbol
1088 //purpose : specifies dimension special symbol display options
1089 //=======================================================================
1091 void AIS_Dimension::SetDisplaySpecialSymbol (const AIS_DisplaySpecialSymbol theDisplaySpecSymbol)
1093 myDisplaySpecialSymbol = theDisplaySpecSymbol;
1096 //=======================================================================
1097 //function : DisplaySpecialSymbol
1098 //purpose : shows dimension special symbol display options
1099 //=======================================================================
1101 AIS_DisplaySpecialSymbol AIS_Dimension::DisplaySpecialSymbol() const
1103 return myDisplaySpecialSymbol;
1106 //=======================================================================
1107 //function : SetSpecialSymbol
1108 //purpose : specifies special symbol
1109 //=======================================================================
1111 void AIS_Dimension::SetSpecialSymbol (const Standard_ExtCharacter theSpecialSymbol)
1113 mySpecialSymbol = theSpecialSymbol;
1116 //=======================================================================
1117 //function : SpecialSymbol
1118 //purpose : returns special symbol
1119 //=======================================================================
1121 Standard_ExtCharacter AIS_Dimension::SpecialSymbol() const
1123 return mySpecialSymbol;
1126 //=======================================================================
1127 //function : IsUnitsDisplayed
1128 //purpose : shows if Units are to be displayed along with dimension value
1129 //=======================================================================
1131 Standard_Boolean AIS_Dimension::IsUnitsDisplayed() const
1133 return myToDisplayUnits;
1136 //=======================================================================
1137 //function : MakeUnitsDisplayed
1138 //purpose : sets to display units along with the dimension value or no
1139 //=======================================================================
1141 void AIS_Dimension::MakeUnitsDisplayed (const Standard_Boolean toDisplayUnits)
1143 myToDisplayUnits = toDisplayUnits;
1146 //=======================================================================
1147 //function : MakeUnitsDisplayed
1148 //purpose : returns the current type of units
1149 //=======================================================================
1151 TCollection_AsciiString AIS_Dimension::UnitsQuantity() const
1153 return myUnitsQuantity;
1156 //=======================================================================
1157 //function : SetUnitsQuantity
1158 //purpose : sets the current type of units
1159 //=======================================================================
1161 void AIS_Dimension::SetUnitsQuantity (const TCollection_AsciiString& theUnitsQuantity)
1163 myUnitsQuantity = theUnitsQuantity;
1166 //=======================================================================
1167 //function : ModelUnits
1168 //purpose : returns the current model units
1169 //=======================================================================
1171 TCollection_AsciiString AIS_Dimension::ModelUnits() const
1173 return myModelUnits;
1176 //=======================================================================
1177 //function : SetModelUnits
1178 //purpose : sets the current model units
1179 //=======================================================================
1181 void AIS_Dimension::SetModelUnits (const TCollection_AsciiString& theUnits)
1183 myModelUnits = theUnits;
1186 //=======================================================================
1187 //function : DisplayUnits
1188 //purpose : returns the current display units
1189 //=======================================================================
1191 TCollection_AsciiString AIS_Dimension::DisplayUnits() const
1193 return myDisplayUnits;
1196 //=======================================================================
1197 //function : SetDisplayUnits
1198 //purpose : sets the current display units
1199 //=======================================================================
1201 void AIS_Dimension::SetDisplayUnits (const TCollection_AsciiString& theUnits)
1203 myDisplayUnits = theUnits;
1206 //=======================================================================
1207 //function : isComputed
1209 //=======================================================================
1211 Standard_Boolean AIS_Dimension::isComputed() const
1213 return myGeom.myIsComputed;
1216 //=======================================================================
1217 //function : setComputed
1219 //=======================================================================
1221 void AIS_Dimension::setComputed (Standard_Boolean isComputed)
1223 myGeom.myIsComputed = isComputed;
1226 //=======================================================================
1227 //function : textPosition
1229 //=======================================================================
1231 gp_Pnt AIS_Dimension::textPosition() const
1233 return myGeom.myTextPosition;
1236 //=======================================================================
1237 //function : setTextPosition
1239 //=======================================================================
1241 void AIS_Dimension::setTextPosition (const gp_Pnt thePosition)
1243 myGeom.myTextPosition = thePosition;
1246 //=======================================================================
1247 //function : resetGeom
1249 //=======================================================================
1251 void AIS_Dimension::resetGeom()
1253 setComputed (Standard_False);
1256 //=======================================================================
1257 //function : IsTextReversed
1259 //=======================================================================
1261 Standard_Boolean AIS_Dimension::IsTextReversed() const
1263 return myIsTextReversed;
1266 //=======================================================================
1267 //function : MakeTextReversed
1269 //=======================================================================
1271 void AIS_Dimension::MakeTextReversed (const Standard_Boolean isTextReversed)
1273 myIsTextReversed = isTextReversed;
1276 //=======================================================================
1277 //function : SetSelToleranceForText2d
1279 //=======================================================================
1281 void AIS_Dimension::SetSelToleranceForText2d (const Standard_Real theTol)
1283 myGeom.mySelToleranceForText2d = theTol;
1286 //=======================================================================
1287 //function : SelToleranceForText2d
1289 //=======================================================================
1291 Standard_Real AIS_Dimension::SelToleranceForText2d() const
1293 return myGeom.mySelToleranceForText2d;
1296 //=======================================================================
1297 //function : ComputeSelection
1299 //=======================================================================
1301 void AIS_Dimension::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
1302 const Standard_Integer theMode)
1309 Handle( Select3D_SensitiveGroup) aSensitiveForLine;
1310 Handle(Select3D_SensitiveEntity) aSensitiveForText;
1311 Select3D_ListOfSensitive aSensitiveList;
1312 aSensitiveList.Assign (myGeom.mySensitiveSegments);
1314 // Full dimension selection
1315 Handle(AIS_DimensionOwner) anOwner = new AIS_DimensionOwner (this, AIS_DDM_All, theMode == 0 ? 5 : 6);
1316 for (Select3D_ListIteratorOfListOfSensitive anIt (aSensitiveList); anIt.More(); anIt.Next())
1318 anIt.Value()->Set (anOwner);
1320 aSensitiveForLine = new Select3D_SensitiveGroup (anOwner, aSensitiveList);
1323 if (myDrawer->DimensionAspect()->IsText3d())
1325 aSensitiveForText = new Select3D_SensitiveBox (anOwner,myGeom.myTextBndBox);
1329 Handle(Geom_Circle) aSensitiveGeom = new Geom_Circle (gp_Circ (gp_Ax2 (myGeom.myTextPosition,
1330 myWorkingPlane.Position().XDirection()),
1331 myGeom.mySelToleranceForText2d != 0
1332 ? myGeom.mySelToleranceForText2d : 1.0));
1333 aSensitiveForText = new Select3D_SensitiveCircle (anOwner, aSensitiveGeom, Standard_True);
1337 anOwner->SetDisplayMode (AIS_DDM_Line);
1338 Handle(AIS_DimensionOwner) aTextOwner = new AIS_DimensionOwner (this, AIS_DDM_Text, 7);
1339 aSensitiveForText->Set (aTextOwner);
1342 theSelection->Add (aSensitiveForLine);
1343 theSelection->Add (aSensitiveForText);