1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 #include <Aspect_TypeOfLine.hxx>
16 #include <Aspect_TypeOfMarker.hxx>
19 #include <gce_MakeLin.hxx>
20 #include <Geom_Circle.hxx>
21 #include <Geom_Curve.hxx>
22 #include <Geom_Line.hxx>
23 #include <Geom_Surface.hxx>
24 #include <GeomAPI_ExtremaCurveCurve.hxx>
25 #include <GeomAPI_ProjectPointOnCurve.hxx>
26 #include <GeomAPI_ProjectPointOnSurf.hxx>
28 #include <gp_Circ.hxx>
30 #include <gp_Elips.hxx>
34 #include <Graphic3d_ArrayOfPoints.hxx>
35 #include <Graphic3d_AspectLine3d.hxx>
36 #include <Graphic3d_AspectMarker3d.hxx>
37 #include <Graphic3d_Group.hxx>
38 #include <Graphic3d_Vertex.hxx>
39 #include <Precision.hxx>
40 #include <Prs3d_Arrow.hxx>
41 #include <Prs3d_ArrowAspect.hxx>
42 #include <Prs3d_DimensionAspect.hxx>
43 #include <Prs3d_LineAspect.hxx>
44 #include <Prs3d_Presentation.hxx>
45 #include <Prs3d_Root.hxx>
46 #include <Quantity_Color.hxx>
47 #include <TCollection_AsciiString.hxx>
48 #include <TCollection_ExtendedString.hxx>
50 void DsgPrs::ComputeSymbol (const Handle(Prs3d_Presentation)& aPresentation,
51 const Handle(Prs3d_DimensionAspect)& LA,
56 const DsgPrs_ArrowSide ArrowSide,
57 const Standard_Boolean drawFromCenter)
59 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
61 Quantity_Color aColor = LA->LineAspect()->Aspect()->Color();
62 Handle(Graphic3d_AspectMarker3d) aMarkerAsp = new Graphic3d_AspectMarker3d (Aspect_TOM_O, aColor, 1.0);
63 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect (aMarkerAsp);
64 Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(LA->LineAspect()->Aspect());
71 case DsgPrs_AS_FIRSTAR:
74 Prs3d_Arrow::Draw(aPresentation,
77 LA->ArrowAspect()->Angle(),
78 LA->ArrowAspect()->Length());
81 case DsgPrs_AS_LASTAR:
84 Prs3d_Arrow::Draw(aPresentation,
87 LA->ArrowAspect()->Angle(),
88 LA->ArrowAspect()->Length());
92 case DsgPrs_AS_BOTHAR:
94 Prs3d_Arrow::Draw(aPresentation,
97 LA->ArrowAspect()->Angle(),
98 LA->ArrowAspect()->Length());
99 Prs3d_Arrow::Draw(aPresentation,
102 LA->ArrowAspect()->Angle(),
103 LA->ArrowAspect()->Length());
108 case DsgPrs_AS_FIRSTPT:
112 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
113 anArrayOfPoints->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
114 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
119 case DsgPrs_AS_LASTPT:
121 // On dessine un rond
122 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
123 anArrayOfPoints->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
124 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
128 case DsgPrs_AS_BOTHPT:
132 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints1 = new Graphic3d_ArrayOfPoints (1);
133 anArrayOfPoints1->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
134 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints1);
138 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints2 = new Graphic3d_ArrayOfPoints (1);
139 anArrayOfPoints2->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
140 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints2);
145 case DsgPrs_AS_FIRSTAR_LASTPT:
148 Prs3d_Arrow::Draw(aPresentation,
151 LA->ArrowAspect()->Angle(),
152 LA->ArrowAspect()->Length());
154 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
155 anArrayOfPoints->AddVertex (pt2.X(), pt2.Y(), pt2.Z());
156 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
160 case DsgPrs_AS_FIRSTPT_LASTAR:
165 Handle(Graphic3d_ArrayOfPoints) anArrayOfPoints = new Graphic3d_ArrayOfPoints (1);
166 anArrayOfPoints->AddVertex (pt1.X(), pt1.Y(), pt1.Z());
167 Prs3d_Root::CurrentGroup(aPresentation)->AddPrimitiveArray (anArrayOfPoints);
170 Prs3d_Arrow::Draw(aPresentation,
173 LA->ArrowAspect()->Angle(),
174 LA->ArrowAspect()->Length());
181 //=======================================================================
182 //function : ComputePlanarFacesLengthPresentation
184 //=======================================================================
186 void DsgPrs::ComputePlanarFacesLengthPresentation( const Standard_Real FirstArrowLength,
187 const Standard_Real SecondArrowLength,
188 const gp_Pnt& AttachmentPoint1,
189 const gp_Pnt& AttachmentPoint2,
190 const gp_Dir& DirAttach,
191 const gp_Pnt& OffsetPoint,
192 const gp_Pln& PlaneOfFaces,
193 gp_Pnt & EndOfArrow1,
194 gp_Pnt & EndOfArrow2,
195 gp_Dir & DirOfArrow1 )
197 gp_Lin FirstLin( AttachmentPoint1, DirAttach );
198 gp_Lin SecondLin( AttachmentPoint2, DirAttach );
200 EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( FirstLin, OffsetPoint ), FirstLin );
201 EndOfArrow2 = ElCLib::Value( ElCLib::Parameter( SecondLin, OffsetPoint ), SecondLin );
203 if (EndOfArrow1.SquareDistance( EndOfArrow2 ) > Precision::SquareConfusion()) // not null length
205 gp_Dir LengthDir( gp_Vec( EndOfArrow1, EndOfArrow2 ) );
206 if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) <
207 EndOfArrow1.SquareDistance( EndOfArrow2 ))
208 DirOfArrow1 = -LengthDir;
210 DirOfArrow1 = LengthDir;
213 DirOfArrow1 = PlaneOfFaces.Axis().Direction();
216 //=======================================================================
217 //function : ComputeCurvilinearFacesLengthPresentation
219 //=======================================================================
221 void DsgPrs::ComputeCurvilinearFacesLengthPresentation( const Standard_Real FirstArrowLength,
222 const Standard_Real SecondArrowLength,
223 const Handle( Geom_Surface )& SecondSurf,
224 const gp_Pnt& AttachmentPoint1,
225 const gp_Pnt& AttachmentPoint2,
226 const gp_Dir& DirAttach,
227 gp_Pnt & EndOfArrow2,
228 gp_Dir & DirOfArrow1,
229 Handle( Geom_Curve )& VCurve,
230 Handle( Geom_Curve )& UCurve,
231 Standard_Real & FirstU,
232 Standard_Real & deltaU,
233 Standard_Real & FirstV,
234 Standard_Real & deltaV )
236 GeomAPI_ProjectPointOnSurf ProjectorOnSurface;
237 GeomAPI_ProjectPointOnCurve ProjectorOnCurve;
238 Quantity_Parameter U1, V1, U2, V2;
239 Standard_Real LastU, LastV;
240 Standard_Real SquareTolerance = Precision::SquareConfusion();
242 ProjectorOnSurface.Init( AttachmentPoint1, SecondSurf );
243 Standard_Integer Index(1);
244 Quantity_Length MinDist = RealLast();
245 Quantity_Parameter LocalU, LocalV;
248 for (Standard_Integer i = 1; i <= ProjectorOnSurface.NbPoints(); i++)
250 ProjectorOnSurface.Parameters( i, LocalU, LocalV );
252 SecondSurf->D1( LocalU, LocalV, EndOfArrow2, D1U, D1V );
253 if (D1U.SquareMagnitude() <= SquareTolerance || D1V.SquareMagnitude() <= SquareTolerance)
254 LocalDir = gp_Dir( gp_Vec( AttachmentPoint1, ProjectorOnSurface.Point( i ) ) );
256 LocalDir = gp_Dir( D1U ^ D1V );
257 if (DirAttach.IsParallel( LocalDir, Precision::Angular() ) && ProjectorOnSurface.Distance( i ) < MinDist)
260 MinDist = ProjectorOnSurface.Distance( i );
263 EndOfArrow2 = ProjectorOnSurface.Point( Index );
264 ProjectorOnSurface.Parameters( Index, U1, V1 );
266 if ((FirstArrowLength + SecondArrowLength)*(FirstArrowLength + SecondArrowLength) <
267 AttachmentPoint1.SquareDistance( EndOfArrow2 ))
268 DirOfArrow1 = -DirAttach;
270 DirOfArrow1 = DirAttach;
272 if (EndOfArrow2.SquareDistance( AttachmentPoint2 ) > Precision::SquareConfusion())
274 VCurve = SecondSurf->VIso( V1 );
275 ProjectorOnCurve.Init( EndOfArrow2, VCurve );
276 FirstU = ProjectorOnCurve.LowerDistanceParameter();
278 ProjectorOnSurface.Init( AttachmentPoint2, SecondSurf );
279 ProjectorOnSurface.LowerDistanceParameters( U2, V2 );
280 UCurve = SecondSurf->UIso( U2 );
282 ProjectorOnCurve.Init( AttachmentPoint2, UCurve );
283 LastV = ProjectorOnCurve.LowerDistanceParameter();
285 gp_Pnt Intersection = SecondSurf->Value( U2, V1 );
286 ProjectorOnCurve.Init( Intersection, VCurve );
287 LastU = ProjectorOnCurve.LowerDistanceParameter();
288 ProjectorOnCurve.Init( Intersection, UCurve );
289 FirstV = ProjectorOnCurve.LowerDistanceParameter();
291 deltaU = LastU - FirstU;
292 deltaV = LastV - FirstV;
294 if (VCurve->IsPeriodic() && Abs( deltaU ) > VCurve->Period()/2)
296 Standard_Real Sign = (deltaU > 0.0)? -1.0 : 1.0;
297 deltaU = VCurve->Period() - Abs( deltaU );
300 if (UCurve->IsPeriodic() && Abs( deltaV ) > UCurve->Period()/2)
302 Standard_Real Sign = (deltaV > 0.0)? -1.0 : 1.0;
303 deltaV = UCurve->Period() - Abs( deltaV );
310 //=======================================================================
311 //function : ComputeFacesAnglePresentation
313 //=======================================================================
315 void DsgPrs::ComputeFacesAnglePresentation( const Standard_Real ArrowLength,
316 const Standard_Real Value,
317 const gp_Pnt& CenterPoint,
318 const gp_Pnt& AttachmentPoint1,
319 const gp_Pnt& AttachmentPoint2,
322 const gp_Dir& axisdir,
323 const Standard_Boolean isPlane,
324 const gp_Ax1& AxisOfSurf,
325 const gp_Pnt& OffsetPoint,
327 Standard_Real & FirstParAngleCirc,
328 Standard_Real & LastParAngleCirc,
329 gp_Pnt & EndOfArrow1,
330 gp_Pnt & EndOfArrow2,
331 gp_Dir & DirOfArrow1,
332 gp_Dir & DirOfArrow2,
333 gp_Pnt & ProjAttachPoint2,
334 gp_Circ & AttachCirc,
335 Standard_Real & FirstParAttachCirc,
336 Standard_Real & LastParAttachCirc )
338 if (Value > Precision::Angular() && Abs( M_PI-Value ) > Precision::Angular())
340 // Computing presentation of angle's arc
341 gp_Ax2 ax( CenterPoint, axisdir, dir1 );
342 AngleCirc.SetPosition( ax );
343 AngleCirc.SetRadius( CenterPoint.Distance( OffsetPoint ) );
345 vec1 *= AngleCirc.Radius();
346 gp_Pnt p1 = CenterPoint.Translated( vec1 );
348 vec2 *= AngleCirc.Radius();
349 gp_Pnt p2 = CenterPoint.Translated( vec2 );
351 Standard_Real Par1 = 0.;
352 Standard_Real Par2 = ElCLib::Parameter( AngleCirc, p2 );
353 Standard_Real Par0 = ElCLib::Parameter( AngleCirc, OffsetPoint );
355 gp_Vec PosVec( CenterPoint, OffsetPoint );
356 gp_Vec NormalOfPlane = vec1 ^ vec2;
358 gp_Vec Normal1 = NormalOfPlane ^ vec1;
359 gp_Vec Normal2 = NormalOfPlane ^ vec2;
360 Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
361 Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
362 if (Sign1 == 1 && Sign2 == -1)
364 FirstParAngleCirc = Par1;
365 LastParAngleCirc = Par2;
367 else if (Sign1 == 1 && Sign2 == 1)
369 FirstParAngleCirc = Par1;
370 LastParAngleCirc = Par0;
372 else if (Sign1 == -1 && Sign2 == 1)
376 FirstParAngleCirc = Par1;
377 LastParAngleCirc = Par2;
379 else //Sign1 == -1 && Sign2 == -1
381 AngleCirc.SetPosition( gp_Ax2( CenterPoint, axisdir, gp_Dir( PosVec ) ) );
383 Par1 = ElCLib::Parameter( AngleCirc, p1 );
384 Par2 = ElCLib::Parameter( AngleCirc, p2 );
385 FirstParAngleCirc = Par0;
386 LastParAngleCirc = Par2;
389 // Computing presentation of arrows
390 EndOfArrow1 = ElCLib::Value( Par1, AngleCirc );
391 EndOfArrow2 = ElCLib::Value( Par2, AngleCirc );
392 Standard_Real beta = 0.;
393 if (AngleCirc.Radius() > Precision::Confusion())
394 beta = ArrowLength / AngleCirc.Radius();
395 gp_Pnt OriginOfArrow1 = ElCLib::Value( Par1 + beta, AngleCirc );
396 gp_Pnt OriginOfArrow2 = ElCLib::Value( Par2 - beta, AngleCirc );
397 DirOfArrow1 = gp_Dir( gp_Vec( OriginOfArrow1, EndOfArrow1 ) );
398 DirOfArrow2 = gp_Dir( gp_Vec( OriginOfArrow2, EndOfArrow2 ) );
399 if (EndOfArrow1.SquareDistance( EndOfArrow2 ) <= (ArrowLength + ArrowLength)*(ArrowLength + ArrowLength))
401 DirOfArrow1.Reverse();
402 DirOfArrow2.Reverse();
405 else // dir1 and dir2 are parallel
407 gp_Dir ArrowDir = axisdir ^ dir1;
408 DirOfArrow1 = ArrowDir;
409 DirOfArrow2 = -ArrowDir;
410 gp_Lin DirLine( AttachmentPoint1, dir1 );
411 EndOfArrow1 = ElCLib::Value( ElCLib::Parameter( DirLine, OffsetPoint ), DirLine );
412 EndOfArrow2 = EndOfArrow1;
415 // Line or arc from AttachmentPoint2 to its "projection"
416 gp_Lin SecondLin( CenterPoint, dir2 );
417 if (SecondLin.Contains( AttachmentPoint2, Precision::Confusion() ))
418 ProjAttachPoint2 = AttachmentPoint2;
422 ProjAttachPoint2 = ElCLib::Value( ElCLib::Parameter( SecondLin, AttachmentPoint2 ), SecondLin );
425 gp_Lin LineOfAxis( AxisOfSurf );
426 gp_Pnt CenterOfArc = ElCLib::Value( ElCLib::Parameter( LineOfAxis, AttachmentPoint2 ),
429 gp_Ax2 Ax2( CenterOfArc,
430 AxisOfSurf.Direction(),
431 gp_Dir( gp_Vec( CenterOfArc, AttachmentPoint2 ) ) );
432 AttachCirc.SetPosition( Ax2 );
433 AttachCirc.SetRadius( CenterOfArc.Distance( AttachmentPoint2 ) );
435 GeomAPI_ExtremaCurveCurve Intersection( new Geom_Circle( AttachCirc ),
436 new Geom_Line( SecondLin ) );
437 Intersection.NearestPoints( ProjAttachPoint2, ProjAttachPoint2 );
439 Standard_Real U2 = ElCLib::Parameter( AttachCirc, ProjAttachPoint2 );
442 FirstParAttachCirc = 0;
443 LastParAttachCirc = U2;
447 FirstParAttachCirc = U2;
448 LastParAttachCirc = 2*M_PI;
456 void DsgPrs::ComputeFilletRadiusPresentation( const Standard_Real /*ArrowLength*/,
457 const Standard_Real Value,
458 const gp_Pnt & Position,
459 const gp_Dir & NormalDir,
460 const gp_Pnt & FirstPoint,
461 const gp_Pnt & SecondPoint,
462 const gp_Pnt & Center,
463 const gp_Pnt & BasePnt,
464 const Standard_Boolean drawRevers,
465 Standard_Boolean & SpecCase,
466 gp_Circ & FilletCirc,
467 Standard_Real & FirstParCirc,
468 Standard_Real & LastParCirc,
471 gp_Pnt & DrawPosition)
473 gp_Dir dir1(gp_Vec(Center, FirstPoint));
474 gp_Dir dir2(gp_Vec(Center, SecondPoint));
475 Standard_Real Angle = dir1.Angle(dir2);
476 if(Angle <= Precision::Angular() || ( M_PI - Angle ) <= Precision::Angular() ||
477 Value <= Precision::Confusion()) SpecCase = Standard_True;
478 else SpecCase = Standard_False;
481 // Computing presentation of fillet's arc
482 gp_Ax2 ax( Center, NormalDir, dir1 );
483 FilletCirc.SetPosition( ax );
484 FilletCirc.SetRadius( Center.Distance( FirstPoint ) ); //***
486 vec1 *= FilletCirc.Radius();
488 vec2 *= FilletCirc.Radius();
490 if(! Center.IsEqual( Position, Precision::Confusion() ))
491 PosVec.SetXYZ( gp_Vec(Center, Position).XYZ() );
493 PosVec.SetXYZ( (vec1.Added(vec2)).XYZ() );
494 gp_Vec NormalOfPlane = vec1 ^ vec2;
495 gp_Vec Normal1 = NormalOfPlane ^ vec1;
496 gp_Vec Normal2 = NormalOfPlane ^ vec2;
497 Standard_Integer Sign1 = (PosVec * Normal1 >= 0)? 1 : -1;
498 Standard_Integer Sign2 = (PosVec * Normal2 >= 0)? 1 : -1;
499 gp_Lin L1( Center, dir1 );
500 gp_Lin L2( Center, dir2 );
501 if ( Sign1 != Sign2 )
503 DrawPosition = Position; //***
504 gp_Dir direction(PosVec) ;
505 Standard_Real angle = dir1.Angle(direction) ;
506 if (( dir1 ^ direction) * NormalDir < 0.0e0) angle = -angle ;
507 if(Sign1 == -1) angle += M_PI;
508 EndOfArrow = ElCLib::Value(angle, FilletCirc); //***
513 if(L1.Distance(Position) < L2.Distance(Position))
515 EndOfArrow = FirstPoint; //***
516 DrawPosition = ElCLib::Value(ElCLib::Parameter(L1, Position), L1);
520 EndOfArrow = SecondPoint; //***
521 DrawPosition = ElCLib::Value(ElCLib::Parameter(L2, Position), L2);
524 if((dir1^dir2).IsOpposite(NormalDir, Precision::Angular()))
526 gp_Dir newdir = NormalDir.Reversed() ;
527 gp_Ax2 axnew( Center, newdir, dir1 );
528 FilletCirc.SetPosition( axnew );
530 FirstParCirc = ElCLib::Parameter( FilletCirc, FirstPoint );
531 LastParCirc = ElCLib::Parameter( FilletCirc, SecondPoint );
533 else //Angle equal 0 or PI or R = 0
535 DrawPosition = Position;
536 EndOfArrow = BasePnt;
541 gp_Vec Vd(DrawPosition, EndOfArrow);
542 DrawPosition.Translate(Vd *2);
544 DirOfArrow.SetXYZ(gp_Dir(gp_Vec(DrawPosition, EndOfArrow)).XYZ());
547 //=======================================================================
548 //function : ComputeRadiusLine
550 //=======================================================================
552 void DsgPrs::ComputeRadiusLine(const gp_Pnt & aCenter,
553 const gp_Pnt & anEndOfArrow,
554 const gp_Pnt & aPosition,
555 const Standard_Boolean drawFromCenter,
556 gp_Pnt & aRadLineOrign,
557 gp_Pnt & aRadLineEnd)
561 gp_Lin RadiusLine = gce_MakeLin( aCenter, anEndOfArrow );
562 Standard_Real PosParOnLine = ElCLib::Parameter( RadiusLine, aPosition );
563 Standard_Real EndOfArrowPar = ElCLib::Parameter( RadiusLine, anEndOfArrow );
564 if (PosParOnLine < 0.0)
566 aRadLineOrign = aPosition;
567 aRadLineEnd = anEndOfArrow;
569 else if (PosParOnLine > EndOfArrowPar)
571 aRadLineOrign = aPosition;
572 aRadLineEnd = aCenter;
576 aRadLineOrign = aCenter;
577 aRadLineEnd = anEndOfArrow;
582 aRadLineOrign = aPosition;
583 aRadLineEnd = anEndOfArrow;
588 //=======================================================================
589 //function : DistanceFromApex
591 //=======================================================================
593 Standard_Real DsgPrs::DistanceFromApex(const gp_Elips & elips,
595 const Standard_Real par)
598 Standard_Real parApex = ElCLib::Parameter ( elips, Apex );
599 if(parApex == 0.0 || parApex == M_PI)
601 if(parApex == 0.0) //pos Apex
602 dist = (par < M_PI) ? par : (2*M_PI - par);
604 dist = (par < M_PI) ? ( M_PI - par) : ( par - M_PI );
608 if(parApex == M_PI / 2) //pos Apex
610 if(par <= parApex + M_PI && par > parApex )
611 dist = par - parApex;
614 if(par > parApex + M_PI)
615 dist = 2*M_PI - par + parApex;
617 dist = parApex - par; // 0 < par < M_PI/2
620 else //neg Apex == 3/2 PI
622 if(par <= parApex && par >= M_PI/2)
623 dist = parApex - par;
627 dist = par - parApex;
629 dist = par + M_PI/2; // 0 < par < PI/2