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