0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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>
44d5a096 18#include <Message.hxx>
19#include <Message_Messenger.hxx>
7fd59977 20#include <OSD_Path.hxx>
b508cbc5 21#include <OSD_OpenFile.hxx>
42cf5bc1 22#include <RWStl.hxx>
b508cbc5 23#include <BRep_Tool.hxx>
24#include <TopoDS.hxx>
25#include <TopoDS_Face.hxx>
26#include <TopExp_Explorer.hxx>
27#include <Poly_Triangulation.hxx>
7fd59977 28
4178b353 29//=============================================================================
30//function : StlAPI_Writer
31//purpose :
32//=============================================================================
7fd59977 33StlAPI_Writer::StlAPI_Writer()
4178b353 34: myASCIIMode (Standard_True)
7fd59977 35{
4178b353 36 //
7fd59977 37}
38
4178b353 39//=============================================================================
40//function : Write
41//purpose :
42//=============================================================================
43Standard_Boolean StlAPI_Writer::Write (const TopoDS_Shape& theShape,
1fc1a207 44 const Standard_CString theFileName,
45 const Handle(Message_ProgressIndicator)& theProgress)
7fd59977 46{
4178b353 47 Standard_Integer aNbNodes = 0;
48 Standard_Integer aNbTriangles = 0;
b508cbc5 49
4178b353 50 // calculate total number of the nodes and triangles
51 for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
b508cbc5 52 {
4178b353 53 TopLoc_Location aLoc;
54 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (anExpSF.Current()), aLoc);
22e70738 55 if (! aTriangulation.IsNull())
56 {
57 aNbNodes += aTriangulation->NbNodes ();
58 aNbTriangles += aTriangulation->NbTriangles ();
59 }
b508cbc5 60 }
b508cbc5 61
44d5a096 62 if (aNbTriangles == 0)
63 {
64 // No triangulation on the shape
65 return Standard_False;
66 }
67
4178b353 68 // create temporary triangulation
69 Handle(Poly_Triangulation) aMesh = new Poly_Triangulation (aNbNodes, aNbTriangles, Standard_False);
44d5a096 70 // count faces missing triangulation
71 Standard_Integer aNbFacesNoTri = 0;
4178b353 72 // fill temporary triangulation
73 Standard_Integer aNodeOffset = 0;
74 Standard_Integer aTriangleOffet = 0;
75 for (TopExp_Explorer anExpSF (theShape, TopAbs_FACE); anExpSF.More(); anExpSF.Next())
b508cbc5 76 {
44d5a096 77 const TopoDS_Shape& aFace = anExpSF.Current();
4178b353 78 TopLoc_Location aLoc;
44d5a096 79 Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (TopoDS::Face (aFace), aLoc);
80 if (aTriangulation.IsNull())
81 {
82 ++aNbFacesNoTri;
83 continue;
84 }
b508cbc5 85
4178b353 86 const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes();
87 const Poly_Array1OfTriangle& aTriangles = aTriangulation->Triangles();
b508cbc5 88
4178b353 89 // copy nodes
90 gp_Trsf aTrsf = aLoc.Transformation();
91 for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter)
b508cbc5 92 {
4178b353 93 gp_Pnt aPnt = aNodes (aNodeIter);
94 aPnt.Transform (aTrsf);
95 aMesh->ChangeNode (aNodeIter + aNodeOffset) = aPnt;
b508cbc5 96 }
b508cbc5 97
4178b353 98 // copy triangles
99 const TopAbs_Orientation anOrientation = anExpSF.Current().Orientation();
100 for (Standard_Integer aTriIter = aTriangles.Lower(); aTriIter <= aTriangles.Upper(); ++aTriIter)
b508cbc5 101 {
4178b353 102 Poly_Triangle aTri = aTriangles (aTriIter);
b508cbc5 103
4178b353 104 Standard_Integer anId[3];
105 aTri.Get (anId[0], anId[1], anId[2]);
106 if (anOrientation == TopAbs_REVERSED)
107 {
108 // Swap 1, 2.
109 Standard_Integer aTmpIdx = anId[1];
110 anId[1] = anId[2];
111 anId[2] = aTmpIdx;
112 }
b508cbc5 113
4178b353 114 // Update nodes according to the offset.
115 anId[0] += aNodeOffset;
116 anId[1] += aNodeOffset;
117 anId[2] += aNodeOffset;
b508cbc5 118
4178b353 119 aTri.Set (anId[0], anId[1], anId[2]);
120 aMesh->ChangeTriangle (aTriIter + aTriangleOffet) = aTri;
b508cbc5 121 }
4178b353 122
123 aNodeOffset += aNodes.Size();
124 aTriangleOffet += aTriangles.Size();
b508cbc5 125 }
126
4178b353 127 OSD_Path aPath (theFileName);
44d5a096 128 Standard_Boolean isDone = (myASCIIMode
1fc1a207 129 ? RWStl::WriteAscii(aMesh, aPath, theProgress)
130 : RWStl::WriteBinary(aMesh, aPath, theProgress));
44d5a096 131
132 if (isDone && (aNbFacesNoTri > 0))
133 {
134 // Print warning with number of faces missing triangulation
135 TCollection_AsciiString aWarningMsg =
136 TCollection_AsciiString ("Warning: ") +
137 TCollection_AsciiString (aNbFacesNoTri) +
138 TCollection_AsciiString ((aNbFacesNoTri == 1) ? " face has" : " faces have") +
139 TCollection_AsciiString (" been skipped due to null triangulation");
a87b1b37 140 Message::SendWarning (aWarningMsg);
44d5a096 141 }
142
143 return isDone;
7fd59977 144}