0030153: Visualization, TKOpenGl - AIS_ColoredShape::SynchronizeAspects() doesn't...
[occt.git] / src / StlAPI / StlAPI_Writer.cxx
CommitLineData
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 31StlAPI_Writer::StlAPI_Writer()
4178b353 32: myASCIIMode (Standard_True)
7fd59977 33{
4178b353 34 //
7fd59977 35}
36
4178b353 37//=============================================================================
38//function : Write
39//purpose :
40//=============================================================================
41Standard_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);
22e70738 52 if (! aTriangulation.IsNull())
53 {
54 aNbNodes += aTriangulation->NbNodes ();
55 aNbTriangles += aTriangulation->NbTriangles ();
56 }
b508cbc5 57 }
b508cbc5 58
4178b353 59 // create temporary triangulation
60 Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False);
b9c1e440 61
4178b353 62 // fill temporary triangulation
63 Standard_Integer aNodeOffset = 0;
64 Standard_Integer aTriangleOffet = 0;
65 for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
b508cbc5 66 {
4178b353 67 TopLoc_Location aLoc;
68 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc);
b508cbc5 69
4178b353 70 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
71 const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
b508cbc5 72
4178b353 73 // copy nodes
74 gp_Trsf aTrsf = aLoc.Transformation();
75 for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
b508cbc5 76 {
4178b353 77 gp_Pnt aPnt = aNodes (aNodeIter);
78 aPnt.Transform (aTrsf);
79 aMesh->ChangeNode (aNodeIter + aNodeOffset) = aPnt;
b508cbc5 80 }
b508cbc5 81
4178b353 82 // copy triangles
83 const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
84 for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter)
b508cbc5 85 {
4178b353 86 Poly_Triangle aTri = aTriangles (aTriIter);
b508cbc5 87
4178b353 88 Standard_Integer anId[3];
89 aTri.Get (anId[0], anId[1], anId[2]);
90 if (anOrientation == TopAbs_REVERSED)
91 {
92 // Swap 1, 2.
93 Standard_Integer aTmpIdx = anId[1];
94 anId[1] = anId[2];
95 anId[2] = aTmpIdx;
96 }
b508cbc5 97
4178b353 98 // Update nodes according to the offset.
99 anId[0] += aNodeOffset;
100 anId[1] += aNodeOffset;
101 anId[2] += aNodeOffset;
b508cbc5 102
4178b353 103 aTri.Set (anId[0], anId[1], anId[2]);
104 aMesh->ChangeTriangle (aTriIter + aTriangleOffet) = aTri;
b508cbc5 105 }
4178b353 106
107 aNodeOffset += aNodes.Size();
108 aTriangleOffet += aTriangles.Size();
b508cbc5 109 }
110
4178b353 111 OSD_Path aPath (theFileName);
112 return myASCIIMode
113 ? RWStl::WriteAscii (aMesh, aPath)
114 : RWStl::WriteBinary (aMesh, aPath);
7fd59977 115}