1 // Created on: 1996-12-05
2 // Created by: Flore Lantheaume/Odile Olivier
3 // Copyright (c) 1996-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
18 // if any in all dimensions.
20 #include <Standard_NotImplemented.hxx>
22 #include <AIS_FixRelation.ixx>
24 #include <AIS_Shape.hxx>
26 #include <TopAbs_ShapeEnum.hxx>
28 #include <SelectMgr_EntityOwner.hxx>
29 #include <Select3D_SensitiveSegment.hxx>
31 #include <BRep_Tool.hxx>
32 #include <BRepAdaptor_Curve.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Vertex.hxx>
37 #include <TopoDS_Wire.hxx>
39 #include <TopLoc_Location.hxx>
40 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
41 #include <TopTools_IndexedMapOfShape.hxx>
42 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TColStd_ListIteratorOfListOfTransient.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Line.hxx>
48 #include <Geom_Circle.hxx>
49 #include <Geom_Plane.hxx>
60 #include <Precision.hxx>
62 #include <Standard_DomainError.hxx>
64 #include <DsgPrs_FixPresentation.hxx>
68 static Standard_Boolean InDomain(const Standard_Real fpar,
69 const Standard_Real lpar,
70 const Standard_Real para)
73 return ((para >= fpar) && (para <= lpar));
75 if (para >= (fpar+2*M_PI)) return Standard_True;
76 if (para <= lpar) return Standard_True;
77 return Standard_False;
80 //=======================================================================
81 //function : Constructor
82 //purpose : vertex Fix Relation
83 //=======================================================================
85 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
86 const Handle(Geom_Plane)& aPlane,
87 const TopoDS_Wire& aWire)
93 myAutomaticPosition = Standard_True;
97 //=======================================================================
98 //function : Constructor
99 //purpose : vertex Fix Relation
100 //=======================================================================
102 AIS_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)
112 myPosition = aPosition;
114 SetArrowSize( anArrowSize );
116 myArrowSize = anArrowSize;
118 myAutomaticPosition = Standard_False;
122 //=======================================================================
123 //function : Constructor
124 //purpose : edge (line or circle) Fix Relation
125 //=======================================================================
127 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
128 const Handle(Geom_Plane)& aPlane)
132 myAutomaticPosition = Standard_True;
136 //=======================================================================
137 //function : Constructor
138 //purpose : edge (line or circle) Fix Relation
139 //=======================================================================
141 AIS_FixRelation::AIS_FixRelation(
142 const TopoDS_Shape& aShape,
143 const Handle(Geom_Plane)& aPlane,
144 const gp_Pnt& aPosition,
145 const Standard_Real anArrowSize)
149 myPosition = aPosition;
151 SetArrowSize( anArrowSize );
153 myArrowSize = anArrowSize;
155 myAutomaticPosition = Standard_False;
158 //=======================================================================
161 //=======================================================================
163 TopoDS_Wire AIS_FixRelation::Wire()
168 //=======================================================================
171 //=======================================================================
173 void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
179 //=======================================================================
182 //=======================================================================
184 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
185 const Handle(Prs3d_Presentation)& aPresentation,
186 const Standard_Integer)
188 aPresentation->Clear();
190 // Calculate position of the symbol and
191 // point of attach of the segment on the shape
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);
198 const gp_Dir& nor = myPlane->Axis().Direction();
201 // calculate presentation
202 // definition of the symbol size
204 if( !myArrowSizeIsDefined )
208 //creation of the presentation
209 DsgPrs_FixPresentation::Add(aPresentation,
217 //=======================================================================
219 //purpose : to avoid warning
220 //=======================================================================
222 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
223 const Handle(Prs3d_Presentation)& aPresentation)
225 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
226 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
229 //=======================================================================
232 //=======================================================================
234 void AIS_FixRelation::Compute(const Handle_Prs3d_Projector& aProjector,
235 const Handle_Geom_Transformation& aTransformation,
236 const Handle_Prs3d_Presentation& aPresentation)
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 ) ;
242 //=======================================================================
243 //function : ComputeSelection
245 //=======================================================================
247 void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
248 const Standard_Integer)
250 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
252 // creation of segment sensible for the linked segment
253 // of the shape fixed to symbol 'Fix'
254 Handle(Select3D_SensitiveSegment) seg;
255 seg = new Select3D_SensitiveSegment(own,
258 aSelection->Add(seg);
260 // Creation of the sensible zone of symbol 'Fix'
261 gp_Dir norm = myPlane->Axis().Direction();
263 gp_Vec dirac(myPntAttach,myPosition);
265 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
266 gp_Ax1 ax(myPosition, norm);
267 norac.Rotate(ax, M_PI/8);
269 norac*=(myArrowSize/2);
270 gp_Pnt P1 = myPosition.Translated(norac);
271 gp_Pnt P2 = myPosition.Translated(-norac);
272 seg = new Select3D_SensitiveSegment(own,
275 aSelection->Add(seg);
278 P1 = myPosition.Translated(norac);
279 P2 = myPosition.Translated(-norac);
280 dirac*=(myArrowSize/2);
282 gp_Pnt PL = PF.Translated(dirac);
284 seg = new Select3D_SensitiveSegment(own,
287 aSelection->Add(seg);
291 PL = PF.Translated(dirac);
293 seg = new Select3D_SensitiveSegment(own,
296 aSelection->Add(seg);
298 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
299 PL = PF.Translated(dirac);
301 seg = new Select3D_SensitiveSegment(own,
306 //=======================================================================
307 //function : ComputeVertex
308 //purpose : computes myPntAttach and the position of the presentation
309 // when you fix a vertex
310 //=======================================================================
312 void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
315 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
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);;
323 myAutomaticPosition = Standard_True;
327 //=======================================================================
328 //function : ComputePosition
330 //=======================================================================
332 gp_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
339 //---------------------------------------------------------
340 // calculate the point of attach
341 //---------------------------------------------------------
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);
353 gp_Vec vec1(firstp1,lastp1);
354 gp_Vec vec2(firstp2,lastp2);
356 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
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);
365 gp_Vec crossvec = vec1.Crossed(vec2);
366 vec1.Cross(crossvec);
368 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
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
380 // The "dimension" is in the "middle" of the two edges.
381 //=======================================================================
383 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
384 const gp_Pnt& firstp,
385 const gp_Pnt& lastp) const
387 //---------------------------------------------------------
388 // calculate the point of attach
389 //---------------------------------------------------------
392 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
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);
399 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
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));
408 gp_Vec transvec = vec*myArrowSize;
409 curpos = myPntAttach.Translated(transvec);
410 gp_Ax1 RotAx( myPntAttach, NormPln);
411 curpos.Rotate(RotAx, M_PI/10);
417 //=======================================================================
418 //function : ComputeEdge
419 //purpose : computes myPntAttach and the position of the presentation
420 // when you fix an edge
421 //=======================================================================
423 void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
425 Handle(Geom_Curve) curEdge;
427 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
429 //---------------------------------------------------------
430 // calcul du point de positionnement du symbole 'fix'
431 //---------------------------------------------------------
432 //--> In case of a straight line
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);
440 //--> In case of a circle
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);
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
460 //=======================================================================
462 void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
464 Standard_Real& pfirst,
465 Standard_Real& plast)
467 if (myAutomaticPosition) {
468 // point of attach is chosen as middle of the segment
469 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
471 gp_Dir norm = myPlane ->Axis().Direction();
473 norm.Cross(glin.Position().Direction());
474 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
475 myAutomaticPosition = Standard_True;
476 } // if (myAutomaticPosition)
480 Standard_Real linparam = ElCLib::Parameter(glin, pos);
482 // case if the projection of position is located between 2 vertices
484 if ( (linparam >= pfirst) && (linparam <= plast) )
485 myPntAttach = ElCLib::Value(linparam,glin);
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
491 Standard_Real pOnLin;
492 if (linparam > plast)
496 myPntAttach = ElCLib::Value(pOnLin,glin);
497 gp_Dir norm = myPlane->Axis().Direction();
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);
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
514 //=======================================================================
516 void AIS_FixRelation::ComputeCirclePosition(
517 const gp_Circ& gcirc,
519 Standard_Real& pfirst,
520 Standard_Real& plast)
522 // readjust parametres on the circle
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;
529 if (myAutomaticPosition) {
530 // the point attach is the "middle" of the segment (relatively
531 // to the parametres of start and end vertices of the edge
533 Standard_Real circparam = (pfirst + plast)/2.;
535 if ( !InDomain(pfirst,plast,circparam)) {
536 Standard_Real otherpar = circparam + M_PI;
537 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
538 circparam = otherpar;
541 myPntAttach = ElCLib::Value(circparam, gcirc );
543 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
545 gp_Vec transvec = dir*myArrowSize;
546 pos = myPntAttach.Translated(transvec);
548 myAutomaticPosition = Standard_True;
549 } // if (myAutomaticPosition)
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
557 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
559 if ( !InDomain(pfirst,plast,circparam)) {
560 Standard_Real otherpar = circparam + M_PI;
561 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
562 circparam = otherpar;
565 myPntAttach = ElCLib::Value(circparam,gcirc);
569 //=======================================================================
570 //function : ConnectedEdges
572 //=======================================================================
573 Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
574 const TopoDS_Vertex& V,
578 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
579 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
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;
592 return Standard_False;
595 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
596 if (iterator.More()) {
597 E1 = TopoDS::Edge(iterator.Value());
598 BRepAdaptor_Curve curv(E1);
603 return Standard_False;
606 if (iterator.More()) {
607 E2 = TopoDS::Edge(iterator.Value());
608 BRepAdaptor_Curve curv(E2);
613 return Standard_False;
616 if (iterator.More()) {
619 return Standard_False;
621 return Standard_True;