Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2000-10-20 |
2 | // Created by: Julia DOROVSKIKH | |
973c2be1 | 3 | // Copyright (c) 2000-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
7fd59977 | 15 | |
7fd59977 | 16 | |
17 | #include <AIS.hxx> | |
42cf5bc1 | 18 | #include <AIS_MidPointRelation.hxx> |
19 | #include <BRep_Tool.hxx> | |
20 | #include <BRepAdaptor_Curve.hxx> | |
21 | #include <BRepAdaptor_Surface.hxx> | |
22 | #include <DsgPrs_MidPointPresentation.hxx> | |
7fd59977 | 23 | #include <ElCLib.hxx> |
42cf5bc1 | 24 | #include <gce_MakeLin.hxx> |
7fd59977 | 25 | #include <Geom_Circle.hxx> |
26 | #include <Geom_Ellipse.hxx> | |
42cf5bc1 | 27 | #include <Geom_Line.hxx> |
28 | #include <Geom_Plane.hxx> | |
29 | #include <Geom_Transformation.hxx> | |
7fd59977 | 30 | #include <Geom_TrimmedCurve.hxx> |
42cf5bc1 | 31 | #include <gp_Ax1.hxx> |
32 | #include <gp_Ax2.hxx> | |
33 | #include <gp_Circ.hxx> | |
34 | #include <gp_Dir.hxx> | |
35 | #include <gp_Elips.hxx> | |
36 | #include <gp_Lin.hxx> | |
37 | #include <gp_Pln.hxx> | |
38 | #include <gp_Pnt.hxx> | |
39 | #include <Precision.hxx> | |
40 | #include <Prs3d_ArrowAspect.hxx> | |
41 | #include <Prs3d_DimensionAspect.hxx> | |
42 | #include <Prs3d_Drawer.hxx> | |
43 | #include <Prs3d_Presentation.hxx> | |
44 | #include <Prs3d_Projector.hxx> | |
45 | #include <Select3D_SensitiveCurve.hxx> | |
46 | #include <Select3D_SensitiveSegment.hxx> | |
7fd59977 | 47 | #include <SelectMgr_EntityOwner.hxx> |
f751596e | 48 | #include <SelectMgr_Selection.hxx> |
42cf5bc1 | 49 | #include <Standard_NotImplemented.hxx> |
50 | #include <Standard_Type.hxx> | |
7fd59977 | 51 | #include <TopExp_Explorer.hxx> |
42cf5bc1 | 52 | #include <TopoDS.hxx> |
53 | #include <TopoDS_Shape.hxx> | |
7fd59977 | 54 | #include <TopoDS_Vertex.hxx> |
55 | ||
92efcf78 | 56 | IMPLEMENT_STANDARD_RTTIEXT(AIS_MidPointRelation,AIS_Relation) |
57 | ||
7fd59977 | 58 | //======================================================================= |
59 | //function : AIS_MidPointRelation | |
60 | //purpose : | |
61 | //======================================================================= | |
62 | AIS_MidPointRelation::AIS_MidPointRelation(const TopoDS_Shape& aMidPointTool, | |
63 | const TopoDS_Shape& FirstShape, | |
64 | const TopoDS_Shape& SecondShape, | |
65 | const Handle(Geom_Plane)& aPlane) | |
66 | :AIS_Relation(), | |
67 | myTool(aMidPointTool) | |
68 | { | |
69 | SetFirstShape(FirstShape); | |
70 | SetSecondShape(SecondShape); | |
71 | SetPlane(aPlane); | |
72 | myPosition = aPlane->Pln().Location(); | |
73 | } | |
74 | ||
75 | //======================================================================= | |
76 | //function : Compute | |
77 | //purpose : | |
78 | //======================================================================= | |
79 | void AIS_MidPointRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, | |
80 | const Handle(Prs3d_Presentation)& aprs, | |
81 | const Standard_Integer) | |
82 | { | |
83 | aprs->Clear(); | |
84 | ||
85 | if (myTool.ShapeType() == TopAbs_VERTEX) | |
86 | { | |
87 | gp_Pnt pp; | |
88 | Standard_Boolean isonplane; | |
89 | if ( AIS::ComputeGeometry(TopoDS::Vertex(myTool),pp,myPlane,isonplane) ) | |
90 | { | |
91 | if ( !isonplane ) ComputeProjVertexPresentation(aprs,TopoDS::Vertex(myTool),pp); | |
92 | } | |
93 | myMidPoint = pp; | |
94 | } | |
95 | else return; | |
96 | ||
97 | if ( myAutomaticPosition ) myPosition = myMidPoint; | |
98 | ||
99 | switch (myFShape.ShapeType()) | |
100 | { | |
101 | case TopAbs_FACE : | |
102 | { | |
103 | ComputeFaceFromPnt(aprs, Standard_True); | |
104 | } | |
105 | break; | |
106 | case TopAbs_EDGE : | |
107 | { | |
108 | ComputeEdgeFromPnt(aprs, Standard_True); | |
109 | } | |
110 | break; | |
111 | case TopAbs_VERTEX : | |
112 | { | |
113 | ComputeVertexFromPnt(aprs, Standard_True); | |
114 | } | |
115 | break; | |
116 | default: | |
117 | break; | |
118 | } | |
119 | ||
120 | switch (mySShape.ShapeType()) | |
121 | { | |
122 | case TopAbs_FACE : | |
123 | { | |
124 | ComputeFaceFromPnt(aprs, Standard_False); | |
125 | } | |
126 | break; | |
127 | case TopAbs_EDGE : | |
128 | { | |
129 | ComputeEdgeFromPnt(aprs, Standard_False); | |
130 | } | |
131 | break; | |
132 | case TopAbs_VERTEX : | |
133 | { | |
134 | ComputeVertexFromPnt(aprs, Standard_False); | |
135 | } | |
136 | break; | |
137 | default: | |
138 | break; | |
139 | } | |
140 | } | |
141 | ||
142 | //======================================================================= | |
143 | //function : Compute | |
144 | //purpose : to avoid warning at compilation (SUN) | |
145 | //======================================================================= | |
146 | void AIS_MidPointRelation::Compute(const Handle(Prs3d_Projector)& /*aProjector*/, | |
147 | const Handle(Prs3d_Presentation)& /*aPresentation*/) | |
148 | { | |
149 | // Standard_NotImplemented::Raise("AIS_MidPointRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)"); | |
150 | // PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ; | |
151 | } | |
152 | ||
857ffd5e | 153 | void AIS_MidPointRelation::Compute(const Handle(Prs3d_Projector)& aProjector, |
154 | const Handle(Geom_Transformation)& aTransformation, | |
155 | const Handle(Prs3d_Presentation)& aPresentation) | |
7fd59977 | 156 | { |
857ffd5e | 157 | Standard_NotImplemented::Raise("AIS_MidPointRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)"); |
7fd59977 | 158 | PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ; |
159 | } | |
160 | ||
161 | //======================================================================= | |
162 | //function : ComputeSelection | |
163 | //purpose : | |
164 | //======================================================================= | |
165 | void AIS_MidPointRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSel, | |
166 | const Standard_Integer) | |
167 | { | |
168 | Handle(Select3D_SensitiveSegment) seg; | |
169 | Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7); | |
170 | ||
171 | if ( !myMidPoint.IsEqual(myFAttach,Precision::Confusion()) ) | |
172 | { | |
173 | // segment from mid point to the first geometry | |
174 | seg = new Select3D_SensitiveSegment(own,myFAttach,myMidPoint); | |
175 | aSel->Add(seg); | |
176 | // segment from mid point to the second geometry | |
177 | seg = new Select3D_SensitiveSegment(own,mySAttach,myMidPoint); | |
178 | aSel->Add(seg); | |
179 | } | |
180 | if ( !myMidPoint.IsEqual(myPosition,Precision::Confusion()) ) | |
181 | { | |
182 | // segment from mid point to the text position | |
183 | seg = new Select3D_SensitiveSegment(own,myMidPoint,myPosition); | |
184 | aSel->Add(seg); | |
185 | } | |
186 | ||
187 | // center of the symmetry - circle around the MidPoint | |
188 | gp_Ax2 ax = myPlane->Pln().Position().Ax2(); | |
189 | ax.SetLocation(myMidPoint); | |
190 | Standard_Real rad = myFAttach.Distance(myMidPoint)/20.0; | |
191 | gp_Circ aCircleM (ax,rad); | |
543a9964 | 192 | Handle(Geom_Curve) thecir = new Geom_Circle(aCircleM); |
7fd59977 | 193 | Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own, thecir); |
194 | aSel->Add(scurv); | |
195 | ||
196 | Handle(Geom_Curve) curv; | |
197 | gp_Pnt firstp,lastp; | |
198 | Standard_Boolean isInfinite,isOnPlane; | |
199 | Handle(Geom_Curve) extCurv; | |
200 | ||
201 | // segment on first curve | |
202 | if ( myFShape.ShapeType() == TopAbs_EDGE ) | |
203 | { | |
204 | TopoDS_Edge E = TopoDS::Edge(myFShape); | |
205 | if ( !AIS::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return; | |
206 | if ( curv->IsInstance(STANDARD_TYPE(Geom_Line)) ) // case of line | |
207 | { | |
208 | // segment on line | |
209 | seg = new Select3D_SensitiveSegment(own,myFirstPnt1,myFirstPnt2); | |
210 | aSel->Add(seg); | |
211 | } | |
212 | else if ( curv->IsInstance(STANDARD_TYPE(Geom_Circle)) ) // case of circle | |
213 | { | |
214 | // segment on circle | |
c5f3a425 | 215 | Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv); |
7fd59977 | 216 | Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),myFirstPnt1); |
217 | Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),myFirstPnt2); | |
543a9964 | 218 | Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin); |
7fd59977 | 219 | |
220 | scurv = new Select3D_SensitiveCurve(own, thecu); | |
221 | aSel->Add(scurv); | |
222 | } | |
223 | else if ( curv->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) // case of ellipse | |
224 | { | |
225 | // segment on ellipse | |
c5f3a425 | 226 | Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv); |
7fd59977 | 227 | Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),myFirstPnt1); |
228 | Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),myFirstPnt2); | |
543a9964 | 229 | Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin); |
7fd59977 | 230 | |
231 | scurv = new Select3D_SensitiveCurve(own, thecu); | |
232 | aSel->Add(scurv); | |
233 | } | |
234 | } | |
235 | ||
236 | // segment on second curve | |
237 | if ( mySShape.ShapeType() == TopAbs_EDGE ) | |
238 | { | |
239 | TopoDS_Edge E = TopoDS::Edge(mySShape); | |
240 | if ( !AIS::ComputeGeometry(E,curv,firstp,lastp,extCurv,isInfinite,isOnPlane,myPlane) ) return; | |
241 | if ( curv->IsInstance(STANDARD_TYPE(Geom_Line)) ) // case of line | |
242 | { | |
243 | // segment on line | |
244 | seg = new Select3D_SensitiveSegment(own,mySecondPnt1,mySecondPnt2); | |
245 | aSel->Add(seg); | |
246 | } | |
247 | else if ( curv->IsInstance(STANDARD_TYPE(Geom_Circle)) ) // case of circle | |
248 | { | |
249 | // segment on circle | |
c5f3a425 | 250 | Handle(Geom_Circle) thecirc = Handle(Geom_Circle)::DownCast (curv); |
7fd59977 | 251 | Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),mySecondPnt1); |
252 | Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),mySecondPnt2); | |
543a9964 | 253 | Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin); |
7fd59977 | 254 | |
255 | scurv = new Select3D_SensitiveCurve(own, thecu); | |
256 | aSel->Add(scurv); | |
257 | } | |
258 | else if ( curv->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) // case of ellipse | |
259 | { | |
260 | // segment on ellipse | |
c5f3a425 | 261 | Handle(Geom_Ellipse) theEll = Handle(Geom_Ellipse)::DownCast (curv); |
7fd59977 | 262 | Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),mySecondPnt1); |
263 | Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),mySecondPnt2); | |
543a9964 | 264 | Handle(Geom_Curve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin); |
7fd59977 | 265 | |
266 | scurv = new Select3D_SensitiveCurve(own, thecu); | |
267 | aSel->Add(scurv); | |
268 | } | |
269 | } | |
270 | } | |
271 | ||
272 | //======================================================================= | |
273 | //function : ComputeFaceFromPnt | |
274 | //purpose : | |
275 | //======================================================================= | |
276 | void AIS_MidPointRelation::ComputeFaceFromPnt(const Handle(Prs3d_Presentation)&, | |
277 | const Standard_Boolean /*first*/) | |
278 | { | |
279 | } | |
280 | ||
281 | //======================================================================= | |
282 | //function : ComputeEdgeFromPnt | |
283 | //purpose : | |
284 | //======================================================================= | |
285 | void AIS_MidPointRelation::ComputeEdgeFromPnt(const Handle(Prs3d_Presentation)& aprs, | |
286 | const Standard_Boolean first) | |
287 | { | |
288 | TopoDS_Edge E; | |
289 | if ( first ) E = TopoDS::Edge(myFShape); | |
290 | else E = TopoDS::Edge(mySShape); | |
291 | ||
292 | Handle(Geom_Curve) geom; | |
293 | gp_Pnt ptat1,ptat2; | |
294 | Handle(Geom_Curve) extCurv; | |
295 | Standard_Boolean isInfinite,isOnPlane; | |
296 | if ( !AIS::ComputeGeometry(E, geom, ptat1, ptat2, extCurv, isInfinite, isOnPlane, myPlane) ) return; | |
297 | ||
298 | gp_Ax2 ax = myPlane->Pln().Position().Ax2(); | |
299 | ||
300 | if ( geom->IsInstance(STANDARD_TYPE(Geom_Line)) ) | |
301 | { | |
302 | if ( !isInfinite ) ComputePointsOnLine(ptat1,ptat2,first); | |
303 | else | |
304 | { | |
c5f3a425 | 305 | const gp_Lin& line = Handle(Geom_Line)::DownCast (geom)->Lin(); |
7fd59977 | 306 | ComputePointsOnLine(line,first); |
307 | } | |
308 | if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition, | |
309 | myFAttach,myFirstPnt1,myFirstPnt2,first); | |
310 | else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition, | |
311 | mySAttach,mySecondPnt1,mySecondPnt2,first); | |
312 | } | |
313 | else if ( geom->IsInstance(STANDARD_TYPE(Geom_Circle)) ) | |
314 | { | |
c5f3a425 | 315 | Handle(Geom_Circle) geom_cir (Handle(Geom_Circle)::DownCast (geom)); |
7fd59977 | 316 | gp_Circ circ (geom_cir->Circ()); |
317 | ComputePointsOnCirc(circ,ptat1,ptat2,first); | |
318 | if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,circ,myMidPoint,myPosition, | |
319 | myFAttach,myFirstPnt1,myFirstPnt2,first); | |
320 | else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,circ,myMidPoint,myPosition, | |
321 | mySAttach,mySecondPnt1,mySecondPnt2,first); | |
322 | } | |
323 | else if ( geom->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) | |
324 | { | |
c5f3a425 | 325 | Handle(Geom_Ellipse) geom_ell (Handle(Geom_Ellipse)::DownCast (geom)); |
7fd59977 | 326 | gp_Elips elips (geom_ell->Elips()); |
327 | ComputePointsOnElips(elips,ptat1,ptat2,first); | |
328 | if ( first ) DsgPrs_MidPointPresentation::Add(aprs,myDrawer,elips,myMidPoint,myPosition, | |
329 | myFAttach,myFirstPnt1,myFirstPnt2,first); | |
330 | else DsgPrs_MidPointPresentation::Add(aprs,myDrawer,elips,myMidPoint,myPosition, | |
331 | mySAttach,mySecondPnt1,mySecondPnt2,first); | |
332 | } | |
333 | else return; | |
334 | ||
335 | // projection on myPlane | |
336 | if ( !isOnPlane ) ComputeProjEdgePresentation(aprs,E,geom,ptat1,ptat2); | |
337 | } | |
338 | ||
339 | //======================================================================= | |
340 | //function : ComputeVertexFromPnt | |
341 | //purpose : | |
342 | //======================================================================= | |
343 | void AIS_MidPointRelation::ComputeVertexFromPnt(const Handle(Prs3d_Presentation)& aprs, | |
344 | const Standard_Boolean first) | |
345 | { | |
346 | gp_Ax2 ax = myPlane->Pln().Position().Ax2(); | |
347 | if ( first ) | |
348 | { | |
349 | Standard_Boolean isOnPlane; | |
350 | TopoDS_Vertex V = TopoDS::Vertex(myFShape); | |
351 | AIS::ComputeGeometry(V, myFAttach, myPlane, isOnPlane); | |
352 | DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,myFAttach,first); | |
353 | if ( !isOnPlane ) ComputeProjVertexPresentation(aprs,V,myFAttach); | |
354 | } | |
355 | else | |
356 | { | |
357 | Standard_Boolean isOnPlane; | |
358 | TopoDS_Vertex V = TopoDS::Vertex(mySShape); | |
359 | AIS::ComputeGeometry(V, mySAttach, myPlane, isOnPlane); | |
360 | DsgPrs_MidPointPresentation::Add(aprs,myDrawer,ax,myMidPoint,myPosition,mySAttach,first); | |
361 | if ( !isOnPlane ) ComputeProjVertexPresentation(aprs,V,mySAttach); | |
362 | } | |
363 | } | |
364 | ||
365 | //======================================================================= | |
366 | //function : ComputePointsOnLine | |
367 | //purpose : | |
368 | //======================================================================= | |
369 | void AIS_MidPointRelation::ComputePointsOnLine(const gp_Lin& aLin, | |
370 | const Standard_Boolean first) | |
371 | { | |
372 | Standard_Real ppar = ElCLib::Parameter(aLin,myMidPoint); | |
373 | gp_Pnt anAttach = ElCLib::Value(ppar,aLin); | |
374 | ||
375 | Standard_Real dist = anAttach.Distance(myMidPoint)/10.0; | |
376 | if ( dist < Precision::Confusion() ) dist = 10.0; | |
377 | ||
378 | Standard_Real fpar = ppar + dist; | |
379 | Standard_Real spar = ppar - dist; | |
380 | ||
381 | gp_Pnt aPnt1 = ElCLib::Value(fpar,aLin); | |
382 | gp_Pnt aPnt2 = ElCLib::Value(spar,aLin); | |
383 | ||
384 | if ( first ) | |
385 | { | |
386 | myFAttach = anAttach; | |
387 | myFirstPnt1 = aPnt1; | |
388 | myFirstPnt2 = aPnt2; | |
389 | } | |
390 | else | |
391 | { | |
392 | mySAttach = anAttach; | |
393 | mySecondPnt1 = aPnt1; | |
394 | mySecondPnt2 = aPnt2; | |
395 | } | |
396 | } | |
397 | ||
398 | //======================================================================= | |
399 | //function : ComputePointsOnLine | |
400 | //purpose : | |
401 | //======================================================================= | |
402 | void AIS_MidPointRelation::ComputePointsOnLine(const gp_Pnt& pnt1, const gp_Pnt& pnt2, | |
403 | const Standard_Boolean first) | |
404 | { | |
405 | gp_Vec aVec (pnt1,pnt2); | |
406 | gp_Lin aLin (pnt1,gp_Dir(aVec)); | |
407 | ||
408 | Standard_Real fpar = ElCLib::Parameter(aLin,pnt1); | |
409 | Standard_Real spar = ElCLib::Parameter(aLin,pnt2); | |
410 | Standard_Real ppar = ElCLib::Parameter(aLin,myMidPoint); | |
411 | ||
412 | gp_Pnt aProjPnt = ElCLib::Value(ppar,aLin); | |
413 | Standard_Real dist = myMidPoint.Distance(aProjPnt); | |
414 | Standard_Real ll = pnt1.Distance(pnt2); | |
415 | Standard_Real segm = Min(dist,ll)*0.75; | |
416 | if ( dist < Precision::Confusion() ) segm = ll*0.75; | |
417 | ||
418 | gp_Pnt anAttach,aPnt1,aPnt2; | |
419 | anAttach = aProjPnt; | |
420 | gp_Vec aVecTr; | |
421 | if ( ppar <= fpar ) | |
422 | { | |
423 | aPnt2 = pnt1; | |
424 | aVecTr = gp_Vec(pnt2,pnt1); | |
425 | aVecTr.Normalize(); | |
426 | aPnt1 = aProjPnt.Translated(aVecTr*segm); | |
427 | } | |
428 | else if ( ppar >= spar ) | |
429 | { | |
430 | aPnt1 = pnt2; | |
431 | aVecTr = gp_Vec(pnt1,pnt2); | |
432 | aVecTr.Normalize(); | |
433 | aPnt2 = aProjPnt.Translated(aVecTr*segm); | |
434 | } | |
435 | else | |
436 | { | |
437 | Standard_Real dp1 = aProjPnt.Distance(pnt1); | |
438 | Standard_Real dp2 = aProjPnt.Distance(pnt2); | |
439 | ||
440 | segm = Min(dist,dp1)*0.75; | |
441 | aVecTr = gp_Vec(aProjPnt,pnt1); | |
442 | aVecTr.Normalize(); | |
443 | aPnt1 = aProjPnt.Translated(aVecTr*segm); | |
444 | ||
445 | segm = Min(dist,dp2)*0.75; | |
446 | aVecTr = gp_Vec(aProjPnt,pnt2); | |
447 | aVecTr.Normalize(); | |
448 | aPnt2 = aProjPnt.Translated(aVecTr*segm); | |
449 | } | |
450 | ||
451 | if ( first ) | |
452 | { | |
453 | myFAttach = anAttach; | |
454 | myFirstPnt1 = aPnt1; | |
455 | myFirstPnt2 = aPnt2; | |
456 | } | |
457 | else | |
458 | { | |
459 | mySAttach = anAttach; | |
460 | mySecondPnt1 = aPnt1; | |
461 | mySecondPnt2 = aPnt2; | |
462 | } | |
463 | } | |
464 | ||
465 | //======================================================================= | |
466 | //function : ComputePointsOnCirc | |
467 | //purpose : | |
468 | //======================================================================= | |
469 | void AIS_MidPointRelation::ComputePointsOnCirc(const gp_Circ& aCirc, | |
470 | const gp_Pnt& pnt1, const gp_Pnt& pnt2, | |
471 | const Standard_Boolean first) | |
472 | { | |
473 | gp_Pnt curpos = myMidPoint; | |
474 | ||
475 | // Case of confusion between the current position and the center | |
476 | // of the circle -> we move the current position | |
477 | Standard_Real confusion (Precision::Confusion()); | |
478 | gp_Pnt aCenter = aCirc.Location(); | |
479 | if ( aCenter.Distance(curpos) <= confusion ) | |
480 | { | |
481 | gp_Vec vprec(aCenter, pnt1); | |
482 | vprec.Normalize(); | |
483 | curpos.Translate(vprec*1e-5); | |
484 | } | |
485 | ||
486 | Standard_Real pcurpos = ElCLib::Parameter(aCirc,curpos); | |
487 | ||
c6541a0c | 488 | Standard_Real rad = M_PI / 5.0; |
7fd59977 | 489 | Standard_Real segm; |
490 | ||
491 | Standard_Real pFPnt; | |
492 | Standard_Real pSPnt; | |
493 | ||
494 | if ( pnt1.IsEqual(pnt2,confusion) ) // full circle | |
495 | { | |
496 | pFPnt = pcurpos - rad; | |
497 | pSPnt = pcurpos + rad; | |
498 | } | |
499 | else | |
500 | { | |
501 | Standard_Real pFAttach = ElCLib::Parameter(aCirc,pnt1); | |
502 | Standard_Real pSAttach = ElCLib::Parameter(aCirc,pnt2); | |
503 | ||
504 | Standard_Real pSAttachM = pSAttach; | |
505 | Standard_Real deltap = pSAttachM - pFAttach; | |
506 | if ( deltap < 0 ) | |
507 | { | |
c6541a0c D |
508 | deltap += 2 * M_PI; |
509 | pSAttachM += 2 * M_PI; | |
7fd59977 | 510 | } |
511 | pSAttachM -= pFAttach; | |
512 | ||
c6541a0c | 513 | Standard_Real pmiddleout = pSAttachM/2.0 + M_PI; |
7fd59977 | 514 | |
515 | Standard_Real pcurpos1 = pcurpos; | |
516 | // define where curpos lays | |
517 | if ( pcurpos1 < pFAttach ) | |
518 | { | |
c6541a0c | 519 | pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach; |
7fd59977 | 520 | if ( pcurpos1 > pSAttachM ) // out |
521 | { | |
522 | segm = Min(rad,deltap*0.75); | |
523 | if ( pcurpos1 > pmiddleout ) | |
524 | { | |
525 | pcurpos = pFAttach; | |
526 | pFPnt = pFAttach; | |
527 | pSPnt = pFAttach + segm; | |
528 | } | |
529 | else | |
530 | { | |
531 | pcurpos = pSAttach; | |
532 | pFPnt = pSAttach - segm; | |
533 | pSPnt = pSAttach; | |
534 | } | |
535 | } | |
536 | else // on arc | |
537 | { | |
538 | Standard_Real dp1 = pcurpos1 - pFAttach; | |
539 | Standard_Real dp2 = pSAttachM - pcurpos1; | |
540 | ||
541 | segm = Min(rad,dp1*0.75); | |
542 | pFPnt = pcurpos - segm; | |
543 | ||
544 | segm = Min(rad,dp2*0.75); | |
545 | pSPnt = pcurpos + segm; | |
546 | } | |
547 | } | |
548 | else if ( pcurpos1 > (pFAttach + deltap) ) // out | |
549 | { | |
550 | pcurpos1 -= pFAttach; | |
551 | segm = Min(rad,deltap*0.75); | |
552 | if ( pcurpos1 > pmiddleout ) | |
553 | { | |
554 | pcurpos = pFAttach; | |
555 | pFPnt = pFAttach; | |
556 | pSPnt = pFAttach + segm; | |
557 | } | |
558 | else | |
559 | { | |
560 | pcurpos = pSAttach; | |
561 | pFPnt = pSAttach - segm; | |
562 | pSPnt = pSAttach; | |
563 | } | |
564 | } | |
565 | else // on arc | |
566 | { | |
567 | Standard_Real dp1 = pcurpos1 - pFAttach; | |
568 | Standard_Real dp2 = pSAttach - pcurpos1; | |
569 | ||
570 | segm = Min(rad,dp1*0.75); | |
571 | pFPnt = pcurpos - segm; | |
572 | ||
573 | segm = Min(rad,dp2*0.75); | |
574 | pSPnt = pcurpos + segm; | |
575 | } | |
576 | } | |
577 | ||
578 | if ( first ) | |
579 | { | |
580 | myFAttach = ElCLib::Value(pcurpos,aCirc); | |
581 | myFirstPnt1 = ElCLib::Value(pFPnt,aCirc); | |
582 | myFirstPnt2 = ElCLib::Value(pSPnt,aCirc); | |
583 | } | |
584 | else | |
585 | { | |
586 | mySAttach = ElCLib::Value(pcurpos,aCirc); | |
587 | mySecondPnt1 = ElCLib::Value(pFPnt,aCirc); | |
588 | mySecondPnt2 = ElCLib::Value(pSPnt,aCirc); | |
589 | } | |
590 | } | |
591 | ||
592 | //======================================================================= | |
593 | //function : ComputePointsOnElips | |
594 | //purpose : | |
595 | //======================================================================= | |
596 | void AIS_MidPointRelation::ComputePointsOnElips(const gp_Elips& anEll, | |
597 | const gp_Pnt& pnt1, const gp_Pnt& pnt2, | |
598 | const Standard_Boolean first) | |
599 | { | |
600 | gp_Pnt curpos = myMidPoint; | |
601 | ||
602 | // Case of confusion between the current position and the center | |
603 | // of the circle -> we move the current position | |
604 | Standard_Real confusion (Precision::Confusion()); | |
605 | gp_Pnt aCenter = anEll.Location(); | |
606 | if ( aCenter.Distance(curpos) <= confusion ) | |
607 | { | |
608 | gp_Vec vprec(aCenter, pnt1); | |
609 | vprec.Normalize(); | |
610 | curpos.Translate(vprec*1e-5); | |
611 | } | |
612 | ||
613 | Standard_Real pcurpos = ElCLib::Parameter(anEll,curpos); | |
614 | ||
c6541a0c | 615 | Standard_Real rad = M_PI / 5.0; |
7fd59977 | 616 | Standard_Real segm; |
617 | ||
618 | Standard_Real pFPnt; | |
619 | Standard_Real pSPnt; | |
620 | ||
621 | if ( pnt1.IsEqual(pnt2,confusion) ) // full circle | |
622 | { | |
623 | pFPnt = pcurpos - rad; | |
624 | pSPnt = pcurpos + rad; | |
625 | } | |
626 | else | |
627 | { | |
628 | Standard_Real pFAttach = ElCLib::Parameter(anEll,pnt1); | |
629 | Standard_Real pSAttach = ElCLib::Parameter(anEll,pnt2); | |
630 | ||
631 | Standard_Real pSAttachM = pSAttach; | |
632 | Standard_Real deltap = pSAttachM - pFAttach; | |
633 | if ( deltap < 0 ) | |
634 | { | |
c6541a0c D |
635 | deltap += 2 * M_PI; |
636 | pSAttachM += 2 * M_PI; | |
7fd59977 | 637 | } |
638 | pSAttachM -= pFAttach; | |
639 | ||
c6541a0c | 640 | Standard_Real pmiddleout = pSAttachM / 2.0 + M_PI; |
7fd59977 | 641 | |
642 | Standard_Real pcurpos1 = pcurpos; | |
643 | // define where curpos lays | |
644 | if ( pcurpos1 < pFAttach ) | |
645 | { | |
c6541a0c | 646 | pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach; |
7fd59977 | 647 | if ( pcurpos1 > pSAttachM ) // out |
648 | { | |
649 | segm = Min(rad,deltap*0.75); | |
650 | if ( pcurpos1 > pmiddleout ) | |
651 | { | |
652 | pcurpos = pFAttach; | |
653 | pFPnt = pFAttach; | |
654 | pSPnt = pFAttach + segm; | |
655 | } | |
656 | else | |
657 | { | |
658 | pcurpos = pSAttach; | |
659 | pFPnt = pSAttach - segm; | |
660 | pSPnt = pSAttach; | |
661 | } | |
662 | } | |
663 | else // on arc | |
664 | { | |
665 | Standard_Real dp1 = pcurpos1 - pFAttach; | |
666 | Standard_Real dp2 = pSAttachM - pcurpos1; | |
667 | ||
668 | segm = Min(rad,dp1*0.75); | |
669 | pFPnt = pcurpos - segm; | |
670 | ||
671 | segm = Min(rad,dp2*0.75); | |
672 | pSPnt = pcurpos + segm; | |
673 | } | |
674 | } | |
675 | else if ( pcurpos1 > (pFAttach + deltap) ) // out | |
676 | { | |
677 | pcurpos1 -= pFAttach; | |
678 | segm = Min(rad,deltap*0.75); | |
679 | if ( pcurpos1 > pmiddleout ) | |
680 | { | |
681 | pcurpos = pFAttach; | |
682 | pFPnt = pFAttach; | |
683 | pSPnt = pFAttach + segm; | |
684 | } | |
685 | else | |
686 | { | |
687 | pcurpos = pSAttach; | |
688 | pFPnt = pSAttach - segm; | |
689 | pSPnt = pSAttach; | |
690 | } | |
691 | } | |
692 | else // on arc | |
693 | { | |
694 | Standard_Real dp1 = pcurpos1 - pFAttach; | |
695 | Standard_Real dp2 = pSAttach - pcurpos1; | |
696 | ||
697 | segm = Min(rad,dp1*0.75); | |
698 | pFPnt = pcurpos - segm; | |
699 | ||
700 | segm = Min(rad,dp2*0.75); | |
701 | pSPnt = pcurpos + segm; | |
702 | } | |
703 | } | |
704 | ||
705 | if ( first ) | |
706 | { | |
707 | myFAttach = ElCLib::Value(pcurpos,anEll); | |
708 | myFirstPnt1 = ElCLib::Value(pFPnt,anEll); | |
709 | myFirstPnt2 = ElCLib::Value(pSPnt,anEll); | |
710 | } | |
711 | else | |
712 | { | |
713 | mySAttach = ElCLib::Value(pcurpos,anEll); | |
714 | mySecondPnt1 = ElCLib::Value(pFPnt,anEll); | |
715 | mySecondPnt2 = ElCLib::Value(pSPnt,anEll); | |
716 | } | |
717 | } |