0027860: Visualization - clean up Transformation Persistence API
[occt.git] / src / AIS / AIS_ParallelRelation.cxx
1 // Created on: 1996-12-05
2 // Created by: Jean-Pierre COMBE/Odile Olivier
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <AIS.hxx>
19 #include <AIS_ParallelRelation.hxx>
20 #include <BRep_Tool.hxx>
21 #include <BRepAdaptor_Curve.hxx>
22 #include <BRepAdaptor_Surface.hxx>
23 #include <DsgPrs_LengthPresentation.hxx>
24 #include <ElCLib.hxx>
25 #include <gce_MakeLin.hxx>
26 #include <Geom_Ellipse.hxx>
27 #include <Geom_Line.hxx>
28 #include <Geom_Plane.hxx>
29 #include <Geom_Transformation.hxx>
30 #include <gp_Ax1.hxx>
31 #include <gp_Ax2.hxx>
32 #include <gp_Dir.hxx>
33 #include <gp_Lin.hxx>
34 #include <gp_Pln.hxx>
35 #include <gp_Pnt.hxx>
36 #include <Precision.hxx>
37 #include <Prs3d_ArrowAspect.hxx>
38 #include <Prs3d_DimensionAspect.hxx>
39 #include <Prs3d_Drawer.hxx>
40 #include <Prs3d_Presentation.hxx>
41 #include <Prs3d_Projector.hxx>
42 #include <Select3D_SensitiveBox.hxx>
43 #include <Select3D_SensitiveSegment.hxx>
44 #include <SelectMgr_EntityOwner.hxx>
45 #include <SelectMgr_Selection.hxx>
46 #include <Standard_DomainError.hxx>
47 #include <Standard_NotImplemented.hxx>
48 #include <Standard_Type.hxx>
49 #include <TCollection_AsciiString.hxx>
50 #include <TCollection_ExtendedString.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopoDS.hxx>
53 #include <TopoDS_Shape.hxx>
54
55 IMPLEMENT_STANDARD_RTTIEXT(AIS_ParallelRelation,AIS_Relation)
56
57 //=======================================================================
58 //function : Constructor
59 //purpose  : 
60 //=======================================================================
61 AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, 
62                                            const TopoDS_Shape& aSShape, 
63                                            const Handle(Geom_Plane)& aPlane)
64 {
65   myFShape = aFShape;
66   mySShape = aSShape;
67   myPlane = aPlane;
68   myAutomaticPosition = Standard_True;
69   myArrowSize = 0.01;
70   mySymbolPrs = DsgPrs_AS_BOTHAR;
71 }
72
73 //=======================================================================
74 //function : Constructor
75 //purpose  : 
76 //=======================================================================
77 AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, 
78                                            const TopoDS_Shape& aSShape, 
79                                            const Handle(Geom_Plane)& aPlane, 
80                                            const gp_Pnt& aPosition,
81                                            const DsgPrs_ArrowSide aSymbolPrs, 
82                                            const Standard_Real anArrowSize)
83 {
84   myFShape = aFShape;
85   mySShape = aSShape;
86   myPlane = aPlane;
87   myAutomaticPosition = Standard_False;
88   SetArrowSize( anArrowSize );
89   myPosition = aPosition;
90   mySymbolPrs = aSymbolPrs;
91 }
92
93 //=======================================================================
94 //function : Compute
95 //purpose  : 
96 //=======================================================================
97 void AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, 
98                                    const Handle(Prs3d_Presentation)& aPresentation, 
99                                    const Standard_Integer)
100 {
101   aPresentation->Clear();
102
103   switch (myFShape.ShapeType())
104     {
105     case TopAbs_FACE :
106       {
107         // cas longueur entre deux faces
108         ComputeTwoFacesParallel(aPresentation);
109       }
110       break;
111     case TopAbs_EDGE :
112       {
113         // cas longueur entre deux edges
114         ComputeTwoEdgesParallel(aPresentation);
115       }
116       break;
117     default:
118       break;
119     }
120 }
121
122 //=======================================================================
123 //function : Compute
124 //purpose  : to avoid warning
125 //=======================================================================
126 void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
127                                    const Handle(Prs3d_Presentation)& aPresentation)
128 {
129 // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
130   PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
131 }
132
133 void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Geom_Transformation)& aTransformation, const Handle(Prs3d_Presentation)& aPresentation)
134 {
135 // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
136   PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
137 }
138
139 //=======================================================================
140 //function : ComputeSelection
141 //purpose  : 
142 //=======================================================================
143 void AIS_ParallelRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, 
144                                             const Standard_Integer)
145 {
146   gp_Lin L1 (myFAttach,myDirAttach);
147   gp_Lin L2 (mySAttach,myDirAttach);
148   gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1);
149   gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2);
150   
151   gp_Lin L3;
152   Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
153
154   if (!Proj1.IsEqual(Proj2,Precision::Confusion()))
155     {
156       L3 = gce_MakeLin(Proj1,Proj2);
157     }
158   else
159     {
160       L3 = gce_MakeLin(Proj1,myDirAttach);
161       Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
162       Handle(Select3D_SensitiveBox) box =
163         new Select3D_SensitiveBox(own,
164                                   myPosition.X(),
165                                   myPosition.Y(),
166                                   myPosition.Z(),
167                                   myPosition.X()+size,
168                                   myPosition.Y()+size,
169                                   myPosition.Z()+size);
170       aSelection->Add(box);
171     }
172   Standard_Real parmin,parmax,parcur;
173   parmin = ElCLib::Parameter(L3,Proj1);
174   parmax = parmin;
175   
176   parcur = ElCLib::Parameter(L3,Proj2);
177   parmin = Min(parmin,parcur);
178   parmax = Max(parmax,parcur);
179   
180   parcur = ElCLib::Parameter(L3,myPosition);
181   parmin = Min(parmin,parcur);
182   parmax = Max(parmax,parcur);
183   
184   gp_Pnt PointMin = ElCLib::Value(parmin,L3);
185   gp_Pnt PointMax = ElCLib::Value(parmax,L3);
186
187   Handle(Select3D_SensitiveSegment) seg;
188   
189   if (!PointMin.IsEqual(PointMax,Precision::Confusion()))
190     {
191       seg = new Select3D_SensitiveSegment(own,
192                                           PointMin,
193                                           PointMax);
194       aSelection->Add(seg);
195     }
196   if (!myFAttach.IsEqual(Proj1,Precision::Confusion()))
197     {
198       seg = new Select3D_SensitiveSegment(own, myFAttach, Proj1);
199       aSelection->Add(seg);
200     }
201   if (!mySAttach.IsEqual(Proj2,Precision::Confusion()))
202     {
203       seg = new Select3D_SensitiveSegment(own, mySAttach, Proj2);
204       aSelection->Add(seg);
205     }
206 }
207
208 //=======================================================================
209 //function : ComputeTwoFacesParallel
210 //purpose  : 
211 //=======================================================================
212 void AIS_ParallelRelation::ComputeTwoFacesParallel(const Handle(Prs3d_Presentation)&)
213 {
214   Standard_NotImplemented::Raise("AIS_ParallelRelation::ComputeTwoFacesParallel not implemented");
215 }
216
217 //=======================================================================
218 //function : ComputeTwoEdgesParallel
219 //purpose  : 
220 //=======================================================================
221 void AIS_ParallelRelation::ComputeTwoEdgesParallel(const Handle(Prs3d_Presentation)& aPresentation)
222 {
223   TopoDS_Edge E1 = TopoDS::Edge(myFShape);
224   TopoDS_Edge E2 = TopoDS::Edge(mySShape);
225
226   gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d;
227   Handle(Geom_Curve) geom1,geom2;
228   Standard_Boolean isInfinite1,isInfinite2;
229   Handle(Geom_Curve) extCurv;
230   if (!AIS::ComputeGeometry(E1,E2,myExtShape,
231                             geom1,geom2,
232                             ptat11,ptat12,ptat21,ptat22,
233                             extCurv,
234                             isInfinite1,isInfinite2,
235                             myPlane))
236     {
237       return;
238     }
239
240   aPresentation->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape != 0));
241
242   gp_Lin l1;
243   gp_Lin l2;
244   Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False;
245
246   if (geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
247     {
248       Handle(Geom_Ellipse) geom_el1 (Handle(Geom_Ellipse)::DownCast (geom1));
249       // construct lines through focuses
250       gp_Ax1 elAx = geom_el1->XAxis();
251       l1 = gp_Lin(elAx);
252       Standard_Real focex = geom_el1->MajorRadius() - geom_el1->Focal()/2.0;
253       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
254       ptat11 = geom_el1->Focus1().Translated(transvec);
255       ptat12 = geom_el1->Focus2().Translated(-transvec);
256       isEl1 = Standard_True;
257     }
258   else if (geom1->IsInstance(STANDARD_TYPE(Geom_Line)))
259     {
260       Handle(Geom_Line) geom_lin1 (Handle(Geom_Line)::DownCast (geom1));
261       l1 = geom_lin1->Lin();
262     }
263   else return;
264
265   if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
266     {
267       Handle(Geom_Ellipse) geom_el2 (Handle(Geom_Ellipse)::DownCast (geom2));
268       // construct lines through focuses
269       gp_Ax1 elAx = geom_el2->XAxis();
270       l2 = gp_Lin(elAx);
271       Standard_Real focex = geom_el2->MajorRadius() - geom_el2->Focal()/2.0;
272       gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
273       ptat21 = geom_el2->Focus1().Translated(transvec);
274       ptat22 = geom_el2->Focus2().Translated(-transvec);
275       isEl2 = Standard_True;
276     }
277   else if (geom2->IsInstance(STANDARD_TYPE(Geom_Line)))
278     {
279       Handle(Geom_Line) geom_lin2 (Handle(Geom_Line)::DownCast (geom2));
280       l2 = geom_lin2->Lin();
281     }
282   else return;
283
284   const Handle(Geom_Line)& geom_lin1 = new Geom_Line(l1);
285   const Handle(Geom_Line)& geom_lin2 = new Geom_Line(l2);
286
287   myDirAttach = l1.Direction();
288   // size
289   if( !myArrowSizeIsDefined ) {
290     Standard_Real arrSize1 (myArrowSize), arrSize2 (myArrowSize);
291     if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/50.;
292     if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/50.;
293     myArrowSize = Max(myArrowSize,Max(arrSize1,arrSize2));
294 //  myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2));
295   }
296
297   if ( myAutomaticPosition )
298     {    
299       gp_Pnt curpos;
300       if ( !isInfinite1 )
301         {
302           gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2);
303           curpos.SetXYZ((ptat11.XYZ() + p2.XYZ())/2.);
304         }
305       else if ( !isInfinite2 )
306         {
307           gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1);
308           curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.);
309         }
310       else
311         {
312           curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.);
313         }
314       // offset pour eviter confusion Edge et Dimension
315       gp_Vec offset (myDirAttach);
316       offset = offset*myArrowSize*(-10.);
317       curpos.Translate(offset);
318       myPosition = curpos;
319     }
320
321   // recherche points attache
322   if (!isInfinite1)
323     {
324       if ( isEl1 )
325         {
326           if (myPosition.Distance(ptat11) < myPosition.Distance(ptat12)) myFAttach = ptat12;
327           else myFAttach = ptat11;
328         }
329       else
330         {
331           if (myPosition.Distance(ptat11) > myPosition.Distance(ptat12)) myFAttach = ptat12;
332           else myFAttach = ptat11;
333         }
334     }
335   else
336     {
337       myFAttach = ElCLib::Value(ElCLib::Parameter(l1,myPosition),l1);
338     }
339   
340   if (!isInfinite2)
341     {
342       if ( isEl2 )
343         {
344           if (myPosition.Distance(ptat21) < myPosition.Distance(ptat22)) mySAttach = ptat22;
345           else mySAttach = ptat21;
346         }
347       else
348         {
349           if (myPosition.Distance(ptat21) > myPosition.Distance(ptat22)) mySAttach = ptat22;
350           else mySAttach = ptat21;
351         }
352     }
353   else
354     {
355       mySAttach = ElCLib::Value(ElCLib::Parameter(l2,myPosition),l2);
356     }
357   TCollection_ExtendedString aText (" //");
358   
359   if (l1.Distance(l2) <= Precision::Confusion())
360     {
361       myArrowSize = 0.;
362     }
363   Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
364   Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
365   arr->SetLength(myArrowSize);
366   arr = la->ArrowAspect();
367   arr->SetLength(myArrowSize);
368   if ( myExtShape == 1)
369     mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR;
370   else if ( myExtShape == 2)
371     mySymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT;
372
373   DsgPrs_LengthPresentation::Add(aPresentation,
374                                  myDrawer,
375                                  aText,
376                                  myFAttach,
377                                  mySAttach,
378                                  myDirAttach,
379                                  myPosition,
380                                  mySymbolPrs);
381   if ( (myExtShape != 0) &&  !extCurv.IsNull())
382     {
383       gp_Pnt pf, pl;
384       if ( myExtShape == 1 )
385         {
386           if (!isInfinite1)
387             {
388               pf = ptat11; 
389               pl = ptat12;
390             }
391           ComputeProjEdgePresentation(aPresentation,E1,geom_lin1,pf,pl);
392         }
393       else
394         {
395           if (!isInfinite2)
396             {
397               pf = ptat21; 
398               pl = ptat22;
399             }
400           ComputeProjEdgePresentation(aPresentation,E2,geom_lin2,pf,pl);
401         }
402     }
403 }