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