1b2eb65a73fc58179591e2d94f0789d2c3303280
[occt.git] / src / Prs3d / Prs3d_Line.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <Graphic3d_ArrayOfPolylines.hxx>
20 #include <Graphic3d_Vertex.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Prs3d_Arrow.hxx>
23 #include <Prs3d_ArrowAspect.hxx>
24 #include <gp_Pnt.hxx>
25 #include <gp_Dir.hxx>
26 #include <Prs3d_LineAspect.hxx>
27 #include <Prs3d.hxx>
28
29 static void DrawLine (const anyLine& aLine, const Handle(Graphic3d_Group)& aGroup)
30 {
31   Quantity_Length x,y,z;
32
33   Standard_Integer i = LineTool::Lower(aLine);
34   const Standard_Integer Upper = LineTool::Upper(aLine);
35
36   Handle(Graphic3d_ArrayOfPolylines) aPrims = new Graphic3d_ArrayOfPolylines(Upper-i+1);
37   for (; i <= Upper; i++) {
38     LineTool::Coord(aLine,i,x,y,z);
39     aPrims->AddVertex((Standard_ShortReal)x,(Standard_ShortReal)y,(Standard_ShortReal)z);
40   }
41   aGroup->AddPrimitiveArray(aPrims);
42 }
43
44 void Prs3d_Line::Add (const Handle (Prs3d_Presentation)& aPresentation,
45                     const anyLine& aLine,
46                     const Handle (Prs3d_Drawer)& aDrawer)
47 {
48   Handle(Graphic3d_Group) TheGroup = Prs3d_Root::CurrentGroup(aPresentation);    
49   TheGroup->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect());
50   DrawLine(aLine,TheGroup);
51   if (aDrawer->LineArrowDraw()) {
52     Standard_Integer Lower = LineTool::Lower(aLine);
53     Standard_Integer Upper = LineTool::Upper(aLine);    
54     if ( Upper > Lower ){
55       Quantity_Length x1,y1,z1,x2,y2,z2;
56       LineTool::Coord(aLine,Upper-1,x1,y1,z1);
57       LineTool::Coord(aLine,Upper,x2,y2,z2);
58       
59       Prs3d_Arrow::Draw(aPresentation,
60                       gp_Pnt(x2,y2,z2),
61                       gp_Dir(x2-x1,y2-y1,z2-z1),
62                       aDrawer->ArrowAspect()->Angle(),
63                       aDrawer->ArrowAspect()->Length());
64     }
65   }
66 }
67
68 void Prs3d_Line::Add (const Handle (Prs3d_Presentation)& aPresentation, const anyLine& aLine)
69 {
70   DrawLine (aLine,Prs3d_Root::CurrentGroup(aPresentation));
71 }
72
73 Standard_Integer Prs3d_Line::Pick
74              (const Quantity_Length X,
75               const Quantity_Length Y,
76               const Quantity_Length Z,
77               const Quantity_Length aDistance,
78               const anyLine& aLine,
79               const Handle (Prs3d_Drawer)& aDrawer,
80               const Prs3d_TypeOfLinePicking TypeOfPicking)
81 {
82   Standard_Integer i = LineTool::Lower(aLine);
83   const Standard_Integer Upper = LineTool::Upper(aLine);
84
85   Standard_Integer num = 0;
86   Quantity_Length X1,Y1,Z1,X2,Y2,Z2,dist;
87
88   Standard_Real DistMin = RealLast();
89
90   for (; i <= Upper; i++)
91   {
92     LineTool::Coord(aLine,i,X2,Y2,Z2);
93     switch (TypeOfPicking) {
94       case Prs3d_TOLP_Point: {
95         dist = Abs(X-X2)+Abs(Y-Y2)+ Abs(Z-Z2);
96         if(dist < aDistance) {
97           if (dist < DistMin) {
98             DistMin = dist;
99             num = i;
100           }
101         }
102         break;
103       }
104       case Prs3d_TOLP_Segment: {
105         if (i > 1) {
106           if (Prs3d::MatchSegment(X,Y,Z,aDistance,gp_Pnt(X1,Y1,Z1),gp_Pnt(X2,Y2,Z2),dist)) {
107             if(dist < aDistance) {
108               if (dist < DistMin) {
109                 DistMin = dist;
110                 num = i;
111               }
112             }
113           }
114         }
115         X1=X2;Y1=Y2;Z1=Z2;
116         break;
117       }
118     }
119   }
120   return num;
121 }