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