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.
19 #include <AIS_FixRelation.hxx>
20 #include <AIS_Shape.hxx>
21 #include <BRep_Tool.hxx>
22 #include <BRepAdaptor_Curve.hxx>
23 #include <DsgPrs_FixPresentation.hxx>
26 #include <Geom_Circle.hxx>
27 #include <Geom_Curve.hxx>
28 #include <Geom_Line.hxx>
29 #include <Geom_Plane.hxx>
30 #include <Geom_Transformation.hxx>
32 #include <gp_Circ.hxx>
38 #include <Precision.hxx>
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>
44 #include <Standard_DomainError.hxx>
45 #include <Standard_NotImplemented.hxx>
46 #include <Standard_Type.hxx>
47 #include <TColStd_ListIteratorOfListOfTransient.hxx>
48 #include <TopAbs_ShapeEnum.hxx>
50 #include <TopLoc_Location.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>
60 IMPLEMENT_STANDARD_RTTIEXT(AIS_FixRelation,AIS_Relation)
62 static Standard_Boolean InDomain(const Standard_Real fpar,
63 const Standard_Real lpar,
64 const Standard_Real para)
67 return ((para >= fpar) && (para <= lpar));
69 if (para >= (fpar+2*M_PI)) return Standard_True;
70 if (para <= lpar) return Standard_True;
71 return Standard_False;
74 //=======================================================================
75 //function : Constructor
76 //purpose : vertex Fix Relation
77 //=======================================================================
79 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
80 const Handle(Geom_Plane)& aPlane,
81 const TopoDS_Wire& aWire)
87 myAutomaticPosition = Standard_True;
91 //=======================================================================
92 //function : Constructor
93 //purpose : vertex Fix Relation
94 //=======================================================================
96 AIS_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)
106 myPosition = aPosition;
107 SetArrowSize( anArrowSize );
108 myAutomaticPosition = Standard_False;
112 //=======================================================================
113 //function : Constructor
114 //purpose : edge (line or circle) Fix Relation
115 //=======================================================================
117 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
118 const Handle(Geom_Plane)& aPlane)
122 myAutomaticPosition = Standard_True;
126 //=======================================================================
127 //function : Constructor
128 //purpose : edge (line or circle) Fix Relation
129 //=======================================================================
131 AIS_FixRelation::AIS_FixRelation(
132 const TopoDS_Shape& aShape,
133 const Handle(Geom_Plane)& aPlane,
134 const gp_Pnt& aPosition,
135 const Standard_Real anArrowSize)
139 myPosition = aPosition;
140 SetArrowSize( anArrowSize );
141 myAutomaticPosition = Standard_False;
144 //=======================================================================
147 //=======================================================================
149 TopoDS_Wire AIS_FixRelation::Wire()
154 //=======================================================================
157 //=======================================================================
159 void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
165 //=======================================================================
168 //=======================================================================
170 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
171 const Handle(Prs3d_Presentation)& aPresentation,
172 const Standard_Integer)
174 // Calculate position of the symbol and
175 // point of attach of the segment on the shape
177 if (myFShape.ShapeType() == TopAbs_VERTEX)
178 ComputeVertex(TopoDS::Vertex(myFShape), curpos);
179 else if (myFShape.ShapeType() == TopAbs_EDGE)
180 ComputeEdge(TopoDS::Edge(myFShape), curpos);
182 const gp_Dir& nor = myPlane->Axis().Direction();
185 // calculate presentation
186 // definition of the symbol size
187 if( !myArrowSizeIsDefined )
190 //creation of the presentation
191 DsgPrs_FixPresentation::Add(aPresentation,
199 //=======================================================================
201 //purpose : to avoid warning
202 //=======================================================================
204 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
205 const Handle(Prs3d_Presentation)& aPresentation)
207 // throw Standard_NotImplemented("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
208 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
211 //=======================================================================
214 //=======================================================================
216 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
217 const Handle(Geom_Transformation)& aTransformation,
218 const Handle(Prs3d_Presentation)& aPresentation)
220 // throw Standard_NotImplemented("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
221 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
224 //=======================================================================
225 //function : ComputeSelection
227 //=======================================================================
229 void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
230 const Standard_Integer)
232 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
234 // creation of segment sensible for the linked segment
235 // of the shape fixed to symbol 'Fix'
236 Handle(Select3D_SensitiveSegment) seg;
237 seg = new Select3D_SensitiveSegment(own,
240 aSelection->Add(seg);
242 // Creation of the sensible zone of symbol 'Fix'
243 gp_Dir norm = myPlane->Axis().Direction();
245 gp_Vec dirac(myPntAttach,myPosition);
247 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
248 gp_Ax1 ax(myPosition, norm);
249 norac.Rotate(ax, M_PI/8);
251 norac*=(myArrowSize/2);
252 gp_Pnt P1 = myPosition.Translated(norac);
253 gp_Pnt P2 = myPosition.Translated(-norac);
254 seg = new Select3D_SensitiveSegment(own,
257 aSelection->Add(seg);
260 P1 = myPosition.Translated(norac);
261 P2 = myPosition.Translated(-norac);
262 dirac*=(myArrowSize/2);
264 gp_Pnt PL = PF.Translated(dirac);
266 seg = new Select3D_SensitiveSegment(own,
269 aSelection->Add(seg);
273 PL = PF.Translated(dirac);
275 seg = new Select3D_SensitiveSegment(own,
278 aSelection->Add(seg);
280 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
281 PL = PF.Translated(dirac);
283 seg = new Select3D_SensitiveSegment(own,
288 //=======================================================================
289 //function : ComputeVertex
290 //purpose : computes myPntAttach and the position of the presentation
291 // when you fix a vertex
292 //=======================================================================
294 void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
297 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
299 if (myAutomaticPosition) {
300 gp_Pln pln(myPlane->Pln());
301 gp_Dir dir(pln.XAxis().Direction());
302 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
303 curpos = myPntAttach.Translated(transvec);;
305 myAutomaticPosition = Standard_True;
309 //=======================================================================
310 //function : ComputePosition
312 //=======================================================================
314 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv1,
315 const Handle(Geom_Curve)& curv2,
316 const gp_Pnt& firstp1,
317 const gp_Pnt& lastp1,
318 const gp_Pnt& firstp2,
319 const gp_Pnt& lastp2) const
321 //---------------------------------------------------------
322 // calculate the point of attach
323 //---------------------------------------------------------
326 if (curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) || curv2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
327 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv1);
328 if (gcirc.IsNull()) gcirc = Handle(Geom_Circle)::DownCast(curv2);
329 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
330 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
331 curpos = myPntAttach.Translated(transvec);
335 gp_Vec vec1(firstp1,lastp1);
336 gp_Vec vec2(firstp2,lastp2);
338 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
340 Standard_Real conf =Precision::Confusion();
341 if (lastp1.IsEqual(firstp2,conf) || firstp1.IsEqual(lastp2,conf)) dir.SetXYZ(vec1.XYZ() - vec2.XYZ());
342 else dir.SetXYZ(vec1.XYZ() + vec2.XYZ());
343 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
344 curpos = myPntAttach.Translated(transvec);
347 gp_Vec crossvec = vec1.Crossed(vec2);
348 vec1.Cross(crossvec);
350 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
357 //=======================================================================
358 //function : ComputePosition
359 //purpose : Computes the position of the "fix dimension" when the
360 // fixed object is a vertex which is set at the intersection
362 // The "dimension" is in the "middle" of the two edges.
363 //=======================================================================
365 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
366 const gp_Pnt& firstp,
367 const gp_Pnt& lastp) const
369 //---------------------------------------------------------
370 // calculate the point of attach
371 //---------------------------------------------------------
374 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
376 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv);
377 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
378 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
379 curpos = myPntAttach.Translated(transvec);
381 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
384 // gp_Pln pln(Component()->WorkingPlane()->Plane()->GetValue()->Pln());
385 gp_Pln pln(myPlane->Pln());
386 gp_Dir NormPln = pln.Axis().Direction();
387 gp_Vec vec(firstp,lastp);
388 vec.Cross( gp_Vec(NormPln));
390 gp_Vec transvec = vec*myArrowSize;
391 curpos = myPntAttach.Translated(transvec);
392 gp_Ax1 RotAx( myPntAttach, NormPln);
393 curpos.Rotate(RotAx, M_PI/10);
399 //=======================================================================
400 //function : ComputeEdge
401 //purpose : computes myPntAttach and the position of the presentation
402 // when you fix an edge
403 //=======================================================================
405 void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
407 Handle(Geom_Curve) curEdge;
409 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
411 //---------------------------------------------------------
412 // calcul du point de positionnement du symbole 'fix'
413 //---------------------------------------------------------
414 //--> In case of a straight line
415 if (curEdge->IsKind(STANDARD_TYPE(Geom_Line))){
416 gp_Lin glin = Handle(Geom_Line)::DownCast(curEdge)->Lin();
417 Standard_Real pfirst(ElCLib::Parameter(glin,ptbeg));
418 Standard_Real plast(ElCLib::Parameter(glin,ptend));
419 ComputeLinePosition(glin, curpos, pfirst, plast);
422 //--> In case of a circle
423 else if (curEdge->IsKind(STANDARD_TYPE(Geom_Circle))) {
424 gp_Circ gcirc = Handle(Geom_Circle)::DownCast(curEdge)->Circ();
425 Standard_Real pfirst, plast;
426 BRepAdaptor_Curve cu(FixEdge);
427 pfirst = cu.FirstParameter();
428 plast = cu.LastParameter();
429 ComputeCirclePosition(gcirc, curpos, pfirst, plast);
437 //=======================================================================
438 //function : ComputeLinePosition
439 //purpose : compute the values of myPntAttach and the position <pos> of
440 // the symbol when the fixed edge has a geometric support equal
442 //=======================================================================
444 void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
446 Standard_Real& pfirst,
447 Standard_Real& plast)
449 if (myAutomaticPosition) {
450 // point of attach is chosen as middle of the segment
451 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
453 gp_Dir norm = myPlane ->Axis().Direction();
455 norm.Cross(glin.Position().Direction());
456 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
457 myAutomaticPosition = Standard_True;
458 } // if (myAutomaticPosition)
462 Standard_Real linparam = ElCLib::Parameter(glin, pos);
464 // case if the projection of position is located between 2 vertices
466 if ( (linparam >= pfirst) && (linparam <= plast) )
467 myPntAttach = ElCLib::Value(linparam,glin);
469 // case if the projection of Position is outside of the limits
470 // of the edge : the point closest to the projection is chosen
471 // as the attach point
473 Standard_Real pOnLin;
474 if (linparam > plast)
478 myPntAttach = ElCLib::Value(pOnLin,glin);
479 gp_Dir norm = myPlane->Axis().Direction();
481 norm.Cross(glin.Position().Direction());
482 gp_Lin lsup(myPntAttach, norm);
483 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
484 pos = ElCLib::Value(parpos,lsup);
491 //=======================================================================
492 //function : ComputeCirclePosition
493 //purpose : compute the values of myPntAttach and the position <pos> of
494 // the symbol when the fixed edge has a geometric support equal
496 //=======================================================================
498 void AIS_FixRelation::ComputeCirclePosition(
499 const gp_Circ& gcirc,
501 Standard_Real& pfirst,
502 Standard_Real& plast)
504 // readjust parametres on the circle
505 if (plast > 2*M_PI ) {
506 Standard_Real nbtours = Floor(plast / (2*M_PI));
507 plast -= nbtours*2*M_PI;
508 pfirst -= nbtours*2*M_PI;
511 if (myAutomaticPosition) {
512 // the point attach is the "middle" of the segment (relatively
513 // to the parametres of start and end vertices of the edge
515 Standard_Real circparam = (pfirst + plast)/2.;
517 if ( !InDomain(pfirst,plast,circparam)) {
518 Standard_Real otherpar = circparam + M_PI;
519 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
520 circparam = otherpar;
523 myPntAttach = ElCLib::Value(circparam, gcirc );
525 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
527 gp_Vec transvec = dir*myArrowSize;
528 pos = myPntAttach.Translated(transvec);
530 myAutomaticPosition = Standard_True;
531 } // if (myAutomaticPosition)
534 // case if the projection of myPosition is outside of 2
535 // vertices of the edge. In this case the parameter is readjusted
536 // in the valid part of the circle
539 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
541 if ( !InDomain(pfirst,plast,circparam)) {
542 Standard_Real otherpar = circparam + M_PI;
543 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
544 circparam = otherpar;
547 myPntAttach = ElCLib::Value(circparam,gcirc);
551 //=======================================================================
552 //function : ConnectedEdges
554 //=======================================================================
555 Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
556 const TopoDS_Vertex& V,
560 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
561 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
563 Standard_Boolean found(Standard_False);
564 TopoDS_Vertex theVertex;
565 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
566 if (vertexMap.FindKey(i).IsSame(V)) {
567 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
568 found = Standard_True;
574 return Standard_False;
577 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
578 if (iterator.More()) {
579 E1 = TopoDS::Edge(iterator.Value());
580 BRepAdaptor_Curve curv(E1);
585 return Standard_False;
588 if (iterator.More()) {
589 E2 = TopoDS::Edge(iterator.Value());
590 BRepAdaptor_Curve curv(E2);
595 return Standard_False;
598 if (iterator.More()) {
601 return Standard_False;
603 return Standard_True;