0027596: Visualization, StdPrs_WFShape - pack isolines into single group of primitives
[occt.git] / src / Prs3d / Prs3d.cxx
CommitLineData
b311480e 1// Created on: 1993-08-27
2// Created by: Jean-Louis FRENKEL
3// Copyright (c) 1993-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
1b9f5d95 17#include <Prs3d.hxx>
42cf5bc1 18
9dba391d 19#include <Bnd_Box.hxx>
20#include <BRepBndLib.hxx>
42cf5bc1 21#include <gp_Pnt.hxx>
1b9f5d95 22#include <Graphic3d_Group.hxx>
9dba391d 23#include <Prs3d_Drawer.hxx>
1b9f5d95 24#include <Prs3d_LineAspect.hxx>
25#include <Prs3d_Root.hxx>
9dba391d 26#include <TopoDS_Shape.hxx>
1b9f5d95 27#include <Graphic3d_ArrayOfSegments.hxx>
7fd59977 28
9dba391d 29//=======================================================================
30//function : MatchSegment
31//purpose :
32//=======================================================================
7fd59977 33Standard_Boolean Prs3d::MatchSegment
34 (const Quantity_Length X,
9dba391d 35 const Quantity_Length Y,
36 const Quantity_Length Z,
37 const Quantity_Length aDistance,
38 const gp_Pnt& P1,
39 const gp_Pnt& P2,
40 Quantity_Length& dist)
41{
42 Standard_Real X1,Y1,Z1,X2,Y2,Z2;
7fd59977 43 P1.Coord(X1,Y1,Z1); P2.Coord(X2,Y2,Z2);
44 Standard_Real DX = X2-X1;
45 Standard_Real DY = Y2-Y1;
46 Standard_Real DZ = Z2-Z1;
47 Standard_Real Dist = DX*DX + DY*DY + DZ*DZ;
48 if (Dist == 0.) return Standard_False;
49
50 Standard_Real Lambda = ((X-X1)*DX + (Y-Y1)*DY + (Z-Z1)*DZ)/Dist;
51 if ( Lambda < 0. || Lambda > 1. ) return Standard_False;
52 dist = Abs(X-X1-Lambda*DX) +
9dba391d 53 Abs(Y-Y1-Lambda*DY) +
54 Abs(Z-Z1-Lambda*DZ);
7fd59977 55 return (dist < aDistance);
9dba391d 56}
57
58//=======================================================================
59//function : GetDeflection
60//purpose :
61//=======================================================================
62Standard_Real Prs3d::GetDeflection (const TopoDS_Shape& theShape,
63 const Handle(Prs3d_Drawer)& theDrawer)
64{
65#define MAX2(X, Y) (Abs(X) > Abs(Y) ? Abs(X) : Abs(Y))
66#define MAX3(X, Y, Z) (MAX2 (MAX2 (X, Y), Z))
7fd59977 67
9dba391d 68 Standard_Real aDeflection = theDrawer->MaximalChordialDeviation();
69 if (theDrawer->TypeOfDeflection() == Aspect_TOD_RELATIVE)
70 {
71 Bnd_Box aBndBox;
72 BRepBndLib::Add (theShape, aBndBox, Standard_False);
73 if (!aBndBox.IsVoid())
74 {
75 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
76 aBndBox.Get (aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
77 aDeflection = MAX3 (aXmax-aXmin, aYmax-aYmin, aZmax-aZmin) * theDrawer->DeviationCoefficient() * 4.0;
7f917335 78 // we store computed relative deflection of shape as absolute deviation coefficient
79 // in case relative type to use it later on for sub-shapes.
80 theDrawer->SetMaximalChordialDeviation (aDeflection);
9dba391d 81 }
82 }
83 return aDeflection;
7fd59977 84}
1b9f5d95 85
86//==================================================================
87// function: PrimitivesFromPolylines
88// purpose:
89//==================================================================
90Handle(Graphic3d_ArrayOfPrimitives) Prs3d::PrimitivesFromPolylines (const Prs3d_NListOfSequenceOfPnt& thePoints)
91{
92 if (thePoints.IsEmpty())
93 {
94 return Handle(Graphic3d_ArrayOfPrimitives)();
95 }
96
97 Standard_Integer aNbVertices = 0;
98 for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next())
99 {
100 aNbVertices += anIt.Value()->Length();
101 }
102 const Standard_Integer aSegmentEdgeNb = (aNbVertices - thePoints.Size()) * 2;
103 Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNbVertices, aSegmentEdgeNb);
104 for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next())
105 {
106 const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
107
108 Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1;
109 aSegments->AddVertex (aPoints->First());
110 for (Standard_Integer aPntIter = aPoints->Lower() + 1; aPntIter <= aPoints->Upper(); ++aPntIter)
111 {
112 aSegments->AddVertex (aPoints->Value (aPntIter));
113 aSegments->AddEdge ( aSegmentEdge);
114 aSegments->AddEdge (++aSegmentEdge);
115 }
116 }
117
118 return aSegments;
119}
120
121//==================================================================
122// function: AddPrimitivesGroup
123// purpose:
124//==================================================================
125void Prs3d::AddPrimitivesGroup (const Handle(Prs3d_Presentation)& thePrs,
126 const Handle(Prs3d_LineAspect)& theAspect,
127 Prs3d_NListOfSequenceOfPnt& thePolylines)
128{
129 Handle(Graphic3d_ArrayOfPrimitives) aPrims = Prs3d::PrimitivesFromPolylines (thePolylines);
130 thePolylines.Clear();
131 if (!aPrims.IsNull())
132 {
133 Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs);
134 aGroup->SetPrimitivesAspect (theAspect->Aspect());
135 aGroup->AddPrimitiveArray (aPrims);
136 }
137}