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