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)
98 myAutomaticPosition = Standard_True;
102 //=======================================================================
103 //function : Constructor
104 //purpose : vertex Fix Relation
105 //=======================================================================
107 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
108 const Handle(Geom_Plane)& aPlane,
109 const TopoDS_Wire& aWire,
110 const gp_Pnt& aPosition,
111 const Standard_Real anArrowSize)
117 myPosition = aPosition;
119 SetArrowSize( anArrowSize );
121 myArrowSize = anArrowSize;
123 myAutomaticPosition = Standard_False;
127 //=======================================================================
128 //function : Constructor
129 //purpose : edge (line or circle) Fix Relation
130 //=======================================================================
132 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
133 const Handle(Geom_Plane)& aPlane)
137 myAutomaticPosition = Standard_True;
141 //=======================================================================
142 //function : Constructor
143 //purpose : edge (line or circle) Fix Relation
144 //=======================================================================
146 AIS_FixRelation::AIS_FixRelation(
147 const TopoDS_Shape& aShape,
148 const Handle(Geom_Plane)& aPlane,
149 const gp_Pnt& aPosition,
150 const Standard_Real anArrowSize)
154 myPosition = aPosition;
156 SetArrowSize( anArrowSize );
158 myArrowSize = anArrowSize;
160 myAutomaticPosition = Standard_False;
163 //=======================================================================
166 //=======================================================================
168 TopoDS_Wire AIS_FixRelation::Wire()
173 //=======================================================================
176 //=======================================================================
178 void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
184 //=======================================================================
187 //=======================================================================
189 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
190 const Handle(Prs3d_Presentation)& aPresentation,
191 const Standard_Integer)
193 aPresentation->Clear();
195 // Calculate position of the symbol and
196 // point of attach of the segment on the shape
198 if (myFShape.ShapeType() == TopAbs_VERTEX)
199 ComputeVertex(TopoDS::Vertex(myFShape), curpos);
200 else if (myFShape.ShapeType() == TopAbs_EDGE)
201 ComputeEdge(TopoDS::Edge(myFShape), curpos);
203 const gp_Dir& nor = myPlane->Axis().Direction();
206 // calculate presentation
207 // definition of the symbol size
209 if( !myArrowSizeIsDefined )
213 //creation of the presentation
214 DsgPrs_FixPresentation::Add(aPresentation,
222 //=======================================================================
224 //purpose : to avoid warning
225 //=======================================================================
227 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
228 const Handle(Prs3d_Presentation)& aPresentation)
230 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
231 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
234 //=======================================================================
237 //=======================================================================
239 void AIS_FixRelation::Compute(const Handle_Prs3d_Projector& aProjector,
240 const Handle_Geom_Transformation& aTransformation,
241 const Handle_Prs3d_Presentation& aPresentation)
243 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
244 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
247 //=======================================================================
248 //function : ComputeSelection
250 //=======================================================================
252 void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
253 const Standard_Integer)
255 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
257 // creation of segment sensible for the linked segment
258 // of the shape fixed to symbol 'Fix'
259 Handle(Select3D_SensitiveSegment) seg;
260 seg = new Select3D_SensitiveSegment(own,
263 aSelection->Add(seg);
265 // Creation of the sensible zone of symbol 'Fix'
266 gp_Dir norm = myPlane->Axis().Direction();
268 gp_Vec dirac(myPntAttach,myPosition);
270 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
271 gp_Ax1 ax(myPosition, norm);
272 norac.Rotate(ax, M_PI/8);
274 norac*=(myArrowSize/2);
275 gp_Pnt P1 = myPosition.Translated(norac);
276 gp_Pnt P2 = myPosition.Translated(-norac);
277 seg = new Select3D_SensitiveSegment(own,
280 aSelection->Add(seg);
283 P1 = myPosition.Translated(norac);
284 P2 = myPosition.Translated(-norac);
285 dirac*=(myArrowSize/2);
287 gp_Pnt PL = PF.Translated(dirac);
289 seg = new Select3D_SensitiveSegment(own,
292 aSelection->Add(seg);
296 PL = PF.Translated(dirac);
298 seg = new Select3D_SensitiveSegment(own,
301 aSelection->Add(seg);
303 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
304 PL = PF.Translated(dirac);
306 seg = new Select3D_SensitiveSegment(own,
311 //=======================================================================
312 //function : ComputeVertex
313 //purpose : computes myPntAttach and the position of the presentation
314 // when you fix a vertex
315 //=======================================================================
317 void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
320 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
322 if (myAutomaticPosition) {
323 gp_Pln pln(myPlane->Pln());
324 gp_Dir dir(pln.XAxis().Direction());
325 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
326 curpos = myPntAttach.Translated(transvec);;
328 myAutomaticPosition = Standard_True;
332 //=======================================================================
333 //function : ComputePosition
335 //=======================================================================
337 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv1,
338 const Handle(Geom_Curve)& curv2,
339 const gp_Pnt& firstp1,
340 const gp_Pnt& lastp1,
341 const gp_Pnt& firstp2,
342 const gp_Pnt& lastp2) const
344 //---------------------------------------------------------
345 // calculate the point of attach
346 //---------------------------------------------------------
349 if (curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) || curv2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
350 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv1);
351 if (gcirc.IsNull()) gcirc = Handle(Geom_Circle)::DownCast(curv2);
352 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
353 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
354 curpos = myPntAttach.Translated(transvec);
358 gp_Vec vec1(firstp1,lastp1);
359 gp_Vec vec2(firstp2,lastp2);
361 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
363 Standard_Real conf =Precision::Confusion();
364 if (lastp1.IsEqual(firstp2,conf) || firstp1.IsEqual(lastp2,conf)) dir.SetXYZ(vec1.XYZ() - vec2.XYZ());
365 else dir.SetXYZ(vec1.XYZ() + vec2.XYZ());
366 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
367 curpos = myPntAttach.Translated(transvec);
370 gp_Vec crossvec = vec1.Crossed(vec2);
371 vec1.Cross(crossvec);
373 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
380 //=======================================================================
381 //function : ComputePosition
382 //purpose : Computes the position of the "fix dimension" when the
383 // fixed object is a vertex which is set at the intersection
385 // The "dimension" is in the "middle" of the two edges.
386 //=======================================================================
388 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
389 const gp_Pnt& firstp,
390 const gp_Pnt& lastp) const
392 //---------------------------------------------------------
393 // calculate the point of attach
394 //---------------------------------------------------------
397 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
399 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv);
400 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
401 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
402 curpos = myPntAttach.Translated(transvec);
404 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
407 // gp_Pln pln(Component()->WorkingPlane()->Plane()->GetValue()->Pln());
408 gp_Pln pln(myPlane->Pln());
409 gp_Dir NormPln = pln.Axis().Direction();
410 gp_Vec vec(firstp,lastp);
411 vec.Cross( gp_Vec(NormPln));
413 gp_Vec transvec = vec*myArrowSize;
414 curpos = myPntAttach.Translated(transvec);
415 gp_Ax1 RotAx( myPntAttach, NormPln);
416 curpos.Rotate(RotAx, M_PI/10);
422 //=======================================================================
423 //function : ComputeEdge
424 //purpose : computes myPntAttach and the position of the presentation
425 // when you fix an edge
426 //=======================================================================
428 void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
430 Handle(Geom_Curve) curEdge;
432 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
434 //---------------------------------------------------------
435 // calcul du point de positionnement du symbole 'fix'
436 //---------------------------------------------------------
437 //--> In case of a straight line
438 if (curEdge->IsKind(STANDARD_TYPE(Geom_Line))){
439 gp_Lin glin = Handle(Geom_Line)::DownCast(curEdge)->Lin();
440 Standard_Real pfirst(ElCLib::Parameter(glin,ptbeg));
441 Standard_Real plast(ElCLib::Parameter(glin,ptend));
442 ComputeLinePosition(glin, curpos, pfirst, plast);
445 //--> In case of a circle
446 else if (curEdge->IsKind(STANDARD_TYPE(Geom_Circle))) {
447 gp_Circ gcirc = Handle(Geom_Circle)::DownCast(curEdge)->Circ();
448 Standard_Real pfirst, plast;
449 BRepAdaptor_Curve cu(FixEdge);
450 pfirst = cu.FirstParameter();
451 plast = cu.LastParameter();
452 ComputeCirclePosition(gcirc, curpos, pfirst, plast);
460 //=======================================================================
461 //function : ComputeLinePosition
462 //purpose : compute the values of myPntAttach and the position <pos> of
463 // the symbol when the fixed edge has a geometric support equal
465 //=======================================================================
467 void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
469 Standard_Real& pfirst,
470 Standard_Real& plast)
472 if (myAutomaticPosition) {
473 // point of attach is chosen as middle of the segment
474 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
476 gp_Dir norm = myPlane ->Axis().Direction();
478 norm.Cross(glin.Position().Direction());
479 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
480 myAutomaticPosition = Standard_True;
481 } // if (myAutomaticPosition)
485 Standard_Real linparam = ElCLib::Parameter(glin, pos);
487 // case if the projection of position is located between 2 vertices
489 if ( (linparam >= pfirst) && (linparam <= plast) )
490 myPntAttach = ElCLib::Value(linparam,glin);
492 // case if the projection of Position is outside of the limits
493 // of the edge : the point closest to the projection is chosen
494 // as the attach point
496 Standard_Real pOnLin;
497 if (linparam > plast)
501 myPntAttach = ElCLib::Value(pOnLin,glin);
502 gp_Dir norm = myPlane->Axis().Direction();
504 norm.Cross(glin.Position().Direction());
505 gp_Lin lsup(myPntAttach, norm);
506 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
507 pos = ElCLib::Value(parpos,lsup);
514 //=======================================================================
515 //function : ComputeCirclePosition
516 //purpose : compute the values of myPntAttach and the position <pos> of
517 // the symbol when the fixed edge has a geometric support equal
519 //=======================================================================
521 void AIS_FixRelation::ComputeCirclePosition(
522 const gp_Circ& gcirc,
524 Standard_Real& pfirst,
525 Standard_Real& plast)
527 // readjust parametres on the circle
528 if (plast > 2*M_PI ) {
529 Standard_Real nbtours = Floor(plast / (2*M_PI));
530 plast -= nbtours*2*M_PI;
531 pfirst -= nbtours*2*M_PI;
534 if (myAutomaticPosition) {
535 // the point attach is the "middle" of the segment (relatively
536 // to the parametres of start and end vertices of the edge
538 Standard_Real circparam = (pfirst + plast)/2.;
540 if ( !InDomain(pfirst,plast,circparam)) {
541 Standard_Real otherpar = circparam + M_PI;
542 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
543 circparam = otherpar;
546 myPntAttach = ElCLib::Value(circparam, gcirc );
548 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
550 gp_Vec transvec = dir*myArrowSize;
551 pos = myPntAttach.Translated(transvec);
553 myAutomaticPosition = Standard_True;
554 } // if (myAutomaticPosition)
557 // case if the projection of myPosition is outside of 2
558 // vertices of the edge. In this case the parameter is readjusted
559 // in the valid part of the circle
562 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
564 if ( !InDomain(pfirst,plast,circparam)) {
565 Standard_Real otherpar = circparam + M_PI;
566 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
567 circparam = otherpar;
570 myPntAttach = ElCLib::Value(circparam,gcirc);
574 //=======================================================================
575 //function : ConnectedEdges
577 //=======================================================================
578 Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
579 const TopoDS_Vertex& V,
583 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
584 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
586 Standard_Boolean found(Standard_False);
587 TopoDS_Vertex theVertex;
588 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
589 if (vertexMap.FindKey(i).IsSame(V)) {
590 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
591 found = Standard_True;
597 return Standard_False;
600 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
601 if (iterator.More()) {
602 E1 = TopoDS::Edge(iterator.Value());
603 BRepAdaptor_Curve curv(E1);
608 return Standard_False;
611 if (iterator.More()) {
612 E2 = TopoDS::Edge(iterator.Value());
613 BRepAdaptor_Curve curv(E2);
618 return Standard_False;
621 if (iterator.More()) {
624 return Standard_False;
626 return Standard_True;