0024153: Adding OpenCL to OCCT prerequisites
[occt.git] / src / AIS / AIS_LengthDimension.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Arnaud BOUZY/Odile Olivier
3// Copyright (c) 1996-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23// if any in all dimensions.
24
25#include <Standard_NotImplemented.hxx>
26
27#include <AIS_LengthDimension.ixx>
28
29#include <AIS.hxx>
30#include <AIS_DimensionOwner.hxx>
31#include <AIS_Drawer.hxx>
32
33#include <BRepAdaptor_Curve.hxx>
34#include <BRepAdaptor_Surface.hxx>
35#include <BRep_Tool.hxx>
36
37#include <DsgPrs.hxx>
38#include <DsgPrs_LengthPresentation.hxx>
39
40#include <ElCLib.hxx>
41#include <ElSLib.hxx>
42
43#include <Geom_Circle.hxx>
44#include <Geom_Curve.hxx>
45#include <Geom_TrimmedCurve.hxx>
46#include <Geom_Line.hxx>
47#include <Geom_Plane.hxx>
48#include <Geom_OffsetSurface.hxx>
49
50#include <Precision.hxx>
51
52#include <ProjLib.hxx>
53
54#include <Prs3d_ArrowAspect.hxx>
55#include <Prs3d_Drawer.hxx>
56#include <Prs3d_LengthAspect.hxx>
57#include <Prs3d_LineAspect.hxx>
58
59#include <Select3D_SensitiveBox.hxx>
60#include <Select3D_SensitiveSegment.hxx>
61#include <Select3D_SensitiveCurve.hxx>
62#include <SelectMgr_EntityOwner.hxx>
63
64#include <Standard_DomainError.hxx>
65
66#include <StdPrs_WFDeflectionShape.hxx>
67
68#include <TCollection_AsciiString.hxx>
69#include <TCollection_ExtendedString.hxx>
70
71#include <TopExp.hxx>
72#include <TopExp_Explorer.hxx>
73#include <TopoDS.hxx>
74
75#include <gce_MakeDir.hxx>
76#include <gce_MakeLin.hxx>
77
78#include <gp_Ax1.hxx>
79#include <gp_Ax2.hxx>
80#include <gp_Dir.hxx>
81#include <gp_Lin.hxx>
82#include <gp_Pln.hxx>
83#include <gp_Pnt.hxx>
84#include <gp_Pnt2d.hxx>
85
86#include <Prs3d_AngleAspect.hxx>
87
88#include <BRepGProp_Face.hxx>
89
90
91//=======================================================================
92//function : Constructor
93//purpose : TwoFacesLength dimension
94//=======================================================================
95
96AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& aFirstFace,
97 const TopoDS_Face& aSecondFace,
98 const Standard_Real aVal,
99 const TCollection_ExtendedString& aText)
100:AIS_Relation(),
101 myNbShape(2)
102{
103 SetFirstShape( aFirstFace );
104 SetSecondShape( aSecondFace );
105 myVal = aVal;
106
107 myText = aText;
108 mySymbolPrs = DsgPrs_AS_BOTHAR;
109 myAutomaticPosition = Standard_True;
110
111 myArrowSize = myVal / 10.;
112}
113
114//=======================================================================
115//function : Constructor
81bba717 116//purpose : TwoFacesLength dimension (with position and text)
7fd59977 117//=======================================================================
118
119AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Face& aFirstFace,
120 const TopoDS_Face& aSecondFace,
121 const Standard_Real aVal,
122 const TCollection_ExtendedString& aText,
123 const gp_Pnt& aPosition,
124 const DsgPrs_ArrowSide aSymbolPrs,
125 const Standard_Real anArrowSize)
126:AIS_Relation(),
127 myNbShape(2)
128{
129 SetFirstShape( aFirstFace );
130 SetSecondShape( aSecondFace );
131 myVal = aVal;
132
133 myText = aText;
134 mySymbolPrs = aSymbolPrs;
135 myAutomaticPosition = Standard_False;
136#ifdef BUC60915
137 SetArrowSize( anArrowSize );
138#else
139 myArrowSize = anArrowSize;
140#endif
141 myPosition = aPosition;
142}
143
144
145
146//=======================================================================
147//function : AIS_LengthDimension
81bba717 148//purpose : Distance Face - Edge for chamfer 3D
7fd59977 149//=======================================================================
150
151AIS_LengthDimension::AIS_LengthDimension (const TopoDS_Face& Face,const TopoDS_Edge& Edge,const Standard_Real Val,const TCollection_ExtendedString& Text)
152
153:AIS_Relation (),
154 myNbShape (2)
155{
156 SetFirstShape (Face);
157 SetSecondShape (Edge);
158 myText = Text;
159 myVal = Val;
160 mySymbolPrs = DsgPrs_AS_BOTHAR;
161 myAutomaticPosition = Standard_True;
162 myArrowSize = myVal/10.0;
163}
164
165
166
167//=======================================================================
168//function : Constructor
169//purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
170//=======================================================================
171
172AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape,
173 const TopoDS_Shape& aSShape,
174 const Handle(Geom_Plane)& aPlane,
175 const Standard_Real aVal,
176 const TCollection_ExtendedString& aText)
177:AIS_Relation(),
178 myNbShape(2),
179 myTypeDist(AIS_TOD_Unknown)
180{
181 myFShape = aFShape;
182 mySShape = aSShape;
183 myVal = aVal;
184 myText = aText;
185 mySymbolPrs = DsgPrs_AS_BOTHAR;
186 myAutomaticPosition = Standard_True;
187 myPlane =aPlane;
188 myArrowSize = myVal / 10.;
189}
190
191//=======================================================================
192//function : Constructor
193//purpose : TwoEdgesLength dimension or OneEdgeOneVertexLength dimension or TwoVerticesLength dimension
194//=======================================================================
195
196AIS_LengthDimension::AIS_LengthDimension(const TopoDS_Shape& aFShape,
197 const TopoDS_Shape& aSShape,
198 const Handle(Geom_Plane)& aPlane,
199 const Standard_Real aVal,
200 const TCollection_ExtendedString& aText,
201 const gp_Pnt& aPosition,
202 const DsgPrs_ArrowSide aSymbolPrs,
203 const AIS_TypeOfDist aTypeDist,
204 const Standard_Real anArrowSize)
205:AIS_Relation(),
206 myNbShape(2),
207 myTypeDist(aTypeDist)
208{
209 myFShape = aFShape;
210 mySShape = aSShape;
211 myVal = aVal;
212 myPlane = aPlane;
213 myText = aText;
214 mySymbolPrs = aSymbolPrs;
215 myAutomaticPosition = Standard_False;
216#ifdef BUC60915
217 SetArrowSize( anArrowSize );
218#else
219 myArrowSize = anArrowSize;
220#endif
221 myPosition = aPosition;
222}
223
224
225
226//=======================================================================
227//function : Compute
228//purpose :
229//=======================================================================
230
231void AIS_LengthDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
232 const Handle(Prs3d_Presentation)& aPresentation,
233 const Standard_Integer)
234{
235 aPresentation->Clear();
236
237 if (myNbShape == 1) {
238 switch (myFShape.ShapeType()) {
239 case TopAbs_FACE:
240 {
81bba717 241 // case length on a face
7fd59977 242 ComputeOneFaceLength(aPresentation);
243 }
244 break;
245 case TopAbs_EDGE:
246 {
81bba717 247 // case length of an edge
7fd59977 248 ComputeOneEdgeLength(aPresentation);
249 }
250 break;
251 default:
252 break;
253 }
254 }
255 else if (myNbShape == 2) {
256 switch (myFShape.ShapeType()) {
257 case TopAbs_FACE:
258 {
259 if (mySShape.ShapeType () == TopAbs_FACE) {
81bba717 260 // case length between two faces
7fd59977 261 ComputeTwoFacesLength(aPresentation);
262 }
263 else if (mySShape.ShapeType () == TopAbs_EDGE) {
264 ComputeEdgeFaceLength (aPresentation);
265 }
266 }
267 break;
268 case TopAbs_EDGE:
269 {
270 if (mySShape.ShapeType() == TopAbs_VERTEX) {
271#ifdef BUC60915
272 if( !myArrowSizeIsDefined )
273#endif
274 myArrowSize = Abs(myVal)/100.;
275 ComputeOneEdgeOneVertexLength( aPresentation,
276 myDrawer,
277 myText,
278 myArrowSize,
279 myFShape,
280 mySShape,
281 myPlane,
282 myAutomaticPosition,
283 myIsSetBndBox,
284 myBndBox,
285 myExtShape,
286 myVal,
287 myDirAttach,
288 myPosition,
289 myFAttach,
290 mySAttach,
291 mySymbolPrs );
292 }
293 else if (mySShape.ShapeType() == TopAbs_EDGE) {
81bba717 294 // case length between two edges
7fd59977 295#ifdef BUC60915
296 if( !myArrowSizeIsDefined )
297#endif
298 myArrowSize = Abs(myVal)/100.;
299 ComputeTwoEdgesLength( aPresentation,
300 myDrawer,
301 myText,
302 myArrowSize,
303 TopoDS::Edge( myFShape ),
304 TopoDS::Edge( mySShape ),
305 myPlane,
306 myAutomaticPosition,
307 myIsSetBndBox,
308 myBndBox,
309 myExtShape,
310 myVal,
311 myDirAttach,
312 myPosition,
313 myFAttach,
314 mySAttach,
315 mySymbolPrs );
316 }
317 }
318 break;
319
320 case TopAbs_VERTEX:
321 {
322 if (mySShape.ShapeType() == TopAbs_VERTEX) {
323#ifdef BUC60915
324 if( !myArrowSizeIsDefined )
325#endif
326 myArrowSize = Abs(myVal)/100.;
327 ComputeTwoVerticesLength( aPresentation,
328 myDrawer,
329 myText,
330 myArrowSize,
331 TopoDS::Vertex( myFShape ),
332 TopoDS::Vertex( mySShape ),
333 myPlane,
334 myAutomaticPosition,
335 myIsSetBndBox,
336 myBndBox,
337 myTypeDist,
338 myExtShape,
339 myVal,
340 myDirAttach,
341 myPosition,
342 myFAttach,
343 mySAttach,
344 mySymbolPrs );
345 }
346 else if (mySShape.ShapeType() == TopAbs_EDGE) {
347#ifdef BUC60915
348 if( !myArrowSizeIsDefined )
349#endif
350 myArrowSize = Abs(myVal)/100.;
351 ComputeOneEdgeOneVertexLength( aPresentation,
352 myDrawer,
353 myText,
354 myArrowSize,
355 myFShape,
356 mySShape,
357 myPlane,
358 myAutomaticPosition,
359 myIsSetBndBox,
360 myBndBox,
361 myExtShape,
362 myVal,
363 myDirAttach,
364 myPosition,
365 myFAttach,
366 mySAttach,
367 mySymbolPrs );
368 }
369 }
370 break;
371 default:
372 break;
373 }
374 }
375
376}
377
378//=======================================================================
379//function : Compute
380//purpose : to avoid warning
381//=======================================================================
382
383void AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
384 const Handle(Prs3d_Presentation)& aPresentation)
385{
386// Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
387 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
388}
389
7fd59977 390void AIS_LengthDimension::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
391{
392// Standard_NotImplemented::Raise("AIS_LengthDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
393 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
394}
395
396//=======================================================================
397//function : ComputeSelection
398//purpose :
399//=======================================================================
400
401void AIS_LengthDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
402 const Standard_Integer)
403{
404 if (myFShape.IsNull() && mySShape.IsNull()) return;
405 if (myFShape.ShapeType() == TopAbs_FACE) ComputeFaceSelection(aSelection);
406 else ComputeEdgeVertexSelection(aSelection);
407
408 // Text
409 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
410 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
411 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
412 myPosition.X(),
413 myPosition.Y(),
414 myPosition.Z(),
415 myPosition.X() + size,
416 myPosition.Y() + size,
417 myPosition.Z() + size);
418 aSelection->Add(box);
419}
420
421
422//=======================================================================
423//function : ComputeOneFaceLength
424//purpose :
425//=======================================================================
426
427void AIS_LengthDimension::ComputeOneFaceLength(const Handle(Prs3d_Presentation)&)
428{
429 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneFaceLength : Not implemented");
430}
431
432//=======================================================================
433//function : ComputeOneOneEdgeLength
434//purpose :
435//=======================================================================
436
437void AIS_LengthDimension::ComputeOneEdgeLength(const Handle(Prs3d_Presentation)&)
438{
439 Standard_DomainError::Raise("AIS_LengthDimension::ComputeOneEdgeLength : Not implemented");
440}
441
442//=======================================================================
443//function : ComputeTwoFacesLength
444//purpose :
445//=======================================================================
446
447void AIS_LengthDimension::ComputeTwoFacesLength( const Handle( Prs3d_Presentation )& aPresentation )
448{
449 if (myFShape.ShapeType() == TopAbs_COMPOUND) { //rob debug from vbu?
450 TopExp_Explorer E (myFShape,TopAbs_FACE);
451 if (E.More()) SetFirstShape(E.Current());
452 }
453 if (mySShape.ShapeType() == TopAbs_COMPOUND) {
454 TopExp_Explorer E (mySShape,TopAbs_FACE);
455 if (E.More()) SetSecondShape(E.Current()); // rob debug from vbu?
456 }
457
458 if (myFirstSurfType == AIS_KOS_Plane)
459 {
460 AIS::ComputeLengthBetweenPlanarFaces( TopoDS::Face(myFShape),
461 TopoDS::Face(mySShape),
462 myFirstPlane,
463 mySecondPlane,
464 myVal,
465 myFAttach,
466 mySAttach,
467 myDirAttach,
468 myAutomaticPosition,
469 myPosition );
470 if (myAutomaticPosition && myIsSetBndBox)
471 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
472
473 myDrawer->LengthAspect()->Arrow1Aspect()->SetLength( myArrowSize );
474 myDrawer->LengthAspect()->Arrow2Aspect()->SetLength( myArrowSize );
475
81bba717 476 // Find text of the face
7fd59977 477
478 DsgPrs_LengthPresentation::Add( aPresentation,
479 myDrawer,
480 myText,
481 myFAttach,
482 mySAttach,
483 myFirstPlane,
484 myDirAttach,
485 myPosition,
486 mySymbolPrs );
487 }
488 else
489 {
490 AIS::ComputeLengthBetweenCurvilinearFaces( TopoDS::Face(myFShape),
491 TopoDS::Face(mySShape),
492 myFirstBasisSurf,
493 mySecondBasisSurf,
494 myAutomaticPosition,
495 myVal,
496 myPosition,
497 myFAttach,
498 mySAttach,
499 myDirAttach );
500 if (myAutomaticPosition && myIsSetBndBox)
501 myPosition = AIS::TranslatePointToBound( myPosition, myDirAttach, myBndBox );
502
503 DsgPrs_LengthPresentation::Add( aPresentation,
504 myDrawer,
505 myText,
506 mySecondBasisSurf,
507 myFAttach,
508 mySAttach,
509 myDirAttach,
510 myPosition,
511 mySymbolPrs );
512 }
513}
514
515
516//=======================================================================
517//function : ComputeEdgeFaceLength
518//purpose : Jean-Claude Vauthier 17/06/98
519// A quick implementation in order to edit the constraint of
520// distance for a chamfer 3D.
521//=======================================================================
522
523void AIS_LengthDimension::ComputeEdgeFaceLength (const Handle(Prs3d_Presentation )& aPresentation )
524{
525
526 //The first attachment point is P1 from the reference Edge
527 //Find the second attachment point which belongs to the reference face
528 //Iterate over the edges of the face and find the point FP1...
529 //....it is the closest point according to P1
530
531 const TopoDS_Edge& E = TopoDS::Edge (mySShape); //The reference edge
532 const TopoDS_Face& F = TopoDS::Face (myFShape); //The reference face
533 TopoDS_Vertex V1, V2;
534 TopExp::Vertices (E, V1, V2);
535 myFAttach = BRep_Tool::Pnt (V1);
536 gp_Pnt P = BRep_Tool::Pnt (V2);
537
538 TopExp_Explorer It (F, TopAbs_EDGE);
539 gp_Pnt2d FP1uv, FP2uv;
540 Standard_Real Dist1 = RealLast ();
541 Standard_Real Dist2 = RealLast ();
542 for (; It.More (); It.Next ()) {
543 const TopoDS_Edge FE = TopoDS::Edge(It.Current ());
544 TopExp::Vertices (FE, V1, V2);
545 gp_Pnt FP1c = BRep_Tool::Pnt (V1);
546 gp_Pnt FP2c = BRep_Tool::Pnt (V2);
547 Standard_Real Dc1 = myFAttach.SquareDistance (FP1c);
548 Standard_Real Dc2 = myFAttach.SquareDistance (FP2c);
549 if (Dc1 <= Dc2) {
550 if (Dc1 <= Dist1) {
551 Dc2 = P.SquareDistance (FP2c);
552 if (Dc2 <= Dist2) {
553 mySAttach = FP1c;
554 Dist1 = Dc1;
555 Dist2 = Dc2;
556 BRep_Tool::UVPoints (FE, F, FP1uv, FP2uv);
557 }
558 }
559 }
560 else {
561 if (Dc2 <= Dist1) {
562 Dc1 = P.SquareDistance (FP1c);
563 if (Dc1 <= Dist2) {
564 mySAttach = FP2c;
565 Dist1 = Dc2;
566 Dist2 = Dc1;
567 BRep_Tool::UVPoints (FE, F, FP2uv, FP1uv);
568 }
569 }
570 }
571 }
572
573 gp_Vec OffsetDirection (0.0, 0.0, 0.0);
574
575 //The offset direction is the normal to the face at the point FP1
576 BRepGProp_Face GF;
577 GF.Load (F);
578 GF.Normal (FP1uv.X(), FP1uv.Y(), P, OffsetDirection);
579
580 if (OffsetDirection.Magnitude () > Precision::Confusion ()) {
581 myDirAttach = gp_Dir (OffsetDirection);
582 }
583 else myDirAttach = gp::DZ ();
584
585
586 gp_Vec Vt (myDirAttach);
587 Vt.Multiply (1.5 * myVal);
588 myPosition = mySAttach.Translated (Vt);
589
590 DsgPrs_LengthPresentation::Add(aPresentation,
591 myDrawer,
592 myText,
593 myFAttach,
594 mySAttach,
595 myDirAttach,
596 myPosition,
597 mySymbolPrs);
598
599}
600
601
602//=======================================================================
603//function : ComputeTwoEdgesLength
604//purpose :
605//=======================================================================
606
607void AIS_LengthDimension::ComputeTwoEdgesLength( const Handle( Prs3d_Presentation )& aPresentation,
608 const Handle( AIS_Drawer )& aDrawer,
609 const TCollection_ExtendedString & aText,
610 const Standard_Real ArrowSize,
611 const TopoDS_Edge & FirstEdge,
612 const TopoDS_Edge & SecondEdge,
613 const Handle( Geom_Plane )& Plane,
614 const Standard_Boolean AutomaticPos,
615 const Standard_Boolean IsSetBndBox,
616 const Bnd_Box & BndBox,
617 Standard_Integer & ExtShape,
618 Standard_Real & Val,
619 gp_Dir & DirAttach,
620 gp_Pnt & Position,
621 gp_Pnt & FirstAttach,
622 gp_Pnt & SecondAttach,
623 DsgPrs_ArrowSide & SymbolPrs )
624{
625 BRepAdaptor_Curve cu1( FirstEdge );
626 if (cu1.GetType() != GeomAbs_Line) return;
627 BRepAdaptor_Curve cu2( SecondEdge );
628 if (cu2.GetType() != GeomAbs_Line) return;
629
630 // 3d lines
631 Handle(Geom_Curve) geom1,geom2;
632 gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
633
634 Standard_Boolean isInfinite1(Standard_False),isInfinite2(Standard_False);
635 Standard_Integer ext(ExtShape);
636 Handle(Geom_Curve) extCurv;
637 if (!AIS::ComputeGeometry(FirstEdge,
638 SecondEdge,
639 ExtShape,
640 geom1,
641 geom2,
642 ptat11,
643 ptat12,
644 ptat21,
645 ptat22,
646 extCurv,
647 isInfinite1,
648 isInfinite2,
649 Plane))
650 {
651 return;
652 }
653 ExtShape = ext;
654 aPresentation->SetInfiniteState(isInfinite1 || isInfinite2);
655 const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1;
656 const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2;
657 const gp_Lin& l1 = geom_lin1->Lin();
658 const gp_Lin& l2 = geom_lin2->Lin();
659
660 // New: computation of myVal
661 Val = l1.Distance( l2 );
662
663 DirAttach = l1.Direction();
664
665 // size
666 Standard_Real arrsize = ArrowSize;
667
668 if (AutomaticPos) {
669 gp_Pnt curpos;
670 if ( !isInfinite1 ) {
671 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
672 curpos.SetXYZ((ptat11.XYZ()+p2.XYZ())/2.);
673 }
674 else if (!isInfinite2) {
675 gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
676 curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
677 }
678 else {
679 curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
680 }
81bba717 681 // offset to avoid confusion Edge and Dimension
7fd59977 682 gp_Vec offset(DirAttach);
683 offset = offset*ArrowSize*(-10.);
684 curpos.Translate(offset);
685 Position = curpos;
686 }
81bba717 687 else { // the point is projected in the plane
7fd59977 688 // it is patch!
689 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
690 }
691
81bba717 692 // find attachment points
7fd59977 693 if (!isInfinite1) {
694 if (Position.Distance(ptat11) > Position.Distance(ptat12)) FirstAttach = ptat12;
695 else FirstAttach = ptat11;
696 }
697 else {
698 FirstAttach = ElCLib::Value(ElCLib::Parameter(l1,Position),l1);
699 }
700
701 if (!isInfinite2) {
702 if (Position.Distance(ptat21) > Position.Distance(ptat22)) SecondAttach = ptat22;
703 else SecondAttach = ptat21;
704 }
705 else {
706 SecondAttach = ElCLib::Value(ElCLib::Parameter(l2,Position),l2);
707 }
708
709 Standard_Real confusion(Precision::Confusion());
710 if (arrsize < confusion) arrsize = Val/10.;
711 if (Abs(Val) <= confusion) {arrsize = 0.;}
712
713 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
714 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
715 arr->SetLength(arrsize);
716 arr = la->Arrow2Aspect();
717 arr->SetLength(arrsize);
718
719 if ( ExtShape == 1)
720 SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
721 else if ( ExtShape == 2)
722 SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
723
724 if (AutomaticPos && IsSetBndBox)
725 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
726
727 DsgPrs_LengthPresentation::Add(aPresentation,
728 aDrawer,
729 aText,
730 FirstAttach,
731 SecondAttach,
732 DirAttach,
733 Position,
734 SymbolPrs);
735
736 if ( (ExtShape != 0) && !extCurv.IsNull()) {
737 gp_Pnt pf, pl;
738 if ( ExtShape == 1 ) {
739 if (!isInfinite1) {
740 pf = ptat11;
741 pl = ptat12;
742 }
743 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, FirstEdge, geom_lin1, pf, pl );
744 }
745 else {
746 if (!isInfinite2) {
747 pf = ptat21;
748 pl = ptat22;
749 }
750 AIS::ComputeProjEdgePresentation( aPresentation, aDrawer, SecondEdge, geom_lin2, pf, pl );
751 }
752 }
753}
754
755//=======================================================================
756//function : ComputeOneEdgeOneVertexLength
757//purpose :
758//=======================================================================
759
760void AIS_LengthDimension::ComputeOneEdgeOneVertexLength( const Handle( Prs3d_Presentation )& aPresentation,
761 const Handle( AIS_Drawer )& aDrawer,
762 const TCollection_ExtendedString & aText,
763 const Standard_Real ArrowSize,
764 const TopoDS_Shape & FirstShape,
765 const TopoDS_Shape & SecondShape,
766 const Handle( Geom_Plane )& Plane,
767 const Standard_Boolean AutomaticPos,
768 const Standard_Boolean IsSetBndBox,
769 const Bnd_Box & BndBox,
770 Standard_Integer & ExtShape,
771 Standard_Real & Val,
772 gp_Dir & DirAttach,
773 gp_Pnt & Position,
774 gp_Pnt & FirstAttach,
775 gp_Pnt & SecondAttach,
776 DsgPrs_ArrowSide & SymbolPrs )
777{
778 TopoDS_Vertex thevertex;
779 TopoDS_Edge theedge;
780 Standard_Integer numedge;
781
782 if (FirstShape.ShapeType() == TopAbs_VERTEX) {
783 thevertex = TopoDS::Vertex(FirstShape);
784 theedge = TopoDS::Edge(SecondShape);
81bba717 785 numedge = 2;// edge = 2nd shape
7fd59977 786 }
787 else {
788 thevertex = TopoDS::Vertex(SecondShape);
789 theedge = TopoDS::Edge(FirstShape);
81bba717 790 numedge = 1; // edge = 1st shape
7fd59977 791 }
792
793 gp_Pnt ptonedge1,ptonedge2;
794 Handle(Geom_Curve) aCurve;
795 Handle(Geom_Curve) extCurv;
796 Standard_Boolean isInfinite;
797 Standard_Boolean isOnPlanEdge, isOnPlanVertex;
798 if (!AIS::ComputeGeometry(theedge,aCurve,ptonedge1,ptonedge2,extCurv,isInfinite,isOnPlanEdge,Plane))
799 return;
800 aPresentation->SetInfiniteState(isInfinite);
801 AIS::ComputeGeometry(thevertex, FirstAttach, Plane, isOnPlanVertex);
802
81bba717 803 // take into consideration that only the curve can be projected
7fd59977 804 if (!isOnPlanEdge && !isOnPlanVertex)
805 return;
806
807 if (!isOnPlanEdge) {
808 if (numedge == 1) ExtShape = 1;
809 else ExtShape = 2;
810 }
811 else if (!isOnPlanVertex) {
812 if (numedge == 1) ExtShape = 2;
813 else ExtShape = 1;
814 }
815
816
817 const Handle(Geom_Line)& geom_lin = (Handle(Geom_Line)&) aCurve;
818 const gp_Lin& l = geom_lin->Lin();
819
820 // New: computation of Val
821 Val = l.Distance( FirstAttach );
822
823 DirAttach = l.Direction();
824 // size
825 Standard_Real arrsize = ArrowSize;
826 if (Abs(Val) <= Precision::Confusion()) {arrsize = 0.;}
827
828 if (AutomaticPos) {
829 gp_Pnt p = ElCLib::Value(ElCLib::Parameter(l,FirstAttach),l);
830 gp_Pnt curpos((FirstAttach.XYZ()+p.XYZ())/2.);
81bba717 831 // offset to avoid confusion Edge and Dimension
7fd59977 832 gp_Vec offset(DirAttach);
833 offset = offset*ArrowSize*(-10.);
834 curpos.Translate(offset);
835 Position = curpos;
836 }
81bba717 837 else { // the point is projected in the plane
7fd59977 838 // it is patch!
839 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
840
841 /*
842 Standard_Real u,v;
843 ElSLib::Parameters(Plane->Pln() , Position, u, v);
844 Position = ElSLib::Value(u,v,Plane->Pln());
845 */
846 }
847
848 if (!isInfinite) {
849 if (Position.Distance(ptonedge1) > Position.Distance(ptonedge2)) SecondAttach = ptonedge2;
850 else SecondAttach = ptonedge1;
851 }
852 else {
853 SecondAttach = ElCLib::Value(ElCLib::Parameter(l,Position),l);
854 }
855
856 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
857 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
858 arr->SetLength(arrsize);
859 arr = la->Arrow2Aspect();
860 arr->SetLength(arrsize);
861
862 if (AutomaticPos && IsSetBndBox)
863 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
864
865 DsgPrs_LengthPresentation::Add(aPresentation,
866 aDrawer,
867 aText,
868 FirstAttach,
869 SecondAttach,
870 DirAttach,
871 Position,
872 SymbolPrs);
873
0d969553 874 //Display the pieces connecting to the curve if it is not in the WP
7fd59977 875 if (ExtShape != 0) {
876
0d969553 877 if (!extCurv.IsNull()) { // this is the edge that is not in the WP
7fd59977 878 AIS::ComputeProjEdgePresentation(aPresentation,aDrawer,theedge,geom_lin,ptonedge1,ptonedge2);
879 }
0d969553 880 else { // this is the point that is not in the WP
7fd59977 881 AIS::ComputeProjVertexPresentation(aPresentation,aDrawer,thevertex,FirstAttach);
882 }
883 }
884}
885
886//=======================================================================
887//function : ComputeTwoVerticesLength
888//purpose :
889//=======================================================================
890
891void AIS_LengthDimension::ComputeTwoVerticesLength( const Handle( Prs3d_Presentation )& aPresentation,
892 const Handle( AIS_Drawer )& aDrawer,
893 const TCollection_ExtendedString& aText,
894 const Standard_Real ArrowSize,
895 const TopoDS_Vertex& FirstVertex,
896 const TopoDS_Vertex& SecondVertex,
897 const Handle( Geom_Plane )& Plane,
898 const Standard_Boolean AutomaticPos,
899 const Standard_Boolean IsSetBndBox,
900 const Bnd_Box& BndBox,
901 const AIS_TypeOfDist TypeDist,
902 Standard_Integer& ExtShape,
903 Standard_Real& Val,
904 gp_Dir& DirAttach,
905 gp_Pnt& Position,
906 gp_Pnt& FirstAttach,
907 gp_Pnt& SecondAttach,
908 DsgPrs_ArrowSide& SymbolPrs )
909{
910 Standard_Boolean isOnPlane1, isOnPlane2;
911
912 AIS::ComputeGeometry( FirstVertex, FirstAttach, Plane, isOnPlane1);
913 AIS::ComputeGeometry( SecondVertex, SecondAttach, Plane, isOnPlane2);
914
915 // New: computation of Val
916 Val = FirstAttach.Distance( SecondAttach );
917
918 if (ExtShape == 0) {
919 if (isOnPlane1 && isOnPlane2)
920 ExtShape = 0;
921 else if ( isOnPlane1 && !isOnPlane2)
922 ExtShape = 2;
923 else if (!isOnPlane1 && isOnPlane2)
924 ExtShape = 1;
925 else
926 return ;
927 }
928 Standard_Real confusion(Precision::Confusion());
929 Standard_Boolean samePoint(FirstAttach.IsEqual(SecondAttach,confusion));
930
931 if (TypeDist == AIS_TOD_Vertical) DirAttach = Plane->Pln().XAxis().Direction();
932 else if (TypeDist == AIS_TOD_Horizontal) DirAttach = Plane->Pln().YAxis().Direction();
933 else {
934 if (!samePoint) {
935 DirAttach = gce_MakeDir(FirstAttach,SecondAttach);
c6541a0c 936 DirAttach.Rotate(Plane->Pln().Axis(),M_PI/2.);
7fd59977 937 }
938 }
939
940 // size
941 //Standard_Real arrsize = ArrowSize;
942 //if (Abs(Val) <= confusion) arrsize =0.;
943
944 if (AutomaticPos) {
945 if (!samePoint) {
946 gp_Pnt curpos((FirstAttach.XYZ()+SecondAttach.XYZ())/2.);
81bba717 947 // offset to avoid confusion Edge and Dimension
7fd59977 948 gp_Vec offset(DirAttach);
949 offset = offset*ArrowSize*(-10.);
950 curpos.Translate(offset);
951 Position = curpos;
952 }
953 else {
954 Position = gp_Pnt(FirstAttach.XYZ()+gp_XYZ(1.,1.,1.));
955 // it is patch!
956 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
957 DirAttach = gce_MakeDir(FirstAttach,Position);
958 }
959 }
960 else {
961 // it is patch!
962 Position = AIS::ProjectPointOnPlane( Position, Plane->Pln() );
963 }
964
965
966 Handle(Prs3d_LengthAspect) la = aDrawer->LengthAspect();
967 Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect();
968 arr->SetLength(ArrowSize);
969 arr = la->Arrow2Aspect();
970 arr->SetLength(ArrowSize);
971
81bba717 972 // Type of arrows
7fd59977 973 if ( ExtShape == 1) SymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
974 else if (ExtShape == 2) SymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
975
976 if (AutomaticPos && IsSetBndBox)
977 Position = AIS::TranslatePointToBound( Position, DirAttach, BndBox );
978
979 DsgPrs_LengthPresentation::Add(aPresentation,
980 aDrawer,
981 aText,
982 FirstAttach,
983 SecondAttach,
984 DirAttach,
985 Position,
986 SymbolPrs);
987
81bba717 988 // Calculate the projection of the vertex
7fd59977 989 if ( ExtShape == 1)
990 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, FirstVertex, FirstAttach);
991 else if ( ExtShape == 2)
992 AIS::ComputeProjVertexPresentation(aPresentation, aDrawer, SecondVertex, SecondAttach);
993}
994
995//=======================================================================
996//function : ComputeTwoFaceSelection
997//purpose :
998//=======================================================================
999
1000void AIS_LengthDimension::ComputeFaceSelection( const Handle( SelectMgr_Selection )& aSelection )
1001{
1002 Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 );
1003 Handle( Select3D_SensitiveSegment ) seg;
1004 Handle( Geom_TrimmedCurve ) curve;
1005 Handle( Select3D_SensitiveCurve ) SensCurve;
1006
1007 Standard_Real ArrowLength = myDrawer->AngleAspect()->ArrowAspect()->Length();
1008
1009 gp_Pnt EndOfArrow1, EndOfArrow2;
1010 gp_Dir DirOfArrow1;
1011
1012 if (myFirstSurfType == AIS_KOS_Plane)
1013 {
1014 DsgPrs::ComputePlanarFacesLengthPresentation( ArrowLength,
1015 ArrowLength,
1016 myFAttach,
1017 mySAttach,
1018 myDirAttach,
1019 myPosition,
1020 myFirstPlane,
1021 EndOfArrow1,
1022 EndOfArrow2,
1023 DirOfArrow1 );
1024 //Add attach lines
1025 seg = new Select3D_SensitiveSegment( own, myFAttach, EndOfArrow1 );
1026 aSelection->Add( seg );
1027
1028 seg = new Select3D_SensitiveSegment( own, mySAttach, EndOfArrow2 );
1029 aSelection->Add( seg );
1030 }
1031 else // curvilinear case
1032 {
1033 if(mySecondBasisSurf.IsNull())
1034 return;
1035
1036 Handle( Geom_Curve ) VCurve, UCurve;
1037 Standard_Real FirstU, deltaU = 0.0e0, FirstV, deltaV = 0.0e0;
1038
1039 EndOfArrow1 = myFAttach;
1040 DsgPrs::ComputeCurvilinearFacesLengthPresentation( ArrowLength,
1041 ArrowLength,
1042 mySecondBasisSurf,
1043 myFAttach,
1044 mySAttach,
1045 myDirAttach,
1046 EndOfArrow2,
1047 DirOfArrow1,
1048 VCurve,
1049 UCurve,
1050 FirstU, deltaU,
1051 FirstV, deltaV );
1052 // Add attach curves
1053 if (Abs( deltaU ) > Precision::PConfusion())
1054 {
1055 if (deltaU > 0.0)
1056 curve = new Geom_TrimmedCurve( VCurve, FirstU, FirstU + deltaU );
1057 else
1058 curve = new Geom_TrimmedCurve( VCurve, FirstU + deltaU, FirstU );
1059 SensCurve = new Select3D_SensitiveCurve( own, curve );
1060 aSelection->Add( SensCurve );
1061 }
1062 if (Abs( deltaV ) > Precision::PConfusion())
1063 {
1064 if (deltaV > 0.0)
1065 curve = new Geom_TrimmedCurve( UCurve, FirstV, FirstV + deltaV );
1066 else
1067 curve = new Geom_TrimmedCurve( UCurve, FirstV + deltaV, FirstV );
1068 SensCurve = new Select3D_SensitiveCurve( own, curve );
1069 aSelection->Add( SensCurve );
1070 }
1071 }
1072
1073 // Add the length's line
1074 gp_Pnt FirstPoint, LastPoint; // ends of length's line
1075 gp_Vec ArrowVec( DirOfArrow1 );
1076 ArrowVec *= ArrowLength;
1077 if (myVal <= Precision::Confusion())
1078 {
1079 if (myPosition.SquareDistance( EndOfArrow1 ) > ArrowLength*ArrowLength)
1080 {
1081 FirstPoint = myPosition;
1082 LastPoint = EndOfArrow1.Translated( ArrowVec );
1083 if (myPosition.SquareDistance( LastPoint ) < myPosition.SquareDistance( EndOfArrow1 ))
1084 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1085 }
1086 else
1087 {
1088 FirstPoint = EndOfArrow1.Translated( ArrowVec );
1089 LastPoint = EndOfArrow1.Translated( -ArrowVec );
1090 }
1091 }
1092 else
1093 {
1094 gp_Lin LengthLine( myPosition, DirOfArrow1 );
1095 Standard_Real Par1 = ElCLib::Parameter( LengthLine, EndOfArrow1 );
1096 Standard_Real Par2 = ElCLib::Parameter( LengthLine, EndOfArrow2 );
0ebaa4db 1097 if ((Par1 > 0.0 && Par2 > 0.0) || (Par1 < 0.0 && Par2 < 0.0))
7fd59977 1098 {
1099 FirstPoint = myPosition;
1100 LastPoint = (Abs( Par1 ) > Abs( Par2 ))? EndOfArrow1 : EndOfArrow2;
1101 LastPoint.Translate( ((Abs( Par1 ) > Abs( Par2 ))? -ArrowVec : ArrowVec) );
1102 }
1103 else
1104 {
1105 FirstPoint = EndOfArrow1;
1106 LastPoint = EndOfArrow2;
1107 }
1108 }
1109 seg = new Select3D_SensitiveSegment( own, FirstPoint, LastPoint );
1110 aSelection->Add( seg );
1111}
1112
1113//=======================================================================
1114//function : ComputeEdgeVertexSelection
1115//purpose :
1116//=======================================================================
1117
1118void AIS_LengthDimension::ComputeEdgeVertexSelection(const Handle(SelectMgr_Selection)& aSelection)
1119{
1120 // ********** NB ->
81bba717 1121 // in the case of a constraint relatively to the border of a face
1122 // only the shape of this contour is valid
7fd59977 1123
81bba717 1124 // Create 2 owner for edition of constraints
7fd59977 1125 Handle(AIS_DimensionOwner) own1 = new AIS_DimensionOwner(this,7);
1126 Handle(AIS_DimensionOwner) own2 = new AIS_DimensionOwner(this,7);
1127
1128 if (myExtShape != 0) {
1129 if (myExtShape == 1) {
1130 own1->SetShape(mySShape);
1131 own2->SetShape(mySShape);
1132 }
1133 else {
1134 own1->SetShape(myFShape);
1135 own2->SetShape(myFShape);
1136 }
1137 }
1138 else {
1139 own1->SetShape(myFShape);
1140 own2->SetShape(mySShape);
1141 }
1142
1143
1144 gp_Lin L1 (myFAttach,myDirAttach);
1145 gp_Lin L2 (mySAttach,myDirAttach);
1146 gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
1147 gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
1148 gp_Lin L3;
1149
1150 Standard_Real confusion(Precision::Confusion());
1151
1152 if (!Proj1.IsEqual(Proj2,confusion)) L3 = gce_MakeLin(Proj1,Proj2);
1153 else {
81bba717 1154 // cas of zero dimension
1155 // own1 is chosen by default
7fd59977 1156 L3 = gce_MakeLin(Proj1,myDirAttach);
1157 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
1158 Handle(Select3D_SensitiveBox) box = new Select3D_SensitiveBox(own1,myPosition.X(),myPosition.Y(),myPosition.Z(),
1159 myPosition.X()+size,
1160 myPosition.Y()+size,
1161 myPosition.Z()+size);
1162 aSelection->Add(box);
1163 }
1164
1165 Standard_Real parmin,parmax,parcur;
1166 parmin = ElCLib::Parameter(L3,Proj1);
1167 parmax = parmin;
1168
1169 parcur = ElCLib::Parameter(L3,Proj2);
1170 parmin = Min(parmin,parcur);
1171 parmax = Max(parmax,parcur);
1172
1173 parcur = ElCLib::Parameter(L3,myPosition);
1174 parmin = Min(parmin,parcur);
1175 parmax = Max(parmax,parcur);
1176
1177 gp_Pnt PointMin = ElCLib::Value(parmin,L3);
1178 gp_Pnt PointMax = ElCLib::Value(parmax,L3);
1179
1180 Handle(Select3D_SensitiveSegment) seg;
1181
1182 if (myFAttach.IsEqual(mySAttach,confusion) && !myPosition.IsEqual(mySAttach,confusion)) {
1183 seg = new Select3D_SensitiveSegment(own1,mySAttach,myPosition);
1184 aSelection->Add(seg);
1185 }
1186 if (!PointMin.IsEqual(PointMax,confusion)) {
1187 gp_Pnt MiddlePoint( (PointMin.XYZ() + PointMax.XYZ())/2);
1188 seg = new Select3D_SensitiveSegment(own1,PointMin,MiddlePoint);
1189 aSelection->Add(seg);
1190 seg = new Select3D_SensitiveSegment(own2,MiddlePoint, PointMax);
1191 aSelection->Add(seg);
1192 }
1193
1194 if (!myFAttach.IsEqual(Proj1,confusion)) {
1195 seg = new Select3D_SensitiveSegment(own1,myFAttach,Proj1);
1196 aSelection->Add(seg);
1197 }
1198 if (!mySAttach.IsEqual(Proj2,confusion)) {
1199 seg = new Select3D_SensitiveSegment(own2,mySAttach,Proj2);
1200 aSelection->Add(seg);
1201 }
1202}
1203
1204
1205
1206
1207//=======================================================================
1208//function : KindOfDimension
1209//purpose :
1210//=======================================================================
1211 AIS_KindOfDimension AIS_LengthDimension::KindOfDimension() const
1212{
1213 return AIS_KOD_LENGTH;
1214}
1215
1216//=======================================================================
1217//function : IsMovable
1218//purpose :
1219//=======================================================================
1220 Standard_Boolean AIS_LengthDimension::IsMovable() const
1221{
1222 return Standard_True;
1223}
1224
1225//=======================================================================
1226//function : SetFirstShape
1227//purpose :
1228//=======================================================================
1229void AIS_LengthDimension::SetFirstShape( const TopoDS_Shape& aFShape )
1230{
1231 myFShape = aFShape;
1232
1233 if (myFShape.ShapeType() == TopAbs_FACE)
1234 AIS::InitFaceLength( TopoDS::Face( myFShape ), myFirstPlane, myFirstBasisSurf, myFirstSurfType, myFirstOffset );
1235}
1236
1237//=======================================================================
1238//function : SetSecondShape
1239//purpose :
1240//=======================================================================
1241void AIS_LengthDimension::SetSecondShape( const TopoDS_Shape& aSShape )
1242{
1243 mySShape = aSShape;
1244
1245 if (mySShape.ShapeType() == TopAbs_FACE)
1246 AIS::InitFaceLength( TopoDS::Face( mySShape ), mySecondPlane, mySecondBasisSurf, mySecondSurfType, mySecondOffset );
1247}