0024326: Get rid of confusing extension line
[occt.git] / src / AIS / AIS_FixRelation.cxx
CommitLineData
b311480e 1// Created on: 1996-12-05
2// Created by: Flore Lantheaume/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
7fd59977 21
22#define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23// if any in all dimensions.
24
25#include <Standard_NotImplemented.hxx>
26
27#include <AIS_FixRelation.ixx>
28
29#include <AIS_Shape.hxx>
30
31#include <TopAbs_ShapeEnum.hxx>
32
33#include <SelectMgr_EntityOwner.hxx>
34#include <Select3D_SensitiveSegment.hxx>
35
36#include <BRep_Tool.hxx>
37#include <BRepAdaptor_Curve.hxx>
38
39#include <TopoDS.hxx>
40#include <TopoDS_Edge.hxx>
41#include <TopoDS_Vertex.hxx>
42#include <TopoDS_Wire.hxx>
43#include <TopExp.hxx>
44#include <TopLoc_Location.hxx>
45#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46#include <TopTools_IndexedMapOfShape.hxx>
47#include <TopTools_ListIteratorOfListOfShape.hxx>
48
49#include <TColStd_ListIteratorOfListOfTransient.hxx>
50
51#include <Geom_Curve.hxx>
52#include <Geom_Line.hxx>
53#include <Geom_Circle.hxx>
54#include <Geom_Plane.hxx>
55
56#include <gp_Pnt.hxx>
57#include <gp_Vec.hxx>
58#include <gp_Dir.hxx>
59#include <gp_Ax1.hxx>
60#include <gp_XYZ.hxx>
61
62#include <ElCLib.hxx>
63#include <ElSLib.hxx>
64
65#include <Precision.hxx>
66
67#include <Standard_DomainError.hxx>
68
69#include <DsgPrs_FixPresentation.hxx>
70
71#include <AIS.hxx>
72
73static Standard_Boolean InDomain(const Standard_Real fpar,
74 const Standard_Real lpar,
75 const Standard_Real para)
76{
77 if (fpar >= 0.) {
78 return ((para >= fpar) && (para <= lpar));
79 }
c6541a0c 80 if (para >= (fpar+2*M_PI)) return Standard_True;
7fd59977 81 if (para <= lpar) return Standard_True;
82 return Standard_False;
83}
84
85//=======================================================================
86//function : Constructor
87//purpose : vertex Fix Relation
88//=======================================================================
89
90AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
91 const Handle(Geom_Plane)& aPlane,
92 const TopoDS_Wire& aWire)
93:AIS_Relation(),
258ff83b 94 myWire(aWire)
7fd59977 95{
96 myFShape = aShape;
97 myPlane = aPlane;
98 myAutomaticPosition = Standard_True;
99 myArrowSize = 5.;
100}
101
102//=======================================================================
103//function : Constructor
104//purpose : vertex Fix Relation
105//=======================================================================
106
107AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
108 const Handle(Geom_Plane)& aPlane,
109 const TopoDS_Wire& aWire,
110 const gp_Pnt& aPosition,
111 const Standard_Real anArrowSize)
112:AIS_Relation(),
258ff83b 113 myWire(aWire)
7fd59977 114{
115 myFShape = aShape;
116 myPlane = aPlane;
117 myPosition = aPosition;
118#ifdef BUC60915
119 SetArrowSize( anArrowSize );
120#else
121 myArrowSize = anArrowSize;
122#endif
123 myAutomaticPosition = Standard_False;
124}
125
126
127//=======================================================================
128//function : Constructor
129//purpose : edge (line or circle) Fix Relation
130//=======================================================================
131
132AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
258ff83b 133 const Handle(Geom_Plane)& aPlane)
7fd59977 134{
135 myFShape = aShape;
136 myPlane = aPlane;
137 myAutomaticPosition = Standard_True;
138 myArrowSize = 5.;
139}
140
141//=======================================================================
142//function : Constructor
143//purpose : edge (line or circle) Fix Relation
144//=======================================================================
145
146AIS_FixRelation::AIS_FixRelation(
147 const TopoDS_Shape& aShape,
148 const Handle(Geom_Plane)& aPlane,
149 const gp_Pnt& aPosition,
258ff83b 150 const Standard_Real anArrowSize)
7fd59977 151{
152 myFShape = aShape;
153 myPlane = aPlane;
154 myPosition = aPosition;
155#ifdef BUC60915
156 SetArrowSize( anArrowSize );
157#else
158 myArrowSize = anArrowSize;
159#endif
160 myAutomaticPosition = Standard_False;
161}
162
163//=======================================================================
164//function : Wire
165//purpose :
166//=======================================================================
167
168TopoDS_Wire AIS_FixRelation::Wire()
169{
170 return myWire;
171}
172
173//=======================================================================
174//function : SetWire
175//purpose :
176//=======================================================================
177
178void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
179{
180 myWire = aWire;
181}
182
183
184//=======================================================================
185//function : Compute
186//purpose :
187//=======================================================================
188
189void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
190 const Handle(Prs3d_Presentation)& aPresentation,
191 const Standard_Integer)
192{
193 aPresentation->Clear();
194
81bba717 195 // Calculate position of the symbol and
196 // point of attach of the segment on the shape
7fd59977 197 gp_Pnt curpos;
198 if (myFShape.ShapeType() == TopAbs_VERTEX)
199 ComputeVertex(TopoDS::Vertex(myFShape), curpos);
200 else if (myFShape.ShapeType() == TopAbs_EDGE)
201 ComputeEdge(TopoDS::Edge(myFShape), curpos);
202
203 const gp_Dir& nor = myPlane->Axis().Direction();
204
205
81bba717 206 // calculate presentation
207 // definition of the symbol size
7fd59977 208#ifdef BUC60915
209 if( !myArrowSizeIsDefined )
210#endif
211 myArrowSize = 5.;
212
81bba717 213 //creation of the presentation
7fd59977 214 DsgPrs_FixPresentation::Add(aPresentation,
215 myDrawer,
216 myPntAttach,
217 curpos,
218 nor,
219 myArrowSize);
220}
221
222//=======================================================================
223//function : Compute
224//purpose : to avoid warning
225//=======================================================================
226
227void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
228 const Handle(Prs3d_Presentation)& aPresentation)
229{
230// Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
231 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
232}
233
7fd59977 234//=======================================================================
235//function : Compute
236//purpose :
237//=======================================================================
238
239void AIS_FixRelation::Compute(const Handle_Prs3d_Projector& aProjector,
240 const Handle_Geom_Transformation& aTransformation,
241 const Handle_Prs3d_Presentation& aPresentation)
242{
243// Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
244 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
245}
246
247//=======================================================================
248//function : ComputeSelection
249//purpose :
250//=======================================================================
251
252void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
253 const Standard_Integer)
254{
255 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
256
81bba717 257 // creation of segment sensible for the linked segment
258 // of the shape fixed to symbol 'Fix'
7fd59977 259 Handle(Select3D_SensitiveSegment) seg;
260 seg = new Select3D_SensitiveSegment(own,
261 myPntAttach,
262 myPosition);
263 aSelection->Add(seg);
264
81bba717 265 // Creation of the sensible zone of symbol 'Fix'
7fd59977 266 gp_Dir norm = myPlane->Axis().Direction();
267
268 gp_Vec dirac(myPntAttach,myPosition);
269 dirac.Normalize();
270 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
271 gp_Ax1 ax(myPosition, norm);
c6541a0c 272 norac.Rotate(ax, M_PI/8);
7fd59977 273
274 norac*=(myArrowSize/2);
275 gp_Pnt P1 = myPosition.Translated(norac);
276 gp_Pnt P2 = myPosition.Translated(-norac);
277 seg = new Select3D_SensitiveSegment(own,
278 P1,
279 P2);
280 aSelection->Add(seg);
281
282 norac*=0.8;
283 P1 = myPosition.Translated(norac);
284 P2 = myPosition.Translated(-norac);
285 dirac*=(myArrowSize/2);
286 gp_Pnt PF(P1.XYZ());
287 gp_Pnt PL = PF.Translated(dirac);
288 PL.Translate(norac);
289 seg = new Select3D_SensitiveSegment(own,
290 PF,
291 PL);
292 aSelection->Add(seg);
293
294
295 PF.SetXYZ(P2.XYZ());
296 PL = PF.Translated(dirac);
297 PL.Translate(norac);
298 seg = new Select3D_SensitiveSegment(own,
299 PF,
300 PL);
301 aSelection->Add(seg);
302
303 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
304 PL = PF.Translated(dirac);
305 PL.Translate(norac);
306 seg = new Select3D_SensitiveSegment(own,
307 PF,
308 PL);
309}
310
311//=======================================================================
312//function : ComputeVertex
313//purpose : computes myPntAttach and the position of the presentation
314// when you fix a vertex
315//=======================================================================
316
317void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
318 gp_Pnt& curpos)
319{
320 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
321 curpos = myPosition;
322 if (myAutomaticPosition) {
323 gp_Pln pln(myPlane->Pln());
324 gp_Dir dir(pln.XAxis().Direction());
325 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
326 curpos = myPntAttach.Translated(transvec);;
327 myPosition = curpos;
328 myAutomaticPosition = Standard_True;
329 }
330}
331
332//=======================================================================
333//function : ComputePosition
334//purpose :
335//=======================================================================
336
337gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv1,
338 const Handle(Geom_Curve)& curv2,
339 const gp_Pnt& firstp1,
340 const gp_Pnt& lastp1,
341 const gp_Pnt& firstp2,
342 const gp_Pnt& lastp2) const
343{
344 //---------------------------------------------------------
81bba717 345 // calculate the point of attach
7fd59977 346 //---------------------------------------------------------
347 gp_Pnt curpos;
348
349 if (curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) || curv2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
350 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv1);
351 if (gcirc.IsNull()) gcirc = Handle(Geom_Circle)::DownCast(curv2);
352 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
353 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
354 curpos = myPntAttach.Translated(transvec);
355 }
356
357 else {
358 gp_Vec vec1(firstp1,lastp1);
359 gp_Vec vec2(firstp2,lastp2);
360
361 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
362 gp_Dir dir;
363 Standard_Real conf =Precision::Confusion();
364 if (lastp1.IsEqual(firstp2,conf) || firstp1.IsEqual(lastp2,conf)) dir.SetXYZ(vec1.XYZ() - vec2.XYZ());
365 else dir.SetXYZ(vec1.XYZ() + vec2.XYZ());
366 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
367 curpos = myPntAttach.Translated(transvec);
368 }
369 else {
370 gp_Vec crossvec = vec1.Crossed(vec2);
371 vec1.Cross(crossvec);
372 gp_Dir dir(vec1);
373 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
374 }
375 }
376
377 return curpos;
378}
379
380//=======================================================================
381//function : ComputePosition
382//purpose : Computes the position of the "fix dimension" when the
383// fixed object is a vertex which is set at the intersection
384// of two curves.
385// The "dimension" is in the "middle" of the two edges.
386//=======================================================================
387
388gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
389 const gp_Pnt& firstp,
390 const gp_Pnt& lastp) const
391{
392 //---------------------------------------------------------
81bba717 393 // calculate the point of attach
7fd59977 394 //---------------------------------------------------------
395 gp_Pnt curpos;
396
397 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
398
399 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv);
400 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
401 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
402 curpos = myPntAttach.Translated(transvec);
403
404 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
405
406 else {
407// gp_Pln pln(Component()->WorkingPlane()->Plane()->GetValue()->Pln());
408 gp_Pln pln(myPlane->Pln());
409 gp_Dir NormPln = pln.Axis().Direction();
410 gp_Vec vec(firstp,lastp);
411 vec.Cross( gp_Vec(NormPln));
412 vec.Normalize();
413 gp_Vec transvec = vec*myArrowSize;
414 curpos = myPntAttach.Translated(transvec);
415 gp_Ax1 RotAx( myPntAttach, NormPln);
c6541a0c 416 curpos.Rotate(RotAx, M_PI/10);
7fd59977 417 }
418
419 return curpos;
420 }
421
422//=======================================================================
423//function : ComputeEdge
424//purpose : computes myPntAttach and the position of the presentation
425// when you fix an edge
426//=======================================================================
427
428void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
429{
430 Handle(Geom_Curve) curEdge;
431 gp_Pnt ptbeg,ptend;
432 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
433
434 //---------------------------------------------------------
435 // calcul du point de positionnement du symbole 'fix'
436 //---------------------------------------------------------
81bba717 437 //--> In case of a straight line
7fd59977 438 if (curEdge->IsKind(STANDARD_TYPE(Geom_Line))){
439 gp_Lin glin = Handle(Geom_Line)::DownCast(curEdge)->Lin();
440 Standard_Real pfirst(ElCLib::Parameter(glin,ptbeg));
441 Standard_Real plast(ElCLib::Parameter(glin,ptend));
442 ComputeLinePosition(glin, curpos, pfirst, plast);
443 }
444
81bba717 445 //--> In case of a circle
7fd59977 446 else if (curEdge->IsKind(STANDARD_TYPE(Geom_Circle))) {
447 gp_Circ gcirc = Handle(Geom_Circle)::DownCast(curEdge)->Circ();
448 Standard_Real pfirst, plast;
449 BRepAdaptor_Curve cu(FixEdge);
450 pfirst = cu.FirstParameter();
451 plast = cu.LastParameter();
452 ComputeCirclePosition(gcirc, curpos, pfirst, plast);
453 }
454
455 else
456 return;
457
458}
459
460//=======================================================================
461//function : ComputeLinePosition
462//purpose : compute the values of myPntAttach and the position <pos> of
463// the symbol when the fixed edge has a geometric support equal
464// to a line.
465//=======================================================================
466
467void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
468 gp_Pnt& pos,
469 Standard_Real& pfirst,
470 Standard_Real& plast)
471{
472 if (myAutomaticPosition) {
81bba717 473 // point of attach is chosen as middle of the segment
7fd59977 474 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
475
476 gp_Dir norm = myPlane ->Axis().Direction();
477
478 norm.Cross(glin.Position().Direction());
479 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
480 myAutomaticPosition = Standard_True;
481 } // if (myAutomaticPosition)
482
483 else {
484 pos = myPosition;
485 Standard_Real linparam = ElCLib::Parameter(glin, pos);
486
81bba717 487 // case if the projection of position is located between 2 vertices
7fd59977 488 // de l'edge
489 if ( (linparam >= pfirst) && (linparam <= plast) )
490 myPntAttach = ElCLib::Value(linparam,glin);
491
81bba717 492 // case if the projection of Position is outside of the limits
493 // of the edge : the point closest to the projection is chosen
494 // as the attach point
7fd59977 495 else {
496 Standard_Real pOnLin;
497 if (linparam > plast)
498 pOnLin = plast;
499 else
500 pOnLin = pfirst;
501 myPntAttach = ElCLib::Value(pOnLin,glin);
502 gp_Dir norm = myPlane->Axis().Direction();
503
504 norm.Cross(glin.Position().Direction());
505 gp_Lin lsup(myPntAttach, norm);
506 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
507 pos = ElCLib::Value(parpos,lsup);
508 }
509
510 }
511 myPosition = pos;
512}
513
514//=======================================================================
515//function : ComputeCirclePosition
516//purpose : compute the values of myPntAttach and the position <pos> of
517// the symbol when the fixed edge has a geometric support equal
518// to a circle.
519//=======================================================================
520
521void AIS_FixRelation::ComputeCirclePosition(
522 const gp_Circ& gcirc,
523 gp_Pnt& pos,
524 Standard_Real& pfirst,
525 Standard_Real& plast)
526{
81bba717 527 // readjust parametres on the circle
c6541a0c
D
528 if (plast > 2*M_PI ) {
529 Standard_Real nbtours = Floor(plast / (2*M_PI));
530 plast -= nbtours*2*M_PI;
531 pfirst -= nbtours*2*M_PI;
7fd59977 532 }
533
534 if (myAutomaticPosition) {
81bba717 535 // the point attach is the "middle" of the segment (relatively
536 // to the parametres of start and end vertices of the edge
7fd59977 537
538 Standard_Real circparam = (pfirst + plast)/2.;
539
540 if ( !InDomain(pfirst,plast,circparam)) {
c6541a0c
D
541 Standard_Real otherpar = circparam + M_PI;
542 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
7fd59977 543 circparam = otherpar;
544 }
545
546 myPntAttach = ElCLib::Value(circparam, gcirc );
547
548 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
549 dir.Normalize();
550 gp_Vec transvec = dir*myArrowSize;
551 pos = myPntAttach.Translated(transvec);
552 myPosition = pos;
553 myAutomaticPosition = Standard_True;
554 } // if (myAutomaticPosition)
555
556 else {
81bba717 557 // case if the projection of myPosition is outside of 2
558 // vertices of the edge. In this case the parameter is readjusted
559 // in the valid part of the circle
7fd59977 560 pos = myPosition;
561
562 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
563
564 if ( !InDomain(pfirst,plast,circparam)) {
c6541a0c
D
565 Standard_Real otherpar = circparam + M_PI;
566 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
7fd59977 567 circparam = otherpar;
568 }
569
570 myPntAttach = ElCLib::Value(circparam,gcirc);
571 }
572}
573
574//=======================================================================
575//function : ConnectedEdges
576//purpose :
577//=======================================================================
578Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
579 const TopoDS_Vertex& V,
580 TopoDS_Edge& E1,
581 TopoDS_Edge& E2)
582{
583 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
584 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
585
586 Standard_Boolean found(Standard_False);
587 TopoDS_Vertex theVertex;
588 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
589 if (vertexMap.FindKey(i).IsSame(V)) {
590 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
591 found = Standard_True;
592 }
593 }
594 if (!found) {
595 E1.Nullify();
596 E2.Nullify();
597 return Standard_False;
598 }
599
600 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
601 if (iterator.More()) {
602 E1 = TopoDS::Edge(iterator.Value());
603 BRepAdaptor_Curve curv(E1);
604 iterator.Next();
605 }
606 else {
607 E1.Nullify();
608 return Standard_False;
609 }
610
611 if (iterator.More()) {
612 E2 = TopoDS::Edge(iterator.Value());
613 BRepAdaptor_Curve curv(E2);
614 iterator.Next();
615 }
616 else {
617 E2.Nullify();
618 return Standard_False;
619 }
620
621 if (iterator.More()) {
622 E1.Nullify();
623 E2.Nullify();
624 return Standard_False;
625 }
626 return Standard_True;
627}