973c2be1 |
1 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
2 | // |
973c2be1 |
3 | // This file is part of Open CASCADE Technology software library. |
b311480e |
4 | // |
d5f74e42 |
5 | // This library is free software; you can redistribute it and/or modify it under |
6 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
7 | // by the Free Software Foundation, with special exception defined in the file |
8 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
9 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
10 | // |
973c2be1 |
11 | // Alternatively, this file may be used under the terms of Open CASCADE |
12 | // commercial license or contractual agreement. |
b311480e |
13 | |
4178b353 |
14 | #include <StlAPI_Writer.hxx> |
42cf5bc1 |
15 | |
7fd59977 |
16 | #include <Bnd_Box.hxx> |
7fd59977 |
17 | #include <BRepBndLib.hxx> |
18 | #include <OSD_Path.hxx> |
b508cbc5 |
19 | #include <OSD_OpenFile.hxx> |
42cf5bc1 |
20 | #include <RWStl.hxx> |
b508cbc5 |
21 | #include <BRep_Tool.hxx> |
22 | #include <TopoDS.hxx> |
23 | #include <TopoDS_Face.hxx> |
24 | #include <TopExp_Explorer.hxx> |
25 | #include <Poly_Triangulation.hxx> |
7fd59977 |
26 | |
4178b353 |
27 | //============================================================================= |
28 | //function : StlAPI_Writer |
29 | //purpose : |
30 | //============================================================================= |
7fd59977 |
31 | StlAPI_Writer::StlAPI_Writer() |
4178b353 |
32 | : myASCIIMode (Standard_True) |
7fd59977 |
33 | { |
4178b353 |
34 | // |
7fd59977 |
35 | } |
36 | |
4178b353 |
37 | //============================================================================= |
38 | //function : Write |
39 | //purpose : |
40 | //============================================================================= |
41 | Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape& theShape, |
42 | const Standard_CString theFileName) |
7fd59977 |
43 | { |
4178b353 |
44 | Standard_Integer aNbNodes = 0; |
45 | Standard_Integer aNbTriangles = 0; |
b508cbc5 |
46 | |
4178b353 |
47 | // calculate total number of the nodes and triangles |
48 | for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) |
b508cbc5 |
49 | { |
4178b353 |
50 | TopLoc_Location aLoc; |
51 | Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc); |
52 | aNbNodes += aTriangulation->NbNodes(); |
53 | aNbTriangles += aTriangulation->NbTriangles(); |
b508cbc5 |
54 | } |
b508cbc5 |
55 | |
4178b353 |
56 | // create temporary triangulation |
57 | Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False); |
b9c1e440 |
58 | |
4178b353 |
59 | // fill temporary triangulation |
60 | Standard_Integer aNodeOffset = 0; |
61 | Standard_Integer aTriangleOffet = 0; |
62 | for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next()) |
b508cbc5 |
63 | { |
4178b353 |
64 | TopLoc_Location aLoc; |
65 | Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc); |
b508cbc5 |
66 | |
4178b353 |
67 | const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); |
68 | const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles(); |
b508cbc5 |
69 | |
4178b353 |
70 | // copy nodes |
71 | gp_Trsf aTrsf = aLoc.Transformation(); |
72 | for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) |
b508cbc5 |
73 | { |
4178b353 |
74 | gp_Pnt aPnt = aNodes (aNodeIter); |
75 | aPnt.Transform (aTrsf); |
76 | aMesh->ChangeNode (aNodeIter + aNodeOffset) = aPnt; |
b508cbc5 |
77 | } |
b508cbc5 |
78 | |
4178b353 |
79 | // copy triangles |
80 | const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation(); |
81 | for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter) |
b508cbc5 |
82 | { |
4178b353 |
83 | Poly_Triangle aTri = aTriangles (aTriIter); |
b508cbc5 |
84 | |
4178b353 |
85 | Standard_Integer anId[3]; |
86 | aTri.Get (anId[0], anId[1], anId[2]); |
87 | if (anOrientation == TopAbs_REVERSED) |
88 | { |
89 | // Swap 1, 2. |
90 | Standard_Integer aTmpIdx = anId[1]; |
91 | anId[1] = anId[2]; |
92 | anId[2] = aTmpIdx; |
93 | } |
b508cbc5 |
94 | |
4178b353 |
95 | // Update nodes according to the offset. |
96 | anId[0] += aNodeOffset; |
97 | anId[1] += aNodeOffset; |
98 | anId[2] += aNodeOffset; |
b508cbc5 |
99 | |
4178b353 |
100 | aTri.Set (anId[0], anId[1], anId[2]); |
101 | aMesh->ChangeTriangle (aTriIter + aTriangleOffet) = aTri; |
b508cbc5 |
102 | } |
4178b353 |
103 | |
104 | aNodeOffset += aNodes.Size(); |
105 | aTriangleOffet += aTriangles.Size(); |
b508cbc5 |
106 | } |
107 | |
4178b353 |
108 | OSD_Path aPath (theFileName); |
109 | return myASCIIMode |
110 | ? RWStl::WriteAscii (aMesh, aPath) |
111 | : RWStl::WriteBinary (aMesh, aPath); |
7fd59977 |
112 | } |