b311480e |
1 | // Created on: 1996-12-05 |
2 | // Created by: Jean-Pierre COMBE/Odile Olivier |
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 | #include <AIS_ParallelRelation.ixx> |
18 | |
19 | #include <Standard_NotImplemented.hxx> |
20 | #include <Standard_DomainError.hxx> |
21 | |
22 | #include <Precision.hxx> |
23 | |
24 | #include <TCollection_AsciiString.hxx> |
25 | #include <TCollection_ExtendedString.hxx> |
26 | |
27 | #include <DsgPrs_LengthPresentation.hxx> |
28 | |
29 | #include <Prs3d_Drawer.hxx> |
30 | #include <Prs3d_ArrowAspect.hxx> |
a6eb515f |
31 | #include <Prs3d_DimensionAspect.hxx> |
7fd59977 |
32 | |
33 | #include <AIS.hxx> |
7fd59977 |
34 | |
35 | #include <SelectMgr_EntityOwner.hxx> |
f751596e |
36 | #include <SelectMgr_Selection.hxx> |
7fd59977 |
37 | #include <Select3D_SensitiveSegment.hxx> |
38 | #include <Select3D_SensitiveBox.hxx> |
39 | |
40 | #include <TopoDS.hxx> |
41 | #include <TopExp_Explorer.hxx> |
42 | #include <BRep_Tool.hxx> |
43 | #include <BRepAdaptor_Surface.hxx> |
44 | #include <BRepAdaptor_Curve.hxx> |
45 | |
46 | #include <gp_Lin.hxx> |
47 | #include <gp_Pnt.hxx> |
48 | #include <ElCLib.hxx> |
49 | #include <gp_Pln.hxx> |
50 | #include <gp_Dir.hxx> |
51 | #include <gp_Ax1.hxx> |
52 | #include <gp_Ax2.hxx> |
53 | |
54 | #include <gce_MakeLin.hxx> |
55 | |
56 | #include <Geom_Plane.hxx> |
57 | #include <Geom_Line.hxx> |
58 | #include <Geom_Ellipse.hxx> |
59 | |
60 | //======================================================================= |
61 | //function : Constructor |
62 | //purpose : |
63 | //======================================================================= |
64 | AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, |
65 | const TopoDS_Shape& aSShape, |
66 | const Handle(Geom_Plane)& aPlane) |
67 | { |
68 | myFShape = aFShape; |
69 | mySShape = aSShape; |
70 | myPlane = aPlane; |
71 | myAutomaticPosition = Standard_True; |
72 | myArrowSize = 0.01; |
73 | mySymbolPrs = DsgPrs_AS_BOTHAR; |
74 | } |
75 | |
76 | //======================================================================= |
77 | //function : Constructor |
78 | //purpose : |
79 | //======================================================================= |
80 | AIS_ParallelRelation::AIS_ParallelRelation(const TopoDS_Shape& aFShape, |
81 | const TopoDS_Shape& aSShape, |
82 | const Handle(Geom_Plane)& aPlane, |
83 | const gp_Pnt& aPosition, |
84 | const DsgPrs_ArrowSide aSymbolPrs, |
85 | const Standard_Real anArrowSize) |
86 | { |
87 | myFShape = aFShape; |
88 | mySShape = aSShape; |
89 | myPlane = aPlane; |
90 | myAutomaticPosition = Standard_False; |
7fd59977 |
91 | SetArrowSize( anArrowSize ); |
7fd59977 |
92 | myPosition = aPosition; |
93 | mySymbolPrs = aSymbolPrs; |
94 | } |
95 | |
96 | //======================================================================= |
97 | //function : Compute |
98 | //purpose : |
99 | //======================================================================= |
100 | void AIS_ParallelRelation::Compute(const Handle(PrsMgr_PresentationManager3d)&, |
101 | const Handle(Prs3d_Presentation)& aPresentation, |
102 | const Standard_Integer) |
103 | { |
104 | aPresentation->Clear(); |
105 | |
106 | switch (myFShape.ShapeType()) |
107 | { |
108 | case TopAbs_FACE : |
109 | { |
110 | // cas longueur entre deux faces |
111 | ComputeTwoFacesParallel(aPresentation); |
112 | } |
113 | break; |
114 | case TopAbs_EDGE : |
115 | { |
116 | // cas longueur entre deux edges |
117 | ComputeTwoEdgesParallel(aPresentation); |
118 | } |
119 | break; |
120 | default: |
121 | break; |
122 | } |
123 | } |
124 | |
125 | //======================================================================= |
126 | //function : Compute |
127 | //purpose : to avoid warning |
128 | //======================================================================= |
129 | void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector, |
130 | const Handle(Prs3d_Presentation)& aPresentation) |
131 | { |
132 | // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&,const Handle(Prs3d_Presentation)&)"); |
133 | PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ; |
134 | } |
135 | |
857ffd5e |
136 | void AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)& aProjector, const Handle(Geom_Transformation)& aTransformation, const Handle(Prs3d_Presentation)& aPresentation) |
7fd59977 |
137 | { |
857ffd5e |
138 | // Standard_NotImplemented::Raise("AIS_ParallelRelation::Compute(const Handle(Prs3d_Projector)&, const Handle(Geom_Transformation)&, const Handle(Prs3d_Presentation)&)"); |
7fd59977 |
139 | PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ; |
140 | } |
141 | |
142 | //======================================================================= |
143 | //function : ComputeSelection |
144 | //purpose : |
145 | //======================================================================= |
146 | void AIS_ParallelRelation::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, |
147 | const Standard_Integer) |
148 | { |
149 | gp_Lin L1 (myFAttach,myDirAttach); |
150 | gp_Lin L2 (mySAttach,myDirAttach); |
151 | gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,myPosition),L1); |
152 | gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,myPosition),L2); |
153 | |
154 | gp_Lin L3; |
155 | Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7); |
156 | |
157 | if (!Proj1.IsEqual(Proj2,Precision::Confusion())) |
158 | { |
159 | L3 = gce_MakeLin(Proj1,Proj2); |
160 | } |
161 | else |
162 | { |
163 | L3 = gce_MakeLin(Proj1,myDirAttach); |
164 | Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6)); |
165 | Handle(Select3D_SensitiveBox) box = |
166 | new Select3D_SensitiveBox(own, |
167 | myPosition.X(), |
168 | myPosition.Y(), |
169 | myPosition.Z(), |
170 | myPosition.X()+size, |
171 | myPosition.Y()+size, |
172 | myPosition.Z()+size); |
173 | aSelection->Add(box); |
174 | } |
175 | Standard_Real parmin,parmax,parcur; |
176 | parmin = ElCLib::Parameter(L3,Proj1); |
177 | parmax = parmin; |
178 | |
179 | parcur = ElCLib::Parameter(L3,Proj2); |
180 | parmin = Min(parmin,parcur); |
181 | parmax = Max(parmax,parcur); |
182 | |
183 | parcur = ElCLib::Parameter(L3,myPosition); |
184 | parmin = Min(parmin,parcur); |
185 | parmax = Max(parmax,parcur); |
186 | |
187 | gp_Pnt PointMin = ElCLib::Value(parmin,L3); |
188 | gp_Pnt PointMax = ElCLib::Value(parmax,L3); |
189 | |
190 | Handle(Select3D_SensitiveSegment) seg; |
191 | |
192 | if (!PointMin.IsEqual(PointMax,Precision::Confusion())) |
193 | { |
194 | seg = new Select3D_SensitiveSegment(own, |
195 | PointMin, |
196 | PointMax); |
197 | aSelection->Add(seg); |
198 | } |
199 | if (!myFAttach.IsEqual(Proj1,Precision::Confusion())) |
200 | { |
201 | seg = new Select3D_SensitiveSegment(own, myFAttach, Proj1); |
202 | aSelection->Add(seg); |
203 | } |
204 | if (!mySAttach.IsEqual(Proj2,Precision::Confusion())) |
205 | { |
206 | seg = new Select3D_SensitiveSegment(own, mySAttach, Proj2); |
207 | aSelection->Add(seg); |
208 | } |
209 | } |
210 | |
211 | //======================================================================= |
212 | //function : ComputeTwoFacesParallel |
213 | //purpose : |
214 | //======================================================================= |
215 | void AIS_ParallelRelation::ComputeTwoFacesParallel(const Handle(Prs3d_Presentation)&) |
216 | { |
217 | Standard_NotImplemented::Raise("AIS_ParallelRelation::ComputeTwoFacesParallel not implemented"); |
218 | } |
219 | |
220 | //======================================================================= |
221 | //function : ComputeTwoEdgesParallel |
222 | //purpose : |
223 | //======================================================================= |
224 | void AIS_ParallelRelation::ComputeTwoEdgesParallel(const Handle(Prs3d_Presentation)& aPresentation) |
225 | { |
226 | TopoDS_Edge E1 = TopoDS::Edge(myFShape); |
227 | TopoDS_Edge E2 = TopoDS::Edge(mySShape); |
228 | |
229 | gp_Pnt ptat11,ptat12,ptat21,ptat22;//,pint3d; |
230 | Handle(Geom_Curve) geom1,geom2; |
231 | Standard_Boolean isInfinite1,isInfinite2; |
232 | Handle(Geom_Curve) extCurv; |
233 | if (!AIS::ComputeGeometry(E1,E2,myExtShape, |
234 | geom1,geom2, |
235 | ptat11,ptat12,ptat21,ptat22, |
236 | extCurv, |
237 | isInfinite1,isInfinite2, |
238 | myPlane)) |
239 | { |
240 | return; |
241 | } |
242 | |
243 | aPresentation->SetInfiniteState((isInfinite1 || isInfinite2) && (myExtShape != 0)); |
244 | |
245 | gp_Lin l1; |
246 | gp_Lin l2; |
247 | Standard_Boolean isEl1 = Standard_False, isEl2 = Standard_False; |
248 | |
249 | if (geom1->IsInstance(STANDARD_TYPE(Geom_Ellipse))) |
250 | { |
251 | const Handle(Geom_Ellipse)& geom_el1 = (Handle(Geom_Ellipse)&) geom1; |
252 | // construct lines through focuses |
253 | gp_Ax1 elAx = geom_el1->XAxis(); |
254 | l1 = gp_Lin(elAx); |
255 | Standard_Real focex = geom_el1->MajorRadius() - geom_el1->Focal()/2.0; |
256 | gp_Vec transvec = gp_Vec(elAx.Direction())*focex; |
257 | ptat11 = geom_el1->Focus1().Translated(transvec); |
258 | ptat12 = geom_el1->Focus2().Translated(-transvec); |
259 | isEl1 = Standard_True; |
260 | } |
261 | else if (geom1->IsInstance(STANDARD_TYPE(Geom_Line))) |
262 | { |
263 | const Handle(Geom_Line)& geom_lin1 = (Handle(Geom_Line)&) geom1; |
264 | l1 = geom_lin1->Lin(); |
265 | } |
266 | else return; |
267 | |
268 | if (geom2->IsInstance(STANDARD_TYPE(Geom_Ellipse))) |
269 | { |
270 | const Handle(Geom_Ellipse)& geom_el2 = (Handle(Geom_Ellipse)&) geom2; |
271 | // construct lines through focuses |
272 | gp_Ax1 elAx = geom_el2->XAxis(); |
273 | l2 = gp_Lin(elAx); |
274 | Standard_Real focex = geom_el2->MajorRadius() - geom_el2->Focal()/2.0; |
275 | gp_Vec transvec = gp_Vec(elAx.Direction())*focex; |
276 | ptat21 = geom_el2->Focus1().Translated(transvec); |
277 | ptat22 = geom_el2->Focus2().Translated(-transvec); |
278 | isEl2 = Standard_True; |
279 | } |
280 | else if (geom2->IsInstance(STANDARD_TYPE(Geom_Line))) |
281 | { |
282 | const Handle(Geom_Line)& geom_lin2 = (Handle(Geom_Line)&) geom2; |
283 | l2 = geom_lin2->Lin(); |
284 | } |
285 | else return; |
286 | |
287 | const Handle(Geom_Line)& geom_lin1 = new Geom_Line(l1); |
288 | const Handle(Geom_Line)& geom_lin2 = new Geom_Line(l2); |
289 | |
290 | myDirAttach = l1.Direction(); |
291 | // size |
7fd59977 |
292 | if( !myArrowSizeIsDefined ) { |
7fd59977 |
293 | Standard_Real arrSize1 (myArrowSize), arrSize2 (myArrowSize); |
294 | if (!isInfinite1) arrSize1 = ptat11.Distance(ptat12)/50.; |
295 | if (!isInfinite2) arrSize2 = ptat21.Distance(ptat22)/50.; |
296 | myArrowSize = Max(myArrowSize,Max(arrSize1,arrSize2)); |
297 | // myArrowSize = Min(myArrowSize,Min(arrSize1,arrSize2)); |
7fd59977 |
298 | } |
7fd59977 |
299 | |
300 | if ( myAutomaticPosition ) |
301 | { |
302 | gp_Pnt curpos; |
303 | if ( !isInfinite1 ) |
304 | { |
305 | gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l2,ptat11),l2); |
306 | curpos.SetXYZ((ptat11.XYZ() + p2.XYZ())/2.); |
307 | } |
308 | else if ( !isInfinite2 ) |
309 | { |
310 | gp_Pnt p2 = ElCLib::Value(ElCLib::Parameter(l1,ptat21),l1); |
311 | curpos.SetXYZ((ptat21.XYZ()+p2.XYZ())/2.); |
312 | } |
313 | else |
314 | { |
315 | curpos.SetXYZ((l1.Location().XYZ()+l2.Location().XYZ())/2.); |
316 | } |
317 | // offset pour eviter confusion Edge et Dimension |
318 | gp_Vec offset (myDirAttach); |
319 | offset = offset*myArrowSize*(-10.); |
320 | curpos.Translate(offset); |
321 | myPosition = curpos; |
322 | } |
323 | |
324 | // recherche points attache |
325 | if (!isInfinite1) |
326 | { |
327 | if ( isEl1 ) |
328 | { |
329 | if (myPosition.Distance(ptat11) < myPosition.Distance(ptat12)) myFAttach = ptat12; |
330 | else myFAttach = ptat11; |
331 | } |
332 | else |
333 | { |
334 | if (myPosition.Distance(ptat11) > myPosition.Distance(ptat12)) myFAttach = ptat12; |
335 | else myFAttach = ptat11; |
336 | } |
337 | } |
338 | else |
339 | { |
340 | myFAttach = ElCLib::Value(ElCLib::Parameter(l1,myPosition),l1); |
341 | } |
342 | |
343 | if (!isInfinite2) |
344 | { |
345 | if ( isEl2 ) |
346 | { |
347 | if (myPosition.Distance(ptat21) < myPosition.Distance(ptat22)) mySAttach = ptat22; |
348 | else mySAttach = ptat21; |
349 | } |
350 | else |
351 | { |
352 | if (myPosition.Distance(ptat21) > myPosition.Distance(ptat22)) mySAttach = ptat22; |
353 | else mySAttach = ptat21; |
354 | } |
355 | } |
356 | else |
357 | { |
358 | mySAttach = ElCLib::Value(ElCLib::Parameter(l2,myPosition),l2); |
359 | } |
360 | TCollection_ExtendedString aText (" //"); |
361 | |
362 | if (l1.Distance(l2) <= Precision::Confusion()) |
363 | { |
364 | myArrowSize = 0.; |
365 | } |
a6eb515f |
366 | Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect(); |
367 | Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect(); |
7fd59977 |
368 | arr->SetLength(myArrowSize); |
a6eb515f |
369 | arr = la->ArrowAspect(); |
7fd59977 |
370 | arr->SetLength(myArrowSize); |
371 | if ( myExtShape == 1) |
372 | mySymbolPrs = DsgPrs_AS_FIRSTPT_LASTAR; |
373 | else if ( myExtShape == 2) |
374 | mySymbolPrs = DsgPrs_AS_FIRSTAR_LASTPT; |
375 | |
376 | DsgPrs_LengthPresentation::Add(aPresentation, |
377 | myDrawer, |
378 | aText, |
379 | myFAttach, |
380 | mySAttach, |
381 | myDirAttach, |
382 | myPosition, |
383 | mySymbolPrs); |
384 | if ( (myExtShape != 0) && !extCurv.IsNull()) |
385 | { |
386 | gp_Pnt pf, pl; |
387 | if ( myExtShape == 1 ) |
388 | { |
389 | if (!isInfinite1) |
390 | { |
391 | pf = ptat11; |
392 | pl = ptat12; |
393 | } |
394 | ComputeProjEdgePresentation(aPresentation,E1,geom_lin1,pf,pl); |
395 | } |
396 | else |
397 | { |
398 | if (!isInfinite2) |
399 | { |
400 | pf = ptat21; |
401 | pl = ptat22; |
402 | } |
403 | ComputeProjEdgePresentation(aPresentation,E2,geom_lin2,pf,pl); |
404 | } |
405 | } |
406 | } |