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