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
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.
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.
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.
22 #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size
23 // if any in all dimensions.
25 #include <Standard_NotImplemented.hxx>
27 #include <AIS_FixRelation.ixx>
29 #include <AIS_Shape.hxx>
31 #include <TopAbs_ShapeEnum.hxx>
33 #include <SelectMgr_EntityOwner.hxx>
34 #include <Select3D_SensitiveSegment.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepAdaptor_Curve.hxx>
40 #include <TopoDS_Edge.hxx>
41 #include <TopoDS_Vertex.hxx>
42 #include <TopoDS_Wire.hxx>
44 #include <TopLoc_Location.hxx>
45 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
46 #include <TopTools_IndexedMapOfShape.hxx>
47 #include <TopTools_ListIteratorOfListOfShape.hxx>
49 #include <TColStd_ListIteratorOfListOfTransient.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom_Line.hxx>
53 #include <Geom_Circle.hxx>
54 #include <Geom_Plane.hxx>
65 #include <Precision.hxx>
67 #include <Standard_DomainError.hxx>
69 #include <DsgPrs_FixPresentation.hxx>
73 static Standard_Boolean InDomain(const Standard_Real fpar,
74 const Standard_Real lpar,
75 const Standard_Real para)
78 return ((para >= fpar) && (para <= lpar));
80 if (para >= (fpar+2*M_PI)) return Standard_True;
81 if (para <= lpar) return Standard_True;
82 return Standard_False;
85 //=======================================================================
86 //function : Constructor
87 //purpose : vertex Fix Relation
88 //=======================================================================
90 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
91 const Handle(Geom_Plane)& aPlane,
92 const TopoDS_Wire& aWire)
95 haspos(Standard_False)
99 myAutomaticPosition = Standard_True;
103 //=======================================================================
104 //function : Constructor
105 //purpose : vertex Fix Relation
106 //=======================================================================
108 AIS_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)
115 haspos(Standard_False)
119 myPosition = aPosition;
121 SetArrowSize( anArrowSize );
123 myArrowSize = anArrowSize;
125 myAutomaticPosition = Standard_False;
129 //=======================================================================
130 //function : Constructor
131 //purpose : edge (line or circle) Fix Relation
132 //=======================================================================
134 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
135 const Handle(Geom_Plane)& aPlane):
136 haspos(Standard_False)
140 myAutomaticPosition = Standard_True;
144 //=======================================================================
145 //function : Constructor
146 //purpose : edge (line or circle) Fix Relation
147 //=======================================================================
149 AIS_FixRelation::AIS_FixRelation(
150 const TopoDS_Shape& aShape,
151 const Handle(Geom_Plane)& aPlane,
152 const gp_Pnt& aPosition,
153 const Standard_Real anArrowSize):
154 haspos(Standard_False)
158 myPosition = aPosition;
160 SetArrowSize( anArrowSize );
162 myArrowSize = anArrowSize;
164 myAutomaticPosition = Standard_False;
167 //=======================================================================
170 //=======================================================================
172 TopoDS_Wire AIS_FixRelation::Wire()
177 //=======================================================================
180 //=======================================================================
182 void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
188 //=======================================================================
191 //=======================================================================
193 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
194 const Handle(Prs3d_Presentation)& aPresentation,
195 const Standard_Integer)
197 aPresentation->Clear();
199 // Calculate position of the symbol and
200 // point of attach of the segment on the shape
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);
207 const gp_Dir& nor = myPlane->Axis().Direction();
210 // calculate presentation
211 // definition of the symbol size
213 if( !myArrowSizeIsDefined )
217 //creation of the presentation
218 DsgPrs_FixPresentation::Add(aPresentation,
226 //=======================================================================
228 //purpose : to avoid warning
229 //=======================================================================
231 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
232 const Handle(Prs3d_Presentation)& aPresentation)
234 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
235 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
238 //=======================================================================
240 //purpose : to avoid warning
241 //=======================================================================
243 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
244 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
245 const Standard_Integer anInteger)
247 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
248 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
251 //=======================================================================
254 //=======================================================================
256 void AIS_FixRelation::Compute(const Handle_Prs3d_Projector& aProjector,
257 const Handle_Geom_Transformation& aTransformation,
258 const Handle_Prs3d_Presentation& aPresentation)
260 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
261 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
264 //=======================================================================
265 //function : ComputeSelection
267 //=======================================================================
269 void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
270 const Standard_Integer)
272 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
274 // creation of segment sensible for the linked segment
275 // of the shape fixed to symbol 'Fix'
276 Handle(Select3D_SensitiveSegment) seg;
277 seg = new Select3D_SensitiveSegment(own,
280 aSelection->Add(seg);
282 // Creation of the sensible zone of symbol 'Fix'
283 gp_Dir norm = myPlane->Axis().Direction();
285 gp_Vec dirac(myPntAttach,myPosition);
287 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
288 gp_Ax1 ax(myPosition, norm);
289 norac.Rotate(ax, M_PI/8);
291 norac*=(myArrowSize/2);
292 gp_Pnt P1 = myPosition.Translated(norac);
293 gp_Pnt P2 = myPosition.Translated(-norac);
294 seg = new Select3D_SensitiveSegment(own,
297 aSelection->Add(seg);
300 P1 = myPosition.Translated(norac);
301 P2 = myPosition.Translated(-norac);
302 dirac*=(myArrowSize/2);
304 gp_Pnt PL = PF.Translated(dirac);
306 seg = new Select3D_SensitiveSegment(own,
309 aSelection->Add(seg);
313 PL = PF.Translated(dirac);
315 seg = new Select3D_SensitiveSegment(own,
318 aSelection->Add(seg);
320 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
321 PL = PF.Translated(dirac);
323 seg = new Select3D_SensitiveSegment(own,
328 //=======================================================================
329 //function : ComputeVertex
330 //purpose : computes myPntAttach and the position of the presentation
331 // when you fix a vertex
332 //=======================================================================
334 void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
337 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
339 if (myAutomaticPosition) {
340 gp_Pln pln(myPlane->Pln());
341 gp_Dir dir(pln.XAxis().Direction());
342 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
343 curpos = myPntAttach.Translated(transvec);;
345 myAutomaticPosition = Standard_True;
349 //=======================================================================
350 //function : ComputePosition
352 //=======================================================================
354 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv1,
355 const Handle(Geom_Curve)& curv2,
356 const gp_Pnt& firstp1,
357 const gp_Pnt& lastp1,
358 const gp_Pnt& firstp2,
359 const gp_Pnt& lastp2) const
361 //---------------------------------------------------------
362 // calculate the point of attach
363 //---------------------------------------------------------
366 if (curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) || curv2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
367 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv1);
368 if (gcirc.IsNull()) gcirc = Handle(Geom_Circle)::DownCast(curv2);
369 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
370 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
371 curpos = myPntAttach.Translated(transvec);
375 gp_Vec vec1(firstp1,lastp1);
376 gp_Vec vec2(firstp2,lastp2);
378 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
380 Standard_Real conf =Precision::Confusion();
381 if (lastp1.IsEqual(firstp2,conf) || firstp1.IsEqual(lastp2,conf)) dir.SetXYZ(vec1.XYZ() - vec2.XYZ());
382 else dir.SetXYZ(vec1.XYZ() + vec2.XYZ());
383 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
384 curpos = myPntAttach.Translated(transvec);
387 gp_Vec crossvec = vec1.Crossed(vec2);
388 vec1.Cross(crossvec);
390 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
397 //=======================================================================
398 //function : ComputePosition
399 //purpose : Computes the position of the "fix dimension" when the
400 // fixed object is a vertex which is set at the intersection
402 // The "dimension" is in the "middle" of the two edges.
403 //=======================================================================
405 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
406 const gp_Pnt& firstp,
407 const gp_Pnt& lastp) const
409 //---------------------------------------------------------
410 // calculate the point of attach
411 //---------------------------------------------------------
414 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
416 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv);
417 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
418 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
419 curpos = myPntAttach.Translated(transvec);
421 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
424 // gp_Pln pln(Component()->WorkingPlane()->Plane()->GetValue()->Pln());
425 gp_Pln pln(myPlane->Pln());
426 gp_Dir NormPln = pln.Axis().Direction();
427 gp_Vec vec(firstp,lastp);
428 vec.Cross( gp_Vec(NormPln));
430 gp_Vec transvec = vec*myArrowSize;
431 curpos = myPntAttach.Translated(transvec);
432 gp_Ax1 RotAx( myPntAttach, NormPln);
433 curpos.Rotate(RotAx, M_PI/10);
439 //=======================================================================
440 //function : ComputeEdge
441 //purpose : computes myPntAttach and the position of the presentation
442 // when you fix an edge
443 //=======================================================================
445 void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
447 Handle(Geom_Curve) curEdge;
449 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
451 //---------------------------------------------------------
452 // calcul du point de positionnement du symbole 'fix'
453 //---------------------------------------------------------
454 //--> In case of a straight line
455 if (curEdge->IsKind(STANDARD_TYPE(Geom_Line))){
456 gp_Lin glin = Handle(Geom_Line)::DownCast(curEdge)->Lin();
457 Standard_Real pfirst(ElCLib::Parameter(glin,ptbeg));
458 Standard_Real plast(ElCLib::Parameter(glin,ptend));
459 ComputeLinePosition(glin, curpos, pfirst, plast);
462 //--> In case of a circle
463 else if (curEdge->IsKind(STANDARD_TYPE(Geom_Circle))) {
464 gp_Circ gcirc = Handle(Geom_Circle)::DownCast(curEdge)->Circ();
465 Standard_Real pfirst, plast;
466 BRepAdaptor_Curve cu(FixEdge);
467 pfirst = cu.FirstParameter();
468 plast = cu.LastParameter();
469 ComputeCirclePosition(gcirc, curpos, pfirst, plast);
477 //=======================================================================
478 //function : ComputeLinePosition
479 //purpose : compute the values of myPntAttach and the position <pos> of
480 // the symbol when the fixed edge has a geometric support equal
482 //=======================================================================
484 void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
486 Standard_Real& pfirst,
487 Standard_Real& plast)
489 if (myAutomaticPosition) {
490 // point of attach is chosen as middle of the segment
491 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
493 gp_Dir norm = myPlane ->Axis().Direction();
495 norm.Cross(glin.Position().Direction());
496 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
497 myAutomaticPosition = Standard_True;
498 } // if (myAutomaticPosition)
502 Standard_Real linparam = ElCLib::Parameter(glin, pos);
504 // case if the projection of position is located between 2 vertices
506 if ( (linparam >= pfirst) && (linparam <= plast) )
507 myPntAttach = ElCLib::Value(linparam,glin);
509 // case if the projection of Position is outside of the limits
510 // of the edge : the point closest to the projection is chosen
511 // as the attach point
513 Standard_Real pOnLin;
514 if (linparam > plast)
518 myPntAttach = ElCLib::Value(pOnLin,glin);
519 gp_Dir norm = myPlane->Axis().Direction();
521 norm.Cross(glin.Position().Direction());
522 gp_Lin lsup(myPntAttach, norm);
523 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
524 pos = ElCLib::Value(parpos,lsup);
531 //=======================================================================
532 //function : ComputeCirclePosition
533 //purpose : compute the values of myPntAttach and the position <pos> of
534 // the symbol when the fixed edge has a geometric support equal
536 //=======================================================================
538 void AIS_FixRelation::ComputeCirclePosition(
539 const gp_Circ& gcirc,
541 Standard_Real& pfirst,
542 Standard_Real& plast)
544 // readjust parametres on the circle
545 if (plast > 2*M_PI ) {
546 Standard_Real nbtours = Floor(plast / (2*M_PI));
547 plast -= nbtours*2*M_PI;
548 pfirst -= nbtours*2*M_PI;
551 if (myAutomaticPosition) {
552 // the point attach is the "middle" of the segment (relatively
553 // to the parametres of start and end vertices of the edge
555 Standard_Real circparam = (pfirst + plast)/2.;
557 if ( !InDomain(pfirst,plast,circparam)) {
558 Standard_Real otherpar = circparam + M_PI;
559 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
560 circparam = otherpar;
563 myPntAttach = ElCLib::Value(circparam, gcirc );
565 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
567 gp_Vec transvec = dir*myArrowSize;
568 pos = myPntAttach.Translated(transvec);
570 myAutomaticPosition = Standard_True;
571 } // if (myAutomaticPosition)
574 // case if the projection of myPosition is outside of 2
575 // vertices of the edge. In this case the parameter is readjusted
576 // in the valid part of the circle
579 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
581 if ( !InDomain(pfirst,plast,circparam)) {
582 Standard_Real otherpar = circparam + M_PI;
583 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
584 circparam = otherpar;
587 myPntAttach = ElCLib::Value(circparam,gcirc);
591 //=======================================================================
592 //function : ConnectedEdges
594 //=======================================================================
595 Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
596 const TopoDS_Vertex& V,
600 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
601 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
603 Standard_Boolean found(Standard_False);
604 TopoDS_Vertex theVertex;
605 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
606 if (vertexMap.FindKey(i).IsSame(V)) {
607 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
608 found = Standard_True;
614 return Standard_False;
617 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
618 if (iterator.More()) {
619 E1 = TopoDS::Edge(iterator.Value());
620 BRepAdaptor_Curve curv(E1);
625 return Standard_False;
628 if (iterator.More()) {
629 E2 = TopoDS::Edge(iterator.Value());
630 BRepAdaptor_Curve curv(E2);
635 return Standard_False;
638 if (iterator.More()) {
641 return Standard_False;
643 return Standard_True;