1 // File: AIS_IdenticRelation.cxx
2 // Created: Mon Mar 3 17:21:37 1997
3 // Author: Jean-Pierre COMBE
7 #include <Standard_NotImplemented.hxx>
9 #include <AIS_IdenticRelation.ixx>
12 #include <AIS_Shape.hxx>
13 #include <AIS_Drawer.hxx>
15 #include <BRep_Tool.hxx>
17 #include <DsgPrs_IdenticPresentation.hxx>
21 #include <Geom_Circle.hxx>
22 #include <Geom_Line.hxx>
23 #include <Geom_Plane.hxx>
24 #include <Geom_TrimmedCurve.hxx>
26 #include <Precision.hxx>
28 #include <Prs3d_Drawer.hxx>
29 #include <Prs3d_LineAspect.hxx>
31 #include <Select3D_SensitiveCurve.hxx>
32 #include <Select3D_SensitiveSegment.hxx>
33 #include <SelectMgr_EntityOwner.hxx>
35 #include <TColStd_ListIteratorOfListOfTransient.hxx>
37 #include <StdPrs_WFDeflectionShape.hxx>
39 #include <TCollection_ExtendedString.hxx>
44 #include <TopoDS_Edge.hxx>
45 #include <TopoDS_Vertex.hxx>
46 #include <TopoDS_Wire.hxx>
47 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
48 #include <TopTools_ListIteratorOfListOfShape.hxx>
56 #include <Geom_Ellipse.hxx>
57 #include <GeomAPI_ProjectPointOnCurve.hxx>
59 static Standard_Real Modulo2PI(const Standard_Real ANGLE)
61 if ( ANGLE < 0 ) return Modulo2PI(ANGLE + 2*M_PI);
62 else if ( ANGLE >= 2*M_PI ) return Modulo2PI(ANGLE - 2*M_PI);
66 static Standard_Boolean IsEqual2PI(const Standard_Real angle1,
67 const Standard_Real angle2, const Standard_Real precision)
69 Standard_Real diff = Abs(angle1-angle2);
70 if ( diff < precision ) return Standard_True;
71 else if ( Abs(diff-2*M_PI) < precision ) return Standard_True;
72 return Standard_False;
76 //=======================================================================
78 //purpose : sort an array of parameters <tab1> in increasing order
79 // updates <tab2> and <tab3> according to <tab1>
80 //=======================================================================
81 static void AIS_Sort(Standard_Real tab1[4],
83 Standard_Integer tab3[4])
85 Standard_Boolean found = Standard_True;
86 Standard_Real cur; gp_Pnt cur1; Standard_Integer cur2;
89 found = Standard_False;
90 for (Standard_Integer i=0; i< 3; i++) {
91 if (tab1[i+1] < tab1[i]) {
92 found = Standard_True;
93 cur = tab1[i]; cur1 = tab2[i]; cur2 = tab3[i];
94 tab1[i] = tab1[i+1]; tab2[i] = tab2[i+1]; tab3[i] = tab3[i+1];
95 tab1[i+1] = cur; tab2[i+1] = cur1; tab3[i+1] = cur2;
101 //=======================================================================
102 //function : ConnectedEdges
104 //=======================================================================
105 static Standard_Boolean ConnectedEdges(const TopoDS_Wire& WIRE,
106 const TopoDS_Vertex& V,
110 TopTools_IndexedDataMapOfShapeListOfShape vertexMap;
111 TopExp::MapShapesAndAncestors (WIRE,TopAbs_VERTEX,TopAbs_EDGE,vertexMap);
113 Standard_Boolean found(Standard_False);
114 TopoDS_Vertex theVertex;
115 for (Standard_Integer i=1; i<=vertexMap.Extent() && !found; i++) {
116 if (vertexMap.FindKey(i).IsSame(V)) {
117 theVertex = TopoDS::Vertex(vertexMap.FindKey(i));
118 found = Standard_True;
124 return Standard_False;
127 TopTools_ListIteratorOfListOfShape iterator(vertexMap.FindFromKey(theVertex));
128 if (iterator.More()) {
129 E1 = TopoDS::Edge(iterator.Value());
134 return Standard_False;
137 if (iterator.More()) {
138 E2 = TopoDS::Edge(iterator.Value());
143 return Standard_False;
146 if (iterator.More()) {
149 return Standard_False;
151 return Standard_True;
155 //=======================================================================
156 //function : ComputeAttach
157 //purpose : Compute a point on the arc of <thecirc>
158 // between <aFAttach> and <aSAttach>
159 // corresponding to <aPosition>
160 // Returns result into <aPosition>
161 // Note : This function is to be used only in the case of circles.
162 // The <aPosition> parameter is in/out.
163 //=======================================================================
164 static Standard_Boolean ComputeAttach(const gp_Circ& thecirc,
165 const gp_Pnt& aFAttach,
166 const gp_Pnt& aSAttach,
169 gp_Pnt curpos = aPosition;
171 // Case of confusion between the current position and the center
172 // of the circle -> we move the current position
173 Standard_Real confusion (Precision::Confusion());
174 gp_Pnt aCenter = thecirc.Location();
175 if ( aCenter.Distance(curpos) <= confusion )
177 gp_Vec vprec(aCenter, aFAttach);
179 curpos.Translate(vprec*1e-5);
182 Standard_Real pcurpos = ElCLib::Parameter(thecirc,curpos);
183 Standard_Real pFAttach = ElCLib::Parameter(thecirc,aFAttach);
184 Standard_Real pSAttach = ElCLib::Parameter(thecirc,aSAttach);
186 Standard_Real pSAttachM = pSAttach;
187 Standard_Real deltap = pSAttachM - pFAttach;
191 pSAttachM += 2 * M_PI;
193 pSAttachM -= pFAttach;
195 Standard_Real pmiddleout = pSAttachM/2.0 + M_PI;
197 Standard_Real pcurpos1 = pcurpos;
198 // define where curpos lays
199 if ( pcurpos1 < pFAttach )
201 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
202 if ( pcurpos1 > pSAttachM ) // out
204 if ( pcurpos1 > pmiddleout ) pcurpos = pFAttach;
205 else pcurpos = pSAttach;
208 else if ( pcurpos1 > (pFAttach + deltap) ) // out
210 pcurpos1 -= pFAttach;
211 if ( pcurpos1 > pmiddleout ) pcurpos = pFAttach;
212 else pcurpos = pSAttach;
215 aPosition = ElCLib::Value(pcurpos,thecirc);
216 return Standard_True;
219 //=======================================================================
220 //function : ComputeAttach
221 //purpose : Compute a point on the arc of ellipse <theEll>
222 // between <aFAttach> and <aSAttach>
223 // corresponding to <aPosition>
224 // Returns result into <aPosition>
225 // Note : This function is to be used only in the case of ellipses.
226 // The <aPosition> parameter is in/out.
227 //=======================================================================
228 static Standard_Boolean ComputeAttach(const gp_Elips& theEll,
229 const gp_Pnt& aFAttach,
230 const gp_Pnt& aSAttach,
233 gp_Pnt curpos = aPosition;
235 // Case of confusion between the current position and the center
236 // of the circle -> we move the current position
237 Standard_Real confusion (Precision::Confusion());
238 gp_Pnt aCenter = theEll.Location();
239 if ( aCenter.Distance(curpos) <= confusion )
241 gp_Vec vprec(aCenter, aFAttach);
243 curpos.Translate(vprec*1e-5);
246 // for ellipses it's not good Standard_Real pcurpos = ElCLib::Parameter(theEll,curpos);
247 Handle(Geom_Ellipse) theEllg = new Geom_Ellipse(theEll);
248 GeomAPI_ProjectPointOnCurve aProj (curpos, theEllg);
249 Standard_Real pcurpos = aProj.LowerDistanceParameter();
251 Standard_Real pFAttach = ElCLib::Parameter(theEll,aFAttach);
252 Standard_Real pSAttach = ElCLib::Parameter(theEll,aSAttach);
254 Standard_Real pSAttachM = pSAttach;
255 Standard_Real deltap = pSAttachM - pFAttach;
259 pSAttachM += 2 * M_PI;
261 pSAttachM -= pFAttach;
263 Standard_Real pmiddleout = pSAttachM/2.0 + M_PI;
265 Standard_Real pcurpos1 = pcurpos;
266 // define where curpos lays
267 if ( pcurpos1 < pFAttach )
269 pcurpos1 = pcurpos1 + 2 * M_PI - pFAttach;
270 if ( pcurpos1 > pSAttachM ) // out
272 if ( pcurpos1 > pmiddleout ) pcurpos = pFAttach;
273 else pcurpos = pSAttach;
276 else if ( pcurpos1 > (pFAttach + deltap) ) // out
278 pcurpos1 -= pFAttach;
279 if ( pcurpos1 > pmiddleout ) pcurpos = pFAttach;
280 else pcurpos = pSAttach;
283 aPosition = ElCLib::Value(pcurpos,theEll);
284 return Standard_True;
286 // jfa 16/10/2000 end
288 //=======================================================================
289 //function : AIS_IdenticRelation
291 //=======================================================================
292 AIS_IdenticRelation::AIS_IdenticRelation(const TopoDS_Shape& FirstShape,
293 const TopoDS_Shape& SecondShape,
294 const Handle(Geom_Plane)& aPlane)
295 :isCircle(Standard_False)
297 myFShape = FirstShape;
298 mySShape = SecondShape;
302 //=======================================================================
305 //=======================================================================
306 void AIS_IdenticRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
307 const Handle(Prs3d_Presentation)& aprs,
308 const Standard_Integer)
312 switch ( myFShape.ShapeType() ) {
316 switch ( mySShape.ShapeType() ) {
319 ComputeTwoVerticesPresentation(aprs);
324 ComputeOneEdgeOVertexPresentation(aprs);
335 switch ( mySShape.ShapeType() ) {
338 ComputeOneEdgeOVertexPresentation(aprs);
343 ComputeTwoEdgesPresentation(aprs);
355 //=======================================================================
358 //=======================================================================
359 void AIS_IdenticRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
360 const Handle(Prs3d_Presentation)& aPresentation)
362 // Standard_NotImplemented::Raise("AIS_IdenticRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
363 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
366 //=======================================================================
369 //=======================================================================
370 void AIS_IdenticRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
371 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
372 const Standard_Integer anInteger)
374 // Standard_NotImplemented::Raise("AIS_IdenticRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
375 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
378 void AIS_IdenticRelation::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
380 // Standard_NotImplemented::Raise("AIS_IdenticRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
381 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
384 //=======================================================================
385 //function : ComputeSelection
386 //purpose : function used to compute the selection associated to the
387 // "identic" presentation
388 // note : if we are in the case of lines, we create a segment between
389 // myFAttach and mySAttach. In the case of Circles, we create
390 // an arc of circle between the sames points. We Add a segment
391 // to link Position to its projection on the curve described
393 //=======================================================================
395 void AIS_IdenticRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
396 const Standard_Integer)
398 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
400 Handle(Select3D_SensitiveSegment) seg;
401 // attachement point of the segment linking position to the curve
403 Standard_Real confusion (Precision::Confusion());
405 if ( myFAttach.IsEqual(mySAttach, confusion) )
412 if ( myFShape.ShapeType() == TopAbs_EDGE )
414 Handle(Geom_Curve) curv1,curv2;
415 gp_Pnt firstp1,lastp1,firstp2,lastp2;
416 Standard_Boolean isInfinite1,isInfinite2;
417 Handle(Geom_Curve) extCurv;
418 if ( !AIS::ComputeGeometry(TopoDS::Edge(myFShape),TopoDS::Edge(mySShape),
419 myExtShape,curv1,curv2,
420 firstp1,lastp1,firstp2,lastp2,
421 extCurv,isInfinite1,isInfinite2,myPlane) ) return;
423 if ( isCircle ) // case of Circles
425 Handle(Geom_Circle) thecirc = (Handle(Geom_Circle)&) curv1;
426 Standard_Real udeb = ElCLib::Parameter(thecirc->Circ(),myFAttach);
427 Standard_Real ufin = ElCLib::Parameter(thecirc->Circ(),mySAttach);
428 Handle(Geom_TrimmedCurve) thecu = new Geom_TrimmedCurve(thecirc,udeb,ufin);
430 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own, thecu);
431 aSelection->Add(scurv);
434 ComputeAttach(thecirc->Circ(),myFAttach,mySAttach,attach);
436 else if ( curv1->IsInstance(STANDARD_TYPE(Geom_Ellipse)) ) // case of ellipses
438 Handle(Geom_Ellipse) theEll = (Handle(Geom_Ellipse)&) curv1;
440 Standard_Real udeb = ElCLib::Parameter(theEll->Elips(),myFAttach);
441 Standard_Real ufin = ElCLib::Parameter(theEll->Elips(),mySAttach);
442 Handle(Geom_TrimmedCurve) thecu = new Geom_TrimmedCurve(theEll,udeb,ufin);
444 Handle(Select3D_SensitiveCurve) scurv = new Select3D_SensitiveCurve(own, thecu);
445 aSelection->Add(scurv);
448 ComputeAttach(theEll->Elips(),myFAttach,mySAttach,attach);
450 else if ( curv1->IsInstance(STANDARD_TYPE(Geom_Line)) ) // case of Lines
452 seg = new Select3D_SensitiveSegment(own, myFAttach, mySAttach);
453 aSelection->Add(seg);
455 //attach = projection of Position() on the curve;
456 gp_Vec v1 (myFAttach, mySAttach);
457 gp_Vec v2 (myFAttach, myPosition);
458 if ( v1.IsParallel(v2, Precision::Angular()) )
464 gp_Lin ll (myFAttach, gp_Dir(v1));
465 attach = ElCLib::Value(ElCLib::Parameter(ll,myPosition), ll);
470 // else if ( myFShape.ShapeType() == TopAbs_VERTEX )
473 // jfa 24/10/2000 end
476 // Creation of the segment linking the attachement point with the
478 if ( !attach.IsEqual(myPosition, confusion) )
480 seg = new Select3D_SensitiveSegment(own, attach, myPosition);
481 aSelection->Add(seg);
485 //=======================================================================
486 //function : ComputeTwoEdgesPresentation
488 //=======================================================================
489 void AIS_IdenticRelation::ComputeTwoEdgesPresentation(const Handle(Prs3d_Presentation)& aPrs)
491 Handle(Geom_Curve) curv1,curv2;
492 gp_Pnt firstp1,lastp1,firstp2,lastp2;
493 Standard_Boolean isInfinite1,isInfinite2;
495 Handle(Geom_Curve) extCurv;
496 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
497 TopoDS::Edge(mySShape),
506 isInfinite1,isInfinite2,
509 aPrs->SetInfiniteState((isInfinite1 || isInfinite2) && myExtShape != 0);
511 // Treatement of the case of lines
512 if ( curv1->IsInstance(STANDARD_TYPE(Geom_Line)) && curv2->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
513 // we take the line curv1 like support
514 Handle(Geom_Line) thelin;
515 if (isInfinite1 && !isInfinite2) thelin = (Handle(Geom_Line)&) curv2;
516 else if (!isInfinite1 && isInfinite2) thelin = (Handle(Geom_Line)&) curv1;
517 else thelin = (Handle(Geom_Line)&) curv1;
518 ComputeTwoLinesPresentation(aPrs, thelin, firstp1, lastp1, firstp2, lastp2, isInfinite1, isInfinite2);
521 // Treatement of the case of circles
522 else if ( curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) && curv2->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
524 isCircle = Standard_True; // useful for ComputeSelection
525 const Handle(Geom_Circle)& thecirc = (Handle(Geom_Circle)&) curv1;
526 ComputeTwoCirclesPresentation(aPrs, thecirc, firstp1, lastp1, firstp2, lastp2);
530 // Treatement of the case of ellipses
531 else if ( curv1->IsInstance(STANDARD_TYPE(Geom_Ellipse)) && curv2->IsInstance(STANDARD_TYPE(Geom_Ellipse)) )
533 const Handle(Geom_Ellipse)& theEll = (Handle(Geom_Ellipse)&) curv1;
534 ComputeTwoEllipsesPresentation(aPrs, theEll, firstp1, lastp1, firstp2, lastp2);
536 // jfa 10/10/2000 end
540 // Calculate presentation of projected edges
541 if ( (myExtShape != 0) && !extCurv.IsNull()) {
542 if (myExtShape == 1 )
543 ComputeProjEdgePresentation(aPrs, TopoDS::Edge(myFShape), curv1, firstp1, lastp1);
545 ComputeProjEdgePresentation(aPrs, TopoDS::Edge(mySShape), curv2, firstp2, lastp2);
549 //=======================================================================
550 //function : ComputeTwoLinesPresentation
551 //purpose : Compute the presentation of the 'identic' constraint
552 // between two lines ( which are equal)
553 //input : <thelin> : the
554 // <firstp1>: first extremity of the 1st curve of the constraint
555 // <lastp1> : last extremity of the 1st curve of the constraint
556 // <firstp2>: first extremity of the 2nd curve of the constraint
557 // <lastp2> :last extremity of the 2nd curve of the constraint
558 //=======================================================================
559 void AIS_IdenticRelation::ComputeTwoLinesPresentation(const Handle(Prs3d_Presentation)& aPrs,
560 const Handle(Geom_Line)& thelin,
565 const Standard_Boolean isInfinite1,
566 const Standard_Boolean isInfinite2)
568 if (isInfinite1 && isInfinite2) {
569 if ( myAutomaticPosition ) {
570 myFAttach = mySAttach = thelin->Lin().Location();
572 gp_Pln pln(myPlane->Pln());
573 gp_Dir dir(pln.XAxis().Direction());
574 gp_Vec transvec = gp_Vec(dir)*myArrowSize;
575 curpos = myFAttach.Translated(transvec);;
577 myAutomaticPosition = Standard_True;
580 myFAttach = mySAttach = ElCLib::Value(ElCLib::Parameter(thelin->Lin(),myPosition),thelin->Lin());
582 TCollection_ExtendedString vals(" ==");
583 DsgPrs_IdenticPresentation::Add(aPrs,
590 // Computation of the parameters of the 4 points on the line <thelin>
591 Standard_Real pf1, pf2, pl1, pl2;
593 pf1 = ElCLib::Parameter(thelin->Lin(), firstp1);
594 pl1 = ElCLib::Parameter(thelin->Lin(), lastp1);
596 pf2 = ElCLib::Parameter(thelin->Lin(), firstp2);
597 pl2 = ElCLib::Parameter(thelin->Lin(), lastp2);
605 else if (isInfinite2) {
612 Standard_Real tabRang1[4]; // array taht contains the parameters of the 4 points
613 // ordered by increasing abscisses.
615 gp_Pnt tabRang2[4]; // array containing the points corresponding to the
616 // parameters in tabRang1
618 Standard_Integer tabRang3[4]; // array containing the number of the curve( 1 or 2)
619 // of which belongs each point of tabRang2
621 // Filling of the arrays
622 tabRang1[0] = pf1; tabRang2[0] = firstp1; tabRang3[0] = 1;
623 tabRang1[1] = pf2; tabRang2[1] = firstp2; tabRang3[1] = 2;
624 tabRang1[2] = pl1; tabRang2[2] = lastp1; tabRang3[2] = 1;
625 tabRang1[3] = pl2; tabRang2[3] = lastp2; tabRang3[3] = 2;
627 // Sort of the array of parameters (tabRang1)
628 AIS_Sort(tabRang1, tabRang2, tabRang3);
630 // Computation of myFAttach and mySAttach according to the
631 // position of the 2 linear edges
635 if ( (tabRang1[0] == tabRang1[1]) && (tabRang1[2] == tabRang1[3]) ) {
636 middle.SetXYZ((tabRang2[1].XYZ() + tabRang2[2].XYZ())/2. );
637 Standard_Real pmiddle = (tabRang1[1] + tabRang1[2]) / 2.;
638 Standard_Real delta = (tabRang1[3] - tabRang1[0])/ 5.;
639 myFAttach = ElCLib::Value(pmiddle-delta, thelin->Lin());
640 mySAttach = ElCLib::Value(pmiddle+delta, thelin->Lin());
643 else if ( tabRang1[1] == tabRang1[2] ) {
644 middle = tabRang2[1];
645 Standard_Real delta1 = tabRang1[1] - tabRang1[0];
646 Standard_Real delta2 = tabRang1[3] - tabRang1[2];
647 if ( delta1 > delta2 ) delta1 = delta2;
648 myFAttach = ElCLib::Value(tabRang1[1]-delta1/2., thelin->Lin());
649 mySAttach = ElCLib::Value(tabRang1[1]+delta1/2., thelin->Lin());
652 // Case of 2 disconnected segments -> the symbol completes the gap
653 // between the 2 edges
654 //--------------------------------
655 else if ( (tabRang3[0] == tabRang3[1]) && (tabRang1[1] != tabRang1[2])) {
656 middle.SetXYZ((tabRang2[1].XYZ() + tabRang2[2].XYZ())/2. );
657 myFAttach = tabRang2[1];
658 mySAttach = tabRang2[2];
660 else if ( (tabRang3[0] != tabRang3[1])
661 && (tabRang3[1] != tabRang3[2]) // Intersection
662 && (tabRang1[1] != tabRang1[2]) ) {
663 middle.SetXYZ((tabRang2[1].XYZ() + tabRang2[2].XYZ())/2. );
664 myFAttach = tabRang2[1];
665 mySAttach = tabRang2[2];
668 myFAttach.SetXYZ((tabRang2[0].XYZ() + tabRang2[1].XYZ())/2. );
669 mySAttach.SetXYZ((tabRang2[1].XYZ() + tabRang2[2].XYZ())/2. );
670 middle.SetXYZ( (myFAttach.XYZ() + mySAttach.XYZ() )/2.);
674 if ( myAutomaticPosition ) {
676 gp_Vec vtrans(myFAttach, mySAttach);
678 vtrans.Cross(gp_Vec(myPlane->Pln().Axis().Direction()));
679 vtrans *= ComputeSegSize();
680 curpos = middle.Translated(vtrans);
682 myAutomaticPosition = Standard_True;
688 Standard_Real pcurpos = ElCLib::Parameter(thelin->Lin() ,curpos);
689 Standard_Real dist = thelin->Lin().Distance(curpos);
690 gp_Pnt proj = ElCLib::Value( pcurpos, thelin->Lin());
692 Standard_Real confusion(Precision::Confusion());
693 if ( dist >= confusion ) {
694 trans = gp_Vec(proj, curpos);
697 Standard_Real pf = ElCLib::Parameter(thelin->Lin() ,myFAttach);
698 Standard_Real pl = ElCLib::Parameter(thelin->Lin() ,mySAttach);
699 if ( pcurpos <= pf ) {
701 curpos = ElCLib::Value( pcurpos, thelin->Lin());
702 if ( dist >= confusion ) curpos.Translate(trans*dist);
704 else if ( pcurpos >= pl ) {
706 curpos = ElCLib::Value( pcurpos, thelin->Lin());
707 if ( dist >= confusion ) curpos.Translate(trans*dist);
712 // Display of the presentation
713 TCollection_ExtendedString vals(" ==");
714 DsgPrs_IdenticPresentation::Add(aPrs,
724 //=======================================================================
725 //function : ComputeTwoCirclesPresentation
726 //purpose : Compute the presentation of the 'identic' constraint
727 // between two circles ( which are equal)
728 //input : <thecirc>: the circle
729 // <firstp1>: first extremity of the 1st curve of the constraint
730 // <lastp1> : last extremity of the 1st curve of the constraint
731 // <firstp2>: first extremity of the 2nd curve of the constraint
732 // <lastp2> :last extremity of the 2nd curve of the constraint
733 //=======================================================================
734 void AIS_IdenticRelation::ComputeTwoCirclesPresentation(const Handle(Prs3d_Presentation)& aPrs,
735 const Handle(Geom_Circle)& thecirc,
736 const gp_Pnt& firstp1,
737 const gp_Pnt& lastp1,
738 const gp_Pnt& firstp2,
739 const gp_Pnt& lastp2)
741 Standard_Real confusion (Precision::Confusion());
743 // Searching of complete circles
744 Standard_Boolean circ1complete = (firstp1.IsEqual(lastp1, confusion));
745 Standard_Boolean circ2complete = (firstp2.IsEqual(lastp2, confusion));
747 myCenter = thecirc->Location();
748 Standard_Real aSegSize = thecirc->Radius()/5.0;
749 Standard_Real rad = M_PI / 5.0;
751 // I. Case of 2 complete circles
752 if ( circ1complete && circ2complete )
754 if (myAutomaticPosition)
756 Standard_Real pfirst1 = ElCLib::Parameter(thecirc->Circ(), firstp1);
757 myFAttach = ElCLib::Value(Modulo2PI(pfirst1-rad), thecirc->Circ());
758 mySAttach = ElCLib::Value(Modulo2PI(pfirst1+rad), thecirc->Circ());
760 gp_Pnt curpos = ElCLib::Value(pfirst1,thecirc->Circ());
761 gp_Vec vtrans(myCenter, curpos);
764 curpos.Translate(vtrans);
767 else ComputeNotAutoCircPresentation(thecirc);
770 // II. Case of one complete circle and one arc
771 else if ( (circ1complete && !circ2complete) || (!circ1complete && circ2complete) )
773 gp_Pnt firstp, lastp;
774 if ( circ1complete && !circ2complete)
785 if (myAutomaticPosition)
787 ComputeAutoArcPresentation(thecirc, firstp, lastp);
791 ComputeNotAutoArcPresentation(thecirc, firstp, lastp);
795 // III and IV. Case of two arcs
796 else if ( !circ1complete && !circ2complete )
798 // We project all the points on the circle
799 Standard_Real pf1, pf2, pl1, pl2;
800 pf1 = ElCLib::Parameter(thecirc->Circ(), firstp1);
801 pf2 = ElCLib::Parameter(thecirc->Circ(), firstp2);
802 pl1 = ElCLib::Parameter(thecirc->Circ(), lastp1);
803 pl2 = ElCLib::Parameter(thecirc->Circ(), lastp2);
805 // III. Arcs with common ends
806 // III.1. First of one and last of another
807 if ( IsEqual2PI(pl1,pf2,confusion) || IsEqual2PI(pf1,pl2,confusion) )
809 gp_Pnt curpos(0.,0.,0.);
810 Standard_Real att=0.;
811 if ( IsEqual2PI(pl1,pf2,confusion) )
816 else if ( IsEqual2PI(pf1,pl2,confusion) )
821 Standard_Real maxrad = Min(Modulo2PI(pl1 - pf1),Modulo2PI(pl2 - pf2))*3/4;
822 if ( rad > maxrad ) rad = maxrad;
823 Standard_Real pFAttach = Modulo2PI(att - rad);
824 Standard_Real pSAttach = Modulo2PI(att + rad);
825 myFAttach = ElCLib::Value(pFAttach, thecirc->Circ());
826 mySAttach = ElCLib::Value(pSAttach, thecirc->Circ());
827 if ( myAutomaticPosition )
829 gp_Vec vtrans(myCenter,curpos);
832 curpos.Translate(vtrans);
836 // III.2. Two first or two last
837 else if ( IsEqual2PI(pf1,pf2,confusion) || IsEqual2PI(pl1,pl2,confusion) )
839 Standard_Real l1 = Modulo2PI(pl1 - pf1);
840 Standard_Real l2 = Modulo2PI(pl2 - pf2);
853 if ( myAutomaticPosition )
855 ComputeAutoArcPresentation(thecirc, firstp, lastp);
859 ComputeNotAutoArcPresentation(thecirc, firstp, lastp);
862 // IV. All others arcs (without common ends)
865 // order the parameters; first will be pf1
866 Standard_Real pl1m = Modulo2PI(pl1 - pf1);
867 Standard_Real pf2m = Modulo2PI(pf2 - pf1);
868 Standard_Real pl2m = Modulo2PI(pl2 - pf1);
870 Standard_Boolean case1 = Standard_False;
871 // 1 - not intersecting arcs
872 // 2 - intersecting arcs, but one doesn't contain another
873 // 3a - first arc contains the second one
874 // 3b - second arc contains the first one
875 // 4 - two intersections
877 gp_Pnt firstp, lastp;
879 if ( pl1m < pf2m ) // 1 or 2b or 3b
881 if ( pl1m < pl2m ) // 1 or 3b
883 if ( pl2m < pf2m ) // 3b
890 case1 = Standard_True;
891 Standard_Real deltap1 = Modulo2PI(pf1 - pl2);
892 Standard_Real deltap2 = Modulo2PI(pf2 - pl1);
893 if ( ((deltap1 < deltap2) && (deltap1 < 2*rad)) ||
894 ((deltap2 < deltap1) && (deltap2 > 2*rad)) ) // deltap2
912 else // 2a or 3a or 4
914 if ( pl1m < pl2m ) // 2a
921 if ( pl2m > pf2m ) // 3a
928 Standard_Real deltap1 = Modulo2PI(pl1 - pf2);
929 Standard_Real deltap2 = Modulo2PI(pl2 - pf1);
930 if ( ((deltap1 < deltap2) && (deltap1 < 2*rad)) ||
931 ((deltap2 < deltap1) && (deltap2 > 2*rad)) ) // deltap2
945 if ( myAutomaticPosition )
947 ComputeAutoArcPresentation(thecirc,firstp,lastp,case1);
956 else ComputeNotAutoArcPresentation(thecirc, firstp, lastp);
961 // Display of the presentation
962 TCollection_ExtendedString vals(" ==");
963 gp_Pnt attach = myPosition;
964 ComputeAttach(thecirc->Circ(),myFAttach,mySAttach,attach);
965 DsgPrs_IdenticPresentation::Add(aPrs,
968 myPlane->Pln().Position().Ax2(),
976 //=======================================================================
977 //function : ComputeAutoArcPresentation
978 //purpose : Compute the presentation of the constraint where we are
979 // not in the case of dragging.
980 //=======================================================================
981 void AIS_IdenticRelation::ComputeAutoArcPresentation(const Handle(Geom_Circle)& thecirc,
982 const gp_Pnt& firstp,
984 const Standard_Boolean isstatic)
986 Standard_Real aSegSize = thecirc->Radius()/5.0;
987 Standard_Real rad = M_PI / 5.0;
989 Standard_Real pFA = ElCLib::Parameter(thecirc->Circ(),firstp);
990 Standard_Real pSA = ElCLib::Parameter(thecirc->Circ(),lastp);
991 Standard_Real maxrad = Modulo2PI(pSA - pFA)/2.0;
993 if ( (rad > maxrad) || isstatic ) rad = maxrad;
994 Standard_Real pmiddle = Modulo2PI(pFA + Modulo2PI(pSA - pFA)/2.0);
996 myFAttach = ElCLib::Value(Modulo2PI(pmiddle - rad),thecirc->Circ());
997 mySAttach = ElCLib::Value(Modulo2PI(pmiddle + rad),thecirc->Circ());
999 gp_Pnt curpos = ElCLib::Value(pmiddle,thecirc->Circ());
1000 gp_Vec vtrans(myCenter, curpos);
1003 myPosition = curpos.Translated(vtrans);
1006 //=======================================================================
1007 //function : ComputeNotAutoCircPresentation
1008 //purpose : Compute the presentation of the constraint where we are
1009 // in the case of dragging.
1010 // Note : This function is to be used only in the case of full circles.
1011 // The symbol of the constraint moves together with arc
1012 // representing the constraint around all the circle.
1013 //=======================================================================
1014 void AIS_IdenticRelation::ComputeNotAutoCircPresentation(const Handle(Geom_Circle)& thecirc)
1016 gp_Pnt curpos = myPosition;
1018 Handle(Geom_Circle) cirNotAuto = new Geom_Circle(thecirc->Circ());
1020 // Case of confusion between the current position and the center
1021 // of the circle -> we move the current position
1022 Standard_Real confusion (Precision::Confusion());
1023 if ( myCenter.Distance(curpos) <= confusion )
1025 gp_Vec vprec(myCenter, myFAttach);
1027 curpos.Translate(vprec*1e-5);
1030 Standard_Real rad = M_PI / 5.0;
1031 Standard_Real pcurpos = ElCLib::Parameter(cirNotAuto->Circ(),curpos);
1032 Standard_Real pFAttach = pcurpos - rad;
1033 Standard_Real pSAttach = pcurpos + rad;
1034 myFAttach = ElCLib::Value(pFAttach,cirNotAuto->Circ());
1035 mySAttach = ElCLib::Value(pSAttach,cirNotAuto->Circ());
1038 //=======================================================================
1039 //function : ComputeNotAutoArcPresentation
1040 //purpose : Compute the presentation of the constraint where we are
1041 // in the case of dragging.
1042 // Note : This function is to be used only in the case of circles.
1043 // The symbol of the constraint moves only between myFAttach
1045 //=======================================================================
1046 void AIS_IdenticRelation::ComputeNotAutoArcPresentation(const Handle(Geom_Circle)& thecirc,
1047 const gp_Pnt& pntfirst,
1048 const gp_Pnt& pntlast)
1050 gp_Pnt curpos = myPosition;
1052 gp_Circ cirNotAuto = thecirc->Circ();
1054 Standard_Real pFPnt = ElCLib::Parameter(cirNotAuto, pntfirst);
1055 Standard_Real pSPnt = ElCLib::Parameter(cirNotAuto, pntlast);
1056 Standard_Real deltap = Modulo2PI(pSPnt - pFPnt)/2.0;
1058 Standard_Real rad = M_PI / 5;
1061 myFAttach = pntfirst;
1062 mySAttach = pntlast;
1066 gp_Pnt aFPnt = ElCLib::Value(Modulo2PI(pFPnt + rad), cirNotAuto);
1067 gp_Pnt aSPnt = ElCLib::Value(Modulo2PI(pSPnt - rad), cirNotAuto);
1069 ComputeAttach(cirNotAuto,aFPnt,aSPnt,curpos);
1071 Standard_Real pcurpos = ElCLib::Parameter(cirNotAuto,curpos);
1072 myFAttach = ElCLib::Value(pcurpos - rad, cirNotAuto);
1073 mySAttach = ElCLib::Value(pcurpos + rad, cirNotAuto);
1076 // jfa 17/10/2000 end
1079 //=======================================================================
1080 //function : ComputeTwoEllipsesPresentation
1081 //purpose : Compute the presentation of the 'identic' constraint
1082 // between two ellipses (which are equal)
1083 //input : <theEll>: the ellipse
1084 // <firstp1>: first extremity of the 1st curve of the constraint
1085 // <lastp1> : last extremity of the 1st curve of the constraint
1086 // <firstp2>: first extremity of the 2nd curve of the constraint
1087 // <lastp2> :last extremity of the 2nd curve of the constraint
1088 //=======================================================================
1089 void AIS_IdenticRelation::ComputeTwoEllipsesPresentation(const Handle(Prs3d_Presentation)& aPrs,
1090 const Handle(Geom_Ellipse)& theEll,
1091 const gp_Pnt& firstp1,
1092 const gp_Pnt& lastp1,
1093 const gp_Pnt& firstp2,
1094 const gp_Pnt& lastp2)
1096 Standard_Real confusion (Precision::Confusion());
1098 // Searching of complete ellipses
1099 Standard_Boolean circ1complete = (firstp1.IsEqual(lastp1, confusion));
1100 Standard_Boolean circ2complete = (firstp2.IsEqual(lastp2, confusion));
1102 myCenter = theEll->Location();
1103 Standard_Real aSegSize = theEll->MajorRadius()/5.0;
1104 Standard_Real rad = M_PI / 5.0;
1106 // I. Case of 2 complete ellipses
1107 if ( circ1complete && circ2complete )
1109 if (myAutomaticPosition)
1111 Standard_Real pfirst1 = ElCLib::Parameter(theEll->Elips(), firstp1);
1112 myFAttach = ElCLib::Value(Modulo2PI(pfirst1-rad), theEll->Elips());
1113 mySAttach = ElCLib::Value(Modulo2PI(pfirst1+rad), theEll->Elips());
1115 gp_Pnt curpos = ElCLib::Value(pfirst1,theEll->Elips());
1116 gp_Vec vtrans(myCenter, curpos);
1119 curpos.Translate(vtrans);
1120 myPosition = curpos;
1122 else ComputeNotAutoElipsPresentation(theEll);
1125 // II. Case of one complete circle and one arc
1126 else if ( (circ1complete && !circ2complete) || (!circ1complete && circ2complete) )
1128 gp_Pnt firstp, lastp;
1129 if ( circ1complete && !circ2complete)
1140 if (myAutomaticPosition)
1142 ComputeAutoArcPresentation(theEll, firstp, lastp);
1146 ComputeNotAutoArcPresentation(theEll, firstp, lastp);
1150 // III and IV. Case of two arcs
1151 else if ( !circ1complete && !circ2complete )
1153 // We project all the points on the circle
1154 Standard_Real pf1, pf2, pl1, pl2;
1155 pf1 = ElCLib::Parameter(theEll->Elips(), firstp1);
1156 pf2 = ElCLib::Parameter(theEll->Elips(), firstp2);
1157 pl1 = ElCLib::Parameter(theEll->Elips(), lastp1);
1158 pl2 = ElCLib::Parameter(theEll->Elips(), lastp2);
1160 // III. Arcs with common ends
1161 // III.1. First of one and last of another
1162 if ( IsEqual2PI(pl1,pf2,confusion) || IsEqual2PI(pf1,pl2,confusion) )
1165 Standard_Real att=0.;
1166 if ( IsEqual2PI(pl1,pf2,confusion) )
1171 else if ( IsEqual2PI(pf1,pl2,confusion) )
1176 Standard_Real maxrad = Min(Modulo2PI(pl1 - pf1),Modulo2PI(pl2 - pf2))*3/4;
1177 if ( rad > maxrad ) rad = maxrad;
1178 Standard_Real pFAttach = Modulo2PI(att - rad);
1179 Standard_Real pSAttach = Modulo2PI(att + rad);
1180 myFAttach = ElCLib::Value(pFAttach, theEll->Elips());
1181 mySAttach = ElCLib::Value(pSAttach, theEll->Elips());
1182 if ( myAutomaticPosition )
1184 gp_Vec vtrans(myCenter,curpos);
1187 curpos.Translate(vtrans);
1188 myPosition = curpos;
1191 // III.2. Two first or two last
1192 else if ( IsEqual2PI(pf1,pf2,confusion) || IsEqual2PI(pl1,pl2,confusion) )
1194 Standard_Real l1 = Modulo2PI(pl1 - pf1);
1195 Standard_Real l2 = Modulo2PI(pl2 - pf2);
1196 gp_Pnt firstp,lastp;
1208 if ( myAutomaticPosition )
1210 ComputeAutoArcPresentation(theEll, firstp, lastp);
1214 ComputeNotAutoArcPresentation(theEll, firstp, lastp);
1217 // IV. All others arcs (without common ends)
1220 // order the parameters; first will be pf1
1221 Standard_Real pl1m = Modulo2PI(pl1 - pf1);
1222 Standard_Real pf2m = Modulo2PI(pf2 - pf1);
1223 Standard_Real pl2m = Modulo2PI(pl2 - pf1);
1225 Standard_Boolean case1 = Standard_False;
1226 // 1 - not intersecting arcs
1227 // 2 - intersecting arcs, but one doesn't contain another
1228 // 3a - first arc contains the second one
1229 // 3b - second arc contains the first one
1230 // 4 - two intersections
1232 gp_Pnt firstp, lastp;
1234 if ( pl1m < pf2m ) // 1 or 2b or 3b
1236 if ( pl1m < pl2m ) // 1 or 3b
1238 if ( pl2m < pf2m ) // 3b
1245 case1 = Standard_True;
1246 Standard_Real deltap1 = Modulo2PI(pf1 - pl2);
1247 Standard_Real deltap2 = Modulo2PI(pf2 - pl1);
1248 if ( ((deltap1 < deltap2) && (deltap1 < 2*rad)) ||
1249 ((deltap2 < deltap1) && (deltap2 > 2*rad)) ) // deltap2
1267 else // 2a or 3a or 4
1269 if ( pl1m < pl2m ) // 2a
1276 if ( pl2m > pf2m ) // 3a
1283 Standard_Real deltap1 = Modulo2PI(pl1 - pf2);
1284 Standard_Real deltap2 = Modulo2PI(pl2 - pf1);
1285 if ( ((deltap1 < deltap2) && (deltap1 < 2*rad)) ||
1286 ((deltap2 < deltap1) && (deltap2 > 2*rad)) ) // deltap2
1300 if ( myAutomaticPosition )
1302 ComputeAutoArcPresentation(theEll,firstp,lastp,case1);
1311 else ComputeNotAutoArcPresentation(theEll, firstp, lastp);
1316 // Display of the presentation
1317 TCollection_ExtendedString vals(" ==");
1318 gp_Pnt attach = myPosition;
1319 ComputeAttach(theEll->Elips(),myFAttach,mySAttach,attach);
1320 DsgPrs_IdenticPresentation::Add(aPrs,
1330 //=======================================================================
1331 //function : ComputeAutoArcPresentation
1332 //purpose : Compute the presentation of the constraint where we are
1333 // not in the case of dragging.
1334 //=======================================================================
1335 void AIS_IdenticRelation::ComputeAutoArcPresentation(const Handle(Geom_Ellipse)& theEll,
1336 const gp_Pnt& firstp,
1337 const gp_Pnt& lastp,
1338 const Standard_Boolean isstatic)
1340 Standard_Real aSegSize = theEll->MajorRadius()/5.0;
1341 Standard_Real rad = M_PI / 5.0;
1343 gp_Elips anEll = theEll->Elips();
1345 Standard_Real pFA = ElCLib::Parameter(anEll,firstp);
1346 Standard_Real pSA = ElCLib::Parameter(anEll,lastp);
1347 Standard_Real maxrad = Modulo2PI(pSA - pFA)/2.0;
1349 if ( (rad > maxrad) || isstatic ) rad = maxrad;
1350 Standard_Real pmiddle = Modulo2PI(pFA + Modulo2PI(pSA - pFA)/2.0);
1352 myFAttach = ElCLib::Value(Modulo2PI(pmiddle - rad),anEll);
1353 mySAttach = ElCLib::Value(Modulo2PI(pmiddle + rad),anEll);
1355 gp_Pnt curpos = ElCLib::Value(pmiddle,anEll);
1356 gp_Vec vtrans(myCenter, curpos);
1359 myPosition = curpos.Translated(vtrans);
1362 //=======================================================================
1363 //function : ComputeNotAutoElipsPresentation
1364 //purpose : Compute the presentation of the constraint where we are
1365 // in the case of dragging.
1366 // Note : This function is to be used only in the case of ellipses.
1367 // The symbol of the constraint moves only between myFAttach
1369 //=======================================================================
1370 void AIS_IdenticRelation::ComputeNotAutoElipsPresentation(const Handle(Geom_Ellipse)& theEll)
1372 gp_Pnt curpos = myPosition;
1374 gp_Elips anEll = theEll->Elips();
1376 // Case of confusion between the current position and the center
1377 // of the ellipse -> we move the current position
1378 Standard_Real confusion (Precision::Confusion());
1379 if ( myCenter.Distance(curpos) <= confusion )
1381 gp_Vec vprec(myCenter, myFAttach);
1383 curpos.Translate(vprec*1e-5);
1386 Standard_Real rad = M_PI / 5.0;
1387 // Standard_Real pcurpos = ElCLib::Parameter(anEll,curpos);
1388 GeomAPI_ProjectPointOnCurve aProj (curpos, theEll);
1389 Standard_Real pcurpos = aProj.LowerDistanceParameter();
1391 Standard_Real pFAttach = pcurpos - rad;
1392 Standard_Real pSAttach = pcurpos + rad;
1393 myFAttach = ElCLib::Value(pFAttach,anEll);
1394 mySAttach = ElCLib::Value(pSAttach,anEll);
1397 //=======================================================================
1398 //function : ComputeNotAutoArcPresentation
1399 //purpose : Compute the presentation of the constraint where we are
1400 // in the case of dragging.
1401 // Note : This function is to be used only in the case of ellipses.
1402 // The symbol of the constraint moves only between myFAttach
1404 //=======================================================================
1405 void AIS_IdenticRelation::ComputeNotAutoArcPresentation(const Handle(Geom_Ellipse)& theEll,
1406 const gp_Pnt& pntfirst,
1407 const gp_Pnt& pntlast)
1409 gp_Pnt curpos = myPosition;
1411 gp_Elips anEll = theEll->Elips();
1413 Standard_Real pFPnt = ElCLib::Parameter(anEll, pntfirst);
1414 Standard_Real pSPnt = ElCLib::Parameter(anEll, pntlast);
1415 Standard_Real deltap = Modulo2PI(pSPnt - pFPnt)/2.0;
1417 Standard_Real rad = M_PI / 5;
1420 myFAttach = pntfirst;
1421 mySAttach = pntlast;
1425 gp_Pnt aFPnt = ElCLib::Value(Modulo2PI(pFPnt + rad), anEll);
1426 gp_Pnt aSPnt = ElCLib::Value(Modulo2PI(pSPnt - rad), anEll);
1428 ComputeAttach(anEll,aFPnt,aSPnt,curpos);
1430 // Standard_Real pcurpos = ElCLib::Parameter(anEll,curpos);
1431 GeomAPI_ProjectPointOnCurve aProj (curpos, theEll);
1432 Standard_Real pcurpos = aProj.LowerDistanceParameter();
1434 myFAttach = ElCLib::Value(pcurpos - rad, anEll);
1435 mySAttach = ElCLib::Value(pcurpos + rad, anEll);
1438 // jfa 18/10/2000 end
1440 //=======================================================================
1441 //function : ComputeTwoVerticesPresentation
1443 //=======================================================================
1444 void AIS_IdenticRelation::ComputeTwoVerticesPresentation(const Handle(Prs3d_Presentation)& aPrs)
1446 Standard_Boolean isOnPlane1, isOnPlane2;
1447 const TopoDS_Vertex& FVertex = TopoDS::Vertex(myFShape);
1448 const TopoDS_Vertex& SVertex = TopoDS::Vertex(mySShape);
1450 AIS::ComputeGeometry(FVertex, myFAttach, myPlane, isOnPlane1);
1451 AIS::ComputeGeometry(SVertex, mySAttach, myPlane, isOnPlane2);
1453 if (isOnPlane1 && isOnPlane2)
1455 else if ( isOnPlane1 && !isOnPlane2)
1457 else if (!isOnPlane1 && isOnPlane2)
1463 // The attachement points are the points themselves that must be
1465 myFAttach = BRep_Tool::Pnt(FVertex);
1466 mySAttach = myFAttach;
1469 if (myAutomaticPosition)
1471 //Computation of the size of the symbol
1472 Standard_Real symbsize = ComputeSegSize();
1473 if (symbsize <= Precision::Confusion()) symbsize = 1.;
1475 // Computation of the direction of the segment of the presentation
1476 // we take the median of the edges connected to vertices
1479 TColStd_ListIteratorOfListOfTransient it(Users());
1482 const Handle(AIS_Shape)& USER = Handle(AIS_Shape)::DownCast(it.Value());
1485 const TopoDS_Shape& SH =USER->Shape();
1486 if ( (!SH.IsNull()) && (SH.ShapeType() == TopAbs_WIRE) )
1488 const TopoDS_Wire& WIRE = TopoDS::Wire(USER->Shape());
1489 Standard_Boolean done = ComputeDirection(WIRE,FVertex,dF);
1491 done = ComputeDirection(WIRE,SVertex,dS);
1498 // computation of the segment direction like average
1499 // of the 2 computed directions.
1500 if ( dF.IsParallel(dS, Precision::Angular()) )
1502 myDir = dF.Crossed(myPlane->Pln().Axis().Direction());
1506 myDir.SetXYZ(dF.XYZ() + dS.XYZ());
1508 curpos = myFAttach.Translated(gp_Vec(myDir)*symbsize) ;
1515 // jfa 11/10/2000 end
1517 myPosition = curpos;
1518 myAutomaticPosition = Standard_False;
1522 curpos = myPosition;
1525 // Presentation computation
1526 TCollection_ExtendedString vals(" ++");
1527 DsgPrs_IdenticPresentation::Add(aPrs,
1532 // Calculate the projection of vertex
1533 if ( myExtShape == 1)
1534 ComputeProjVertexPresentation(aPrs,FVertex,myFAttach);
1535 else if ( myExtShape == 2)
1536 ComputeProjVertexPresentation(aPrs,SVertex,mySAttach);
1541 //=======================================================================
1542 //function : ComputeSegSize
1544 //=======================================================================
1545 Standard_Real AIS_IdenticRelation::ComputeSegSize() const
1550 //=======================================================================
1551 //function : ComputeDirection
1552 //purpose : Compute a direction according to the different geometric
1553 // elements connected to the vertex <VERT>, in way to not have
1554 // overlap between the symbol and them.
1555 //=======================================================================
1556 Standard_Boolean AIS_IdenticRelation::ComputeDirection(const TopoDS_Wire& aWire,
1557 const TopoDS_Vertex& VERT,
1560 // we take the median of the edges connected to vertices
1561 TopoDS_Edge edg1,edg2;
1562 ConnectedEdges(aWire,VERT,edg1,edg2);
1564 if ( edg1.IsNull() && edg2.IsNull() ) {
1565 return Standard_False;
1568 Handle(Geom_Curve) curv1,curv2;
1569 gp_Pnt firstp1,lastp1,firstp2,lastp2;
1571 // Case with 2 edges connected to the vertex <VERT>
1572 if ( !edg1.IsNull() && !edg2.IsNull() ) {
1573 if ( !AIS::ComputeGeometry(edg1,edg2,
1576 firstp2, lastp2,myPlane))
1577 return Standard_False;
1580 if ( curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1581 d1 = ComputeCircleDirection((Handle(Geom_Circle)&) curv1, VERT);
1583 else if (curv1->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1584 d1 = ComputeLineDirection((Handle(Geom_Line)&) curv1, firstp1);
1587 return Standard_False;
1589 if ( curv2->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1590 d2 = ComputeCircleDirection( (Handle(Geom_Circle)&) curv2, VERT);
1592 else if (curv2->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1593 d2 =ComputeLineDirection( (Handle(Geom_Line)&) curv2, firstp2);
1596 return Standard_False;
1598 if ( !d1.IsParallel(d2, Precision::Angular() ))
1599 dF.SetXYZ( (d1.XYZ() + d2.XYZ())/2 );
1601 dF= d1.Crossed(myPlane->Pln().Axis().Direction());
1605 // Case where <VERT> is at an extremity of a wire.
1608 if ( !edg1.IsNull() )
1610 else if (!edg2.IsNull() )
1613 return Standard_False;
1615 if ( !AIS::ComputeGeometry(VEdge, curv1, firstp1, lastp1) )
1616 return Standard_False;
1617 if ( curv1->IsInstance(STANDARD_TYPE(Geom_Circle)) ) {
1618 dF = ComputeCircleDirection( (Handle(Geom_Circle)&) curv1, VERT);
1620 else if (curv1->IsInstance(STANDARD_TYPE(Geom_Line)) ) {
1621 dF = ComputeLineDirection( (Handle(Geom_Line)&) curv1, firstp1);
1624 return Standard_False;
1627 return Standard_True;
1630 //=======================================================================
1631 //function : ComputeLineDirection
1633 //=======================================================================
1634 gp_Dir AIS_IdenticRelation::ComputeLineDirection(const Handle(Geom_Line)& lin,
1635 const gp_Pnt& firstP) const
1638 dir = lin->Lin().Direction();
1639 if ( !myFAttach.IsEqual(firstP, Precision::Confusion()) )
1644 //=======================================================================
1645 //function : ComputeCircleDirection
1647 //=======================================================================
1648 gp_Dir AIS_IdenticRelation::ComputeCircleDirection(const Handle(Geom_Circle)& circ,
1649 const TopoDS_Vertex& VERT) const
1651 gp_Vec V(circ->Location(),BRep_Tool::Pnt(VERT));
1655 //=======================================================================
1656 //function : ComputeOneEdgeOVertexPresentation
1658 //=======================================================================
1659 void AIS_IdenticRelation::ComputeOneEdgeOVertexPresentation(const Handle(Prs3d_Presentation)& aPrs)
1663 Standard_Integer numedge;
1665 if (myFShape.ShapeType() == TopAbs_VERTEX) {
1666 V = TopoDS::Vertex(myFShape);
1667 E = TopoDS::Edge(mySShape);
1668 numedge = 2;// edge = 2nd shape
1671 V = TopoDS::Vertex(mySShape);
1672 E = TopoDS::Edge(myFShape);
1673 numedge = 1; // edge = 1st shape
1675 gp_Pnt ptonedge1,ptonedge2;
1676 Handle(Geom_Curve) aCurve;
1677 Handle(Geom_Curve) extCurv;
1678 Standard_Boolean isInfinite;
1679 Standard_Boolean isOnPlanEdge, isOnPlanVertex;
1680 if (!AIS::ComputeGeometry(E,aCurve,ptonedge1,ptonedge2,extCurv,isInfinite,isOnPlanEdge,myPlane))
1682 aPrs->SetInfiniteState(isInfinite);
1683 AIS::ComputeGeometry(V, myFAttach, myPlane, isOnPlanVertex);
1685 // only the curve can be projected
1686 if (!isOnPlanEdge && !isOnPlanVertex) return;
1688 if (!isOnPlanEdge) {
1689 if (numedge == 1) myExtShape = 1;
1690 else myExtShape = 2;
1692 else if (!isOnPlanVertex) {
1693 if (numedge == 1) myExtShape = 2;
1694 else myExtShape = 1;
1696 // The attachement points are the point
1697 myFAttach = BRep_Tool::Pnt(V);
1698 mySAttach = myFAttach;
1701 if (myAutomaticPosition) {
1702 //Computation of the size of the symbol
1703 Standard_Real symbsize = ComputeSegSize();
1705 // Computation of the direction of the segment of the presentation
1706 // we take the median of the edges connected to vertices
1708 if ( aCurve->IsKind(STANDARD_TYPE(Geom_Line))) {
1709 myDir = ((Handle(Geom_Line)&) aCurve)->Lin().Direction();
1710 myDir.Cross(myPlane->Pln().Axis().Direction());
1712 else if (aCurve->IsKind(STANDARD_TYPE(Geom_Circle))) {
1713 Handle(Geom_Circle) CIR = (Handle(Geom_Circle)&) aCurve;
1714 myDir.SetXYZ(myFAttach.XYZ() - CIR->Location().XYZ());
1717 else if (aCurve->IsKind(STANDARD_TYPE(Geom_Ellipse))) {
1718 Handle(Geom_Ellipse) CIR = (Handle(Geom_Ellipse)&) aCurve;
1719 myDir.SetXYZ(myFAttach.XYZ() - CIR->Location().XYZ());
1721 // jfa 10/10/2000 end
1723 curpos = myFAttach.Translated(gp_Vec(myDir)*symbsize) ;
1724 myPosition = curpos;
1725 myAutomaticPosition = Standard_True;
1728 curpos = myPosition;
1731 // Presentation computation
1732 TCollection_ExtendedString vals(" -+-");
1733 DsgPrs_IdenticPresentation::Add(aPrs,
1738 if (myExtShape != 0) {
1739 if (!extCurv.IsNull()) { // the edge is not in the WP
1740 ComputeProjEdgePresentation(aPrs,E,(Handle(Geom_Line)&) aCurve,ptonedge1,ptonedge2);