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