0028263: Coding Rules - clean up definition of the class Graphic3d_MaterialAspect
[occt.git] / src / Prs3d / Prs3d.cxx
1 // Created on: 1993-08-27
2 // Created by: Jean-Louis FRENKEL
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <Prs3d.hxx>
18
19 #include <Bnd_Box.hxx>
20 #include <BRepBndLib.hxx>
21 #include <gp_Pnt.hxx>
22 #include <Graphic3d_Group.hxx>
23 #include <Prs3d_Drawer.hxx>
24 #include <Prs3d_LineAspect.hxx>
25 #include <Prs3d_Root.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <Graphic3d_ArrayOfSegments.hxx>
28
29 //=======================================================================
30 //function : MatchSegment
31 //purpose  :
32 //=======================================================================
33 Standard_Boolean Prs3d::MatchSegment 
34                  (const Quantity_Length X,
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;
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) +
53           Abs(Y-Y1-Lambda*DY) +
54           Abs(Z-Z1-Lambda*DZ);
55   return (dist < aDistance);
56 }
57
58 //=======================================================================
59 //function : GetDeflection
60 //purpose  :
61 //=======================================================================
62 Standard_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))
67
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;
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);
81     }
82   }
83   return aDeflection;
84 }
85
86 //==================================================================
87 // function: PrimitivesFromPolylines
88 // purpose:
89 //==================================================================
90 Handle(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 //==================================================================
125 void 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 }