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 #include <Standard_NotImplemented.hxx>
19 #include <AIS_FixRelation.ixx>
21 #include <AIS_Shape.hxx>
23 #include <TopAbs_ShapeEnum.hxx>
25 #include <SelectMgr_EntityOwner.hxx>
26 #include <Select3D_SensitiveSegment.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRepAdaptor_Curve.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Vertex.hxx>
34 #include <TopoDS_Wire.hxx>
36 #include <TopLoc_Location.hxx>
37 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
38 #include <TopTools_IndexedMapOfShape.hxx>
39 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TColStd_ListIteratorOfListOfTransient.hxx>
43 #include <Geom_Curve.hxx>
44 #include <Geom_Line.hxx>
45 #include <Geom_Circle.hxx>
46 #include <Geom_Plane.hxx>
57 #include <Precision.hxx>
59 #include <Standard_DomainError.hxx>
61 #include <DsgPrs_FixPresentation.hxx>
65 static Standard_Boolean InDomain(const Standard_Real fpar,
66 const Standard_Real lpar,
67 const Standard_Real para)
70 return ((para >= fpar) && (para <= lpar));
72 if (para >= (fpar+2*M_PI)) return Standard_True;
73 if (para <= lpar) return Standard_True;
74 return Standard_False;
77 //=======================================================================
78 //function : Constructor
79 //purpose : vertex Fix Relation
80 //=======================================================================
82 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
83 const Handle(Geom_Plane)& aPlane,
84 const TopoDS_Wire& aWire)
90 myAutomaticPosition = Standard_True;
94 //=======================================================================
95 //function : Constructor
96 //purpose : vertex Fix Relation
97 //=======================================================================
99 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
100 const Handle(Geom_Plane)& aPlane,
101 const TopoDS_Wire& aWire,
102 const gp_Pnt& aPosition,
103 const Standard_Real anArrowSize)
109 myPosition = aPosition;
110 SetArrowSize( anArrowSize );
111 myAutomaticPosition = Standard_False;
115 //=======================================================================
116 //function : Constructor
117 //purpose : edge (line or circle) Fix Relation
118 //=======================================================================
120 AIS_FixRelation::AIS_FixRelation(const TopoDS_Shape& aShape,
121 const Handle(Geom_Plane)& aPlane)
125 myAutomaticPosition = Standard_True;
129 //=======================================================================
130 //function : Constructor
131 //purpose : edge (line or circle) Fix Relation
132 //=======================================================================
134 AIS_FixRelation::AIS_FixRelation(
135 const TopoDS_Shape& aShape,
136 const Handle(Geom_Plane)& aPlane,
137 const gp_Pnt& aPosition,
138 const Standard_Real anArrowSize)
142 myPosition = aPosition;
143 SetArrowSize( anArrowSize );
144 myAutomaticPosition = Standard_False;
147 //=======================================================================
150 //=======================================================================
152 TopoDS_Wire AIS_FixRelation::Wire()
157 //=======================================================================
160 //=======================================================================
162 void AIS_FixRelation::SetWire(const TopoDS_Wire& aWire)
168 //=======================================================================
171 //=======================================================================
173 void AIS_FixRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
174 const Handle(Prs3d_Presentation)& aPresentation,
175 const Standard_Integer)
177 aPresentation->Clear();
179 // Calculate position of the symbol and
180 // point of attach of the segment on the shape
182 if (myFShape.ShapeType() == TopAbs_VERTEX)
183 ComputeVertex(TopoDS::Vertex(myFShape), curpos);
184 else if (myFShape.ShapeType() == TopAbs_EDGE)
185 ComputeEdge(TopoDS::Edge(myFShape), curpos);
187 const gp_Dir& nor = myPlane->Axis().Direction();
190 // calculate presentation
191 // definition of the symbol size
192 if( !myArrowSizeIsDefined )
195 //creation of the presentation
196 DsgPrs_FixPresentation::Add(aPresentation,
204 //=======================================================================
206 //purpose : to avoid warning
207 //=======================================================================
209 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
210 const Handle(Prs3d_Presentation)& aPresentation)
212 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
213 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
216 //=======================================================================
219 //=======================================================================
221 void AIS_FixRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
222 const Handle(Geom_Transformation)& aTransformation,
223 const Handle(Prs3d_Presentation)& aPresentation)
225 // Standard_NotImplemented::Raise("AIS_FixRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)");
226 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
229 //=======================================================================
230 //function : ComputeSelection
232 //=======================================================================
234 void AIS_FixRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
235 const Standard_Integer)
237 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
239 // creation of segment sensible for the linked segment
240 // of the shape fixed to symbol 'Fix'
241 Handle(Select3D_SensitiveSegment) seg;
242 seg = new Select3D_SensitiveSegment(own,
245 aSelection->Add(seg);
247 // Creation of the sensible zone of symbol 'Fix'
248 gp_Dir norm = myPlane->Axis().Direction();
250 gp_Vec dirac(myPntAttach,myPosition);
252 gp_Vec norac = dirac.Crossed(gp_Vec(norm));
253 gp_Ax1 ax(myPosition, norm);
254 norac.Rotate(ax, M_PI/8);
256 norac*=(myArrowSize/2);
257 gp_Pnt P1 = myPosition.Translated(norac);
258 gp_Pnt P2 = myPosition.Translated(-norac);
259 seg = new Select3D_SensitiveSegment(own,
262 aSelection->Add(seg);
265 P1 = myPosition.Translated(norac);
266 P2 = myPosition.Translated(-norac);
267 dirac*=(myArrowSize/2);
269 gp_Pnt PL = PF.Translated(dirac);
271 seg = new Select3D_SensitiveSegment(own,
274 aSelection->Add(seg);
278 PL = PF.Translated(dirac);
280 seg = new Select3D_SensitiveSegment(own,
283 aSelection->Add(seg);
285 PF.SetXYZ( (P1.XYZ() + P2.XYZ()) /2 );
286 PL = PF.Translated(dirac);
288 seg = new Select3D_SensitiveSegment(own,
293 //=======================================================================
294 //function : ComputeVertex
295 //purpose : computes myPntAttach and the position of the presentation
296 // when you fix a vertex
297 //=======================================================================
299 void AIS_FixRelation::ComputeVertex(const TopoDS_Vertex& /*FixVertex*/,
302 myPntAttach = BRep_Tool::Pnt(TopoDS::Vertex(myFShape));
304 if (myAutomaticPosition) {
305 gp_Pln pln(myPlane->Pln());
306 gp_Dir dir(pln.XAxis().Direction());
307 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
308 curpos = myPntAttach.Translated(transvec);;
310 myAutomaticPosition = Standard_True;
314 //=======================================================================
315 //function : ComputePosition
317 //=======================================================================
319 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv1,
320 const Handle(Geom_Curve)& curv2,
321 const gp_Pnt& firstp1,
322 const gp_Pnt& lastp1,
323 const gp_Pnt& firstp2,
324 const gp_Pnt& lastp2) const
326 //---------------------------------------------------------
327 // calculate the point of attach
328 //---------------------------------------------------------
331 if (curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) || curv2->IsInstance(STANDARD_TYPE(Geom_Circle))) {
332 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv1);
333 if (gcirc.IsNull()) gcirc = Handle(Geom_Circle)::DownCast(curv2);
334 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
335 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
336 curpos = myPntAttach.Translated(transvec);
340 gp_Vec vec1(firstp1,lastp1);
341 gp_Vec vec2(firstp2,lastp2);
343 if (!vec1.IsParallel(vec2, Precision::Angular()) ) {
345 Standard_Real conf =Precision::Confusion();
346 if (lastp1.IsEqual(firstp2,conf) || firstp1.IsEqual(lastp2,conf)) dir.SetXYZ(vec1.XYZ() - vec2.XYZ());
347 else dir.SetXYZ(vec1.XYZ() + vec2.XYZ());
348 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
349 curpos = myPntAttach.Translated(transvec);
352 gp_Vec crossvec = vec1.Crossed(vec2);
353 vec1.Cross(crossvec);
355 curpos = myPntAttach.Translated(gp_Vec(dir)*myArrowSize);
362 //=======================================================================
363 //function : ComputePosition
364 //purpose : Computes the position of the "fix dimension" when the
365 // fixed object is a vertex which is set at the intersection
367 // The "dimension" is in the "middle" of the two edges.
368 //=======================================================================
370 gp_Pnt AIS_FixRelation::ComputePosition(const Handle(Geom_Curve)& curv,
371 const gp_Pnt& firstp,
372 const gp_Pnt& lastp) const
374 //---------------------------------------------------------
375 // calculate the point of attach
376 //---------------------------------------------------------
379 if (curv->IsKind(STANDARD_TYPE(Geom_Circle))) {
381 Handle(Geom_Circle) gcirc = Handle(Geom_Circle)::DownCast(curv);
382 gp_Dir dir( gcirc->Location().XYZ() + myPntAttach.XYZ() );
383 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
384 curpos = myPntAttach.Translated(transvec);
386 } //if (curv->IsKind(STANDARD_TYPE(Geom_Circle))
389 // gp_Pln pln(Component()->WorkingPlane()->Plane()->GetValue()->Pln());
390 gp_Pln pln(myPlane->Pln());
391 gp_Dir NormPln = pln.Axis().Direction();
392 gp_Vec vec(firstp,lastp);
393 vec.Cross( gp_Vec(NormPln));
395 gp_Vec transvec = vec*myArrowSize;
396 curpos = myPntAttach.Translated(transvec);
397 gp_Ax1 RotAx( myPntAttach, NormPln);
398 curpos.Rotate(RotAx, M_PI/10);
404 //=======================================================================
405 //function : ComputeEdge
406 //purpose : computes myPntAttach and the position of the presentation
407 // when you fix an edge
408 //=======================================================================
410 void AIS_FixRelation::ComputeEdge(const TopoDS_Edge& FixEdge, gp_Pnt& curpos)
412 Handle(Geom_Curve) curEdge;
414 if (!AIS::ComputeGeometry(FixEdge,curEdge,ptbeg,ptend)) return;
416 //---------------------------------------------------------
417 // calcul du point de positionnement du symbole 'fix'
418 //---------------------------------------------------------
419 //--> In case of a straight line
420 if (curEdge->IsKind(STANDARD_TYPE(Geom_Line))){
421 gp_Lin glin = Handle(Geom_Line)::DownCast(curEdge)->Lin();
422 Standard_Real pfirst(ElCLib::Parameter(glin,ptbeg));
423 Standard_Real plast(ElCLib::Parameter(glin,ptend));
424 ComputeLinePosition(glin, curpos, pfirst, plast);
427 //--> In case of a circle
428 else if (curEdge->IsKind(STANDARD_TYPE(Geom_Circle))) {
429 gp_Circ gcirc = Handle(Geom_Circle)::DownCast(curEdge)->Circ();
430 Standard_Real pfirst, plast;
431 BRepAdaptor_Curve cu(FixEdge);
432 pfirst = cu.FirstParameter();
433 plast = cu.LastParameter();
434 ComputeCirclePosition(gcirc, curpos, pfirst, plast);
442 //=======================================================================
443 //function : ComputeLinePosition
444 //purpose : compute the values of myPntAttach and the position <pos> of
445 // the symbol when the fixed edge has a geometric support equal
447 //=======================================================================
449 void AIS_FixRelation::ComputeLinePosition(const gp_Lin& glin,
451 Standard_Real& pfirst,
452 Standard_Real& plast)
454 if (myAutomaticPosition) {
455 // point of attach is chosen as middle of the segment
456 myPntAttach = ElCLib::Value((pfirst+ plast)/2, glin);
458 gp_Dir norm = myPlane ->Axis().Direction();
460 norm.Cross(glin.Position().Direction());
461 pos = myPntAttach.Translated(gp_Vec(norm)*myArrowSize);
462 myAutomaticPosition = Standard_True;
463 } // if (myAutomaticPosition)
467 Standard_Real linparam = ElCLib::Parameter(glin, pos);
469 // case if the projection of position is located between 2 vertices
471 if ( (linparam >= pfirst) && (linparam <= plast) )
472 myPntAttach = ElCLib::Value(linparam,glin);
474 // case if the projection of Position is outside of the limits
475 // of the edge : the point closest to the projection is chosen
476 // as the attach point
478 Standard_Real pOnLin;
479 if (linparam > plast)
483 myPntAttach = ElCLib::Value(pOnLin,glin);
484 gp_Dir norm = myPlane->Axis().Direction();
486 norm.Cross(glin.Position().Direction());
487 gp_Lin lsup(myPntAttach, norm);
488 Standard_Real parpos = ElCLib::Parameter(lsup,myPosition);
489 pos = ElCLib::Value(parpos,lsup);
496 //=======================================================================
497 //function : ComputeCirclePosition
498 //purpose : compute the values of myPntAttach and the position <pos> of
499 // the symbol when the fixed edge has a geometric support equal
501 //=======================================================================
503 void AIS_FixRelation::ComputeCirclePosition(
504 const gp_Circ& gcirc,
506 Standard_Real& pfirst,
507 Standard_Real& plast)
509 // readjust parametres on the circle
510 if (plast > 2*M_PI ) {
511 Standard_Real nbtours = Floor(plast / (2*M_PI));
512 plast -= nbtours*2*M_PI;
513 pfirst -= nbtours*2*M_PI;
516 if (myAutomaticPosition) {
517 // the point attach is the "middle" of the segment (relatively
518 // to the parametres of start and end vertices of the edge
520 Standard_Real circparam = (pfirst + plast)/2.;
522 if ( !InDomain(pfirst,plast,circparam)) {
523 Standard_Real otherpar = circparam + M_PI;
524 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
525 circparam = otherpar;
528 myPntAttach = ElCLib::Value(circparam, gcirc );
530 gp_Vec dir( gcirc.Location().XYZ(), myPntAttach.XYZ() );
532 gp_Vec transvec = dir*myArrowSize;
533 pos = myPntAttach.Translated(transvec);
535 myAutomaticPosition = Standard_True;
536 } // if (myAutomaticPosition)
539 // case if the projection of myPosition is outside of 2
540 // vertices of the edge. In this case the parameter is readjusted
541 // in the valid part of the circle
544 Standard_Real circparam = ElCLib::Parameter(gcirc, pos);
546 if ( !InDomain(pfirst,plast,circparam)) {
547 Standard_Real otherpar = circparam + M_PI;
548 if (otherpar > 2*M_PI) otherpar -= 2*M_PI;
549 circparam = otherpar;
552 myPntAttach = ElCLib::Value(circparam,gcirc);
556 //=======================================================================
557 //function : ConnectedEdges
559 //=======================================================================
560 Standard_Boolean AIS_FixRelation::ConnectedEdges(const TopoDS_Wire& WIRE,
561 const TopoDS_Vertex& V,
565 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
566 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
568 Standard_Boolean found(Standard_False);
569 TopoDS_Vertex theVertex;
570 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
571 if (vertexMap.FindKey(i).IsSame(V)) {
572 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
573 found = Standard_True;
579 return Standard_False;
582 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
583 if (iterator.More()) {
584 E1 = TopoDS::Edge(iterator.Value());
585 BRepAdaptor_Curve curv(E1);
590 return Standard_False;
593 if (iterator.More()) {
594 E2 = TopoDS::Edge(iterator.Value());
595 BRepAdaptor_Curve curv(E2);
600 return Standard_False;
603 if (iterator.More()) {
606 return Standard_False;
608 return Standard_True;