60bf98ae |
1 | // Created on: 2013-11-11 |
2 | // Created by: Anastasia BORISOVA |
d5f74e42 |
3 | // Copyright (c) 2013-2014 OPEN CASCADE SAS |
a6eb515f |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
a6eb515f |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
a6eb515f |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
a6eb515f |
15 | |
a6eb515f |
16 | #include <AIS_Dimension.hxx> |
d7bffd44 |
17 | |
18 | #include <AIS.hxx> |
a6eb515f |
19 | #include <AIS_DimensionOwner.hxx> |
a6eb515f |
20 | #include <Adaptor3d_HCurve.hxx> |
21 | #include <BRepAdaptor_Curve.hxx> |
22 | #include <BRepAdaptor_Surface.hxx> |
a6eb515f |
23 | #include <BRepBndLib.hxx> |
60bf98ae |
24 | #include <Bnd_Box.hxx> |
a6eb515f |
25 | #include <ElCLib.hxx> |
26 | #include <Font_BRepFont.hxx> |
27 | #include <GC_MakeCircle.hxx> |
af203d54 |
28 | #include <Geom_Line.hxx> |
fe83e1ea |
29 | #include <GeomAdaptor_Curve.hxx> |
a6eb515f |
30 | #include <Geom_Circle.hxx> |
a6eb515f |
31 | #include <Geom_TrimmedCurve.hxx> |
32 | #include <gce_MakeDir.hxx> |
33 | #include <gce_MakeLin.hxx> |
af203d54 |
34 | #include <gce_MakePln.hxx> |
a6eb515f |
35 | #include <Graphic3d_ArrayOfSegments.hxx> |
36 | #include <Graphic3d_ArrayOfTriangles.hxx> |
37 | #include <Graphic3d_AspectLine3d.hxx> |
38 | #include <Graphic3d_AspectFillArea3d.hxx> |
39 | #include <Graphic3d_AspectText3d.hxx> |
40 | #include <Graphic3d_Group.hxx> |
41 | #include <PrsMgr_PresentationManager3d.hxx> |
42 | #include <Prs3d_Arrow.hxx> |
43 | #include <Prs3d_ArrowAspect.hxx> |
44 | #include <Prs3d_Drawer.hxx> |
45 | #include <Prs3d_LineAspect.hxx> |
46 | #include <Prs3d_Presentation.hxx> |
47 | #include <Prs3d_Root.hxx> |
48 | #include <Prs3d_ShadingAspect.hxx> |
49 | #include <Prs3d_Text.hxx> |
50 | #include <SelectMgr_EntityOwner.hxx> |
51 | #include <SelectMgr_Selection.hxx> |
52 | #include <SelectMgr_SequenceOfOwner.hxx> |
53 | #include <Select3D_ListIteratorOfListOfSensitive.hxx> |
54 | #include <Select3D_ListOfSensitive.hxx> |
a6eb515f |
55 | #include <Select3D_SensitiveCircle.hxx> |
56 | #include <Select3D_SensitiveGroup.hxx> |
fe83e1ea |
57 | #include <Select3D_SensitiveCurve.hxx> |
a6eb515f |
58 | #include <Select3D_SensitiveSegment.hxx> |
fe83e1ea |
59 | #include <Select3D_SensitiveTriangle.hxx> |
51f8f60c |
60 | #include <Select3D_SensitiveTriangulation.hxx> |
61 | #include <Poly_Array1OfTriangle.hxx> |
62 | #include <Poly_Triangulation.hxx> |
a6eb515f |
63 | #include <Standard_CString.hxx> |
af203d54 |
64 | #include <Standard_ProgramError.hxx> |
a6eb515f |
65 | #include <StdPrs_ShadedShape.hxx> |
66 | #include <StdPrs_WFShape.hxx> |
67 | #include <TCollection_AsciiString.hxx> |
68 | #include <TCollection_ExtendedString.hxx> |
69 | #include <TopExp_Explorer.hxx> |
70 | #include <TopoDS.hxx> |
71 | #include <TopoDS_Vertex.hxx> |
72 | #include <Units.hxx> |
73 | #include <Units_UnitsDictionary.hxx> |
74 | #include <UnitsAPI.hxx> |
75 | #include <UnitsAPI_SystemUnits.hxx> |
76 | |
77 | IMPLEMENT_STANDARD_HANDLE(AIS_Dimension, AIS_InteractiveObject) |
78 | IMPLEMENT_STANDARD_RTTIEXT(AIS_Dimension, AIS_InteractiveObject) |
79 | |
d7bffd44 |
80 | namespace |
a6eb515f |
81 | { |
fe83e1ea |
82 | // default text strings |
d7bffd44 |
83 | static const Standard_Utf32Char THE_FILL_CHARACTER ('0'); |
84 | static const TCollection_ExtendedString THE_EMPTY_LABEL; |
60bf98ae |
85 | static const TCollection_AsciiString THE_UNDEFINED_UNITS; |
fe83e1ea |
86 | |
87 | // default text margin and resolution |
88 | static const Standard_Real THE_3D_TEXT_MARGIN = 0.1; |
89 | static const unsigned int THE_2D_TEXT_RESOLUTION = 72; |
90 | |
91 | // default selection priorities |
92 | static const Standard_Integer THE_NEUTRAL_SEL_PRIORITY = 5; |
93 | static const Standard_Integer THE_LOCAL_SEL_PRIORITY = 6; |
d7bffd44 |
94 | }; |
a6eb515f |
95 | |
96 | //======================================================================= |
97 | //function : Constructor |
98 | //purpose : |
99 | //======================================================================= |
60bf98ae |
100 | AIS_Dimension::AIS_Dimension (const AIS_KindOfDimension theType) |
a6eb515f |
101 | : AIS_InteractiveObject(), |
60bf98ae |
102 | myCustomValue (0.0), |
a6eb515f |
103 | myIsValueCustom (Standard_False), |
a6eb515f |
104 | mySpecialSymbol (' '), |
105 | myDisplaySpecialSymbol (AIS_DSS_No), |
60bf98ae |
106 | myGeometryType (GeometryType_UndefShapes), |
107 | myIsPlaneCustom (Standard_False), |
62b6361a |
108 | myFlyout (0.0), |
60bf98ae |
109 | myIsValid (Standard_False), |
110 | myKindOfDimension (theType) |
a6eb515f |
111 | { |
a6eb515f |
112 | } |
113 | |
114 | //======================================================================= |
60bf98ae |
115 | //function : SetCustomValue |
116 | //purpose : |
a6eb515f |
117 | //======================================================================= |
60bf98ae |
118 | void AIS_Dimension::SetCustomValue (const Standard_Real theValue) |
a6eb515f |
119 | { |
60bf98ae |
120 | if (myIsValueCustom && myCustomValue == theValue) |
121 | { |
122 | return; |
123 | } |
a6eb515f |
124 | |
60bf98ae |
125 | myIsValueCustom = Standard_True; |
126 | |
127 | myCustomValue = theValue; |
128 | |
129 | SetToUpdate(); |
a6eb515f |
130 | } |
131 | |
132 | //======================================================================= |
60bf98ae |
133 | //function : GetPlane |
a6eb515f |
134 | //purpose : |
135 | //======================================================================= |
60bf98ae |
136 | const gp_Pln& AIS_Dimension::GetPlane() const |
a6eb515f |
137 | { |
60bf98ae |
138 | return myPlane; |
a6eb515f |
139 | } |
140 | |
141 | //======================================================================= |
60bf98ae |
142 | //function : GetGeometryType |
a6eb515f |
143 | //purpose : |
144 | //======================================================================= |
60bf98ae |
145 | const Standard_Integer AIS_Dimension::GetGeometryType () const |
a6eb515f |
146 | { |
60bf98ae |
147 | return myGeometryType; |
a6eb515f |
148 | } |
149 | |
150 | //======================================================================= |
60bf98ae |
151 | //function : SetUserPlane |
a6eb515f |
152 | //purpose : |
153 | //======================================================================= |
60bf98ae |
154 | void AIS_Dimension::SetCustomPlane (const gp_Pln& thePlane) |
a6eb515f |
155 | { |
60bf98ae |
156 | myPlane = thePlane; |
157 | myIsPlaneCustom = Standard_True; |
158 | |
af203d54 |
159 | // Disable fixed text position |
160 | UnsetFixedTextPosition(); |
161 | |
60bf98ae |
162 | // Check validity if geometry has been set already. |
163 | if (myIsValid) |
164 | { |
165 | myIsValid &= CheckPlane (myPlane); |
166 | SetToUpdate(); |
167 | } |
a6eb515f |
168 | } |
169 | |
170 | //======================================================================= |
60bf98ae |
171 | //function : SetDimensionAspect |
172 | //purpose : |
a6eb515f |
173 | //======================================================================= |
60bf98ae |
174 | void AIS_Dimension::SetDimensionAspect (const Handle(Prs3d_DimensionAspect)& theDimensionAspect) |
a6eb515f |
175 | { |
60bf98ae |
176 | myDrawer->SetDimensionAspect (theDimensionAspect); |
177 | |
178 | SetToUpdate(); |
a6eb515f |
179 | } |
180 | |
181 | //======================================================================= |
60bf98ae |
182 | //function : SetDisplaySpecialSymbol |
183 | //purpose : |
a6eb515f |
184 | //======================================================================= |
60bf98ae |
185 | void AIS_Dimension::SetDisplaySpecialSymbol (const AIS_DisplaySpecialSymbol theDisplaySpecSymbol) |
a6eb515f |
186 | { |
60bf98ae |
187 | if (myDisplaySpecialSymbol == theDisplaySpecSymbol) |
188 | { |
189 | return; |
190 | } |
191 | |
192 | myDisplaySpecialSymbol = theDisplaySpecSymbol; |
193 | |
194 | SetToUpdate(); |
a6eb515f |
195 | } |
196 | |
197 | //======================================================================= |
60bf98ae |
198 | //function : SetSpecialSymbol |
a6eb515f |
199 | //purpose : |
200 | //======================================================================= |
60bf98ae |
201 | void AIS_Dimension::SetSpecialSymbol (const Standard_ExtCharacter theSpecialSymbol) |
a6eb515f |
202 | { |
60bf98ae |
203 | if (mySpecialSymbol == theSpecialSymbol) |
204 | { |
205 | return; |
206 | } |
207 | |
208 | mySpecialSymbol = theSpecialSymbol; |
209 | |
210 | SetToUpdate(); |
a6eb515f |
211 | } |
212 | |
213 | //======================================================================= |
60bf98ae |
214 | //function : SetSelToleranceForText2d |
215 | //purpose : |
a6eb515f |
216 | //======================================================================= |
60bf98ae |
217 | void AIS_Dimension::SetSelToleranceForText2d (const Standard_Real theTol) |
a6eb515f |
218 | { |
60bf98ae |
219 | if (mySelToleranceForText2d == theTol) |
220 | { |
221 | return; |
222 | } |
223 | |
224 | mySelToleranceForText2d = theTol; |
225 | |
226 | SetToUpdate(); |
a6eb515f |
227 | } |
228 | |
229 | //======================================================================= |
60bf98ae |
230 | //function : SetFlyout |
231 | //purpose : |
a6eb515f |
232 | //======================================================================= |
60bf98ae |
233 | void AIS_Dimension::SetFlyout (const Standard_Real theFlyout) |
a6eb515f |
234 | { |
60bf98ae |
235 | if (myFlyout == theFlyout) |
236 | { |
237 | return; |
238 | } |
a6eb515f |
239 | |
60bf98ae |
240 | myFlyout = theFlyout; |
241 | |
af203d54 |
242 | // Disable fixed text position |
243 | UnsetFixedTextPosition(); |
244 | |
60bf98ae |
245 | SetToUpdate(); |
246 | } |
a6eb515f |
247 | |
248 | //======================================================================= |
60bf98ae |
249 | //function : GetDisplayUnits |
250 | //purpose : |
a6eb515f |
251 | //======================================================================= |
60bf98ae |
252 | const TCollection_AsciiString& AIS_Dimension::GetDisplayUnits() const |
a6eb515f |
253 | { |
60bf98ae |
254 | return THE_UNDEFINED_UNITS; |
a6eb515f |
255 | } |
256 | |
257 | //======================================================================= |
60bf98ae |
258 | //function : GetModelUnits |
259 | //purpose : |
a6eb515f |
260 | //======================================================================= |
60bf98ae |
261 | const TCollection_AsciiString& AIS_Dimension::GetModelUnits() const |
a6eb515f |
262 | { |
60bf98ae |
263 | return THE_UNDEFINED_UNITS; |
a6eb515f |
264 | } |
265 | |
266 | //======================================================================= |
60bf98ae |
267 | //function : ValueToDisplayUnits |
268 | //purpose : |
a6eb515f |
269 | //======================================================================= |
60bf98ae |
270 | Standard_Real AIS_Dimension::ValueToDisplayUnits() const |
a6eb515f |
271 | { |
60bf98ae |
272 | return UnitsAPI::AnyToAny (GetValue(), |
273 | GetModelUnits().ToCString(), |
274 | GetDisplayUnits().ToCString()); |
a6eb515f |
275 | } |
276 | |
277 | //======================================================================= |
60bf98ae |
278 | //function : GetValueString |
a6eb515f |
279 | //purpose : |
280 | //======================================================================= |
60bf98ae |
281 | TCollection_ExtendedString AIS_Dimension::GetValueString (Standard_Real& theWidth) const |
a6eb515f |
282 | { |
60bf98ae |
283 | // format value string using "sprintf" |
284 | TCollection_AsciiString aFormatStr = myDrawer->DimensionAspect()->ValueStringFormat(); |
a6eb515f |
285 | |
60bf98ae |
286 | char aFmtBuffer[256]; |
287 | sprintf (aFmtBuffer, aFormatStr.ToCString(), ValueToDisplayUnits()); |
288 | TCollection_ExtendedString aValueStr = TCollection_ExtendedString (aFmtBuffer); |
a6eb515f |
289 | |
60bf98ae |
290 | // add units to values string |
291 | if (myDrawer->DimensionAspect()->IsUnitsDisplayed()) |
a6eb515f |
292 | { |
60bf98ae |
293 | aValueStr += " "; |
294 | aValueStr += TCollection_ExtendedString (GetDisplayUnits()); |
a6eb515f |
295 | } |
60bf98ae |
296 | |
297 | switch (myDisplaySpecialSymbol) |
a6eb515f |
298 | { |
60bf98ae |
299 | case AIS_DSS_Before : aValueStr.Insert (1, mySpecialSymbol); break; |
300 | case AIS_DSS_After : aValueStr.Insert (aValueStr.Length() + 1, mySpecialSymbol); break; |
301 | case AIS_DSS_No : break; |
a6eb515f |
302 | } |
303 | |
d7bffd44 |
304 | // Get text style parameters |
a6eb515f |
305 | Quantity_Color aColor; |
d7bffd44 |
306 | Standard_CString aFontName; |
a6eb515f |
307 | Standard_Real aFactor; |
308 | Standard_Real aSpace; |
d7bffd44 |
309 | myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, aFactor, aSpace); |
fe83e1ea |
310 | Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect(); |
311 | Standard_Real aFontHeight = myDrawer->DimensionAspect()->TextAspect()->Height(); |
312 | |
60bf98ae |
313 | NCollection_Utf8String anUTFString = (Standard_Utf16Char* )aValueStr.ToExtString(); |
fe83e1ea |
314 | |
d7bffd44 |
315 | theWidth = 0.0; |
fe83e1ea |
316 | |
317 | if (myDrawer->DimensionAspect()->IsText3d()) |
318 | { |
319 | // text width produced by BRepFont |
320 | Font_BRepFont aFont (aFontName, aFontAspect, aFontHeight); |
321 | |
322 | for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; ) |
323 | { |
324 | Standard_Utf32Char aCurrChar = *anIter; |
325 | Standard_Utf32Char aNextChar = *(++anIter); |
326 | theWidth += aFont.AdvanceX (aCurrChar, aNextChar); |
327 | } |
328 | } |
329 | else |
d7bffd44 |
330 | { |
fe83e1ea |
331 | // Text width for 1:1 scale 2D case |
60bf98ae |
332 | Handle(Font_FTFont) aFont = new Font_FTFont(); |
fe83e1ea |
333 | aFont->Init (aFontName, aFontAspect, (const unsigned int)aFontHeight, THE_2D_TEXT_RESOLUTION); |
334 | |
335 | for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; ) |
336 | { |
337 | Standard_Utf32Char aCurrChar = *anIter; |
338 | Standard_Utf32Char aNextChar = *(++anIter); |
339 | theWidth += (Standard_Real) aFont->AdvanceX (aCurrChar, aNextChar); |
340 | } |
d7bffd44 |
341 | } |
60bf98ae |
342 | |
343 | return aValueStr; |
a6eb515f |
344 | } |
345 | |
346 | //======================================================================= |
60bf98ae |
347 | //function : DrawArrow |
a6eb515f |
348 | //purpose : |
349 | //======================================================================= |
60bf98ae |
350 | void AIS_Dimension::DrawArrow (const Handle(Prs3d_Presentation)& thePresentation, |
a6eb515f |
351 | const gp_Pnt& theLocation, |
352 | const gp_Dir& theDirection) |
353 | { |
354 | Prs3d_Root::NewGroup (thePresentation); |
fe83e1ea |
355 | |
356 | Quantity_Length aLength = myDrawer->DimensionAspect()->ArrowAspect()->Length(); |
357 | Standard_Real anAngle = myDrawer->DimensionAspect()->ArrowAspect()->Angle(); |
a6eb515f |
358 | |
359 | if (myDrawer->DimensionAspect()->IsArrows3d()) |
360 | { |
361 | Prs3d_Arrow::Draw (thePresentation, |
362 | theLocation, |
d7bffd44 |
363 | theDirection, |
fe83e1ea |
364 | anAngle, |
365 | aLength); |
a6eb515f |
366 | } |
367 | else |
368 | { |
fe83e1ea |
369 | gp_Pnt aLeftPoint (gp::Origin()); |
370 | gp_Pnt aRightPoint (gp::Origin()); |
60bf98ae |
371 | const gp_Dir& aPlane = GetPlane().Axis().Direction(); |
fe83e1ea |
372 | |
373 | PointsForArrow (theLocation, theDirection, aPlane, aLength, anAngle, aLeftPoint, aRightPoint); |
374 | |
a6eb515f |
375 | Handle(Graphic3d_ArrayOfTriangles) anArrow = new Graphic3d_ArrayOfTriangles(3); |
a6eb515f |
376 | |
377 | anArrow->AddVertex (aLeftPoint); |
378 | anArrow->AddVertex (theLocation); |
379 | anArrow->AddVertex (aRightPoint); |
380 | |
381 | // Set aspect for arrow triangles |
382 | Quantity_Color aColor; |
383 | Aspect_TypeOfLine aTOL; |
384 | Standard_Real aWidth; |
385 | myDrawer->DimensionAspect()->ArrowAspect()->Aspect()->Values (aColor, aTOL, aWidth); |
386 | Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT); |
387 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT); |
388 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE); |
389 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR); |
d7bffd44 |
390 | |
391 | Handle(Prs3d_ShadingAspect) aShadingStyle = new Prs3d_ShadingAspect(); |
392 | aShadingStyle->SetColor (aColor); |
393 | aShadingStyle->SetMaterial (aShadeMat); |
394 | |
395 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aShadingStyle->Aspect()); |
396 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (anArrow); |
a6eb515f |
397 | } |
fe83e1ea |
398 | |
399 | SelectionGeometry::Arrow& aSensitiveArrow = mySelectionGeom.NewArrow(); |
400 | aSensitiveArrow.Position = theLocation; |
401 | aSensitiveArrow.Direction = theDirection; |
a6eb515f |
402 | } |
403 | |
404 | //======================================================================= |
60bf98ae |
405 | //function : DrawText |
a6eb515f |
406 | //purpose : |
407 | //======================================================================= |
60bf98ae |
408 | void AIS_Dimension::DrawText (const Handle(Prs3d_Presentation)& thePresentation, |
fe83e1ea |
409 | const gp_Pnt& theTextPos, |
410 | const gp_Dir& theTextDir, |
411 | const TCollection_ExtendedString& theText, |
412 | const Standard_Integer theLabelPosition) |
a6eb515f |
413 | { |
a6eb515f |
414 | if (myDrawer->DimensionAspect()->IsText3d()) |
415 | { |
fe83e1ea |
416 | // getting font parameters |
a6eb515f |
417 | Quantity_Color aColor; |
418 | Standard_CString aFontName; |
419 | Standard_Real anExpansionFactor; |
420 | Standard_Real aSpace; |
421 | myDrawer->DimensionAspect()->TextAspect()->Aspect()->Values (aColor, aFontName, anExpansionFactor, aSpace); |
422 | Font_FontAspect aFontAspect = myDrawer->DimensionAspect()->TextAspect()->Aspect()->GetTextFontAspect(); |
fe83e1ea |
423 | Standard_Real aFontHeight = myDrawer->DimensionAspect()->TextAspect()->Height(); |
a6eb515f |
424 | |
fe83e1ea |
425 | // creating TopoDS_Shape for text |
426 | Font_BRepFont aFont (aFontName, aFontAspect, aFontHeight); |
427 | NCollection_Utf8String anUTFString = (Standard_Utf16Char* )theText.ToExtString(); |
428 | TopoDS_Shape aTextShape = aFont.RenderText (anUTFString); |
a6eb515f |
429 | |
fe83e1ea |
430 | // compute text width with kerning |
431 | Standard_Real aTextWidth = 0.0; |
432 | Standard_Real aTextHeight = aFont.Ascender() + aFont.Descender(); |
d7bffd44 |
433 | |
fe83e1ea |
434 | for (NCollection_Utf8Iter anIter = anUTFString.Iterator(); *anIter != 0; ) |
435 | { |
436 | Standard_Utf32Char aCurrChar = *anIter; |
437 | Standard_Utf32Char aNextChar = *(++anIter); |
438 | aTextWidth += aFont.AdvanceX (aCurrChar, aNextChar); |
439 | } |
440 | |
441 | // formating text position in XOY plane |
d7bffd44 |
442 | Standard_Integer aHLabelPos = theLabelPosition & LabelPosition_HMask; |
443 | Standard_Integer aVLabelPos = theLabelPosition & LabelPosition_VMask; |
444 | |
445 | gp_Dir aTextDir (aHLabelPos == LabelPosition_Left ? -theTextDir : theTextDir); |
446 | |
447 | // compute label offsets |
fe83e1ea |
448 | Standard_Real aMarginSize = aFontHeight * THE_3D_TEXT_MARGIN; |
d7bffd44 |
449 | Standard_Real aCenterHOffset = 0.0; |
450 | Standard_Real aCenterVOffset = 0.0; |
451 | switch (aHLabelPos) |
a6eb515f |
452 | { |
d7bffd44 |
453 | case LabelPosition_HCenter : aCenterHOffset = 0.0; break; |
454 | case LabelPosition_Right : aCenterHOffset = aTextWidth / 2.0 + aMarginSize; break; |
455 | case LabelPosition_Left : aCenterHOffset = -aTextWidth / 2.0 - aMarginSize; break; |
a6eb515f |
456 | } |
d7bffd44 |
457 | switch (aVLabelPos) |
a6eb515f |
458 | { |
d7bffd44 |
459 | case LabelPosition_VCenter : aCenterVOffset = 0.0; break; |
460 | case LabelPosition_Above : aCenterVOffset = aTextHeight / 2.0 + aMarginSize; break; |
461 | case LabelPosition_Below : aCenterVOffset = -aTextHeight / 2.0 - aMarginSize; break; |
a6eb515f |
462 | } |
d7bffd44 |
463 | |
464 | // compute shape offset transformation |
fe83e1ea |
465 | Standard_Real aShapeHOffset = aCenterHOffset - aTextWidth / 2.0; |
d7bffd44 |
466 | Standard_Real aShapeVOffset = aCenterVOffset - aTextHeight / 2.0; |
467 | |
fe83e1ea |
468 | // center shape in its bounding box (suppress border spacing added by FT_Font) |
469 | Bnd_Box aShapeBnd; |
470 | BRepBndLib::AddClose (aTextShape, aShapeBnd); |
471 | |
472 | Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; |
473 | aShapeBnd.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax); |
474 | |
475 | Standard_Real aXalign = aTextWidth * 0.5 - (aXmax + aXmin) * 0.5; |
476 | Standard_Real aYalign = aTextHeight * 0.5 - (aYmax + aYmin) * 0.5; |
477 | aShapeHOffset += aXalign; |
478 | aShapeVOffset += aYalign; |
479 | |
d7bffd44 |
480 | gp_Trsf anOffsetTrsf; |
481 | anOffsetTrsf.SetTranslation (gp::Origin(), gp_Pnt (aShapeHOffset, aShapeVOffset, 0.0)); |
482 | aTextShape.Move (anOffsetTrsf); |
a6eb515f |
483 | |
fe83e1ea |
484 | // transform text to myWorkingPlane coordinate system |
60bf98ae |
485 | gp_Ax3 aTextCoordSystem (theTextPos, GetPlane().Axis().Direction(), aTextDir); |
d7bffd44 |
486 | gp_Trsf aTextPlaneTrsf; |
487 | aTextPlaneTrsf.SetTransformation (aTextCoordSystem, gp_Ax3 (gp::XOY())); |
488 | aTextShape.Move (aTextPlaneTrsf); |
a6eb515f |
489 | |
fe83e1ea |
490 | // set text flipping anchors |
d7bffd44 |
491 | gp_Trsf aCenterOffsetTrsf; |
492 | gp_Pnt aCenterOffset (aCenterHOffset, aCenterVOffset, 0.0); |
493 | aCenterOffsetTrsf.SetTranslation (gp::Origin(), aCenterOffset); |
494 | |
fe83e1ea |
495 | gp_Pnt aCenterOfLabel (gp::Origin()); |
496 | aCenterOfLabel.Transform (aCenterOffsetTrsf); |
497 | aCenterOfLabel.Transform (aTextPlaneTrsf); |
d7bffd44 |
498 | |
60bf98ae |
499 | gp_Ax2 aFlippingAxes (aCenterOfLabel, GetPlane().Axis().Direction(), aTextDir); |
d7bffd44 |
500 | Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_True, aFlippingAxes); |
501 | |
fe83e1ea |
502 | // draw text |
a6eb515f |
503 | if (myDrawer->DimensionAspect()->IsTextShaded()) |
504 | { |
505 | // Setting text shading and color parameters |
506 | Graphic3d_MaterialAspect aShadeMat (Graphic3d_NOM_DEFAULT); |
507 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_AMBIENT); |
508 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_DIFFUSE); |
509 | aShadeMat.SetReflectionModeOff (Graphic3d_TOR_SPECULAR); |
510 | myDrawer->ShadingAspect()->Aspect()->SetInteriorColor (aColor); |
511 | myDrawer->ShadingAspect()->Aspect()->SetBackInteriorColor (aColor); |
512 | myDrawer->ShadingAspect()->SetMaterial (aShadeMat); |
513 | |
fe83e1ea |
514 | // drawing text |
a6eb515f |
515 | StdPrs_ShadedShape::Add (thePresentation, aTextShape, myDrawer); |
516 | } |
517 | else |
518 | { |
fe83e1ea |
519 | // setting color for text |
a6eb515f |
520 | myDrawer->FreeBoundaryAspect()->Aspect()->SetColor (aColor); |
fe83e1ea |
521 | // drawing text |
a6eb515f |
522 | StdPrs_WFShape::Add (thePresentation, aTextShape, myDrawer); |
523 | } |
d7bffd44 |
524 | Prs3d_Root::CurrentGroup (thePresentation)->SetFlippingOptions (Standard_False, gp_Ax2()); |
525 | |
fe83e1ea |
526 | mySelectionGeom.TextPos = aCenterOfLabel; |
527 | mySelectionGeom.TextDir = aTextDir; |
528 | mySelectionGeom.TextWidth = aTextWidth + aMarginSize * 2.0; |
529 | mySelectionGeom.TextHeight = aTextHeight; |
530 | |
531 | return; |
a6eb515f |
532 | } |
533 | |
fe83e1ea |
534 | // generate primitives for 2D text |
d7bffd44 |
535 | myDrawer->DimensionAspect()->TextAspect()->Aspect()->SetDisplayType (Aspect_TODT_DIMENSION); |
536 | |
537 | Prs3d_Text::Draw (thePresentation, |
538 | myDrawer->DimensionAspect()->TextAspect(), |
539 | theText, |
fe83e1ea |
540 | theTextPos); |
d7bffd44 |
541 | |
fe83e1ea |
542 | mySelectionGeom.TextPos = theTextPos; |
543 | mySelectionGeom.TextDir = theTextDir; |
544 | mySelectionGeom.TextWidth = 0.0; |
545 | mySelectionGeom.TextHeight = 0.0; |
a6eb515f |
546 | } |
547 | |
d7bffd44 |
548 | //======================================================================= |
60bf98ae |
549 | //function : DrawExtension |
a6eb515f |
550 | //purpose : |
551 | //======================================================================= |
60bf98ae |
552 | void AIS_Dimension::DrawExtension (const Handle(Prs3d_Presentation)& thePresentation, |
d7bffd44 |
553 | const Standard_Real theExtensionSize, |
554 | const gp_Pnt& theExtensionStart, |
555 | const gp_Dir& theExtensionDir, |
fe83e1ea |
556 | const TCollection_ExtendedString& theLabelString, |
557 | const Standard_Real theLabelWidth, |
558 | const Standard_Integer theMode, |
d7bffd44 |
559 | const Standard_Integer theLabelPosition) |
a6eb515f |
560 | { |
fe83e1ea |
561 | // reference line for extension starting at its connection point |
562 | gp_Lin anExtensionLine (theExtensionStart, theExtensionDir); |
a6eb515f |
563 | |
fe83e1ea |
564 | Standard_Boolean hasLabel = theLabelString.Length() > 0; |
fe83e1ea |
565 | if (hasLabel && (theMode == ComputeMode_All || theMode == ComputeMode_Text)) |
a6eb515f |
566 | { |
d7bffd44 |
567 | // compute text primitives; get its model width |
fe83e1ea |
568 | gp_Pnt aTextPos = ElCLib::Value (theExtensionSize, anExtensionLine); |
60bf98ae |
569 | gp_Dir aTextDir = theExtensionDir; |
fe83e1ea |
570 | |
60bf98ae |
571 | DrawText (thePresentation, |
fe83e1ea |
572 | aTextPos, |
573 | aTextDir, |
574 | theLabelString, |
575 | theLabelPosition); |
a6eb515f |
576 | } |
577 | |
fe83e1ea |
578 | if (theMode != ComputeMode_All && theMode != ComputeMode_Line) |
a6eb515f |
579 | { |
d7bffd44 |
580 | return; |
a6eb515f |
581 | } |
582 | |
fe83e1ea |
583 | Standard_Boolean isShortLine = !myDrawer->DimensionAspect()->IsText3d() |
584 | || theLabelPosition & LabelPosition_VCenter; |
585 | |
d7bffd44 |
586 | // compute graphical primitives and sensitives for extension line |
587 | gp_Pnt anExtStart = theExtensionStart; |
fe83e1ea |
588 | gp_Pnt anExtEnd = !hasLabel || isShortLine |
589 | ? ElCLib::Value (theExtensionSize, anExtensionLine) |
590 | : ElCLib::Value (theExtensionSize + theLabelWidth, anExtensionLine); |
d7bffd44 |
591 | |
fe83e1ea |
592 | // add graphical primitives |
d7bffd44 |
593 | Handle(Graphic3d_ArrayOfSegments) anExtPrimitive = new Graphic3d_ArrayOfSegments (2); |
594 | anExtPrimitive->AddVertex (anExtStart); |
595 | anExtPrimitive->AddVertex (anExtEnd); |
596 | |
fe83e1ea |
597 | // add selection primitives |
598 | SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve(); |
599 | aSensitiveCurve.Append (anExtStart); |
600 | aSensitiveCurve.Append (anExtEnd); |
a6eb515f |
601 | |
fe83e1ea |
602 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All) |
a6eb515f |
603 | { |
d7bffd44 |
604 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True); |
605 | } |
606 | Handle(Graphic3d_AspectLine3d) aDimensionLineStyle = myDrawer->DimensionAspect()->LineAspect()->Aspect(); |
607 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionLineStyle); |
608 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (anExtPrimitive); |
fe83e1ea |
609 | if (!myDrawer->DimensionAspect()->IsText3d() && theMode == ComputeMode_All) |
d7bffd44 |
610 | { |
611 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False); |
a6eb515f |
612 | } |
613 | } |
614 | |
615 | //======================================================================= |
60bf98ae |
616 | //function : DrawLinearDimension |
a6eb515f |
617 | //purpose : |
618 | //======================================================================= |
60bf98ae |
619 | void AIS_Dimension::DrawLinearDimension (const Handle(Prs3d_Presentation)& thePresentation, |
fe83e1ea |
620 | const Standard_Integer theMode, |
60bf98ae |
621 | const gp_Pnt& theFirstPoint, |
622 | const gp_Pnt& theSecondPoint, |
623 | const Standard_Boolean theIsOneSide) |
a6eb515f |
624 | { |
60bf98ae |
625 | // do not build any dimension for equal points |
626 | if (theFirstPoint.IsEqual (theSecondPoint, Precision::Confusion())) |
a6eb515f |
627 | { |
60bf98ae |
628 | Standard_ProgramError::Raise ("Can not build presentation for equal points."); |
a6eb515f |
629 | } |
d7bffd44 |
630 | |
a6eb515f |
631 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
a6eb515f |
632 | |
d7bffd44 |
633 | // For extensions we need to know arrow size, text size and extension size: get it from aspect |
634 | Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
635 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
fe83e1ea |
636 | // prepare label string and compute its geometrical width |
637 | Standard_Real aLabelWidth; |
60bf98ae |
638 | TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth); |
a6eb515f |
639 | |
fe83e1ea |
640 | // add margins to cut dimension lines for 3d text |
641 | if (aDimensionAspect->IsText3d()) |
642 | { |
643 | aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0; |
644 | } |
645 | |
646 | // handle user-defined and automatic arrow placement |
af203d54 |
647 | Standard_Boolean isArrowsExternal = Standard_False; |
648 | Standard_Integer aLabelPosition = LabelPosition_None; |
fe83e1ea |
649 | |
af203d54 |
650 | Prs3d_DimensionTextHorizontalPosition aHorisontalTextPos = aDimensionAspect->TextHorizontalPosition(); |
651 | if (IsTextPositionCustom()) |
652 | { |
653 | AdjustParametersForLinear (myFixedTextPosition, theFirstPoint, theSecondPoint, |
654 | anExtensionSize, aHorisontalTextPos); |
fe83e1ea |
655 | |
a6eb515f |
656 | } |
a6eb515f |
657 | |
af203d54 |
658 | FitTextAlignmentForLinear (theFirstPoint, theSecondPoint, theIsOneSide, aHorisontalTextPos, |
659 | aLabelPosition, isArrowsExternal); |
660 | |
661 | // compute dimension line points |
662 | gp_Ax1 aPlaneNormal = GetPlane().Axis(); |
663 | gp_Dir aTargetPointsVector = gce_MakeDir (theFirstPoint, theSecondPoint); |
664 | |
665 | // compute flyout direction vector |
666 | gp_Dir aFlyoutVector = aPlaneNormal.Direction() ^ aTargetPointsVector; |
667 | |
668 | // create lines for layouts |
669 | gp_Lin aLine1 (theFirstPoint, aFlyoutVector); |
670 | gp_Lin aLine2 (theSecondPoint, aFlyoutVector); |
671 | |
672 | // Get flyout end points |
673 | gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1); |
674 | gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2); |
675 | |
676 | gp_Lin aDimensionLine = gce_MakeLin (aLineBegPoint, aLineEndPoint); |
677 | |
fe83e1ea |
678 | // compute arrows positions and directions |
d7bffd44 |
679 | gp_Dir aFirstArrowDir = aDimensionLine.Direction().Reversed(); |
680 | gp_Dir aSecondArrowDir = aDimensionLine.Direction(); |
681 | gp_Dir aFirstExtensionDir = aDimensionLine.Direction().Reversed(); |
682 | gp_Dir aSecondExtensionDir = aDimensionLine.Direction(); |
683 | |
684 | gp_Pnt aFirstArrowBegin (0.0, 0.0, 0.0); |
685 | gp_Pnt aFirstArrowEnd (0.0, 0.0, 0.0); |
686 | gp_Pnt aSecondArrowBegin (0.0, 0.0, 0.0); |
687 | gp_Pnt aSecondArrowEnd (0.0, 0.0, 0.0); |
a6eb515f |
688 | |
d7bffd44 |
689 | if (isArrowsExternal) |
a6eb515f |
690 | { |
691 | aFirstArrowDir.Reverse(); |
692 | aSecondArrowDir.Reverse(); |
a6eb515f |
693 | } |
d7bffd44 |
694 | |
695 | aFirstArrowBegin = aLineBegPoint; |
696 | aSecondArrowBegin = aLineEndPoint; |
697 | aFirstArrowEnd = aLineBegPoint.Translated (-gp_Vec (aFirstArrowDir).Scaled (anArrowLength)); |
698 | aSecondArrowEnd = aLineEndPoint.Translated (-gp_Vec (aSecondArrowDir).Scaled (anArrowLength)); |
699 | |
700 | gp_Pnt aCenterLineBegin = isArrowsExternal |
60bf98ae |
701 | ? aLineBegPoint : aFirstArrowEnd; |
d7bffd44 |
702 | |
60bf98ae |
703 | gp_Pnt aCenterLineEnd = isArrowsExternal || theIsOneSide |
d7bffd44 |
704 | ? aLineEndPoint : aSecondArrowEnd; |
705 | |
a6eb515f |
706 | |
d7bffd44 |
707 | switch (aLabelPosition & LabelPosition_HMask) |
a6eb515f |
708 | { |
d7bffd44 |
709 | // ------------------------------------------------------------------------ // |
710 | // CENTER // |
711 | // -------------------------------------------------------------------------// |
d7bffd44 |
712 | case LabelPosition_HCenter: |
a6eb515f |
713 | { |
d7bffd44 |
714 | // add label on dimension or extension line to presentation |
715 | Prs3d_Root::NewGroup (thePresentation); |
a6eb515f |
716 | |
af203d54 |
717 | gp_Pnt aTextPos = IsTextPositionCustom() ? myFixedTextPosition |
718 | : (aCenterLineBegin.XYZ() + aCenterLineEnd.XYZ()) * 0.5; |
60bf98ae |
719 | gp_Dir aTextDir = aDimensionLine.Direction(); |
a6eb515f |
720 | |
fe83e1ea |
721 | // add text primitives |
722 | if (theMode == ComputeMode_All || theMode == ComputeMode_Text) |
a6eb515f |
723 | { |
60bf98ae |
724 | DrawText (thePresentation, |
fe83e1ea |
725 | aTextPos, |
726 | aTextDir, |
727 | aLabelString, |
728 | aLabelPosition); |
a6eb515f |
729 | } |
d7bffd44 |
730 | |
fe83e1ea |
731 | // add dimension line primitives |
732 | if (theMode == ComputeMode_All || theMode == ComputeMode_Line) |
733 | { |
734 | Standard_Boolean isLineBreak = aDimensionAspect->TextVerticalPosition() == Prs3d_DTVP_Center |
735 | && aDimensionAspect->IsText3d(); |
d7bffd44 |
736 | |
fe83e1ea |
737 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (isLineBreak ? 4 : 2); |
d7bffd44 |
738 | |
fe83e1ea |
739 | // compute continuous or sectioned main line segments |
740 | if (isLineBreak) |
741 | { |
742 | Standard_Real aPTextPosition = ElCLib::Parameter (aDimensionLine, aTextPos); |
743 | gp_Pnt aSection1Beg = aCenterLineBegin; |
744 | gp_Pnt aSection1End = ElCLib::Value (aPTextPosition - (aLabelWidth * 0.5), aDimensionLine); |
745 | gp_Pnt aSection2Beg = ElCLib::Value (aPTextPosition + (aLabelWidth * 0.5), aDimensionLine); |
746 | gp_Pnt aSection2End = aCenterLineEnd; |
747 | |
748 | aPrimSegments->AddVertex (aSection1Beg); |
749 | aPrimSegments->AddVertex (aSection1End); |
750 | aPrimSegments->AddVertex (aSection2Beg); |
751 | aPrimSegments->AddVertex (aSection2End); |
752 | |
753 | SelectionGeometry::Curve& aLeftSensitiveCurve = mySelectionGeom.NewCurve(); |
754 | SelectionGeometry::Curve& aRightSensitiveCurve = mySelectionGeom.NewCurve(); |
755 | aLeftSensitiveCurve.Append (aSection1Beg); |
756 | aLeftSensitiveCurve.Append (aSection1End); |
757 | aRightSensitiveCurve.Append (aSection2Beg); |
758 | aRightSensitiveCurve.Append (aSection2End); |
759 | } |
760 | else |
761 | { |
762 | aPrimSegments->AddVertex (aCenterLineBegin); |
763 | aPrimSegments->AddVertex (aCenterLineEnd); |
a6eb515f |
764 | |
fe83e1ea |
765 | SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve(); |
766 | aSensitiveCurve.Append (aCenterLineBegin); |
767 | aSensitiveCurve.Append (aCenterLineEnd); |
768 | } |
a6eb515f |
769 | |
fe83e1ea |
770 | // set text label justification |
771 | Graphic3d_VerticalTextAlignment aTextJustificaton = Graphic3d_VTA_BOTTOM; |
772 | switch (aLabelPosition & LabelPosition_VMask) |
773 | { |
774 | case LabelPosition_Above : |
775 | case LabelPosition_VCenter : aTextJustificaton = Graphic3d_VTA_BOTTOM; break; |
776 | case LabelPosition_Below : aTextJustificaton = Graphic3d_VTA_TOP; break; |
777 | } |
778 | aDimensionAspect->TextAspect()->SetVerticalJustification (aTextJustificaton); |
a6eb515f |
779 | |
fe83e1ea |
780 | // main dimension line, short extension |
781 | if (!aDimensionAspect->IsText3d() && theMode == ComputeMode_All) |
782 | { |
783 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_True); |
784 | } |
785 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect()); |
786 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
787 | if (!aDimensionAspect->IsText3d() && theMode == ComputeMode_All) |
788 | { |
789 | Prs3d_Root::CurrentGroup (thePresentation)->SetStencilTestOptions (Standard_False); |
790 | } |
d7bffd44 |
791 | |
fe83e1ea |
792 | // add arrows to presentation |
793 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
794 | |
60bf98ae |
795 | DrawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir); |
796 | if (!theIsOneSide) |
fe83e1ea |
797 | { |
60bf98ae |
798 | DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir); |
fe83e1ea |
799 | } |
d7bffd44 |
800 | |
fe83e1ea |
801 | if (!isArrowsExternal) |
802 | { |
803 | break; |
804 | } |
d7bffd44 |
805 | |
fe83e1ea |
806 | // add arrow extension lines to presentation |
807 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
808 | |
af203d54 |
809 | DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(), |
fe83e1ea |
810 | aFirstArrowEnd, aFirstExtensionDir, |
811 | THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None); |
60bf98ae |
812 | if (!theIsOneSide) |
fe83e1ea |
813 | { |
af203d54 |
814 | DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(), |
fe83e1ea |
815 | aSecondArrowEnd, aSecondExtensionDir, |
816 | THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None); |
817 | } |
a6eb515f |
818 | } |
1d7ca641 |
819 | |
820 | break; |
a6eb515f |
821 | } |
d7bffd44 |
822 | // ------------------------------------------------------------------------ // |
823 | // LEFT // |
824 | // -------------------------------------------------------------------------// |
825 | |
826 | case LabelPosition_Left: |
a6eb515f |
827 | { |
d7bffd44 |
828 | // add label on dimension or extension line to presentation |
829 | Prs3d_Root::NewGroup (thePresentation); |
a6eb515f |
830 | |
a6eb515f |
831 | // Left extension with the text |
60bf98ae |
832 | DrawExtension (thePresentation, anExtensionSize, |
833 | isArrowsExternal |
834 | ? aFirstArrowEnd |
835 | : aFirstArrowBegin, |
d7bffd44 |
836 | aFirstExtensionDir, |
fe83e1ea |
837 | aLabelString, |
838 | aLabelWidth, |
d7bffd44 |
839 | theMode, |
840 | aLabelPosition); |
841 | |
fe83e1ea |
842 | // add dimension line primitives |
843 | if (theMode == ComputeMode_All || theMode == ComputeMode_Line) |
d7bffd44 |
844 | { |
fe83e1ea |
845 | // add central dimension line |
846 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
847 | |
fe83e1ea |
848 | // add graphical primitives |
849 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2); |
850 | aPrimSegments->AddVertex (aCenterLineBegin); |
851 | aPrimSegments->AddVertex (aCenterLineEnd); |
d7bffd44 |
852 | |
fe83e1ea |
853 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect()); |
854 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
d7bffd44 |
855 | |
fe83e1ea |
856 | // add selection primitives |
857 | SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve(); |
858 | aSensitiveCurve.Append (aCenterLineBegin); |
859 | aSensitiveCurve.Append (aCenterLineEnd); |
a6eb515f |
860 | |
fe83e1ea |
861 | // add arrows to presentation |
862 | Prs3d_Root::NewGroup (thePresentation); |
a6eb515f |
863 | |
60bf98ae |
864 | DrawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir); |
865 | if (!theIsOneSide) |
fe83e1ea |
866 | { |
60bf98ae |
867 | DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir); |
fe83e1ea |
868 | } |
d7bffd44 |
869 | |
60bf98ae |
870 | if (!isArrowsExternal || theIsOneSide) |
fe83e1ea |
871 | { |
872 | break; |
873 | } |
d7bffd44 |
874 | |
fe83e1ea |
875 | // add extension lines for external arrows |
876 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
877 | |
af203d54 |
878 | DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(), |
fe83e1ea |
879 | aSecondArrowEnd, aSecondExtensionDir, |
880 | THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None); |
881 | } |
d7bffd44 |
882 | |
a6eb515f |
883 | break; |
884 | } |
d7bffd44 |
885 | // ------------------------------------------------------------------------ // |
886 | // RIGHT // |
887 | // -------------------------------------------------------------------------// |
888 | |
889 | case LabelPosition_Right: |
a6eb515f |
890 | { |
d7bffd44 |
891 | // add label on dimension or extension line to presentation |
892 | Prs3d_Root::NewGroup (thePresentation); |
893 | |
894 | // Right extension with text |
60bf98ae |
895 | DrawExtension (thePresentation, anExtensionSize, |
896 | isArrowsExternal |
897 | ? aSecondArrowEnd |
898 | : aSecondArrowBegin, |
d7bffd44 |
899 | aSecondExtensionDir, |
fe83e1ea |
900 | aLabelString, aLabelWidth, |
d7bffd44 |
901 | theMode, |
902 | aLabelPosition); |
903 | |
fe83e1ea |
904 | if (theMode == ComputeMode_All || theMode == ComputeMode_Line) |
a6eb515f |
905 | { |
fe83e1ea |
906 | // add central dimension line |
907 | Prs3d_Root::NewGroup (thePresentation); |
a6eb515f |
908 | |
fe83e1ea |
909 | // add graphical primitives |
910 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments (2); |
911 | aPrimSegments->AddVertex (aCenterLineBegin); |
912 | aPrimSegments->AddVertex (aCenterLineEnd); |
913 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect()); |
914 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
a6eb515f |
915 | |
fe83e1ea |
916 | // add selection primitives |
917 | SelectionGeometry::Curve& aSensitiveCurve = mySelectionGeom.NewCurve(); |
918 | aSensitiveCurve.Append (aCenterLineBegin); |
919 | aSensitiveCurve.Append (aCenterLineEnd); |
a6eb515f |
920 | |
fe83e1ea |
921 | // add arrows to presentation |
922 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
923 | |
60bf98ae |
924 | DrawArrow (thePresentation, aSecondArrowBegin, aSecondArrowDir); |
925 | if (!theIsOneSide) |
fe83e1ea |
926 | { |
60bf98ae |
927 | DrawArrow (thePresentation, aFirstArrowBegin, aFirstArrowDir); |
fe83e1ea |
928 | } |
d7bffd44 |
929 | |
60bf98ae |
930 | if (!isArrowsExternal || theIsOneSide) |
fe83e1ea |
931 | { |
932 | break; |
933 | } |
a6eb515f |
934 | |
fe83e1ea |
935 | // add extension lines for external arrows |
936 | Prs3d_Root::NewGroup (thePresentation); |
d7bffd44 |
937 | |
af203d54 |
938 | DrawExtension (thePresentation, aDimensionAspect->ArrowTailSize(), |
fe83e1ea |
939 | aFirstArrowEnd, aFirstExtensionDir, |
940 | THE_EMPTY_LABEL, 0.0, theMode, LabelPosition_None); |
941 | } |
d7bffd44 |
942 | |
a6eb515f |
943 | break; |
944 | } |
945 | } |
946 | |
d7bffd44 |
947 | // add flyout lines to presentation |
fe83e1ea |
948 | if (theMode == ComputeMode_All) |
d7bffd44 |
949 | { |
950 | Prs3d_Root::NewGroup (thePresentation); |
951 | |
952 | Handle(Graphic3d_ArrayOfSegments) aPrimSegments = new Graphic3d_ArrayOfSegments(4); |
60bf98ae |
953 | aPrimSegments->AddVertex (theFirstPoint); |
d7bffd44 |
954 | aPrimSegments->AddVertex (aLineBegPoint); |
955 | |
60bf98ae |
956 | aPrimSegments->AddVertex (theSecondPoint); |
d7bffd44 |
957 | aPrimSegments->AddVertex (aLineEndPoint); |
958 | |
959 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
960 | Prs3d_Root::CurrentGroup (thePresentation)->SetPrimitivesAspect (aDimensionAspect->LineAspect()->Aspect()); |
961 | Prs3d_Root::CurrentGroup (thePresentation)->AddPrimitiveArray (aPrimSegments); |
962 | } |
963 | |
60bf98ae |
964 | myIsComputed = Standard_True; |
a6eb515f |
965 | } |
966 | |
967 | //======================================================================= |
60bf98ae |
968 | //function : ComputeLinearFlyouts |
969 | //purpose : |
a6eb515f |
970 | //======================================================================= |
60bf98ae |
971 | void AIS_Dimension::ComputeLinearFlyouts (const Handle(SelectMgr_Selection)& theSelection, |
972 | const Handle(SelectMgr_EntityOwner)& theOwner, |
973 | const gp_Pnt& theFirstPoint, |
974 | const gp_Pnt& theSecondPoint) |
a6eb515f |
975 | { |
60bf98ae |
976 | // count flyout direction |
977 | gp_Ax1 aPlaneNormal = GetPlane().Axis(); |
978 | gp_Dir aTargetPointsVector = gce_MakeDir (theFirstPoint, theSecondPoint); |
a6eb515f |
979 | |
60bf98ae |
980 | // count a flyout direction vector. |
981 | gp_Dir aFlyoutVector = aPlaneNormal.Direction() ^ aTargetPointsVector; |
a6eb515f |
982 | |
60bf98ae |
983 | // create lines for layouts |
984 | gp_Lin aLine1 (theFirstPoint, aFlyoutVector); |
985 | gp_Lin aLine2 (theSecondPoint, aFlyoutVector); |
986 | |
987 | // get flyout end points |
988 | gp_Pnt aFlyoutEnd1 = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1); |
989 | gp_Pnt aFlyoutEnd2 = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2); |
990 | |
991 | // fill sensitive entity for flyouts |
992 | Handle(Select3D_SensitiveGroup) aSensitiveEntity = new Select3D_SensitiveGroup (theOwner); |
993 | aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, theFirstPoint, aFlyoutEnd1)); |
994 | aSensitiveEntity->Add (new Select3D_SensitiveSegment (theOwner, theSecondPoint, aFlyoutEnd2)); |
995 | theSelection->Add (aSensitiveEntity); |
a6eb515f |
996 | } |
997 | |
998 | //======================================================================= |
60bf98ae |
999 | //function : CircleFromPlanarFace |
a6eb515f |
1000 | //purpose : if possible computes circle from planar face |
1001 | //======================================================================= |
60bf98ae |
1002 | Standard_Boolean AIS_Dimension::CircleFromPlanarFace (const TopoDS_Face& theFace, |
a6eb515f |
1003 | Handle(Geom_Curve)& theCurve, |
60bf98ae |
1004 | gp_Pnt& theFirstPoint, |
1005 | gp_Pnt& theLastPoint) |
a6eb515f |
1006 | { |
1007 | TopExp_Explorer anIt (theFace, TopAbs_EDGE); |
1008 | for ( ; anIt.More(); anIt.Next()) |
1009 | { |
1010 | TopoDS_Edge aCurEdge = TopoDS::Edge (anIt.Current()); |
1011 | if (AIS::ComputeGeometry (aCurEdge, theCurve, theFirstPoint, theLastPoint)) |
1012 | { |
1013 | if (theCurve->IsInstance (STANDARD_TYPE(Geom_Circle))) |
1014 | { |
1015 | return Standard_True; |
1016 | } |
1017 | } |
1018 | } |
1019 | return Standard_False; |
1020 | } |
1021 | |
1022 | //======================================================================= |
60bf98ae |
1023 | //function : InitCircularDimension |
1024 | //purpose : |
a6eb515f |
1025 | //======================================================================= |
60bf98ae |
1026 | Standard_Boolean AIS_Dimension::InitCircularDimension (const TopoDS_Shape& theShape, |
a6eb515f |
1027 | gp_Circ& theCircle, |
1028 | gp_Pnt& theMiddleArcPoint, |
60bf98ae |
1029 | Standard_Boolean& theIsClosed) |
a6eb515f |
1030 | { |
1031 | gp_Pln aPln; |
1032 | Handle(Geom_Surface) aBasisSurf; |
1033 | AIS_KindOfSurface aSurfType = AIS_KOS_OtherSurface; |
1034 | gp_Pnt aFirstPoint, aLastPoint; |
1035 | Standard_Real anOffset = 0.0; |
1036 | Standard_Real aFirstParam = 0.0; |
1037 | Standard_Real aLastParam = 0.0; |
a6eb515f |
1038 | |
60bf98ae |
1039 | // discover circular geometry |
a6eb515f |
1040 | if (theShape.ShapeType() == TopAbs_FACE) |
1041 | { |
1042 | AIS::GetPlaneFromFace (TopoDS::Face (theShape), aPln, aBasisSurf, aSurfType, anOffset); |
1043 | |
1044 | if (aSurfType == AIS_KOS_Plane) |
1045 | { |
1046 | Handle(Geom_Curve) aCurve; |
60bf98ae |
1047 | if (!CircleFromPlanarFace (TopoDS::Face (theShape), aCurve, aFirstPoint, aLastPoint)) |
a6eb515f |
1048 | { |
a6eb515f |
1049 | return Standard_False; |
1050 | } |
1051 | |
1052 | theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ(); |
a6eb515f |
1053 | } |
1054 | else |
1055 | { |
1056 | gp_Pnt aCurPos; |
1057 | BRepAdaptor_Surface aSurf1 (TopoDS::Face (theShape)); |
1058 | Standard_Real aFirstU = aSurf1.FirstUParameter(); |
1059 | Standard_Real aLastU = aSurf1.LastUParameter(); |
1060 | Standard_Real aFirstV = aSurf1.FirstVParameter(); |
1061 | Standard_Real aLastV = aSurf1.LastVParameter(); |
1062 | Standard_Real aMidU = (aFirstU + aLastU) * 0.5; |
1063 | Standard_Real aMidV = (aFirstV + aLastV) * 0.5; |
60bf98ae |
1064 | aSurf1.D0 (aMidU, aMidV, aCurPos); |
a6eb515f |
1065 | Handle (Adaptor3d_HCurve) aBasisCurve; |
1066 | Standard_Boolean isExpectedType = Standard_False; |
1067 | if (aSurfType == AIS_KOS_Cylinder) |
1068 | { |
1069 | isExpectedType = Standard_True; |
1070 | } |
1071 | else |
1072 | { |
1073 | if (aSurfType == AIS_KOS_Revolution) |
1074 | { |
1075 | aBasisCurve = aSurf1.BasisCurve(); |
1076 | if (aBasisCurve->GetType() == GeomAbs_Line) |
1077 | { |
1078 | isExpectedType = Standard_True; |
1079 | } |
1080 | } |
1081 | else if (aSurfType == AIS_KOS_Extrusion) |
1082 | { |
1083 | aBasisCurve = aSurf1.BasisCurve(); |
1084 | if (aBasisCurve->GetType() == GeomAbs_Circle) |
1085 | { |
1086 | isExpectedType = Standard_True; |
1087 | } |
1088 | } |
1089 | } |
1090 | |
1091 | if (!isExpectedType) |
1092 | { |
a6eb515f |
1093 | return Standard_False; |
1094 | } |
60bf98ae |
1095 | |
a6eb515f |
1096 | Handle(Geom_Curve) aCurve; |
1097 | aCurve = aBasisSurf->VIso(aMidV); |
1098 | if (aCurve->DynamicType() == STANDARD_TYPE (Geom_Circle)) |
1099 | { |
1100 | theCircle = Handle(Geom_Circle)::DownCast (aCurve)->Circ(); |
1101 | } |
1102 | else if (aCurve->DynamicType() == STANDARD_TYPE (Geom_TrimmedCurve)) |
1103 | { |
1104 | Handle(Geom_TrimmedCurve) aTrimmedCurve = Handle(Geom_TrimmedCurve)::DownCast (aCurve); |
1105 | aFirstU = aTrimmedCurve->FirstParameter(); |
1106 | aLastU = aTrimmedCurve->LastParameter(); |
1107 | if (aTrimmedCurve->DynamicType() == STANDARD_TYPE (Geom_Circle)) |
1108 | { |
1109 | theCircle = Handle(Geom_Circle)::DownCast(aTrimmedCurve)->Circ(); |
1110 | } |
1111 | } |
1112 | else |
1113 | { |
1114 | // Compute a circle from 3 points on "aCurve" |
1115 | gp_Pnt aP1, aP2; |
1116 | aSurf1.D0 (aFirstU, aMidV, aP1); |
1117 | aSurf1.D0 (aLastU, aMidV, aP2); |
1118 | GC_MakeCircle aMkCirc (aP1, aCurPos, aP2); |
1119 | theCircle = aMkCirc.Value()->Circ(); |
1120 | } |
1121 | |
a6eb515f |
1122 | aFirstPoint = ElCLib::Value (aFirstU, theCircle); |
1123 | aLastPoint = ElCLib::Value (aLastU, theCircle); |
1124 | } |
1125 | } |
1126 | else // TopAbs_EDGE | TopAbs_WIRE |
1127 | { |
1128 | TopoDS_Edge anEdge; |
1129 | if (theShape.ShapeType() == TopAbs_WIRE) |
1130 | { |
1131 | TopExp_Explorer anIt (theShape, TopAbs_EDGE); |
1132 | if (anIt.More()) |
1133 | { |
1134 | anEdge = TopoDS::Edge (anIt.Current()); |
1135 | } |
1136 | } |
1137 | else if (theShape.ShapeType() == TopAbs_EDGE) |
1138 | { |
1139 | anEdge = TopoDS::Edge (theShape); |
1140 | } |
1141 | else // Unexpected type of shape |
1142 | { |
a6eb515f |
1143 | return Standard_False; |
1144 | } |
60bf98ae |
1145 | |
a6eb515f |
1146 | BRepAdaptor_Curve anAdaptedCurve (anEdge); |
1147 | if (!anAdaptedCurve.GetType() == GeomAbs_Circle) |
1148 | { |
1149 | return Standard_False; |
1150 | } |
60bf98ae |
1151 | |
1152 | theCircle = anAdaptedCurve.Circle(); |
a6eb515f |
1153 | aFirstPoint = anAdaptedCurve.Value (anAdaptedCurve.FirstParameter()); |
60bf98ae |
1154 | aLastPoint = anAdaptedCurve.Value (anAdaptedCurve.LastParameter()); |
a6eb515f |
1155 | } |
60bf98ae |
1156 | |
1157 | theIsClosed = aFirstPoint.IsEqual (aLastPoint, Precision::Confusion()); |
1158 | |
a6eb515f |
1159 | gp_Pnt aCenter = theCircle.Location(); |
60bf98ae |
1160 | |
1161 | if (theIsClosed) // Circle |
a6eb515f |
1162 | { |
a6eb515f |
1163 | gp_Dir anXDir = theCircle.XAxis().Direction(); |
1164 | theMiddleArcPoint = aCenter.Translated (gp_Vec (anXDir) * theCircle.Radius()); |
a6eb515f |
1165 | } |
60bf98ae |
1166 | else // Arc |
a6eb515f |
1167 | { |
a6eb515f |
1168 | aFirstParam = ElCLib::Parameter (theCircle, aFirstPoint); |
1169 | aLastParam = ElCLib::Parameter (theCircle, aLastPoint); |
1170 | if (aFirstParam > aLastParam) |
1171 | { |
1172 | aFirstParam -= 2.0 * M_PI; |
1173 | } |
60bf98ae |
1174 | |
a6eb515f |
1175 | Standard_Real aParCurPos = (aFirstParam + aLastParam) * 0.5; |
1176 | gp_Vec aVec = gp_Vec (aCenter, ElCLib::Value (aParCurPos, theCircle)).Normalized () * theCircle.Radius (); |
1177 | theMiddleArcPoint = aCenter.Translated (aVec); |
a6eb515f |
1178 | } |
1179 | |
1180 | return Standard_True; |
1181 | } |
1182 | |
a6eb515f |
1183 | //======================================================================= |
1184 | //function : ComputeSelection |
1185 | //purpose : |
1186 | //======================================================================= |
a6eb515f |
1187 | void AIS_Dimension::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection, |
1188 | const Standard_Integer theMode) |
1189 | { |
60bf98ae |
1190 | if (!myIsComputed) |
a6eb515f |
1191 | { |
1192 | return; |
1193 | } |
1194 | |
fe83e1ea |
1195 | AIS_DimensionSelectionMode aSelectionMode = (AIS_DimensionSelectionMode)theMode; |
a6eb515f |
1196 | |
fe83e1ea |
1197 | // init appropriate entity owner |
1198 | Handle(SelectMgr_EntityOwner) aSensitiveOwner; |
a6eb515f |
1199 | |
fe83e1ea |
1200 | switch (aSelectionMode) |
a6eb515f |
1201 | { |
fe83e1ea |
1202 | // neutral selection owner |
1203 | case AIS_DSM_All : |
1204 | aSensitiveOwner = new SelectMgr_EntityOwner (this, THE_NEUTRAL_SEL_PRIORITY); |
1205 | break; |
1206 | |
1207 | // local selection owners |
1208 | case AIS_DSM_Line : |
1209 | case AIS_DSM_Text : |
1210 | aSensitiveOwner = new AIS_DimensionOwner (this, aSelectionMode, THE_LOCAL_SEL_PRIORITY); |
1211 | break; |
a6eb515f |
1212 | } |
fe83e1ea |
1213 | |
1214 | if (aSelectionMode == AIS_DSM_All || aSelectionMode == AIS_DSM_Line) |
a6eb515f |
1215 | { |
fe83e1ea |
1216 | // sensitives for dimension line segments |
1217 | Handle(Select3D_SensitiveGroup) aGroupOfSensitives = new Select3D_SensitiveGroup (aSensitiveOwner); |
1218 | |
1219 | SelectionGeometry::SeqOfCurves::Iterator aCurveIt (mySelectionGeom.DimensionLine); |
1220 | for (; aCurveIt.More(); aCurveIt.Next()) |
1221 | { |
1222 | const SelectionGeometry::HCurve& aCurveData = aCurveIt.Value(); |
1223 | |
1224 | TColgp_Array1OfPnt aSensitivePnts (1, aCurveData->Length()); |
1225 | for (Standard_Integer aPntIt = 1; aPntIt <= aCurveData->Length(); ++aPntIt) |
1226 | { |
1227 | aSensitivePnts.ChangeValue (aPntIt) = aCurveData->Value (aPntIt); |
1228 | } |
1229 | |
1230 | aGroupOfSensitives->Add (new Select3D_SensitiveCurve (aSensitiveOwner, aSensitivePnts)); |
1231 | } |
1232 | |
1233 | Quantity_Length anArrowLength = myDrawer->DimensionAspect()->ArrowAspect()->Length(); |
1234 | Standard_Real anArrowAngle = myDrawer->DimensionAspect()->ArrowAspect()->Angle(); |
1235 | |
1236 | // sensitives for arrows |
1237 | SelectionGeometry::SeqOfArrows::Iterator anArrowIt (mySelectionGeom.Arrows); |
1238 | for (; anArrowIt.More(); anArrowIt.Next()) |
1239 | { |
1240 | const SelectionGeometry::HArrow& anArrow = anArrowIt.Value(); |
1241 | |
1242 | gp_Pnt aSidePnt1 (gp::Origin()); |
1243 | gp_Pnt aSidePnt2 (gp::Origin()); |
60bf98ae |
1244 | const gp_Dir& aPlane = GetPlane().Axis().Direction(); |
fe83e1ea |
1245 | const gp_Pnt& aPeak = anArrow->Position; |
1246 | const gp_Dir& aDir = anArrow->Direction; |
1247 | |
1248 | // compute points for arrow in plane |
1249 | PointsForArrow (aPeak, aDir, aPlane, anArrowLength, anArrowAngle, aSidePnt1, aSidePnt2); |
1250 | |
1251 | aGroupOfSensitives->Add (new Select3D_SensitiveTriangle (aSensitiveOwner, aPeak, aSidePnt1, aSidePnt2)); |
1252 | |
1253 | if (!myDrawer->DimensionAspect()->IsArrows3d()) |
1254 | { |
1255 | continue; |
1256 | } |
1257 | |
1258 | // compute points for orthogonal sensitive plane |
1259 | gp_Dir anOrthoPlane = anArrow->Direction.Crossed (aPlane); |
1260 | |
1261 | PointsForArrow (aPeak, aDir, anOrthoPlane, anArrowLength, anArrowAngle, aSidePnt1, aSidePnt2); |
1262 | |
1263 | aGroupOfSensitives->Add (new Select3D_SensitiveTriangle (aSensitiveOwner, aPeak, aSidePnt1, aSidePnt2)); |
1264 | } |
1265 | |
1266 | theSelection->Add (aGroupOfSensitives); |
a6eb515f |
1267 | } |
fe83e1ea |
1268 | |
1269 | // sensitives for text element |
1270 | if (aSelectionMode == AIS_DSM_All || aSelectionMode == AIS_DSM_Text) |
a6eb515f |
1271 | { |
fe83e1ea |
1272 | Handle(Select3D_SensitiveEntity) aTextSensitive; |
1273 | |
1274 | gp_Ax2 aTextAxes (mySelectionGeom.TextPos, |
60bf98ae |
1275 | GetPlane().Axis().Direction(), |
fe83e1ea |
1276 | mySelectionGeom.TextDir); |
1277 | |
1278 | if (myDrawer->DimensionAspect()->IsText3d()) |
1279 | { |
1280 | // sensitive planar rectangle for text |
1281 | Standard_Real aDx = mySelectionGeom.TextWidth * 0.5; |
1282 | Standard_Real aDy = mySelectionGeom.TextHeight * 0.5; |
1283 | |
1284 | gp_Trsf aLabelPlane; |
1285 | aLabelPlane.SetTransformation (aTextAxes, gp::XOY()); |
1286 | |
51f8f60c |
1287 | TColgp_Array1OfPnt aRectanglePoints(1, 4); |
1288 | aRectanglePoints.ChangeValue(1) = gp_Pnt (-aDx, -aDy, 0.0).Transformed (aLabelPlane); |
1289 | aRectanglePoints.ChangeValue(2) = gp_Pnt (-aDx, aDy, 0.0).Transformed (aLabelPlane); |
1290 | aRectanglePoints.ChangeValue(3) = gp_Pnt ( aDx, aDy, 0.0).Transformed (aLabelPlane); |
1291 | aRectanglePoints.ChangeValue(4) = gp_Pnt ( aDx, -aDy, 0.0).Transformed (aLabelPlane); |
fe83e1ea |
1292 | |
51f8f60c |
1293 | Poly_Array1OfTriangle aTriangles(1, 2); |
1294 | aTriangles.ChangeValue(1) = Poly_Triangle(1, 2, 3); |
1295 | aTriangles.ChangeValue(2) = Poly_Triangle(1, 3, 4); |
1296 | |
1297 | Handle(Poly_Triangulation) aRectanglePoly = |
1298 | new Poly_Triangulation(aRectanglePoints, aTriangles); |
1299 | |
1300 | aTextSensitive = |
1301 | new Select3D_SensitiveTriangulation (aSensitiveOwner, aRectanglePoly, TopLoc_Location(), Standard_True); |
fe83e1ea |
1302 | } |
1303 | else |
1304 | { |
1305 | gp_Circ aTextGeom (aTextAxes, mySelToleranceForText2d != 0.0 |
1306 | ? mySelToleranceForText2d : 1.0); |
1307 | |
1308 | Handle(Geom_Circle) aSensGeom = new Geom_Circle (aTextGeom); |
1309 | |
1310 | aTextSensitive = new Select3D_SensitiveCircle (aSensitiveOwner, aSensGeom, Standard_True); |
1311 | } |
1312 | |
1313 | theSelection->Add (aTextSensitive); |
a6eb515f |
1314 | } |
fe83e1ea |
1315 | |
1316 | // callback for flyout sensitive calculation |
1317 | if (aSelectionMode == AIS_DSM_All) |
d7bffd44 |
1318 | { |
60bf98ae |
1319 | ComputeFlyoutSelection (theSelection, aSensitiveOwner); |
d7bffd44 |
1320 | } |
fe83e1ea |
1321 | } |
1322 | |
1323 | //======================================================================= |
1324 | //function : PointsForArrow |
1325 | //purpose : |
1326 | //======================================================================= |
1327 | void AIS_Dimension::PointsForArrow (const gp_Pnt& thePeakPnt, |
1328 | const gp_Dir& theDirection, |
1329 | const gp_Dir& thePlane, |
1330 | const Standard_Real theArrowLength, |
1331 | const Standard_Real theArrowAngle, |
1332 | gp_Pnt& theSidePnt1, |
1333 | gp_Pnt& theSidePnt2) |
1334 | { |
1335 | gp_Lin anArrowLin (thePeakPnt, theDirection.Reversed()); |
1336 | gp_Pnt anArrowEnd = ElCLib::Value (theArrowLength, anArrowLin); |
1337 | gp_Lin anEdgeLin (anArrowEnd, theDirection.Crossed (thePlane)); |
1338 | |
1339 | Standard_Real anEdgeLength = Tan (theArrowAngle) * theArrowLength; |
a6eb515f |
1340 | |
fe83e1ea |
1341 | theSidePnt1 = ElCLib::Value ( anEdgeLength, anEdgeLin); |
1342 | theSidePnt2 = ElCLib::Value (-anEdgeLength, anEdgeLin); |
a6eb515f |
1343 | } |
af203d54 |
1344 | |
1345 | //======================================================================= |
1346 | //function : GetTextPositionForLinear |
1347 | //purpose : |
1348 | //======================================================================= |
1349 | gp_Pnt AIS_Dimension::GetTextPositionForLinear (const gp_Pnt& theFirstPoint, |
1350 | const gp_Pnt& theSecondPoint, |
1351 | const Standard_Boolean theIsOneSide) const |
1352 | { |
1353 | if (!myIsValid) |
1354 | { |
1355 | return gp::Origin(); |
1356 | } |
1357 | |
1358 | gp_Pnt aTextPosition (gp::Origin()); |
1359 | |
1360 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1361 | |
1362 | // Get label alignment and arrow orientation. |
1363 | Standard_Integer aLabelPosition = 0; |
1364 | Standard_Boolean isArrowsExternal = Standard_False; |
1365 | FitTextAlignmentForLinear (theFirstPoint, theSecondPoint, theIsOneSide, |
1366 | aDimensionAspect->TextHorizontalPosition(), |
1367 | aLabelPosition, isArrowsExternal); |
1368 | |
1369 | // Compute dimension line points. |
1370 | gp_Dir aPlaneNormal = GetPlane().Axis().Direction(); |
1371 | gp_Vec aTargetPointsVec (theFirstPoint, theSecondPoint); |
1372 | |
1373 | // Compute flyout direction vector |
1374 | gp_Dir aFlyoutVector = aPlaneNormal ^ gp_Dir (aTargetPointsVec); |
1375 | |
1376 | // create lines for layouts |
1377 | gp_Lin aLine1 (theFirstPoint, aFlyoutVector); |
1378 | gp_Lin aLine2 (theSecondPoint, aFlyoutVector); |
1379 | // Get flyout end points |
1380 | gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1); |
1381 | gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2); |
1382 | |
1383 | // Get text position. |
1384 | switch (aLabelPosition & LabelPosition_HMask) |
1385 | { |
1386 | case LabelPosition_Left: |
1387 | { |
1388 | gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint); |
1389 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
1390 | |
1391 | Standard_Real anOffset = isArrowsExternal |
1392 | ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length() |
1393 | : anExtensionSize; |
1394 | gp_Vec anExtensionVec = gp_Vec (aTargetPointsDir) * -anOffset; |
1395 | aTextPosition = aLineEndPoint.Translated (anExtensionVec); |
1396 | } |
1397 | break; |
1398 | case LabelPosition_Right: |
1399 | { |
1400 | gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint); |
1401 | Standard_Real anExtensionSize = aDimensionAspect->ExtensionSize(); |
1402 | |
1403 | Standard_Real anOffset = isArrowsExternal |
1404 | ? anExtensionSize + aDimensionAspect->ArrowAspect()->Length() |
1405 | : anExtensionSize; |
1406 | gp_Vec anExtensionVec = gp_Vec (aTargetPointsDir) * anOffset; |
1407 | aTextPosition = aLineBegPoint.Translated (anExtensionVec); |
1408 | } |
1409 | break; |
1410 | case LabelPosition_HCenter: |
1411 | { |
1412 | aTextPosition = (aLineBegPoint.XYZ() + aLineEndPoint.XYZ()) * 0.5; |
1413 | } |
1414 | break; |
1415 | } |
1416 | |
1417 | return aTextPosition; |
1418 | } |
1419 | |
1420 | //======================================================================= |
1421 | //function : AdjustAspectParameters |
1422 | //purpose : |
1423 | //======================================================================= |
1424 | void AIS_Dimension::AdjustParametersForLinear (const gp_Pnt& theTextPos, |
1425 | const gp_Pnt& theFirstPoint, |
1426 | const gp_Pnt& theSecondPoint, |
1427 | Standard_Real& theExtensionSize, |
1428 | Prs3d_DimensionTextHorizontalPosition& theAlignment) |
1429 | { |
1430 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1431 | Standard_Real anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
1432 | |
1433 | //Set new automatic plane. |
1434 | myPlane = gce_MakePln (theTextPos, theFirstPoint, theSecondPoint); |
1435 | myIsPlaneCustom = Standard_False; |
1436 | |
1437 | // Compute dimension line points. |
1438 | gp_Dir aPlaneNormal = GetPlane().Axis().Direction(); |
1439 | gp_Dir aTargetPointsDir = gce_MakeDir (theFirstPoint, theSecondPoint); |
1440 | gp_Vec aTargetPointsVec (theFirstPoint, theSecondPoint); |
1441 | |
1442 | // Compute flyout direction vector. |
1443 | gp_Dir aPositiveFlyout = aPlaneNormal ^ aTargetPointsDir; |
1444 | |
1445 | // Set flyout. |
1446 | gp_Vec aFirstToTextVec (theFirstPoint, theTextPos); |
1447 | |
1448 | Standard_Real aCos = aFirstToTextVec.Normalized() * gp_Vec (aTargetPointsDir); |
1449 | |
1450 | gp_Pnt aTextPosProj = theFirstPoint.Translated |
1451 | (gp_Vec (aTargetPointsDir) * aFirstToTextVec.Magnitude() * aCos); |
1452 | |
1453 | // Compute flyout value and direction. |
1454 | gp_Vec aFlyoutVector = gp_Vec (aTextPosProj, theTextPos); |
1455 | |
1456 | myFlyout = gp_Dir (aFlyoutVector).IsOpposite (aPositiveFlyout, Precision::Angular()) |
1457 | ? -aFlyoutVector.Magnitude() |
1458 | : aFlyoutVector.Magnitude(); |
1459 | |
1460 | // Compute attach points (through which main dimension line passes). |
1461 | gp_Pnt aFirstAttach = theFirstPoint.Translated (aFlyoutVector); |
1462 | gp_Pnt aSecondAttach = theSecondPoint.Translated (aFlyoutVector); |
1463 | |
1464 | // Set horisontal text alignment. |
1465 | if (aCos < 0.0) |
1466 | { |
1467 | theAlignment = Prs3d_DTHP_Left; |
1468 | |
1469 | Standard_Real aNewExtSize = theTextPos.Distance (aFirstAttach) - anArrowLength; |
1470 | theExtensionSize = aNewExtSize < 0.0 ? 0.0 : aNewExtSize; |
1471 | } |
1472 | else if (aTextPosProj.Distance (theFirstPoint) > theFirstPoint.Distance (theSecondPoint)) |
1473 | { |
1474 | theAlignment = Prs3d_DTHP_Right; |
1475 | |
1476 | Standard_Real aNewExtSize = theTextPos.Distance (aSecondAttach) - anArrowLength; |
1477 | theExtensionSize = aNewExtSize < 0.0 ? 0.0 : aNewExtSize; |
1478 | } |
1479 | else |
1480 | { |
1481 | theAlignment = Prs3d_DTHP_Center; |
1482 | } |
1483 | } |
1484 | |
1485 | //======================================================================= |
1486 | //function : FitTextAlignmentForLinear |
1487 | //purpose : |
1488 | //======================================================================= |
1489 | void AIS_Dimension::FitTextAlignmentForLinear (const gp_Pnt& theFirstPoint, |
1490 | const gp_Pnt& theSecondPoint, |
1491 | const Standard_Boolean theIsOneSide, |
1492 | const Prs3d_DimensionTextHorizontalPosition& theHorizontalTextPos, |
1493 | Standard_Integer& theLabelPosition, |
1494 | Standard_Boolean& theIsArrowsExternal) const |
1495 | { |
1496 | theLabelPosition = LabelPosition_None; |
1497 | theIsArrowsExternal = Standard_False; |
1498 | |
1499 | // Compute dimension line points |
1500 | gp_Ax1 aPlaneNormal = GetPlane().Axis(); |
1501 | gp_Dir aTargetPointsVector = gce_MakeDir (theFirstPoint, theSecondPoint); |
1502 | |
1503 | // compute flyout direction vector |
1504 | gp_Dir aFlyoutVector = aPlaneNormal.Direction() ^ aTargetPointsVector; |
1505 | |
1506 | // create lines for layouts |
1507 | gp_Lin aLine1 (theFirstPoint, aFlyoutVector); |
1508 | gp_Lin aLine2 (theSecondPoint, aFlyoutVector); |
1509 | |
1510 | // Get flyout end points |
1511 | gp_Pnt aLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout(), aLine1); |
1512 | gp_Pnt aLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2); |
1513 | |
1514 | Handle(Prs3d_DimensionAspect) aDimensionAspect = myDrawer->DimensionAspect(); |
1515 | |
1516 | gp_Lin aDimensionLine = gce_MakeLin (aLineBegPoint, aLineEndPoint); |
1517 | |
1518 | // For extensions we need to know arrow size, text size and extension size: get it from aspect |
1519 | Quantity_Length anArrowLength = aDimensionAspect->ArrowAspect()->Length(); |
1520 | |
1521 | // prepare label string and compute its geometrical width |
1522 | Standard_Real aLabelWidth; |
1523 | TCollection_ExtendedString aLabelString = GetValueString (aLabelWidth); |
1524 | |
1525 | // Add margins to cut dimension lines for 3d text |
1526 | if (aDimensionAspect->IsText3d()) |
1527 | { |
1528 | aLabelWidth += aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN * 2.0; |
1529 | } |
1530 | |
1531 | // Handle user-defined and automatic arrow placement |
1532 | switch (aDimensionAspect->ArrowOrientation()) |
1533 | { |
1534 | case Prs3d_DAO_External: theIsArrowsExternal = true; break; |
1535 | case Prs3d_DAO_Internal: theIsArrowsExternal = false; break; |
1536 | case Prs3d_DAO_Fit: |
1537 | { |
1538 | // Add margin to ensure a small tail between text and arrow |
1539 | Standard_Real anArrowMargin = aDimensionAspect->IsText3d() |
1540 | ? aDimensionAspect->TextAspect()->Height() * THE_3D_TEXT_MARGIN |
1541 | : 0.0; |
1542 | |
1543 | Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint); |
1544 | Standard_Real anArrowsWidth = theIsOneSide |
1545 | ? anArrowLength + anArrowMargin |
1546 | : (anArrowLength + anArrowMargin) * 2.0; |
1547 | |
1548 | theIsArrowsExternal = aDimensionWidth < aLabelWidth + anArrowsWidth; |
1549 | break; |
1550 | } |
1551 | } |
1552 | |
1553 | // Handle user-defined and automatic text placement |
1554 | switch (theHorizontalTextPos) |
1555 | { |
1556 | case Prs3d_DTHP_Left : theLabelPosition |= LabelPosition_Left; break; |
1557 | case Prs3d_DTHP_Right : theLabelPosition |= LabelPosition_Right; break; |
1558 | case Prs3d_DTHP_Center: theLabelPosition |= LabelPosition_HCenter; break; |
1559 | case Prs3d_DTHP_Fit: |
1560 | { |
1561 | Standard_Real aDimensionWidth = aLineBegPoint.Distance (aLineEndPoint); |
1562 | Standard_Real anArrowsWidth = theIsOneSide ? anArrowLength : 2.0 * anArrowLength; |
1563 | Standard_Real aContentWidth = theIsArrowsExternal ? aLabelWidth : aLabelWidth + anArrowsWidth; |
1564 | |
1565 | theLabelPosition |= aDimensionWidth < aContentWidth ? LabelPosition_Left : LabelPosition_HCenter; |
1566 | break; |
1567 | } |
1568 | } |
1569 | |
1570 | // Handle vertical text placement options |
1571 | switch (aDimensionAspect->TextVerticalPosition()) |
1572 | { |
1573 | case Prs3d_DTVP_Above : theLabelPosition |= LabelPosition_Above; break; |
1574 | case Prs3d_DTVP_Below : theLabelPosition |= LabelPosition_Below; break; |
1575 | case Prs3d_DTVP_Center : theLabelPosition |= LabelPosition_VCenter; break; |
1576 | } |
1577 | } |
1578 | |
1579 | //======================================================================= |
1580 | //function : UnsetFixedTextPosition |
1581 | //purpose : |
1582 | //======================================================================= |
1583 | void AIS_Dimension::UnsetFixedTextPosition() |
1584 | { |
1585 | myIsTextPositionFixed = Standard_False; |
1586 | myFixedTextPosition = gp::Origin(); |
1587 | } |