1 // Created on: 1996-12-05
2 // Created by: Jean-Pierre COMBE/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 #include <Standard_NotImplemented.hxx>
24 #include <AIS_TangentRelation.ixx>
25 #include <DsgPrs_TangentPresentation.hxx>
27 #include <Select3D_SensitiveSegment.hxx>
28 #include <SelectMgr_EntityOwner.hxx>
30 #include <BRep_Tool.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <TopExp_Explorer.hxx>
36 #include <BRepAdaptor_Surface.hxx>
37 #include <BRepBuilderAPI_MakeFace.hxx>
38 #include <TopAbs_ShapeEnum.hxx>
41 #include <Geom_Plane.hxx>
42 #include <Geom_Line.hxx>
43 #include <Geom_Circle.hxx>
48 #include <gp_Circ.hxx>
53 #include <TColStd_ListIteratorOfListOfTransient.hxx>
54 #include <AIS_Shape.hxx>
55 #include <Bnd_Box.hxx>
56 #include <Precision.hxx>
57 #include <Geom_Ellipse.hxx>
58 #include <GeomAPI_ExtremaCurveCurve.hxx>
60 //=======================================================================
61 //function : Constructor
63 //=======================================================================
64 AIS_TangentRelation::AIS_TangentRelation(const TopoDS_Shape& aFShape,
65 const TopoDS_Shape& aSShape,
66 const Handle(Geom_Plane)& aPlane,
67 const Standard_Integer anExternRef)
68 :myExternRef(anExternRef)
73 myAutomaticPosition = Standard_False;
76 //=======================================================================
77 //function : ExternRef
79 //=======================================================================
80 Standard_Integer AIS_TangentRelation::ExternRef()
85 //=======================================================================
86 //function : SetExternRef
88 //=======================================================================
89 void AIS_TangentRelation::SetExternRef(const Standard_Integer aRef)
94 //=======================================================================
97 //=======================================================================
98 void AIS_TangentRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
99 const Handle(Prs3d_Presentation)& aPresentation,
100 const Standard_Integer)
102 aPresentation->Clear();
104 switch (myFShape.ShapeType())
108 ComputeTwoFacesTangent(aPresentation);
113 ComputeTwoEdgesTangent(aPresentation);
121 //=======================================================================
123 //purpose : to avoid warning
124 //=======================================================================
125 void AIS_TangentRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
126 const Handle(Prs3d_Presentation)& aPresentation)
128 // Standard_NotImplemented::Raise("AIS_TangentRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)");
129 PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
132 //=======================================================================
134 //purpose : to avoid warning
135 //=======================================================================
136 void AIS_TangentRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
137 const Handle(Graphic2d_GraphicObject)& aGraphicObject,
138 const Standard_Integer anInteger)
140 // Standard_NotImplemented::Raise("AIS_TangentRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
141 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
144 void AIS_TangentRelation::Compute(const Handle_Prs3d_Projector& aProjector,
145 const Handle_Geom_Transformation& aTransformation,
146 const Handle_Prs3d_Presentation& aPresentation)
148 // Standard_NotImplemented::Raise("AIS_TangentRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
149 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
152 //=======================================================================
153 //function : ComputeSelection
155 //=======================================================================
156 void AIS_TangentRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
157 const Standard_Integer)
160 gp_Vec vec1 = vec.Multiplied(myLength);
161 gp_Vec vec2 = vec.Multiplied(-myLength);
162 gp_Pnt p1 = myPosition.Translated(vec1);
163 gp_Pnt p2 = myPosition.Translated(vec2);
165 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
166 Handle(Select3D_SensitiveSegment) seg = new Select3D_SensitiveSegment(own,p1,p2);
167 aSelection->Add(seg);
170 //=======================================================================
171 //function : ComputeTwoFacesTangent
173 //=======================================================================
174 void AIS_TangentRelation::ComputeTwoFacesTangent
175 (const Handle(Prs3d_Presentation)& /*aPresentation*/)
179 // jfa 19/10/2000 begin
180 //=======================================================================
181 //function : ComputeTangencyPoint
183 //=======================================================================
184 static Standard_Boolean ComputeTangencyPoint(const Handle(Geom_Curve)& GC1,
185 const Handle(Geom_Curve)& GC2,
188 Standard_Real U1f = GC1->FirstParameter();
189 Standard_Real U1l = GC1->LastParameter();
190 Standard_Real U2f = GC2->FirstParameter();
191 Standard_Real U2l = GC2->LastParameter();
194 Standard_Real mindist=0;
195 GeomAPI_ExtremaCurveCurve Ex(GC1,GC2,U1f,U1l,U2f,U2l);
196 for ( Standard_Integer i = 1; i <= Ex.NbExtrema(); i++)
200 Standard_Real dist = P1.Distance(P2);
208 if ( (dist < mindist) || (dist < Precision::Confusion()) )
214 if ( dist < Precision::Confusion() )
216 if (GC1->IsInstance(STANDARD_TYPE(Geom_Line)))
218 continue; // tangent line and conic can have only one point with zero distance
220 gp_Vec aVector1,aVector2;
221 if (GC1->IsInstance(STANDARD_TYPE(Geom_Circle)))
223 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) GC1;
224 Standard_Real par_inter = ElCLib::Parameter(circle->Circ(), P1);
225 ElCLib::D1(par_inter,circle->Circ(),P1,aVector1);
227 else if (GC1->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
229 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) GC1;
230 Standard_Real par_inter = ElCLib::Parameter(ellipse->Elips(), P1);
231 ElCLib::D1(par_inter,ellipse->Elips(),P1,aVector1);
233 if (GC2->IsInstance(STANDARD_TYPE(Geom_Circle)))
235 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) GC2;
236 Standard_Real par_inter = ElCLib::Parameter(circle->Circ(), P2);
237 ElCLib::D1(par_inter,circle->Circ(),P2,aVector2);
239 else if (GC2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
241 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) GC2;
242 Standard_Real par_inter = ElCLib::Parameter(ellipse->Elips(), P2);
243 ElCLib::D1(par_inter,ellipse->Elips(),P2,aVector2);
245 // if ( aVector1.IsParallel(aVector2, 100*Precision::Angular()) ) break;
246 if ( aVector1.IsParallel(aVector2, M_PI / 360.0) ) break; // 0.5 graduce
250 return Standard_True;
252 // jfa 19/10/2000 end
254 //=======================================================================
255 //function : ComputeTwoEdgesTangent
257 //=======================================================================
258 void AIS_TangentRelation::ComputeTwoEdgesTangent(const Handle(Prs3d_Presentation)& aPresentation)
260 Handle(Geom_Curve) copy1,copy2;
261 gp_Pnt ptat11,ptat12,ptat21,ptat22;
262 Standard_Boolean isInfinite1,isInfinite2;
263 Handle(Geom_Curve) extCurv;
264 if (!AIS::ComputeGeometry(TopoDS::Edge(myFShape),
265 TopoDS::Edge(mySShape),
274 isInfinite1,isInfinite2,
280 aPresentation->SetInfiniteState(isInfinite1 || isInfinite2);
282 BRepBuilderAPI_MakeFace makeface(myPlane->Pln());
283 TopoDS_Face face(makeface.Face());
284 BRepAdaptor_Surface adp(makeface.Face());
286 Standard_Integer typArg(0);
288 if (copy1->IsInstance(STANDARD_TYPE(Geom_Line)))
292 else if (copy1->IsInstance(STANDARD_TYPE(Geom_Circle)))
296 else if (copy1->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
302 if (copy2->IsInstance(STANDARD_TYPE(Geom_Line)))
306 else if (copy2->IsInstance(STANDARD_TYPE(Geom_Circle)))
310 else if (copy2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
316 //First find the tangengy vector if exists
318 TopExp_Explorer expF(TopoDS::Edge(myFShape),TopAbs_VERTEX);
319 TopExp_Explorer expS(TopoDS::Edge(mySShape),TopAbs_VERTEX);
322 for (p = 0; expF.More(); expF.Next(),p++)
324 tab[p] = TopoDS::Vertex(expF.Current());
326 Standard_Boolean found(Standard_False);
327 for ( ; expS.More() && !found; expS.Next())
329 for ( Standard_Integer l = 0; l<=p && !found; l++)
331 found = ( expS.Current().IsSame(tab[l]));
332 if (found) VCom = TopoDS::Vertex(expS.Current());
337 gp_Pnt pint3d; // tangency point
338 gp_Dir theDir; // tangency direction
339 Standard_Real par_inter = 0.0; // parameter of tangency point
343 pint3d = BRep_Tool::Pnt(VCom);
346 // Otherwise it is found as if it was known that 2 curves
347 // are tangents (which must be the cases)
350 case 12: // circle line
352 const Handle(Geom_Line)& line = (Handle(Geom_Line)&) copy1;
353 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) copy2;
357 // it is enough to project the circus center on the straight line
358 par_inter = ElCLib::Parameter(line->Lin(), circle->Location());
359 pint3d = ElCLib::Value(par_inter, line->Lin());
362 theDir = line->Lin().Direction();
363 myLength = circle->Radius()/5.;
366 Standard_Real copy1Length = ptat12.Distance(ptat11);
367 if ( copy1Length < myLength )
368 myLength = copy1Length/3.;
372 case 21: // circle line
374 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) copy1;
375 const Handle(Geom_Line)& line = (Handle(Geom_Line)&) copy2;
379 // it is enough to project the circus center on the straight line
380 par_inter = ElCLib::Parameter(line->Lin(), circle->Location());
381 pint3d = ElCLib::Value(par_inter, line->Lin());
384 theDir = line->Lin().Direction();
385 myLength = circle->Radius()/5.;
388 Standard_Real copy2Length = ptat21.Distance(ptat22);
389 if ( copy2Length < myLength )
390 myLength = copy2Length/3.;
394 // jfa 19/10/2000 begin
395 case 13: // line ellipse
397 const Handle(Geom_Line)& line = (Handle(Geom_Line)&) copy1;
398 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) copy2;
402 ComputeTangencyPoint(line,ellipse,pint3d);
405 theDir = line->Lin().Direction();
406 myLength = ellipse->MajorRadius()/5.;
410 Standard_Real copy1Length = ptat12.Distance(ptat11);
411 if ( copy1Length < myLength )
412 myLength = copy1Length/3.;
416 case 31: // ellipse line
418 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) copy1;
419 const Handle(Geom_Line)& line = (Handle(Geom_Line)&) copy2;
423 ComputeTangencyPoint(line,ellipse,pint3d);
426 theDir = line->Lin().Direction();
427 myLength = ellipse->MajorRadius()/5.;
431 Standard_Real copy2Length = ptat21.Distance(ptat22);
432 if ( copy2Length < myLength )
433 myLength = copy2Length/3.;
437 case 22: // circle circle
439 const Handle(Geom_Circle)& circle1 = (Handle(Geom_Circle)&) copy1;
440 const Handle(Geom_Circle)& circle2 = (Handle(Geom_Circle)&) copy2;
441 Standard_Real R1 = circle1->Radius();
442 Standard_Real R2 = circle2->Radius();
443 myLength = Max(R1,R2)/5.0;
446 if ( (circle1->Location()).IsEqual(circle2->Location(),Precision::Confusion()) )
450 ElCLib::D1(par_inter,circle1->Circ(),pint3d,theVector);
454 ElCLib::D1(par_inter,circle2->Circ(),pint3d,theVector);
461 par_inter = ElCLib::Parameter(circle1->Circ(), circle2->Location());
462 ElCLib::D1(par_inter,circle1->Circ(),pint3d,theVector);
466 par_inter = ElCLib::Parameter(circle2->Circ(), circle1->Location());
467 ElCLib::D1(par_inter,circle2->Circ(),pint3d,theVector);
473 par_inter = ElCLib::Parameter(circle1->Circ(), pint3d);
474 ElCLib::D1(par_inter,circle1->Circ(),pint3d,theVector);
476 theDir = gp_Dir(theVector);
479 case 23: // circle ellipse
481 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) copy1;
482 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) copy2;
483 Standard_Real R1 = circle->Radius();
484 Standard_Real R2 = ellipse->MajorRadius();
485 myLength = Max(R1,R2)/5.0;
490 ComputeTangencyPoint(circle,ellipse,pint3d);
491 par_inter = ElCLib::Parameter(circle->Circ(), pint3d);
492 ElCLib::D1(par_inter,circle->Circ(),pint3d,theVector);
496 ComputeTangencyPoint(ellipse,circle,pint3d);
497 par_inter = ElCLib::Parameter(ellipse->Elips(), pint3d);
498 ElCLib::D1(par_inter,ellipse->Elips(),pint3d,theVector);
503 par_inter = ElCLib::Parameter(circle->Circ(), pint3d);
504 ElCLib::D1(par_inter,circle->Circ(),pint3d,theVector);
506 theDir = gp_Dir(theVector);
509 case 32: // ellipse circle
511 const Handle(Geom_Ellipse)& ellipse = (Handle(Geom_Ellipse)&) copy1;
512 const Handle(Geom_Circle)& circle = (Handle(Geom_Circle)&) copy2;
513 Standard_Real R1 = ellipse->MajorRadius();
514 Standard_Real R2 = circle->Radius();
515 myLength = Max(R1,R2)/5.0;
520 ComputeTangencyPoint(ellipse,circle,pint3d);
521 par_inter = ElCLib::Parameter( ellipse->Elips(), pint3d);
522 ElCLib::D1(par_inter,ellipse->Elips(),pint3d,theVector);
526 ComputeTangencyPoint(circle,ellipse,pint3d);
527 par_inter = ElCLib::Parameter( circle->Circ(), pint3d);
528 ElCLib::D1(par_inter,circle->Circ(),pint3d,theVector);
533 par_inter = ElCLib::Parameter(circle->Circ(), pint3d);
534 ElCLib::D1(par_inter,circle->Circ(),pint3d,theVector);
536 theDir = gp_Dir(theVector);
539 case 33: // ellipse ellipse
541 const Handle(Geom_Ellipse)& ellipse1 = (Handle(Geom_Ellipse)&) copy1;
542 const Handle(Geom_Ellipse)& ellipse2 = (Handle(Geom_Ellipse)&) copy2;
543 Standard_Real R1 = ellipse1->MajorRadius();
544 Standard_Real R2 = ellipse2->MajorRadius();
545 myLength = Max(R1,R2)/5.0;
550 ComputeTangencyPoint(ellipse1,ellipse2,pint3d);
551 par_inter = ElCLib::Parameter( ellipse1->Elips(), pint3d);
552 ElCLib::D1(par_inter,ellipse1->Elips(),pint3d,theVector);
556 ComputeTangencyPoint(ellipse2,ellipse1,pint3d);
557 par_inter = ElCLib::Parameter( ellipse2->Elips(), pint3d);
558 ElCLib::D1(par_inter,ellipse2->Elips(),pint3d,theVector);
563 par_inter = ElCLib::Parameter(ellipse1->Elips(), pint3d);
564 ElCLib::D1(par_inter,ellipse1->Elips(),pint3d,theVector);
566 theDir = gp_Dir(theVector);
569 // jfa 19/10/2000 end
577 myLength = Min(myLength,myArrowSize);
579 DsgPrs_TangentPresentation::Add(aPresentation,myDrawer,myAttach,myDir,myLength);
580 if ( (myExtShape != 0) && !extCurv.IsNull())
583 if ( myExtShape == 1 )
590 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),copy1,pf,pl);
599 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),copy2,pf,pl);