| 1 | // Created on: 1998-01-20 |
| 2 | // Created by: Julia GERASIMOVA |
| 3 | // Copyright (c) 1998-1999 Matra Datavision |
| 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
| 5 | // |
| 6 | // This file is part of Open CASCADE Technology software library. |
| 7 | // |
| 8 | // This library is free software; you can redistribute it and / or modify it |
| 9 | // under the terms of the GNU Lesser General Public 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. |
| 13 | // |
| 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
| 15 | // commercial license or contractual agreement. |
| 16 | |
| 17 | #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size |
| 18 | // if any in all dimensions. |
| 19 | |
| 20 | #include <Standard_NotImplemented.hxx> |
| 21 | |
| 22 | #include <AIS_EqualRadiusRelation.ixx> |
| 23 | |
| 24 | #include <AIS.hxx> |
| 25 | #include <DsgPrs_EqualRadiusPresentation.hxx> |
| 26 | #include <BRepAdaptor_Curve.hxx> |
| 27 | #include <TopoDS.hxx> |
| 28 | #include <gp_Circ.hxx> |
| 29 | #include <Geom_Circle.hxx> |
| 30 | #include <ElCLib.hxx> |
| 31 | #include <SelectMgr_EntityOwner.hxx> |
| 32 | #include <Select3D_SensitiveSegment.hxx> |
| 33 | #include <Select3D_SensitiveBox.hxx> |
| 34 | #include <Precision.hxx> |
| 35 | #include <GeomAPI_ProjectPointOnSurf.hxx> |
| 36 | #include <Prs3d_DimensionAspect.hxx> |
| 37 | #include <Prs3d_ArrowAspect.hxx> |
| 38 | #include <AIS_Drawer.hxx> |
| 39 | |
| 40 | //======================================================================= |
| 41 | //function : AIS_EqualRadiusRelation |
| 42 | //purpose : |
| 43 | //======================================================================= |
| 44 | |
| 45 | AIS_EqualRadiusRelation::AIS_EqualRadiusRelation( const TopoDS_Edge& aFirstEdge, |
| 46 | const TopoDS_Edge& aSecondEdge, |
| 47 | const Handle( Geom_Plane )& aPlane ) |
| 48 | :AIS_Relation() |
| 49 | { |
| 50 | myFShape = aFirstEdge; |
| 51 | mySShape = aSecondEdge; |
| 52 | myPlane = aPlane; |
| 53 | } |
| 54 | |
| 55 | //======================================================================= |
| 56 | //function : Compute |
| 57 | //purpose : |
| 58 | //======================================================================= |
| 59 | |
| 60 | void AIS_EqualRadiusRelation::Compute( const Handle( PrsMgr_PresentationManager3d )&, |
| 61 | const Handle( Prs3d_Presentation )& aPresentation, |
| 62 | const Standard_Integer ) |
| 63 | { |
| 64 | aPresentation->Clear(); |
| 65 | |
| 66 | BRepAdaptor_Curve FirstCurve( TopoDS::Edge( myFShape ) ), SecondCurve( TopoDS::Edge( mySShape ) ); |
| 67 | |
| 68 | Standard_Real FirstPar1 = FirstCurve.FirstParameter(), LastPar1 = FirstCurve.LastParameter(), |
| 69 | FirstPar2 = SecondCurve.FirstParameter(), LastPar2 = SecondCurve.LastParameter(); |
| 70 | |
| 71 | Handle( Geom_Curve ) FirstProjCurve = FirstCurve.Curve().Curve(), |
| 72 | SecondProjCurve = SecondCurve.Curve().Curve(); |
| 73 | gp_Pnt FirstPoint1, LastPoint1, FirstPoint2, LastPoint2; |
| 74 | Standard_Boolean isFirstOnPlane, isSecondOnPlane; |
| 75 | |
| 76 | AIS::ComputeGeomCurve( FirstProjCurve, FirstPar1, LastPar1, FirstPoint1, LastPoint1, myPlane, isFirstOnPlane ); |
| 77 | AIS::ComputeGeomCurve( SecondProjCurve, FirstPar2, LastPar2, FirstPoint2, LastPoint2, myPlane, isSecondOnPlane ); |
| 78 | |
| 79 | if (!isFirstOnPlane) |
| 80 | ComputeProjEdgePresentation( aPresentation, TopoDS::Edge( myFShape ), FirstProjCurve, FirstPoint1, LastPoint1 ); |
| 81 | if (! isSecondOnPlane) |
| 82 | ComputeProjEdgePresentation( aPresentation, TopoDS::Edge( mySShape ), SecondProjCurve, FirstPoint2, LastPoint2 ); |
| 83 | |
| 84 | gp_Circ FirstCirc = (Handle( Geom_Circle )::DownCast( FirstProjCurve ))->Circ(); |
| 85 | gp_Circ SecondCirc = (Handle( Geom_Circle )::DownCast( SecondProjCurve ))->Circ(); |
| 86 | |
| 87 | myFirstCenter = FirstCirc.Location(); |
| 88 | mySecondCenter = SecondCirc.Location(); |
| 89 | |
| 90 | //ota -- begin -- |
| 91 | if (myAutomaticPosition) |
| 92 | { |
| 93 | myFirstPoint = ElCLib::Value( (FirstPar1 + LastPar1)*0.5, FirstCirc ); |
| 94 | mySecondPoint = ElCLib::Value( (FirstPar2 + LastPar2)*0.5, SecondCirc ); |
| 95 | } |
| 96 | else { |
| 97 | Standard_Real aPar = ElCLib::Parameter(FirstCirc, myFirstPoint); |
| 98 | if (IntegerPart(0.5*LastPar1/M_PI) != 0 && aPar < FirstPar1 ) |
| 99 | aPar +=2*M_PI*IntegerPart(0.5*LastPar1/M_PI); |
| 100 | Standard_Real aRadius = FirstCirc.Radius(); |
| 101 | |
| 102 | if (Abs(myFirstPoint.Distance(myFirstCenter) - aRadius) >= Precision::Confusion()) |
| 103 | myFirstPoint = ElCLib::Value(aPar, FirstCirc); |
| 104 | if ( FirstPoint1.Distance(LastPoint1) > Precision::Confusion()){ |
| 105 | //check where is myFirstPoint |
| 106 | if (aPar > LastPar1 || aPar < FirstPar1) |
| 107 | { |
| 108 | //myFirstPoint is out of Arc of FirstCircle |
| 109 | if (FirstPoint1.Distance(myFirstPoint)< LastPoint1.Distance(myFirstPoint)) |
| 110 | myFirstPoint = FirstPoint1; |
| 111 | else |
| 112 | myFirstPoint = LastPoint1; |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | |
| 117 | aPar = ElCLib::Parameter(SecondCirc, mySecondPoint); |
| 118 | if (IntegerPart(0.5*LastPar2/M_PI) != 0 && aPar < FirstPar2 ) |
| 119 | aPar +=2*M_PI*IntegerPart(0.5*LastPar2/M_PI); |
| 120 | |
| 121 | aRadius = SecondCirc.Radius(); |
| 122 | if (Abs(mySecondPoint.Distance(mySecondCenter) - aRadius) >= Precision::Confusion()) |
| 123 | mySecondPoint = ElCLib::Value(aPar, SecondCirc); |
| 124 | if (FirstPoint2.Distance(LastPoint2) > Precision::Confusion()){ |
| 125 | if (aPar > LastPar2 || aPar < FirstPar2) |
| 126 | { //mySecondPoint is out of Arc of mySecondCircle |
| 127 | if (FirstPoint2.Distance(mySecondPoint)< LastPoint2.Distance(mySecondPoint)) |
| 128 | mySecondPoint = FirstPoint2; |
| 129 | else |
| 130 | mySecondPoint = LastPoint2; |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | #ifdef BUC60915 |
| 135 | if( !myArrowSizeIsDefined ) |
| 136 | #endif |
| 137 | myArrowSize = (Min(myFirstCenter.Distance(myFirstPoint), |
| 138 | mySecondCenter.Distance(mySecondPoint)))*0.05; |
| 139 | |
| 140 | Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect(); |
| 141 | Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect(); |
| 142 | arr->SetLength(myArrowSize); |
| 143 | |
| 144 | //ota -- end -- |
| 145 | |
| 146 | DsgPrs_EqualRadiusPresentation::Add(aPresentation, myDrawer, |
| 147 | myFirstCenter, mySecondCenter, myFirstPoint, mySecondPoint, myPlane ); |
| 148 | } |
| 149 | |
| 150 | //======================================================================= |
| 151 | //function : Compute |
| 152 | //purpose : to avoid warning at compilation (SUN) |
| 153 | //======================================================================= |
| 154 | |
| 155 | void AIS_EqualRadiusRelation::Compute( const Handle( Prs3d_Projector )& /*aProjector*/, |
| 156 | const Handle( Prs3d_Presentation )& /*aPresentation*/) |
| 157 | { |
| 158 | // Standard_NotImplemented::Raise("AIS_EqualRadiusRelation::Compute( const Handle( Prs3d_Projector )&,const Handle( Prs3d_Presentation )& )"); |
| 159 | // PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ; |
| 160 | } |
| 161 | |
| 162 | //======================================================================= |
| 163 | //function : Compute |
| 164 | //purpose : |
| 165 | //======================================================================= |
| 166 | |
| 167 | void AIS_EqualRadiusRelation::Compute(const Handle_Prs3d_Projector& aProjector, |
| 168 | const Handle_Geom_Transformation& aTransformation, |
| 169 | const Handle_Prs3d_Presentation& aPresentation) |
| 170 | { |
| 171 | // Standard_NotImplemented::Raise("AIS_EqualRadiusRelation::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)"); |
| 172 | PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ; |
| 173 | } |
| 174 | |
| 175 | //======================================================================= |
| 176 | //function : ComputeSelection |
| 177 | //purpose : |
| 178 | //======================================================================= |
| 179 | |
| 180 | void AIS_EqualRadiusRelation::ComputeSelection( const Handle( SelectMgr_Selection )& aSelection, |
| 181 | const Standard_Integer ) |
| 182 | { |
| 183 | Handle( SelectMgr_EntityOwner ) own = new SelectMgr_EntityOwner( this, 7 ); |
| 184 | Handle( Select3D_SensitiveSegment ) seg; |
| 185 | |
| 186 | seg = new Select3D_SensitiveSegment( own, myFirstCenter, myFirstPoint ); |
| 187 | aSelection->Add( seg ); |
| 188 | |
| 189 | if(!myAutomaticPosition) |
| 190 | ComputeRadiusPosition(); |
| 191 | |
| 192 | seg = new Select3D_SensitiveSegment( own, mySecondCenter, mySecondPoint ); |
| 193 | aSelection->Add( seg ); |
| 194 | |
| 195 | seg = new Select3D_SensitiveSegment( own, myFirstCenter, mySecondCenter ); |
| 196 | aSelection->Add( seg ); |
| 197 | |
| 198 | |
| 199 | // Two small lines |
| 200 | gp_Pnt Middle( (myFirstCenter.XYZ() + mySecondCenter.XYZ())*0.5 ); |
| 201 | |
| 202 | Standard_Real SmallDist = .001; |
| 203 | //Should be changed as the domain of small lines could be changed. |
| 204 | Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox(own, |
| 205 | Middle.X() - SmallDist, |
| 206 | Middle.Y() - SmallDist, |
| 207 | Middle.Z() - SmallDist, |
| 208 | Middle.X() + SmallDist, |
| 209 | Middle.Y() + SmallDist, |
| 210 | Middle.Z() + SmallDist ); |
| 211 | aSelection->Add(box); |
| 212 | } |
| 213 | |
| 214 | //================================================================= |
| 215 | //function : ComputeRadiusPosition |
| 216 | //purpose : |
| 217 | //================================================================= |
| 218 | void AIS_EqualRadiusRelation::ComputeRadiusPosition() |
| 219 | { |
| 220 | if (myAutomaticPosition || |
| 221 | myFirstCenter.Distance(myPosition) < Precision::Confusion() || |
| 222 | mySecondCenter.Distance(myPosition) < Precision::Confusion()) |
| 223 | return; |
| 224 | |
| 225 | gp_Pnt aPosition; |
| 226 | |
| 227 | //project myPosition to the plane of constraint |
| 228 | GeomAPI_ProjectPointOnSurf aProj(myPosition, myPlane); |
| 229 | aPosition = aProj.NearestPoint(); |
| 230 | |
| 231 | Standard_Real aDist1 = myFirstPoint.Distance(aPosition); |
| 232 | Standard_Real aDist2 = mySecondPoint.Distance(aPosition); |
| 233 | |
| 234 | if(aDist1<aDist2) |
| 235 | { |
| 236 | Standard_Real Rad1 = myFirstPoint.Distance(myFirstCenter); |
| 237 | const gp_Dir aNewDir1(aPosition.XYZ() - myFirstCenter.XYZ()); |
| 238 | const gp_Vec aTVec (aNewDir1.XYZ()*Rad1); |
| 239 | myFirstPoint = myFirstCenter.Translated(aTVec); |
| 240 | } |
| 241 | else { |
| 242 | Standard_Real Rad2 = mySecondPoint.Distance(mySecondCenter); |
| 243 | const gp_Dir aNewDir2(aPosition.XYZ() - mySecondCenter.XYZ()); |
| 244 | gp_Vec aTVec (aNewDir2.XYZ()*Rad2); |
| 245 | mySecondPoint = mySecondCenter.Translated(aTVec); |
| 246 | } |
| 247 | |
| 248 | } |
| 249 | |