0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[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 <gp_Pnt.hxx>
20 #include <Graphic3d_ArrayOfSegments.hxx>
21 #include <Graphic3d_Group.hxx>
22 #include <Poly_Connect.hxx>
23 #include <Poly_Triangulation.hxx>
24 #include <Prs3d_LineAspect.hxx>
25
26 // =========================================================================
27 // function : AddFreeEdges
28 // purpose  :
29 // =========================================================================
30 void Prs3d::AddFreeEdges (TColgp_SequenceOfPnt& theSegments,
31                           const Handle(Poly_Triangulation)& thePolyTri,
32                           const gp_Trsf& theLocation)
33 {
34   if (thePolyTri.IsNull())
35   {
36     return;
37   }
38
39   const TColgp_Array1OfPnt& aNodes = thePolyTri->Nodes();
40
41   // Build the connect tool.
42   Poly_Connect aPolyConnect (thePolyTri);
43
44   Standard_Integer aNbTriangles = thePolyTri->NbTriangles();
45   Standard_Integer aT[3];
46   Standard_Integer aN[3];
47
48   // Count the free edges.
49   Standard_Integer aNbFree = 0;
50   for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
51   {
52     aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
53     for (Standard_Integer aJ = 0; aJ < 3; ++aJ)
54     {
55       if (aT[aJ] == 0)
56       {
57         ++aNbFree;
58       }
59     }
60   }
61   if (aNbFree == 0)
62   {
63     return;
64   }
65
66   TColStd_Array1OfInteger aFree (1, 2 * aNbFree);
67
68   Standard_Integer aFreeIndex = 1;
69   const Poly_Array1OfTriangle& aTriangles = thePolyTri->Triangles();
70   for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI)
71   {
72     aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]);
73     aTriangles (anI).Get (aN[0], aN[1], aN[2]);
74     for (Standard_Integer aJ = 0; aJ < 3; aJ++)
75     {
76       Standard_Integer k = (aJ + 1) % 3;
77       if (aT[aJ] == 0)
78       {
79         aFree (aFreeIndex)     = aN[aJ];
80         aFree (aFreeIndex + 1) = aN[k];
81         aFreeIndex += 2;
82       }
83     }
84   }
85
86   // free edges
87   Standard_Integer aFreeHalfNb = aFree.Length() / 2;
88   for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI)
89   {
90     const gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (theLocation);
91     const gp_Pnt aPoint2 = aNodes (aFree (2 * anI    )).Transformed (theLocation);
92     theSegments.Append (aPoint1);
93     theSegments.Append (aPoint2);
94   }
95 }
96
97 //=======================================================================
98 //function : MatchSegment
99 //purpose  :
100 //=======================================================================
101 Standard_Boolean Prs3d::MatchSegment 
102                  (const Standard_Real X,
103                   const Standard_Real Y,
104                   const Standard_Real Z,
105                   const Standard_Real aDistance,
106                   const gp_Pnt& P1,
107                   const gp_Pnt& P2,
108                   Standard_Real& dist)
109 {
110   Standard_Real X1,Y1,Z1,X2,Y2,Z2;
111   P1.Coord(X1,Y1,Z1); P2.Coord(X2,Y2,Z2);
112   Standard_Real DX = X2-X1; 
113   Standard_Real DY = Y2-Y1; 
114   Standard_Real DZ = Z2-Z1;
115   Standard_Real Dist = DX*DX + DY*DY + DZ*DZ;
116   if (Dist == 0.) return Standard_False;
117   
118   Standard_Real Lambda = ((X-X1)*DX + (Y-Y1)*DY + (Z-Z1)*DZ)/Dist;
119   if ( Lambda < 0. || Lambda > 1. ) return Standard_False;
120   dist =  Abs(X-X1-Lambda*DX) +
121           Abs(Y-Y1-Lambda*DY) +
122           Abs(Z-Z1-Lambda*DZ);
123   return (dist < aDistance);
124 }
125
126 //==================================================================
127 // function: PrimitivesFromPolylines
128 // purpose:
129 //==================================================================
130 Handle(Graphic3d_ArrayOfPrimitives) Prs3d::PrimitivesFromPolylines (const Prs3d_NListOfSequenceOfPnt& thePoints)
131 {
132   if (thePoints.IsEmpty())
133   {
134     return Handle(Graphic3d_ArrayOfPrimitives)();
135   }
136
137   Standard_Integer aNbVertices = 0;
138   for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next())
139   {
140     aNbVertices += anIt.Value()->Length();
141   }
142   const Standard_Integer aSegmentEdgeNb = (aNbVertices - thePoints.Size()) * 2;
143   Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNbVertices, aSegmentEdgeNb);
144   for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next())
145   {
146     const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value();
147
148     Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1;
149     aSegments->AddVertex (aPoints->First());
150     for (Standard_Integer aPntIter = aPoints->Lower() + 1; aPntIter <= aPoints->Upper(); ++aPntIter)
151     {
152       aSegments->AddVertex (aPoints->Value (aPntIter));
153       aSegments->AddEdge (  aSegmentEdge);
154       aSegments->AddEdge (++aSegmentEdge);
155     }
156   }
157
158   return aSegments;
159 }
160
161 //==================================================================
162 // function: AddPrimitivesGroup
163 // purpose:
164 //==================================================================
165 void Prs3d::AddPrimitivesGroup (const Handle(Prs3d_Presentation)& thePrs,
166                                 const Handle(Prs3d_LineAspect)&   theAspect,
167                                 Prs3d_NListOfSequenceOfPnt&       thePolylines)
168 {
169   Handle(Graphic3d_ArrayOfPrimitives) aPrims = Prs3d::PrimitivesFromPolylines (thePolylines);
170   thePolylines.Clear();
171   if (!aPrims.IsNull())
172   {
173     Handle(Graphic3d_Group) aGroup = thePrs->NewGroup();
174     aGroup->SetPrimitivesAspect (theAspect->Aspect());
175     aGroup->AddPrimitiveArray (aPrims);
176   }
177 }