Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1996-12-11 |
2 | // Created by: Robert COUBLANC | |
3 | // Copyright (c) 1996-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 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. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
7fd59977 | 17 | |
18 | #include <Adaptor3d_HCurve.hxx> | |
19 | #include <Adaptor3d_HSurface.hxx> | |
42cf5bc1 | 20 | #include <AIS.hxx> |
21 | #include <Bnd_Box.hxx> | |
22 | #include <BRep_Tool.hxx> | |
7fd59977 | 23 | #include <BRepAdaptor_Curve.hxx> |
24 | #include <BRepAdaptor_HSurface.hxx> | |
25 | #include <BRepAdaptor_Surface.hxx> | |
42cf5bc1 | 26 | #include <BRepBuilderAPI_MakeEdge.hxx> |
27 | #include <BRepBuilderAPI_MakeVertex.hxx> | |
60bf98ae | 28 | #include <BRepTools.hxx> |
42cf5bc1 | 29 | #include <BRepTopAdaptor_FClass2d.hxx> |
7fd59977 | 30 | #include <ElCLib.hxx> |
31 | #include <ElSLib.hxx> | |
7fd59977 | 32 | #include <GccEnt_QualifiedLin.hxx> |
60bf98ae | 33 | #include <gce_MakeDir.hxx> |
34 | #include <gce_MakeLin.hxx> | |
7fd59977 | 35 | #include <Geom2d_Circle.hxx> |
7fd59977 | 36 | #include <Geom_CartesianPoint.hxx> |
37 | #include <Geom_Circle.hxx> | |
38 | #include <Geom_ConicalSurface.hxx> | |
39 | #include <Geom_Curve.hxx> | |
40 | #include <Geom_CylindricalSurface.hxx> | |
41 | #include <Geom_Ellipse.hxx> | |
42 | #include <Geom_Line.hxx> | |
43 | #include <Geom_OffsetSurface.hxx> | |
44 | #include <Geom_Plane.hxx> | |
45 | #include <Geom_SphericalSurface.hxx> | |
42cf5bc1 | 46 | #include <Geom_Surface.hxx> |
7fd59977 | 47 | #include <Geom_SurfaceOfLinearExtrusion.hxx> |
48 | #include <Geom_SurfaceOfRevolution.hxx> | |
49 | #include <Geom_ToroidalSurface.hxx> | |
50 | #include <Geom_TrimmedCurve.hxx> | |
42cf5bc1 | 51 | #include <GeomAPI_ExtremaCurveCurve.hxx> |
52 | #include <GeomAPI_IntSS.hxx> | |
53 | #include <GeomAPI_ProjectPointOnCurve.hxx> | |
54 | #include <GeomAPI_ProjectPointOnSurf.hxx> | |
55 | #include <GeomLib.hxx> | |
56 | #include <GeomProjLib.hxx> | |
60bf98ae | 57 | #include <gp_Ax1.hxx> |
58 | #include <gp_Ax3.hxx> | |
59 | #include <gp_Dir.hxx> | |
60 | #include <gp_Elips.hxx> | |
61 | #include <gp_Lin.hxx> | |
62 | #include <gp_Pln.hxx> | |
63 | #include <gp_Pnt.hxx> | |
64 | #include <gp_Vec.hxx> | |
65 | #include <gp_XYZ.hxx> | |
7fd59977 | 66 | #include <Precision.hxx> |
67 | #include <Prs3d_LineAspect.hxx> | |
68 | #include <Prs3d_PointAspect.hxx> | |
42cf5bc1 | 69 | #include <Prs3d_Presentation.hxx> |
7fd59977 | 70 | #include <StdPrs_Point.hxx> |
5ad8c033 | 71 | #include <StdPrs_WFShape.hxx> |
7fd59977 | 72 | #include <TColStd_Array1OfReal.hxx> |
73 | #include <TColStd_Array2OfReal.hxx> | |
74 | #include <TopExp.hxx> | |
75 | #include <TopExp_Explorer.hxx> | |
7fd59977 | 76 | #include <TopoDS.hxx> |
42cf5bc1 | 77 | #include <TopoDS_Edge.hxx> |
78 | #include <TopoDS_Face.hxx> | |
79 | #include <TopoDS_Shape.hxx> | |
80 | #include <TopoDS_Vertex.hxx> | |
81 | #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx> | |
7fd59977 | 82 | |
08cd2f6b | 83 | const Standard_Real SquareTolerance = Precision::SquareConfusion(); |
7fd59977 | 84 | |
85 | //======================================================================= | |
86 | //function : Nearest | |
87 | //purpose : | |
88 | //======================================================================= | |
7fd59977 | 89 | gp_Pnt AIS::Nearest(const TopoDS_Shape& ashape, const gp_Pnt& apoint) |
90 | { | |
91 | Standard_Real dist2 = RealLast(); | |
92 | Standard_Real curdist2; | |
93 | gp_Pnt result(0.0,0.0,0.0); | |
94 | gp_Pnt curpnt(0.0,0.0,0.0); | |
95 | TopExp_Explorer explo(ashape,TopAbs_VERTEX); | |
96 | while (explo.More()) | |
97 | { | |
98 | curpnt = BRep_Tool::Pnt(TopoDS::Vertex(explo.Current())); | |
99 | curdist2 = apoint.SquareDistance(curpnt); | |
100 | if (curdist2 < dist2) | |
101 | { | |
102 | result = curpnt; | |
103 | dist2 = curdist2; | |
104 | } | |
105 | explo.Next(); | |
106 | } | |
107 | return result; | |
108 | } | |
109 | ||
60bf98ae | 110 | //======================================================================= |
111 | //function : Nearest | |
112 | //purpose : For <thePoint> finds the nearest point on <theLine>. | |
113 | //======================================================================= | |
114 | gp_Pnt AIS::Nearest (const gp_Lin& theLine, const gp_Pnt& thePoint) | |
115 | { | |
116 | Handle(Geom_Line) aLine = new Geom_Line (theLine); | |
117 | ||
118 | GeomAPI_ProjectPointOnCurve aPointProj (thePoint, aLine); | |
119 | return aPointProj.Point (1); | |
120 | } | |
121 | ||
122 | //======================================================================= | |
123 | //function : Nearest | |
124 | //purpose : For the given point finds nearest point on the curve, | |
125 | // return TRUE if found point is belongs to curve | |
126 | // and FALSE otherwise. | |
127 | //======================================================================= | |
128 | Standard_Boolean AIS::Nearest (const Handle(Geom_Curve)& theCurve, | |
129 | const gp_Pnt& thePoint, | |
130 | const gp_Pnt& theFirstPoint, | |
131 | const gp_Pnt& theLastPoint, | |
132 | gp_Pnt& theNearestPoint) | |
133 | { | |
134 | GeomAPI_ProjectPointOnCurve aPointProj (thePoint, theCurve); | |
135 | theNearestPoint = theCurve->Value (aPointProj.LowerDistanceParameter()); | |
136 | ||
137 | Standard_Real aLength = theFirstPoint.Distance (theLastPoint); | |
138 | ||
139 | if (theNearestPoint.Distance (theFirstPoint) > aLength | |
140 | || theNearestPoint.Distance (theLastPoint) >aLength) | |
141 | { | |
142 | return Standard_False; | |
143 | } | |
144 | ||
145 | return Standard_True; | |
146 | } | |
147 | ||
7fd59977 | 148 | //======================================================================= |
149 | //function : Farest | |
150 | //purpose : | |
151 | //======================================================================= | |
7fd59977 | 152 | gp_Pnt AIS::Farest( const TopoDS_Shape& aShape, const gp_Pnt& aPoint ) |
153 | { | |
154 | Standard_Real MaxDist2 = 0.0e0, curdist2; | |
155 | gp_Pnt Result(0.0,0.0,0.0); | |
156 | gp_Pnt curpnt(0.0,0.0,0.0); | |
157 | TopExp_Explorer Explo( aShape, TopAbs_VERTEX ); | |
158 | for (; Explo.More(); Explo.Next()) | |
159 | { | |
160 | curpnt = BRep_Tool::Pnt( TopoDS::Vertex( Explo.Current() ) ); | |
161 | curdist2 = aPoint.SquareDistance( curpnt ); | |
162 | if (curdist2 > MaxDist2) | |
163 | { | |
164 | MaxDist2 = curdist2; | |
165 | Result = curpnt; | |
166 | } | |
167 | } | |
168 | return Result; | |
169 | } | |
170 | ||
171 | ||
172 | //======================================================================= | |
173 | //function : ComputeGeometry | |
60bf98ae | 174 | //purpose : for line, circle, ellipse. |
7fd59977 | 175 | //======================================================================= |
60bf98ae | 176 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge, |
177 | Handle(Geom_Curve)& theCurve, | |
178 | gp_Pnt& theFirstPnt, | |
179 | gp_Pnt& theLastPnt) | |
180 | { | |
181 | TopLoc_Location anEdgeLoc; | |
182 | Standard_Real aFirst, aLast; | |
183 | theCurve = BRep_Tool::Curve (theEdge, anEdgeLoc, aFirst, aLast); | |
184 | if (theCurve.IsNull()) | |
185 | { | |
186 | return Standard_False; | |
187 | } | |
188 | ||
189 | if (!anEdgeLoc.IsIdentity()) | |
190 | { | |
191 | Handle(Geom_Geometry) aGeometry = theCurve->Transformed (anEdgeLoc.Transformation()); | |
c5f3a425 | 192 | theCurve = Handle(Geom_Curve)::DownCast (aGeometry); |
60bf98ae | 193 | } |
194 | ||
195 | if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) | |
196 | { | |
c5f3a425 | 197 | theCurve = Handle(Geom_TrimmedCurve)::DownCast (theCurve)->BasisCurve(); |
60bf98ae | 198 | } |
199 | ||
200 | if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line))) | |
201 | { | |
c5f3a425 | 202 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve); |
60bf98ae | 203 | theFirstPnt = ElCLib::Value (aFirst, aLine->Lin()); |
204 | theLastPnt = ElCLib::Value (aLast, aLine->Lin()); | |
205 | } | |
206 | else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) | |
207 | { | |
c5f3a425 | 208 | Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve); |
60bf98ae | 209 | |
210 | theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ()); | |
211 | theLastPnt = ElCLib::Value (aLast, aCirc->Circ()); | |
212 | } | |
213 | else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse))) | |
214 | { | |
c5f3a425 | 215 | Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve); |
60bf98ae | 216 | theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips()); |
217 | theLastPnt = ElCLib::Value (aLast, anEllipse->Elips()); | |
218 | } | |
219 | else | |
220 | { | |
221 | return Standard_False; | |
222 | } | |
7fd59977 | 223 | |
60bf98ae | 224 | return Standard_True; |
225 | } | |
226 | ||
227 | //======================================================================= | |
228 | //function : ComputeGeometry | |
229 | //purpose : for line, circle, ellipse. | |
230 | //======================================================================= | |
231 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge, | |
232 | Handle(Geom_Curve)& theCurve, | |
233 | gp_Pnt& theFirstPnt, | |
234 | gp_Pnt& theLastPnt, | |
235 | Standard_Boolean& theIsInfinite) | |
7fd59977 | 236 | { |
60bf98ae | 237 | Standard_Real aFirst, aLast; |
238 | ||
239 | BRepAdaptor_Curve anAdaptor (theEdge); | |
240 | ||
241 | theCurve = Handle(Geom_Curve)::DownCast | |
242 | (anAdaptor.Curve().Curve()->Transformed (anAdaptor.Trsf())); | |
243 | ||
244 | if (theCurve.IsNull()) | |
245 | { | |
246 | return Standard_False; | |
247 | } | |
248 | ||
249 | aFirst = anAdaptor.FirstParameter(); | |
250 | aLast = anAdaptor.LastParameter(); | |
251 | ||
252 | theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast)); | |
253 | ||
254 | if (theCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) | |
255 | { | |
c5f3a425 | 256 | theCurve = Handle(Geom_TrimmedCurve)::DownCast (theCurve)->BasisCurve(); |
60bf98ae | 257 | } |
258 | ||
259 | if (!theIsInfinite) | |
260 | { | |
261 | theFirstPnt = theCurve->Value (aFirst); | |
262 | theLastPnt = theCurve->Value (aLast); | |
263 | } | |
264 | else | |
265 | { | |
266 | theFirstPnt = gp::Origin(); | |
267 | theLastPnt = gp::Origin(); | |
268 | } | |
269 | ||
7fd59977 | 270 | return Standard_True; |
271 | } | |
272 | ||
273 | //======================================================================= | |
274 | //function : ComputeGeometry | |
275 | //purpose : | |
276 | //======================================================================= | |
277 | ||
60bf98ae | 278 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theEdge, |
279 | Handle(Geom_Curve)& theCurve, | |
280 | gp_Pnt& theFirstPnt, | |
281 | gp_Pnt& theLastPnt, | |
282 | Handle(Geom_Curve)& theExtCurve, | |
283 | Standard_Boolean& theIsInfinite, | |
284 | Standard_Boolean& theIsOnPlane, | |
285 | const Handle(Geom_Plane)& thePlane) | |
7fd59977 | 286 | { |
60bf98ae | 287 | if (thePlane.IsNull()) |
288 | { | |
289 | return Standard_False; | |
290 | } | |
7fd59977 | 291 | |
60bf98ae | 292 | Standard_Real aFirst, aLast; |
293 | BRepAdaptor_Curve aCurveAdaptor (theEdge); | |
294 | theCurve = Handle(Geom_Curve)::DownCast (aCurveAdaptor.Curve().Curve()->Transformed (aCurveAdaptor.Trsf())); | |
295 | aFirst = aCurveAdaptor.FirstParameter(); | |
296 | aLast = aCurveAdaptor.LastParameter(); | |
7fd59977 | 297 | |
60bf98ae | 298 | if (theCurve.IsNull()) |
299 | { | |
300 | return Standard_False; | |
301 | } | |
7fd59977 | 302 | |
60bf98ae | 303 | theExtCurve = theCurve; |
304 | theIsInfinite = (Precision::IsInfinite (aFirst) || Precision::IsInfinite (aLast)); | |
305 | ||
306 | // Checks that the projected curve is not in the plane. | |
307 | theIsOnPlane = Standard_True; | |
308 | if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) | |
309 | { | |
c5f3a425 | 310 | theExtCurve = Handle(Geom_TrimmedCurve)::DownCast (theExtCurve)->BasisCurve(); |
60bf98ae | 311 | } |
7fd59977 | 312 | |
60bf98ae | 313 | if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Line))) |
314 | { | |
c5f3a425 | 315 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theExtCurve); |
60bf98ae | 316 | theIsOnPlane = thePlane->Pln().Contains (aLine->Lin(), |
317 | Precision::Confusion(), | |
318 | Precision::Angular()); | |
7fd59977 | 319 | } |
60bf98ae | 320 | else if (theExtCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) |
321 | { | |
c5f3a425 | 322 | Handle(Geom_Circle) aCircle = Handle(Geom_Circle)::DownCast (theExtCurve); |
60bf98ae | 323 | |
324 | gp_Ax3 aCircPos (aCircle->Position()); | |
325 | theIsOnPlane = aCircPos.IsCoplanar (thePlane->Pln().Position(), | |
326 | Precision::Confusion(), | |
327 | Precision::Angular()); | |
328 | } | |
329 | ||
330 | if (theIsOnPlane) | |
331 | { | |
332 | theExtCurve.Nullify(); | |
333 | } | |
334 | ||
335 | theCurve = GeomProjLib::ProjectOnPlane (theCurve, thePlane, | |
336 | thePlane->Pln().Axis().Direction(), | |
337 | Standard_False); | |
338 | ||
339 | if (theCurve->IsInstance (STANDARD_TYPE (Geom_Line))) | |
340 | { | |
c5f3a425 | 341 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theCurve); |
60bf98ae | 342 | if (!theIsInfinite) |
343 | { | |
344 | theFirstPnt = ElCLib::Value (aFirst, aLine->Lin()); | |
345 | theLastPnt = ElCLib::Value (aLast, aLine->Lin()); | |
7fd59977 | 346 | } |
347 | } | |
60bf98ae | 348 | else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) |
349 | { | |
c5f3a425 | 350 | Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theCurve); |
60bf98ae | 351 | |
352 | theFirstPnt = ElCLib::Value (aFirst, aCirc->Circ()); | |
353 | theLastPnt = ElCLib::Value (aLast, aCirc->Circ()); | |
7fd59977 | 354 | } |
60bf98ae | 355 | else if (theCurve->IsInstance (STANDARD_TYPE (Geom_Ellipse))) |
7fd59977 | 356 | { |
c5f3a425 | 357 | Handle(Geom_Ellipse) anEllipse = Handle(Geom_Ellipse)::DownCast (theCurve); |
60bf98ae | 358 | |
359 | theFirstPnt = ElCLib::Value (aFirst, anEllipse->Elips()); | |
360 | theLastPnt = ElCLib::Value (aLast, anEllipse->Elips()); | |
7fd59977 | 361 | } |
60bf98ae | 362 | else |
363 | { | |
364 | return Standard_False; | |
365 | } | |
366 | ||
7fd59977 | 367 | return Standard_True; |
368 | } | |
369 | ||
370 | //======================================================================= | |
371 | //function : ComputeGeometry | |
372 | //purpose : | |
373 | //======================================================================= | |
60bf98ae | 374 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge, |
375 | const TopoDS_Edge& theSecondEdge, | |
376 | Handle(Geom_Curve)& theFirstCurve, | |
377 | Handle(Geom_Curve)& theSecondCurve, | |
378 | gp_Pnt& theFirstPnt1, | |
379 | gp_Pnt& theLastPnt1, | |
380 | gp_Pnt& theFirstPnt2, | |
381 | gp_Pnt& theLastPnt2, | |
382 | const Handle(Geom_Plane)& thePlane) | |
7fd59977 | 383 | { |
60bf98ae | 384 | if (thePlane.IsNull()) |
385 | { | |
386 | return Standard_False; | |
387 | } | |
7fd59977 | 388 | |
60bf98ae | 389 | TopLoc_Location aFirstEdgeLoc, aSecondEdgeLoc; |
390 | Standard_Real aFirst1, aLast1, aFirst2, aLast2; | |
7fd59977 | 391 | |
60bf98ae | 392 | theFirstCurve = BRep_Tool::Curve (theFirstEdge, aFirstEdgeLoc, aFirst1, aLast1); |
393 | theSecondCurve = BRep_Tool::Curve (theSecondEdge, aSecondEdgeLoc, aFirst2, aLast2); | |
7fd59977 | 394 | |
60bf98ae | 395 | if (theFirstCurve.IsNull()) |
396 | { | |
397 | return Standard_False; | |
398 | } | |
399 | ||
400 | if (theSecondCurve.IsNull()) | |
401 | { | |
402 | return Standard_False; | |
403 | } | |
7fd59977 | 404 | |
60bf98ae | 405 | if (!aFirstEdgeLoc.IsIdentity()) |
406 | { | |
407 | Handle(Geom_Geometry) aGeomGeometry = theFirstCurve->Transformed (aFirstEdgeLoc.Transformation()); | |
c5f3a425 | 408 | theFirstCurve = Handle(Geom_Curve)::DownCast (aGeomGeometry); |
60bf98ae | 409 | } |
410 | ||
411 | if (!aSecondEdgeLoc.IsIdentity()) | |
412 | { | |
413 | Handle(Geom_Geometry) aGeomGeometry = theSecondCurve->Transformed (aSecondEdgeLoc.Transformation()); | |
c5f3a425 | 414 | theSecondCurve = Handle(Geom_Curve)::DownCast (aGeomGeometry); |
60bf98ae | 415 | } |
416 | ||
417 | theFirstCurve = GeomProjLib::ProjectOnPlane (theFirstCurve, thePlane, | |
418 | thePlane->Pln().Axis().Direction(), | |
419 | Standard_False); | |
420 | ||
421 | ||
422 | theSecondCurve = GeomProjLib::ProjectOnPlane (theSecondCurve, thePlane, | |
423 | thePlane->Pln().Axis().Direction(), | |
424 | Standard_False); | |
425 | ||
426 | ||
427 | if (theFirstCurve->IsInstance (STANDARD_TYPE(Geom_TrimmedCurve))) | |
428 | { | |
c5f3a425 | 429 | theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve(); |
60bf98ae | 430 | } |
431 | ||
432 | if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) | |
433 | { | |
c5f3a425 | 434 | theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve(); |
60bf98ae | 435 | } |
436 | ||
437 | if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Line))) | |
438 | { | |
c5f3a425 | 439 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theFirstCurve); |
60bf98ae | 440 | |
441 | theFirstPnt1 = ElCLib::Value (aFirst1, aLine->Lin()); | |
442 | theLastPnt1 = ElCLib::Value (aLast1, aLine->Lin()); | |
443 | } | |
444 | else if (theFirstCurve->IsInstance(STANDARD_TYPE(Geom_Circle))) | |
445 | { | |
c5f3a425 | 446 | Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theFirstCurve); |
60bf98ae | 447 | |
448 | theFirstPnt1 = ElCLib::Value (aFirst1, aCirc->Circ()); | |
449 | theLastPnt1 = ElCLib::Value (aLast1, aCirc->Circ()); | |
450 | } | |
451 | else | |
452 | { | |
453 | return Standard_False; | |
454 | } | |
455 | ||
456 | if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Line))) | |
457 | { | |
c5f3a425 | 458 | Handle(Geom_Line) aLine = Handle(Geom_Line)::DownCast (theSecondCurve); |
60bf98ae | 459 | |
460 | theFirstPnt2 = ElCLib::Value (aFirst2, aLine->Lin()); | |
461 | theLastPnt2 = ElCLib::Value (aLast2, aLine->Lin()); | |
462 | } | |
463 | else if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_Circle))) | |
464 | { | |
c5f3a425 | 465 | Handle(Geom_Circle) aCirc = Handle(Geom_Circle)::DownCast (theSecondCurve); |
60bf98ae | 466 | |
467 | theFirstPnt2 = ElCLib::Value (aFirst2, aCirc->Circ()); | |
468 | theLastPnt2 = ElCLib::Value (aLast2, aCirc->Circ()); | |
469 | } | |
470 | else | |
471 | { | |
472 | return Standard_False; | |
473 | } | |
7fd59977 | 474 | |
475 | return Standard_True; | |
476 | } | |
477 | ||
60bf98ae | 478 | //======================================================================= |
479 | //function : ComputeGeometry | |
480 | //purpose : Computes the geometry of the 2 edges. | |
481 | //======================================================================= | |
482 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge, | |
483 | const TopoDS_Edge& theSecondEdge, | |
484 | Handle(Geom_Curve)& theFirstCurve, | |
485 | Handle(Geom_Curve)& theSecondCurve, | |
486 | gp_Pnt& theFirstPnt1, | |
487 | gp_Pnt& theLastPnt1, | |
488 | gp_Pnt& theFirstPnt2, | |
489 | gp_Pnt& theLastPnt2, | |
490 | Standard_Boolean& theIsInfinite1, | |
491 | Standard_Boolean& theIsInfinite2) | |
492 | { | |
493 | theIsInfinite1 = theIsInfinite2 = Standard_False; | |
494 | ||
495 | if (!AIS::ComputeGeometry (theFirstEdge, theFirstCurve,theFirstPnt1, theLastPnt1, theIsInfinite1)) | |
496 | { | |
497 | return Standard_False; | |
498 | } | |
499 | ||
500 | if (!AIS::ComputeGeometry (theSecondEdge, theSecondCurve,theFirstPnt2, theLastPnt2, theIsInfinite2)) | |
501 | { | |
502 | return Standard_False; | |
503 | } | |
504 | ||
505 | if (theIsInfinite1 || theIsInfinite2) | |
506 | { | |
507 | if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()) | |
508 | { | |
c5f3a425 | 509 | gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin(); |
510 | gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin(); | |
60bf98ae | 511 | |
512 | if (theIsInfinite1) | |
513 | { | |
514 | theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1); | |
515 | theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1); | |
516 | } | |
517 | else if (theIsInfinite2) | |
518 | { | |
519 | theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2); | |
520 | theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2); | |
521 | } | |
522 | } | |
523 | else | |
524 | { | |
525 | if (theIsInfinite1 && !theIsInfinite2) | |
526 | { | |
527 | GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt2, theFirstCurve); | |
528 | theFirstPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ()); | |
529 | ||
530 | aProjector.Init (theLastPnt2, theFirstCurve); | |
531 | theLastPnt1 = theFirstCurve->Value (aProjector.LowerDistanceParameter ()); | |
532 | } | |
533 | else if (!theIsInfinite1 && theIsInfinite2) | |
534 | { | |
535 | GeomAPI_ProjectPointOnCurve aProjector (theFirstPnt1, theSecondCurve); | |
536 | theFirstPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ()); | |
537 | ||
538 | aProjector.Init (theLastPnt1, theSecondCurve); | |
539 | theLastPnt2 = theSecondCurve->Value (aProjector.LowerDistanceParameter ()); | |
540 | } | |
541 | else | |
542 | { | |
543 | return Standard_False; | |
544 | } | |
545 | } | |
546 | } | |
547 | ||
548 | return Standard_True; | |
549 | } | |
550 | ||
7fd59977 | 551 | //======================================================================= |
552 | //function : ComputeGeometry | |
553 | //purpose : Computes the geometry of the 2 edges in the current wp | |
a6eb515f | 554 | // and the 'right' geometry of the edges if one doesn't |
555 | // belong to the current working plane. | |
7fd59977 | 556 | // There may be only one curve that can't belong to the |
a6eb515f | 557 | // current working plane ( attachement constraint) |
7fd59977 | 558 | // if the 2 edges belong to the current WP, <WhatProj> = 0 |
559 | // | |
560 | // indexExt = 0 2 edges are in the current wp | |
561 | // indexExt = 1 first edge is not in the current wp | |
562 | // indexExt = 2 second edge is not in the current wp | |
563 | // if none of the two edges is in the current wp , | |
564 | // it returns Standard_False | |
565 | //======================================================================= | |
60bf98ae | 566 | Standard_Boolean AIS::ComputeGeometry (const TopoDS_Edge& theFirstEdge, |
567 | const TopoDS_Edge& theSecondEdge, | |
568 | Standard_Integer& theExtIndex, | |
569 | Handle(Geom_Curve)& theFirstCurve, | |
570 | Handle(Geom_Curve)& theSecondCurve, | |
571 | gp_Pnt& theFirstPnt1, | |
572 | gp_Pnt& theLastPnt1, | |
573 | gp_Pnt& theFirstPnt2, | |
574 | gp_Pnt& theLastPnt2, | |
575 | Handle(Geom_Curve)& theExtCurve, | |
576 | Standard_Boolean& theIsInfinite1, | |
577 | Standard_Boolean& theIsInfinite2, | |
578 | const Handle(Geom_Plane)& thePlane) | |
7fd59977 | 579 | { |
60bf98ae | 580 | if (thePlane.IsNull()) |
581 | { | |
582 | return Standard_False; | |
583 | } | |
584 | ||
585 | theExtCurve.Nullify(); | |
586 | theExtIndex = 0; | |
587 | ||
588 | Standard_Real aFirst1, aLast1, aFirst2, aLast2; | |
589 | theIsInfinite1 = theIsInfinite2 = Standard_False; | |
7fd59977 | 590 | |
60bf98ae | 591 | BRepAdaptor_Curve aFirstAdaptor (theFirstEdge); |
592 | BRepAdaptor_Curve aSecondAdaptor (theSecondEdge); | |
7fd59977 | 593 | |
60bf98ae | 594 | theFirstCurve = Handle(Geom_Curve)::DownCast |
595 | (aFirstAdaptor.Curve().Curve()->Transformed (aFirstAdaptor.Trsf())); | |
596 | theSecondCurve = Handle(Geom_Curve)::DownCast | |
597 | (aSecondAdaptor.Curve().Curve()->Transformed (aSecondAdaptor.Trsf())); | |
598 | ||
599 | if (theFirstCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) | |
600 | { | |
c5f3a425 | 601 | theFirstCurve = Handle(Geom_TrimmedCurve)::DownCast (theFirstCurve)->BasisCurve(); |
7fd59977 | 602 | } |
60bf98ae | 603 | if (theSecondCurve->IsInstance (STANDARD_TYPE (Geom_TrimmedCurve))) |
604 | { | |
c5f3a425 | 605 | theSecondCurve = Handle(Geom_TrimmedCurve)::DownCast (theSecondCurve)->BasisCurve(); |
7fd59977 | 606 | } |
607 | ||
60bf98ae | 608 | aFirst1 = aFirstAdaptor.FirstParameter(); |
609 | aLast1 = aFirstAdaptor.LastParameter(); | |
7fd59977 | 610 | |
60bf98ae | 611 | aFirst2 = aSecondAdaptor.FirstParameter(); |
612 | aLast2 = aSecondAdaptor.LastParameter(); | |
613 | ||
614 | if (theFirstCurve.IsNull() || theSecondCurve.IsNull()) | |
615 | { | |
7fd59977 | 616 | return Standard_False; |
60bf98ae | 617 | } |
618 | ||
619 | Handle(Geom_Curve) aFirstSaved = theFirstCurve; | |
620 | Handle(Geom_Curve) aSecondSaved = theSecondCurve; | |
621 | ||
622 | // Checks that the projected curve is not in the plane | |
623 | Standard_Boolean isFirstOnPlane,isSecondOnPlane; | |
624 | ||
625 | if ((!ComputeGeomCurve (theFirstCurve, aFirst1, aLast1, theFirstPnt1, theLastPnt1, thePlane, isFirstOnPlane)) | |
626 | || (!ComputeGeomCurve( theSecondCurve, aFirst2, aLast2, theFirstPnt2, theLastPnt2, thePlane,isSecondOnPlane))) | |
627 | { | |
628 | return Standard_False; | |
629 | } | |
630 | ||
631 | if (Precision::IsInfinite (aFirst1) || Precision::IsInfinite (aLast1)) | |
632 | { | |
633 | theIsInfinite1 = Standard_True; | |
634 | theExtIndex = 1; | |
635 | } | |
636 | if (Precision::IsInfinite (aFirst2) || Precision::IsInfinite (aLast2)) | |
637 | { | |
638 | theIsInfinite2 = Standard_True; | |
639 | theExtIndex = 2; | |
640 | } | |
641 | if (theIsInfinite1 && theIsInfinite2) | |
642 | { | |
643 | theExtIndex = 0; | |
644 | } | |
645 | ||
646 | if (theIsInfinite1 || theIsInfinite2) | |
647 | { | |
648 | if (theFirstCurve->DynamicType() == theSecondCurve->DynamicType()) | |
649 | { | |
c5f3a425 | 650 | gp_Lin aLin1 = Handle(Geom_Line)::DownCast (theFirstCurve)->Lin(); |
651 | gp_Lin aLin2 = Handle(Geom_Line)::DownCast (theSecondCurve)->Lin(); | |
60bf98ae | 652 | |
653 | if (theExtIndex == 1) | |
654 | { | |
655 | theFirstPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theFirstPnt2), aLin1); | |
656 | theLastPnt1 = ElCLib::Value (ElCLib::Parameter (aLin2, theLastPnt2), aLin1); | |
7fd59977 | 657 | } |
60bf98ae | 658 | else if (theExtIndex == 2) |
659 | { | |
660 | theFirstPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theFirstPnt1), aLin2); | |
661 | theLastPnt2 = ElCLib::Value (ElCLib::Parameter (aLin1, theLastPnt1), aLin2); | |
7fd59977 | 662 | } |
663 | } | |
664 | } | |
665 | ||
60bf98ae | 666 | if (isFirstOnPlane && isSecondOnPlane) |
667 | { | |
668 | return Standard_True; | |
669 | } | |
7fd59977 | 670 | |
60bf98ae | 671 | if (!isFirstOnPlane && isSecondOnPlane) |
672 | {// curve 2 only in the plane | |
673 | theExtIndex = 1; | |
674 | theExtCurve = aFirstSaved; | |
7fd59977 | 675 | } |
60bf98ae | 676 | else if (isFirstOnPlane && !isSecondOnPlane) |
677 | {// curve 1 only in the plane | |
678 | theExtIndex = 2; | |
679 | theExtCurve = aSecondSaved; | |
7fd59977 | 680 | } |
681 | else | |
60bf98ae | 682 | { |
7fd59977 | 683 | return Standard_False; |
60bf98ae | 684 | } |
685 | ||
7fd59977 | 686 | return Standard_True; |
687 | } | |
688 | ||
7fd59977 | 689 | //======================================================================= |
690 | //function : ComputeGeomCurve | |
691 | //purpose : Checks if aCurve belongs to aPlane; if not, projects aCurve in aPlane | |
692 | // and returns aCurveproj; | |
693 | // Return TRUE if ok | |
694 | //======================================================================= | |
60bf98ae | 695 | Standard_Boolean AIS::ComputeGeomCurve (Handle(Geom_Curve)& aCurve, |
696 | const Standard_Real first1, | |
697 | const Standard_Real last1, | |
698 | gp_Pnt& FirstPnt1, | |
699 | gp_Pnt& LastPnt1, | |
700 | const Handle(Geom_Plane)& aPlane, | |
701 | Standard_Boolean& isOnPlane) | |
7fd59977 | 702 | { |
703 | isOnPlane = Standard_True; | |
7fd59977 | 704 | const Standard_Integer NodeNumber = 20; |
705 | Standard_Real Delta = (last1 - first1) / (NodeNumber - 1); | |
706 | if (Delta <= Precision::PConfusion()) | |
60bf98ae | 707 | { |
7fd59977 | 708 | Delta = last1 - first1; |
60bf98ae | 709 | } |
710 | ||
711 | gp_Pnt CurPnt(0.0, 0.0, 0.0); | |
7fd59977 | 712 | Standard_Real CurPar = first1; |
713 | for (Standard_Integer i = 1; i <= NodeNumber; i++) | |
60bf98ae | 714 | { |
715 | CurPnt = aCurve->Value( CurPar ); | |
716 | if (aPlane->Pln().SquareDistance( CurPnt ) > SquareTolerance) | |
7fd59977 | 717 | { |
60bf98ae | 718 | isOnPlane = Standard_False; |
719 | break; | |
7fd59977 | 720 | } |
60bf98ae | 721 | CurPar += Delta; |
722 | } | |
723 | ||
724 | if (!Precision::IsInfinite(first1) && !Precision::IsInfinite(last1)) | |
725 | { | |
726 | FirstPnt1 = aCurve->Value (first1); | |
727 | LastPnt1 = aCurve->Value (last1); | |
728 | } | |
729 | ||
730 | if (!isOnPlane) | |
731 | { | |
732 | Handle(Geom_Curve) aGeomCurve = GeomProjLib::ProjectOnPlane (aCurve, | |
733 | aPlane, | |
734 | aPlane->Pln().Axis().Direction(), | |
735 | Standard_False); | |
736 | aCurve = aGeomCurve; | |
737 | if (aCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve))) | |
7fd59977 | 738 | { |
c5f3a425 | 739 | aCurve = Handle(Geom_TrimmedCurve)::DownCast (aCurve)->BasisCurve(); |
7fd59977 | 740 | } |
60bf98ae | 741 | if (! Precision::IsInfinite(first1) && ! Precision::IsInfinite(last1)) |
742 | { | |
7fd59977 | 743 | FirstPnt1 = AIS::ProjectPointOnPlane( FirstPnt1, aPlane->Pln() ); |
744 | LastPnt1 = AIS::ProjectPointOnPlane( LastPnt1, aPlane->Pln() ); | |
745 | } | |
746 | } | |
747 | return Standard_True; | |
748 | } | |
749 | ||
7fd59977 | 750 | //======================================================================= |
751 | //function : ComputeGeometry | |
752 | //purpose : computes the point corresponding to the vertex <aVertex> | |
753 | // in the plane <aPlane>. If the vertex is already in the plane | |
754 | // <isOnPlane>, <isOnPlane> = true. | |
755 | // <point> is the projected vertex in the plane. | |
756 | //======================================================================= | |
7fd59977 | 757 | Standard_Boolean AIS::ComputeGeometry(const TopoDS_Vertex& aVertex, |
758 | gp_Pnt& point, | |
759 | const Handle(Geom_Plane)& aPlane, | |
760 | Standard_Boolean& isOnPlane) | |
761 | { | |
762 | point = BRep_Tool::Pnt(aVertex); | |
763 | isOnPlane = aPlane->Pln().Contains(point, Precision::Confusion()); | |
764 | if ( !isOnPlane) { | |
765 | point = AIS::ProjectPointOnPlane( point, aPlane->Pln() ); | |
766 | } | |
767 | return Standard_True; | |
768 | } | |
769 | ||
770 | //======================================================================= | |
771 | //function : GetPlaneFromFace | |
772 | //purpose : | |
773 | // Returns type of surface which can be Plane or OtherSurface | |
774 | //======================================================================= | |
60bf98ae | 775 | Standard_Boolean AIS::GetPlaneFromFace(const TopoDS_Face& aFace, |
7fd59977 | 776 | gp_Pln & aPlane, |
777 | Handle( Geom_Surface )& aSurf, | |
778 | AIS_KindOfSurface & aSurfType, | |
60bf98ae | 779 | Standard_Real & Offset) |
7fd59977 | 780 | |
781 | { | |
782 | Standard_Boolean Result = Standard_False; | |
783 | BRepAdaptor_Surface surf1( aFace ); | |
784 | Handle( Adaptor3d_HSurface ) surf2; | |
7fd59977 | 785 | Standard_Boolean isOffset = Standard_False; |
786 | ||
787 | if (surf1.GetType() == GeomAbs_OffsetSurface) | |
60bf98ae | 788 | { |
789 | // Extracting Basis Surface | |
790 | surf2 = surf1.BasisSurface(); | |
791 | isOffset = Standard_True; | |
792 | } | |
7fd59977 | 793 | else |
794 | surf2 = new BRepAdaptor_HSurface( surf1 ); | |
795 | ||
796 | aSurf = surf1.Surface().Surface(); | |
797 | // aSurf->Transform(surf1.Trsf()) ; | |
798 | aSurf = Handle( Geom_Surface )::DownCast( aSurf->Transformed( surf1.Trsf() ) ); | |
799 | ||
800 | if (surf2->GetType() == GeomAbs_Plane) | |
60bf98ae | 801 | { |
802 | aPlane = surf2->Plane(); | |
803 | aSurfType = AIS_KOS_Plane; | |
804 | Offset = 0.; | |
805 | Result = Standard_True; | |
806 | } | |
807 | ||
808 | else if (surf2->GetType() == GeomAbs_SurfaceOfExtrusion) | |
809 | { | |
810 | Handle( Adaptor3d_HCurve ) BasisCurve = surf2->BasisCurve(); | |
811 | gp_Dir ExtrusionDir = surf2->Direction(); | |
812 | if (BasisCurve->GetType() == GeomAbs_Line) | |
7fd59977 | 813 | { |
60bf98ae | 814 | gp_Lin BasisLine = BasisCurve->Line(); |
815 | gp_Dir LineDir = BasisLine.Direction(); | |
816 | gp_Pnt LinePos = BasisLine.Location(); | |
817 | gp_Pln thePlane( LinePos, LineDir ^ ExtrusionDir); | |
818 | aPlane = thePlane; | |
7fd59977 | 819 | aSurfType = AIS_KOS_Plane; |
820 | Offset = 0.; | |
821 | Result = Standard_True; | |
822 | } | |
60bf98ae | 823 | } |
7fd59977 | 824 | |
825 | if (Result == Standard_True && isOffset) | |
60bf98ae | 826 | { |
827 | aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface(); | |
828 | aPlane = (Handle( Geom_Plane )::DownCast( aSurf ))->Pln(); | |
829 | Offset = 0.0e0; | |
830 | } | |
7fd59977 | 831 | if (Result == Standard_False) |
60bf98ae | 832 | { |
833 | if (isOffset) | |
7fd59977 | 834 | { |
7fd59977 | 835 | Handle( Standard_Type ) TheType = aSurf->DynamicType(); |
60bf98ae | 836 | if (TheType == STANDARD_TYPE(Geom_CylindricalSurface) || |
837 | TheType == STANDARD_TYPE(Geom_ConicalSurface) || | |
838 | TheType == STANDARD_TYPE(Geom_SphericalSurface) || | |
839 | TheType == STANDARD_TYPE(Geom_ToroidalSurface)) | |
840 | { | |
841 | aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Surface(); | |
842 | Offset = 0.0e0; | |
843 | } | |
7fd59977 | 844 | else |
60bf98ae | 845 | { |
846 | Offset = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->Offset(); | |
847 | aSurf = (Handle( Geom_OffsetSurface )::DownCast( aSurf ))->BasisSurface(); | |
848 | } | |
7fd59977 | 849 | } |
60bf98ae | 850 | Handle( Standard_Type ) TheType = aSurf->DynamicType(); |
851 | if (TheType == STANDARD_TYPE(Geom_CylindricalSurface)) | |
852 | aSurfType = AIS_KOS_Cylinder; | |
853 | else if (TheType == STANDARD_TYPE(Geom_ConicalSurface)) | |
854 | aSurfType = AIS_KOS_Cone; | |
855 | else if (TheType == STANDARD_TYPE(Geom_SphericalSurface)) | |
856 | aSurfType = AIS_KOS_Sphere; | |
857 | else if (TheType == STANDARD_TYPE(Geom_ToroidalSurface)) | |
858 | aSurfType = AIS_KOS_Torus; | |
859 | else if (TheType == STANDARD_TYPE(Geom_SurfaceOfRevolution)) | |
860 | aSurfType = AIS_KOS_Revolution; | |
861 | else if (TheType == STANDARD_TYPE(Geom_SurfaceOfLinearExtrusion)) | |
862 | aSurfType = AIS_KOS_Extrusion; | |
863 | else | |
864 | aSurfType = AIS_KOS_OtherSurface; | |
865 | } | |
7fd59977 | 866 | return Result; |
867 | } | |
868 | ||
869 | ||
870 | //======================================================================= | |
871 | //function : ProjectPointOnPlane | |
872 | //purpose : | |
873 | //======================================================================= | |
874 | ||
875 | gp_Pnt AIS::ProjectPointOnPlane( const gp_Pnt & aPoint, const gp_Pln & aPlane ) | |
876 | { | |
877 | gp_Vec aVec( aPlane.Location(), aPoint ); | |
878 | gp_Vec Normal = aPlane.Axis().Direction(); | |
879 | Normal = (aVec * Normal) * Normal; | |
880 | ||
881 | return ( aPoint.Translated( -Normal ) ); | |
882 | } | |
883 | ||
884 | //======================================================================= | |
885 | //function : ProjectPointOnLine | |
886 | //purpose : | |
887 | //======================================================================= | |
888 | ||
889 | gp_Pnt AIS::ProjectPointOnLine( const gp_Pnt & aPoint, const gp_Lin & aLine ) | |
890 | { | |
891 | gp_XYZ LinLoc = aLine.Location().XYZ(); | |
892 | gp_XYZ LinDir = aLine.Direction().XYZ(); | |
893 | Standard_Real Parameter = (aPoint.XYZ() - LinLoc) * LinDir; | |
894 | gp_Pnt Result( LinLoc + Parameter * LinDir ); | |
895 | return Result; | |
896 | } | |
897 | ||
7fd59977 | 898 | //======================================================================= |
899 | //function : InitFaceLength | |
900 | //purpose : | |
901 | //======================================================================= | |
60bf98ae | 902 | void AIS::InitFaceLength (const TopoDS_Face& aFace, |
903 | gp_Pln & aPlane, | |
904 | Handle(Geom_Surface) & aSurface, | |
905 | AIS_KindOfSurface & aSurfaceType, | |
906 | Standard_Real & anOffset) | |
7fd59977 | 907 | { |
908 | AIS::GetPlaneFromFace( aFace, aPlane, aSurface, aSurfaceType, anOffset ); | |
909 | ||
910 | if (Abs( anOffset ) > Precision::Confusion()) | |
911 | { | |
912 | aSurface = new Geom_OffsetSurface( aSurface, anOffset ); | |
913 | anOffset = 0.0e0; | |
914 | } | |
915 | ||
916 | } | |
917 | ||
918 | //======================================================================= | |
60bf98ae | 919 | //function : InitAngleBetweenPlanarFaces |
7fd59977 | 920 | //purpose : |
921 | //======================================================================= | |
60bf98ae | 922 | Standard_Boolean AIS::InitAngleBetweenPlanarFaces (const TopoDS_Face& theFirstFace, |
923 | const TopoDS_Face& theSecondFace, | |
924 | gp_Pnt & theCenter, | |
925 | gp_Pnt & theFirstAttach, | |
926 | gp_Pnt & theSecondAttach, | |
927 | const Standard_Boolean theIsFirstPointSet) | |
7fd59977 | 928 | { |
60bf98ae | 929 | Handle(Geom_Plane) aFirstPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theFirstFace)); |
930 | Handle(Geom_Plane) aSecondPlane = Handle(Geom_Plane)::DownCast (BRep_Tool::Surface (theSecondFace)); | |
7fd59977 | 931 | |
60bf98ae | 932 | GeomAPI_IntSS aPlaneIntersector (aFirstPlane, aSecondPlane, Precision::Confusion()); |
933 | ||
934 | // Fails if two planes haven't only one intersection line. | |
935 | if (!aPlaneIntersector.IsDone()) | |
936 | { | |
937 | return Standard_False; | |
938 | } | |
7fd59977 | 939 | |
60bf98ae | 940 | if (aPlaneIntersector.NbLines() != 1) |
941 | { | |
942 | return Standard_False; | |
943 | } | |
7fd59977 | 944 | |
60bf98ae | 945 | // Get intersect line. |
946 | Handle(Geom_Curve) anIntersectCurve = aPlaneIntersector.Line (1); | |
947 | ||
948 | Handle(Geom_Line) anIntersectLine = Handle(Geom_Line)::DownCast (anIntersectCurve); | |
949 | ||
950 | if (anIntersectLine.IsNull()) | |
951 | { | |
952 | return Standard_False; | |
7fd59977 | 953 | } |
954 | ||
60bf98ae | 955 | gp_Lin anIntersectLin = anIntersectLine->Lin(); |
956 | ||
957 | gp_Pnt aFirstCenter, aSecondCenter; | |
958 | Standard_Real anU1Min, anU1Max, aV1Min, aV1Max; | |
959 | Standard_Real anU2Min, anU2Max, aV2Min, aV2Max; | |
7fd59977 | 960 | |
60bf98ae | 961 | BRepTools::UVBounds (theFirstFace, anU1Min, anU1Max, aV1Min, aV1Max); |
962 | BRepTools::UVBounds (theSecondFace, anU2Min, anU2Max, aV2Min, aV2Max); | |
963 | ||
964 | // Get first and second attach. | |
965 | if (theIsFirstPointSet) | |
966 | { | |
967 | GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstPlane); | |
968 | if (!aProjector.IsDone()) | |
7fd59977 | 969 | { |
60bf98ae | 970 | return Standard_False; |
7fd59977 | 971 | } |
7fd59977 | 972 | |
60bf98ae | 973 | aFirstCenter = aProjector.Point (1); |
974 | } | |
7fd59977 | 975 | else |
60bf98ae | 976 | { |
977 | aFirstCenter = aFirstPlane->Value ((anU1Min + anU1Max) * 0.5, (aV1Min + aV1Max) * 0.5); | |
978 | } | |
979 | ||
980 | aSecondCenter = aSecondPlane->Value ((anU2Min + anU2Max) * 0.5, (aV2Min + aV2Max) * 0.5); | |
981 | ||
982 | GeomAPI_ProjectPointOnCurve aProj (aFirstCenter, anIntersectCurve); | |
983 | theCenter = aProj.NearestPoint(); | |
984 | ||
985 | gp_Vec aFirstNormal = anIntersectLin.Direction() ^ aFirstPlane->Pln().Axis().Direction(); | |
986 | if (aFirstNormal * gp_Vec (theCenter, aFirstCenter) < 0.0) | |
987 | { | |
988 | aFirstNormal.Reverse(); | |
989 | } | |
990 | theFirstAttach = theCenter.Translated (aFirstNormal); | |
991 | ||
992 | gp_Vec aSecondNormal = anIntersectLin.Direction() ^ aSecondPlane->Pln().Axis().Direction(); | |
993 | if (aSecondNormal * gp_Vec (theCenter, aSecondCenter) < 0.0) | |
994 | { | |
995 | aSecondNormal.Reverse(); | |
996 | } | |
997 | theSecondAttach = theCenter.Translated (aSecondNormal); | |
998 | ||
999 | return Standard_True; | |
7fd59977 | 1000 | } |
60bf98ae | 1001 | |
1002 | //======================================================================= | |
1003 | //function : InitAngleBetweenCurvilinearFaces | |
1004 | //purpose : | |
1005 | //======================================================================= | |
1006 | Standard_Boolean AIS::InitAngleBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace, | |
1007 | const TopoDS_Face& theSecondFace, | |
1008 | const AIS_KindOfSurface theFirstSurfType, | |
1009 | const AIS_KindOfSurface theSecondSurfType, | |
1010 | gp_Pnt& theCenter, | |
1011 | gp_Pnt& theFirstAttach, | |
1012 | gp_Pnt& theSecondAttach, | |
1013 | const Standard_Boolean theIsFirstPointSet) | |
7fd59977 | 1014 | { |
60bf98ae | 1015 | Handle(Geom_Surface) aFirstSurf = BRep_Tool::Surface (theFirstFace); |
1016 | Handle(Geom_Surface) aSecondSurf = BRep_Tool::Surface (theSecondFace); | |
1017 | ||
1018 | // Find intersection curve between two surfaces. | |
1019 | GeomAPI_IntSS aSurfaceIntersector (aFirstSurf, aSecondSurf, Precision::Confusion()); | |
1020 | ||
1021 | // Fails if two planes haven't only one intersection line. | |
1022 | if (!aSurfaceIntersector.IsDone()) | |
1023 | { | |
1024 | return Standard_False; | |
1025 | } | |
1026 | ||
1027 | if (aSurfaceIntersector.NbLines() != 1) | |
1028 | { | |
1029 | return Standard_False; | |
1030 | } | |
1031 | ||
1032 | // Get intersect line. | |
1033 | Handle(Geom_Curve) anIntersectCurve = aSurfaceIntersector.Line (1); | |
1034 | ||
1035 | Handle(Geom_Line) aFirstLine, aSecondLine; | |
1036 | Standard_Real aFirstU = 0.0; | |
1037 | Standard_Real aFirstV = 0.0; | |
1038 | ||
1039 | if (theIsFirstPointSet) | |
1040 | { | |
1041 | GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aFirstSurf); | |
1042 | if (!aProjector.IsDone()) | |
7fd59977 | 1043 | { |
60bf98ae | 1044 | return Standard_False; |
7fd59977 | 1045 | } |
7fd59977 | 1046 | |
60bf98ae | 1047 | theFirstAttach = aProjector.Point (1); |
1048 | } | |
1049 | else | |
1050 | { | |
1051 | theFirstAttach = aFirstSurf->Value (aFirstU, aFirstV); | |
1052 | } | |
1053 | ||
1054 | aFirstLine = Handle(Geom_Line)::DownCast (aFirstSurf->UIso (aFirstU)); | |
1055 | ||
1056 | if (theSecondSurfType == AIS_KOS_Cylinder) | |
1057 | { | |
1058 | Handle(Geom_CylindricalSurface) aCylinder = Handle(Geom_CylindricalSurface)::DownCast (aSecondSurf); | |
1059 | ||
1060 | Standard_Real aSecondU = aCylinder->Cylinder().XAxis().Direction().Angle( | |
1061 | gce_MakeDir (ProjectPointOnLine (theFirstAttach, | |
1062 | gp_Lin (aCylinder->Cylinder().Axis())), | |
1063 | theFirstAttach)); | |
1064 | ||
1065 | aSecondLine = Handle(Geom_Line)::DownCast (aCylinder->UIso (aSecondU)); | |
1066 | } | |
1067 | else if (theSecondSurfType == AIS_KOS_Cone) | |
1068 | { | |
1069 | Handle(Geom_ConicalSurface) aCone = Handle(Geom_ConicalSurface)::DownCast (aSecondSurf); | |
1070 | ||
1071 | gp_Dir anXdirection = aCone->Cone().XAxis().Direction(); | |
1072 | ||
1073 | gp_Dir aToFirstAttach = gce_MakeDir (ProjectPointOnLine (theFirstAttach, | |
1074 | gp_Lin (aCone->Cone().Axis())), | |
1075 | theFirstAttach); | |
1076 | ||
1077 | Standard_Real aSecondU = anXdirection.Angle (aToFirstAttach); | |
1078 | ||
1079 | // Check sign | |
1080 | if (!anXdirection.IsEqual (aToFirstAttach, Precision::Angular()) && | |
1081 | !anXdirection.IsOpposite (aToFirstAttach, Precision::Angular()) && | |
1082 | (anXdirection ^ aToFirstAttach) * aCone->Cone().Axis().Direction() < 0.0) | |
7fd59977 | 1083 | { |
60bf98ae | 1084 | aSecondU = 2*M_PI - aSecondU; |
7fd59977 | 1085 | } |
60bf98ae | 1086 | aSecondLine = Handle( Geom_Line )::DownCast (aCone->UIso(aSecondU)); |
1087 | } | |
1088 | else | |
1089 | { | |
1090 | return Standard_False; | |
1091 | } | |
1092 | ||
1093 | // If angle can be computed between two lines. | |
1094 | if (!(aFirstLine->Lin().Direction().IsEqual (aSecondLine->Lin().Direction(), Precision::Angular() )) && | |
1095 | !(aFirstLine->Lin().Direction().IsOpposite (aSecondLine->Lin().Direction(), Precision::Angular()))) | |
1096 | { | |
1097 | GeomAPI_ExtremaCurveCurve anIntersector (aFirstLine, aSecondLine); | |
1098 | anIntersector.Points (1, theCenter, theCenter); | |
1099 | ||
1100 | // Move theFirstAttach on aFirstLine if it is on theCenter. | |
1101 | if (theCenter.SquareDistance(theFirstAttach ) <= SquareTolerance) | |
7fd59977 | 1102 | { |
60bf98ae | 1103 | gp_Vec aDir (aFirstLine->Lin().Direction()); |
1104 | theFirstAttach = theCenter.Translated (aDir); | |
1105 | ||
1106 | // theFirstAttach should be on theFirstSurf. | |
1107 | Standard_Real anU, aV; | |
1108 | if (theFirstSurfType == AIS_KOS_Cylinder) | |
1109 | { | |
1110 | ElSLib::Parameters ((Handle(Geom_CylindricalSurface)::DownCast (aFirstSurf))->Cylinder(), | |
1111 | theFirstAttach, anU, aV); | |
1112 | ||
1113 | theFirstAttach = ElSLib::Value (aFirstU, aV, | |
1114 | (Handle( Geom_CylindricalSurface )::DownCast (aFirstSurf))->Cylinder() ); | |
1115 | } | |
1116 | else if (theFirstSurfType == AIS_KOS_Cone) | |
1117 | { | |
1118 | ElSLib::Parameters ((Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone(), | |
1119 | theFirstAttach, anU, aV); | |
1120 | theFirstAttach = ElSLib::Value (aFirstU, aV, | |
1121 | (Handle(Geom_ConicalSurface)::DownCast (aFirstSurf))->Cone()); | |
1122 | } | |
1123 | else | |
1124 | { | |
1125 | return Standard_False; | |
1126 | } | |
7fd59977 | 1127 | } |
1128 | ||
60bf98ae | 1129 | // Find theSecondAttach |
1130 | GeomAPI_ProjectPointOnSurf aProjector (theFirstAttach, aSecondSurf); | |
1131 | if (!aProjector.IsDone()) | |
1132 | { | |
1133 | return Standard_False; | |
7fd59977 | 1134 | } |
60bf98ae | 1135 | Quantity_Parameter anU, aV; |
1136 | aProjector.LowerDistanceParameters (anU, aV); | |
1137 | theSecondAttach = aSecondSurf->Value (anU, aV); | |
1138 | } | |
1139 | else // aFirstLine and aSecondLine are coincident | |
1140 | { | |
1141 | gp_Vec aDir (aFirstLine->Lin().Direction()); | |
1142 | theFirstAttach = theCenter.Translated (aDir); | |
1143 | theSecondAttach = theCenter.Translated (-aDir); | |
1144 | } | |
1145 | return Standard_True; | |
7fd59977 | 1146 | } |
1147 | ||
60bf98ae | 1148 | //======================================================================= |
1149 | //function : ComputeLengthBetweenCurvilinearFaces | |
1150 | //purpose : | |
1151 | //======================================================================= | |
1152 | void AIS::InitLengthBetweenCurvilinearFaces (const TopoDS_Face& theFirstFace, | |
1153 | const TopoDS_Face& theSecondFace, | |
1154 | Handle(Geom_Surface)& theFirstSurf, | |
1155 | Handle(Geom_Surface)& theSecondSurf, | |
1156 | gp_Pnt& theFirstAttach, | |
1157 | gp_Pnt& theSecondAttach, | |
1158 | gp_Dir& theDirOnPlane) | |
7fd59977 | 1159 | { |
1160 | GeomAPI_ProjectPointOnSurf aProjector; | |
60bf98ae | 1161 | Quantity_Parameter aPU, aPV; |
1162 | ||
1163 | TopExp_Explorer anExplorer (theFirstFace, TopAbs_VERTEX); | |
1164 | ||
1165 | theFirstAttach = BRep_Tool::Pnt (TopoDS::Vertex (anExplorer.Current())); | |
1166 | aProjector.Init (theFirstAttach, theFirstSurf); | |
1167 | ||
1168 | theFirstAttach = aProjector.NearestPoint(); | |
1169 | aProjector.LowerDistanceParameters (aPU, aPV); | |
1170 | ||
1171 | gp_Vec aD1U, aD1V; | |
1172 | theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V); | |
1173 | ||
1174 | if (aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance) | |
1175 | { | |
1176 | theFirstAttach = AIS::Farest (theFirstFace, theFirstAttach); | |
1177 | aProjector.Init (theFirstAttach, theFirstSurf); | |
1178 | aProjector.LowerDistanceParameters (aPU, aPV); | |
1179 | theFirstSurf->D1 (aPU, aPV, theFirstAttach, aD1U, aD1V); | |
1180 | } | |
7fd59977 | 1181 | |
60bf98ae | 1182 | aD1U.Normalize(); |
1183 | aD1V.Normalize(); | |
1184 | ||
1185 | theDirOnPlane = gp_Dir (aD1U); | |
1186 | ||
1187 | gp_Dir aFirstSurfN = gp_Dir (aD1U ^ aD1V); | |
1188 | ||
1189 | aProjector.Init (theFirstAttach, theSecondSurf); | |
1190 | ||
1191 | Standard_Integer aBestPointIndex = 0; | |
1192 | Quantity_Length aMinDist = RealLast(); | |
1193 | gp_Dir aLocalDir; | |
1194 | ||
1195 | for (Standard_Integer aPointIt = 1; aPointIt <= aProjector.NbPoints(); aPointIt++) | |
1196 | { | |
1197 | aProjector.Parameters (aPointIt, aPU, aPV); | |
1198 | ||
1199 | theSecondSurf->D1 (aPU, aPV, theSecondAttach, aD1U, aD1V); | |
1200 | ||
1201 | aLocalDir = aD1U.SquareMagnitude() <= SquareTolerance || aD1V.SquareMagnitude() <= SquareTolerance | |
1202 | ? gp_Dir (gp_Vec (theFirstAttach, aProjector.Point (aPointIt))) | |
1203 | : gp_Dir (aD1U ^ aD1V); | |
1204 | ||
1205 | if (aFirstSurfN.IsParallel (aLocalDir, Precision::Angular()) && aProjector.Distance (aPointIt) < aMinDist) | |
7fd59977 | 1206 | { |
60bf98ae | 1207 | aBestPointIndex = aPointIt; |
1208 | aMinDist = aProjector.Distance (aPointIt); | |
7fd59977 | 1209 | } |
60bf98ae | 1210 | } |
7fd59977 | 1211 | |
60bf98ae | 1212 | if (aBestPointIndex == 0) |
1213 | { | |
1214 | theSecondAttach = theFirstAttach; | |
1215 | } | |
1216 | else | |
1217 | { | |
1218 | theSecondAttach = aProjector.Point (aBestPointIndex); | |
1219 | aProjector.Parameters (aBestPointIndex, aPU, aPV); | |
1220 | ||
1221 | // Now there is projection of FirstAttach onto SecondSurf in aProjector | |
1222 | BRepTopAdaptor_FClass2d aClassifier (theSecondFace, Precision::Confusion()); | |
1223 | ||
1224 | TopAbs_State aState = | |
1225 | aClassifier.Perform (gp_Pnt2d (aPU, aPV), theSecondSurf->IsUPeriodic() || theSecondSurf->IsVPeriodic()); | |
1226 | ||
1227 | if (aState == TopAbs_OUT || aState == TopAbs_UNKNOWN) | |
1228 | { | |
1229 | theSecondAttach = AIS::Nearest (theSecondFace, theSecondAttach); | |
7fd59977 | 1230 | } |
60bf98ae | 1231 | } |
7fd59977 | 1232 | } |
60bf98ae | 1233 | |
7fd59977 | 1234 | gp_Pnt AIS::TranslatePointToBound( const gp_Pnt & aPoint, const gp_Dir & aDir, const Bnd_Box & aBndBox ) |
1235 | { | |
1236 | if (aBndBox.IsOut( aPoint )) | |
1237 | return aPoint; | |
1238 | else | |
1239 | { | |
1240 | gp_Pnt Result(0.0,0.0,0.0); | |
1241 | TColStd_Array2OfReal Bound( 1, 3, 1, 2 ); | |
1242 | TColStd_Array1OfReal Origin( 1, 3 ); | |
1243 | TColStd_Array1OfReal Dir( 1, 3 ); | |
1244 | Standard_Real t; | |
1245 | ||
1246 | aBndBox.Get( Bound(1,1), Bound(2,1), Bound(3,1), Bound(1,2), Bound(2,2), Bound(3,2) ); | |
1247 | aPoint.Coord( Origin(1), Origin(2), Origin(3) ); | |
1248 | aDir.Coord( Dir(1), Dir(2), Dir(3) ); | |
1249 | ||
1250 | Bnd_Box EnlargedBox = aBndBox; | |
1251 | EnlargedBox.Enlarge( aBndBox.GetGap() + Precision::Confusion() ); | |
1252 | ||
1253 | Standard_Boolean IsFound = Standard_False; | |
1254 | for (Standard_Integer i = 1; i <= 3; i++) | |
1255 | { | |
1256 | if (Abs( Dir( i ) ) <= gp::Resolution()) | |
1257 | continue; | |
1258 | for (Standard_Integer j = 1; j <= 2; j++) | |
1259 | { | |
1260 | t = (Bound( i, j ) - Origin( i )) / Dir( i ); | |
1261 | if (t < 0.0e0) | |
1262 | continue; | |
1263 | Result = aPoint.Translated( gp_Vec( aDir ) * t ); | |
1264 | if (! EnlargedBox.IsOut( Result )) | |
1265 | { | |
1266 | IsFound = Standard_True; | |
1267 | break; | |
1268 | } | |
1269 | } | |
1270 | if (IsFound) break; | |
1271 | } | |
1272 | return Result; | |
1273 | } | |
1274 | } | |
1275 | ||
1276 | ||
1277 | //======================================================================= | |
1278 | //function : InDomain | |
1279 | //purpose : | |
1280 | //======================================================================= | |
1281 | ||
1282 | Standard_Boolean AIS::InDomain(const Standard_Real fpar, | |
1283 | const Standard_Real lpar, | |
1284 | const Standard_Real para) | |
1285 | { | |
1286 | if (fpar >= 0.) { | |
1287 | if(lpar > fpar) | |
1288 | return ((para >= fpar) && (para <= lpar)); | |
1289 | else { // fpar > lpar | |
c6541a0c | 1290 | Standard_Real delta = 2*M_PI-fpar; |
7fd59977 | 1291 | Standard_Real lp, par, fp; |
1292 | lp = lpar + delta; | |
1293 | par = para + delta; | |
c6541a0c D |
1294 | while(lp > 2*M_PI) lp-=2*M_PI; |
1295 | while(par > 2*M_PI) par-=2*M_PI; | |
7fd59977 | 1296 | fp = 0.; |
1297 | return ((par >= fp) && (par <= lp)); | |
1298 | } | |
1299 | ||
1300 | } | |
c6541a0c | 1301 | if (para >= (fpar+2*M_PI)) return Standard_True; |
7fd59977 | 1302 | if (para <= lpar) return Standard_True; |
1303 | return Standard_False; | |
1304 | } | |
1305 | ||
1306 | //======================================================================= | |
1307 | //function : DistanceFromApex | |
1308 | //purpose : calculates parametric length arc of ellipse | |
1309 | //======================================================================= | |
1310 | ||
1311 | Standard_Real AIS::DistanceFromApex(const gp_Elips & elips, | |
1312 | const gp_Pnt & Apex, | |
1313 | const Standard_Real par) | |
1314 | { | |
1315 | Standard_Real dist; | |
1316 | Standard_Real parApex = ElCLib::Parameter ( elips, Apex ); | |
c6541a0c | 1317 | if(parApex == 0.0 || parApex == M_PI) |
7fd59977 | 1318 | {//Major case |
1319 | if(parApex == 0.0) //pos Apex | |
c6541a0c | 1320 | dist = (par < M_PI) ? par : (2*M_PI - par); |
7fd59977 | 1321 | else //neg Apex |
c6541a0c | 1322 | dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI ); |
7fd59977 | 1323 | } |
1324 | else | |
1325 | {// Minor case | |
c6541a0c | 1326 | if(parApex == M_PI / 2) //pos Apex |
7fd59977 | 1327 | { |
c6541a0c | 1328 | if(par <= parApex + M_PI && par > parApex) // 3/2*M_PI < par < M_PI/2 |
7fd59977 | 1329 | dist = par - parApex; |
1330 | else | |
1331 | { | |
c6541a0c D |
1332 | if(par > parApex + M_PI) // 3/2*M_PI < par < 2*M_PI |
1333 | dist = 2*M_PI - par + parApex; | |
7fd59977 | 1334 | else |
1335 | dist = parApex - par; | |
1336 | } | |
1337 | } | |
c6541a0c | 1338 | else //neg Apex == 3/2*M_PI |
7fd59977 | 1339 | { |
c6541a0c | 1340 | if(par <= parApex && par >= M_PI/2) // M_PI/2 < par < 3/2*M_PI |
7fd59977 | 1341 | dist = parApex - par; |
1342 | else | |
1343 | { | |
c6541a0c | 1344 | if(par > parApex) // 3/2*M_PI < par < 2*M_PI |
7fd59977 | 1345 | dist = par - parApex; |
1346 | else | |
c6541a0c | 1347 | dist = par + M_PI/2; // 0 < par < M_PI/2 |
7fd59977 | 1348 | } |
1349 | } | |
1350 | } | |
1351 | return dist; | |
1352 | } | |
1353 | ||
1354 | //======================================================================= | |
1355 | //function : NearestApex | |
1356 | //purpose : | |
1357 | //======================================================================= | |
1358 | ||
1359 | gp_Pnt AIS::NearestApex(const gp_Elips & elips, | |
1360 | const gp_Pnt & pApex, | |
1361 | const gp_Pnt & nApex, | |
1362 | const Standard_Real fpara, | |
1363 | const Standard_Real lpara, | |
1364 | Standard_Boolean & IsInDomain) | |
1365 | { | |
1366 | Standard_Real parP, parN; | |
1367 | gp_Pnt EndOfArrow(0.0,0.0,0.0); | |
1368 | IsInDomain = Standard_True; | |
1369 | parP = ElCLib::Parameter ( elips, pApex ); | |
1370 | if(InDomain(fpara, lpara, parP)) EndOfArrow = pApex; | |
1371 | else | |
1372 | { | |
1373 | parN = ElCLib::Parameter ( elips, nApex ); | |
1374 | if(InDomain(fpara, lpara, parN)) EndOfArrow = nApex; | |
1375 | else { | |
1376 | IsInDomain = Standard_False; | |
1377 | Standard_Real posd = Min(DistanceFromApex (elips,pApex, fpara), | |
1378 | DistanceFromApex (elips,pApex, lpara)); | |
1379 | Standard_Real negd = Min(DistanceFromApex (elips,nApex, fpara), | |
1380 | DistanceFromApex (elips,nApex, lpara)); | |
1381 | if( posd < negd ) | |
1382 | EndOfArrow = pApex; | |
1383 | else | |
1384 | EndOfArrow = nApex; | |
1385 | } | |
1386 | } | |
1387 | return EndOfArrow; | |
1388 | } | |
1389 | ||
1390 | //======================================================================= | |
1391 | //function : ComputeProjEdgePresentation | |
1392 | //purpose : | |
1393 | //======================================================================= | |
1394 | ||
6262338c | 1395 | void AIS::ComputeProjEdgePresentation (const Handle(Prs3d_Presentation)& aPresentation, |
1396 | const Handle(Prs3d_Drawer)& aDrawer, | |
1397 | const TopoDS_Edge& anEdge, | |
1398 | const Handle(Geom_Curve)& ProjCurve, | |
1399 | const gp_Pnt& FirstP, | |
1400 | const gp_Pnt& LastP, | |
1401 | const Quantity_NameOfColor aColor, | |
1402 | const Standard_Real aWidth, | |
1403 | const Aspect_TypeOfLine aProjTOL, | |
1404 | const Aspect_TypeOfLine aCallTOL) | |
7fd59977 | 1405 | { |
6262338c | 1406 | if (!aDrawer->HasOwnWireAspect()){ |
7fd59977 | 1407 | aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aProjTOL,2.));} |
1408 | else { | |
1409 | // CLE | |
1410 | // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect(); | |
1411 | Handle(Prs3d_LineAspect) li = aDrawer->WireAspect(); | |
1412 | // ENDCLE | |
1413 | li->SetColor(aColor); | |
1414 | li->SetTypeOfLine(aProjTOL); | |
1415 | li->SetWidth(aWidth); | |
1416 | } | |
1417 | ||
1418 | Standard_Real pf, pl; | |
1419 | TopLoc_Location loc; | |
1420 | Handle(Geom_Curve) curve; | |
1421 | Standard_Boolean isInfinite; | |
1422 | curve = BRep_Tool::Curve(anEdge,loc,pf,pl); | |
1423 | isInfinite = (Precision::IsInfinite(pf) || Precision::IsInfinite(pl)); | |
1424 | ||
1425 | TopoDS_Edge E; | |
1426 | ||
0d969553 | 1427 | // Calculate presentation of the edge |
7fd59977 | 1428 | if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Line)) ) { |
1429 | // CLE | |
c5f3a425 | 1430 | // Handle(Geom_Line) gl (Handle(Geom_Line)::DownCast (ProjCurve)); |
1431 | Handle(Geom_Line) gl = Handle(Geom_Line)::DownCast (ProjCurve); | |
7fd59977 | 1432 | // ENDCLE |
1433 | if ( !isInfinite) { | |
1434 | pf = ElCLib::Parameter(gl->Lin(),FirstP); | |
1435 | pl = ElCLib::Parameter(gl->Lin(),LastP); | |
1436 | BRepBuilderAPI_MakeEdge MakEd(gl->Lin(), pf, pl); | |
1437 | E = MakEd.Edge(); | |
1438 | } | |
1439 | else { | |
1440 | BRepBuilderAPI_MakeEdge MakEd(gl->Lin()); | |
1441 | E = MakEd.Edge(); | |
1442 | } | |
1443 | } | |
1444 | else if (ProjCurve->IsInstance(STANDARD_TYPE(Geom_Circle)) ) { | |
1445 | // CLE | |
c5f3a425 | 1446 | // Handle(Geom_Circle) gc (Handle(Geom_Circle)::DownCast (ProjCurve)); |
1447 | Handle(Geom_Circle) gc = Handle(Geom_Circle)::DownCast (ProjCurve); | |
7fd59977 | 1448 | // ENDCLE |
1449 | pf = ElCLib::Parameter(gc->Circ(),FirstP); | |
1450 | pl = ElCLib::Parameter(gc->Circ(),LastP); | |
1451 | BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl); | |
1452 | E = MakEd.Edge(); | |
1453 | } | |
5ad8c033 | 1454 | StdPrs_WFShape::Add (aPresentation, E, aDrawer); |
7fd59977 | 1455 | |
0d969553 | 1456 | //Calculate the presentation of line connections |
7fd59977 | 1457 | aDrawer->WireAspect()->SetTypeOfLine(aCallTOL); |
1458 | if (!isInfinite) { | |
1459 | gp_Pnt ppf(0.0,0.0,0.0), ppl(0.0,0.0,0.0); | |
1460 | ppf = BRep_Tool::Pnt( TopExp::FirstVertex(TopoDS::Edge(anEdge))); | |
1461 | ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge))); | |
1462 | ||
1463 | // it is patch! | |
5ad8c033 | 1464 | if (FirstP.SquareDistance (ppf) > SquareTolerance) |
1465 | { | |
1466 | BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); | |
1467 | StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer); | |
1468 | } | |
7fd59977 | 1469 | else |
5ad8c033 | 1470 | { |
1471 | BRepBuilderAPI_MakeVertex MakVert1 (FirstP); | |
1472 | StdPrs_WFShape::Add (aPresentation, MakVert1.Vertex(), aDrawer); | |
1473 | } | |
1474 | if (LastP.SquareDistance (ppl) > SquareTolerance) | |
1475 | { | |
1476 | BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); | |
1477 | StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer); | |
1478 | } | |
7fd59977 | 1479 | else |
5ad8c033 | 1480 | { |
1481 | BRepBuilderAPI_MakeVertex MakVert2 (LastP); | |
1482 | StdPrs_WFShape::Add (aPresentation, MakVert2.Vertex(), aDrawer); | |
1483 | } | |
7fd59977 | 1484 | /* |
5ad8c033 | 1485 | BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); |
1486 | StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer); | |
1487 | BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); | |
1488 | StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer); | |
7fd59977 | 1489 | */ |
1490 | } | |
1491 | } | |
1492 | ||
1493 | //======================================================================= | |
1494 | //function : ComputeProjVertexPresentation | |
1495 | //purpose : | |
1496 | //======================================================================= | |
1497 | ||
6262338c | 1498 | void AIS::ComputeProjVertexPresentation (const Handle( Prs3d_Presentation )& aPresentation, |
1499 | const Handle( Prs3d_Drawer )& aDrawer, | |
1500 | const TopoDS_Vertex& aVertex, | |
1501 | const gp_Pnt& ProjPoint, | |
1502 | const Quantity_NameOfColor aColor, | |
1503 | const Standard_Real aWidth, | |
1504 | const Aspect_TypeOfMarker aProjTOM, | |
1505 | const Aspect_TypeOfLine aCallTOL) | |
7fd59977 | 1506 | { |
6262338c | 1507 | if (!aDrawer->HasOwnPointAspect()){ |
7fd59977 | 1508 | aDrawer->SetPointAspect(new Prs3d_PointAspect(aProjTOM, aColor,1));} |
1509 | else { | |
1510 | // CLE | |
1511 | // const Handle(Prs3d_PointAspect)& pa = aDrawer->PointAspect(); | |
1512 | Handle(Prs3d_PointAspect) pa = aDrawer->PointAspect(); | |
1513 | // ENDCLE | |
1514 | pa->SetColor(aColor); | |
1515 | pa->SetTypeOfMarker(aProjTOM); | |
1516 | } | |
1517 | ||
0d969553 | 1518 | // calculate the projection |
7fd59977 | 1519 | StdPrs_Point::Add(aPresentation, new Geom_CartesianPoint(ProjPoint), aDrawer); |
1520 | ||
6262338c | 1521 | if (!aDrawer->HasOwnWireAspect()){ |
7fd59977 | 1522 | aDrawer->SetWireAspect(new Prs3d_LineAspect(aColor,aCallTOL,2.));} |
1523 | else { | |
1524 | // CLE | |
1525 | // const Handle(Prs3d_LineAspect)& li = aDrawer->WireAspect(); | |
1526 | Handle(Prs3d_LineAspect) li = aDrawer->WireAspect(); | |
1527 | // ENDCLE | |
1528 | li->SetColor(aColor); | |
1529 | li->SetTypeOfLine(aCallTOL); | |
1530 | li->SetWidth(aWidth); | |
1531 | } | |
1532 | ||
0d969553 | 1533 | // If the points are not mixed... |
5ad8c033 | 1534 | if (!ProjPoint.IsEqual (BRep_Tool::Pnt (aVertex), Precision::Confusion())) |
1535 | { | |
0d969553 | 1536 | // calculate the lines of recall |
5ad8c033 | 1537 | BRepBuilderAPI_MakeEdge MakEd (ProjPoint, BRep_Tool::Pnt (aVertex)); |
1538 | StdPrs_WFShape::Add (aPresentation, MakEd.Edge(), aDrawer); | |
7fd59977 | 1539 | } |
1540 | } |