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_PerpendicularRelation.ixx>
28 #include <BRepBuilderAPI_MakeFace.hxx>
29 #include <BRepAdaptor_Surface.hxx>
30 #include <BRep_Tool.hxx>
32 #include <DsgPrs_PerpenPresentation.hxx>
36 #include <Geom2d_Line.hxx>
37 #include <GeomAPI.hxx>
38 #include <Geom_Line.hxx>
39 #include <Geom_Line.hxx>
40 #include <Geom_Plane.hxx>
42 #include <IntAna2d_AnaIntersection.hxx>
43 #include <IntAna2d_IntPoint.hxx>
45 #include <Precision.hxx>
47 #include <Select3D_SensitiveSegment.hxx>
48 #include <SelectMgr_EntityOwner.hxx>
51 #include <TopoDS_Edge.hxx>
52 #include <TopoDS_Face.hxx>
53 #include <TopoDS_Vertex.hxx>
55 #include <gce_MakeDir.hxx>
59 #include <gp_Pnt2d.hxx>
60 #include <gp_Trsf.hxx>
62 #include <Geom_Ellipse.hxx>
64 //=======================================================================
65 //function : Constructor
66 //purpose : TwoEdgesPerpendicular
67 //=======================================================================
68 AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape,
69 const TopoDS_Shape& aSShape,
70 const Handle(Geom_Plane)& aPlane)
78 //=======================================================================
79 //function : Constructor
80 //purpose : TwoFacesPerpendicular
81 //=======================================================================
82 AIS_PerpendicularRelation::AIS_PerpendicularRelation(const TopoDS_Shape& aFShape,
83 const TopoDS_Shape& aSShape)
90 //=======================================================================
93 //=======================================================================
94 void AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&,
95 const Handle(Prs3d_Presentation)& aPresentation,
96 const Standard_Integer)
98 aPresentation->Clear();
100 if (myFShape.ShapeType() == mySShape.ShapeType()) {
101 switch (myFShape.ShapeType()) {
104 // cas perpendiculaire entre deux faces
105 ComputeTwoFacesPerpendicular(aPresentation);
110 // cas perpendiculaire entre deux edges
111 ComputeTwoEdgesPerpendicular(aPresentation);
118 // Cas pas traite - Edge/Face
121 //=======================================================================
123 //purpose : to avoid warning
124 //=======================================================================
125 void AIS_PerpendicularRelation::Compute(const Handle(Prs3d_Projector)& aProjector,
126 const Handle(Prs3d_Presentation)& aPresentation)
128 // Standard_NotImplemented::Raise("AIS_PerpendicularRelation::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_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager2d)& aPresentationManager2d,
137 const Handle(Graphic2d_GraphicObject)&
139 const Standard_Integer anInteger)
141 // Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle(PrsMgr_PresentationManager2d)&,const Handle(Graphic2d_GraphicObject)&,const Standard_Integer)");
142 PrsMgr_PresentableObject::Compute( aPresentationManager2d ,aGraphicObject,anInteger) ;
145 void AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector& aProjector, const Handle_Geom_Transformation& aTransformation, const Handle_Prs3d_Presentation& aPresentation)
147 // Standard_NotImplemented::Raise("AIS_PerpendicularRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)");
148 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
151 //=======================================================================
152 //function : ComputeSelection
154 //=======================================================================
155 void AIS_PerpendicularRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
156 const Standard_Integer)
158 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
159 const gp_Pnt& pos = myPosition;
160 Handle(Select3D_SensitiveSegment) seg;
161 Standard_Boolean ok1(Standard_False),ok2(Standard_False);
163 if (!myFAttach.IsEqual(pos,Precision::Confusion())) {
164 seg = new Select3D_SensitiveSegment(own,
167 aSelection->Add(seg);
170 if (!mySAttach.IsEqual(myPosition,Precision::Confusion())) {
171 seg = new Select3D_SensitiveSegment(own,
174 aSelection->Add(seg);
179 gp_Vec vec1(gce_MakeDir(pos,myFAttach));
180 gp_Vec vec2(gce_MakeDir(pos,mySAttach));
181 Standard_Real dist1(pos.Distance(myFAttach));
182 Standard_Real dist2(pos.Distance(mySAttach));
188 gp_Pnt pAx11 = pos.Translated(vec1);
189 gp_Pnt pAx22 = pos.Translated(vec2);
190 gp_Pnt p_symb = pAx22.Translated(vec1);
191 seg = new Select3D_SensitiveSegment(own,pAx11,p_symb);
192 aSelection->Add(seg);
193 seg = new Select3D_SensitiveSegment(own,p_symb,pAx22);
194 aSelection->Add(seg);
198 //=======================================================================
199 //function : ComputeTwoFacesPerpendicular
201 //=======================================================================
202 void AIS_PerpendicularRelation::ComputeTwoFacesPerpendicular
203 (const Handle(Prs3d_Presentation)& /*aPresentation*/)
207 //=======================================================================
208 //function : ComputeTwoEdgesPerpendicular
210 //=======================================================================
211 void AIS_PerpendicularRelation::ComputeTwoEdgesPerpendicular(const Handle(Prs3d_Presentation)& aPresentation)
214 Handle(Geom_Curve) geom1,geom2;
215 gp_Pnt pint3d,p1,p2,pAx1,pAx2,ptat11,ptat12,ptat21,ptat22;
216 Standard_Boolean isInfinite1,isInfinite2;
217 Handle(Geom_Curve) extCurv;
218 if ( !AIS::ComputeGeometry(TopoDS::Edge(myFShape),TopoDS::Edge(mySShape),
221 ptat11,ptat12,ptat21,ptat22,
223 isInfinite1,isInfinite2,
226 Standard_Boolean interOut1(Standard_False),interOut2(Standard_False);
228 Handle(Geom_Line) geom_lin1;
229 Handle(Geom_Line) geom_lin2;
230 if ( geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse)) )
232 const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom1;
233 // construct lines through focuses
234 gp_Ax1 elAx = geom_el->XAxis();
236 geom_lin1 = new Geom_Line(ll);
237 Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
238 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
239 ptat11 = geom_el->Focus1().Translated(transvec);
240 ptat12 = geom_el->Focus2().Translated(-transvec);
241 interOut1 = Standard_True;
243 else if ( geom1->IsInstance(STANDARD_TYPE(Geom_Line)) )
245 geom_lin1 = (Handle(Geom_Line)&) geom1;
249 if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse)))
251 const Handle(Geom_Ellipse)& geom_el = (Handle(Geom_Ellipse)&) geom2;
252 // construct lines through focuses
253 gp_Ax1 elAx = geom_el->XAxis();
255 geom_lin2 = new Geom_Line(ll);
256 Standard_Real focex = geom_el->MajorRadius() - geom_el->Focal()/2.0;
257 gp_Vec transvec = gp_Vec(elAx.Direction())*focex;
258 ptat21 = geom_el->Focus1().Translated(transvec);
259 ptat22 = geom_el->Focus2().Translated(-transvec);
260 interOut2 = Standard_True;
262 else if ( geom2->IsInstance(STANDARD_TYPE(Geom_Line)) )
264 geom_lin2 = (Handle(Geom_Line)&) geom2;
269 BRepBuilderAPI_MakeFace makeface (myPlane->Pln());
270 TopoDS_Face face (makeface.Face());
271 BRepAdaptor_Surface adp (makeface.Face());
273 // 2d lines => projection of 3d on current plane
274 Handle(Geom2d_Curve) aGeom2dCurve = GeomAPI::To2d(geom_lin1,myPlane->Pln());
275 Handle(Geom2d_Line) lin1_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
276 aGeom2dCurve = GeomAPI::To2d(geom_lin2,myPlane->Pln());
277 Handle(Geom2d_Line) lin2_2d = (Handle(Geom2d_Line)&) aGeom2dCurve ;
278 IntAna2d_AnaIntersection inter(lin1_2d->Lin2d(),lin2_2d->Lin2d());
279 if (!inter.IsDone()) return;
280 if (!inter.NbPoints()) return;
282 gp_Pnt2d pint(inter.Point(1).Value());
283 pint3d = adp.Value(pint.X(),pint.Y());
286 // recherche points attache
287 Standard_Real par1,par2,curpar,pmin,pmax;//,dist,sign;
288 Standard_Real length(0.);
290 if ( isInfinite1 && isInfinite2 )
292 Standard_Real curpar1 = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
293 Standard_Real curpar2 = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
296 myFAttach = ElCLib::Value(curpar1+par1,geom_lin1->Lin());
297 mySAttach = ElCLib::Value(curpar2+par2,geom_lin2->Lin());
301 Standard_Boolean lengthComputed (Standard_False);
304 curpar = ElCLib::Parameter(geom_lin1->Lin(),pint3d);
305 par1 = ElCLib::Parameter(geom_lin1->Lin(),ptat11);
306 par2 = ElCLib::Parameter(geom_lin1->Lin(),ptat12);
307 pmin = Min(par1,par2);
308 pmax = Max(par1,par2);
310 if ( myPosition.SquareDistance(ptat11) > myPosition.SquareDistance(ptat12) )
314 if ( (curpar < pmin) || (curpar > pmax) )
316 interOut1 = Standard_True;
318 if ( !isInfinite2 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
319 else length = 2.*ptat11.Distance(ptat12)/5.;
320 lengthComputed = Standard_True;
321 gp_Vec vec1 (gce_MakeDir(myPosition,p1));
322 vec1.Multiply(length);
323 pAx1 = myPosition.Translated(vec1);
328 curpar = ElCLib::Parameter(geom_lin2->Lin(),pint3d);
329 par1 = ElCLib::Parameter(geom_lin2->Lin(),ptat21);
330 par2 = ElCLib::Parameter(geom_lin2->Lin(),ptat22);
331 pmin = Min(par1,par2);
332 pmax = Max(par1,par2);
334 if ( myPosition.SquareDistance(ptat21) > myPosition.SquareDistance(ptat22) ) p2 = ptat21;
336 if ( (curpar < pmin) || (curpar > pmax) )
338 interOut2 = Standard_True;
340 gp_Vec vec2 (gce_MakeDir(myPosition,p2));
341 if ( !lengthComputed )
343 if ( !isInfinite1 ) length = 2.*Min(ptat11.Distance(ptat12),ptat21.Distance(ptat22))/5.;
344 else length = 2.*ptat21.Distance(ptat22)/5.;
346 vec2.Multiply(length);
347 pAx2 = myPosition.Translated(vec2);
353 gp_Vec vec1(geom_lin1->Lin().Direction());
354 vec1.Multiply(length);
355 myFAttach = myPosition.Translated(vec1);
360 gp_Vec vec2(geom_lin2->Lin().Direction());
361 vec2.Multiply(length);
362 mySAttach = myPosition.Translated(vec2);
365 DsgPrs_PerpenPresentation::Add(aPresentation,myDrawer,
369 interOut1,interOut2);
371 if ( (myExtShape != 0) && !extCurv.IsNull()) {
373 if ( myExtShape == 1 ) {
378 aPresentation->SetInfiniteState(isInfinite1);
379 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(myFShape),geom_lin1,pf,pl);
386 aPresentation->SetInfiniteState(isInfinite2);
387 ComputeProjEdgePresentation(aPresentation,TopoDS::Edge(mySShape),geom_lin2,pf,pl);