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