Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-12-05 |
2 | // Created by: Jean-Pierre COMBE/Odile Olivier/Serguei Zaritchny | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
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. | |
10 | // | |
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. | |
13 | // | |
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. | |
20 | ||
7fd59977 | 21 | // modified <SZY> 20-feb-98 |
22 | // <VBU> myFShape could be a wire. | |
23 | ||
24 | #define BUC60915 //GG 05/06/01 Enable to compute the requested arrow size | |
25 | // if any in all dimensions. | |
26 | ||
27 | #include <Standard_NotImplemented.hxx> | |
28 | ||
29 | #include <AIS_RadiusDimension.ixx> | |
30 | ||
31 | #include <AIS_DimensionOwner.hxx> | |
32 | #include <DsgPrs_RadiusPresentation.hxx> | |
33 | #include <DsgPrs.hxx> | |
34 | ||
35 | #include <Geom_Surface.hxx> | |
36 | #include <Geom_Plane.hxx> | |
37 | #include <Geom_Circle.hxx> | |
38 | #include <Geom_Curve.hxx> | |
39 | #include <Geom_TrimmedCurve.hxx> | |
40 | #include <Geom_ToroidalSurface.hxx> | |
41 | #include <Geom_CylindricalSurface.hxx> | |
42 | #include <Geom_SurfaceOfLinearExtrusion.hxx> | |
43 | ||
44 | #include <gp_Circ.hxx> | |
45 | #include <gp_Pnt.hxx> | |
46 | #include <gp_Trsf.hxx> | |
47 | #include <ElCLib.hxx> | |
48 | #include <GC_MakeCircle.hxx> | |
49 | #include <gce_MakeLin.hxx> | |
50 | #include <gce_MakeCirc.hxx> | |
51 | ||
52 | #include <SelectMgr_EntityOwner.hxx> | |
53 | #include <Select3D_SensitiveSegment.hxx> | |
54 | ||
55 | #include <Precision.hxx> | |
56 | ||
57 | #include <TopExp_Explorer.hxx> | |
58 | #include <TopAbs_ShapeEnum.hxx> | |
59 | #include <TopoDS.hxx> | |
60 | #include <TopoDS_Face.hxx> | |
61 | #include <TopoDS_Wire.hxx> | |
62 | #include <TopoDS_Edge.hxx> | |
63 | #include <TopLoc_Location.hxx> | |
64 | #include <BRep_Tool.hxx> | |
65 | #include <BRepAdaptor_Surface.hxx> | |
66 | #include <BRepAdaptor_Curve.hxx> | |
67 | #include <Adaptor3d_HCurve.hxx> | |
68 | ||
69 | #include <Prs3d_AngleAspect.hxx> | |
70 | #include <Prs3d_ArrowAspect.hxx> | |
71 | #include <Prs3d_LengthAspect.hxx> | |
72 | #include <Prs3d_Drawer.hxx> | |
73 | ||
74 | #include <TCollection_AsciiString.hxx> | |
75 | #include <TCollection_ExtendedString.hxx> | |
76 | ||
77 | ||
78 | #include <AIS.hxx> | |
79 | #include <AIS_Drawer.hxx> | |
80 | #include <gce_MakeDir.hxx> | |
81 | #include <Select3D_SensitiveBox.hxx> | |
82 | ||
83 | ||
84 | ||
85 | //====================================================================== | |
86 | //function : CircleFromPlanarFace | |
87 | //purpose : if possible gets circle from planar face | |
88 | //======================================================================= | |
89 | static Standard_Boolean CircleFromPlanarFace (const TopoDS_Shape& aFace, | |
90 | Handle(Geom_Curve)& aCurve, | |
91 | gp_Pnt & ptfirst, | |
92 | gp_Pnt & ptend) | |
93 | { | |
94 | TopExp_Explorer ExploEd (aFace, TopAbs_EDGE); | |
95 | for ( ; ExploEd.More(); ExploEd.Next()) | |
96 | { | |
97 | TopoDS_Edge curedge = TopoDS::Edge (ExploEd.Current()); | |
98 | if (AIS::ComputeGeometry (curedge, aCurve, ptfirst, ptend)) | |
99 | if (aCurve->IsInstance (STANDARD_TYPE(Geom_Circle)) && | |
100 | !Handle(Geom_Circle)::DownCast(aCurve).IsNull()) | |
101 | return Standard_True; | |
102 | } | |
103 | return Standard_False; | |
104 | } | |
105 | ||
106 | ||
107 | //======================================================================= | |
108 | //function : Constructor | |
109 | //purpose : | |
110 | //======================================================================= | |
111 | AIS_RadiusDimension::AIS_RadiusDimension(const TopoDS_Shape& aShape, | |
112 | const Standard_Real aVal, | |
113 | const TCollection_ExtendedString& aText) | |
114 | :mydrawFromCenter(Standard_True) | |
115 | { | |
116 | myFShape = aShape; | |
117 | myVal = aVal; | |
118 | myText = aText; | |
119 | mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR; | |
120 | myAutomaticPosition = Standard_True; | |
121 | ||
122 | myArrowSize = myVal / 100.; | |
123 | InitFirstShape(); | |
124 | } | |
125 | ||
126 | //======================================================================= | |
127 | //function : Constructor | |
128 | //purpose :(avec position et texte) | |
129 | //======================================================================= | |
130 | AIS_RadiusDimension::AIS_RadiusDimension( const TopoDS_Shape& aShape, | |
131 | const Standard_Real aVal, | |
132 | const TCollection_ExtendedString& aText, | |
133 | const gp_Pnt& aPosition, | |
134 | const DsgPrs_ArrowSide aSymbolPrs, | |
135 | const Standard_Real anArrowSize ) | |
136 | :mydrawFromCenter(Standard_True) | |
137 | { | |
138 | myFShape = aShape; | |
139 | myVal = aVal; | |
140 | myText = aText; | |
141 | myPosition = aPosition; | |
142 | mySymbolPrs = aSymbolPrs; | |
143 | #ifdef BUC60915 | |
144 | SetArrowSize( anArrowSize ); | |
145 | #else | |
146 | myArrowSize = anArrowSize; | |
147 | #endif | |
148 | myAutomaticPosition = Standard_False; | |
149 | InitFirstShape(); | |
150 | } | |
151 | ||
152 | //======================================================================= | |
153 | //function : InitFirstShape | |
154 | //purpose : | |
155 | //======================================================================= | |
156 | void AIS_RadiusDimension::InitFirstShape() | |
157 | { | |
158 | if (myFShape.ShapeType() == TopAbs_FACE) | |
159 | { | |
160 | BRepAdaptor_Surface surfAlgo( TopoDS::Face( myFShape ) ); | |
161 | Standard_Real uFirst, uLast, vFirst, vLast; | |
162 | uFirst = surfAlgo.FirstUParameter(); | |
163 | uLast = surfAlgo.LastUParameter(); | |
164 | vFirst = surfAlgo.FirstVParameter(); | |
165 | vLast = surfAlgo.LastVParameter(); | |
166 | Standard_Real uMoy = (uFirst + uLast)/2; | |
167 | Standard_Real vMoy = (vFirst + vLast)/2; | |
168 | Handle( Geom_Surface ) surf = surfAlgo.Surface().Surface(); | |
169 | surf = Handle( Geom_Surface )::DownCast( surf->Transformed( surfAlgo.Trsf() ) ); | |
170 | Handle( Geom_Curve ) aCurve; | |
171 | ||
172 | if (surf->DynamicType() == STANDARD_TYPE(Geom_ToroidalSurface)) | |
173 | { | |
174 | aCurve = surf->UIso( uMoy ); | |
175 | uFirst = vFirst; | |
176 | uLast = vLast; | |
177 | } | |
178 | else if (surf->DynamicType() == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) | |
179 | { | |
180 | Handle( Adaptor3d_HCurve ) BasisCurve = surfAlgo.BasisCurve(); | |
181 | if ( BasisCurve->GetType() == GeomAbs_Circle ) | |
182 | aCurve = surf->VIso( vMoy ); | |
183 | else return; | |
184 | } | |
185 | else if (surf->DynamicType() == STANDARD_TYPE(Geom_Plane)) | |
186 | { | |
187 | gp_Pnt FirstPnt, LastPnt; | |
188 | if (CircleFromPlanarFace (TopoDS::Face(myFShape), aCurve, FirstPnt, LastPnt)) | |
189 | // if (CircleFromPlanarFace (myFShape, aCurve, FirstPnt, LastPnt)) | |
190 | { | |
191 | uFirst = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), FirstPnt); | |
192 | uLast = ElCLib::Parameter ((Handle(Geom_Circle)::DownCast( aCurve ))->Circ(), LastPnt); | |
193 | } | |
194 | else return; | |
195 | } | |
196 | else | |
197 | aCurve = surf->VIso( vMoy ); | |
198 | ||
199 | if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) | |
200 | myCircle = (Handle( Geom_Circle )::DownCast( aCurve ))->Circ(); | |
201 | else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve)) { | |
202 | Handle(Geom_TrimmedCurve) tCurve = Handle(Geom_TrimmedCurve)::DownCast(aCurve); | |
203 | aCurve = tCurve->BasisCurve(); | |
204 | uFirst = tCurve->FirstParameter(); | |
205 | uLast = tCurve->LastParameter(); | |
206 | if (aCurve->DynamicType() == STANDARD_TYPE(Geom_Circle)) | |
207 | myCircle = Handle(Geom_Circle)::DownCast(aCurve)->Circ();//gp_Circ | |
208 | else return; | |
209 | } | |
210 | else if (aCurve->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) { | |
211 | gp_Pnt P1,P2,P3; | |
212 | aCurve->D0(uFirst,P1); | |
213 | aCurve->D0((uFirst+uLast)/2,P2); | |
214 | aCurve->D0(uLast,P3); | |
215 | gce_MakeCirc MakeCirc = gce_MakeCirc(P1,P2,P3); | |
216 | myCircle = MakeCirc.Value(); | |
217 | uFirst = ElCLib::Parameter(myCircle,P1); | |
218 | uLast = ElCLib::Parameter(myCircle,P2); | |
219 | } | |
220 | ||
221 | myFirstPar = uFirst; | |
222 | myLastPar = uLast; | |
223 | } // TopAbs_FACE | |
224 | ||
225 | else // it is edge or a wire | |
226 | { | |
227 | TopoDS_Edge anEdge; | |
228 | if (myFShape.ShapeType() == TopAbs_WIRE) { | |
229 | TopExp_Explorer exp (myFShape,TopAbs_EDGE); | |
230 | if (exp.More()) anEdge = TopoDS::Edge (exp.Current()); | |
231 | } | |
232 | else { | |
233 | if ( myFShape.ShapeType() == TopAbs_EDGE) { | |
234 | anEdge = TopoDS::Edge (myFShape); | |
235 | BRepAdaptor_Curve AdaptedCurve (anEdge); | |
236 | if (!AdaptedCurve.GetType() == GeomAbs_Circle) return; | |
237 | ||
238 | myCircle = AdaptedCurve.Circle(); | |
239 | myFirstPar = AdaptedCurve.FirstParameter(); | |
240 | myLastPar = AdaptedCurve.LastParameter(); | |
241 | } | |
242 | #ifdef DEB | |
243 | else { | |
244 | cout << "AIS_RadiusDimension::InitFirstShape ==> myFShape.ShapeType() == " << myFShape.ShapeType() << endl; | |
245 | } | |
246 | #endif | |
247 | } | |
248 | } | |
249 | ||
250 | myCenter = myCircle.Location(); | |
251 | myCircle.SetRadius(myVal); | |
c6541a0c D |
252 | while (myFirstPar > 2*M_PI) myFirstPar -= 2*M_PI; |
253 | while (myFirstPar < 0.0 ) myFirstPar += 2*M_PI; | |
254 | while (myLastPar > 2*M_PI) myLastPar -= 2*M_PI; | |
255 | while (myLastPar < 0.0 ) myLastPar += 2*M_PI; | |
7fd59977 | 256 | myPlane = new Geom_Plane(gp_Pln(gp_Ax3(myCircle.Position()))); |
257 | myFirstLine = gce_MakeLin( myCenter, ElCLib::Value( myFirstPar, myCircle ) ); | |
258 | myLastLine = gce_MakeLin( myCenter, ElCLib::Value( myLastPar, myCircle ) ); | |
259 | } | |
260 | ||
261 | //======================================================================= | |
262 | //function : SetFirstShape | |
263 | //purpose : | |
264 | //======================================================================= | |
265 | void AIS_RadiusDimension::SetFirstShape( const TopoDS_Shape& aFShape ) | |
266 | { | |
267 | myFShape = aFShape; | |
268 | InitFirstShape(); | |
269 | } | |
270 | ||
271 | //======================================================================= | |
272 | //function : Compute | |
273 | //purpose : | |
274 | //======================================================================= | |
275 | void AIS_RadiusDimension::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentationManager*/, | |
276 | const Handle(Prs3d_Presentation)& aPresentation, | |
277 | const Standard_Integer /*aMode*/) | |
278 | { | |
279 | aPresentation->Clear(); | |
280 | ||
281 | ComputeRadius( aPresentation ); | |
282 | } | |
283 | ||
284 | //======================================================================= | |
285 | //function : Compute | |
286 | //purpose : to avoid warning | |
287 | //======================================================================= | |
288 | void AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector, | |
289 | const Handle(Prs3d_Presentation)& aPresentation) | |
290 | { | |
291 | // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)"); | |
292 | PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ; | |
293 | } | |
294 | ||
7fd59977 | 295 | //======================================================================= |
296 | //function : Compute | |
297 | //purpose : | |
298 | //======================================================================= | |
299 | ||
300 | void AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector& aProjector, | |
301 | const Handle_Geom_Transformation& aTransformation, | |
302 | const Handle_Prs3d_Presentation& aPresentation) | |
303 | { | |
304 | // Standard_NotImplemented::Raise("AIS_RadiusDimension::Compute(const Handle_Prs3d_Projector&, const Handle_Geom_Transformation&, const Handle_Prs3d_Presentation&)"); | |
305 | PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ; | |
306 | } | |
307 | ||
308 | //======================================================================= | |
309 | //function : ComputeSelection | |
310 | //purpose : | |
311 | //======================================================================= | |
312 | void AIS_RadiusDimension::ComputeSelection( const Handle(SelectMgr_Selection)& aSelection, | |
313 | const Standard_Integer ) | |
314 | { | |
315 | gp_Pnt LineOrigin, LineEnd; | |
316 | DsgPrs::ComputeRadiusLine( myCenter, myEndOfArrow, myPosition, mydrawFromCenter, | |
317 | LineOrigin,LineEnd); | |
318 | Handle(AIS_DimensionOwner) own = new AIS_DimensionOwner(this,7); | |
319 | own->SetShape(myFShape); | |
320 | Handle( Select3D_SensitiveSegment ) seg = new Select3D_SensitiveSegment( own, LineOrigin, LineEnd ); | |
321 | aSelection->Add( seg ); | |
322 | ||
323 | // Text | |
324 | Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6)); | |
325 | Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own, | |
326 | myPosition.X(), | |
327 | myPosition.Y(), | |
328 | myPosition.Z(), | |
329 | myPosition.X() + size, | |
330 | myPosition.Y() + size, | |
331 | myPosition.Z() + size ); | |
332 | aSelection->Add(box); | |
333 | } | |
334 | ||
335 | //======================================================================= | |
336 | //function : ComputeRadius | |
337 | //purpose : | |
338 | //======================================================================= | |
339 | ||
340 | void AIS_RadiusDimension::ComputeRadius( const Handle( Prs3d_Presentation )& aPresentation ) | |
341 | { | |
342 | if (myAutomaticPosition) | |
343 | { | |
344 | InitFirstShape(); | |
345 | myEndOfArrow = ElCLib::Value( (myFirstPar + myLastPar)/2, myCircle ); | |
346 | if(mydrawFromCenter) { | |
347 | myPosition = myCenter; | |
348 | } | |
349 | else | |
350 | { | |
351 | gp_Vec v1(myCenter, myEndOfArrow); | |
352 | myPosition = myCenter.Translated(v1 * 1.2); | |
353 | } | |
354 | myAutomaticPosition = Standard_True; | |
355 | ||
356 | if (myIsSetBndBox) | |
357 | myPosition = AIS::TranslatePointToBound(myPosition, gce_MakeDir( myCenter, myEndOfArrow ), | |
358 | myBndBox ); | |
359 | } | |
360 | else | |
361 | { | |
362 | //!Automaticposition | |
363 | myPosition = AIS::ProjectPointOnPlane( myPosition, myPlane->Pln() ); | |
364 | Standard_Real PosPar = ElCLib::Parameter( myCircle, myPosition ); | |
365 | if (!AIS::InDomain(myFirstPar, myLastPar, PosPar)) | |
366 | { // not in domain | |
c6541a0c D |
367 | Standard_Real otherpar = PosPar + M_PI; |
368 | if (otherpar > 2*M_PI) otherpar -= 2*M_PI; | |
7fd59977 | 369 | if (AIS::InDomain(myFirstPar, myLastPar, otherpar)){ |
370 | PosPar = otherpar;// parameter on circle | |
371 | myEndOfArrow = ElCLib::Value( PosPar, myCircle ); | |
372 | } | |
373 | else { | |
374 | Standard_Real Teta1 = Abs( PosPar - myFirstPar ), Teta2 = Abs( PosPar - myLastPar ); | |
c6541a0c D |
375 | if (Teta1 > M_PI) |
376 | Teta1 = 2.0*M_PI - Teta1; | |
377 | if (Teta2 > M_PI) | |
378 | Teta2 = 2.0*M_PI - Teta2; | |
7fd59977 | 379 | if (Teta1 < Teta2) |
380 | { | |
381 | if(myFirstLine.Contains(myPosition,Precision::Confusion())) | |
382 | PosPar = myFirstPar; | |
383 | else | |
384 | PosPar = myLastPar; | |
385 | } | |
386 | else | |
387 | { | |
388 | if(myLastLine.Contains(myPosition,Precision::Confusion())) | |
389 | PosPar = myLastPar; | |
390 | else | |
391 | PosPar = myFirstPar; | |
392 | } | |
393 | myEndOfArrow = ElCLib::Value( PosPar, myCircle ); | |
394 | gp_Lin RadiusLine = gce_MakeLin( myCenter, myEndOfArrow ); | |
395 | // project on radius line | |
396 | myPosition = ElCLib::Value( ElCLib::Parameter( RadiusLine, myPosition ), RadiusLine ); | |
397 | } | |
398 | } | |
399 | else | |
400 | myEndOfArrow = ElCLib::Value( PosPar, myCircle ); | |
401 | } | |
402 | ||
403 | Handle(Prs3d_LengthAspect) la = myDrawer->LengthAspect(); | |
404 | Handle(Prs3d_ArrowAspect) arr = la->Arrow1Aspect(); | |
405 | // size | |
406 | #ifdef BUC60915 | |
407 | if( !myArrowSizeIsDefined ) { | |
408 | myArrowSize = Min(myArrowSize,myVal/5.); | |
409 | } | |
410 | arr->SetLength(myArrowSize); | |
411 | #else | |
412 | if (myVal/5. > myArrowSize) | |
413 | arr->SetLength(myArrowSize); | |
414 | else | |
415 | arr->SetLength(myVal/5.); | |
416 | #endif | |
417 | ||
418 | DsgPrs_RadiusPresentation::Add( aPresentation, myDrawer, myText, myPosition, | |
419 | myCenter, myEndOfArrow, mySymbolPrs, mydrawFromCenter ); | |
420 | } |