b311480e |
1 | // Created on: 1996-12-05 |
2 | // Created by: Arnaud BOUZY/Odile Olivier |
3 | // Copyright (c) 1996-1999 Matra Datavision |
a6eb515f |
4 | // Copyright (c) 1999-2013 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
12 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
b311480e |
16 | |
a6eb515f |
17 | #include <AIS_LengthDimension.hxx> |
7fd59977 |
18 | |
19 | #include <AIS.hxx> |
a6eb515f |
20 | #include <BRep_Tool.hxx> |
7fd59977 |
21 | #include <BRepAdaptor_Curve.hxx> |
1c078d3b |
22 | #include <BRepExtrema_DistShapeShape.hxx> |
a6eb515f |
23 | #include <BRepLib_MakeVertex.hxx> |
24 | #include <BRepTopAdaptor_FClass2d.hxx> |
60bf98ae |
25 | #include <BRepTools.hxx> |
7fd59977 |
26 | #include <ElCLib.hxx> |
27 | #include <ElSLib.hxx> |
a6eb515f |
28 | #include <gce_MakeDir.hxx> |
60bf98ae |
29 | #include <gce_MakePln.hxx> |
1c078d3b |
30 | #include <Geom_TrimmedCurve.hxx> |
60bf98ae |
31 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
60bf98ae |
32 | #include <GeomAPI_ExtremaSurfaceSurface.hxx> |
33 | #include <Geom_Curve.hxx> |
34 | #include <Geom_Line.hxx> |
7fd59977 |
35 | #include <TopExp.hxx> |
36 | #include <TopExp_Explorer.hxx> |
7fd59977 |
37 | |
7fd59977 |
38 | |
92efcf78 |
39 | IMPLEMENT_STANDARD_RTTIEXT(AIS_LengthDimension,AIS_Dimension) |
40 | |
7fd59977 |
41 | //======================================================================= |
42 | //function : Constructor |
60bf98ae |
43 | //purpose : Dimension between two faces |
44 | //======================================================================= |
45 | AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFirstFace, |
46 | const TopoDS_Face& theSecondFace) |
948c552a |
47 | : AIS_Dimension (AIS_KOD_LENGTH), |
48 | myHasCustomDirection (Standard_False) |
60bf98ae |
49 | { |
50 | SetMeasuredGeometry (theFirstFace, theSecondFace); |
51 | SetFlyout (15.0); |
52 | } |
53 | |
54 | //======================================================================= |
55 | //function : Constructor |
56 | //purpose : Dimension between two shape |
7fd59977 |
57 | //======================================================================= |
60bf98ae |
58 | AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& theFace, |
59 | const TopoDS_Edge& theEdge) |
948c552a |
60 | : AIS_Dimension (AIS_KOD_LENGTH), |
61 | myHasCustomDirection (Standard_False) |
60bf98ae |
62 | { |
63 | SetMeasuredGeometry (theFace, theEdge); |
64 | SetFlyout (15.0); |
65 | } |
7fd59977 |
66 | |
60bf98ae |
67 | //======================================================================= |
68 | //function : Constructor |
69 | //purpose : Dimension between two points |
70 | //======================================================================= |
a6eb515f |
71 | AIS_LengthDimension::AIS_LengthDimension (const gp_Pnt& theFirstPoint, |
72 | const gp_Pnt& theSecondPoint, |
60bf98ae |
73 | const gp_Pln& thePlane) |
948c552a |
74 | : AIS_Dimension (AIS_KOD_LENGTH), |
75 | myHasCustomDirection (Standard_False) |
7fd59977 |
76 | { |
60bf98ae |
77 | SetMeasuredGeometry (theFirstPoint, theSecondPoint, thePlane); |
d7bffd44 |
78 | SetFlyout (15.0); |
7fd59977 |
79 | } |
80 | |
7fd59977 |
81 | //======================================================================= |
82 | //function : Constructor |
a6eb515f |
83 | //purpose : Dimension between two shape |
7fd59977 |
84 | //======================================================================= |
a6eb515f |
85 | AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Shape& theFirstShape, |
86 | const TopoDS_Shape& theSecondShape, |
60bf98ae |
87 | const gp_Pln& thePlane) |
948c552a |
88 | : AIS_Dimension (AIS_KOD_LENGTH), |
89 | myHasCustomDirection (Standard_False) |
7fd59977 |
90 | { |
60bf98ae |
91 | SetCustomPlane (thePlane); |
92 | SetMeasuredShapes (theFirstShape, theSecondShape); |
d7bffd44 |
93 | SetFlyout (15.0); |
7fd59977 |
94 | } |
95 | |
96 | //======================================================================= |
97 | //function : Constructor |
a6eb515f |
98 | //purpose : Dimension of one edge |
7fd59977 |
99 | //======================================================================= |
a6eb515f |
100 | AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Edge& theEdge, |
60bf98ae |
101 | const gp_Pln& thePlane) |
948c552a |
102 | : AIS_Dimension (AIS_KOD_LENGTH), |
103 | myHasCustomDirection (Standard_False) |
7fd59977 |
104 | { |
60bf98ae |
105 | SetMeasuredGeometry (theEdge, thePlane); |
d7bffd44 |
106 | SetFlyout (15.0); |
7fd59977 |
107 | } |
108 | |
7fd59977 |
109 | //======================================================================= |
60bf98ae |
110 | //function : SetMeasuredGeometry |
111 | //purpose : |
7fd59977 |
112 | //======================================================================= |
60bf98ae |
113 | void AIS_LengthDimension::SetMeasuredGeometry (const gp_Pnt& theFirstPoint, |
114 | const gp_Pnt& theSecondPoint, |
115 | const gp_Pln& thePlane) |
116 | { |
91b16a64 |
117 | myFirstPoint = theFirstPoint; |
118 | mySecondPoint = theSecondPoint; |
119 | myFirstShape = BRepLib_MakeVertex (myFirstPoint); |
120 | mySecondShape = BRepLib_MakeVertex (mySecondPoint); |
121 | myGeometryType = GeometryType_Points; |
60bf98ae |
122 | SetCustomPlane (thePlane); |
91b16a64 |
123 | myIsGeometryValid = IsValidPoints (theFirstPoint, theSecondPoint); |
60bf98ae |
124 | |
125 | SetToUpdate(); |
126 | } |
7fd59977 |
127 | |
60bf98ae |
128 | //======================================================================= |
129 | //function : SetMeasuredGeometry |
130 | //purpose : |
131 | //======================================================================= |
132 | void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Edge& theEdge, |
133 | const gp_Pln& thePlane) |
7fd59977 |
134 | { |
91b16a64 |
135 | myFirstShape = theEdge; |
136 | mySecondShape = TopoDS_Shape(); |
137 | myGeometryType = GeometryType_Edge; |
60bf98ae |
138 | SetCustomPlane (thePlane); |
91b16a64 |
139 | myIsGeometryValid = InitOneShapePoints (myFirstShape); |
60bf98ae |
140 | |
141 | SetToUpdate(); |
7fd59977 |
142 | } |
143 | |
144 | //======================================================================= |
60bf98ae |
145 | //function : SetMeasuredGeometry |
146 | //purpose : |
7fd59977 |
147 | //======================================================================= |
60bf98ae |
148 | void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFirstFace, |
149 | const TopoDS_Face& theSecondFace) |
150 | { |
151 | SetMeasuredShapes (theFirstFace, theSecondFace); |
152 | } |
7fd59977 |
153 | |
60bf98ae |
154 | //======================================================================= |
155 | //function : SetMeasuredGeometry |
156 | //purpose : |
157 | //======================================================================= |
158 | void AIS_LengthDimension::SetMeasuredGeometry (const TopoDS_Face& theFace, |
159 | const TopoDS_Edge& theEdge) |
7fd59977 |
160 | { |
60bf98ae |
161 | SetMeasuredShapes (theFace, theEdge); |
162 | } |
163 | |
164 | //======================================================================= |
165 | //function : SetMeasuredShapes |
166 | //purpose : |
167 | //======================================================================= |
168 | void AIS_LengthDimension::SetMeasuredShapes (const TopoDS_Shape& theFirstShape, |
169 | const TopoDS_Shape& theSecondShape) |
170 | { |
171 | gp_Pln aComputedPlane; |
172 | Standard_Boolean isPlaneReturned = Standard_False; |
60bf98ae |
173 | |
91b16a64 |
174 | myFirstShape = theFirstShape; |
175 | mySecondShape = theSecondShape; |
176 | myIsGeometryValid = InitTwoShapesPoints (myFirstShape, mySecondShape, aComputedPlane, isPlaneReturned); |
177 | |
178 | if (myIsGeometryValid && !myIsPlaneCustom) |
60bf98ae |
179 | { |
180 | if (isPlaneReturned) |
181 | { |
182 | myPlane = aComputedPlane; |
183 | } |
184 | else |
185 | { |
91b16a64 |
186 | myIsGeometryValid = Standard_False; |
60bf98ae |
187 | } |
188 | } |
189 | |
60bf98ae |
190 | SetToUpdate(); |
191 | } |
192 | |
193 | //======================================================================= |
194 | //function : CheckPlane |
195 | //purpose : |
196 | //======================================================================= |
197 | Standard_Boolean AIS_LengthDimension::CheckPlane (const gp_Pln& thePlane) const |
198 | { |
b0804487 |
199 | Standard_Boolean anIsFaultyNormal = |
200 | thePlane.Axis().Direction().IsParallel(gce_MakeDir (myFirstPoint, mySecondPoint), Precision::Angular()); |
201 | |
202 | if ((!thePlane.Contains (myFirstPoint, Precision::Confusion()) && !thePlane.Contains (mySecondPoint, Precision::Confusion())) |
203 | || anIsFaultyNormal) |
60bf98ae |
204 | { |
205 | return Standard_False; |
206 | } |
207 | |
208 | return Standard_True; |
209 | } |
210 | |
211 | //======================================================================= |
212 | //function : ComputePlane |
213 | //purpose : |
214 | //======================================================================= |
215 | gp_Pln AIS_LengthDimension::ComputePlane (const gp_Dir& theAttachDir) const |
216 | { |
217 | if (!IsValidPoints (myFirstPoint, mySecondPoint)) |
218 | { |
219 | return gp_Pln(); |
220 | } |
221 | |
222 | gp_Pnt aThirdPoint (myFirstPoint.Translated (gp_Vec(theAttachDir))); |
223 | gce_MakePln aPlaneConstrustor (myFirstPoint, mySecondPoint, aThirdPoint); |
224 | return aPlaneConstrustor.Value(); |
225 | } |
226 | |
227 | //======================================================================= |
228 | //function : GetModelUnits |
229 | //purpose : |
230 | //======================================================================= |
231 | const TCollection_AsciiString& AIS_LengthDimension::GetModelUnits() const |
232 | { |
233 | return myDrawer->DimLengthModelUnits(); |
7fd59977 |
234 | } |
235 | |
236 | //======================================================================= |
60bf98ae |
237 | //function : GetDisplayUnits |
238 | //purpose : |
7fd59977 |
239 | //======================================================================= |
60bf98ae |
240 | const TCollection_AsciiString& AIS_LengthDimension::GetDisplayUnits() const |
241 | { |
242 | return myDrawer->DimLengthDisplayUnits(); |
243 | } |
244 | |
245 | //======================================================================= |
246 | //function : SetModelUnits |
247 | //purpose : |
248 | //======================================================================= |
249 | void AIS_LengthDimension::SetModelUnits (const TCollection_AsciiString& theUnits) |
250 | { |
251 | myDrawer->SetDimLengthModelUnits (theUnits); |
252 | } |
253 | |
254 | //======================================================================= |
255 | //function : SetDisplayUnits |
256 | //purpose : |
257 | //======================================================================= |
258 | void AIS_LengthDimension::SetDisplayUnits (const TCollection_AsciiString& theUnits) |
259 | { |
260 | myDrawer->SetDimLengthDisplayUnits (theUnits); |
261 | } |
7fd59977 |
262 | |
60bf98ae |
263 | //======================================================================= |
264 | //function : ComputeValue |
265 | //purpose : |
266 | //======================================================================= |
267 | Standard_Real AIS_LengthDimension::ComputeValue() const |
268 | { |
948c552a |
269 | if (!IsValid()) |
270 | return 0.0; |
271 | |
272 | if (!myHasCustomDirection) |
273 | return myFirstPoint.Distance (mySecondPoint); |
274 | |
275 | return fabs (gp_Vec(myFirstPoint, mySecondPoint).Dot (myDirection)); |
60bf98ae |
276 | } |
277 | |
278 | //======================================================================= |
279 | //function : Compute |
280 | //purpose : |
281 | //======================================================================= |
282 | void AIS_LengthDimension::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePM*/, |
283 | const Handle(Prs3d_Presentation)& thePresentation, |
284 | const Standard_Integer theMode) |
285 | { |
60bf98ae |
286 | mySelectionGeom.Clear (theMode); |
287 | |
288 | if (!IsValid()) |
289 | { |
290 | return; |
291 | } |
292 | |
293 | DrawLinearDimension (thePresentation, theMode, myFirstPoint, mySecondPoint); |
294 | } |
295 | |
948c552a |
296 | //======================================================================= |
297 | //function : ComputeFlyoutLinePoints |
298 | //purpose : |
299 | //======================================================================= |
300 | void AIS_LengthDimension::ComputeFlyoutLinePoints (const gp_Pnt& theFirstPoint, const gp_Pnt& theSecondPoint, |
301 | gp_Pnt& theLineBegPoint, gp_Pnt& theLineEndPoint) |
302 | { |
303 | if (!myHasCustomDirection) |
304 | { |
305 | AIS_Dimension::ComputeFlyoutLinePoints (theFirstPoint, theSecondPoint, theLineBegPoint, theLineEndPoint); |
306 | return; |
307 | } |
308 | |
309 | // find scalar of projection target vector (from start to second point) to flyout vector |
310 | gp_Ax1 aPlaneNormal = GetPlane().Axis(); |
311 | gp_Vec aFlyoutNormalizedDir(aPlaneNormal.Direction() ^ myDirection); |
312 | aFlyoutNormalizedDir.Normalize(); |
313 | Standard_Real aTargetProjectedToFlyout = gp_Vec(theFirstPoint, theSecondPoint).Dot (aFlyoutNormalizedDir); |
314 | |
315 | gp_Dir aFlyoutVector = aFlyoutNormalizedDir; |
316 | // create lines for layouts |
317 | gp_Lin aLine1 (theFirstPoint, aFlyoutVector); |
318 | gp_Lin aLine2 (theSecondPoint, aFlyoutVector); |
319 | |
320 | // Get flyout end points |
321 | theLineBegPoint = ElCLib::Value (ElCLib::Parameter (aLine1, theFirstPoint) + GetFlyout() + aTargetProjectedToFlyout, aLine1); |
322 | theLineEndPoint = ElCLib::Value (ElCLib::Parameter (aLine2, theSecondPoint) + GetFlyout(), aLine2); |
323 | } |
324 | |
60bf98ae |
325 | //======================================================================= |
326 | //function : ComputeFlyoutSelection |
327 | //purpose : |
328 | //======================================================================= |
329 | void AIS_LengthDimension::ComputeFlyoutSelection (const Handle(SelectMgr_Selection)& theSelection, |
330 | const Handle(SelectMgr_EntityOwner)& theEntityOwner) |
331 | { |
332 | if (!IsValid()) |
333 | { |
334 | return; |
335 | } |
336 | |
337 | ComputeLinearFlyouts (theSelection, theEntityOwner, myFirstPoint, mySecondPoint); |
338 | } |
339 | |
340 | //======================================================================= |
341 | //function : IsValidPoints |
342 | //purpose : |
343 | //======================================================================= |
344 | Standard_Boolean AIS_LengthDimension::IsValidPoints (const gp_Pnt& theFirstPoint, |
345 | const gp_Pnt& theSecondPoint) const |
346 | { |
347 | return theFirstPoint.Distance (theSecondPoint) > Precision::Confusion(); |
348 | } |
349 | |
350 | //======================================================================= |
351 | //function : InitTwoEdgesLength |
352 | //purpose : Initialization of dimension between two linear edges |
353 | //======================================================================= |
354 | Standard_Boolean AIS_LengthDimension::InitTwoEdgesLength (const TopoDS_Edge& theFirstEdge, |
d7bffd44 |
355 | const TopoDS_Edge& theSecondEdge, |
356 | gp_Dir& theDirAttach) |
7fd59977 |
357 | { |
a6eb515f |
358 | BRepAdaptor_Curve aFirstCurveAdapt (theFirstEdge); |
359 | if (aFirstCurveAdapt.GetType() != GeomAbs_Line) |
60bf98ae |
360 | { |
a6eb515f |
361 | return Standard_False; |
60bf98ae |
362 | } |
363 | |
a6eb515f |
364 | BRepAdaptor_Curve aSecondCurveAdapt (theSecondEdge); |
365 | if (aSecondCurveAdapt.GetType() != GeomAbs_Line) |
60bf98ae |
366 | { |
a6eb515f |
367 | return Standard_False; |
60bf98ae |
368 | } |
a6eb515f |
369 | |
60bf98ae |
370 | Handle(Geom_Curve) aFirstCurve; |
371 | Handle(Geom_Curve) aSecondCurve; |
372 | |
373 | gp_Pnt aPoint11 (gp::Origin()); |
374 | gp_Pnt aPoint12 (gp::Origin()); |
375 | gp_Pnt aPoint21 (gp::Origin()); |
376 | gp_Pnt aPoint22 (gp::Origin()); |
377 | Standard_Boolean isFirstInfinite = Standard_False; |
378 | Standard_Boolean isSecondInfinite = Standard_False; |
379 | |
380 | if (!AIS::ComputeGeometry (theFirstEdge, theSecondEdge, |
381 | aFirstCurve, aSecondCurve, |
382 | aPoint11, aPoint12, |
383 | aPoint21, aPoint22, |
384 | isFirstInfinite, |
385 | isSecondInfinite)) |
a6eb515f |
386 | { |
60bf98ae |
387 | return Standard_False; |
a6eb515f |
388 | } |
60bf98ae |
389 | |
390 | const Handle(Geom_Line) aFirstLine = Handle(Geom_Line)::DownCast (aFirstCurve); |
391 | const Handle(Geom_Line) aSecondLine = Handle(Geom_Line)::DownCast (aSecondCurve); |
392 | |
393 | if (!aFirstLine->Lin().Direction().IsParallel (aSecondLine->Lin().Direction(),Precision::Angular())) |
a6eb515f |
394 | { |
60bf98ae |
395 | return Standard_False; |
7fd59977 |
396 | } |
60bf98ae |
397 | |
398 | theDirAttach = aFirstLine->Lin().Direction(); |
399 | |
400 | gp_Pnt aPoint; |
401 | |
a6eb515f |
402 | if (!isFirstInfinite) |
403 | { |
60bf98ae |
404 | if (AIS::Nearest (aSecondCurve, aPoint11, aPoint21, aPoint22, aPoint)) |
405 | { |
a6eb515f |
406 | myFirstPoint = aPoint11; |
60bf98ae |
407 | mySecondPoint = aPoint; |
408 | return IsValidPoints (myFirstPoint, mySecondPoint); |
409 | } |
410 | else if (AIS::Nearest (aSecondCurve, aPoint12, aPoint21, aPoint22, aPoint)) |
411 | { |
412 | myFirstPoint = aPoint12; |
413 | mySecondPoint = aPoint; |
414 | return IsValidPoints (myFirstPoint, mySecondPoint); |
415 | } |
7fd59977 |
416 | } |
417 | |
a6eb515f |
418 | if (!isSecondInfinite) |
419 | { |
60bf98ae |
420 | if (AIS::Nearest (aFirstCurve, aPoint21, aPoint11, aPoint12, aPoint)) |
421 | { |
422 | myFirstPoint = aPoint; |
a6eb515f |
423 | mySecondPoint = aPoint21; |
60bf98ae |
424 | return IsValidPoints (myFirstPoint, mySecondPoint); |
425 | } |
426 | if (AIS::Nearest (aFirstCurve, aPoint22, aPoint11, aPoint12, aPoint)) |
427 | { |
428 | myFirstPoint = aPoint; |
429 | mySecondPoint = aPoint22; |
430 | return IsValidPoints (myFirstPoint, mySecondPoint); |
431 | } |
a6eb515f |
432 | } |
7fd59977 |
433 | |
60bf98ae |
434 | GeomAPI_ExtremaCurveCurve anExtrema (aFirstCurve, aSecondCurve); |
435 | anExtrema.NearestPoints (myFirstPoint, mySecondPoint); |
436 | return IsValidPoints (myFirstPoint, mySecondPoint); |
7fd59977 |
437 | } |
438 | |
7fd59977 |
439 | //======================================================================= |
60bf98ae |
440 | //function : InitEdgeVertexLength |
a6eb515f |
441 | //purpose : for first edge and second vertex shapes |
7fd59977 |
442 | //======================================================================= |
60bf98ae |
443 | Standard_Boolean AIS_LengthDimension::InitEdgeVertexLength (const TopoDS_Edge& theEdge, |
444 | const TopoDS_Vertex& theVertex, |
445 | gp_Dir& theEdgeDir, |
d7bffd44 |
446 | Standard_Boolean isInfinite) |
7fd59977 |
447 | { |
60bf98ae |
448 | gp_Pnt anEdgePoint1 (gp::Origin()); |
449 | gp_Pnt anEdgePoint2 (gp::Origin()); |
a6eb515f |
450 | Handle(Geom_Curve) aCurve; |
60bf98ae |
451 | |
452 | if (!AIS::ComputeGeometry (theEdge, aCurve, anEdgePoint1, anEdgePoint2, isInfinite)) |
453 | { |
a6eb515f |
454 | return Standard_False; |
60bf98ae |
455 | } |
456 | |
457 | myFirstPoint = BRep_Tool::Pnt (theVertex); |
a6eb515f |
458 | |
c5f3a425 |
459 | Handle(Geom_Line) aGeomLine (Handle(Geom_Line)::DownCast (aCurve)); |
a6eb515f |
460 | const gp_Lin& aLin = aGeomLine->Lin(); |
461 | |
60bf98ae |
462 | // Get direction of edge to build plane automatically. |
463 | theEdgeDir = aLin.Direction(); |
a6eb515f |
464 | |
60bf98ae |
465 | mySecondPoint = AIS::Nearest (aLin, myFirstPoint); |
a6eb515f |
466 | |
60bf98ae |
467 | return IsValidPoints (myFirstPoint, mySecondPoint); |
7fd59977 |
468 | } |
469 | |
7fd59977 |
470 | //======================================================================= |
60bf98ae |
471 | //function : InitEdgeFaceLength |
7fd59977 |
472 | //purpose : |
473 | //======================================================================= |
60bf98ae |
474 | Standard_Boolean AIS_LengthDimension::InitEdgeFaceLength (const TopoDS_Edge& theEdge, |
a6eb515f |
475 | const TopoDS_Face& theFace, |
60bf98ae |
476 | gp_Dir& theEdgeDir) |
7fd59977 |
477 | { |
3c162495 |
478 | theEdgeDir = gp::DX(); |
479 | |
480 | // Find attachment points (closest distance between the edge and the face) |
481 | BRepExtrema_DistShapeShape aDistAdaptor (theEdge, theFace, Extrema_ExtFlag_MIN); |
482 | if (!aDistAdaptor.IsDone() || aDistAdaptor.NbSolution() <1) |
a6eb515f |
483 | { |
60bf98ae |
484 | return Standard_False; |
7fd59977 |
485 | } |
3c162495 |
486 | myFirstPoint = aDistAdaptor.PointOnShape1 (1); |
487 | mySecondPoint = aDistAdaptor.PointOnShape2 (1); |
488 | |
489 | // Take direction for dimension line (will be orthogonalized later) parallel to edge |
490 | BRepAdaptor_Curve aCurveAdaptor (theEdge); |
491 | Standard_Real aParam; |
492 | if (aDistAdaptor.SupportOnShape1 (1).ShapeType() == TopAbs_EDGE) |
a6eb515f |
493 | { |
3c162495 |
494 | aDistAdaptor.ParOnEdgeS1 (1, aParam); |
495 | } |
496 | else |
497 | { |
498 | Standard_Real aD1 = aCurveAdaptor.Value(aCurveAdaptor.FirstParameter()).SquareDistance (myFirstPoint); |
499 | Standard_Real aD2 = aCurveAdaptor.Value(aCurveAdaptor.LastParameter()).SquareDistance (myFirstPoint); |
500 | aParam = (aD1 < aD2 ? aCurveAdaptor.FirstParameter() : aCurveAdaptor.LastParameter()); |
501 | } |
502 | gp_Pnt aP; |
503 | gp_Vec aV; |
504 | aCurveAdaptor.D1 (aParam, aP, aV); |
505 | if (aV.SquareMagnitude() > gp::Resolution()) |
506 | { |
507 | theEdgeDir = aV; |
7fd59977 |
508 | } |
7fd59977 |
509 | |
3c162495 |
510 | // reverse direction if parameter is close to the end of the curve, |
511 | // to reduce chances to have overlapping between dimension line and edge |
512 | if (Abs (aParam - aCurveAdaptor.FirstParameter()) < Abs (aParam - aCurveAdaptor.LastParameter())) |
1c078d3b |
513 | { |
3c162495 |
514 | theEdgeDir.Reverse(); |
1c078d3b |
515 | } |
60bf98ae |
516 | |
517 | return IsValidPoints (myFirstPoint, mySecondPoint); |
7fd59977 |
518 | } |
519 | |
520 | //======================================================================= |
60bf98ae |
521 | //function : InitTwoShapesPoints |
a6eb515f |
522 | //purpose : Initialization of two points where dimension layouts |
523 | // will be attached |
7fd59977 |
524 | //======================================================================= |
60bf98ae |
525 | Standard_Boolean AIS_LengthDimension::InitTwoShapesPoints (const TopoDS_Shape& theFirstShape, |
526 | const TopoDS_Shape& theSecondShape, |
527 | gp_Pln& theComputedPlane, |
528 | Standard_Boolean& theIsPlaneComputed) |
7fd59977 |
529 | { |
60bf98ae |
530 | theIsPlaneComputed = Standard_False; |
a6eb515f |
531 | gp_Dir aDirAttach; |
532 | Standard_Boolean isInfinite = Standard_False; |
60bf98ae |
533 | Standard_Boolean isSuccess = Standard_False; |
a6eb515f |
534 | switch (theFirstShape.ShapeType()) |
535 | { |
60bf98ae |
536 | case TopAbs_FACE: |
7fd59977 |
537 | { |
a6eb515f |
538 | // Initialization for face |
539 | gp_Pln aFirstPlane; |
540 | Handle(Geom_Surface) aFirstSurface; |
541 | AIS_KindOfSurface aFirstSurfKind; |
542 | Standard_Real aFirstOffset; |
60bf98ae |
543 | |
a6eb515f |
544 | TopoDS_Face aFirstFace = TopoDS::Face (theFirstShape); |
a6eb515f |
545 | |
60bf98ae |
546 | AIS::InitFaceLength (TopoDS::Face (theFirstShape), |
547 | aFirstPlane, |
548 | aFirstSurface, |
549 | aFirstSurfKind, |
550 | aFirstOffset); |
551 | |
552 | if (theSecondShape.ShapeType() == TopAbs_FACE) |
a6eb515f |
553 | { |
554 | // Initialization for face |
60bf98ae |
555 | myGeometryType = GeometryType_Faces; |
a6eb515f |
556 | gp_Pln aSecondPlane; |
557 | Handle(Geom_Surface) aSecondSurface; |
558 | AIS_KindOfSurface aSecondSurfKind; |
559 | Standard_Real aSecondOffset; |
60bf98ae |
560 | |
a6eb515f |
561 | TopoDS_Face aSecondFace = TopoDS::Face (theSecondShape); |
60bf98ae |
562 | |
563 | AIS::InitFaceLength (aSecondFace, |
564 | aSecondPlane, |
565 | aSecondSurface, |
566 | aSecondSurfKind, |
567 | aSecondOffset); |
568 | |
a6eb515f |
569 | if (aFirstSurfKind == AIS_KOS_Plane) |
7fd59977 |
570 | { |
60bf98ae |
571 | if (!aFirstPlane.Axis().Direction().IsParallel (aSecondPlane.Axis().Direction(), Precision::Angular())) |
572 | { |
573 | return Standard_False; |
574 | } |
575 | |
a6eb515f |
576 | TopExp_Explorer anExplorer (theFirstShape, TopAbs_VERTEX); |
60bf98ae |
577 | |
a6eb515f |
578 | // In case of infinite planes |
579 | if (!anExplorer.More()) |
60bf98ae |
580 | { |
a6eb515f |
581 | myFirstPoint = aFirstPlane.Location(); |
60bf98ae |
582 | } |
583 | else |
584 | { |
585 | myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current())); |
586 | } |
587 | |
a6eb515f |
588 | mySecondPoint = AIS::ProjectPointOnPlane (myFirstPoint, aSecondPlane); |
589 | |
ee2be2a8 |
590 | Standard_Real anU, aV; |
a6eb515f |
591 | ElSLib::Parameters (aSecondPlane, mySecondPoint, anU, aV); |
60bf98ae |
592 | |
a6eb515f |
593 | BRepTopAdaptor_FClass2d aClassifier (aSecondFace, Precision::Confusion()); |
594 | TopAbs_State aState = aClassifier.Perform (gp_Pnt2d (anU, aV), Standard_False); |
60bf98ae |
595 | |
a6eb515f |
596 | if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN) |
597 | { |
60bf98ae |
598 | mySecondPoint = AIS::Nearest (aSecondFace, myFirstPoint); |
599 | } |
600 | |
601 | isSuccess = IsValidPoints (myFirstPoint, mySecondPoint); |
602 | if (isSuccess) |
603 | { |
604 | theComputedPlane = ComputePlane (aFirstPlane.Position().XDirection()); |
605 | theIsPlaneComputed = Standard_True; |
a6eb515f |
606 | } |
7fd59977 |
607 | } |
a6eb515f |
608 | else // curvilinear faces |
7fd59977 |
609 | { |
60bf98ae |
610 | Standard_Real aU1Min, aV1Min, aU1Max, aV1Max; |
611 | Standard_Real aU2Min, aV2Min, aU2Max, aV2Max; |
612 | BRepTools::UVBounds (aFirstFace, aU1Min, aU1Max, aV1Min, aV1Max); |
613 | BRepTools::UVBounds (aSecondFace, aU2Min, aU2Max, aV2Min, aV2Max); |
614 | |
615 | GeomAPI_ExtremaSurfaceSurface anExtrema (aFirstSurface, aSecondSurface, |
616 | aU1Min, aU1Max, aV1Min, aV1Max, |
617 | aU2Min, aU2Max, aV2Min, aV2Max); |
618 | |
619 | Standard_Real aU1, aV1, aU2, aV2; |
620 | anExtrema.LowerDistanceParameters (aU1, aV1, aU2, aV2); |
621 | myFirstPoint = BRep_Tool::Surface (aFirstFace)->Value (aU1, aV1); |
622 | mySecondPoint = BRep_Tool::Surface (aSecondFace)->Value (aU2, aV2); |
623 | |
624 | // Adjust automatic plane |
625 | gp_Ax2 aLocalAxes (myFirstPoint, gce_MakeDir (myFirstPoint, mySecondPoint)); |
626 | aDirAttach = gce_MakeDir (aLocalAxes.XDirection ()); |
627 | |
628 | // Check points |
629 | isSuccess = IsValidPoints (myFirstPoint, mySecondPoint); |
630 | if (isSuccess) |
631 | { |
632 | theComputedPlane = ComputePlane (aDirAttach); |
633 | theIsPlaneComputed = Standard_True; |
634 | } |
7fd59977 |
635 | } |
60bf98ae |
636 | |
637 | return isSuccess && IsValidPoints (myFirstPoint, mySecondPoint); |
a6eb515f |
638 | } |
1c078d3b |
639 | else if (theSecondShape.ShapeType() == TopAbs_EDGE) |
a6eb515f |
640 | { |
60bf98ae |
641 | myGeometryType = GeometryType_EdgeFace; |
1c078d3b |
642 | isSuccess = InitEdgeFaceLength (TopoDS::Edge (theSecondShape), |
643 | TopoDS::Face (theFirstShape), |
a6eb515f |
644 | aDirAttach); |
60bf98ae |
645 | |
646 | if (isSuccess) |
647 | { |
648 | theComputedPlane = ComputePlane (aDirAttach); |
649 | theIsPlaneComputed = Standard_True; |
650 | } |
651 | |
652 | return isSuccess; |
a6eb515f |
653 | } |
7fd59977 |
654 | } |
a6eb515f |
655 | break; |
60bf98ae |
656 | |
657 | case TopAbs_EDGE: |
7fd59977 |
658 | { |
a6eb515f |
659 | if (theSecondShape.ShapeType() == TopAbs_VERTEX) |
660 | { |
60bf98ae |
661 | myGeometryType = GeometryType_EdgeVertex; |
662 | isSuccess = InitEdgeVertexLength (TopoDS::Edge (theFirstShape), |
663 | TopoDS::Vertex (theSecondShape), |
664 | aDirAttach, |
665 | isInfinite); |
666 | |
667 | if (isSuccess) |
668 | { |
669 | theComputedPlane = ComputePlane (aDirAttach); |
670 | theIsPlaneComputed = Standard_True; |
671 | } |
672 | |
673 | return isSuccess; |
a6eb515f |
674 | } |
675 | else if (theSecondShape.ShapeType() == TopAbs_EDGE) |
676 | { |
60bf98ae |
677 | myGeometryType = GeometryType_Edges; |
678 | isSuccess = InitTwoEdgesLength (TopoDS::Edge (theFirstShape), |
679 | TopoDS::Edge (theSecondShape), |
680 | aDirAttach); |
681 | |
682 | if (isSuccess) |
683 | { |
684 | theComputedPlane = ComputePlane (aDirAttach); |
685 | theIsPlaneComputed = Standard_True; |
686 | } |
687 | |
1c078d3b |
688 | return isSuccess; |
689 | } |
690 | else if (theSecondShape.ShapeType() == TopAbs_FACE) |
691 | { |
692 | myGeometryType = GeometryType_EdgeFace; |
693 | isSuccess = InitEdgeFaceLength (TopoDS::Edge (theFirstShape), |
694 | TopoDS::Face (theSecondShape), |
695 | aDirAttach); |
696 | |
697 | if (isSuccess) |
698 | { |
699 | theComputedPlane = ComputePlane (aDirAttach); |
700 | theIsPlaneComputed = Standard_True; |
701 | } |
702 | |
60bf98ae |
703 | return isSuccess; |
a6eb515f |
704 | } |
7fd59977 |
705 | } |
a6eb515f |
706 | break; |
60bf98ae |
707 | |
708 | case TopAbs_VERTEX: |
7fd59977 |
709 | { |
a6eb515f |
710 | if (theSecondShape.ShapeType() == TopAbs_VERTEX) |
711 | { |
60bf98ae |
712 | myGeometryType = GeometryType_Points; |
713 | myFirstPoint = BRep_Tool::Pnt (TopoDS::Vertex (theFirstShape)); |
a6eb515f |
714 | mySecondPoint = BRep_Tool::Pnt (TopoDS::Vertex (theSecondShape)); |
60bf98ae |
715 | |
716 | return IsValidPoints (myFirstPoint, mySecondPoint); |
a6eb515f |
717 | } |
718 | else if (theSecondShape.ShapeType() == TopAbs_EDGE) |
719 | { |
60bf98ae |
720 | myGeometryType = GeometryType_EdgeVertex; |
51740958 |
721 | isSuccess = InitEdgeVertexLength (TopoDS::Edge(theSecondShape), |
722 | TopoDS::Vertex(theFirstShape), |
723 | aDirAttach, |
724 | isInfinite); |
60bf98ae |
725 | if (isSuccess) |
726 | { |
727 | theComputedPlane = ComputePlane (aDirAttach); |
728 | theIsPlaneComputed = Standard_True; |
729 | } |
730 | |
731 | return isSuccess; |
a6eb515f |
732 | } |
7fd59977 |
733 | } |
a6eb515f |
734 | break; |
60bf98ae |
735 | |
736 | case TopAbs_COMPOUND: |
737 | case TopAbs_COMPSOLID: |
738 | case TopAbs_SOLID: |
739 | case TopAbs_SHELL: |
740 | case TopAbs_WIRE: |
741 | case TopAbs_SHAPE: |
742 | break; |
a6eb515f |
743 | } |
60bf98ae |
744 | |
745 | return Standard_False; |
7fd59977 |
746 | } |
747 | |
748 | //======================================================================= |
60bf98ae |
749 | //function : InitOneShapePoints |
a6eb515f |
750 | //purpose : Initialization of two points where dimension layouts |
751 | // will be attached |
752 | // Attention: 1) <theShape> can be only the edge in currect implementation |
753 | // 2) No length for infinite edge |
7fd59977 |
754 | //======================================================================= |
60bf98ae |
755 | Standard_Boolean AIS_LengthDimension::InitOneShapePoints (const TopoDS_Shape& theShape) |
7fd59977 |
756 | { |
60bf98ae |
757 | if (theShape.ShapeType() != TopAbs_EDGE) |
a6eb515f |
758 | { |
a6eb515f |
759 | return Standard_False; |
60bf98ae |
760 | } |
7fd59977 |
761 | |
60bf98ae |
762 | TopoDS_Edge anEdge = TopoDS::Edge (theShape); |
7fd59977 |
763 | |
60bf98ae |
764 | BRepAdaptor_Curve aBrepCurve(anEdge); |
765 | Standard_Real aFirst = aBrepCurve.FirstParameter(); |
766 | Standard_Real aLast = aBrepCurve.LastParameter(); |
fe83e1ea |
767 | |
60bf98ae |
768 | if (aBrepCurve.GetType() != GeomAbs_Line) |
a6eb515f |
769 | { |
60bf98ae |
770 | return Standard_False; |
7fd59977 |
771 | } |
d7bffd44 |
772 | |
60bf98ae |
773 | Standard_Boolean isInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast)); |
774 | if (isInfinite) |
d7bffd44 |
775 | { |
60bf98ae |
776 | return Standard_False; |
d7bffd44 |
777 | } |
7fd59977 |
778 | |
60bf98ae |
779 | myFirstPoint = aBrepCurve.Value (aBrepCurve.FirstParameter()); |
780 | mySecondPoint = aBrepCurve.Value (aBrepCurve.LastParameter()); |
7fd59977 |
781 | |
60bf98ae |
782 | return IsValidPoints (myFirstPoint, mySecondPoint); |
7fd59977 |
783 | } |
af203d54 |
784 | |
785 | //======================================================================= |
786 | //function : GetTextPosition |
787 | //purpose : |
788 | //======================================================================= |
789 | const gp_Pnt AIS_LengthDimension::GetTextPosition() const |
790 | { |
791 | if (IsTextPositionCustom()) |
792 | { |
793 | return myFixedTextPosition; |
794 | } |
795 | |
796 | // Counts text position according to the dimension parameters |
797 | return GetTextPositionForLinear (myFirstPoint, mySecondPoint); |
798 | } |
799 | |
800 | //======================================================================= |
801 | //function : SetTextPosition |
802 | //purpose : |
803 | //======================================================================= |
804 | void AIS_LengthDimension::SetTextPosition (const gp_Pnt& theTextPos) |
805 | { |
91b16a64 |
806 | if (!IsValid()) |
af203d54 |
807 | { |
808 | return; |
809 | } |
810 | |
811 | myIsTextPositionFixed = Standard_True; |
812 | myFixedTextPosition = theTextPos; |
813 | |
814 | SetToUpdate(); |
815 | } |
948c552a |
816 | |
817 | //======================================================================= |
818 | //function : SetDirection |
819 | //purpose : |
820 | //======================================================================= |
821 | void AIS_LengthDimension::SetDirection (const gp_Dir& theDirection, const Standard_Boolean theUseDirection) |
822 | { |
823 | myHasCustomDirection = theUseDirection; |
824 | if (myHasCustomDirection) |
825 | myDirection = theDirection; |
826 | } |