0024428: Implementation of LGPL license
[occt.git] / src / AIS / AIS_OffsetDimension.cxx
CommitLineData
b311480e 1// Created on: 1997-03-04
2// Created by: Jean-Pierre COMBE
3// Copyright (c) 1997-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//
973c2be1 8// This library is free software; you can redistribute it and / or modify it
9// under the terms of the GNU Lesser General Public version 2.1 as published
10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <Standard_NotImplemented.hxx>
18
19#include <AIS_OffsetDimension.ixx>
20
21#include <AIS.hxx>
22#include <AIS_Drawer.hxx>
23#include <BRepBuilderAPI_Transform.hxx>
24#include <BRepAdaptor_Surface.hxx>
25#include <BRep_Tool.hxx>
26#include <DsgPrs_OffsetPresentation.hxx>
27#include <ElCLib.hxx>
28#include <ElSLib.hxx>
29#include <GeomAbs_SurfaceType.hxx>
30#include <Graphic3d_Structure.hxx>
31#include <Precision.hxx>
32#include <Prs3d_ArrowAspect.hxx>
33#include <Prs3d_Drawer.hxx>
a6eb515f 34#include <Prs3d_DimensionAspect.hxx>
7fd59977 35#include <Prs3d_LineAspect.hxx>
36#include <Select3D_SensitiveBox.hxx>
37#include <Select3D_SensitiveSegment.hxx>
38#include <SelectMgr_EntityOwner.hxx>
39#include <StdPrs_WFDeflectionShape.hxx>
40#include <TColStd_Array2OfReal.hxx>
41#include <TCollection_ExtendedString.hxx>
42#include <TopExp_Explorer.hxx>
43#include <TopoDS.hxx>
44#include <TopoDS_Vertex.hxx>
45#include <gce_MakeLin.hxx>
46#include <gp_Ax1.hxx>
47#include <gp_Ax2.hxx>
48#include <gp_Ax3.hxx>
49#include <gp_Lin.hxx>
50#include <gp_Pln.hxx>
51#include <gp_Pnt.hxx>
52#include <gp_Trsf.hxx>
53#include <gp_Vec.hxx>
54
55//=======================================================================
56//function : AIS_OffsetDimension
57//purpose :
58//=======================================================================
59AIS_OffsetDimension::AIS_OffsetDimension(const TopoDS_Shape& FistShape,
60 const TopoDS_Shape& SecondShape,
61 const Standard_Real aVal,
62 const TCollection_ExtendedString& aText)
63:AIS_Relation(),
64myFAttach(0.,0.,0.),
65mySAttach(0.,0.,0.)
66{
67 myFShape = FistShape;
68 mySShape = SecondShape;
69 mySymbolPrs = DsgPrs_AS_BOTHAR;
70 myVal = aVal;
71 myText = aText;
72 //myArrowSize = fabs (myVal/5.);
73 myArrowSize = fabs (myVal/10.0);
74 if (myArrowSize > 30.) myArrowSize = 30.;
75 if (myArrowSize < 15.) myArrowSize = 15.;
76 //cout<<"AIS_OffsetDimension::AIS_OffsetDimension " << myArrowSize << " myArrowSize"<<endl;
77}
78
79//=======================================================================
80//function : Compute
81//purpose :
82//=======================================================================
83void AIS_OffsetDimension::Compute(const Handle(PrsMgr_PresentationManager3d)&,
84 const Handle(Prs3d_Presentation)& aprs,
85 const Standard_Integer)
86{
87 aprs->Clear();
88
89 //cout << endl << "This is strange Offset Dimension!" << endl;
90
91 gp_Trsf aInvertTrsf = myRelativePos;
92 //myArrowSize = fabs (myVal/5.);
93 myArrowSize = fabs (myVal/10.0);
94 if (myArrowSize > 30.) myArrowSize = 30.;
95 if (myArrowSize < 15.) myArrowSize = 15.;
96 //cout<<"AIS_OffsetDimension::AIS_OffsetDimension " << myArrowSize << " myArrowSize"<<endl;
97
98 BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
99 BRepAdaptor_Surface surf2(TopoDS::Face(mySShape));
100
101 if (surf1.GetType() == GeomAbs_Cylinder ||
102 surf1.GetType() == GeomAbs_Cone ||
103 surf1.GetType() == GeomAbs_Torus) {
104 if (surf2.GetType() == GeomAbs_Cylinder ||
105 surf2.GetType() == GeomAbs_Cone ||
106 surf2.GetType() == GeomAbs_Torus) {
107 ComputeTwoAxesOffset(aprs, aInvertTrsf);
108 } else {
109 ComputeAxeFaceOffset(aprs, aInvertTrsf);
110 }
111 }
112 else {
113 //myDirAttach : oriente de myFShape vers mySShape
114 gp_Pln aPln = surf1.Plane();
115 gp_Pnt aPnt = aPln.Location();
116
117 gp_Pln bPln = surf2.Plane();
118
119 Standard_Real uPnt, vPnt;
120 ElSLib::Parameters (bPln , aPnt , uPnt, vPnt);
121 gp_Pnt bPnt = ElSLib::Value (uPnt, vPnt, bPln);
122 if (aPnt.IsEqual(bPnt,Precision::Confusion())) {
123 gp_Ax1 aAx1 = aPln.Axis();
124 myDirAttach = aAx1.Direction();
125 } else {
126 gp_Vec aVec (aPnt,bPnt);
127 myDirAttach.SetCoord(aVec.X(),aVec.Y(),aVec.Z());
128 }
129 ComputeTwoFacesOffset(aprs, aInvertTrsf);
130 }
131}
132
133
134//=======================================================================
135//function : Compute
136//purpose : to avoid warning at compilation (SUN)
137//=======================================================================
138void AIS_OffsetDimension::Compute(const Handle(Prs3d_Projector)& /*aProjector*/,
139 const Handle(Prs3d_Presentation)& /*aPresentation*/)
140{
141// Standard_NotImplemented::Raise("AIS_OffsetDimension::Compute(const Handle(Prs3d_Projector)& aProjector,const Handle(Prs3d_Presentation)& aPresentation)");
142// PrsMgr_PresentableObject::Compute( aProjector , aPresentation ) ;
143}
144
7fd59977 145void AIS_OffsetDimension::Compute(const Handle(Prs3d_Projector)& aProjector,
146 const Handle(Geom_Transformation)& aTransformation,
147 const Handle(Prs3d_Presentation)& aPresentation)
148{
149// Standard_NotImplemented::Raise("AIS_OffsetDimension::Compute(const Handle(Prs3d_Projector)&,const Handle(Geom_Transformation)&,const Handle(Prs3d_Presentation)&)");
150 PrsMgr_PresentableObject::Compute( aProjector , aTransformation , aPresentation ) ;
151}
152
153//=======================================================================
154//function : ComputeSelection
155//purpose :
156//=======================================================================
157void AIS_OffsetDimension::ComputeSelection(const Handle(SelectMgr_Selection)& aSel,
158 const Standard_Integer)
159{
160 //myArrowSize = fabs (myVal/5.);
161 myArrowSize = fabs (myVal/10.0);
162 if (myArrowSize > 30.) myArrowSize = 30.;
163 if (myArrowSize < 15.) myArrowSize = 15.;
164 //cout<<"AIS_OffsetDimension::AIS_OffsetDimension " << myArrowSize << " myArrowSize"<<endl;
165 gp_Pnt myTFAttach = myFAttach.Transformed (myRelativePos);
166 gp_Pnt myTSAttach = mySAttach.Transformed (myRelativePos);
167 gp_Dir myTDirAttach = myDirAttach.Transformed (myRelativePos);
168 gp_Dir myTDirAttach2 = myDirAttach2.Transformed (myRelativePos);
169 gp_Pnt Tcurpos = myPosition.Transformed (myRelativePos);;
170
171 gp_Lin L1 (myTFAttach,myTDirAttach);
172 gp_Lin L2 (myTSAttach,myTDirAttach2);
173 gp_Pnt Proj1 = ElCLib::Value(ElCLib::Parameter(L1,Tcurpos),L1);
174 gp_Pnt Proj2 = ElCLib::Value(ElCLib::Parameter(L2,Tcurpos),L2);
175 gp_Lin L3;
176
177 Handle(SelectMgr_EntityOwner) own = new SelectMgr_EntityOwner(this,7);
178
179 if (!Proj1.IsEqual(Proj2,Precision::Confusion())) {
180 L3 = gce_MakeLin(Proj1,Proj2);
181 }
182 else { // cas ou la dimension est nulle
183 if (!Proj1.IsEqual(Tcurpos,Precision::Confusion())) {
184 gp_Vec v3 (Proj1,Tcurpos);
185 gp_Dir d3 (v3);
186 L3 = gce_MakeLin(Proj1,d3);
187 } else {
188 L3 = gce_MakeLin(Proj1,myTDirAttach);
189 }
190
191 // Text
192 Standard_Real size(Min(myVal/100.+1.e-6,myArrowSize+1.e-6));
193 Handle( Select3D_SensitiveBox ) box = new Select3D_SensitiveBox( own,
194 Tcurpos.X(),
195 Tcurpos.Y(),
196 Tcurpos.Z(),
197 Tcurpos.X() + size,
198 Tcurpos.Y() + size,
199 Tcurpos.Z() + size);
200 aSel->Add(box);
201 }
202
203 Standard_Real parmin,parmax,parcur;
204 parmin = ElCLib::Parameter(L3,Proj1);
205 parmax = parmin;
206
207 parcur = ElCLib::Parameter(L3,Proj2);
208 parmin = Min(parmin,parcur);
209 parmax = Max(parmax,parcur);
210
211 parcur = ElCLib::Parameter(L3,Tcurpos);
212 parmin = Min(parmin,parcur);
213 parmax = Max(parmax,parcur);
214
215 gp_Pnt PointMin = ElCLib::Value(parmin,L3);
216 gp_Pnt PointMax = ElCLib::Value(parmax,L3);
217
218 Handle(Select3D_SensitiveSegment) seg;
219 if (!PointMin.IsEqual(PointMax,Precision::Confusion())) {
220 seg = new Select3D_SensitiveSegment(own,
221 PointMin,
222 PointMax);
223 aSel->Add(seg);
224 }
225
226 if (!myTFAttach.IsEqual(Proj1,Precision::Confusion())) {
227 seg = new Select3D_SensitiveSegment(own,
228 myTFAttach,
229 Proj1);
230 aSel->Add(seg);
231 }
232 if (!myTSAttach.IsEqual(Proj2,Precision::Confusion())) {
233 seg = new Select3D_SensitiveSegment(own,
234 myTSAttach,
235 Proj2);
236 aSel->Add(seg);
237 }
238}
239
240//=======================================================================
241//function : ComputeTwoAxesOffset
242//purpose :
243//=======================================================================
244void AIS_OffsetDimension::ComputeTwoAxesOffset(const Handle(Prs3d_Presentation)& aprs,
245 const gp_Trsf& aTrsf)
246{
247 BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
248 BRepAdaptor_Surface surf2(TopoDS::Face(mySShape));
249
250 gp_Ax1 Ax1Surf1, Ax1Surf2;
251
252 if (surf1.GetType() == GeomAbs_Cylinder) {
253 gp_Cylinder aCyl= surf1.Cylinder();
254 Ax1Surf1 = aCyl.Axis();
255 } else if (surf1.GetType() == GeomAbs_Cone) {
256 gp_Cone aCone= surf1.Cone();
257 Ax1Surf1 = aCone.Axis();
258 } else if (surf1.GetType() == GeomAbs_Torus) {
259 gp_Torus aTore= surf1.Torus();
260 Ax1Surf1 = aTore.Axis();
261 }
262 Standard_Real FirstUParam = surf1.FirstUParameter();
263 Standard_Real FirstVParam = surf1.FirstVParameter();
264 Standard_Real LastVParam = surf1.LastVParameter();
265 gp_Pnt P1First = surf1.Value(FirstUParam,FirstVParam);
266 gp_Pnt P1Last = surf1.Value(FirstUParam,LastVParam);
267
268
269 if (surf2.GetType() == GeomAbs_Cylinder) {
270 gp_Cylinder aCyl= surf2.Cylinder();
271 Ax1Surf2 = aCyl.Axis();
272 } else if (surf2.GetType() == GeomAbs_Cone) {
273 gp_Cone aCone= surf2.Cone();
274 Ax1Surf2 = aCone.Axis();
275 } else if (surf2.GetType() == GeomAbs_Torus) {
276 gp_Torus aTore= surf2.Torus();
277 Ax1Surf2 = aTore.Axis();
278 }
279 FirstUParam = surf2.FirstUParameter();
280 FirstVParam = surf2.FirstVParameter();
281 LastVParam = surf2.LastVParameter();
282 gp_Pnt P2First = surf2.Value(FirstUParam,FirstVParam);
283 gp_Pnt P2Last = surf2.Value(FirstUParam,LastVParam);
284
285
286
287 myFAttach = Ax1Surf1.Location();
288 mySAttach = Ax1Surf2.Location();
289 myDirAttach = Ax1Surf1.Direction();
290 myDirAttach2 = myDirAttach;
291 gp_Pnt curpos;
292 gp_Lin aProjLine = gce_MakeLin(myFAttach,myDirAttach);
293
294 if (myAutomaticPosition) {
295 curpos.SetX ( (myFAttach.X() + mySAttach.X()) /2. + 0.01);
296 curpos.SetY ( (myFAttach.Y() + mySAttach.Y()) /2. + 0.01);
297 curpos.SetZ ( (myFAttach.Z() + mySAttach.Z()) /2. + 0.01);
298 // + 0.01 pour eviter un raise de ComputeSelection...
299
300 myPosition = curpos;
301 }
302 else {
303 curpos = myPosition;
304 }
305
306 curpos = ElCLib::Value(ElCLib::Parameter(aProjLine,curpos),aProjLine);
307 // on projette pour la presentation
308
309 gp_Pnt P1FirstProj = ElCLib::Value(ElCLib::Parameter(aProjLine,P1First),aProjLine);
310 gp_Pnt P1LastProj = ElCLib::Value(ElCLib::Parameter(aProjLine,P1Last),aProjLine);
311 if (P1FirstProj.Distance(curpos) > P1LastProj.Distance(curpos))
312 myFAttach = P1FirstProj;
313 else
314 myFAttach = P1LastProj;
315
316 gp_Pnt P2FirstProj = ElCLib::Value(ElCLib::Parameter(aProjLine,P2First),aProjLine);
317 gp_Pnt P2LastProj = ElCLib::Value(ElCLib::Parameter(aProjLine,P2Last),aProjLine);
318 if (P2FirstProj.Distance(curpos) > P2LastProj.Distance(curpos))
319 mySAttach = P2FirstProj;
320 else
321 mySAttach = P2LastProj;
322
323
a6eb515f 324 Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
325 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
7fd59977 326 //cout<<"AIS_OffsetDimension::AIS_OffsetDimension " << myArrowSize << " myArrowSize"<<endl;
327 arr->SetLength(myArrowSize);
a6eb515f 328 arr = la->ArrowAspect();
7fd59977 329 arr->SetLength(myArrowSize);
330
331 gp_Pnt myTFAttach = myFAttach.Transformed (aTrsf);
332 gp_Pnt myTSAttach = mySAttach.Transformed (aTrsf);
333 gp_Dir myTDirAttach = myDirAttach.Transformed (aTrsf);
334 gp_Dir myTDirAttach2 = myTDirAttach;
335 gp_Pnt Tcurpos = curpos.Transformed (aTrsf);
336
337 if (myIsSetBndBox)
338 Tcurpos = AIS::TranslatePointToBound( Tcurpos, myDirAttach, myBndBox );
339
340 DsgPrs_OffsetPresentation::AddAxes(aprs,
341 myDrawer,
342 myText,
343 myTFAttach,
344 myTSAttach,
345 myTDirAttach,
346 myTDirAttach2,
347 Tcurpos);
348
349 BRepBuilderAPI_Transform transform1 (myFShape, aTrsf, Standard_True);
350 TopoDS_Shape myTFShape = transform1.Shape();
351 BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True);
352 TopoDS_Shape myTSShape = transform2.Shape();
353
354 StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer);
355 StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer);
356}
357
358//=======================================================================
359//function : ComputeTwoFacesOffset
360//purpose :
361//=======================================================================
362void AIS_OffsetDimension::ComputeTwoFacesOffset(const Handle(Prs3d_Presentation)& aprs,
363 const gp_Trsf& aTrsf)
364{
365 gp_Dir norm1 = myDirAttach;
366 gp_Pnt curpos;
367 gp_Ax2 myax2;
368 if (myAutomaticPosition && ! myIsSetBndBox) {
369 TopExp_Explorer explo(myFShape,TopAbs_VERTEX);
370 if (explo.More()) {
371 TopoDS_Vertex vertref = TopoDS::Vertex(explo.Current());
372 myFAttach = BRep_Tool::Pnt(vertref);
373 gp_Vec trans = norm1.XYZ()*fabs(myVal/2);
374 gp_Ax2 ax2(myFAttach,norm1);
375 myDirAttach = ax2.XDirection();
376 curpos = myFAttach.Translated(trans);
377 if (myVal <= Precision::Confusion()) {
378 gp_Vec vecnorm1 = norm1.XYZ()*.001;
379 curpos.Translate(vecnorm1);
380 }
381 myPosition = curpos;
382 myax2 = ax2;
383 }
384 }
385 else {
386 if (myAutomaticPosition && myIsSetBndBox)
387 {
388 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
389 myBndBox.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax );
390 myPosition.SetCoord( aXmax, aYmax, aZmax );
391 }
392
393 curpos = myPosition;
394 myFAttach = AIS::Nearest(myFShape,curpos);
395 if (myFAttach.Distance(curpos) <= Precision::Confusion()) {
396 gp_Ax2 ax2(myFAttach,norm1);
397 myDirAttach = ax2.XDirection();
398 myax2 = ax2;
399 }
400 else {
401 gp_Dir orient(myFAttach.XYZ()-curpos.XYZ());
402 gp_Ax2 ax2(myFAttach,norm1);
403 if (orient.Angle(norm1) <= Precision::Angular()) {
404 myDirAttach = ax2.XDirection();
405 }
406 else {
407 gp_Dir adir = norm1 ^ orient;
408 myDirAttach = adir ^ norm1;
409 }
410 myax2 = ax2;
411 }
412 }
413 // en attendant mieux
414 mySAttach = AIS::Nearest(mySShape,curpos);
415 gp_Ax3 anax3 (myax2);
416 gp_Pln apln (anax3);
417
418 //gp_Pnt proj2;
419 Standard_Real u2,v2, uatt, vatt;
420 ElSLib::Parameters (apln , mySAttach, uatt,vatt);
421 ElSLib::Parameters (apln , curpos , u2,v2);
422
423 if (uatt== u2 && vatt == v2) {
424 myDirAttach2 = myDirAttach;
425 } else {
426 gp_Vec avec (ElSLib::Value (uatt,vatt, apln) , ElSLib::Value (u2,v2, apln));
427 myDirAttach2.SetCoord (avec.X(),avec.Y(),avec.Z());
428 }
429
a6eb515f 430 Handle(Prs3d_DimensionAspect) la = myDrawer->DimensionAspect();
431 Handle(Prs3d_ArrowAspect) arr = la->ArrowAspect();
7fd59977 432 //cout<<"AIS_OffsetDimension::AIS_OffsetDimension " << myArrowSize << " myArrowSize"<<endl;
433 arr->SetLength(myArrowSize);
a6eb515f 434 arr = la->ArrowAspect();
7fd59977 435 arr->SetLength(myArrowSize);
436
437 gp_Pnt myTFAttach = myFAttach.Transformed (aTrsf);
438 gp_Pnt myTSAttach = mySAttach.Transformed (aTrsf);
439 gp_Dir myTDirAttach = myDirAttach.Transformed (aTrsf);
440 gp_Dir myTDirAttach2 = myDirAttach2.Transformed (aTrsf);
441 gp_Pnt Tcurpos = curpos.Transformed (aTrsf);
442
443/*
444 if (myIsSetBndBox)
445 {
446 BRepAdaptor_Surface surf1(TopoDS::Face(myFShape));
447 Tcurpos = AIS::TranslatePointToBound( Tcurpos, surf1.Plane().XAxis().Direction(), myBndBox );
448 }
449*/
450 DsgPrs_OffsetPresentation::Add(aprs,
451 myDrawer,
452 myText,
453 myTFAttach,
454 myTSAttach,
455 myTDirAttach,
456 myTDirAttach2,
457 Tcurpos);
458
459
460 BRepBuilderAPI_Transform transform1 (myFShape, aTrsf, Standard_True);
461 TopoDS_Shape myTFShape = transform1.Shape();
462 BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True);
463 TopoDS_Shape myTSShape = transform2.Shape();
464
465 StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer);
466 StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer);
467
468}
469
470//=======================================================================
471//function : ComputeAxeFaceOffset
472//purpose :
473//=======================================================================
474void AIS_OffsetDimension::ComputeAxeFaceOffset(const Handle(Prs3d_Presentation)& aprs,
475 const gp_Trsf& aTrsf)
476{
477 BRepBuilderAPI_Transform transform1 (myFShape, aTrsf, Standard_True);
478 TopoDS_Shape myTFShape = transform1.Shape();
479 BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True);
480 TopoDS_Shape myTSShape = transform2.Shape();
481
482 StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer);
483 StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer);
484}
485